マリオ風のジャンプが出ない。(意図したとおりにならない)

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら

トピックに返信する


答えを正確にご入力ください。答えられるかどうかでスパムボットか否かを判定します。

BBCode: ON
[img]: ON
[flash]: OFF
[url]: ON
スマイリー: OFF

トピックのレビュー
   

展開ビュー トピックのレビュー: マリオ風のジャンプが出ない。(意図したとおりにならない)

Re: マリオ風のジャンプが出ない。(意図したとおりにならない)

#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;
}
追記:バグが有ったみたいなので少し修正いたしました。

Re: マリオ風のジャンプが出ない。(意図したとおりにならない)

#16

by Math » 7年前

キーは押し続けると連続入力になります。[例]a aaaaaaaaaaaaa.....プログラム例はそれを抑止します。
開発者コマンドプロンプトが見つかったら最新のDxLibを設定します。
http://dxlib.o.oo7.jp/dxdload.htmlここからVer3.17eをダウンロードしてその中の
プロジェクトに追加すべきファイル_VC用”をD:\ドライブがにコピーして”名前をdxlibにかえます。これで最新のDxLibの設定は終わりです。
---
d:\ドライブにgmフォルダーを作りその中にg1フォルダーを作ります。その中にg.batをつくります。
d:\gm\g.bat

コード:

nmake -f g.mak
次にd:\gm\g.mak

コード:

TARGETNAME=g1

C_FLAGS=/c /TP /EHsc /D "_MBCS" /MT  /Id:\dxlib /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /W3 

LINK_FLAGS=/SUBSYSTEM:WINDOWS /LIBPATH:d:\dxlib "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" 

ALL:
	cl $(C_FLAGS) $(TARGETNAME).cpp
	link /out:$(TARGETNAME).exe $(LINK_FLAGS) $(TARGETNAME).obj
	$(TARGETNAME).exe

次にc:\gm\g1.cpp

コード:

#include "DxLib.h"
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    ChangeWindowMode(TRUE);SetGraphMode(320,240,32);///////
    DxLib_Init();SetDrawScreen(DX_SCREEN_BACK);////////////

    int x;      //x座標
    int y;      //y座標
    int size;   //プレイヤーのサイズ 今回は正方形とする。
    double vx;  //x方向への加速度
    double vy;  //y方向への加速度
 
    int cnt_z;  //Zキーの押されたフレーム数
    const double JUMP_P = 16;   //プレイヤーのジャンプパワー

    const double G_on = 0.4;    //キーが押されているときの重力
    const double G_off = 1.6;   //キーが押されていないときの重力
    const int W_WIDTH = 320;    //ウィンドウの高さ
    const int W_HEIGHT = 240;   //ウィンドウの幅
 
    //ゲーム初期化
    x = W_WIDTH / 2;
    y = W_HEIGHT / 2;
    vx = 0;
    vy = 0;
    cnt_z = 0;
    size = 16;
 
    // ループ
    while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0){
 
        //Zキーの押されたフレーム数を格納する。
        if (CheckHitKey(KEY_INPUT_Z) != 0){
            cnt_z++;
        }else{
            cnt_z = 0;
        }
 
        //Zキーが押されている間
        if (cnt_z > 0){
            //Zキーが押された瞬間、かつ地面に接していたら
            if (cnt_z == 1 && y == W_HEIGHT - size){
                vy = JUMP_P;    //ジャンプ力を与える
            }
            vy -= G_on;//押されてる間は重力を弱めに
        }else{
            vy -= G_off;//そうでないときは重力を強めに
        }
 
        y = y - vy;     //実際に座標に対して計算
 
        //めり込み防止
        if (y > W_HEIGHT - size){
            y = W_HEIGHT - size;
            vy = 0;
        }
 
        //描画
        DrawBox(x, y, x + size, y + size, GetColor(255, 255, 255), true);
    }
 
    DxLib_End();return 0;////////////////////////
}
これで完了しました。
開発者コマンドプロンプトを立ち上げ

コード:

C:\Program Files (x86)\Microsoft Visual Studio 14.0>d:

D:\>cd gm

D:\gm>cd g1

D:\gm\g1>g

D:\gm\g1>nmake -f g.mak

Microsoft(R) Program Maintenance Utility Version 14.00.24210.0
Copyright (C) Microsoft Corporation.  All rights reserved.

        cl /c /TP /EHsc /D "_MBCS" /MT  /Id:\dxlib /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /W3 g1.cpp
