移動とジャンプが上手く行きません。
Posted: 2017年1月17日(火) 19:07
DXライブラリの公式サイトにあるサンプルコードを参考にして、アクションゲームを作っていて、当たり判定のプログラムを完成させたはいいのですが、何かの不具合でジャンプするとどこまでも飛んでいってしまう上に、左右に移動しようとしても全く反応しません。(正確には1マス動いて止まります。)コードは以下のとおりです。
#include "dxlib.h"
#define SCREEN_WIDTH (320)
#define SCREEN_HEIGHT (240)
#define CHIP_SIZE (16)
#define MAP_WIDTH (SCREEN_WIDTH/CHIP_SIZE)
#define MAP_HEIGHT (SCREEN_HEIGHT/CHIP_SIZE)
float PlayerX = 24.0F, PlayerY = 216.0F, DropPower = 0.0F,Gravity;
char dir, JumpFlag, DashFlag,AirFlag;
int GetChipParam(float X, float Y);
int MoveChecker(float *X, float *Y, float *DropPower, float MoveX, float MoveY, float Size,char *JumpFlag);
int MapHitCheck(float X,float Y,float *MoveX,float *MoveY);
int PlayerHandle, MapChipHandle[2], JumpCount, DashTrigger, Time, Input,EdgeInput;
int Key[256];
int gpUpdateKey() {
char tmpKey[256];
GetHitKeyStateAll(tmpKey);
for (int i = 0; i < 256; i++){
if (tmpKey[i] != 0) {
Key[i]++;
}
else {
Key[i] = 0;
}
}
return 0;
}
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,
0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,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,
};
//マップチップ確認
int GetChipParam(float X, float Y)
{
int x, y;
x = (int)X / CHIP_SIZE;
y = (int)Y / CHIP_SIZE;
if (x >= MAP_WIDTH || y >= MAP_HEIGHT || x < 0 || y < 0) return 0;
return MapData[y][x];
}
//マップの当たり判定
int MapHitCheck(float X, float Y, float *MoveX, float *MoveY) {
float afX, afY;
afX = X + *MoveX;
afY = Y + *MoveY;
if (GetChipParam(X, Y) == 1) {
float blx, bty, brx, bby;
//壁衝突確認
blx = (float)((int)afX / CHIP_SIZE)*CHIP_SIZE;//左辺の当たり判定
brx = (float)((int)afX / CHIP_SIZE + 1)*CHIP_SIZE;//右辺の当たり判定
bty = (float)((int)afY / CHIP_SIZE)*CHIP_SIZE;//上辺の当たり判定
bby = (float)((int)afY / CHIP_SIZE + 1)*CHIP_SIZE;//下辺の当たり判定
//上辺に当たったら3を返す
if (*MoveY > 0.0F) {
*MoveY = bty - Y - 1.0F;
return 3;
}
//下辺に当たっていたら4を返す
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 MoveChecker(float *X, float *Y, float *DropPower, 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) *DropPower = 0.0F;
//右下
if (MapHitCheck(*X + hsize, *Y + hsize, &Dummy, &MoveY) == 3) *DropPower = 0.0F;
//左上
if (MapHitCheck(*X - hsize, *Y - hsize, &Dummy, &MoveY) == 4) *DropPower = -1.0F;
//右上
if (MapHitCheck(*X - hsize, *Y - hsize, &Dummy, &MoveY) == 4) *DropPower = -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) && (*X + Size*0.5, *Y + Size*0.5F)) {
}
//もし足場に着地したらジャンプ回数をリセットする
else {
JumpCount = 0;
Gravity = 0;
*JumpFlag = FALSE;
}
return 0;
}
}
int main(void) {
SetDrawScreen(DX_SCREEN_BACK);
Input = 0;
Time = GetNowCount();//カウント値を更新する
PlayerHandle = LoadGraph("テスト用.png");
LoadDivGraph("マップチップ.bmp", 2, 2, 1, 16, 16, MapChipHandle);
dir = TRUE;
DashFlag = FALSE;
while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0 && gpUpdateKey() == 0) {
//カウント値を更新する
Time = GetNowCount();
//入力状態を更新する
{
int i;
i = GetJoypadInputState(DX_INPUT_KEY_PAD1);
//チョン押しを確認する
EdgeInput = i & ~Input;
Input = i;
}
//ダッシュトリガー確認
if ((Input&PAD_INPUT_1) == 0) {
DashFlag = FALSE;
}
if (JumpCount >= 2) {
JumpFlag = TRUE;
}
//移動処理
{
float MoveX, MoveY;
MoveX = 0.0F;
MoveY = 0.0F;
//左に移動
if ((Input&PAD_INPUT_LEFT) != 0) {
dir = FALSE;
MoveX -= 5.0F;
}
//右に移動
if ((Input&PAD_INPUT_RIGHT) != 0) {
dir = TRUE;
MoveX += 5.0F;
}
//左ラン
if ((Input&PAD_INPUT_LEFT) != 0 && (Input&PAD_INPUT_1) != 0 && JumpFlag == FALSE) {
dir = FALSE;
DashFlag = TRUE;
MoveX -= 5.25F;
}
//右ラン
if ((Input&PAD_INPUT_RIGHT) != 0 && (Input&PAD_INPUT_1) != 0 && JumpFlag == FALSE) {
dir = TRUE;
DashFlag = TRUE;
MoveX += 5.25F;
}
//ダッシュボタン
if ((EdgeInput&PAD_INPUT_3) != 0) {
}
//ジャンプ処理
if ((EdgeInput&PAD_INPUT_2) != 0 && JumpFlag == FALSE) {
//ジャンプできる状態にする
DropPower = 0;
//ジャンプ回数を増やす
JumpCount += 1;
//ジャンプする
DropPower = -9.5F;
//ジャンプするときの重力を決める
Gravity = 0.5F;
}
if ((EdgeInput&PAD_INPUT_2) != 0 && DashFlag == TRUE && JumpFlag == FALSE) {
DashFlag = TRUE;
DropPower = 0;
JumpCount += 1;
DropPower = -12.0F;
Gravity = 0.5F;
}
//落下処理
DropPower += Gravity;
//落下速度を移動量に追加する
MoveY = DropPower;
//当たり判定に基づく移動を行う
MoveChecker(&PlayerX, &PlayerY, &DropPower, MoveX, MoveY, CHIP_SIZE,&JumpFlag);
}
//マップの描画
{
int i, j;
for (i = 0; i < MAP_HEIGHT; i++) {
for (j = 0; j < MAP_WIDTH; j++) {
if (MapData[i][j] == 1) {
DrawGraph(j * CHIP_SIZE, i*CHIP_SIZE, MapChipHandle[1],TRUE);
}
}
}
}
//キャラの描画
{
if (dir == TRUE)
DrawRotaGraph((int)PlayerX, (int)PlayerY, 1.0, 0.0, PlayerHandle, TRUE, FALSE);
else
DrawRotaGraph((int)PlayerX, (int)PlayerY, 1.0, 0, PlayerHandle, TRUE, TRUE);
}
}
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
ChangeWindowMode(TRUE), SetGraphMode(320, 240, 32);
//初期化
if (DxLib_Init() == -1) {
return -1;
}
//メインプログラム
main();
//DXライブラリを終了する
DxLib_End();
return 0;
}