0

我目前正在制作一个 Flash 平台游戏引擎……但我的碰撞检测需要一些认真的帮助。每当我的角色“跳跃”并降落在碰撞对象上时,他会在碰撞对象的中途停留片刻,然后回到顶部(我希望他在的位置)。如果我继续跳多次,他的影子,如果你愿意,那一瞬间出现的影子会越来越深入碰撞对象,最终让他一路跌倒。这是我的主要课程的代码,如果您需要我澄清任何事情,请询问。

package {


import flash.display.MovieClip;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.display.Stage;
import Player;
import HitObject;

public class TestGame extends MovieClip {

    private var _hitObject:HitObject; 
    private var _player:Player;
    private var _leftArrow:Boolean;
    private var _rightArrow:Boolean;
    private var _upArrow:Boolean;
    private var _hit:Boolean;
    private var _fall:Boolean;
    private var _jump:Boolean = true;
    private var _velR:Number = 0;
    private var _velL:Number = 0;
    private var _scale:Number = .1;
    private var _jumpCount:Number = 0;
    private var _i:Number = .5;
    private var _i2:Number = 7;
    private var _i3:Number = 0;
    private var _adjustHit:Number;
    private var _jumpRL:Number;
    private var _jumpVel:Number;

    public function TestGame() {
        _hitObject = new HitObject();
        _player = new Player();
        addChild(_hitObject);
        addChild(_player);
        _hitObject.x = (stage.width * 0.5) + 50;
        _hitObject.y = (stage.height * 0.5) + 150;
        _hitObject.scaleY = 3;
        _hitObject.alpha = .5;
        _player.scaleX = _scale;
        _player.scaleY = _scale;
        _player.x += 200;
        _player.y += 250;
        stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
        stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
        stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
    }

    private function enterFrameHandler(e:Event) {
        if(_player.hitTestObject(_hitObject)) {
            _adjustHit = _hitObject.y - _hitObject.height/2 - _player.height/2;
            _player.y = _adjustHit;
            _hit = true;
            _jump = false;
            if(_i3 > 8) {
            _jump = true;
            }
            _jumpCount = 0;
            _i2 = 7;
            _fall = false;
            _i3++;
        }

        else if(!_player.hitTestObject(_hitObject) && !_upArrow) {
            _fall = true;
        }


        if(_fall) {
            _player.y += _i;
            _i += .5;
            if(_i < 3) {
                _i = 3;
            }
            _hit = false;
        }
        if(_upArrow && _hit && _jump) {
            if(_velR > 0) {
                _jumpRL = _velR;
                _jumpVel = _velR;
            }
            else if(_velL > 0) {
                _jumpRL = -_velL;
                _jumpVel = _velL;
            }
            else {
                _jumpVel = 1;
                if(_player.scaleX == .1) {
                    _jumpRL = 1;
                }
                else {
                    _jumpRL = -1;
                }
            }

            _player.y -= _i2 + _jumpVel/2;
            _player.x += _jumpRL/2;
            _jumpCount += _i2;
            _i2 -= .5;
            _fall = false;
            if(_i2 < -3) {
              _jumpCount = 61;
            }
            if(_jumpCount > 60) {
                _i2 = 7;
                _jump = false;
                _fall = true;
                _jumpCount = 0;
            }
            _i3 = 0;
        }
        if(_rightArrow) {
            _player.startRun();
            _player.scaleX = _scale;
            _velL = 0;
            _player.x += _velR;
            if(_velR < 20) {
                _velR += 2;
            }
            if(_velR > 20) {
                _velR = 20;
            }  
        }

        else if(_leftArrow) {
            _player.startRun();
            _player.scaleX = -_scale;
            _velR = 0;
            _player.x -= _velL;
            if(_velL < 20) {
                _velL += 2;
            }
            if(_velL > 20) {
                _velL = 20;
            }  
        }

        if(_velR > 0) {
        _player.x += _velR;
        _velR -= .7;
        }
        else if(_velL > 0) {
        _player.x -= _velL;
        _velL -= .7;
        }
        if(_velR < 0 || _velL < 0) {
            _velR = 0;
            _velL = 0;
        }
    }

    private function keyDownHandler(e:KeyboardEvent):void {
        if(e.keyCode == 39) {
        _rightArrow = true;
        }
        if(e.keyCode == 37) {
        _leftArrow = true;
        }
        if(e.keyCode == 38) {
        _upArrow = true;
        }
    }
    private function keyUpHandler(e:KeyboardEvent):void {
        _upArrow = false;
        _rightArrow = false;
        _leftArrow = false;
    }
}

}

4

3 回答 3

3

对于遇到此问题的任何人,除了重新定位碰撞外,请确保您正在施加力以响应碰撞。这种情况听起来可能速度会受到重力的影响,这意味着您会继续将物体向后移动,但它的速度并没有被归零,因此它会随着每个更新步骤越来越远地移动到地板中。

施加法向力将取消重力并解决此问题。

于 2011-12-08T17:26:07.423 回答
2

如果您只想要易于使用的碰撞检测,请查看 Actionscript 3 的碰撞检测工具包。我以前使用过它,它胜过我用过的所有其他碰撞检测框架。

于 2009-10-17T18:10:42.550 回答
1

From what you have said it sounds like at time 't' the player has not hit the object as yet but at time 't+1' the player has moved 10px (for example) so now appears stuck in the object until your collision handler moves the player to the correct spot.

Also with the jumping up and down perhaps the player has not been moved back correctly after a collision before his position increments which is why over time the player eventually falls through if you keep jumping.

Be careful about comparing numbers. I see a if (_player.scaleX == .1). Numbers in AS3 are called Floating Point numbers in other languages. Due to the way Floating Point numbers are handled by the computer they can give misleading results. Sometimes a value like 1.0 is really 0.999998 and if thats the case a compare statement will always fail.

As a tip you might want to change some of the values to CONST as you have a lot of hardcoded values, some which are related and could be changed easier by making them a CONST.

于 2009-10-18T02:46:17.847 回答