我正在制作一个简单的基于瓷砖的游戏。当涉及到碰撞检测时,我往往失败。这是第三次尝试得到一个像素精确的运动正确。我仍然面临一些问题。(http://prntscr.com/2evl5c)例如-> http://prntscr.com/2evl92,http://prntscr.com/2evlg6,http://prntscr.com/2evll1。
这是我上的课。//package /imports公共类LevelOne扩展BasicGameState{ //state是这个类的id,objLayer是层的id来检查碰撞,tileX,Y=位置上的tiles公共int状态,objLayer,tileX,tileY;布尔esc;输入;
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;
}
}
}
}}//它有用吗?
发布于 2013-12-30 03:34:41
现正作出以下假设:
TILE_SIZE宽的,因此它跨越0到TILE_SIZE - 1。(TILE_SIZE/2 ,TILE_SIZE/2 )像素的位置。

我认为在AABB()末尾添加以下代码块应该可以修复它:
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;
}你忘了考虑到,如果球员是在右边,那么他们可以向左。在上面的图片中,播放机应该能够向上、左和右移动;但是,您的代码不会考虑到当前方框中有可用的空间来移动。
https://stackoverflow.com/questions/20826869
复制相似问题