角色重力 java,我应该如何在此2d Java游戏中实现跳跃/重力/下落

So Here's my Player class (The object I would like to jump on spacebar), I just don't know where to begin, are there any good resources I can read on the internet that relates to me? Any help is great, thank-you.

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);

}

}

And here is my KeyManager class:

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) {

}

}

I have been struggling to implement a way for my character to jump, currently the player moves up the Y axis on spacebar press but I can hold the key down and jump endlessly.

I'll add my Creature class which has my collision detection:

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;

}

}

解决方案

What you want to do, is implement speed, acceleration and gravity for the objects on your scene. Speed is a 2D vector, which tells you how fast something moves, while acceleration tells you how much the speed increases.

All objects should have an update() method, which is called periodically. It will apply the speed of the object to it's position (that's how speed and position are related anyways) and when you want to accelerate an object, you will basically just increase its speed. In the update() method we also apply gravity (in form of negative Y acceleration)

You can also make use of friction. Friction makes sure that your objects will slow down, as they move into a certain direction.

In this simple simulation, friction gets weaker, as the value approaches 1. That means at FRICTION==1 you have no friction and at FRICTION==0 your objects will stop immediately.

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;

}

}

You can also use update() to process collision detection (which should set speed to zero) and enemies could do their AI logic..

You class Player could extend this PhysicsObject and have the methods jump(), runLeft() and runRight(), which could look like this:

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);

}

}

Collision detection is a huge thing on it's own and it would be too much to cover here, but this video describes it very well. Go check it out!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值