Microsoft(R) C/C++ Optimizing Compiler Version 19.00.24215.1 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

g1.cpp
g1.cpp(50): warning C4244: '=': 'double' から 'int' への変換です。データが失われる可能性があります 。
        link /out:g1.exe /SUBSYSTEM:WINDOWS /LIBPATH:"d:\DxLib_VC\プロジェクトに追加すべきファイル_VC用" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" g1.obj
Microsoft (R) Incremental Linker Version 14.00.24215.1
Copyright (C) Microsoft Corporation.  All rights reserved.

        g1.exe

D:\gm\g1>g
(動かない場合私のホームページhttp://cswin10.nisinippon.com/cs/cs1/vs ... /dx01.htmlをみてください。
[/size]

Re: マリオ風のジャンプが出ない。(意図したとおりにならない)

#15

by keito940 » 7年前

サンプルコードをテストしてみたんですが、そういう感じなんですね。了解いたしました!!
ちょっと日本語がおかしいですが、大体はその通りです。
ですが、何回でも垂直でジャンプできてしまいます。開発者コマンドプロンプトによるとジャンプフラグが立っていないことにあるようです。

コード:

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) {
				DropPower = -9.50F;
			}
			JumpFlag == TRUE;
			Grav = 0.25F;
		}
		else {
			if (JumpFlag == TRUE) {
				Grav = 0.5F;
			}
		}
		//斜めへジャンプ
		if (JumpFlag == FALSE && NonVertJumpFlag == 1 && (EdgeInput&PAD_INPUT_1) > PAD_INPUT_ON) {
			Grav = 0.5F;
			DropPower = -9.5F;
			if (RunButton == TRUE) {
				VectX = 8.0F;
				MaxVect = 8.0F;
			}
			else {
				VectX = 5.0F;
				MaxVect = 5.0F;
			}
			//斜めに飛んでいることを確認
			NonVertJump = TRUE;
			JumpFlag = TRUE;
			//コントロールカウントをリセット
			ContCnt = 0;
		}
		if (JumpFlag == FALSE && NonVertJumpFlag == 2 && (EdgeInput&PAD_INPUT_1) > PAD_INPUT_ON) {
				Grav = 0.5F;
				DropPower = -9.5F;
				if (RunButton == TRUE) {
					VectX = -8.0F;
				}
				else {
					VectX = -5.0F;
				}
				//斜めに飛んでいることを確認
				NonVertJump = TRUE;
				JumpFlag = TRUE;
				//コントロールカウントをリセット
				ContCnt = 0;
				}
		}

		if (NonVertJump == TRUE && VectX == 0) {
			NonVertJump = FALSE;
		}
		//右へジャンプしているときに左で減速
		if (NonVertJump == TRUE && VectX > 0 &&(Input&PAD_INPUT_LEFT) > PAD_INPUT_ON) {
			VectX -= 0.5F;
			if (DropPower < 0) {
				DropPower += 0.1F;
			}
			else {
				DropPower -= 0.1F;
			}
			MoveX = VectX;
		}
		//左へジャンプしているときに右で減速
		if (NonVertJump == TRUE && VectX < 0 &&(Input&PAD_INPUT_RIGHT) > PAD_INPUT_ON) {
			VectX += 0.5F;
			if (DropPower < 0) {
				DropPower += 0.1F;
			}
			else {
				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);
}

Re: マリオ風のジャンプが出ない。(意図したとおりにならない)

#14

by Math » 7年前

