トップページ > 過去ログ > 記事閲覧
アクションゲームの厳密な当たり判定
名前:TKOZ 日時: 2010/02/14 17:01

色で当たり判定を行っているのですが、 厳密な(白色の周りを沿う形での)当たり判定が したいです。 例えば、下に白い当たり判定がある場合は、 その下をキャラクターが滑る (滑るというのは、移動量を加算するという 意味ではなく、位置を的確に捉えて白い塊の上を ピタリと移動する) 様な移動をしたいです。 また、キャラクターの右側に白い凸状のものが あれば、右側に移動しない様にしたいです。 あと、上側に白い壁がある場合は、ジャンプしても 移動しないようにしたいです。 例えるなら、HSPの「大誤」様作 「Art Action」を想像して頂ければ結構です。 ソースを添付します。 #include"DxLib.h" #include<math.h> #include<string.h> #include<stdlib.h> #include<stdio.h> #define MAX_ENEMY 50 #define MAX_BULLET 500 #define RAD (3.14159265/180) #define RIGHT 0 #define LEFT 1 extern int MainGraphic[]; class Jiki{ public: int x; int y; int width; int height; int zanki; int zandan; int muki; int ShootingAngle; void Draw(void) { DrawRectGraph(x, y, 0, 0, 60, 76, MainGraphic[0], TRUE, muki*1 ) ; } void Move(void) { } Jiki() { } ~Jiki() { } }; /* class Teki{ public: double x; double y; int width; int height; int Mode; int muki; void MoveByAI(void); void Draw(void); Teki(); ~Teki(); }; class Tama{ public: double x; double y; int witdh; int height; int kind; //種類 int speed; int moveangle;//動く角度 int drawangle;//描画する角度 void Shot(int x,int y,int speed,int kind); void Move(void); void Draw(void); Tama(); ~Tama(); }; class System{ public: long int time; int flag; //ゲームの状態 System(); ~System(); }; */ extern Jiki Player; /* extern Teki Enemy[]; extern Tama Bullet[]; extern System Sys; */ Jiki Player; //Teki Enemy[MAX_ENEMY]; //Tama Bullet[MAX_BULLET]; //System Sys; int MouseX,MouseY; int map; int g=10; int MainGraphic[100]; int GetCol(int x,int y) { int r,g,b,a; GetPixelSoftImage(map, x, y, &r, &g, &b, &a ) ; return GetColor(r,g,b); } void DivideColor(int src,int *r,int *g,int *b) { *r = ((src>>16)&0xFF); *g = ((src>>8)&0xFF); *b = (src&0xFF); } void HitCheckColor() { int i,j; int white=GetColor(255,255,255); float speed=0.15f; float jump_speed=-8.6f; float jump_accel=0.5f; static int Jump=1; static float VX=0; static float VY=0; static int ground_y; if(!Jump) { if(CheckHitKey(KEY_INPUT_X)) { Jump=1; VY=jump_speed; } } else { VY+=jump_accel; Player.y+=VY; } if(CheckHitKey(KEY_INPUT_LEFT)) { Jump=1; Player.x-=3; } if(CheckHitKey(KEY_INPUT_RIGHT)) { Jump=1; Player.x+=3; } DrawFormatString(0,45,GetColor(255,0,0),"GetColor=%d",GetColor(255,255,255)); DrawFormatString(0,70,GetColor(255,0,0),"GetPixel(x,y)=%d",GetPixel(Player.x,Player.y+63)); DrawFormatString(0,90,GetColor(255,0,0),"x,y=(%d,%d)",Player.x,Player.y); DrawFormatString(0,128,GetColor(255,0,0),"Jump=%d",Jump); if(GetCol(Player.x,Player.y)==white) { //MessageBox(NULL,"OK","OK",NULL); DrawString(0,0,"左上",GetColor(255,255,255)); Player.x+=3; Jump=1; } if(GetCol(Player.x+60,Player.y)==white) { //MessageBox(NULL,"OK","OK",NULL); DrawString(0,0,"右上",GetColor(255,255,255)); Player.x-=3; Jump=1; } if(GetCol(Player.x,Player.y+76)==white) { //MessageBox(NULL,"OK","OK",NULL); DrawString(0,0,"左下",GetColor(255,255,255)); Player.y-=1; ground_y=Player.y+64; Jump=0; VY=0; } if(GetCol(Player.x+60,Player.y+76)==white) { //MessageBox(NULL,"OK","OK",NULL); DrawString(0,0,"右下",GetColor(255,255,255)); Player.y-=1; //Player.x-=3; Jump=0; VY=0; } } void Init() { Player.x=(640-32)/2; Player.y=0; map = LoadSoftImage( "./DATA/Map.png" ) ;//640x480の起伏のある白い塊が //画面下にあるグラフィック MainGraphic[0]=LoadGraph("./DATA/jon.png");//60x76のグラフィック } int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hP,LPSTR lpC,int nC) { ChangeWindowMode(TRUE); //ウィンドウモードで起動 SetGraphMode(640,480,32); SetMainWindowText("METAL TANK ver0.01"); //ウィンドウのタイトル if(DxLib_Init() == -1) return (-1); //DXライブラリ初期化 Init(); //データ読み込み中と表示する DrawString( 0 , 0 , "データ読み込み中" , GetColor(255,255,255) ); //乱数の初期化 srand((unsigned)GetTickCount()); SetDrawScreen(DX_SCREEN_BACK); //メインループ while( ProcessMessage()==0 && CheckHitKey(KEY_INPUT_ESCAPE)==0){ ProcessMessage(); ClsDrawScreen(); //画面を初期化 Player.Move(); HitCheckColor(); DrawSoftImage(0,0, map ) ; Player.Draw(); ScreenFlip(); //フリップする } DxLib_End(); //DXライブラリ終了処理 return (0); //終了 }

Page: 1 |

Re: アクションゲームの厳密な当たり判定 ( No.1 )
名前:いっち 日時:2010/02/14 22:40

とりあえず坂道のことは忘れて天井、床、壁の衝突判定を作成されてはどうでしょうか? (坂道は登れない(すべる)坂を考えると難しいです) その際には管理人さんが作成なさった以下のサンプルが参考になると思います。 「29.アクションゲームにおけるマップとの当たり判定基本」 「32.3Dアクション基本」 「32.3Dアクション基本」は3DですがTKOZさんがなさりたいことの大部分が含まれているのではないかと思います。 天上の衝突判定については以下のようにすればそれなりに動作すると思います。 if(GetCol(Player.x,Player.y)==white) { //MessageBox(NULL,"OK","OK",NULL); DrawString(0,0,"左上",GetColor(255,255,255)); Player.x+=3; Player.y++; // 追加 VY = 0; // 追加 Jump=1; } if(GetCol(Player.x+60,Player.y)==white) { //MessageBox(NULL,"OK","OK",NULL); DrawString(0,0,"右上",GetColor(255,255,255)); Player.x-=3; Player.y++; // 追加 VY = 0; // 追加 Jump=1; }
Re: アクションゲームの厳密な当たり判定 ( No.2 )
名前:いっち 日時:2010/02/18 01:09

TKOZさんはもう見ていらっしゃらないかも知れませんし、ご存知かもしれませんが、 厳密な当たり判定をやってみてわかったのですが、GetPixelSoftImage はかなりコストが高いようです。 (GetPixel のコストが高いのは知っていましたが、SoftImageはたいしたこと無いと思っていました) 事前にSoftImageをint型のBuff等に展開して当たり判定に利用したほうが良いようでした。

Page: 1 |