-1

This is the strangest problem I've faced in flash so far. I have no idea what's causing it. I can provide a .swf if someone wants to actually see it, but I'll describe it as best I can.

I'm creating bullets for a tank object to shoot. The tank is a child of the document class. The way I am creating the bullet is:

var bullet:Bullet = new Bullet();
(parent as MovieClip).addChild(bullet);

The bullet itself simply moves itself in a direction using code like this.x += 5;

The problem is the bullets will trace for their creation and destruction at the correct times, however the bullet is sometimes not visible until half way across the screen, sometimes not at all, and sometimes for the whole traversal. Oddly removing the timer I have on bullet creation seems to solve this.

The timer is implemented as such:

if(shot_timer == 0) {
shoot(); // This contains the aforementioned bullet creation method
shot_timer = 10;

My enter frame handler for the tank object controls the timer and decrements it every frame if it is greater than zero.

Can anyone suggest why this could be happening?

EDIT: As requested, full code:

Bullet.as

package {

import flash.display.MovieClip;
import flash.events.Event;

public class Bullet extends MovieClip {

    public var facing:int;
    private var speed:int;

    public function Bullet():void {
        trace("created");
        speed = 10;
        addEventListener(Event.ADDED_TO_STAGE,addedHandler);
    }

    private function addedHandler(e:Event):void {
        addEventListener(Event.ENTER_FRAME,enterFrameHandler);
        removeEventListener(Event.ADDED_TO_STAGE,addedHandler);
    }

    private function enterFrameHandler(e:Event):void {
        //0 - up, 1 - left, 2 - down, 3 - right
        if(this.x > 720 || this.x < 0 || this.y < 0 || this.y > 480) {
            removeEventListener(Event.ENTER_FRAME,enterFrameHandler);
            trace("destroyed");
            (parent as MovieClip).removeChild(this);
            return;
        }

        switch(facing) {
            case 0: this.y -= speed; break;
            case 1: this.x -= speed; break;
            case 2: this.y += speed; break;
            case 3: this.x += speed; break;
        }
    }
}

}

Tank.as:

package {

import flash.display.MovieClip;
import flash.events.KeyboardEvent;
import flash.events.Event;
import flash.ui.Keyboard;

public class Tank extends MovieClip {

    private var right:Boolean = false;
    private var left:Boolean = false;
    private var up:Boolean = false;
    private var down:Boolean = false;
    private var facing:int = 0; //0 - up, 1 - left, 2 - down, 3 - right
    private var horAllowed:Boolean = true;
    private var vertAllowed:Boolean = true;
    private const GRID_SIZE:int = 100;
    private var shooting:Boolean = false;
    private var shot_timer:int = 0;

    private var speed:int = 2;

    public function Tank():void {
        addEventListener(Event.ADDED_TO_STAGE,stageAddHandler);
        addEventListener(Event.ENTER_FRAME, enterFrameHandler);
    }

    private function stageAddHandler(e:Event):void {
        stage.addEventListener(KeyboardEvent.KEY_DOWN,checkKeys);
        stage.addEventListener(KeyboardEvent.KEY_UP,keyUps);
        removeEventListener(Event.ADDED_TO_STAGE,stageAddHandler);
    }

    public function checkKeys(event:KeyboardEvent):void {
        if(event.keyCode == 32) {
            //trace("Spacebar is down");
            shooting = true;
        }
        if(event.keyCode == 39) {
            //trace("Right key is down");
            right = true;
        }
        if(event.keyCode == 38) {
            //trace("Up key is down");  // lol
            up = true;
        }
        if(event.keyCode == 37) {
            //trace("Left key is down");
            left = true;
        }
        if(event.keyCode == 40) {
            //trace("Down key is down");
            down = true;
        }
    }

    public function keyUps(event:KeyboardEvent):void {
        if(event.keyCode == 32) {
            event.keyCode = 0;
            shooting = false;
            //trace("Spacebar is not down");
        }
        if(event.keyCode == 39) {
            event.keyCode = 0;
            right = false;
            //trace("Right key is not down");
        }
        if(event.keyCode == 38) {
            event.keyCode = 0;
            up = false;
            //trace("Up key is not down");
        }
        if(event.keyCode == 37) {
            event.keyCode = 0;
            left = false;
            //trace("Left key is not down");
        }
        if(event.keyCode == 40) {
            event.keyCode = 0;
            down = false;
            //trace("Down key is not down") // O.o
        }
    }

    public function checkDirectionPermissions(): void {
        if(this.y % GRID_SIZE < 5 || GRID_SIZE - this.y % GRID_SIZE < 5) {
            horAllowed = true;
        } else {
            horAllowed = false;
        }
        if(this.x % GRID_SIZE < 5 || GRID_SIZE - this.x % GRID_SIZE < 5) {
            vertAllowed = true;
        } else {
            vertAllowed = false;
        }

        if(!horAllowed && !vertAllowed) {
            realign();
        }
    }

    public function realign():void {
        if(!horAllowed) {
            if(this.x % GRID_SIZE < GRID_SIZE / 2) {
                this.x -= this.x % GRID_SIZE;
            } else {
                this.x += (GRID_SIZE - this.x % GRID_SIZE);
            }   
        }
        if(!vertAllowed) {
            if(this.y % GRID_SIZE < GRID_SIZE / 2) {
                this.y -= this.y % GRID_SIZE;
            } else {
                this.y += (GRID_SIZE - this.y % GRID_SIZE);
            }
        }
    }

    public function enterFrameHandler(Event):void {
        //trace(shot_timer);
        if(shot_timer > 0) {
            shot_timer--;
        }
        movement();
        firing();
    }

    public function firing():void {
        if(shooting) {
            if(shot_timer == 0) {
                shoot();
                shot_timer = 10;
            }
        }
    }

    public function shoot():void {
        var bullet = new Bullet();
        bullet.facing = facing;
        //0 - up, 1 - left, 2 - down, 3 - right
        switch(facing) {
            case 0: bullet.x = this.x; bullet.y = this.y - this.height / 2; break;
            case 1: bullet.x = this.x - this.width / 2; bullet.y = this.y; break;
            case 2: bullet.x = this.x; bullet.y = this.y + this.height / 2; break;
            case 3: bullet.x = this.x + this.width / 2; bullet.y = this.y; break;
        }
        (parent as MovieClip).addChild(bullet);
    }

    public function movement():void {
        //0 - up, 1 - left, 2 - down, 3 - right

        checkDirectionPermissions();

        if(horAllowed) {
            if(right) {
                orient(3);
                realign();
                this.x += speed;
            }
            if(left) {
                orient(1);
                realign();
                this.x -= speed;
            }
        }
        if(vertAllowed) {
            if(up) {
                orient(0);
                realign();
                this.y -= speed;
            }
            if(down) {
                orient(2);
                realign();
                this.y += speed;
            }
        }
    }

    public function orient(dest:int):void {
        //trace("facing: " + facing);
        //trace("dest: " + dest);
        var angle = facing - dest;
        this.rotation += (90 * angle);
        facing = dest;
    }

}

}

The complete application is here if someone wants to attempt to replicate the error. It uses electroserver for parts of it so they may have to be commented out.

TankAttack.rar

vimuth
  • 5,064
  • 33
  • 79
  • 116
Ben
  • 107
  • 1
  • 12
  • I think you'll need to post the full code. There isn't much of anything arcane to trip over for stuff like this, so I think it's more likely to be a kick-yourself kind of issue. – fenomas May 26 '10 at 15:36
  • The link takes you to a page with the following message: "The file link that you requested is not valid. Please contact link publisher or try to make a search". – Taurayi Jan 31 '11 at 03:13

3 Answers3

0

I think the answer to this is really simple, I had this happen to me a number of times (CS4). Check your timelime... there's usually an extra unwanted empty frame. How this happens is still a bit of a mystery to me, but it's usually the culprit... from hitting some key inadvertently.

0

Add the method stop(); to the bullet. Sometimes it flickers when the movie clip repeats.

Marvin
  • 229
  • 1
  • 3
  • 11
user2956947
  • 239
  • 1
  • 2
  • 12
0

Are these lines correct ?

public function enterFrameHandler(Event):void { //Instead of e:Event

,

var bullet = new Bullet(); // Instead of var bullet:Bullet

And

var angle = facing - dest; // Instead of var angle:int

I just want to make sure I am reading this right.

phwd
  • 19,975
  • 5
  • 50
  • 78
  • I believe so. enterFrameHandler does not need an actual event to function, and forcing types onto variables while good practice, is unnecessary. Anyone else can confirm me on this? – Ben May 26 '10 at 17:26
  • Alright well I kept it untouched. Gave it a run and was able to get creation and destruction of the Bullet with the timer. Tried multiple shots (which are limited by the timer), and it worked as well. The only place I could see it disappearing is the bounds. Sorry I could not recreate your problem :( – phwd May 26 '10 at 18:08
  • ok thanks for trying :) perhaps it's just my machine. Uploaded full source if someone desires to run it. – Ben May 26 '10 at 19:08