質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

DXライブラリ

DXライブラリとは、DirectXを使ったWindowsソフトの開発に必ず付いて回るDirectXやWindows関連のプログラムを使い易くまとめた形で利用できるようにしたC++言語用のゲームライブラリです。

Q&A

解決済

1回答

4171閲覧

アクションゲームのプログラムでめり込みが多発するのをなんとかしたい。

Nagkei10

総合スコア15

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

DXライブラリ

DXライブラリとは、DirectXを使ったWindowsソフトの開発に必ず付いて回るDirectXやWindows関連のプログラムを使い易くまとめた形で利用できるようにしたC++言語用のゲームライブラリです。

0グッド

0クリップ

投稿2017/03/26 05:56

編集2017/03/26 06:38

###前提・実現したいこと
DXライブラリとそのサンプルコードを使って、アクションゲームを制作しているのですが、質問があってここに来ました。キャラのサイズを変更して、めり込まないようにしたいです。

###発生している問題・エラーメッセージ
着地した地点でめり込んでしまう。しかも、壁にぶつかるとめり込みが発生してしまう。
縦列が1マスの足場では、何故かこの症状が起こらない。

###該当のソースコード
main.cpp

C++

1//マップデータ 2char MapData[MAP_HEIGHT][MAP_WIDTH] 3{ 4 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, 5 1,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,1, 6 1,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,1, 7 1,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,1, 8 1,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,1, 9 10 1,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,1, 11 1,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,1, 12 1,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,1, 13 1,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,1, 14 1,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,1, 15 16 1,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,1, 17 1,0,0,0,0, 0,1,1,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,1, 18 1,0,0,0,0, 1,1,1,1,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,1, 19 1,0,0,0,1, 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,1, 20 1,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,1,1,1,0, 0,0,0,0,1, 21 22 1,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,1, 23 1,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,1, 24 1,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,1, 25 1,0,0,0,0, 0,0,1,0,1, 1,1,1,1,1, 1,1,1,1,1, 0,0,0,0,1, 26 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, 27}; 28//宣言の部分は省略。 29//マップチップのデータ獲得 30int MapChipParam(float X, float Y) { 31 int x, y; 32 33 x = (int)X / CHIP_SIZE; 34 y = (int)Y / CHIP_SIZE; 35 36 if (x >= MAP_WIDTH || y >= MAP_HEIGHT || x < 0 || y < 0) return 0; 37 38 return MapData[y][x]; 39} 40 41//衝突判定 42int MapHitCheck(float X, float Y, float *MoveX, float *MoveY, int Size) { 43 float afX, afY; 44 afX = X + *MoveX; 45 afY = Y + *MoveY; 46 float blx, brx, bby, bty; 47 blx = (float)((int)afX / Size)*Size; 48 brx = (float)((int)afX / Size + 1)*Size; 49 bty = (float)((int)afY / Size)*Size; 50 bby = (float)((int)afY / Size + 1)*Size; 51 if (MapChipParam(afX, afY) == 1) { 52 if (*MoveY > 0.0F) { 53 printf("\n下に当たりました。"); 54 //移動量を補正する 55 *MoveY = bty - Y - 1.0F; 56 //上の壁に当たったと判定する 57 return 3; 58 } 59 if (*MoveY < 0.0F) { 60 printf("\n上に当たりました。"); 61 //移動量を補正する 62 *MoveY = bby - Y + 1.0F; 63 //下の壁に当たったと判定する 64 return 4; 65 } 66 //右の当たり判定 67 if (*MoveX > 0.0F) { 68 printf("\n右に当たりました。"); 69 //移動量を補正する 70 *MoveX = blx - X - 1.0F; 71 //右の壁に当たったと判定する 72 return 1; 73 } 74 //左の当たり判定 75 if (*MoveX < 0.0F) { 76 printf("\n左に当たりました。"); 77 //移動量を補正する 78 *MoveX = brx - X + 1.0F; 79 //左の壁に当たったと判定する 80 return 2; 81 } 82 //ここに来たら適当な値を返す 83 return 4; 84 } 85 return 0; 86} 87 88//当たり判定チェック 89int CharMove(float *X, float *Y, float MoveX, float MoveY, float *Drop,float *G,char *Jump,char *Air,char *Vert, int *JumpT,float *Vect,int Size, char *Slide, int *JCount){ 90 float Dummy = 0.0F; 91 float hsize; 92 //直前フレーム 93 float PrevX = *X + MoveX; 94 float PrevY = *Y + MoveY; 95 //ベクトルのバックアップ 96 float SaveMoveX = MoveX; 97 float SaveMoveY = MoveY; 98 99 hsize = Size * 0.5F; 100 //上下の当たり判定チェック、上に衝突したら落下させ、下に衝突したら着地させる。 101 { 102 //左下 103 if (MapHitCheck(*X - hsize, *Y + hsize - 1.0F, &Dummy, &MoveY,(int)Size) == 3) *Drop = 0.0F, MoveY -= 2.0F,printf("\n上下::左下"); 104 //右下 105 if (MapHitCheck(*X + hsize, *Y + hsize - 1.0F, &Dummy, &MoveY,(int)Size) == 3) *Drop = 0.0F, MoveY -= 2.0F,printf("\n上下::右下"); 106 //左上 107 if (MapHitCheck(*X - hsize, *Y - hsize + 1.0F, &Dummy, &MoveY,(int)Size) == 4) *Drop *= -0.5F, MoveY += 2.0F,printf("\n上下::左上"); 108 //右上 109 if (MapHitCheck(*X + hsize, *Y - hsize + 1.0F, &Dummy, &MoveY,(int)Size) == 4) *Drop *= -0.5F, MoveY += 2.0F,printf("\n上下::右上"); 110 //問題ないのなら移動させる 111 PrevY = *Y + MoveY; 112 *Y = PrevY; 113 } 114 //左右の当たり判定チェック 115 { 116 //左下 117 if (MapHitCheck(*X - hsize + 1.0F, *Y + hsize, &MoveX, &Dummy, (int)Size))*Slide = FALSE, MoveX += 2.0F,*Vect = 0.0F, printf("\n左右::左下"); 118 //右上 119 if (MapHitCheck(*X + hsize - 1.0F, *Y + hsize, &MoveX, &Dummy, (int)Size))*Slide = FALSE, MoveX -= 2.0F,*Vect = 0.0F, printf("\n左右::右下"); 120 //左上 121 if (MapHitCheck(*X - hsize + 1.0F, *Y - hsize, &MoveX, &Dummy, (int)Size))*Slide = FALSE, MoveX += 2.0F,*Vect = 0.0F, printf("\n左右::左上"); 122 //右上 123 if (MapHitCheck(*X + hsize - 1.0F, *Y - hsize, &MoveX, &Dummy, (int)Size))*Slide = FALSE, MoveX -= 2.0F,*Vect = 0.0F, printf("\n左右::右上"); 124 //問題ないのなら移動させる 125 PrevX = *X + MoveX; 126 *X = PrevX; 127 } 128 //着地判定 129 { 130 if (MapChipParam(*X - hsize, *Y + hsize + 1.0F) == 0 && MapChipParam(*X + hsize, *Y + hsize + 1.0F) == 0) { 131 *Air = TRUE; 132 *G = 0.5F; 133 } 134 else { 135 *JumpT = 0; 136 *Drop = 0.0F; 137 *G = 0.0F; 138 *Air = FALSE; 139 *JCount = 0; 140 *Vert = FALSE; 141 *Jump = FALSE; 142 } 143 } 144 return 0; 145} 146 147//カメラの位置計算 148int CameraCheck(float X, float Y) { 149 //カメラのチェック 150 CharX = X; 151 CharY = Y; 152 //カメラの位置を計算する 153 CameraX = (int)CharX - SCREEN_WIDTH / 2; 154 CameraY = (int)CharY - SCREEN_HEIGHT / 2; 155 //カメラの補正 156 if (CameraX < 0)CameraX = 0; 157 if (CameraX >(STAGE_WIDTH - SCREEN_WIDTH))CameraX = (STAGE_WIDTH - SCREEN_WIDTH); 158 if (CameraY < 0)CameraY = 0; 159 if (CameraY >(STAGE_HEIGHT - SCREEN_HEIGHT))CameraY = (STAGE_HEIGHT - SCREEN_HEIGHT); 160 ViewCharX = CharX - CameraX; 161 ViewCharY = CharY - CameraY; 162 return 0; 163} 164 165int init(void) { 166 ChangeWindowMode(TRUE),SetGraphMode(320,240,32),printf("初期化しています…"); 167 if (DxLib_Init() == -1) { return -1; } 168 PlayerX = 240.0F, PlayerY = 200.0F, MoveX = 0.0F, MoveY = 0.0F; 169 JumpFlag = FALSE, DropPower = 0.0F, Grav = 0.5F, Dir = TRUE; 170 Input = 0, EdgeInput = 0, FreamStartTime = GetNowCount(); 171 DashCnt = 0,MaxVect = 0.0F, NonVertJump = FALSE, dir = 0,DirT = FALSE; 172 MaxJump = FALSE, DashB = FALSE, CameraX = 0, CameraY = 0; 173 return 0; 174} 175 176int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) 177{ 178 AllocConsole(); FILE* out = 0; freopen_s(&out, "CON", "w", stdout); Stdout = GetStdHandle(STD_OUTPUT_HANDLE); 179 init(); 180 while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0) { 181 main(); 182 } 183 DxLib_End(); fclose(out); FreeConsole(); 184 return 0; 185}

