セットアップ:
iPhone 用の 2D タイル ベースのゲーム (鳥瞰図) に取り組んでいます。アプリは、ヒーローがタイルを移動できるかどうかを表す true または false の「ブロック」プロパティを持つタイルの tile-d (.tbx) タイルマップ ファイルを読み取ります。マップ内の各タイルを繰り返し処理し、タイルの行と列を表す 2 次元の C 配列を作成して、各タイルのブロックされたプロパティ (true/false) を保持します。ヒーローをボード上で移動するときは、アレイでヒーローの位置を確認して、移動したタイルがブロックされているかどうかを確認します。ブロックされた場合、ヒーローの位置は前進した分だけ反転します。
問題:
ブロックされたタイルをヒーローが踏んだ場合、そこから移動できないという問題があります。ブロックされたタイルが本来あるべき場所で検出されるという意味で、タイルの位置は正しいですが、それでもヒーローは立ち往生しています。ヒーローは「タイルごと」ではなく「ピクセルごと」に進みます。それがすべてです。残っているのはコードを表示することだけです: (ヒーローのサイズは 28 x 36 ピクセルです)
//Code from GameScreen.m
-(void)generateCollisionMap
{
for(int layer=0; layer < 2; layer++) {
for(int yy=0; yy < _screenTilesHeight; yy++) {
NSLog(@"Row %i", yy);
for(int xx=0; xx < _screenTilesWide; xx++) {
int _globalTileID = [[[tileMap layers] objectAtIndex:layer] getGlobalTileIDAtX:xx y:yy];
NSString *_value = [tileMap getTilePropertyForGlobalTileID:_globalTileID key:@"blocked" defaultValue:@"false"];
if([_value isEqualToString:@"true"]) {
_blocked[xx][yy] = YES;
NSLog(@"Cell %i = YES", xx);
}else{
if(_blocked[xx][yy] == YES){
NSLog(@"Leaving Cell %i as = YES", xx);
//Leave As Is
}else{
_blocked[xx][yy] = NO;
NSLog(@"Cell %i = NO", xx);
}
}
}
}
}
}
//Code from Hero.m
-(void)moveHero
{
// Up
if(moveDirection == 1 && !doesNeedShiftWorld) {
heroY += _playerSpeed;
[self checkBlocked:1];
_currentAnimation = _upAnimation;
_moving = YES;
}
// Down
if(moveDirection == 2 && !doesNeedShiftWorld) {
heroY -= _playerSpeed;
[self checkBlocked:2];
_currentAnimation = _downAnimation;
_moving = YES;
}
// Left
if(moveDirection == 3 && !doesNeedShiftWorld) {
heroX -= _playerSpeed;
[self checkBlocked:3];
_currentAnimation = _leftAnimation;
_moving = YES;
}
// Right
if(moveDirection == 4 && !doesNeedShiftWorld) {
heroX += _playerSpeed;
[self checkBlocked:4];
_currentAnimation = _rightAnimation;
_moving = YES;
}
}
// ...
- (void) checkBlocked:(int)checkDirection
{
float xx = (heroX+160.0f+_tileWidth) / _tileWidth;
float yy = 11-((heroY+300.0f+_tileHeight) / _tileHeight);
switch (checkDirection) {
case 1:
yy -= 1;
if([_scene isBlocked:xx y:yy] ||
[_scene isBlocked:(heroX+160.0f) y:yy]) {
NSLog(@"Scene Blocked at %i, %i!", (int)xx, (int)yy);
heroY -= _playerSpeed;
}else{
NSLog(@"Clear at %i, %i!", (int)xx, (int)yy);
}
break;
case 2:
if([_scene isBlocked:xx y:yy] ||
[_scene isBlocked:xx y:(heroY+300.0f)] ||
[_scene isBlocked:(heroX+160.0f) y:(heroY+300.0f)]) {
NSLog(@"Scene Blocked at %i, %i!", (int)xx, (int)yy);
heroY += _playerSpeed;
}else{
NSLog(@"Clear at %i, %i!", (int)xx, (int)yy);
}
break;
case 3:
xx += 1;
if([_scene isBlocked:xx y:yy] ||
[_scene isBlocked:(heroX+160.0f) y:yy] ||
[_scene isBlocked:(heroX+160.0f) y:(heroY+300.0f)]) {
NSLog(@"Scene Blocked at %i, %i!", (int)xx, (int)yy);
heroX += _playerSpeed;
}else{
NSLog(@"Clear at %i, %i!", (int)xx, (int)yy);
}
break;
case 4:
if([_scene isBlocked:xx y:yy] ||
[_scene isBlocked:xx y:(heroY+300.0f)]) {
NSLog(@"Scene Blocked at %i, %i!", (int)xx, (int)yy);
heroX -= _playerSpeed;
}else{
NSLog(@"Clear at %i, %i!", (int)xx, (int)yy);
}
break;
}
}