我有两个实体,一个播放器和一个块。玩家和街区都是正方形。我希望玩家在遇到障碍时停止移动。我已经完成了一些代码,但它只适用于横向,我想知道使用我现有的代码,如果我可以添加一个垂直碰撞部分。
我需要横向和纵向碰撞,因为我需要知道玩家在哪个方向击中该区块以及在哪一侧。这将帮助我确定当碰撞到块中时是否应该停止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);
}
}
WorldEntity:
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(实体e)。
如果您对我的措辞或代码有任何疑问,我建议您要求澄清。感谢您抽出宝贵时间阅读本文。
答案 0 :(得分:1)
我已经解决了这个问题!我通过拆分X和Y来解决它。这是故障。
所以现在我碰撞并滑向墙壁!感谢那些给我读文章的人:)