move.cpp

C++

1int main(void) { 2//移動アルゴリズムなどは省略。 3 //マップの描画 4 { 5 int i, j; 6 for (i = 0; i < MAP_HEIGHT; i++) { 7 for (j = 0; j < MAP_WIDTH; j++) { 8 if (MapData[i][j] == 1) { 9 DrawBox(j*CHIP_SIZE - CameraX, i*CHIP_SIZE - CameraY, j*CHIP_SIZE + CHIP_SIZE - CameraX, i*CHIP_SIZE + CHIP_SIZE - CameraY, GetColor(255, 255, 255), TRUE); 10 } 11 } 12 } 13 } 14 //キャラの描画 15 DrawBox((int)(ViewCharX)-(CHAR_SIZE / 2), (int)(ViewCharY)-(CHAR_SIZE / 2), (int)(ViewCharX + CHAR_SIZE) - (CHAR_SIZE / 2), (int)(ViewCharY + CHAR_SIZE) - (CHAR_SIZE / 2), GetColor(255, 0, 0), TRUE); 16}

###試したこと
画面サイズを2のべき乗にして見たけど、だめでした。
ちなみに画面サイズは直後に320x240に戻してます。

###補足情報(言語/FW/ツール等のバージョンなど)
Windows 10のVisual Studio 2017です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

当たり判定チェックの部分を調整したら治りました。
ですが、着地するときに空中に少し浮いてしまうようです。

C++

1//当たり判定チェック 2int CharMove(float *X, float *Y, float MoveX, float MoveY, float *Drop,float *G,char *Jump,char *Air,char *Vert, int *JumpT,float *Vect,int Size, char *Slide, int *JCount){ 3 float Dummy = 0.0F; 4 float hsize; 5 //直前フレーム 6 float PrevX = *X + MoveX; 7 float PrevY = *Y + MoveY; 8 //ベクトルのバックアップ 9 float SaveMoveX = MoveX; 10 float SaveMoveY = MoveY; 11 12 hsize = Size * 0.5F; 13 //上下の当たり判定チェック、上に衝突したら落下させ、下に衝突したら着地させる。 14 { 15 //左下 16 if (MapHitCheck(*X - hsize, *Y + hsize - 1.0F, &Dummy, &MoveY,(int)Size) == 3) *Drop = 0.0F, MoveY = -1.0F,printf("\n上下::左下"); 17 //右下 18 if (MapHitCheck(*X + hsize, *Y + hsize - 1.0F, &Dummy, &MoveY,(int)Size) == 3) *Drop = 0.0F, MoveY = -1.0F,printf("\n上下::右下"); 19 //左上 20 if (MapHitCheck(*X - hsize, *Y - hsize + 1.0F, &Dummy, &MoveY,(int)Size) == 4) *Drop *= -0.5F, MoveY = 1.0F,printf("\n上下::左上"); 21 //右上 22 if (MapHitCheck(*X + hsize, *Y - hsize + 1.0F, &Dummy, &MoveY,(int)Size) == 4) *Drop *= -0.5F, MoveY = 1.0F,printf("\n上下::右上"); 23 //問題ないのなら移動させる 24 PrevY = *Y + MoveY; 25 *Y = PrevY; 26 } 27 //左右の当たり判定チェック 28 { 29 //左下 30 if (MapHitCheck(*X - hsize + 1.0F, *Y + hsize, &MoveX, &Dummy, (int)Size))*Slide = FALSE, MoveX = 1.0F,*Vect = 0.0F, printf("\n左右::左下"); 31 //右上 32 if (MapHitCheck(*X + hsize - 1.0F, *Y + hsize, &MoveX, &Dummy, (int)Size))*Slide = FALSE, MoveX = -1.0F,*Vect = 0.0F, printf("\n左右::右下"); 33 //左上 34 if (MapHitCheck(*X - hsize - 1.0F, *Y - hsize, &MoveX, &Dummy, (int)Size))*Slide = FALSE, MoveX = -1.0F,*Vect = 0.0F, printf("\n左右::左上"); 35 //右上 36 if (MapHitCheck(*X + hsize + 1.0F, *Y - hsize, &MoveX, &Dummy, (int)Size))*Slide = FALSE, MoveX = 1.0F,*Vect = 0.0F, printf("\n左右::右上"); 37 //問題ないのなら移動させる 38 PrevX = *X + MoveX; 39 *X = PrevX; 40 } 41 //着地判定 42 { 43 if (MapChipParam(*X - hsize, *Y + hsize + 1.0F) == 0 && MapChipParam(*X + hsize, *Y + hsize + 1.0F) == 0) { 44 *Air = TRUE; 45 *G = 0.5F; 46 } 47 else { 48 *JumpT = 0; 49 *Drop = 0.0F; 50 *G = 0.0F; 51 *Air = FALSE; 52 *JCount = 0; 53 *Vert = FALSE; 54 *Jump = FALSE; 55 } 56 } 57 return 0; 58}

投稿2017/03/26 07:12

Nagkei10

総合スコア15

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問