壁と空間の設定ができて、キャラの画像の四隅を使って左右に壁があるときは歩けないようにできたので
ジャンプの処理に取り掛かりました。
私の作ったコードは、ジャンプ中は『Jump』という変数が1で、着地中は0という設定にしたうえで、
キャラの右下と左下がマップチップの『1』(床)だったら『Jump』を0にして、スペースキーを押したら『Jump』を1にして飛び上がらせ、
『Jump』が1の間だけキャラを落下させるというコードを組みました。
歩いているときに踏み外した場合も『Jump』を1にさせるところまでいったのですが、
着地したときに落下速度を0にするだけでは床にめりこんでしまうことになってしまいました。
床の位置を座標で指定していたときは着地したら床のY座標にキャラを動かせば良いのですが、
マップチップで考えると着地した床だけの座標が決まっていないので『キャラのY座標をこの位置にうごかす』
ということができない気がするんですが…着地したらキャラのY座標をどう動かせばよいのでしょうか…
ちなみにキャラの画像は64×64の大きさの画像の中心に32×64の縦2マス分のキャラが描かれています。
24コマ入っていますが今は12コマしか使ってません。
#include "DxLib.h"
//構造体
//プレイヤー構造体
struct Playerdata{
int X, Y, img;
}Player;
////
int Key[256];
int GetHitKeyStateAll_2(int GetHitKeyStateAll_InputKey[]){
char GetHitKeyStateAll_Key[256];
GetHitKeyStateAll( GetHitKeyStateAll_Key );
for(int i=0;i<256;i++){
if(GetHitKeyStateAll_Key[i]==1) GetHitKeyStateAll_InputKey[i]++;
else GetHitKeyStateAll_InputKey[i]=0;
}
return 0;
}
#define MAP_SIZE 32 // マップチップ一つのドットサイズ
#define MAP_WIDTH 20 // マップの幅
#define MAP_HEIGHT 15 // マップの縦長さ
// マップのデータ
int MapData[ MAP_HEIGHT ][ MAP_WIDTH ] =
{
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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 } ,
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1 } ,
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1 } ,
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1 } ,
{ 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1 } ,
{ 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 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, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ,
} ;
/////
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
ChangeWindowMode(TRUE);//ウィンドウモード
if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化
// 画像をロード
//マップ
int lenga1 = LoadGraph( "image/map/lenga1.png" );
int statesbar = LoadGraph( "image/statesbar.png" );
int haikei1 = LoadGraph( "image/haikei1.png" );
//キャラ関係
int chara[24]; //キャラ画像
int HPgazou[11]; //HPの画像
LoadDivGraph( "image/chara.png" , 24 , 6 , 4 , 64 , 64 , chara );//プレイヤー
LoadDivGraph( "image/HP.png" , 11 , 1 , 11 , 224 , 32 , HPgazou );//体力
//関数
Player.X = 32 , Player.Y = 288 ; //プレイヤー座標
int JumpPower = 0 ; //ジャンプパワー
int Jump = 0 ; //ジャンプ状態か
int walkdirection = 1 ; //歩く向き
int walkanime = 0 ; //歩くアニメーション用
int HP = 10 ; //HP
int HPimg ; //HP画像
int i , j ; //座標用
while(ProcessMessage()==0 && ClearDrawScreen()==0 && GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){
//↑メッセージ処理 ↑画面をクリア ↑入力状態を保存 ↑ESCが押されていない
//ココから
//背景を描画
DrawGraph( 0, 0, haikei1, FALSE ); // 背景
// マップを描画
for( i = 0 ; i < MAP_HEIGHT ; i ++ )
{
for( j = 0 ; j < MAP_WIDTH ; j ++ )
{
if( MapData[ i ][ j ] == 1 ) //1のとき壁を描画
{
DrawGraph( j * MAP_SIZE , i * MAP_SIZE , lenga1 , FALSE ) ;
}
}
}
// ジャンプ状態じゃなく、ジャンプボタンを押して地面についていたらジャンプ
if ( Jump==0 && (Key[KEY_INPUT_SPACE] >=1 ))
if(MapData[(Player.Y+63)/32][(Player.X + 17)/32] != 1
&&MapData[(Player.Y+63)/32][(Player.X + 47)/32] != 1)
{
JumpPower = 16 ;
Jump = 1 ;
}
//ジャンプ状態で右向きなら右ジャンプの画像
if ( walkdirection == 1 && Jump == 1 ){
Player.img=chara[5];
}
//ジャンプ状態で左向きなら左ジャンプの画像
if ( walkdirection == 0 && Jump == 1 ){
Player.img=chara[11];
}
if( Key[ KEY_INPUT_RIGHT ] >= 1 ) { //右キーが押されて
if(MapData[(Player.Y)/32][(Player.X + 47)/32] != 1 //右が壁じゃなかったら
&&MapData[(Player.Y+63)/32][(Player.X + 47)/32] != 1)
Player.X+=3 ; //右に動く
walkdirection = 1 ;
}
if( Key[ KEY_INPUT_RIGHT ] >= 1 && Jump== 0 ){ // 右キーが押されていてジャンプ状態じゃなかったら
walkanime++;
Player.img=chara[(walkanime/10)%4 +1];//右に歩くアニメ
}
if( walkdirection == 1 && ( Key[ KEY_INPUT_RIGHT ] == 0 )&& Jump== 0 )// 右キーが離されてジャンプ状態じゃなかったら
Player.img=chara[0]; //右を向く
if( Key[ KEY_INPUT_LEFT ] >= 1 ){// 左キーが押されて
if(MapData[(Player.Y)/32][(Player.X+17)/32] != 1
&&MapData[(Player.Y+63)/32][(Player.X+17)/32] != 1) //左が壁じゃなかったら
Player.X-=3 ; //左に動く
walkdirection = 0 ;
}
if(( Key[ KEY_INPUT_LEFT ] >= 1 ) && Player.Y == 288 && Jump== 0 ){ // 左キーが押されていてジャンプ状態じゃなかったら
walkanime++;
Player.img=chara[(walkanime/10)%4 +7];//右に歩くアニメ
}
if( walkdirection == 0 && ( Key[ KEY_INPUT_LEFT ] == 0 ) && Jump== 0 ) // 左キーが離されてジャンプ状態じゃなかったら
Player.img=chara[6]; //左を向く
if( Key[ KEY_INPUT_RIGHT ] >= 1 && Key[ KEY_INPUT_LEFT ] >= 1)//左右両方押されてたら右向く
Player.img=chara[0];
// ジャンプ中ならキャラの落下処理
if(Jump == 1){
Player.Y -= JumpPower ;
JumpPower -= 1 ;
}
// ジャンプ中にキャラが地面についたら落下をやめる
if(Jump == 1)
if(MapData[(Player.Y+65)/32][(Player.X + 17)/32] != 0
&&MapData[(Player.Y+65)/32][(Player.X + 47)/32] != 0)
{
JumpPower = 0 ;
Jump = 0 ;
}
//歩いているときに踏み外したらジャンプ状態にする
if(Jump == 0)
if(MapData[(Player.Y+65)/32][(Player.X + 17)/32] != 1
&&MapData[(Player.Y+65)/32][(Player.X + 47)/32] != 1)
{
Jump = 1 ;
}
//HP
if( HP==10 )
HPimg = HPgazou[10];
//画像
DrawGraph( Player.X, Player.Y, Player.img, TRUE ); // x,y の位置にキャラを描画
//ステータスバー背景
for(int y=0 ; y<1 ; y++){
for(int x=0 ; x<20 ; x++){
DrawGraph(x*32+0,y*32+418,statesbar,FALSE);
}
}
DrawGraph( 0, 420, HPimg, TRUE ); // HPバー
ScreenFlip();
}
DxLib_End();
return 0;
}