Falmil
Level 6
|
|
« on: January 26, 2010, 02:49:44 PM » |
|
After several failures of trying to learn and make a game multiple steps at a time while inexperienced, I'm trying again from the beginning. I'm trying to make a simple draw loop in flash that will draw a cannon on a tank rotating around. After getting a static image of a poorly aligned cannon to be drawn in multiple rotated positions, I learned that an infinite loop won't work and that you need to use events in order to give Flash sometime to update the display list and what ever other crap it does. I added a timer and a timer event handler, but now nothing will display at all. I am unsure what the heck I did wrong and would appreciate some help from those more experienced in AS3 and Flash. package { import flash.display.*; import flash.geom.*; import flash.events.*; import flash.utils.*; [SWF(width="600", height="450")]
public class Test extends Sprite { [Embed(source="cannon.png")] public const imgCannon:Class;
[Embed(source="projectile.png")] public const imgProjectile:Class; [Embed(source="tank.png")] public const imgTank:Class; private var screenWidth:int = 600; private var screenHeight:int = 450; private var screen:BitmapData = new BitmapData(screenWidth, screenHeight); private var scn:Bitmap= new Bitmap(screen); private var buffer:BitmapData= new BitmapData(screenWidth, screenHeight); private var bTank:Bitmap= new imgTank(); private var bCannon:Bitmap = new imgCannon(); private var clock:Timer = new Timer(1000); private var a:Number = 1; public function Test() : void { //show screen addChild(scn); //event listeners clock.addEventListener(TimerEvent.TIMER, update); clock.addEventListener(TimerEvent.TIMER, render); //start timer clock.start(); } public function update():void { a+=(Math.PI/12); if(a>(2*Math.PI)) a -= (Math.PI*2); } public function render():void { //draw tank drawTank(new Point(50, 100), a); //draw buffer to screen drawScreen(); } public function drawTank(p:Point, angle:Number): void { //draw tank //cannon spot:41,31 drawToBuffer(bTank.bitmapData, new Point(64,64), new Point(p.x, p.y)); //draw cannon //cannon center:29,3 drawTransformed(bCannon.bitmapData, new Point(p.x+12, p.y+28), angle, false); } public function drawToBuffer(bd:BitmapData, s:Point, p:Point): void { buffer.copyPixels(bd, new Rectangle(0,0,s.x, s.y), p, null, null, true); } public function drawTransformed(bd:BitmapData, pos:Point, angle:Number, mirrored:Boolean ): void { var mat:Matrix = new Matrix(); //reset transform, set rotation between 0-90 degrees, reverse direction for opposite facing mat.identity(); mat.rotate(angle); mat.translate(pos.x, pos.y); if(mirrored == true) mat.a = mat.a * -1; buffer.draw(bd, mat); } public function drawScreen(): void { //blank screen first screen.copyPixels(new BitmapData(screenWidth, screenHeight), new Rectangle(0,0,screenWidth,screenHeight), new Point(0,0)); screen.copyPixels(buffer, new Rectangle(0,0,screenWidth,screenHeight), new Point(0,0));
} }
|
|
|
Logged
|
|
|
|
Montoli
|
|
« Reply #1 on: January 26, 2010, 06:26:37 PM » |
|
Ok, I think I see what is going wrong here:
On event listeners, they expect a particular function signature. They need to be able to accept as an argument the event that triggered them.
So instead of writing public function update():void public function render():void
you should write something like public function update(e:Event):void public function render(e:Event):void
After that, I think it will work.
Hope this helps!
|
|
|
Logged
|
|
|
|
Falmil
Level 6
|
|
« Reply #2 on: January 26, 2010, 08:41:29 PM » |
|
Ah, that was in fact the problem. Thanks. I haven't worked much with events but I DO remember the handlers taking the events as arguments, so I'm not sure why I didn't remember this time. Now I just need to figure out how to clear the screen in between draws, since my method of attempting to copy a solid white bitmap over it doesn't seem to be working.
|
|
|
Logged
|
|
|
|
lpmaurice
|
|
« Reply #3 on: January 26, 2010, 09:18:28 PM » |
|
If at the start of your render function you clear the bitmapData, you'll get the result you're looking for:
public function render():void { buffer.fillRect(new Rectangle(0, 0, yourWidth, yourHeight), 0xFFFFFFFF); ...rest of your code goes here }
|
|
|
Logged
|
|
|
|
bateleur
|
|
« Reply #4 on: January 27, 2010, 01:49:08 AM » |
|
As a bit of an aside: I strongly recommend using the ENTER_FRAME event rather than a clock event. You'll get smoother animation in almost all cases.
|
|
|
Logged
|
|
|
|
Falmil
Level 6
|
|
« Reply #5 on: January 27, 2010, 11:49:45 AM » |
|
Oh jeeze, I was trying to clear the wrong bitmap before drawing. Thanks lpmaurice.
I wasn't aware ENTER_FRAME worked for Sprite-based classes. I guess I just thought it was for MovieClips.
|
|
« Last Edit: January 27, 2010, 11:59:57 AM by Falmil »
|
Logged
|
|
|
|
Montoli
|
|
« Reply #6 on: January 27, 2010, 12:11:48 PM » |
|
I'd like to second the enter_Frame event as a heartbeat, btw. For most of the same reasons Bateleur gives.
|
|
|
Logged
|
|
|
|
jotapeh
|
|
« Reply #7 on: January 27, 2010, 05:10:56 PM » |
|
If at the start of your render function you clear the bitmapData, you'll get the result you're looking for:
public function render():void { buffer.fillRect(new Rectangle(0, 0, yourWidth, yourHeight), 0xFFFFFFFF); ...rest of your code goes here }
If I may suggest one tiny improvement to this: buffer.fillRect(buffer.rect, 0xFFFFFFFF);It's a bit clearer, adjusts automatically if you ever adjust the buffer size, and prevents creation of a new Rectangle object each time. All BitmapData classes provide a Rectangle property in this fashion.
|
|
« Last Edit: January 27, 2010, 05:16:30 PM by jotapeh »
|
Logged
|
|
|
|
basudec1509
Level 0
|
|
« Reply #8 on: January 31, 2010, 10:42:34 AM » |
|
hello guys ...
its really nice and informative post....
i just liked it....
thanks for your information guys ...........
|
|
|
Logged
|
|
|
|
|