#17
by keito940 » 7年前
ごめんなさい、実は自己解決していました。それに際して前に質問いたした横へのジャンプも、そのルーチンに束ねました。
コード:
#include "DxLib.h"
#define SCREEN_WIDTH (320) //画面の横幅
#define SCREEN_HEIGHT (240) //画面の縦幅
#define STAGE_WIDTH (400)
#define STAGE_HEIGHT (320)
#define CHIP_SIZE (16) //チップのサイズ
#define MAP_WIDTH (STAGE_WIDTH/CHIP_SIZE)
#define MAP_HEIGHT (STAGE_HEIGHT/CHIP_SIZE)
#define JOYPAD_BUTTON_MAX (28)
#define PAD_INPUT_ON 1
#define PAD_INPUT_OFF 0
HANDLE Stdout;
//テスト用のマップデータ。実際の開発では、Tiled(フリーのマップエディタ)を使う予定。
//このテストプログラムがある程度の段階に達したら、本格的な開発に移ります。
//TinyXML2は便利だ
char 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,1,1,1,1,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
};
float PlayerX, PlayerY;
float SaveX, SaveY;
float MoveX, MoveY;
float VectX;
float DropPower, Grav;
char JumpFlag, Dir, AirFlag, NonVertJump;
int DashCnt, ContCnt, JumpTimer;
int Input, EdgeInput, Pad;
int FreamStartTime;
int CameraX = 0;
int CameraY = 0;
float CharX, CharY, ViewCharX, ViewCharY;
int MapHitCheck(float X, float Y, float *MoveX, float *MoveY, int Size);
int 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);
int MapChipParam(float X, float Y);
int CameraCheck(float X, float Y);
bool IsPush(int PadHandle);
bool IsFree(int PadHandle);
bool IsHold(int PadHandle);
bool IsPull(int PadHandle);
//将来の開発で使う予定の関数。
//押されたか?
bool IsPush(int PadHandle) {
if (((EdgeInput&PadHandle) > PAD_INPUT_ON)) {
return true;
}
return false;
}
//押されていないか?
bool IsFree (int PadHandle) {
if ((Input&PadHandle) == PAD_INPUT_OFF) {
return true;
}
return false;
}
//離されたか?
bool IsPull(int PadHandle) {
if ((EdgeInput&PadHandle) == PAD_INPUT_OFF) {
return true;
}
return false;
}
//押されているか?
bool IsHold (int PadHandle) {
if ((Input&PadHandle) > PAD_INPUT_ON) {
return true;
}
return false;
}
//マップチップのデータ獲得
int MapChipParam(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, int Size) {
float afX, afY;
afX = X + *MoveX;
afY = Y + *MoveY;
float blx, brx, bby, bty;
blx = (float)((int)afX / Size)*Size;
brx = (float)((int)afX / Size + 1)*Size;
bty = (float)((int)afY / Size)*Size;
bby = (float)((int)afY / Size + 1)*Size;
if (MapChipParam(afX, afY) == 1) {
if (*MoveY > 0.0F) {
printf("\n下に当たりました。");
//移動量を補正する
*MoveY = bty - Y - 1.0F;
//上の壁に当たったと判定する
return 3;
}
if (*MoveY < 0.0F) {
printf("\n上に当たりました。");
//移動量を補正する
*MoveY = bby - Y + 1.0F;
//下の壁に当たったと判定する
return 4;
}
//右の当たり判定
if (*MoveX > 0.0F) {
printf("\n右に当たりました。");
//移動量を補正する
*MoveX = blx - X - 1.0F;
//右の壁に当たったと判定する
return 1;
}
//左の当たり判定
if (*MoveX < 0.0F) {
printf("\n左に当たりました。");
//移動量を補正する
*MoveX = brx - X + 1.0F;
//左の壁に当たったと判定する
return 2;
}
//ここに来たら適当な値を返す
return 4;
}
return 0;
}
//当たり判定チェック
int 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){
float Dummy = 0.0F;
float hsize;
//直前フレーム
float PrevX = *X + MoveX;
float PrevY = *Y + MoveY;
//ベクトルのバックアップ
float SaveMoveX = MoveX;
float SaveMoveY = MoveY;
hsize = Size * 0.5F;
//上下の当たり判定チェック、上に衝突したら落下させ、下に衝突したら着地させる。
{
//左下
if (MapHitCheck(*X - hsize, *Y + hsize - 1.0F, &Dummy, &MoveY,(int)Size) == 3) *Drop = 0.0F,MoveY -= 1.0F,printf("\n上下::左下");
//右下
if (MapHitCheck(*X + hsize, *Y + hsize - 1.0F, &Dummy, &MoveY,(int)Size) == 3) *Drop = 0.0F,MoveY -= 1.0F,printf("\n上下::右下");
//左上
if (MapHitCheck(*X - hsize, *Y - hsize + 1.0F, &Dummy, &MoveY,(int)Size) == 4) *Drop *= -0.5F,MoveY = 0.0F,printf("\n上下::左上");
//右上
if (MapHitCheck(*X + hsize, *Y - hsize + 1.0F, &Dummy, &MoveY,(int)Size) == 4) *Drop *= -0.5F,MoveY = 0.0F,printf("\n上下::右上");
//問題ないのなら移動させる
PrevY = *Y + MoveY;
*Y = PrevY;
}
//左右の当たり判定チェック
{
//左下
if (MapHitCheck(*X - hsize + 1.0F, *Y + hsize, &MoveX, &Dummy, (int)Size))*Vect = 0.0F, MoveX += 1.0F, printf("\n左右::左下");
//右上
if (MapHitCheck(*X + hsize - 1.0F, *Y + hsize, &MoveX, &Dummy, (int)Size))*Vect = 0.0F, MoveX -= 1.0F, printf("\n左右::右下");
//左上
if (MapHitCheck(*X - hsize + 1.0F, *Y - hsize, &MoveX, &Dummy, (int)Size))*Vect = 0.0F, MoveX += 1.0F, printf("\n左右::左上");
//右上
if (MapHitCheck(*X + hsize - 1.0F, *Y - hsize, &MoveX, &Dummy, (int)Size))*Vect = 0.0F, MoveX -= 1.0F, printf("\n左右::右上");
//問題ないのなら移動させる
PrevX = *X + MoveX;
*X = PrevX;
}
//着地判定
{
if (MapChipParam(*X - hsize, *Y + hsize + 1.0F) == 0 && MapChipParam(*X + hsize, *Y + hsize + 1.0F) == 0) {
*Air = TRUE;
*G = 0.5F;
}
else {
*JumpT = 0;
*Drop = 0.0F;
*G = 0.0F;
*Air = FALSE;
*Vert = FALSE;
*Jump = FALSE;
}
}
return 0;
}
//カメラの位置計算
int CameraCheck(float X, float Y) {
//カメラのチェック
CharX = X;
CharY = Y;
//カメラの位置を計算する
CameraX = (int)CharX - SCREEN_WIDTH / 2;
CameraY = (int)CharY - SCREEN_HEIGHT / 2;
//カメラの補正
if (CameraX < 0)CameraX = 0;
if (CameraX >(STAGE_WIDTH - SCREEN_WIDTH))CameraX = (STAGE_WIDTH - SCREEN_WIDTH);
if (CameraY < 0)CameraY = 0;
if (CameraY >(STAGE_HEIGHT - SCREEN_HEIGHT))CameraY = (STAGE_HEIGHT - SCREEN_HEIGHT);
ViewCharX = CharX - CameraX;
ViewCharY = CharY - CameraY;
return 0;
}
int init(void) {
ChangeWindowMode(TRUE),SetGraphMode(320,240,32),printf("初期化しています…");
if (DxLib_Init() == -1) { return -1; }
PlayerX = 240.0F, PlayerY = 200.0F, MoveX = 0.0F, MoveY = 0.0F;
JumpFlag = FALSE, DropPower = 0.0F, Grav = 0.5F, Dir = TRUE;
Input = 0, EdgeInput = 0, FreamStartTime = GetNowCount();
NonVertJump = FALSE;
return 0;
}
int main(void) {
FreamStartTime = GetNowCount();
while (GetNowCount() - FreamStartTime < 1000 / 60) {}
system("cls");
printf("メインループ開始\n");
printf("\nPlayerX=%d,PlayerY=%d,Grav=%8.2f,DropPower=%8.2f", (int)PlayerX, (int)PlayerY, Grav,DropPower);
printf("\nMoveX=%8.1f,MoveY=%8.1f,Jump=%d", MoveX, MoveY,JumpFlag);
printf("\nCharX=%8.1f,CharY=%8.1f,CameraX=%d,CameraY=%d,ViewX=%8.1f,ViewY=%8.1f", CharX, CharY, CameraX, CameraY, ViewCharX, ViewCharY);
printf("\n現在の向き=%d\t右は1、左は0,NonVert = %d,VectX = %8.1f,JumpTimer = %d", Dir, NonVertJump, VectX,JumpTimer);
//カメラの処理を行う
CameraCheck(PlayerX, PlayerY);
//入力状態を更新
{
int i;
i = GetJoypadInputState(DX_INPUT_KEY_PAD1);
EdgeInput = i & ~Input;
Input = i;
}
//移動処理
{
float MaxVect;
int DashTimer = 8;
int ContTimer = 8;
DashCnt = 0;
ContCnt = 0;
//ベクトルを初期化し、加減速処理を行う。
if (NonVertJump == FALSE) {
MoveX = 0.0F;
VectX = 0.0F;
MaxVect = 0.0F;
}
else {
MoveX = VectX;
}
MoveY = 0.0F;
char RunButton;
//0なら移動していない、1なら右へ移動中、2なら左へ移動中
char NonVertJumpFlag = 0;
if ((Input&PAD_INPUT_2) > PAD_INPUT_ON) {
RunButton = TRUE;
}
else {
RunButton = FALSE;
}
//右へ移動
if (NonVertJump == FALSE && (Input&PAD_INPUT_RIGHT) > PAD_INPUT_ON) {
Dir = TRUE;
NonVertJumpFlag = 1;
if (RunButton == TRUE && JumpFlag == FALSE) {
MoveX = 8.0F;
}
else if (RunButton == FALSE && JumpFlag == FALSE) {
MoveX = 5.0F;
}
else {
MoveX = 3.0F;
}
}
//左に移動
if (NonVertJump == FALSE && (Input&PAD_INPUT_LEFT) > PAD_INPUT_ON) {
Dir = FALSE;
NonVertJumpFlag = 2;
if (RunButton == TRUE) {
MoveX = -8.0F;
}
else if (RunButton == FALSE && JumpFlag == FALSE) {
MoveX = -5.0F;
}
else {
MoveX = -3.0F;
}
}
//ジャンプボタンが押されているフレームを格納する。
if ((Input&PAD_INPUT_1) > PAD_INPUT_ON) {
JumpTimer++;
}
else {
JumpTimer = 0;
}
//長押しで重力が弱く、離せば、重力が強く。
if (JumpTimer > 0) {
if (JumpTimer == 1 && NonVertJumpFlag == 0 && JumpFlag == FALSE) {
JumpFlag = TRUE;
DropPower = -7.0F;
}
if (JumpTimer == 1 && NonVertJumpFlag == 1 && JumpFlag == FALSE) {
JumpFlag = TRUE;
DropPower = -7.0F;
if (RunButton == TRUE) {
VectX = 8.0F;
MaxVect = 8.0F;
}
else {
VectX = 5.0F;
MaxVect = 5.0F;
}
//斜めに飛んでいることを確認
NonVertJump = TRUE;
//コントロールカウントをリセット
ContCnt = 0;
}
if (JumpTimer == 1 && NonVertJumpFlag == 2 && JumpFlag == FALSE) {
JumpFlag = TRUE;
DropPower = -7.0F;
if (RunButton == TRUE) {
VectX = -8.0F;
}
else {
VectX = -5.0F;
}
NonVertJump = TRUE;
}
Grav = 0.25F;
}
else {
if (JumpFlag == TRUE) {
Grav = 0.5F;
}
}
}
//空中での移動を解禁する
if (NonVertJump == TRUE && VectX == 0 || DropPower > 0) {
VectX = 0.0F;
NonVertJump = FALSE;
}
//右へジャンプしているときに左で減速
if (NonVertJump == TRUE && VectX > 0 &&(Input&PAD_INPUT_LEFT) > PAD_INPUT_ON) {
//マリオ3以降よろしく、方向転換する。
Dir = FALSE;
VectX -= 0.5F;
if (DropPower < 0) {
DropPower += 0.1F;
}
MoveX = VectX;
}
//左へジャンプしているときに右で減速
if (NonVertJump == TRUE && VectX < 0 &&(Input&PAD_INPUT_RIGHT) > PAD_INPUT_ON) {
//マリオ3以降よろしく、方向転換する。
Dir = TRUE;
VectX += 0.5F;
if (DropPower < 0) {
DropPower += 0.1F;
}
MoveX = VectX;
}
ContCnt++;
//落下処理
DropPower += Grav;
MoveY = DropPower;
//移動量に基づいて移動する。
CharMove(&PlayerX, &PlayerY, MoveX, MoveY, &DropPower, &Grav, &JumpFlag, &AirFlag, &NonVertJump, &JumpTimer ,&VectX, CHIP_SIZE);
//マップの描画
{
int i, j;
for (i = 0; i < MAP_HEIGHT; i++) {
for (j = 0; j < MAP_WIDTH; j++) {
if (MapData[i][j] == 1) {
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);
}
}
}
}
//キャラの描画
DrawBox((int)(ViewCharX)-(CHIP_SIZE / 2), (int)(ViewCharY)-(CHIP_SIZE / 2), (int)(ViewCharX + CHIP_SIZE) - (CHIP_SIZE / 2), (int)(ViewCharY + CHIP_SIZE) - (CHIP_SIZE / 2), GetColor(255, 0, 0), TRUE);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
AllocConsole(); FILE* out = 0; freopen_s(&out, "CON", "w", stdout); Stdout = GetStdHandle(STD_OUTPUT_HANDLE);
init();
while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0) {
main();
}
DxLib_End(); fclose(out); FreeConsole();
return 0;
}
追記:バグが有ったみたいなので少し修正いたしました。
ごめんなさい、実は自己解決していました。それに際して前に質問いたした横へのジャンプも、そのルーチンに束ねました。
[code]
#include "DxLib.h"
#define SCREEN_WIDTH (320) //画面の横幅
#define SCREEN_HEIGHT (240) //画面の縦幅
#define STAGE_WIDTH (400)
#define STAGE_HEIGHT (320)
#define CHIP_SIZE (16) //チップのサイズ
#define MAP_WIDTH (STAGE_WIDTH/CHIP_SIZE)
#define MAP_HEIGHT (STAGE_HEIGHT/CHIP_SIZE)
#define JOYPAD_BUTTON_MAX (28)
#define PAD_INPUT_ON 1
#define PAD_INPUT_OFF 0
HANDLE Stdout;
//テスト用のマップデータ。実際の開発では、Tiled(フリーのマップエディタ)を使う予定。
//このテストプログラムがある程度の段階に達したら、本格的な開発に移ります。
//TinyXML2は便利だ
char 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,1,1,1,1,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
};
float PlayerX, PlayerY;
float SaveX, SaveY;
float MoveX, MoveY;
float VectX;
float DropPower, Grav;
char JumpFlag, Dir, AirFlag, NonVertJump;
int DashCnt, ContCnt, JumpTimer;
int Input, EdgeInput, Pad;
int FreamStartTime;
int CameraX = 0;
int CameraY = 0;
float CharX, CharY, ViewCharX, ViewCharY;
int MapHitCheck(float X, float Y, float *MoveX, float *MoveY, int Size);
int 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);
int MapChipParam(float X, float Y);
int CameraCheck(float X, float Y);
bool IsPush(int PadHandle);
bool IsFree(int PadHandle);
bool IsHold(int PadHandle);
bool IsPull(int PadHandle);
//将来の開発で使う予定の関数。
//押されたか?
bool IsPush(int PadHandle) {
if (((EdgeInput&PadHandle) > PAD_INPUT_ON)) {
return true;
}
return false;
}
//押されていないか?
bool IsFree (int PadHandle) {
if ((Input&PadHandle) == PAD_INPUT_OFF) {
return true;
}
return false;
}
//離されたか?
bool IsPull(int PadHandle) {
if ((EdgeInput&PadHandle) == PAD_INPUT_OFF) {
return true;
}
return false;
}
//押されているか?
bool IsHold (int PadHandle) {
if ((Input&PadHandle) > PAD_INPUT_ON) {
return true;
}
return false;
}
//マップチップのデータ獲得
int MapChipParam(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, int Size) {
float afX, afY;
afX = X + *MoveX;
afY = Y + *MoveY;
float blx, brx, bby, bty;
blx = (float)((int)afX / Size)*Size;
brx = (float)((int)afX / Size + 1)*Size;
bty = (float)((int)afY / Size)*Size;
bby = (float)((int)afY / Size + 1)*Size;
if (MapChipParam(afX, afY) == 1) {
if (*MoveY > 0.0F) {
printf("\n下に当たりました。");
//移動量を補正する
*MoveY = bty - Y - 1.0F;
//上の壁に当たったと判定する
return 3;
}
if (*MoveY < 0.0F) {
printf("\n上に当たりました。");
//移動量を補正する
*MoveY = bby - Y + 1.0F;
//下の壁に当たったと判定する
return 4;
}
//右の当たり判定
if (*MoveX > 0.0F) {
printf("\n右に当たりました。");
//移動量を補正する
*MoveX = blx - X - 1.0F;
//右の壁に当たったと判定する
return 1;
}
//左の当たり判定
if (*MoveX < 0.0F) {
printf("\n左に当たりました。");
//移動量を補正する
*MoveX = brx - X + 1.0F;
//左の壁に当たったと判定する
return 2;
}
//ここに来たら適当な値を返す
return 4;
}
return 0;
}
//当たり判定チェック
int 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){
float Dummy = 0.0F;
float hsize;
//直前フレーム
float PrevX = *X + MoveX;
float PrevY = *Y + MoveY;
//ベクトルのバックアップ
float SaveMoveX = MoveX;
float SaveMoveY = MoveY;
hsize = Size * 0.5F;
//上下の当たり判定チェック、上に衝突したら落下させ、下に衝突したら着地させる。
{
//左下
if (MapHitCheck(*X - hsize, *Y + hsize - 1.0F, &Dummy, &MoveY,(int)Size) == 3) *Drop = 0.0F,MoveY -= 1.0F,printf("\n上下::左下");
//右下
if (MapHitCheck(*X + hsize, *Y + hsize - 1.0F, &Dummy, &MoveY,(int)Size) == 3) *Drop = 0.0F,MoveY -= 1.0F,printf("\n上下::右下");
//左上
if (MapHitCheck(*X - hsize, *Y - hsize + 1.0F, &Dummy, &MoveY,(int)Size) == 4) *Drop *= -0.5F,MoveY = 0.0F,printf("\n上下::左上");
//右上
if (MapHitCheck(*X + hsize, *Y - hsize + 1.0F, &Dummy, &MoveY,(int)Size) == 4) *Drop *= -0.5F,MoveY = 0.0F,printf("\n上下::右上");
//問題ないのなら移動させる
PrevY = *Y + MoveY;
*Y = PrevY;
}
//左右の当たり判定チェック
{
//左下
if (MapHitCheck(*X - hsize + 1.0F, *Y + hsize, &MoveX, &Dummy, (int)Size))*Vect = 0.0F, MoveX += 1.0F, printf("\n左右::左下");
//右上
if (MapHitCheck(*X + hsize - 1.0F, *Y + hsize, &MoveX, &Dummy, (int)Size))*Vect = 0.0F, MoveX -= 1.0F, printf("\n左右::右下");
//左上
if (MapHitCheck(*X - hsize + 1.0F, *Y - hsize, &MoveX, &Dummy, (int)Size))*Vect = 0.0F, MoveX += 1.0F, printf("\n左右::左上");
//右上
if (MapHitCheck(*X + hsize - 1.0F, *Y - hsize, &MoveX, &Dummy, (int)Size))*Vect = 0.0F, MoveX -= 1.0F, printf("\n左右::右上");
//問題ないのなら移動させる
PrevX = *X + MoveX;
*X = PrevX;
}
//着地判定
{
if (MapChipParam(*X - hsize, *Y + hsize + 1.0F) == 0 && MapChipParam(*X + hsize, *Y + hsize + 1.0F) == 0) {
*Air = TRUE;
*G = 0.5F;
}
else {
*JumpT = 0;
*Drop = 0.0F;
*G = 0.0F;
*Air = FALSE;
*Vert = FALSE;
*Jump = FALSE;
}
}
return 0;
}
//カメラの位置計算
int CameraCheck(float X, float Y) {
//カメラのチェック
CharX = X;
CharY = Y;
//カメラの位置を計算する
CameraX = (int)CharX - SCREEN_WIDTH / 2;
CameraY = (int)CharY - SCREEN_HEIGHT / 2;
//カメラの補正
if (CameraX < 0)CameraX = 0;
if (CameraX >(STAGE_WIDTH - SCREEN_WIDTH))CameraX = (STAGE_WIDTH - SCREEN_WIDTH);
if (CameraY < 0)CameraY = 0;
if (CameraY >(STAGE_HEIGHT - SCREEN_HEIGHT))CameraY = (STAGE_HEIGHT - SCREEN_HEIGHT);
ViewCharX = CharX - CameraX;
ViewCharY = CharY - CameraY;
return 0;
}
int init(void) {
ChangeWindowMode(TRUE),SetGraphMode(320,240,32),printf("初期化しています…");
if (DxLib_Init() == -1) { return -1; }
PlayerX = 240.0F, PlayerY = 200.0F, MoveX = 0.0F, MoveY = 0.0F;
JumpFlag = FALSE, DropPower = 0.0F, Grav = 0.5F, Dir = TRUE;
Input = 0, EdgeInput = 0, FreamStartTime = GetNowCount();
NonVertJump = FALSE;
return 0;
}
int main(void) {
FreamStartTime = GetNowCount();
while (GetNowCount() - FreamStartTime < 1000 / 60) {}
system("cls");
printf("メインループ開始\n");
printf("\nPlayerX=%d,PlayerY=%d,Grav=%8.2f,DropPower=%8.2f", (int)PlayerX, (int)PlayerY, Grav,DropPower);
printf("\nMoveX=%8.1f,MoveY=%8.1f,Jump=%d", MoveX, MoveY,JumpFlag);
printf("\nCharX=%8.1f,CharY=%8.1f,CameraX=%d,CameraY=%d,ViewX=%8.1f,ViewY=%8.1f", CharX, CharY, CameraX, CameraY, ViewCharX, ViewCharY);
printf("\n現在の向き=%d\t右は1、左は0,NonVert = %d,VectX = %8.1f,JumpTimer = %d", Dir, NonVertJump, VectX,JumpTimer);
//カメラの処理を行う
CameraCheck(PlayerX, PlayerY);
//入力状態を更新
{
int i;
i = GetJoypadInputState(DX_INPUT_KEY_PAD1);
EdgeInput = i & ~Input;
Input = i;
}
//移動処理
{
float MaxVect;
int DashTimer = 8;
int ContTimer = 8;
DashCnt = 0;
ContCnt = 0;
//ベクトルを初期化し、加減速処理を行う。
if (NonVertJump == FALSE) {
MoveX = 0.0F;
VectX = 0.0F;
MaxVect = 0.0F;
}
else {
MoveX = VectX;
}
MoveY = 0.0F;
char RunButton;
//0なら移動していない、1なら右へ移動中、2なら左へ移動中
char NonVertJumpFlag = 0;
if ((Input&PAD_INPUT_2) > PAD_INPUT_ON) {
RunButton = TRUE;
}
else {
RunButton = FALSE;
}
//右へ移動
if (NonVertJump == FALSE && (Input&PAD_INPUT_RIGHT) > PAD_INPUT_ON) {
Dir = TRUE;
NonVertJumpFlag = 1;
if (RunButton == TRUE && JumpFlag == FALSE) {
MoveX = 8.0F;
}
else if (RunButton == FALSE && JumpFlag == FALSE) {
MoveX = 5.0F;
}
else {
MoveX = 3.0F;
}
}
//左に移動
if (NonVertJump == FALSE && (Input&PAD_INPUT_LEFT) > PAD_INPUT_ON) {
Dir = FALSE;
NonVertJumpFlag = 2;
if (RunButton == TRUE) {
MoveX = -8.0F;
}
else if (RunButton == FALSE && JumpFlag == FALSE) {
MoveX = -5.0F;
}
else {
MoveX = -3.0F;
}
}
//ジャンプボタンが押されているフレームを格納する。
if ((Input&PAD_INPUT_1) > PAD_INPUT_ON) {
JumpTimer++;
}
else {
JumpTimer = 0;
}
//長押しで重力が弱く、離せば、重力が強く。
if (JumpTimer > 0) {
if (JumpTimer == 1 && NonVertJumpFlag == 0 && JumpFlag == FALSE) {
JumpFlag = TRUE;
DropPower = -7.0F;
}
if (JumpTimer == 1 && NonVertJumpFlag == 1 && JumpFlag == FALSE) {
JumpFlag = TRUE;
DropPower = -7.0F;
if (RunButton == TRUE) {
VectX = 8.0F;
MaxVect = 8.0F;
}
else {
VectX = 5.0F;
MaxVect = 5.0F;
}
//斜めに飛んでいることを確認
NonVertJump = TRUE;
//コントロールカウントをリセット
ContCnt = 0;
}
if (JumpTimer == 1 && NonVertJumpFlag == 2 && JumpFlag == FALSE) {
JumpFlag = TRUE;
DropPower = -7.0F;
if (RunButton == TRUE) {
VectX = -8.0F;
}
else {
VectX = -5.0F;
}
NonVertJump = TRUE;
}
Grav = 0.25F;
}
else {
if (JumpFlag == TRUE) {
Grav = 0.5F;
}
}
}
//空中での移動を解禁する
if (NonVertJump == TRUE && VectX == 0 || DropPower > 0) {
VectX = 0.0F;
NonVertJump = FALSE;
}
//右へジャンプしているときに左で減速
if (NonVertJump == TRUE && VectX > 0 &&(Input&PAD_INPUT_LEFT) > PAD_INPUT_ON) {
//マリオ3以降よろしく、方向転換する。
Dir = FALSE;
VectX -= 0.5F;
if (DropPower < 0) {
DropPower += 0.1F;
}
MoveX = VectX;
}
//左へジャンプしているときに右で減速
if (NonVertJump == TRUE && VectX < 0 &&(Input&PAD_INPUT_RIGHT) > PAD_INPUT_ON) {
//マリオ3以降よろしく、方向転換する。
Dir = TRUE;
VectX += 0.5F;
if (DropPower < 0) {
DropPower += 0.1F;
}
MoveX = VectX;
}
ContCnt++;
//落下処理
DropPower += Grav;
MoveY = DropPower;
//移動量に基づいて移動する。
CharMove(&PlayerX, &PlayerY, MoveX, MoveY, &DropPower, &Grav, &JumpFlag, &AirFlag, &NonVertJump, &JumpTimer ,&VectX, CHIP_SIZE);
//マップの描画
{
int i, j;
for (i = 0; i < MAP_HEIGHT; i++) {
for (j = 0; j < MAP_WIDTH; j++) {
if (MapData[i][j] == 1) {
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);
}
}
}
}
//キャラの描画
DrawBox((int)(ViewCharX)-(CHIP_SIZE / 2), (int)(ViewCharY)-(CHIP_SIZE / 2), (int)(ViewCharX + CHIP_SIZE) - (CHIP_SIZE / 2), (int)(ViewCharY + CHIP_SIZE) - (CHIP_SIZE / 2), GetColor(255, 0, 0), TRUE);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
AllocConsole(); FILE* out = 0; freopen_s(&out, "CON", "w", stdout); Stdout = GetStdHandle(STD_OUTPUT_HANDLE);
init();
while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0) {
main();
}
DxLib_End(); fclose(out); FreeConsole();
return 0;
}
[/code]
追記:バグが有ったみたいなので少し修正いたしました。