サンプルは単独でテストして頂きましたでしょうか。
どのような問題点があるのでしょう?
[開発環境なVS2015でしょうか?開発者コマンドプロンプトはお使いですか?。(短いサンプルはコマンドプロンプトが便利だし一瞬で立ち上がる。沢山のサンプルをうまく組み合わせて大きなプログラムにしないとbugった時面倒ですね]

Re: マリオ風のジャンプが出ない。(意図したとおりにならない)

#13

by keito940 » 7年前

Mathさん、いつもありがとうございます。ですが、今のコードでは、小ジャンプしか出ません。
10F押せば、大ジャンプが出るのですが…。コードは以下のとおりです。

コード:

int main(void) {
	FreamStartTime = GetNowCount();
	while (GetNowCount() - FreamStartTime < 1000 / 60) {}
	system("cls");
	printf("メインループ開始\n");
	printf("\nPlayerX=%d,PlayerY=%d,Grav=%8.1f,DropPower=%8.1f", (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 (JumpFlag == FALSE && JumpTimer == 10 && NonVertJumpFlag == 0) {
				Grav = 0.5F;
				DropPower = -9.5F;
				JumpFlag = TRUE;
			}
			else if (JumpFlag == FALSE && JumpTimer < 10 && NonVertJumpFlag == 0) {
				Grav = 1.0F;
				DropPower = -5.0F;
				JumpFlag = TRUE;
			}
		}
		//斜めへジャンプ
		if (JumpFlag == FALSE && NonVertJumpFlag == 1 && (EdgeInput&PAD_INPUT_1) > PAD_INPUT_ON) {
			Grav = 0.5F;
			DropPower = -9.5F;
			if (RunButton == TRUE) {
				VectX = 8.0F;
				MaxVect = 8.0F;
			}
			else {
				VectX = 5.0F;
				MaxVect = 5.0F;
			}
			//斜めに飛んでいることを確認
			NonVertJump = TRUE;
			JumpFlag = TRUE;
			//コントロールカウントをリセット
			ContCnt = 0;
		}
		if (JumpFlag == FALSE && NonVertJumpFlag == 2 && (EdgeInput&PAD_INPUT_1) > PAD_INPUT_ON) {
				Grav = 0.5F;
				DropPower = -9.5F;
				if (RunButton == TRUE) {
					VectX = -8.0F;
				}
				else {
					VectX = -5.0F;
				}
				//斜めに飛んでいることを確認
				NonVertJump = TRUE;
				JumpFlag = TRUE;
				//コントロールカウントをリセット
				ContCnt = 0;
				}
		}

		if (NonVertJump == TRUE && VectX == 0) {
			NonVertJump = FALSE;
		}
		//右へジャンプしているときに左で減速
		if (NonVertJump == TRUE && VectX > 0 &&(Input&PAD_INPUT_LEFT) > PAD_INPUT_ON) {
			VectX -= 0.5F;
			if (DropPower < 0) {
				DropPower += 0.1F;
			}
			else {
				DropPower -= 0.1F;
			}
			MoveX = VectX;
		}
		//左へジャンプしているときに右で減速
		if (NonVertJump == TRUE && VectX < 0 &&(Input&PAD_INPUT_RIGHT) > PAD_INPUT_ON) {
			VectX += 0.5F;
			if (DropPower < 0) {
				DropPower += 0.1F;
			}
			else {
				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);
}

Re: マリオ風のジャンプが出ない。(意図したとおりにならない)

#12

by Math » 7年前

そう言うことだったのですね!
それではこういうのはどうでしょうか。

コード:

#include "DxLib.h"
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    ChangeWindowMode(TRUE);SetGraphMode(320,240,32);///////
    DxLib_Init();SetDrawScreen(DX_SCREEN_BACK);////////////

    int x;      //x座標
    int y;      //y座標
    int size;   //プレイヤーのサイズ 今回は正方形とする。
    double vx;  //x方向への加速度
    double vy;  //y方向への加速度
 
    int cnt_z;  //Zキーの押されたフレーム数

    const double JUMP_P = 16;   //プレイヤーのジャンプパワー
    const double G_on = 0.4;    //キーが押されているときの重力
    const double G_off = 1.6;   //キーが押されていないときの重力
    const int W_WIDTH = 320;    //ウィンドウの高さ
    const int W_HEIGHT = 240;   //ウィンドウの幅
 
    //ゲーム初期化
    x = W_WIDTH / 2;
    y = W_HEIGHT / 2;
    vx = 0;
    vy = 0;
    cnt_z = 0;
    size = 16;
 
    // ループ
    while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0){
 
        //Zキーの押されたフレーム数を格納する。
        if (CheckHitKey(KEY_INPUT_Z) != 0){
            cnt_z++;
        }else{
            cnt_z = 0;
        }
 
        //Zキーが押されている間
        if (cnt_z > 0){
            //Zキーが押された瞬間、かつ地面に接していたら
            if (cnt_z == 1 && y == W_HEIGHT - size){
                vy = JUMP_P;    //ジャンプ力を与える
            }
            vy -= G_on;//押されてる間は重力を弱めに
        }else{
            vy -= G_off;//そうでないときは重力を強めに
        }
 
        y = y - vy;     //実際に座標に対して計算
 
        //めり込み防止
        if (y > W_HEIGHT - size){
            y = W_HEIGHT - size;
            vy = 0;
        }
 
        //描画
        DrawBox(x, y, x + size, y + size, GetColor(255, 255, 255), true);
    }
 
    DxLib_End();return 0;////////////////////////
}

