如何通过碰撞检测添加死亡特征?

时间:2016-12-10 06:12:47

标签: java collision-detection

注意:这篇文章是从游戏开发中复制粘贴的,因为我收到评论说要在Stack Overflow上发布这个帖子)

我想要的是当我的玩家与我的Tiles(它们是固体)发生碰撞时,他们会被发送到menustate(或菜单屏幕)。我已经对我的瓷砖进行了碰撞检测(使用isSolid)。所以如何制作它,以便如果我的玩家与瓷砖碰撞(那些是实心的),它将被发送到我的menustate。

抱歉,如果我添加了不需要的类,那我的Player,Creature和Entity类就会相互扩展。

这是我的生物类,其中存在碰撞检测。

public abstract class Creatures extends Entity {

public static final int DEFAULT_HEALTH = 1;
public static final float DEFAULT_SPEED = 5.0f;
public static final int DEFAULT_CREATURE_WIDTH = 128;
public static final int DEFAULT_CREATURE_HEIGHT = 128;

protected int health;
protected float speed;
public static float xMove;
public static float yMove;
protected int MinHeight;

public Creatures(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;
    MinHeight = -1;
}

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

//COLLISION DETECTION BELOW
public void moveX(){
    if(xMove > 0){//Moving right
        int tx = (int) (x + xMove + bounds.x + bounds.width) / Tile.TILEWIDTH;

        if(!collisionWithTile(tx, (int) (y + bounds.y) / Tile.TILEHEIGHT) &&
                !collisionWithTile(tx, (int) (y + bounds.y + bounds.height) / Tile.TILEHEIGHT)){
            x += xMove;
        }else{
            x = tx * Tile.TILEWIDTH - bounds.x - bounds.width - 1;
        }

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

        if(!collisionWithTile(tx, (int) (y + bounds.y) / Tile.TILEHEIGHT) &&
                !collisionWithTile(tx, (int) (y + bounds.y + bounds.height) / Tile.TILEHEIGHT)){
            x += xMove;
        }else{
            x = tx * Tile.TILEWIDTH + Tile.TILEWIDTH - bounds.x;
        }
    }
}

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

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

    }else if(yMove > 0){//Down
        int ty = (int) (y + yMove + bounds.y + bounds.height) / Tile.TILEHEIGHT;

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

//This code below checks if the tile im colliding is Solid or not
protected boolean collisionWithTile(int x, int y){
    return handler.getWorld().getTile(x, y).isSolid();
}

//GETTERS AND SETTERS

public float getxMove() {
    return xMove;
}

@SuppressWarnings("static-access")
public void setxMove(float xMove) {
    this.xMove = xMove;
}

public float getyMove() {
    return yMove;
}

@SuppressWarnings("static-access")
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;
}

}

然后我的实体类(我的Creature类扩展到这个类)

import java.awt.Graphics;
import java.awt.Rectangle;

public abstract class Entity {

protected Handler handler;
protected float x, y;
protected int width, height;
protected Rectangle bounds;

public Entity(Handler handler, float x, float y, int width, int height){
    this.handler = handler;
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;

    bounds = new Rectangle(0, 0, width, height);
}

public abstract void tick();

public abstract void render(Graphics g);

public float getX() {
    return x;
}

public void setX(float x) {
    this.x = x;
}

public float getY() {
    return y;
}

public void setY(float y) {
    this.y = y;
}

public int getWidth() {
    return width;
}

public void setWidth(int width) {
    this.width = width;
}

public int getHeight() {
    return height;
}

public void setHeight(int height) {
    this.height = height;
}

}

我的播放器类(我的播放器类扩展到我的Creature类)

import java.awt.Graphics;
import java.awt.image.BufferedImage;

