gpt4 book ai didi

java - 我应该如何在这个 2d Java 游戏中实现跳跃/重力/坠落

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:39:42 24 4
gpt4 key购买 nike

这是我的 Player 类(我想在空格键上跳转的对象),我只是不知道从哪里开始,是否有任何我可以在互联网上阅读的相关资源大部头书?任何帮助都很棒,谢谢。

package com.zetcode;
import java.awt.Color;
import java.awt.Graphics;

public class Player extends Creature {

private boolean jumping = false;
private Creature creature;

public Player(Handler handler, float x, float y) {
super(handler, x, y, Creature.PLAYER_WIDTH, Creature.PLAYER_HEIGHT);

bounds.x = 16;
bounds.y = 31;
bounds.width = 40;
bounds.height = 58;
}

@Override
public void tick() {
getInput();
move();
handler.getGameCamera().centerOnEntity(this);
}

private void getInput(){
xMove = 0;
yMove = 3;
gravity = 2;

if(handler.getKeyManager().jump)
yMove = -speed;
if(handler.getKeyManager().down)
yMove = speed;
if(handler.getKeyManager().left)
xMove = -speed;
if(handler.getKeyManager().right)
xMove = speed;
}

@Override
public void render(Graphics g) {
g.drawImage(Assets.player, (int) (x - handler.getGameCamera().getxOffset()), (int) (y - handler.getGameCamera().getyOffset()), width, height, null);
}
}

这是我的 KeyManager 类:

package com.zetcode;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class KeyManager implements KeyListener{

private boolean[] keys;
public boolean up, down, left, right, jump;

public KeyManager(){
keys = new boolean[256];
}

public void tick(){
down = keys[KeyEvent.VK_S];
left = keys[KeyEvent.VK_A];
right = keys[KeyEvent.VK_D];
jump = keys[KeyEvent.VK_SPACE];
}

@Override
public void keyPressed(KeyEvent e) {
keys[e.getKeyCode()] = true;
System.out.println("A Key was pressed");
}

@Override
public void keyReleased(KeyEvent e) {
keys[e.getKeyCode()] = false;
}

@Override
public void keyTyped(KeyEvent e) {

}
}

我一直在努力实现一种让我的角色跳跃的方式,目前玩家在按下空格键时沿 Y 轴向上移动,但我可以按住该键并无限跳跃。

我将添加具有碰撞检测功能的 Creature 类:

package com.zetcode;

public abstract class Creature extends Entity {

public static final int DEFAULT_HEALTH = 10;
public static final float DEFAULT_SPEED = 3.0f;
public static final int DEFAULT_CREATURE_WIDTH = 64,
DEFAULT_CREATURE_HEIGHT = 64;
public static final int PLAYER_HEIGHT = 90, PLAYER_WIDTH = 64;

protected int health;
protected float speed;
protected float xMove, yMove;
protected float gravity;

public boolean falling = true;
private boolean jumping = false;

public Creature(Handler handler, float x, float y, int width, int height) {
super(handler, x, y, width, height);
health = DEFAULT_HEALTH;
speed = DEFAULT_SPEED;
xMove = 0;
yMove = 0;
gravity = 0;
}

//collision detection

public void move(){
moveX();
moveY();
}

public void moveX(){
if(xMove > 0){//move right
int tx = (int) (x + xMove + bounds.x + bounds.width) / Tile.TILE_WIDTH;

if(!collisionWithTile(tx, (int) (y + bounds.y) / Tile.TILE_HEIGHT) && //check top right corner of hitbox
!collisionWithTile(tx, (int) (y + bounds.y + bounds.height) / Tile.TILE_HEIGHT)){ //check bottom right corner of hitbox
x += xMove;
}else{
x = tx * Tile.TILE_WIDTH - bounds.x - bounds.width - 1;
}

}else if(xMove < 0){//move left
int tx = (int) (x + xMove + bounds.x) / Tile.TILE_WIDTH;

if(!collisionWithTile(tx, (int) (y + bounds.y) / Tile.TILE_HEIGHT) && //check top left corner of hitbox
!collisionWithTile(tx, (int) (y + bounds.y + bounds.height) / Tile.TILE_HEIGHT)){ //check bottom left corner of hitbox
x += xMove;
}else{
x = tx * Tile.TILE_WIDTH + Tile.TILE_WIDTH - bounds.x;
}
}
}

public void moveY(){
if(yMove < 0){//up
int ty = (int) (y+ yMove + bounds.y) / Tile.TILE_HEIGHT;

if(!collisionWithTile((int) (x + bounds.x) / Tile.TILE_WIDTH, ty) &&
!collisionWithTile((int) (x + bounds.x + bounds.width) / Tile.TILE_WIDTH,ty)){
y += yMove;
}else{
y = ty * Tile.TILE_HEIGHT + Tile.TILE_HEIGHT - bounds.y;
}

}else if(yMove > 0){//down
int ty = (int) (y+ yMove + bounds.y + bounds.getHeight()) / Tile.TILE_HEIGHT;

if(!collisionWithTile((int) (x + bounds.x) / Tile.TILE_WIDTH,ty) &&
!collisionWithTile((int) (x + bounds.x + bounds.width) / Tile.TILE_WIDTH,ty)){
y += yMove;
}else{
y = ty * Tile.TILE_HEIGHT - bounds.y - bounds.height -1;
}
}
}

protected boolean collisionWithTile(int x, int y){
return handler.getWorld().getTile(x, y).isSolid();
}

//getters and setters

public float getxMove() {
return xMove;
}

public void setxMove(float xMove) {
this.xMove = xMove;
}

public float getyMove() {
return yMove;
}

public void setyMove(float yMove) {
this.yMove = yMove;
}

public int getHealth() {
return health;
}

public void setHealth(int health) {
this.health = health;
}

public float getSpeed() {
return speed;
}

public void setSpeed(float speed) {
this.speed = speed;
}
}

