-1

这是迄今为止我在 Flash 中遇到的最奇怪的问题。我不知道是什么原因造成的。如果有人想真正看到它,我可以提供一个 .swf,但我会尽我所能描述它。

我正在为坦克物体制造子弹以射击。坦克是文档类的孩子。我创建子弹的方式是:

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

子弹本身只是使用如下代码向一个方向移动this.x += 5;

问题是子弹会在正确的时间追踪它们的创建和销毁,但是子弹有时直到屏幕的一半才可见,有时根本不可见,有时在整个遍历过程中。奇怪地删除了我在创建子弹时的计时器似乎可以解决这个问题。

定时器是这样实现的:

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

我的坦克对象的输入帧处理程序控制计时器,如果它大于零,则每帧递减它。

谁能建议为什么会发生这种情况?

编辑:根据要求,完整代码:

子弹头文件

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;
        }
    }
}

}

坦克.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;
    }

}

}

如果有人想尝试复制错误,完整的应用程序就在这里。它对部分内容使用了电子服务器,因此可能必须将它们注释掉。

坦克攻击.rar

4

3 回答 3

0

这些行正确吗?

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

,

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

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

我只是想确保我读的是正确的。

于 2010-05-26T17:19:04.347 回答
0

我认为这个问题的答案非常简单,我曾多次遇到过这种情况(CS4)。检查你的时间......通常有一个额外的不需要的空帧。这是如何发生的对我来说仍然是一个谜,但它通常是罪魁祸首……不经意间击中了某个键。

于 2014-01-19T07:10:17.867 回答
0

将方法添加stop();到项目符号中。有时,当影片剪辑重复时,它会闪烁。

于 2014-03-02T23:49:42.010 回答