角色跳跃但没有回到地面平台游戏AS3

时间:2017-07-18 19:49:20

标签: actionscript-3 flash animation game-physics

我正在制作一个平台游戏,其中主角左右移动并跳跃然而我的角色跳跃并且不会返回地面而是停留在舞台的顶部。我的角色电影剪辑符号被称为'鸣'我的地面符号被称为“地面”。

这是我的代码:

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

naruto.gotoAndStop("stance");
var rightPressed:Boolean = new Boolean(false);
var leftPressed:Boolean = new Boolean(false);
var upPressed:Boolean = new Boolean(false);
var downPressed:Boolean = new Boolean(false);
var narutoSpeed:Number = 10;
stage.addEventListener(KeyboardEvent.KEY_DOWN,keyDownHandler);
stage.addEventListener(KeyboardEvent.KEY_UP,keyUpHandler);
stage.addEventListener(Event.ENTER_FRAME,gameLoop);


function keyDownHandler(keyEvent:KeyboardEvent):void
{
    if (keyEvent.keyCode == Keyboard.RIGHT)
    {
    rightPressed = true;    
    }
    else if(keyEvent.keyCode == Keyboard.LEFT)
    {
    leftPressed = true;
    }
    else if(keyEvent.keyCode == Keyboard.UP)
    {
    upPressed = true;
    }else if(keyEvent.keyCode == Keyboard.DOWN)
    {
    downPressed = true;
    }

}
function keyUpHandler(keyEvent:KeyboardEvent):void
{
    if (keyEvent.keyCode == Keyboard.RIGHT)
    {
    rightPressed = false;
        naruto.gotoAndStop("standright")
    }
    else if(keyEvent.keyCode == Keyboard.LEFT)
    {
    leftPressed = false;
    naruto.gotoAndStop("standleft") 
    }
    else if(keyEvent.keyCode == Keyboard.UP)
    {
    upPressed = false;
    naruto.gotoAndStop("stance")    
    }else if(keyEvent.keyCode == Keyboard.DOWN)
    {
    downPressed = false;
    naruto.gotoAndStop("stance")    
    }

}

function gameLoop(loopEvent: Event): void {
    //If the right key is pressed, and the left key is NOT pressed
    if (rightPressed && !leftPressed) {
        naruto.x += narutoSpeed;
        naruto.gotoAndStop("right");
    }

    if(leftPressed && !rightPressed) {
        naruto.x -= narutoSpeed;
        naruto.gotoAndStop("left");

    }
var jumpHeight =0;
var defaultJumpSpeed = 20;
var jumpSpeed = 20;




if(upPressed && naruto.hitTestObject(ground))
{
    trace("HELLO!");
naruto.y -= jumpSpeed;
jumpSpeed-= 4;
}


if(upPressed)
{
    trace("HELLO!");
jumpHeight++;
naruto.y -= jumpSpeed;
if(jumpHeight>10)
jumpSpeed -= 4;
}


if(naruto.hitTestObject(ground))
{
    trace("HELLO!");
jumpHeight =0;
jumpSpeed = defaultJumpSpeed;
}
    }

以下是我工作的链接:https://www.mediafire.com/?8d5opy49fuqmup5

问题在于:

enter image description here

1 个答案:

答案 0 :(得分:0)

主要问题是,在您当前的代码中,玩家只能在3个位置:

  1. 无论地面位置如何
  2. 16(按下并且角色没有接触地面
  3. 12(按下并且角色接触地面)
  4. 请参阅原始代码旁边的代码注释,以解释发生的情况:

    //you have this var inside the game loop, so every loop it resets to 20
    var jumpSpeed = 20;
    
    //so here, if up is pressed and the character is touching the ground
    //you initiate a jump
    if(upPressed && naruto.hitTestObject(ground))
    {
        trace("HELLO!");
        naruto.y -= jumpSpeed;
        jumpSpeed-= 4;  //since you reset jumpSpeed to 20 every loop, this value will always just be 16
    }
    
    
    if(upPressed)
    {
        trace("HELLO!");
        jumpHeight++;
    
        //if naruto is touching the ground
        //you are subtracting jumpSpeed above and right here again. 
        //so now the y position is 12 if touching the ground (or 16 if not touching the ground)
        //since you reset jumpSpeed to 20 every loop, it always be one of those two values
        naruto.y -= jumpSpeed; 
    
    
        if(jumpHeight>10)
        jumpSpeed -= 4;  //this serves no purpose, as your not using the value again and it gets reset to 20 next time the game loop runs
    }
    
    //this hit test will succeed in addition to the first one above when your jump starts.
    if(naruto.hitTestObject(ground))
    {
        trace("HELLO!");
        jumpHeight =0;
        jumpSpeed = defaultJumpSpeed;
    }
    

    为了弥补你的跳跃,你需要做一些事情:

    //initialize these vars outside of the game-loop for efficient and proper scoping (so their values don't reset every frame)
    var isJumping:Boolean = false; //a flag to know if a jump is in progress
    var jumpSpeed:Number = 0; //the current velocity of the jump
    var defaultJumpSpeed:Number = 20; //the initial force (speed) of a jump
    var jumpGravity:Number = 2; //subtract this from the speed every frame to slow the jump over time and fall
    var onGround:Boolean = false; //a helper var for efficiency
    
    function gameLoop(loopEvent: Event): void {
        //If the right key is pressed, and the left key is NOT pressed
        if (rightPressed && !leftPressed) {
            naruto.x += narutoSpeed;
            naruto.gotoAndStop("right");
        }
    
        if (leftPressed && !rightPressed) {
            naruto.x -= narutoSpeed;
            naruto.gotoAndStop("left");
    
        }
    
        //only do the hit test once per frame for efficiency (store the result)
        onGround = naruto.hitTestObject(ground);
    
        if (upPressed && onGround) {
            trace("START JUMP");
            isJumping = true;
            jumpSpeed = defaultJumpSpeed; //set the initial jump velocity
        }
    
        if(isJumping){ //if jumping
            naruto.y -= jumpSpeed; //move the player based off the current jump velocity
            jumpSpeed -= jumpGravity; //slow the jump every frame (eventually causing it to be negative making the player fall)
        }   
    
        //touching the ground and the up key is not pressed
        //it's very important to put !upPressed so this doesn't run at the time as the initial jump above
        if (!upPressed && onGround) {
            //stop any jump motion
            jumpSpeed = 0;
            isJumping = false;
    
            //you probably also want to snap the player to the ground
            naruto.y = ground.y - naruto.height + 2; //the plus 2 ensures that the ground and the player touch so the hit test succeeds
        }
    }