最佳答案

您要做的是为场景中的对象实现速度加速度重力。速度是一个二维 vector ,它告诉您物体移动的速度有多快,而加速度则告诉您速度增加了多少

所有对象都应该有一个 update() 方法,该方法会定期调用。它会将物体的速度应用到它的位置(这就是速度和位置无论如何相关的方式)并且当你想要加速一个物体时,你基本上只会增加它的速度。在 update() 方法中,我们还应用了重力(以负 Y 加速度的形式)

您还可以利用摩擦力。摩擦可确保您的物体在朝特定方向移动时减速。

在这个简单的模拟中,随着值接近 1,摩擦变弱。这意味着在 FRICTION==1 时您没有摩擦,在 FRICTION==0 时您的物体将立即停止。

public class PhysicsObject {
public static final double FRICTION = 0.99;
public static final double GRAVITY = 0.01;
private double posX;
private double posY;
private double speedX = 0;
private double speedY = 0;

public PhysicsObject(double posX, double posY) {
this.posX = posX;
this.posY = posY;
}

public void accelerate(double accelerationX, double accelerationY) {
speedX += accelerationX;
speedY += accelerationY;
}

public void move(double xDelta, double yDelta) {
posX += xDelta;
posY += yDelta;
// do collision detection here. upon collision, set speedX/speedY to zero..!
}

public void update() {
move(speedX, speedY);
speedX *= FRICTION;
speedY *= FRICTION;
accelerate(0, -GRAVITY); // gravity accelerates the object downwards each tick
}

public double getPosX() {
return posX;
}

public double getPosY() {
return posY;
}
}

您还可以使用 update() 来处理碰撞检测(应该将速度设置为零)并且敌人可以执行他们的 AI 逻辑..

Player 类可以扩展此 PhysicsObject 并具有方法 jump()runLeft()runRight(),可能如下所示:

public class Player extends PhysicsObject{
public static final double JUMP_STRENGTH = 5;
public static final double SPEED = 1;
public void jump() {
accelerate(0, JUMP_STRENGTH); // change 5 for some constant or variable indicating the "strength" of the jump
}

public void runRight() {
move(SPEED, 0);
}

public void runLeft() {
move(-SPEED, 0);
}
}

碰撞检测本身就是一件大事,在这里涵盖太多,但是 this video描述得很好。去看看吧!

关于java - 我应该如何在这个 2d Java 游戏中实现跳跃/重力/坠落,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35478428/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com