我知道Slick2D已被废弃但我觉得这个库的类型代码很舒服。
也许你已经看到了与Slick2d相同的事情,碰撞。现在,我有一个我无法解决的问题,我有这个问题已经有两个星期了。在我的游戏中,有一个TileMap,在那里我找到了所有属于" solid"图层和我在同一位置绘制矩形以使用物理。问题是我的角色(是一些动画)没有检测到属于我的tilemap的实体层的矩形。
如果我使用for循环,则角色不会检测矩形。但是,如果我通过ifs语句查看所有rects,那么碰撞就会起作用。
有谁知道为什么会这样?
抱歉我的英文>。<
任何帮助都会被贬低。
谢谢!
编辑:这是关于我的碰撞的代码。
包含tilemap的Level类:
public class Level extends TiledMap{
private int tileId;
private int layerIndex;
private boolean solids[][];
private Shape rects[][];
public Level(String path) throws SlickException {
super(path);
solids = new boolean [super.getWidth()][super.getHeight()];
rects = new Rectangle[super.getWidth()][super.getHeight()];
tileId=0;
layerIndex=0;
}
public int getTileId() {
return tileId;
}
public int getLayerIndex() {
return layerIndex;
}
public boolean[][] getSolids() {
return solids;
}
public Shape[][] getRects() {
return rects;
}
public Shape getSingleRect(int i, int j){
return rects[i][j];
}
public void setTileId(int tileId) {
this.tileId = tileId;
}
public void setLayerIndex(String layerName) {
this.layerIndex = super.getLayerIndex(layerName);
}
public void setSolid(int i, int j, boolean solid) {
this.solids[j][i] = solid;
}
public void setRect(int i, int j, Shape rect) {
this.rects[j][i] = rect;
}
//other methods
public void printSolidMatrix(){
System.out.println("SOLID MATRIX");
for(int i=0;i<super.getWidth();i++){
for(int j=0;j<super.getHeight();j++){
System.out.print(solids[j][i]+" ");
}
System.out.println();
}
}
public void drawDebugRects(Graphics g){
layerIndex = this.getLayerIndex();
tileId = 0;
for(int i=0;i<this.getWidth();i++){
for(int j=0;j<this.getHeight();j++){
tileId = this.getTileId(j, i, layerIndex);
g.draw(rects[j][i]);
}
}
}
public boolean collidesWith(Shape s){
for(int i=0;i<this.getWidth();i++){
for(int j=0;j<this.getHeight;j++){
if(s.intersects(rects[j][i]) && solids[j][i]){
}
}
}
return false;
}
}
我的播放器类包含有关物理的属性:
public class Player{
private Level map;
private float x;
private float y;
private boolean falling;
private Shape bounds;
public Player(Level map) throws SlickException{
falling = true;
x=0;
y=500;
this.map = map;
this.setBounds(this.x, this.y, this.x*32, this.y*32);
}
public float getX() {
return x;
}
public void increaseX(float x) {
this.x += x;
}
public float getY() {
return y;
}
public void increaseY(float y) {
this.y += y;
}
public Shape getBounds() {
return bounds;
}
public void setBounds(float x, float y, float width, float height) {
bounds = new Rectangle(x, y, this.currentAnimation.getWidth(), this.currentAnimation.getHeight());
}
public boolean isFalling() {
return falling;
}
public void setFalling(boolean falling) {
this.falling = falling;
}
public void render(GameContainer gc, Graphics g) throws SlickException {
this.getCurrentAnimation().draw(this.getX(), this.getY());
this.setBounds(this.getX(), this.getY(), this.getCurrentAnimation().getWidth(),this.getCurrentAnimation().getHeight());
g.draw(this.getBounds());
}
public void update(GameContainer gc, int delta) throws SlickException {
this.getCurrentAnimation().update(delta);
//character movement
if(gc.getInput().isKeyDown(Input.KEY_D)){
this.setRight(true);
this.setCurrentAnimation(this.getWalkAnimation());
this.increaseX(2.5f);
}
else if(gc.getInput().isKeyDown(Input.KEY_A)){
this.setRight(false);
this.setCurrentAnimation(this.getWalkAnimationReverse());
if(this.getX()<0){
}else{
this.increaseX(-2.5f);
}
}
else{
if(!this.isRight()){
this.setCurrentAnimation(this.getStandAnimationReverse());
}else{
this.setCurrentAnimation(this.getDefaultAnimation());
}
}
}
}
我正在工作的当前水平:
public class IntroStage extends BasicGameState{
Level map;
Player p;
@Override
public void init(GameContainer gc, StateBasedGame sbg) throws SlickException {
initMap();
p = new Player(map);
//map.printSolidMatrix();
}
@Override
public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException {
map.render(0, 0);
map.drawDebugRects(g);
p.render(gc, g);
}
@Override
public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException {
p.update(gc, delta);
//this if make character fall while he doesnt collides
if(map.collidesWith(p.getBounds())){
p.increaseY(delta);
}
else{
p.increaseY(0);
}
}
@Override
public int getID() {
return 1;
}
public void initMap() throws SlickException{
map = new Level("res/tiles/test.tmx");
map.setLayerIndex("suelo");
int id=0;
int x=0;
int y=0;
for(int i=0; i<map.getWidth();i++){
for(int j=0;j<map.getHeight();j++){
id = map.getTileId(j, i, map.getLayerIndex());
x=j*32;
y=i*32;
map.setRect(i, j, new Rectangle(x, y, map.getTileWidth(), map.getTileHeight()));
if(id!=0){
map.setSolid(i, j, true);
}
else{
map.setSolid(i, j, false);
}
}
}
}
}
注意:Slick2D的getTileId方法效果不好,这就是为什么我使用matrix [j] [i]而不是matrix [i] [j]
答案 0 :(得分:0)
因此,互联网上有很多教程解释了如何做到这一点:
我可以推荐这些以便很好地理解你可能做错了什么:
Slick2d | Entity collision detection
我强烈建议您的播放器为hitbox。例如,一个32 * 32的矩形,这对于 easy &amp; 精确碰撞检测,因为您可以使用shape.intersects(Shape s)方法。
我检查了你的代码,我理解的缺少的是播放器端的碰撞检测。所以现在你要确定哪些瓷砖被“阻止”了。从您的方法中,每个被阻止的区块都是一个存储在数组中的x,y的形状。
你需要在球员身上做什么,如果你的球员想要移动的方向被阻挡,那么在移动后进行检查。
没有播放器收件箱的方法,虽然可能表现得很谦逊,但取决于你的速度。这应该最适合每个移动命令1个瓦片的速度。 E.G。
if(gc.getInput().isKeyDown(Input.KEY_D)){
if(Level.solids[Player.x+Player.xv][Player.y] == false){ // Checking whether the tile to the right of the Player is returning false or true
// ...Do your movement / Animation stuff.
}
}
在我看来,如果你通过形状检查碰撞做同样的事情会更好。
if(gc.getInput().isKeyDown(Input.KEY_D)){
for(Shape s : Level.shapes){
if(!Player.hitbox.intersects(s)){
// ...Do your movement / Animation stuff.
}
请注意,您可能无法一个一个地使用它,因为它表现得不精确,您需要根据您的要求进行调整。但是它应该重新考虑你的游戏设计,并给你一个暗示问题可能存在的提示。
希望这会对你有所帮助。