0

标题说了很多,我之前尝试过thread.sleep,但没有帮助。我想放慢跳跃命令,这样你就可以看到角色跳跃,现在它在眨眼之间完成。请解释如何做到这一点。我使用 slick2d java,Java 新手

谢谢你的时间!

package JavaGame;

import org.newdawn.slick.*;
import org.newdawn.slick.state.*;

public class Play extends BasicGameState{

    Animation bucky, movingUp, movingDown, movingLeft, movingRight;

    boolean quit = false;
    int[] duration = {400, 100}; //2 tenths of a second and 2 tenths of a second, both in under half a second. Series of image, how long each image lasts  
    //the array of numbers decides the length of the animation
    float buckyPositionX = 0;
    float buckyPositionY = 0;
    float shiftX = buckyPositionX + 540; //Shifting something 320, always letting bucky be in the middle of the screen
    float shiftY = buckyPositionY + 620;
    boolean jumping = false;
    double gravity = 10;
    double jumpingTime = 200;
    float v = shiftY;
    double counter2 = 4;

    public Play(int state){

    }

    public void init(GameContainer gc, StateBasedGame sbg) throws SlickException{
        Image[] walkUp = {new Image("res/buckysRight.png"), new Image("res/buckysFront.png")}; //Change to jump, add more imagines (same amount of duration as images)
        Image[] walkDown = {new Image("res/buckysFront.png"), new Image("res/buckysFront.png")}; //change last picture to the front will restore it to the front frame ending the animation
        Image[] walkLeft = {new Image("res/buckysLeft.png"), new Image("res/buckysFront.png")};
        Image[] walkRight = {new Image("res/buckysRight.png"), new Image("res/buckysFront.png")};

        //Creating the actual animation, animations defined Animation, bucky bla bla
        movingUp = new Animation(walkUp, duration, false);
        movingLeft = new Animation(walkLeft, duration, false);
        movingRight = new Animation(walkRight, duration, false);
        movingDown = new Animation(walkDown, duration, false);
        bucky = movingDown;
    }


    public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException{
        g.fillRect(buckyPositionX, buckyPositionY, 10000, 50); //Øverste boks
        g.fillRect(buckyPositionX, buckyPositionY + 660, 10000, 70); //Nederste boks
        g.fillRect(buckyPositionX, buckyPositionY + 360, 50, 300); // Bakerste Kant

        bucky.draw(shiftX, shiftY);
        boolean debug = true;

        if(debug == true){
            g.drawString("Buckys X: " + buckyPositionX + "\nBuckys y: " +buckyPositionY, 900, 50);
            g.drawString("Buckys 2 X: " + shiftX + "\nBuckys 2 y: " + shiftY, 900, 100);
        }

        if(quit == true){ //When esc is hit launch the menu.
            g.drawString("Resume (R)", 250, 100);
            g.drawString("Main Menu (M)", 250, 150);
            g.drawString("Quit (Q)", 250, 200);

            if(quit == false){
                g.clear();
            }
        }
    }


    public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException{
        Input input = gc.getInput();

        if(input.isKeyDown(Input.KEY_RIGHT)){
            bucky = movingRight;
            buckyPositionX -= .2;
        }

        if(input.isKeyDown(Input.KEY_LEFT)){
            bucky = movingLeft;
            buckyPositionX += .2;

            if(buckyPositionX > 492){
                buckyPositionX -= .2;
            }//delta * .1f
        }

        if(shiftY < 620 && jumping != true){
            shiftY += gravity;  
        }

        if(input.isKeyPressed(Input.KEY_SPACE)){
            jumping = true;

            while(jumping == true){
                counter2 += 0.0005;
                shiftY = shiftY - (int) ((Math.sin(counter2) + (Math.cos(counter2)))*20);

                if(counter2 >= 7){
                    counter2 = 4;
                    jumping = false;
                }
            }
        }

        //escape
        if(input.isKeyDown(Input.KEY_ESCAPE)){
            quit = true;
        }

        //when the menu is up
        if(quit == true){
            if(input.isKeyDown(Input.KEY_R)){
                quit = false;
            }

            if(input.isKeyDown(Input.KEY_M)){
                sbg.enterState(0);
            }

            if(input.isKeyDown(Input.KEY_Q)){
                System.exit(0);
            }
        }   
    }

