首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Java Slick2D -平铺地图碰撞

Java Slick2D -平铺地图碰撞
EN

Stack Overflow用户
提问于 2013-12-29 15:41:30
回答 1查看 1.6K关注 0票数 0

我正在制作一个简单的基于瓷砖的游戏。当涉及到碰撞检测时,我往往失败。这是第三次尝试得到一个像素精确的运动正确。我仍然面临一些问题。(http://prntscr.com/2evl5c)例如-> http://prntscr.com/2evl92http://prntscr.com/2evlg6http://prntscr.com/2evll1

这是我上的课。//package /imports公共类LevelOne扩展BasicGameState{ //state是这个类的id,objLayer是层的id来检查碰撞,tileX,Y=位置上的tiles公共int状态,objLayer,tileX,tileY;布尔esc;输入;

代码语言:javascript
运行
复制
public int[][] obj; //store each tile's id of the object layer here

private TiledMap map;

private float x,y,vel, TILE_SIZE;//x position , y position ,velocity, tile size in pixels

private Sound jump;//nevermind

public boolean cLeft,cRight,cUp,cDown;//c(anMove)Left/Right/Down etc

public LevelOne(int state){
    this.state = state;//constructor to pass the 
}

@Override
public void init(GameContainer arg0, StateBasedGame arg1)
        throws SlickException {
      TILE_SIZE = 32;//initialization
      esc = false;
      map = new TiledMap("res/map/map.tmx");
      cUp = false;
      cDown = false;
      cLeft = false;
      cRight = false;
      x = 2 * TILE_SIZE;//see the map
      y = 1 * TILE_SIZE;
      vel = .1f;
      objLayer = map.getLayerIndex("Objects");//get the layer
      jump = new Sound("res/sound/jump.wav");

      obj = new int[10][10];//initialize the 2d array to store the blocked tiles

      for(int col = 0; col < 10;col++){
          for(int row = 0;row < 10;row++){
              obj[col][row] = map.getTileId(col, row, objLayer);
          }
      }
}

@Override
public void render(GameContainer arg0, StateBasedGame arg1, Graphics g)
        throws SlickException {
        map.render(0, 0);//render only the map and a white rectangle (player)

        g.fillRect(x, y, TILE_SIZE, TILE_SIZE);

}

@Override
public void update(GameContainer gc, StateBasedGame sbg, int delta)
        throws SlickException {
    input = gc.getInput();//get input
    if(esc){//somehting about the menu , ignore it!
        Mouse.setGrabbed(false);

    }else{
        Mouse.setGrabbed(true);
    }
        if(input.isKeyPressed(Input.KEY_ESCAPE)){
            esc = true;
        }   
    if(esc){
        Mouse.setGrabbed(false);
            if(input.isKeyPressed(Input.KEY_R)){
                esc = false;
            }else if(input.isKeyPressed(Keyboard.KEY_Q)){
                System.exit(0);
            }else if(input.isKeyPressed(Keyboard.KEY_M)){
                esc = false;
                sbg.enterState(0);
                Mouse.setGrabbed(false);
            }
        }


    //calculate collisions
    AABB();



    //TODO -- FIX COLLISIONS , thats what we need to do :/

    if(input.isKeyDown(Input.KEY_RIGHT)){//arrow keys, check if player can move and decide, see AABB() method!
        if(cRight){
            x += vel * delta;
        }
    }

    if(input.isKeyDown(Input.KEY_LEFT)){
        if(cLeft){
            x -= vel * delta;
        }
    }

    if(input.isKeyDown(Input.KEY_UP)){
        if(cUp){
            y -= vel * delta;
        }
    }

    if(input.isKeyDown(Input.KEY_DOWN)){
        if(cDown){
            y += vel * delta;
        }
    }

        }

@Override
public int getID() {//get the id of the class
    return state;
}

private void AABB(){

    cLeft = false;//re-initialize
    cRight = false;
    cUp = false;
    cDown = false;

    tileX = (int) Math.round(Math.ceil(x / TILE_SIZE));//get the tile of the player
    tileY = (int) Math.round(Math.ceil(y / TILE_SIZE));

    int diffX = (int) Math.round(Math.ceil(x % TILE_SIZE));//get the remainder , sorry for the name
    int diffY = (int) Math.round(Math.ceil(y % TILE_SIZE));

    int HALF_TILE_SIZE = 32 / 2;//get half the tile size

    //Start handling collisions

    if(diffX == HALF_TILE_SIZE){//if the player is actually on a number that can be divided by 32 without remainder , do a simple up/down check
        if(obj[tileX][tileY - 1] == 0){
            cUp = true;
        }   
        if(obj[tileX][tileY + 1] == 0){
            cDown = true;
        }
    }else{
        if(diffX > HALF_TILE_SIZE){//if it is not , check the other nearby squares.Here because diffX > HALF_TILE_SIZE , I get the one near these tiles. its obj[numberoftilex][numberoftiley] to get the tile's id. it returns 0 if it is empty.
            if(obj[tileX][tileY - 1] == 0 && obj[tileX + 1][tileY - 1] == 0){
                cUp = true;
            }
            if(obj[tileX][tileY + 1] == 0 && obj[tileX + 1][tileY + 1] == 0){
                cDown = true;
            }
        }else if(diffX < HALF_TILE_SIZE){
            if(obj[tileX][tileY - 1] == 0 && obj[tileX - 1][tileY - 1] == 0){
                cUp = true;
            }
            if(obj[tileX][tileY + 1] == 0 && obj[tileX - 1][tileY + 1] == 0){
                cDown = true;
            }
        }
    }
    //same things done with X are done with Y
    if(diffY == HALF_TILE_SIZE){
        if(obj[tileX - 1][tileY] == 0){
            cLeft = true;
        }

        if(obj[tileX + 1][tileY] == 0){
            cRight = true;
        }
    }else{
        if(diffY > HALF_TILE_SIZE){
            if(obj[tileX - 1][tileY] == 0 && obj[tileX - 1][tileY - 1] == 0){
                cLeft = true;
            }
            if(obj[tileX + 1][tileY] == 0 && obj[tileX + 1][tileY - 1] == 0){
                cRight = true;
            }
        }else if(diffY < HALF_TILE_SIZE){
            if(obj[tileX - 1][tileY] == 0 && obj[tileX - 1][tileY + 1] == 0){
                cLeft = true;
            }
            if(obj[tileX + 1][tileY] == 0 && obj[tileX + 1][tileY + 1] == 0){
                cRight = true;
            }
        }


    }

}

}//它有用吗?

EN

回答 1

Stack Overflow用户

发布于 2013-12-30 03:34:41

现正作出以下假设:

  1. 瓷砖从0开始,并且是TILE_SIZE宽的,因此它跨越0到TILE_SIZE - 1
  2. 网格的起源(瓷砖0,0)位于网格的左上角。
  3. 边缘周围有一个非空瓷砖的边框,所以玩家的瓷砖永远不能离开边缘。
  4. 播放机瓷砖x和y坐标是相对于其左上角的(TILE_SIZE/2 ,TILE_SIZE/2 )像素的位置。

我认为在AABB()末尾添加以下代码块应该可以修复它:

代码语言:javascript
运行
复制
    if(diffX>HALF_TILE_SIZE){
        cRight=true;
    }else if(diffX<HALF_TILE_SIZE){
        cLeft=true;
    }
    if(diffY>HALF_TILE_SIZE){
        cDown=true;
    }else if(diffY<HALF_TILE_SIZE){
        cUp=true;
    }

你忘了考虑到,如果球员是在右边,那么他们可以向左。在上面的图片中,播放机应该能够向上、左和右移动;但是,您的代码不会考虑到当前方框中有可用的空间来移动。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20826869

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档