Last night I made time to look at something I've been meaning to check out for years - drawing with ActionScript. While I have absolutely no need for this at all, it's something I've meant to take a look at. I've only looked at a few pages of the drawing API so far, but it was enough to do a few experiments in AIR. I began with the recreation of something I wrote once in AppleSoft BASIC, my very first programming language.
This code simply begins at the top left corner of the screen and draws to the bottom. It then inches down the left side and moves the bottom towards the right. Here is the complete code listing. I have to thank the writers here for helping me get the Shape object onto the Flex screen. (And please - remember - I spent like 5 minutes on this - the code is horrible I'm sure.)
<mx:Script>
<![CDATA[ public function init():void { var myLine:Shape = new Shape()
myLine.graphics.lineStyle(1, 0x990000, 1) for(var i:int=1; i<screen.height; i=i+5) {
myLine.graphics.moveTo(1, i)
myLine.graphics.lineTo(1+i, screen.height)
} this.rawChildren.addChild(myLine) } ]]>
</mx:Script> </mx:WindowedApplication>
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()">
Even if you don't know ActionScript, you can probably read that and grok what it is doing. The output - which actually looked much cooler on my Apple 2e's monochrome screen is this:
I then followed up with something a bit more random:
<mx:Script>
<![CDATA[ public function init():void {
drawIt()
} public function drawIt():void {
var myLine:Shape = new Shape()
myLine.graphics.lineStyle(1, 0x990000, 1) var initx:int = 1;
var inity:int = 1;
var newx:int;
var newy:int; myLine.graphics.moveTo(initx, inity) //Draw 20 lines
for(var i:int=1; i<=20; i++) {
//pick new position
newx = Math.round(Math.random() * screen.width)+1;
newy = Math.round(Math.random() * screen.height)+1;
myLine.graphics.lineTo(newx, newy) } this.rawChildren.addChild(myLine) } ]]>
</mx:Script> <mx:Button label="Redraw" x="1" y="1" click="drawIt()" /> </mx:WindowedApplication>
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()">
In this example, I simply draw from one random position to the next. I added a button so I could run it multiple times.
Awesome, eh? I won't be winning any awards yet. What I need to learn next is:
- When I put the shape onto the Flex screen, I lose access to it. I want to keep working with it, but I'm not sure how.
- In the second example, the button ends up getting drawn over. Is there a way to handle z-index?
Archived Comments
Just a thought - what if you declare your shape globally? Would that allow you to continue to work with it? I have no experience with this either, just throwing that out there.
Another thought - try adding the button programatically with actionscript - and do it after you draw. If I remember correctly Flex/AS does a 'top down' approach for 'z-index' (IE: the last object added is on top).
Of course I may be completely wrong... it wouldn't be the first time :D
I tried that.
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()">
<mx:Script>
<![CDATA[
public var myLine:Shape;
public var current:int;
public function init():void {
current = 10
myLine = new Shape()
myLine.graphics.lineStyle(5, 0x990000, 1)
myLine.graphics.moveTo(current, 10)
myLine.graphics.lineTo(10, 50)
this.rawChildren.addChild(myLine)
var myTimer:Timer = new Timer(1000, 20)
myTimer.addEventListener(TimerEvent.TIMER, moveLine)
}
public function moveLine(event:TimerEvent):void {
current+=10
myLine.moveTo(current, 10)
}
]]>
</mx:Script>
</mx:WindowedApplication>
The issue here is that it won't compile. Gives me an error on that last moveTo:
Call to a possibly undefined method moveTo through a reference with static type flash.display:Shape.
myLine.moveTo(current, 10)
must be
myLine.graphics.moveTo(current, 10)
If you're looking to hold onto the objects themselves, you'll have to draw using a Vector of IGraphicsData. Check out flash.display.Graphics::drawGraphicsData, it'll have a good example. Cool stuff!
http://livedocs.adobe.com/f...
I probably missunderstood the problem, with the last moveTo, do you want to reposition the line? than you should do something like this: myLine.x += 10?
Could you describe exactly what you want to do, then I'll probably can help you out.
For the button: if you add something to the stage with the addChild function you can also use the addChildAt(myLine,0).
Holy crap Bert. That's so obvious. -sigh-
No error now - but no animation. I'll get that next.
@JesterXL: I'll check it out. Thanks!
And it helps if I _start_ my timer. ;) Timer is running -b ut the graphics aren't updated. Thinking...
God I'm an idiot -helps if I _lineTo_, not just _moveTo_. Ok, will post a new demo a bit later.
That first design there - I remember doing that on graph paper all throughout math class when I'd get bored. Fascinating design. :)
Maybe these posts at my blog can help you on your experiments:
http://mylinerider.com/2009...
http://mylinerider.com/2009...
http://mylinerider.com/2009...
Neat stuff Gilbert!
Thanks Raymond. Soon I will post an article about how to create regular polygons, stars and bursts dynamically.