0

我有两个实体,一个玩家和一个块。玩家和方块都是正方形。我希望玩家在遇到障碍物时停止移动。我已经完成了一些代码,但它只适用于水平,我想知道是否可以向它添加垂直碰撞部分,使用我现有的代码。

我需要水平和垂直碰撞,因为我需要知道玩家击球的方式以及在哪一侧。这将帮助我确定在碰撞到块时是否应该停止 X 或 Y 速度。

我已经对这个主题进行了大量研究,但没有什么真正简单的,也没有用 Slick2d 的 Rectangle 对象很好地解释。如果您使用过 Slick;s Shape 类,您已经知道它有一个 .intersect(Shape s) 方法。我已经在我的代码中使用它来查看是否有必要检查它碰撞到哪一侧并停止播放器。

这是我认为相对而言的课程(如果您需要其他课程,请询问)。

实体:

import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.geom.Shape;
import org.newdawn.slick.state.StateBasedGame;

public abstract class Entity {

    private Shape shape;
    private float velX = 0f, velY = 0f;

    public Entity(Shape shape){
        this.shape = shape;
    }

    //Get Methods
    public Shape getShape(){ return shape; }
    public float getVelocityX(){ return velX; }
    public float getVelocityY(){ return velY; }

    //Set Methods
    public void setVelocityX(float velX){ this.velX = velX; }
    public void setVelocityY(float velY){ this.velY = velY; }

    protected abstract void onUpdate(GameContainer gc, StateBasedGame sbg, int d) throws SlickException;
    protected abstract void onRender(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException;

    public void update(GameContainer gc, StateBasedGame sbg, int d) throws SlickException {
        //Use velocity to change x and y.
        this.shape.setX(shape.getX() + (velX * (float)d));
        this.shape.setY(shape.getY() + (velY * (float)d));

        onUpdate(gc, sbg, d);
    }

    public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException {
        onRender(gc, sbg, g);
    }

}

世界实体:

import org.newdawn.slick.geom.Shape;

public abstract class WorldEntity extends Entity{

    private World world;

    public WorldEntity(World world, Shape shape) {
        super(shape);
        this.world = world;
    }

    //Get Methods
    public World getWorld(){ return world; }

    public abstract boolean collidedWithEntity(Entity e);
    public abstract void remove();

}

堵塞:

import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.geom.Rectangle;
import org.newdawn.slick.state.StateBasedGame;

public class Block extends WorldEntity{

    private BlockType type;

    public Block(World world, float x, float y, BlockType type) {
        super(world, new Rectangle(x, y, 48, 48));
        this.type = type;
    }

    //Get Methods
    public Color getColor(){ return type.getColor(); }
    public Image getTexture(){ return type.getTexture(); }
    public boolean isSolid(){ return type.isSolid(); }
    public BlockType getType(){ return type; }

    @Override
    public boolean collidedWithEntity(Entity e) {
        return false;
    }

    @Override
    protected void onUpdate(GameContainer gc, StateBasedGame sbg, int d) throws SlickException {

    }

    @Override
    protected void onRender(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException {
        if(type.getTexture() != null){
            if(type.getColor() != null){
                g.drawImage(type.getTexture(), getShape().getX(), getShape().getX(), type.getColor());
            }
            else{
                g.drawImage(type.getTexture(), getShape().getX(), getShape().getX());
            }
        }
        else{
            g.setColor(type.getColor());
            g.fill(getShape());
        }
    }

    @Override
    public void remove() {
        getWorld().getBlocks().remove(this);
    }

}

玩家:

import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.geom.Rectangle;
import org.newdawn.slick.geom.Shape;
import org.newdawn.slick.state.StateBasedGame;

import us.chrisix.coloroid.world.Block;
import us.chrisix.coloroid.world.Entity;
import us.chrisix.coloroid.world.World;
import us.chrisix.coloroid.world.WorldEntity;

public class Player extends WorldEntity{

    private Color c;
    private float speed = 0.3f;

    public Player(World world, float x, float y, Color c) {
        super(world, new Rectangle(x, y, 48, 48));
        this.c = c;
    }

    public Color getColor(){ return c; }

    @Override
    public boolean collidedWithEntity(Entity e) {
        if(e instanceof Block && e.getShape().intersects(getShape()) && ((Block) e).isSolid()){
            Shape b = e.getShape();
            Shape p = getShape();
            if(b.getX() > p.getX()){
                p.setX(b.getX() - 48.1f);
                setVelocityX(0);
            }
            else if(b.getX() < p.getX()){
                p.setX(b.getX() + 48.1f);
                setVelocityX(0);
            }
            return true;
        }
        return false;
    }

    @Override
    public void remove() {

    }

    @Override
    protected void onUpdate(GameContainer gc, StateBasedGame sbg, int d) throws SlickException {
        Input in = gc.getInput();
        if(in.isKeyDown(Input.KEY_D)){
            this.setVelocityX(speed);
        }
        else if(in.isKeyDown(Input.KEY_A)){
                this.setVelocityX(-speed);
        }
        else{
            this.setVelocityX(0);
        }

        if(in.isKeyDown(Input.KEY_W)){
            this.setVelocityY(-speed);
        }
        else if(in.isKeyDown(Input.KEY_S)){
            this.setVelocityY(speed);
        }
        else{
            this.setVelocityY(0);
        }
    }

    @Override
    protected void onRender(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException {
        g.setColor(c);
        g.fill(getShape());
        g.setColor(Color.black);
        g.draw(getShape());
        g.draw(new Rectangle(getShape().getX() + 1, getShape().getY() + 1, 46, 46));
    }

}

我希望改进的部分代码是 Player.collidedWithEntity(Entity e)。

如果您对我的措辞或代码有任何疑问,我鼓励您要求澄清。感谢您抽出时间来阅读。

4

1 回答 1

1

我已经解决了这个问题!我通过拆分 X 和 Y 来解决它。这是分解的。

  • 保存 X 和 Y 坐标。
  • 根据速度移动 X。
  • 如果实体碰撞到一个实体对象,它会撤消 X 移动。
  • 根据速度移动 Y。
  • 如果实体碰撞到一个实体对象,它会撤消 Y 运动。

所以现在我让它在墙上碰撞和滑动!感谢那些给我文章阅读的人:)

于 2013-03-03T19:56:30.987 回答