还记得玩超级马里奥兄弟吗?当马里奥移动时,他跑,然后当玩家停止移动时,他停下来,但他没有完全停下来。他滑了一下。我需要做到这一点。在过去的两天里,我一直在完全改写我的Mario克隆/平台游戏的运动,因为我之前的模型效率低下而且总体上很糟糕。现在,我不知道如何继续这么小的速度,以便停止不是那么突然。我怎么做到这一点?以下所有移动代码都在Player
类中,控件代码在Main
类中。那么我该怎么办才能检测到玩家何时停止,并使用它来增加一点速度呢?
主:
import com.hasherr.platformer.entity.Player;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import static org.lwjgl.opengl.GL11.*;
public class Main {
private void display() {
try {
Display.setDisplayMode(new DisplayMode(1000, 550));
Display.setTitle("Unnamed Platformer Game");
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
System.exit(0);
}
// OpenGL
while (!Display.isCloseRequested()) {
Display.update();
Display.sync(60); // sync to 60 fps
initGL();
player.update();
handleKeyboardInput();
}
Display.destroy();
}
private boolean keyboardInUse() {
boolean keyboardInUse;
if (!(Keyboard.isKeyDown(Keyboard.KEY_A)
|| Keyboard.isKeyDown(Keyboard.KEY_D) || Keyboard
.isKeyDown(Keyboard.KEY_SPACE))) {
keyboardInUse = false;
} else {
keyboardInUse = true;
}
return keyboardInUse;
}
private void handleKeyboardInput() {
if (!keyboardInUse()) {
player.goingLeft = false;
player.goingRight = false;
player.resetVelocity();
}
if (Keyboard.isKeyDown(Keyboard.KEY_D)) {
player.goingLeft = false;
player.goingRight = true;
player.moveRight();
} else if (Keyboard.isKeyDown(Keyboard.KEY_A)) {
player.goingLeft = true;
player.goingRight = false;
player.moveLeft();
} else if (Keyboard.isKeyDown(Keyboard.KEY_SPACE)) {
player.jump();
}
}
private void initGL() {
// initial OpenGL items for 2D rendering
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glOrtho(0, 1000, 0, 550, 1, -1);
// start rendering player image
player.grabTexture().bind();
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex2f(player.xPos, player.yPos);
glTexCoord2f(1, 0);
glVertex2f(player.xPos + 150, player.yPos);
glTexCoord2f(1, 1);
glVertex2f(player.xPos + 150, player.yPos + 150);
glTexCoord2f(0, 1);
glVertex2f(player.xPos, player.yPos + 150);
glEnd(); // stop rendering this image
}
Player player = new Player();
public static void main(String[] args) {
Main main = new Main();
main.display();
}
}
玩家:
import java.io.IOException;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
import org.newdawn.slick.util.ResourceLoader;
public class Player {
public Texture playerTexture;
// Positions & speed
public float xPos = 20.0f; // This is initial
public float yPos = 0.0f; // Same as above.
public float xVel, yVel;
public static int gravityForce = 6;
public static int jumpVelocity = 100;
private float moveSpeed = 8.0f;
private static int MAX_MOVE_SPEED = 25;
public boolean isSupported = true; // Once again, initial value.
public boolean goingRight, goingLeft, canJump;
// movement methods & constants
public void update() {
applyGravity();
checkForSupport();
}
public Texture grabTexture() {
try {
playerTexture = TextureLoader.getTexture("PNG",
ResourceLoader.getResourceAsStream("res/test_char.png"));
} catch (IOException e) {
e.printStackTrace();
}
return playerTexture;
}
private void checkForSupport() {
if (yPos == 0) {
isSupported = true;
} else if (yPos > 0 /* and is not on a platform */) {
isSupported = false;
}
}
private void applyGravity() {
if (!isSupported) {
yPos -= gravityForce;
}
}
public void printPos(String moveMethod) {
System.out.println(" X: " + xPos + " Y: " + yPos + " Going Right: "
+ goingRight + " Going Left: " + goingLeft);
}
// movement methods
public void resetVelocity() {
moveSpeed = 15;
}
private void accelerateX() {
moveSpeed += (float) (moveSpeed * 0.0096);
if (moveSpeed >= MAX_MOVE_SPEED) {
moveSpeed = MAX_MOVE_SPEED;
}
System.out.println(moveSpeed);
}
private void accelerateY() {
}
public void moveRight() {
printPos("Moving Right!");
accelerateX();
xPos += moveSpeed;
}
public void moveLeft() {
printPos("Moving Left!");
accelerateX();
xPos -= moveSpeed;
}
public void jump() {
printPos("Jumping!");
accelerateY();
yPos += jumpVelocity;
}
}
答案 0 :(得分:3)
每次更新都会降低马里奥的速度,并以速度移动马里奥的位置。
你应该允许他的速度持续多个更新。目前,当按下左箭头键或右箭头键时,您只能移动马里奥。这是一种很好的方法,适用于某些游戏,但现在您需要更多的物理行为,因此需要一种新的方法。是时候节约一些能量了!
请改为尝试:
float acceleration = 15;
private void accelerateX(float speed) {
moveSpeed += (float) (speed * 0.0096);
if (moveSpeed >= MAX_MOVE_SPEED) {
moveSpeed = MAX_MOVE_SPEED;
}else if(moveSpeed<=-MAX_MOVE_SPEED){ moveSpeed= - MAX_MOVE_SPEED;}
}
public void moveRight() {
printPos("Moving Right!");
accelerateX(acceleration);
}
public void moveLeft() {
printPos("Moving Left!");
accelerateX(-acceleration);
}
//call this every update.
public void update(){
float minMoveSpeed = 1;
//snap to zero movement if movespeed is too slow.
//this is so the player actually stops moving eventually. otherwise
//the dampening affect would constantly shift the player to and fro.
if(this.moveSpeed<minMoveSpeed && this.moveSpeed>-minMoveSpeed){
this.moveSpeed = 0;
}
else{
float dampening = 1f;
//Counter velocity. this will bring mario to a halt over a number of updates
//play with the value of dampening to get right effect.
double sign = -(int)Math.signum(moveSpeed);
float dampeningValue = dampening*sign;
this.moveSpeed += dampeningValue;
}
xPos+= this.moveSpeed;
}
此代码允许他的速度在更新中持续存在,如果速度没有按moveRight
/ moveLeft
递增/递减,则减速会使Mario停止。
此外,你应该按时间缩放你的速度,以便游戏在不同的硬件上运行类似。在发展的这一点上,这一点不太重要;请记住未来。