Re: マリオ風のジャンプが出ない。(意図したとおりにならない)

#11

by keito940 » 7年前

usao さんが書きました:まず,「マリオ風のジャンプ」…って何ですか? っていう具体的定義が不明.
usaoさん、ちょっと僕の説明が不適切でしたね…。僕の言うマリオ風と言うのは、「押す時間によってジャンプする距離が異なる」がわかりやすいでしょうか?でも、今のコードで押し続けていると、ジャンプし続けてしまうからこの質問をしているのです。
(私の知っているマリオとは違うけども)
一時期、ボタンを離すまではジャンプしないのかと思っていました。ごめんなさい。

Re: マリオ風のジャンプが出ない。(意図したとおりにならない)

#10

by usao » 7年前

オフトピック
まず,「マリオ風のジャンプ」…って何ですか? っていう具体的定義が不明.


>どうしたら、ジャンプボタンを離したと同時にジャンプできるんだろうか…

「ボタンを離すまではジャンプしない」という挙動(タメ的な?)にしたいのでしょうか.
(私の知っているマリオとは違うけども)

Re: マリオ風のジャンプが出ない。(意図したとおりにならない)

#9

by keito940 » 7年前

Math さんが書きました:http://dixq.net/forum/viewtopic.php?f=3&t=18930に載せたコードは参考になりませんか?)
確かに参考にはなるんですが…。僕が考えているのとは違うと思います。

Re: マリオ風のジャンプが出ない。(意図したとおりにならない)

#8

by Math » 7年前

http://dixq.net/forum/viewtopic.php?f=3&t=18930に載せたコードは参考になりませんか?)

Re: マリオ風のジャンプが出ない。

#7

by keito940 » 7年前

今現在のコードはこんな感じです。何か回答はありますか?

コード:

int main(void) {
	FreamStartTime = GetNowCount();
	while (GetNowCount() - FreamStartTime < 1000 / 60) {}
	system("cls");
	printf("メインループ開始\n");
	printf("\nPlayerX=%d,PlayerY=%d,Grav=%8.1f,DropPower=%8.1f", (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;
			}
		}
		//ジャンプの処理について:押している間はJumpTimerが加算され、離れたらジャンプする。
		//今のコードのジャンプは押している間もジャンプして長く押していたら大ジャンプするというとんでも仕様。
		if (JumpTimer > 0 && JumpFlag == FALSE) {
			if ((Input&PAD_INPUT_1) > PAD_INPUT_ON) {
				JumpTimer++;
			}
		}
		else {
			if ((Input&PAD_INPUT_1) > JumpTimer) {
				if (JumpTimer == 10 && NonVertJumpFlag == 0) {
					Grav = 0.5F;
					DropPower = -9.5F;
					JumpFlag = TRUE;
				}
				else if (JumpTimer < 10 && NonVertJumpFlag == 0) {
					Grav = 1.0F;
					DropPower = -5.0F;
					JumpFlag = TRUE;
				}
			}
			JumpTimer++;
		}
		//斜めへジャンプ
		if (JumpFlag == FALSE && NonVertJumpFlag == 1 && (EdgeInput&PAD_INPUT_1) > PAD_INPUT_ON) {
			Grav = 0.5F;
			DropPower = -9.5F;
			if (RunButton == TRUE) {
				VectX = 8.0F;
				MaxVect = 8.0F;
			}
			else {
				VectX = 5.0F;
				MaxVect = 5.0F;
			}
			//斜めに飛んでいることを確認
			NonVertJump = TRUE;
			JumpFlag = TRUE;
			//コントロールカウントをリセット
			ContCnt = 0;
		}
		if (JumpFlag == FALSE && NonVertJumpFlag == 2 && (EdgeInput&PAD_INPUT_1) > PAD_INPUT_ON) {
				Grav = 0.5F;
				DropPower = -9.5F;
				if (RunButton == TRUE) {
					VectX = -8.0F;
				}
				else {
					VectX = -5.0F;
				}
				//斜めに飛んでいることを確認
				NonVertJump = TRUE;
				JumpFlag = TRUE;
				//コントロールカウントをリセット
				ContCnt = 0;
				}
		}

		if (NonVertJump == TRUE && VectX == 0) {
			NonVertJump = FALSE;
		}
		//右へジャンプしているときに左で減速
		if (NonVertJump == TRUE && VectX > 0 &&(Input&PAD_INPUT_LEFT) > PAD_INPUT_ON) {
			VectX -= 0.5F;
			if (DropPower < 0) {
				DropPower += 0.1F;
			}
			else {
				DropPower -= 0.1F;
			}
			MoveX = VectX;
		}
		//左へジャンプしているときに右で減速
		if (NonVertJump == TRUE && VectX < 0 &&(Input&PAD_INPUT_RIGHT) > PAD_INPUT_ON) {
			VectX += 0.5F;
			if (DropPower < 0) {
				DropPower += 0.1F;
			}
			else {
				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);
}