public class Player extends Creatures{

//Animations
private Animation animRight, animLeft;

public Player(Handler handler, float x, float y) {
    super(handler, x, y, Creatures.DEFAULT_CREATURE_WIDTH, Creatures.DEFAULT_CREATURE_HEIGHT);

    bounds.x = 32;
    bounds.y = 32;
    bounds.width = 92;
    bounds.height = 96;

    //Animations
    animRight = new Animation(100, Assets.DerpDino_right);
    animLeft  = new Animation(100, Assets.DerpDino_left);
}

@Override
public void tick() {

    //Animations
    animRight.tick();
    animLeft.tick();
    //Movement
    getInput();
    move();
    handler.getGameCamera().centerOnEntity(this);

}

@SuppressWarnings("unused")
private void Dead(){
   //what to put in here
}

private void getInput(){
    xMove = 6;
    //Gravity
    yMove = 6;
    MinHeight = 0;

    if(handler.getKeyManager().left)
        xMove = -speed;
    if(handler.getKeyManager().right)
        xMove = speed;
    if(handler.getKeyManager().jumping)
        //this makes my player fly
        yMove = -speed;
}

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


private BufferedImage getCurrentAnimationFrame(){
    if(xMove < 0){
        return animLeft.getCurrentFrame();
    }else{
        return animRight.getCurrentFrame();
    }
}

}

Tile Class(其中isSolid()是)

import java.awt.Graphics;
import java.awt.image.BufferedImage;

public class Tile {

//STATIC STUFF HERE

public static Tile[] tiles = new Tile[256];
public static Tile grassTile = new GrassTile(0);
public static Tile cactusTile = new CactusTile(1);
public static Tile dirtTile = new DirtTile(2);
public static Tile skyTile = new SkyTile(3);
public static Tile cloudTile = new CloudTile(4);
public static Tile caveTile = new CaveTile(5);
public static Tile stoneTile = new StoneTile(6);

//CLASS

public static final int TILEWIDTH = 128, TILEHEIGHT = 128;

protected BufferedImage texture;
protected final int id;

public Tile(BufferedImage texture, int id){
    this.texture = texture;
    this.id = id;

    tiles[id] = this;
}

public void tick(){

}

public void render(Graphics g, int x, int y){
    g.drawImage(texture, x, y, TILEWIDTH, TILEHEIGHT, null);
}

//HERE!!
public boolean isSolid(){
    return false;
}

public int getId(){
    return id;
}

}

2 个答案:

答案 0 :(得分:0)

你必须创建一个名为STATE的枚举,它将包含并处理你的游戏状态。

public enum STATE {GAME, MENU};
public STATE state = STATE.GAME;

在你的游戏循环中,你必须实现if语句。

if (state == STATE.GAME) {
    // game logic here
} else if (state == STATE.MENU) {
    // menu logic here
}

另外,不要忘记在图形中添加这些内容,当状态设置为游戏时应该呈现什么以及何时将其设置为菜单。

然后你应该打电话:

if (collisionWithTile) {
    state = STATE.MENU;
}

答案 1 :(得分:0)

得到了答案!!!我刚刚添加了State.setstate(menustate),如果我的播放器与该块发生碰撞,请在我的代码中找到 // here 。< / p>

public boolean moveX(){
    if(xMove > 0){//Moving right
        int tx = (int) (x + xMove + bounds.x + bounds.width) / Tile.TILEWIDTH;

        if(!collisionWithTile(tx, (int) (y + bounds.y) / Tile.TILEHEIGHT) &&
                !collisionWithTile(tx, (int) (y + bounds.y + bounds.height) / Tile.TILEHEIGHT)){
            x += xMove;
        }else{
            x = tx * Tile.TILEWIDTH - bounds.x - bounds.width - 1;
            State.setState(handler.getGame().menuState);//here!!!
        }

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

        if(!collisionWithTile(tx, (int) (y + bounds.y) / Tile.TILEHEIGHT) &&
                !collisionWithTile(tx, (int) (y + bounds.y + bounds.height) / Tile.TILEHEIGHT)){
            x += xMove;
        }else{
            x = tx * Tile.TILEWIDTH + Tile.TILEWIDTH - bounds.x;
            State.setState(handler.getGame().menuState);//here!!!
        }
    }
    return false;
}

public boolean moveY(){
    if(yMove < 0){//Up
        int ty = (int) (y + yMove + bounds.y) / Tile.TILEHEIGHT;

        if(!collisionWithTile((int) (x + bounds.x) / Tile.TILEWIDTH, ty) &&
                !collisionWithTile((int) (x + bounds.x + bounds.width) /     Tile.TILEWIDTH, ty)){
            y += yMove;
        }else{
            y = ty * Tile.TILEHEIGHT + Tile.TILEHEIGHT - bounds.y;
            State.setState(handler.getGame().menuState);//here!!!
        }