    public int getID(){
        return 1;
    }       
}
4

3 回答 3

3

您应该始终根据时间进行游戏更新,因此它在所有计算机上都具有相同的速度而不会出现问题。它也解决了你的问题。

public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException

游戏容器应该有这样的东西:

gc.getTime()

这显示了上次运行经过了多少时间。如果没有这个,你可以使用

System.nanoTime()

然后您只需要一些 int 值,您可以在其中存储时间并进行一些更新,例如每 50 毫秒一次。

于 2013-10-12T16:05:19.640 回答
0

由于 Slick2D 使用 LWJGL,您会发现 LWJGL wiki 特别有用。

这对您的问题非常有用:LWJGL Basics 4: Timing

Aso,试试这个“如何快速习惯使用增量代码”

private float yRect;

@Override
public void update(GameContainer gc, int delta) throws SlickException {

    yRect += 0.03f * delta;
}

@Override
public void render(GameContainer gc, Graphics g) throws SlickException {

    g.pushTransform();
    g.translate(0, yRect);
    g.fillRect(20, 20, 200, 100);
    g.popTransform();
}

确保以合理的帧速率运行此示例...

appgamecontainer.setTargetFrameRate(60);
于 2014-02-23T13:04:09.837 回答
0

哦,你在没有渲染的情况下在一个while循环中完成所有的跳跃计算。

        while(jumping == true){
            counter2 += 0.0005;
            shiftY = shiftY - (int) ((Math.sin(counter2) + (Math.cos(counter2)))*20);

            if(counter2 >= 7){
                counter2 = 4;
                jumping = false;
            }
        }

这是不正确的。您必须在跳跃循环的每一轮中渲染图像。否则会发生跳跃计算但不会显示。

我给出这个答案希望你的主要方法是这样的。或者,如果您要覆盖其中一个类,则使用 slick 的主要方法。

init()
while(true){
    update();
    render();
    doTiming(); // Whatever the method you use for timing in the game loop.
}

所以你要做的就是在跳跃发生时放置一个标志并阻止其他动作。

public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException{

        if(jumping){    // Or jumping == true
            counter2 += 0.0005;
            shiftY = shiftY - (int) ((Math.sin(counter2) + (Math.cos(counter2)))*20);
            if(counter2 >= 7){
                counter2 = 4;
                jumping = false;
            }
        }else{
            Input input = gc.getInput();        
            if(input.isKeyDown(Input.KEY_RIGHT)){
                bucky = movingRight;
                buckyPositionX -= .2;
            }

            if(input.isKeyDown(Input.KEY_LEFT)){
                bucky = movingLeft;
                buckyPositionX += .2;

                if(buckyPositionX > 492){
                    buckyPositionX -= .2;
                }//delta * .1f
            }

            if(shiftY < 620 && jumping != true){
                shiftY += gravity;  
            }

            if(input.isKeyPressed(Input.KEY_SPACE)){
                jumping = true;
            }

            //escape
            if(input.isKeyDown(Input.KEY_ESCAPE)){
                quit = true;
            }

            //when the menu is up
            if(quit == true){
                if(input.isKeyDown(Input.KEY_R)){
                    quit = false;
                }

                if(input.isKeyDown(Input.KEY_M)){
                    sbg.enterState(0);
                }

                if(input.isKeyDown(Input.KEY_Q)){
                    System.exit(0);
                }
            }
        }       
    }

所以在每一轮跳跃循环中都会调用render方法。所以你的跳跃中的所有部分都会被显示出来。

一个建议:如果您擅长物理,请使用运动方程而不是使用 sin 和 cos 的东西来模拟跳跃。我不确定您如何更改 shiftY 进行跳转。但是,如果您使用 v=u+at等式,您可以将其视为真实世界的跳跃。

于 2014-02-24T10:12:17.677 回答