Re: マリオ風のジャンプが出ない。

#6

by keito940 » 7年前

いや解決じゃなかった、ジェットみたいなジャンプになっているんだった!!どうしたら、ジャンプボタンを離したと同時にジャンプできるんだろうか…

Re: マリオ風のジャンプが出ない。

#5

by keito940 » 7年前

ごめんなさい、また自己解決しました!!

コード:

int main(void) {
	FreamStartTime = GetNowCount();
	while (GetNowCount() - FreamStartTime < 1000 / 60) {}
	system("cls");
	printf("メインループ開始\n");
	printf("\nPlayerX=%d,PlayerY=%d,Grav=%8.1f,DropPower=%8.1f", (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;
		JumpTimer = 0;
		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 (JumpTimer > 0 && JumpFlag == FALSE) {
			if ((Input&PAD_INPUT_1) > PAD_INPUT_ON) {
				JumpTimer++;
			}
		}
		else {
			if ((Input&PAD_INPUT_1) > PAD_INPUT_OFF) {
				if (JumpTimer == 10 && NonVertJumpFlag == 0) {
					Grav = 0.5F;
					DropPower = -9.5F;
					JumpFlag = TRUE;
				}
				else if (JumpTimer < 10 && NonVertJumpFlag == 0) {
					Grav = 1.0F;
					DropPower = -5.0F;
					JumpFlag = TRUE;
				}
			}
			JumpTimer++;
		}
		//斜めへジャンプ
		if (JumpFlag == FALSE && NonVertJumpFlag == 1 && (EdgeInput&PAD_INPUT_1) > PAD_INPUT_ON) {
			Grav = 0.5F;
			DropPower = -9.5F;
			if (RunButton == TRUE) {
				VectX = 8.0F;
				MaxVect = 8.0F;
			}
			else {
				VectX = 5.0F;
				MaxVect = 5.0F;
			}
			//斜めに飛んでいることを確認
			NonVertJump = TRUE;
			JumpFlag = TRUE;
			//コントロールカウントをリセット
			ContCnt = 0;
		}
		if (JumpFlag == FALSE && NonVertJumpFlag == 2 && (EdgeInput&PAD_INPUT_1) > PAD_INPUT_ON) {
				Grav = 0.5F;
				DropPower = -9.5F;
				if (RunButton == TRUE) {
					VectX = -8.0F;
				}
				else {
					VectX = -5.0F;
				}
				//斜めに飛んでいることを確認
				NonVertJump = TRUE;
				JumpFlag = TRUE;
				//コントロールカウントをリセット
				ContCnt = 0;
				}
		}

		if (NonVertJump == TRUE && VectX == 0) {
			NonVertJump = FALSE;
		}
		//右へジャンプしているときに左で減速
		if (NonVertJump == TRUE && VectX > 0 &&(Input&PAD_INPUT_LEFT) > PAD_INPUT_ON) {
			VectX -= 0.5F;
			if (DropPower < 0) {
				DropPower += 0.1F;
			}
			else {
				DropPower -= 0.1F;
			}
			MoveX = VectX;
		}
		//左へジャンプしているときに右で減速
		if (NonVertJump == TRUE && VectX < 0 &&(Input&PAD_INPUT_RIGHT) > PAD_INPUT_ON) {
			VectX += 0.5F;
			if (DropPower < 0) {
				DropPower += 0.1F;
			}
			else {
				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);
}

Re: マリオ風のジャンプが出ない。

#4

by keito940 » 7年前

あと、少し変更してあります。斜めのジャンプはジャンプカウントに依存しないので出るのですが…。

コード:

int main(void) {
	FreamStartTime = GetNowCount();
	while (GetNowCount() - FreamStartTime < 1000 / 60) {}
	system("cls");
	printf("メインループ開始\n");
	printf("\nPlayerX=%d,PlayerY=%d,Grav=%8.1f,DropPower=%8.1f", (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 (JumpTimer == 0 && JumpFlag == FALSE && (Input&PAD_INPUT_1) > PAD_INPUT_ON) {
			JumpTimer++;
		}
		if ((Input&PAD_INPUT_1) == PAD_INPUT_OFF && JumpTimer == 10 && NonVertJumpFlag == 0) {
			Grav = 0.5F;
			DropPower = -9.5F;
			JumpFlag = TRUE;
		}
		if ((Input&PAD_INPUT_1) == PAD_INPUT_OFF && JumpTimer > 10 && NonVertJumpFlag == 0) {
			Grav = 0.5F;
			DropPower = -5.0F;
			JumpFlag = TRUE;
		}
			//斜めへジャンプ
		if (JumpFlag == FALSE && NonVertJumpFlag == 1 && (EdgeInput&PAD_INPUT_1) > PAD_INPUT_ON) {
			Grav = 0.5F;
			DropPower = -9.5F;
			if (RunButton == TRUE) {
				VectX = 8.0F;
				MaxVect = 8.0F;
			}
			else {
				VectX = 5.0F;
				MaxVect = 5.0F;
			}
			//斜めに飛んでいることを確認
			NonVertJump = TRUE;
			JumpFlag = TRUE;
			//コントロールカウントをリセット
			ContCnt = 0;
		}
		if (JumpFlag == FALSE && NonVertJumpFlag == 2 && (EdgeInput&PAD_INPUT_1) > PAD_INPUT_ON) {
				Grav = 0.5F;
				DropPower = -9.5F;
				if (RunButton == TRUE) {
					VectX = -8.0F;
				}
				else {
					VectX = -5.0F;
				}
				//斜めに飛んでいることを確認
				NonVertJump = TRUE;
				JumpFlag = TRUE;
				//コントロールカウントをリセット
				ContCnt = 0;
				}
		}

		if (NonVertJump == TRUE && VectX == 0) {
			NonVertJump = FALSE;
		}
		//右へジャンプしているときに左で減速
		if (NonVertJump == TRUE && VectX > 0 &&(Input&PAD_INPUT_LEFT) > PAD_INPUT_ON) {
			VectX -= 0.5F;
			if (DropPower < 0) {
				DropPower += 0.1F;
			}
			else {
				DropPower -= 0.1F;
			}
			MoveX = VectX;
		}
		//左へジャンプしているときに右で減速
		if (NonVertJump == TRUE && VectX < 0 &&(Input&PAD_INPUT_RIGHT) > PAD_INPUT_ON) {
			VectX += 0.5F;
			if (DropPower < 0) {
				DropPower += 0.1F;
			}
			else {
				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);
}

Re: マリオ風のジャンプが出ない。

#3

by keito940 » 7年前

あっ、そうか、全体のコードを出さなければいけないのか!
というわけでプログラム全体のコードを出します。

コード:

//衝突のテストプログラム(だった)
//アクションゲームのテストシステムを作る前に、
//めり込み防止のアルゴリズムを初心者なりに作らざるをえない。
//(完成しました)
//でも現在はアクションゲーム全般のテストプログラムになりつつある…。
//現在マリオで使われるジャンプの加減速で悪戦苦闘中…。
//サンプルコードのジョイパッドのやつは欠陥だらけらしいことに気づき、ちょっと書き直し中…。
//(やっぱり、これでよかったのか…。)
//しかしどうしたら加減速ができるんだ?
//そうか!スピードを保存して、移動している方向を決めればいいんだ!
//Create 2017/02/10
#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,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,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, float 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,float 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.1f,DropPower=%8.1f", (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 (JumpTimer == 0 && JumpFlag == FALSE && (Input&PAD_INPUT_1) > PAD_INPUT_ON) {
			JumpTimer++;
		}
		if (JumpTimer == 10 && NonVertJumpFlag == 0) {
			Grav = 0.5F;
			DropPower = -9.5F;
			JumpFlag = TRUE;
		}
		if (JumpTimer > 10 && NonVertJumpFlag == 0) {
			Grav = 0.5F;
			DropPower = -5.0F;
			JumpFlag = TRUE;
		}
			//斜めへジャンプ
		if (JumpFlag == FALSE && NonVertJumpFlag == 1 && (EdgeInput&PAD_INPUT_1) > PAD_INPUT_ON) {
			Grav = 0.5F;
			DropPower = -9.5F;
			if (RunButton == TRUE) {
				VectX = 8.0F;
				MaxVect = 8.0F;
			}
			else {
				VectX = 5.0F;
				MaxVect = 5.0F;
			}
			//斜めに飛んでいることを確認
			NonVertJump = TRUE;
			JumpFlag = TRUE;
			//コントロールカウントをリセット
			ContCnt = 0;
		}
		if (JumpFlag == FALSE && NonVertJumpFlag == 2 && (EdgeInput&PAD_INPUT_1) > PAD_INPUT_ON) {
				Grav = 0.5F;
				DropPower = -9.5F;
				if (RunButton == TRUE) {
					VectX = -8.0F;
				}
				else {
					VectX = -5.0F;
				}
				//斜めに飛んでいることを確認
				NonVertJump = TRUE;
				JumpFlag = TRUE;
				//コントロールカウントをリセット
				ContCnt = 0;
				}
		}

		if (NonVertJump == TRUE && VectX == 0) {
			NonVertJump = FALSE;
		}
		//右へジャンプしているときに左で減速
		if (NonVertJump == TRUE && VectX > 0 &&(Input&PAD_INPUT_LEFT) > PAD_INPUT_ON) {
			VectX -= 0.5F;
			if (DropPower < 0) {
				DropPower += 0.1F;
			}
			else {
				DropPower -= 0.1F;
			}
			MoveX = VectX;
		}
		//左へジャンプしているときに右で減速
		if (NonVertJump == TRUE && VectX < 0 &&(Input&PAD_INPUT_RIGHT) > PAD_INPUT_ON) {
			VectX += 0.5F;
			if (DropPower < 0) {
				DropPower += 0.1F;
			}
			else {
				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;
}

Re: マリオ風のジャンプが出ない。

#2

by keito940 » 7年前

何かと思えば、ちょっとしたミスだったんですね。すいませんでした。前のスレにも書いたように http://dixq.net/forum/viewtopic.php?f=3&t=11328 を参考にして、ジャンプを実装しようとしているのですが、ジャンプボタンを押しているつもりなのに何故か出ません。コンソールによれば、JumpTimerが、0のままなことにあるようです。コードは以下のとおりです。

コード:


int main(void) {
	FreamStartTime = GetNowCount();
	while (GetNowCount() - FreamStartTime < 1000 / 60) {}
	system("cls");
	printf("メインループ開始\n");
	printf("\nPlayerX=%d,PlayerY=%d,Grav=%8.1f,DropPower=%8.1f", (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 (JumpTimer == 0 && JumpFlag == FALSE && (Input&PAD_INPUT_1) > PAD_INPUT_ON) {
			JumpTimer++;
		}
		if (JumpTimer == 10 && NonVertJumpFlag == 0) {
			Grav = 0.5F;
			DropPower = -9.5F;
			JumpFlag = TRUE;
		}
		if (JumpTimer > 10 && NonVertJumpFlag == 0) {
			Grav = 0.5F;
			DropPower = -5.0F;
			JumpFlag = TRUE;
		}
			//斜めへジャンプ
		if (JumpFlag == FALSE && NonVertJumpFlag == 1 && (EdgeInput&PAD_INPUT_1) > PAD_INPUT_ON) {
			Grav = 0.5F;
			DropPower = -9.5F;
			if (RunButton == TRUE) {
				VectX = 8.0F;
				MaxVect = 8.0F;
			}
			else {
				VectX = 5.0F;
				MaxVect = 5.0F;
			}
			//斜めに飛んでいることを確認
			NonVertJump = TRUE;
			JumpFlag = TRUE;
			//コントロールカウントをリセット
			ContCnt = 0;
		}
		if (JumpFlag == FALSE && NonVertJumpFlag == 2 && (EdgeInput&PAD_INPUT_1) > PAD_INPUT_ON) {
				Grav = 0.5F;
				DropPower = -9.5F;
				if (RunButton == TRUE) {
					VectX = -8.0F;
				}
				else {
					VectX = -5.0F;
				}
				//斜めに飛んでいることを確認
				NonVertJump = TRUE;
				JumpFlag = TRUE;
				//コントロールカウントをリセット
				ContCnt = 0;
				}
		}

		if (NonVertJump == TRUE && VectX == 0) {
			NonVertJump = FALSE;
		}
		//右へジャンプしているときに左で減速
		if (NonVertJump == TRUE && VectX > 0 &&(Input&PAD_INPUT_LEFT) > PAD_INPUT_ON) {
			VectX -= 0.5F;
			if (DropPower < 0) {
				DropPower += 0.1F;
			}
			else {
				DropPower -= 0.1F;
			}
			MoveX = VectX;
		}
		//左へジャンプしているときに右で減速
		if (NonVertJump == TRUE && VectX < 0 &&(Input&PAD_INPUT_RIGHT) > PAD_INPUT_ON) {
			VectX += 0.5F;
			if (DropPower < 0) {
				DropPower += 0.1F;
			}
			else {
				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);
}

マリオ風のジャンプが出ない。(意図したとおりにならない)

#1

by keito940 » 7年前

http://dixq.net/forum/viewtopic.php?f=3&t=18906の続きです
前回は加減速を(めり込むという問題点はあるもの)なんとか実装させたのですが、今度は小ジャンプを実装しようと思います。
…ですが、何故か何もしないとジャンプしてしまい、左右に入れると落下してしまいます。
前回から変更したコードは以下のとおりです。

コード:

int main(void) {
	FreamStartTime = GetNowCount();
	while (GetNowCount() - FreamStartTime < 1000 / 60) {}
	system("cls");
	printf("メインループ開始\n");
	printf("\nPlayerX=%d,PlayerY=%d,Grav=%8.1f,DropPower=%8.1f", (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 (JumpTimer < 0) {
			if ((Input&PAD_INPUT_1) > PAD_INPUT_ON) {
				JumpTimer++;
			}
		}
		else {
			if (JumpTimer < 10 && NonVertJumpFlag == 0) {
				Grav = 0.5F;
				DropPower = -5.0F;
				JumpFlag = TRUE;
			}
			//垂直大ジャンプ
			if (JumpTimer == 10 && NonVertJumpFlag == 0) {
				Grav = 0.5F;
				DropPower = -9.5F;
				JumpFlag = TRUE;
			}
			//斜めへジャンプ
			if (JumpFlag == FALSE && NonVertJumpFlag == 1 && (EdgeInput&PAD_INPUT_1) > PAD_INPUT_ON) {
				Grav = 0.5F;
				DropPower = -9.5F;
				if (RunButton == TRUE) {
					VectX = 8.0F;
					MaxVect = 8.0F;
				}
				else {
					VectX = 5.0F;
					MaxVect = 5.0F;
				}
				//斜めに飛んでいることを確認
				NonVertJump = TRUE;
				JumpFlag = TRUE;
				//コントロールカウントをリセット
				ContCnt = 0;
			}
			if (JumpFlag == FALSE && NonVertJumpFlag == 2 && (EdgeInput&PAD_INPUT_1) > PAD_INPUT_ON) {
					Grav = 0.5F;
					DropPower = -9.5F;
					if (RunButton == TRUE) {
						VectX = -8.0F;
					}
					else {
						VectX = -5.0F;
					}
					//斜めに飛んでいることを確認
					NonVertJump = TRUE;
					JumpFlag = TRUE;
					//コントロールカウントをリセット
					ContCnt = 0;
					}
			}
		}
		if (NonVertJump == TRUE && VectX == 0) {
			NonVertJump = FALSE;
		}
		//右へジャンプしているときに左で減速
		if (NonVertJump == TRUE && VectX > 0 &&(Input&PAD_INPUT_LEFT) > PAD_INPUT_ON) {
			VectX -= 0.5F;
			if (DropPower < 0) {
				DropPower += 0.1F;
			}
			else {
				DropPower -= 0.1F;
			}
			MoveX = VectX;
		}
		//左へジャンプしているときに右で減速
		if (NonVertJump == TRUE && VectX < 0 &&(Input&PAD_INPUT_RIGHT) > PAD_INPUT_ON) {
			VectX += 0.5F;
			if (DropPower < 0) {
				DropPower += 0.1F;
			}
			else {
				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);
}


ページトップ