トップページ > 過去ログ > 記事閲覧
アイテムについて
名前:tomato 日時: 2011/10/26 17:15

すみません初心者なもので当たり判定がわかりません なのでサンプルを見て作っていて #include "DxLib.h" #define SCREEN_WIDTH (640) // 画面の横幅 #define SCREEN_HEIGHT (480) // 画面の縦幅 #define CHIP_SIZE (32) // 一つのチップのサイズ #define MAP_WIDTH (SCREEN_WIDTH / CHIP_SIZE) // マップの横幅 #define MAP_HEIGHT (SCREEN_HEIGHT / CHIP_SIZE) // マップの縦幅 #define G (0.3F) // キャラに掛かる重力加速度 #define JUMP_POWER (9.0F) // キャラのジャンプ力 #define SPEED (4.0F) // キャラの移動スピード #define CHAR_SIZE (30) // プレイヤーのサイズ // マップデータ char MapData[MAP_HEIGHT][MAP_WIDTH] = { 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,1, 1,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,1, 1,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,1, 1,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,1, 1,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,1, 1,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,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, 1,0,0,0,0, 2,0,0,0,0, 0,0,0,0,0, 0,0,0,0,1, 1,0,0,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,0,0,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, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, } ; float PlX, PlY ; // プレイヤーの座標(中心座標) float PlDownSp ; // プレイヤーの落下速度 char PlJumpFlag ; // プレイヤーがジャンプ中か、のフラグ char ITEMUGET ; int houkouFlag ; int Input, EdgeInput ; // 入力状態 int FrameStartTime ; // 60FPS固定用、時間保存用変数 // マップチップの値を取得する関数 int GetChipParam( float X, float Y ) ; // キャラクタをマップとの当たり判定を考慮しながら移動する関数 int CharMove( float *X, float *Y, float *DownSP, float MoveX, float MoveY, float Size, char *JumpFlag ) ; // アクションサンプルプログラムメイン関数 int ActMain( void ) ; // マップとの当たり判定( 戻り値 0:当たらなかった 1:左辺に当たった 2:右辺に当たった // 3:上辺に当たった 4:下辺に当たった // 注意:MoveX と MoveY 、どっちか片方が0じゃないとまともに動作しません(爆) int MapHitCheck( float X, float Y, float *MoveX, float *MoveY ) ; int PlayerGraph[5]; int Background; // WinMain関数 int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { ChangeWindowMode( TRUE ) ; // DXライブラリの初期化 if( DxLib_Init() == -1 ) return -1 ; // アクションゲームのメイン関数を呼ぶ PlayerGraph[1] = LoadGraph( "ブロック.png" ) ; PlayerGraph[2] = LoadGraph( "自機.png" ) ; PlayerGraph[3] = LoadGraph( "アイテム.png" ) ; PlayerGraph[4] = LoadGraph( "敵.png" ) ; Background = LoadGraph( "背景.png" ) ; ActMain() ; // DXライブラリの後始末 DxLib_End() ; // 終了 return 0 ; } // アクションサンプルプログラムメイン int ActMain( void ) { // 描画先を裏画面にセット SetDrawScreen( DX_SCREEN_BACK ) ; // 垂直同期信号を待たない SetWaitVSyncFlag( FALSE ) ; // プレイヤーの座標を初期化 PlX = 320.0F ; PlY = 240.0F ; // プレイヤーの落下速度を初期化 PlDownSp = 0.0F ; // ジャンプ中フラグを倒す PlJumpFlag = FALSE ; // 入力状態の初期化 Input = 0 ; EdgeInput = 0 ; // 60FPS固定用、時間保存用変数を現在のカウント値にセット FrameStartTime = GetNowCount() ; // メインループ開始、ESCキーで外に出る while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 ) { // 画面のクリア ClsDrawScreen() ; // 1/60秒立つまで待つ while( GetNowCount() - FrameStartTime < 1000 / 60 ){} // 現在のカウント値を保存 FrameStartTime = GetNowCount() ; DrawGraph(0 , 0 , Background , TRUE ); // 入力状態を更新 { int i ; // パッド1とキーボードから入力を得る i = GetJoypadInputState( DX_INPUT_KEY_PAD1 ) ; // エッジを取った入力をセット EdgeInput = i & ~Input ; // 入力状態の保存 Input = i ; } // プレイヤーの移動処理 { float MoveX, MoveY ; // 移動量の初期化 MoveX = 0.0F ; MoveY = 0.0F ; // 左右の移動を見る if( ( Input & PAD_INPUT_LEFT ) != 0 ){ houkouFlag = 0; MoveX -= SPEED ; }; if( ( Input & PAD_INPUT_RIGHT ) != 0 ){ houkouFlag = 1; MoveX += SPEED ; }; // 地に足が着いている場合のみジャンプボタン(ボタン1 or Zキー)を見る if( PlJumpFlag == FALSE && ( EdgeInput & PAD_INPUT_A ) != 0 ) { PlDownSp = -JUMP_POWER ; PlJumpFlag = TRUE ; } // 落下処理 PlDownSp += G ; // 落下速度を移動量に加える MoveY = PlDownSp ; // 移動量に基づいてキャラクタの座標を移動 CharMove( &PlX, &PlY, &PlDownSp, MoveX, MoveY, CHAR_SIZE, &PlJumpFlag ) ; } // マップの描画 { int i, j ; for( i = 0 ; i < MAP_HEIGHT ; i ++ ) { for( j = 0 ; j < MAP_WIDTH ; j ++ ) { // 1は当たり判定チップを表しているので1のところだけ描画 if( MapData[i][j] == 1 ) { DrawGraph(j * CHIP_SIZE , i * CHIP_SIZE , PlayerGraph[1] , TRUE ) ; } if( MapData[i][j] == 2 ) { DrawGraph(j * CHIP_SIZE , i * CHIP_SIZE , PlayerGraph[3] , TRUE ) ; } } } } // キャラクタの描画 if (houkouFlag == 1){DrawGraph(PlX - CHAR_SIZE * 0.5F , PlY - CHAR_SIZE * 0.5F , PlayerGraph[2] , TRUE ) ;} // 画面の更新 ScreenFlip() ; } // 終了 return 0 ; } // キャラクタをマップとの当たり判定を考慮しながら移動する int CharMove( float *X, float *Y, float *DownSP, float MoveX, float MoveY, float Size, char *JumpFlag ) { float Dummy = 0.0F ; float hsize ; // キャラクタの左上、右上、左下、右下部分が当たり判定のある // マップに衝突しているか調べ、衝突していたら補正する // 半分のサイズを算出 hsize = Size * 0.5F ; // 先ず上下移動成分だけでチェック { // 左下のチェック、もしブロックの上辺に着いていたら落下を止める if( MapHitCheck( *X - hsize, *Y + hsize, &Dummy, &MoveY ) == 3 ) *DownSP = 0.0F ; // 右下のチェック、もしブロックの上辺に着いていたら落下を止める if( MapHitCheck( *X + hsize, *Y + hsize, &Dummy, &MoveY ) == 3 ) *DownSP = 0.0F ; // 左上のチェック、もしブロックの下辺に当たっていたら落下させる if( MapHitCheck( *X - hsize, *Y - hsize, &Dummy, &MoveY ) == 4 ) *DownSP *= -1.0F ; // 右上のチェック、もしブロックの下辺に当たっていたら落下させる if( MapHitCheck( *X + hsize, *Y - hsize, &Dummy, &MoveY ) == 4 ) *DownSP *= -1.0F ; // 上下移動成分を加算 *Y += MoveY ; } // 後に左右移動成分だけでチェック { // 左下のチェック MapHitCheck( *X - hsize, *Y + hsize, &MoveX, &Dummy ) ; // 右下のチェック MapHitCheck( *X + hsize, *Y + hsize, &MoveX, &Dummy ) ; // 左上のチェック MapHitCheck( *X - hsize, *Y - hsize, &MoveX, &Dummy ) ; // 右上のチェック MapHitCheck( *X + hsize, *Y - hsize, &MoveX, &Dummy ) ; // 左右移動成分を加算 *X += MoveX ; } // 接地判定 { // キャラクタの左下と右下の下に地面があるか調べる if( GetChipParam( *X - Size * 0.5F, *Y + Size * 0.5F + 1.0F ) == 0 && GetChipParam( *X + Size * 0.5F, *Y + Size * 0.5F + 1.0F ) == 0 ) { // 足場が無かったらジャンプ中にする *JumpFlag = TRUE ; } else { // 足場が在ったら接地中にする *JumpFlag = FALSE ; } } if(PlX - CHAR_SIZE * 0.5F <= -10 ){PlX=640;} if(PlX - CHAR_SIZE * 0.5F >= 640 ){PlX=10;} // 終了 return 0 ; } // マップとの当たり判定( 戻り値 0:当たらなかった 1:左辺に当たった 2:右辺に当たった // 3:上辺に当たった 4:下辺に当たった // 注意:MoveX と MoveY 、どっちか片方が0じゃないとまともに動作しません(爆) int MapHitCheck( float X, float Y, float *MoveX, float *MoveY ) { float afX, afY ; // 移動量を足す afX = X + *MoveX ; afY = Y + *MoveY ; // 当たり判定のあるブロックに当たっているかチェック if( GetChipParam( afX, afY ) == 1 ) { float blx, bty, brx, bby ; // 当たっていたら壁から離す処理を行う // ブロックの上下左右の座標を算出 blx = (float)( (int)afX / CHIP_SIZE ) * CHIP_SIZE ; // 左辺の X 座標 brx = (float)( (int)afX / CHIP_SIZE + 1 ) * CHIP_SIZE ; // 右辺の X 座標 bty = (float)( (int)afY / CHIP_SIZE ) * CHIP_SIZE ; // 上辺の Y 座標 bby = (float)( (int)afY / CHIP_SIZE + 1 ) * CHIP_SIZE ; // 下辺の Y 座標 // 上辺に当たっていた場合 if( *MoveY > 0.0F ) { // 移動量を補正する *MoveY = bty - Y - 1.0F ; // 上辺に当たったと返す return 3 ; } // 下辺に当たっていた場合 if( *MoveY < 0.0F ) { // 移動量を補正する *MoveY = bby - Y + 1.0F ; // 下辺に当たったと返す return 4 ; } // 左辺に当たっていた場合 if( *MoveX > 0.0F ) { // 移動量を補正する *MoveX = blx - X - 1.0F ; // 左辺に当たったと返す return 1 ; } // 右辺に当たっていた場合 if( *MoveX < 0.0F ) { // 移動量を補正する *MoveX = brx - X + 1.0F ; // 右辺に当たったと返す return 2 ; } // ここに来たら適当な値を返す return 4 ; } // どこにも当たらなかったと返す return 0 ; } // マップチップの値を取得する関数 int GetChipParam( float X, float Y ) { int x, y ; // 整数値へ変換 x = (int)X / CHIP_SIZE ; y = (int)Y / CHIP_SIZE ; // マップからはみ出ていたら 0 を返す if( x >= MAP_WIDTH || y >= MAP_HEIGHT || x < 0 || y < 0 ) return 0 ; // 指定の座標に該当するマップの情報を返す return MapData[ y ][ x ] ; } このコードのマップの2のところはアイテムにして 取ったら消えるようにしたいのです こんな事で質問してしまって本当にすみません よろしくお願いします

