二维iPhone游戏中基于分片的碰撞检测问题

二维iPhone游戏中基于分片的碰撞检测问题,iphone,opengl-es,collision-detection,tiles,Iphone,Opengl Es,Collision Detection,Tiles,设置: 我正在为iPhone开发一款基于二维瓷砖的游戏(鸟瞰图)。应用程序读入一个tile-d(.tbx)tilemap文件,其中tile的“blocked”属性为true或false,以表示英雄是否可以在tile中移动。我迭代映射中的每个图块,并创建一个表示图块行和列的二维C数组,以保存每个图块的blocked属性(true/false)。当我将英雄移动到整个棋盘上时,我用阵列检查英雄的位置,看他移动的棋盘是否被阻挡。如果被阻挡,英雄的位置会被向前移动的距离反转 问题: 问题是,当一个英雄踩到

设置:
我正在为iPhone开发一款基于二维瓷砖的游戏(鸟瞰图)。应用程序读入一个tile-d(.tbx)tilemap文件,其中tile的“blocked”属性为true或false,以表示英雄是否可以在tile中移动。我迭代映射中的每个图块,并创建一个表示图块行和列的二维C数组,以保存每个图块的blocked属性(true/false)。当我将英雄移动到整个棋盘上时,我用阵列检查英雄的位置,看他移动的棋盘是否被阻挡。如果被阻挡,英雄的位置会被向前移动的距离反转

问题:
问题是,当一个英雄踩到一块被阻挡的地砖时,他无法离开它。瓷砖的位置是正确的,因为被阻挡的瓷砖被检测到应该在哪里,但是英雄仍然被卡住了。英雄“按像素”而不是“按瓷砖”前进。差不多就这些了。唯一剩下的就是显示代码:(英雄是28像素乘36像素的大小)

//来自GameScreen.m的代码
-(无效)generateCollisionMap
{
对于(int层=0;层<2;层++){
对于(int-yy=0;yy<_屏幕高度;yy++){
NSLog(@“行%i”,yy);
对于(int xx=0;xx<_屏幕宽度;xx++){
int[u globalTileID=[[tileMap layers]objectAtIndex:layer]getGlobalTileIDAtX:xx y:yy];
NSString*(U值=[tileMap GetTilePropertyForgLobalTeleId:_GlobalTeleId键:@“阻止”默认值:@“假”];
if([[u值IsequalString:@“true”]){
_阻塞[xx][yy]=是;
NSLog(@“单元%i=YES”,xx);
}否则{
如果(_blocked[xx][yy]==是){
NSLog(@“将单元格%i保留为是”,xx);
//原封不动
}否则{
_阻塞[xx][yy]=否;
NSLog(@“单元%i=NO”,xx);
}
}
}
}
}
}
//来自Hero.m的代码
-(无效)英雄
{
//向上
if(moveDirection==1&&!doesNeedShiftWorld){
heroY+=\u玩家速度;
[自检被阻止:1];
_currentAnimation=\u upAnimation;
_移动=是;
}
//向下
if(moveDirection==2&&!doesNeedShiftWorld){
heroY-=\u玩家速度;
[自检被阻止:2];
_currentAnimation=\u downAnimation;
_移动=是;
}
//左
if(moveDirection==3&&!doesNeedShiftWorld){
heroX-=\u玩家速度;
[自查封锁:3];
_currentAnimation=_leftAnimation;
_移动=是;
}
//对
if(moveDirection==4&&!doesNeedShiftWorld){
heroX+=\u玩家速度;
[自查封锁:4];
_currentAnimation=_rightAnimation;
_移动=是;
}
}   
//  ... 
-(void)checkBlocked:(int)checkDirection
{
浮动xx=(heroX+160.0f+_平铺宽度)/_平铺宽度;
浮动yy=11-((heroY+300.0f+_tileHeight)/_tileHeight);
开关(检查方向){
案例1:
yy-=1;
如果([\u场景被阻止:xx y:yy]||
[_场景被阻止:(heroX+160.0f)y:yy]){
NSLog(@“场景在%i,%i!”,(int)xx,(int)yy被阻止);
heroY-=\u玩家速度;
}否则{
NSLog(@“在%i、%i!,(int)xx,(int)yy清除”);
}
打破
案例2:
如果([\u场景被阻止:xx y:yy]||
[\u场景被阻止:xx y:(heroY+300.0f)]||
[_场景被阻止:(heroX+160.0f)y:(heroY+300.0f)]){
NSLog(@“场景在%i,%i!”,(int)xx,(int)yy被阻止);
heroY+=\u玩家速度;
}否则{
NSLog(@“在%i、%i!,(int)xx,(int)yy清除”);
}
打破
案例3:
xx+=1;
如果([\u场景被阻止:xx y:yy]||
[_场景被阻止:(heroX+160.0f)y:yy]|
[_场景被阻止:(heroX+160.0f)y:(heroY+300.0f)]){
NSLog(@“场景在%i,%i!”,(int)xx,(int)yy被阻止);
heroX+=\u玩家速度;
}否则{
NSLog(@“在%i、%i!,(int)xx,(int)yy清除”);
}
打破
案例4:
如果([_场景被阻止:xx y:yy]|
[[场景被阻止:xx y:(heroY+300.0f)]){
NSLog(@“场景在%i,%i!”,(int)xx,(int)yy被阻止);
heroX-=\u玩家速度;
}否则{
NSLog(@“在%i、%i!,(int)xx,(int)yy清除”);
}
打破
}
}

我认为问题在于你允许玩家移动到被阻挡的磁贴上,他会被卡住


在尝试移动玩家之前,我会检查玩家移动的方向是否被阻挡。

我认为问题在于你允许玩家移动到被阻挡的磁贴上,他会被卡住


在尝试移动玩家之前,我会检查玩家移动的方向是否被阻挡。

您的问题是移动玩家,然后检查他移动到的空间是否被阻挡。相反,你要找出他想要移动到的位置,看看它是否被阻挡,然后只在它没有被阻挡的情况下移动他。此外,您可以始终添加子句以排除其当前空格。i、 只要你的角色不改变网格空间,他总是可以移动的,但是一旦他要改变网格空间,你应该检查他是否会与什么东西碰撞

以下是您的代码:

if(moveDirection == 1 && !doesNeedShiftWorld) {
    heroY += _playerSpeed;
    [self checkBlocked:1];
    _currentAnimation = _upAnimation;
    _moving = YES;
}
应该是这样的:

if(moveDirection == 1 && !doesNeedShiftWorld)
{
    //Figure out if the player is changing grid spaces.
    BOOL isChangingSpaces = ((int)((heroY + _playerSpeed) / myGridSizeVariable) != (int)(heroY / myGridSizeVariable));

    //The player should be able to move either if he isn't
    //changing grid spaces or if his destination space is free.
    if ( !isChangingSpaces || (spaceIsOpenAtX:heroX andY:heroY+_playerSpeed) )
    {
        heroY += _playerSpeed;
        _currentAnimation = _upAnimation;
        _moving = YES;
    }
}
if(moveDirection == 1 && !doesNeedShiftWorld)
{
    //Figure out if the player is changing grid spaces.
    BOOL isChangingSpaces = ((int)((heroY + _playerSpeed) / myGridSizeVariable) != (int)(heroY / myGridSizeVariable));

    //The player should be able to move either if he isn't
    //changing grid spaces or if his destination space is free.
    if ( !isChangingSpaces || (spaceIsOpenAtX:heroX andY:heroY+_playerSpeed) )
    {
        heroY += _playerSpeed;
        _currentAnimation = _upAnimation;
        _moving = YES;
    }
}