アクションゲームを作ろうとしております。
(イメージとしてはチャリ走などのシンプルなものです)
また今回はビット演算がよくわからないので、
当たり判定をビット演算で実装しようと考えております。
マップの自動生成っぽいもの+スクロール処理はできたのですが
キャラクターの移動系の処理が壊滅的にできません・・・。
色々と試してみたのですが、何かができると何かがダメになったりしてしまいました・・・。
①当たり判定をリセット
②ジャンプ判定
③移動
④当たり判定(あたっていたら前の座標に戻す)
⑤前の座標を保存
みたいな処理をしております。
こちらだと、当たり判定が来た1フレームずれる?感じになってしまうのと
地面とあたっても引きづられたりしてしまいます。
宜しければで構いませんのでアドバイスなど頂けないでしょうか。
// マップ関連
#define MAP_SIZE 32
#define MAP_WIDTH 20
#define MAP_HEIGHT 8
#define TABLE_MAX 3
#define CHARACTER_WIDTH 32
#define CHARACTER_HEIGHT 32
// 当たり判定用
#define DIR_NONE 0x0000
#define DIR_UP 0x0001
#define DIR_DOWN 0x0002
#define DIR_RIGHT 0x0004
#define DIR_LEFT 0x0008
#define DIR_SOME 0x0016 // どれかに当たったら
typedef struct{
float Scroll[2];
TIMER Time;
}OBJECT_GAME;
static OBJECT_GAME Obj;
// レベルデザイン用
typedef struct{
int Time;
int Pattern[LEVEL_DESIGN_PATTERN_MAX];
}LEVEL_DESIGN;
// レベルデザイン用
static LEVEL_DESIGN Level[LEVEL_DESIGN_MAX] = {
{ 60*0, { 0,1,2,2,0 } },
{ 60*40, { 1,2,0,2,1 } },
{ 60*120, { 0,0,0,0,0 } },
{ 60*130, { 0,0,0,0,0 } },
{ 60*140, { 0,0,0,0,0 } }
};
static int tblMapMaster[TABLE_MAX][MAP_HEIGHT][MAP_WIDTH] = {
// MAP_1
{
{ 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{ 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{ 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{ 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{ 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{ 1,1,1,0,0, 0,0,0,1,1, 1,1,1,0,0, 0,0,0,1,1 },
{ 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1 },
{ 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1 }
},
// MAP_2
{
{ 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{ 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{ 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{ 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{ 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{ 2,1,1,0,0, 0,0,0,1,1, 1,1,1,0,0, 0,0,0,1,1 },
{ 2,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1 },
{ 2,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1 }
},
// MAP_3
{
{ 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{ 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{ 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{ 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{ 3,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{ 3,1,1,0,0, 0,0,0,1,1, 1,1,1,0,0, 0,0,0,1,1 },
{ 3,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1 },
{ 3,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1 }
}
};
static int tblMap[2][MAP_HEIGHT][MAP_WIDTH];
class PLAYER{
public:
bool Flag;
float Px, Py, Dx, Dy, Ox, Oy;
unsigned int Dir;
void Init();
void Loop();
void HitCheck( float scroll[] );
};
void PLAYER::Init(){
this->Dir = DIR_NONE;
this->Flag = false;
this->Px = 0.0f;
this->Py = 0.0f;
this->Dx = 0.0f;
this->Dy = 3.0f;
this->Ox = 0.0f;
this->Oy = 0.0f;
}
void PLAYER::Loop(){
//this->Dx = 0;
//this->Dy = 0;
this->Dir = DIR_NONE;
if( System.touch.trgFlag ){
this->Dy = -8.0f;
}
this->Dy += 0.22f;
//if( this->Dy <= 0.0f ) this->Dy = 0.0f;
// 移動場所
this->Px += this->Dx;
this->Py += this->Dy;
// 当たり判定
this->HitCheck( Obj.Scroll );
// 下方向が当たってたら
if( ( this->Dir & DIR_DOWN ) ){
this->Dy = 0.0f;
this->Py = this->Oy;
}
// 右方向
//Log( @"%d", ( this->Dir & DIR_RIGHT ) );
if( ( this->Dir & DIR_RIGHT ) ){
Log( @"くるときがある" );
//this->Dx = -3.0f;
}else{
this->Dx = 0.0f;
}
// 前のフレームを保存
if( !( this->Dir & DIR_RIGHT ) || !( this->Dir & DIR_LEFT ) ) this->Ox = this->Px;
if( !( this->Dir & DIR_DOWN ) || !( this->Dir & DIR_UP ) ) this->Oy = this->Py;
/*
// 右方向が当たってたら
if( ( this->Dir & DIR_RIGHT ) ){
this->Px -= 3;
}
*/
if( this->Py >= 960 ) this->Py = 200;
if( this->Px <= 0 ) this->Px = 400;
/*
this->Dir = this->Dir | DIR_LEFT;
if( System.touch.trgFlag ) this->Dir = this->Dir | DIR_UP;
*/
}
void PLAYER::HitCheck( float scroll[] ){
for(int y=0; y<MAP_HEIGHT; y++){
for(int x=0; x<MAP_WIDTH; x++){
for(int tbl=0; tbl<2; tbl++){
int px1 = ( x*MAP_SIZE ) + ( MAP_SIZE/2 ) + scroll[tbl];
int py1 = ( y*MAP_SIZE ) + ( MAP_SIZE/2 );
int diff = 10;
if( tblMap[tbl][y][x] == 1 || tblMap[tbl][y][x] == 2 || tblMap[tbl][y][x] == 3 ){
// 何かに当たってる
if( this->Px-CHARACTER_WIDTH/2 < px1+MAP_SIZE/2 && this->Px+CHARACTER_WIDTH/2 > px1-MAP_SIZE/2 &&
this->Py-CHARACTER_HEIGHT/2 < py1+MAP_SIZE/2 && this->Py+CHARACTER_HEIGHT/2 > py1-MAP_SIZE/2 ){
this->Dir = this->Dir | DIR_SOME;
}
// キャラクターから下方向が当たってる
if( this->Px-CHARACTER_WIDTH/2 < px1+MAP_SIZE/2 && this->Px+CHARACTER_WIDTH/2 > px1-MAP_SIZE/2 &&
this->Py+CHARACTER_HEIGHT/2 < py1+MAP_SIZE/2 && this->Py+CHARACTER_HEIGHT/2 > py1-MAP_SIZE/2 ){
this->Dir = this->Dir | DIR_DOWN;
}
// キャラクターから上方向が当たってる
if( this->Px-CHARACTER_WIDTH/2 < px1+MAP_SIZE/2 && this->Px+CHARACTER_WIDTH/2 > px1-MAP_SIZE/2 &&
this->Py-CHARACTER_HEIGHT/2 < py1+MAP_SIZE/2 && this->Py-CHARACTER_HEIGHT/2 > py1-MAP_SIZE/2 ){
this->Dir = this->Dir | DIR_UP;
}
// キャラクターから右方向が当たってる
if( this->Px+CHARACTER_WIDTH/2 < px1+MAP_SIZE/2 && this->Px+CHARACTER_WIDTH/2 > px1-MAP_SIZE/2 &&
this->Py-CHARACTER_HEIGHT/2+diff < py1+MAP_SIZE/2 && this->Py+CHARACTER_HEIGHT/2-diff > py1-MAP_SIZE/2 ){
this->Dir = this->Dir | DIR_RIGHT;
this->Dx = -3.0f;
NSLog( @"aaa" );
}
// キャラクターから左方向が当たってる
if( this->Px-CHARACTER_WIDTH/2 < px1+MAP_SIZE/2 && this->Px-CHARACTER_WIDTH/2 > px1-MAP_SIZE/2 &&
this->Py-CHARACTER_HEIGHT/2+diff < py1+MAP_SIZE/2 && this->Py+CHARACTER_HEIGHT/2-diff > py1-MAP_SIZE/2 ){
this->Dir = this->Dir | DIR_LEFT;
}
}
}
}
}
}