Page: 1 |

Re: アイテムについて ( No.1 )
名前:いっち 日時:2011/10/26 20:41

例えばですが、このような感じでどうでしょうか? 以下2つの関数(とプロトタイプ宣言)を追加して、 int SetChipParam( float X, float Y, int NewChip ) { int x = X / CHIP_SIZE; int y = Y / CHIP_SIZE; if( x >= MAP_WIDTH || y >= MAP_HEIGHT || x < 0 || y < 0 ) return 0 ; int OldChip = MapData[ y ][ x ] ; MapData[ y ][ x ] = NewChip; return OldChip; } int ItemHitCheck( float X, float Y ) { if ( GetChipParam( X, Y ) != 2 ) return 0; return SetChipParam( X, Y, 0 ); } 以下の処理を適当な行(たとえば187行目辺りの "// マップの描画" というコメントの直前)へ追加してください。 ItemHitCheck( PlX, PlY );
Re: アイテムについて ( No.2 )
名前:tomato 日時:2011/10/26 22:46

やって見ましたがうまくできませんでした 自分のやり方が拙いだけだと思うんですが 以下2つの関数(とプロトタイプ宣言)を追加する 場所はどこでもいいのですか? 関係はありませんが // キャラクタの描画 if (houkouFlag == 0){DrawTurnGraph(PlX - CHAR_SIZE * 0.5F , PlY - CHAR_SIZE * 0.5F , PlayerGraph[2] , TRUE ) ;} if (houkouFlag == 1){DrawGraph(PlX - CHAR_SIZE * 0.5F , PlY - CHAR_SIZE * 0.5F , PlayerGraph[2] , TRUE ) ;} が抜けてました
Re: アイテムについて ( No.3 )
名前:いっち 日時:2011/10/27 00:32

ソースをアップロードしました。 > h t t p : / / w w w1.axfc.net/uploader/Sc/so/287163.zip&key=dxlib
Re: アイテムについて ( No.4 )
名前:tomato 日時:2011/10/27 19:03

あざああした 本当にありがとうございましたうまくいきました

Page: 1 |