長押しで調整ができるジャンプのアルゴリズム

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

長押しで調整ができるジャンプのアルゴリズム

#1

投稿記事 by うまお » 5年前

Player.cpp

コード:

//=============================================================================
//【Player.cpp】
//Playerポリゴンを管理する関数を扱うクラス
//=============================================================================

//*****************************************************************************
//インクルード・ヘッダーファイル
//*****************************************************************************
#include "input.h"																										//入力処理用ヘッダー
#include "Player.h"																										//Playerポリゴンのヘッダー

//*****************************************************************************
//ライブラリのリンク
//*****************************************************************************

//*****************************************************************************
//マクロ定義
//*****************************************************************************
//#define PLAYER_TEXTURENAME		 "DATA/TEXTURE/Player.png"															//テクスチャファイル名
#define PLAYER_INITPOS_X			(SCREEN_CENTER_X)																	//初期位置X
#define PLAYER_INITPOS_Y			(SCREEN_CENTER_Y)																	//初期位置Y
#define PLAYER_SIZE_X				(50)																				//横幅
#define PLAYER_SIZE_Y				(50)																				//縦幅
#define PLAYER_SPEED				(3.0f)																				//速度
#define PLAYER_INITIALVELOCITYJUMP	(15.0f)																				//飛び幅初速
#define PLAYER_MAXJUMP				(250.0f)																			//最大飛び幅度
#define PLAYER_GRAVITY				(0.98)																				//重力
#define PLAYER_MAXGRAVITY			(50.0)																				//最大重力

//*****************************************************************************
//イーナム定義
//*****************************************************************************

//*****************************************************************************
//構造体定義
//*****************************************************************************

//*****************************************************************************
//プロトタイプ宣言
//*****************************************************************************
void MakeFormatPlayer	(LPDIRECT3DDEVICE9 pDevice);																	//Playerポリゴンフォーマット情報作成関数
void PosChangePlayer	(float moveX, float moveY, float moveZ, float zoomX, float zoomY, float zoomZ, float angle);	//Playerポリゴン座標変更関数

//*****************************************************************************
//グローバル変数:
//*****************************************************************************
CUSTOMVERTEX			g_pFormatPlayer			[NUM_VERTEX];															//フォーマット情報格納用変数
LPDIRECT3DVERTEXBUFFER9 g_pVertexPlayer			= NULL;																	//頂点バッファコンポーネントへのポインタ
LPDIRECT3DTEXTURE9		g_pTexturePlayer		= NULL;																	//テクスチャオブジェクト格納用変数
D3DXMATRIX				g_pBasePosMATRIXPlayer	[NUM_VERTEX];															//ベース座標格納マトリックス
D3DXVECTOR3				g_Pos					= D3DXVECTOR3(PLAYER_INITPOS_X, PLAYER_INITPOS_Y, 0.0f);				//原点位置格納用変数
D3DXVECTOR3				g_Zoom					= D3DXVECTOR3(1.0f, 1.0f, 1.0f);										//拡張量格納用変数
float					g_Angle					= 0.0f;																	//回転量格納用変数
float					g_nSideIertia			= 0.0f;																	//横軸慣性格納用変数
float					g_nSideLength			= 0.0f;																	//縦軸慣性格納用変数
float					g_nJumpAxis				= 0.0f;																	//ジャンプ前の縦軸格納用変数
bool					g_bJump					= false;																//ジャンプ判定確認用変数

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【Playerポリゴン初期化関数】
//Playerポリゴンの初期化処理を行う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
HRESULT InitPlayer(
	LPDIRECT3D9		  pD3D,																								//Direct3Dへアクセスするためのポインタ
	LPDIRECT3DDEVICE9 pDevice)																							//ビデオカードへアクセスするためのポインタ
{
	//フォーマット情報を作成する
	MakeFormatPlayer(pDevice);

	//頂点バッファの作成をする
	if (FAILED(pDevice->CreateVertexBuffer(
		sizeof(CUSTOMVERTEX) * 4,																						//確保する頂点バッファのサイズ
		D3DUSAGE_WRITEONLY,																								//リソースの使用法を定義するフラグ
		FVF_CUSTOM,																										//頂点フォーマットの型の指定
		D3DPOOL_MANAGED,																								//どの種類のメモリに頂点バッファを置くかの指定
		&g_pVertexPlayer,																								//頂点バッファコンポーネントへのポインタのアドレス
		NULL)))																											//特に使用されていない為NULL
	{
		pDevice->Release();
		pD3D->Release();
		return E_FAIL;
	}

	return S_OK;
}

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【Playerポリゴン終了処理関数】
//Playerポリゴンの終了処理を行う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void UninitPlayer(void)
{
	if (g_pVertexPlayer != NULL) {
		g_pVertexPlayer->Release();
		g_pVertexPlayer = NULL;
	}

	if (g_pTexturePlayer != NULL) {
		g_pTexturePlayer->Release();
		g_pTexturePlayer = NULL;
	}
}

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【Playerポリゴン更新処理関数】
//Playeポリゴンrの更新処理を行う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void UpdataPlayer(LPDIRECT3DDEVICE9 pDevice)
{
	//Dを押した場合右移動処理を行う
	if (GetKeyboardPress(DIK_D)) {
		//左Siftを押した場合ダッシュ処理を行う
		if (GetKeyboardPress(DIK_LSHIFT)) {
			if (g_nSideIertia < PLAYER_SPEED * 2) g_nSideIertia += 0.2f;												//走り速度よりも小さい場合は横慣性を0.2増やす
		}
		//左Siftを押していない場合は歩き処理を行う
		else {
			if (g_nSideIertia < PLAYER_SPEED) g_nSideIertia += 0.1f;													//歩き速度よりも小さい場合は横慣性を0.1増やす

		}
	}
	//Aを押した場合左移動処理を行う
	if (GetKeyboardPress(DIK_A)) {
		//左Siftを押した場合ダッシュ処理を行う
		if (GetKeyboardPress(DIK_LSHIFT)) {
			if (-PLAYER_SPEED * 2 < g_nSideIertia) g_nSideIertia -= 0.2f;												//走り速度よりも大きい場合は横慣性を0.2増やす
		}
		//左Siftを押していない場合は歩き処理を行う
		else {
			if (-PLAYER_SPEED < g_nSideIertia) g_nSideIertia -= 0.1f;													//歩き速度よりも大きい場合は横慣性を0.2増やす
		}
	}
	//DとAを押していない場合横慣性処理を行う
	if (!GetKeyboardPress(DIK_D) && !GetKeyboardPress(DIK_A)) {
		//0よりも横慣性が高い場合左に横慣性を加える
		if (0.0f < g_nSideIertia) {
			if (PLAYER_SPEED < g_nSideIertia) g_nSideIertia -= 0.10f;													//歩き速度よりも大きい場合は横慣性を0.10減らす
			else g_nSideIertia -= 0.5f;																					//上記じゃない場合は横慣性を0.5減らす																		
			if (g_nSideIertia < 0.0f) g_nSideIertia = 0.0f;																//横慣性が0より小さい場合は横慣性を0にする
		}
		//0よりも横慣性が低い場合右に横慣性を加える
		if (g_nSideIertia < 0.0f) {
			if (g_nSideIertia < -PLAYER_SPEED) g_nSideIertia += 0.10f;													//歩き速度よりも小さい場合は横慣性を0.10増やす
			else g_nSideIertia += 0.5f;																					//上記じゃない場合は横慣性を0.5増やす
			if (0.0f < g_nSideIertia) g_nSideIertia = 0.0f;																//横慣性が0より大きい場合は横慣性を0にする
		}
	}
	g_Pos.x += g_nSideIertia;

	if (GetKeyboardTrigger(DIK_SPACE) && g_bJump) {
		g_nSideLength = -PLAYER_INITIALVELOCITYJUMP;
		g_bJump = false;
	}
	if (!g_bJump) {
		g_nSideLength += PLAYER_GRAVITY;
	}
	g_Pos.y += g_nSideLength;

	//変わった横慣性分移動値を変える

	//画面外判定の下準備
	float originX = NULL;																								//移動前の中心X
	float originY = NULL;																								//移動前の中心Y
	float minX = NULL;																									//移動前のX頂点最低値
	float minY = NULL;																									//移動前のY頂点最低値
	float maxX = NULL;																									//移動前のX頂点最大値
	float maxY = NULL;																									//移動前のY頂点最大値
	//上記の変数に数値を入れる
	for (int i = 0; i < NUM_VERTEX; i++) {
		if (originX != NULL) originX += g_pFormatPlayer[i].pos.x;
		else originX = g_pFormatPlayer[i].pos.x;
		if (originY != NULL) originY += g_pFormatPlayer[i].pos.y;
		else originY = g_pFormatPlayer[i].pos.y;
		if (minX == NULL) minX = g_pFormatPlayer[i].pos.x;
		else if (g_pFormatPlayer[i].pos.x < minX) minX = g_pFormatPlayer[i].pos.x;
		if (minY == NULL) minY = g_pFormatPlayer[i].pos.y;
		else if (g_pFormatPlayer[i].pos.y < minY) minY = g_pFormatPlayer[i].pos.y;
		if (maxX == NULL) maxX = g_pFormatPlayer[i].pos.x;
		else if (maxX < g_pFormatPlayer[i].pos.x) maxX = g_pFormatPlayer[i].pos.x;
		if (maxY == NULL) maxY = g_pFormatPlayer[i].pos.y;
		else if (maxY < g_pFormatPlayer[i].pos.y) maxY = g_pFormatPlayer[i].pos.y;
	}
	//頂点の数分割って重点を求める
	originX = originX / (float)NUM_VERTEX;
	originY = originY / (float)NUM_VERTEX;

	//左画面外判定
	if (minX + (g_Pos.x - originX) < 0) {
		g_Pos.x += 0 - (minX + (g_Pos.x - originX));
		g_nSideIertia = 0;
	}
	//右画面外判定
	if (SCREEN_WIDTH < maxX + (g_Pos.x - originX)) {
		g_Pos.x += SCREEN_WIDTH - (maxX + (g_Pos.x - originX));
		g_nSideIertia = 0;
	}
	//上画面判定
	if (minY + (g_Pos.y - originY) < 0) {
		g_Pos.y += 0 - (minY + (g_Pos.y - originY));
		g_bJump = false;
		g_nSideLength = 0;
	}
	//下画面判定
	if (SCREEN_HEIGHT < maxY + (g_Pos.y - originY)) {
		g_Pos.y += SCREEN_HEIGHT - (maxY + (g_Pos.y - originY));
		g_bJump = true;
		g_nSideLength = 0;
	}



	//位置更新処理
	PosChangePlayer(g_Pos.x, g_Pos.y, g_Pos.z, g_Zoom.x, g_Zoom.y, g_Zoom.z, g_Angle);

}

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【Playerポリゴン描画処理関数】
//Playerポリゴンの描画処理を行う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void DrawPlayer(LPDIRECT3DDEVICE9 pDevice)																				//ビデオカードへアクセスするためのポインタ
{
	//頂点バッファを書き込むためにメモリをロックする
	void *pData;
	if (SUCCEEDED(g_pVertexPlayer->Lock(
		0,																												//全体にロックをするため0
		sizeof(CUSTOMVERTEX) * 4,																						//ロックしたいメモリサイズ
		(void**)&pData,																									//ロックされたメモリ範囲の先頭アドレスへのポインタ
		0)))																											//ロック時の動作を定義するフラグ
	{
		memcpy(pData, g_pFormatPlayer, sizeof(CUSTOMVERTEX) * 4);
		g_pVertexPlayer->Unlock();
	}
	//ストリームソースという頂点処理の流れに頂点バッファを実際にセットする
	pDevice->SetStreamSource(
		0,																												//ストリームの番号
		g_pVertexPlayer,																								//頂点バッファコンポーネントへのポインタ
		0,																												//頂点データの書き始めを示すオフセット
		sizeof(CUSTOMVERTEX));																							//1頂点のサイズ
	//ストリームに頂点バッファの型を教える
	pDevice->SetFVF(FVF_CUSTOM);
	//テクスチャをデバイスのステージに割り当てる
	pDevice->SetTexture(0, g_pTexturePlayer);
	//頂点の結び方とポリゴンの描画枚数を指定
	pDevice->DrawPrimitive(
		D3DPT_TRIANGLESTRIP,																							//頂点をどう結びポリゴンにするかのフラグ
		0,																												//描画を開始する最初の頂点番号
		2);																												//描画するポリゴンの数
}

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【Playerポリゴンフォーマット情報作成関数】
//Playerポリゴンのフォーマット情報作成処理を行う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void MakeFormatPlayer(LPDIRECT3DDEVICE9 pDevice)																		//ビデオカードへアクセスするためのポインタ
{
	//頂点座標設定
	g_pFormatPlayer[0].pos =																							//左上
		D3DXVECTOR3(-PLAYER_SIZE_X / 2,  -PLAYER_SIZE_Y / 2, 0.0f);
	g_pFormatPlayer[1].pos =																							//右上
		D3DXVECTOR3(+ PLAYER_SIZE_X / 2,  - PLAYER_SIZE_Y / 2, 0.0f);
	g_pFormatPlayer[2].pos =																							//左下
		D3DXVECTOR3( - PLAYER_SIZE_X / 2,  + PLAYER_SIZE_Y / 2, 0.0f);
	g_pFormatPlayer[3].pos =																							//右下
		D3DXVECTOR3( + PLAYER_SIZE_X / 2,  + PLAYER_SIZE_Y / 2, 0.0f);
	D3DXMatrixTranslation(&g_pBasePosMATRIXPlayer[0], g_pFormatPlayer[0].pos.x, g_pFormatPlayer[0].pos.y, g_pFormatPlayer[0].pos.z);
	D3DXMatrixTranslation(&g_pBasePosMATRIXPlayer[1], g_pFormatPlayer[1].pos.x, g_pFormatPlayer[1].pos.y, g_pFormatPlayer[0].pos.z);
	D3DXMatrixTranslation(&g_pBasePosMATRIXPlayer[2], g_pFormatPlayer[2].pos.x, g_pFormatPlayer[2].pos.y, g_pFormatPlayer[0].pos.z);
	D3DXMatrixTranslation(&g_pBasePosMATRIXPlayer[3], g_pFormatPlayer[3].pos.x, g_pFormatPlayer[3].pos.y, g_pFormatPlayer[0].pos.z);
	//除算数設定
	g_pFormatPlayer[0].rhw = 1.0f;
	g_pFormatPlayer[1].rhw = 1.0f;
	g_pFormatPlayer[2].rhw = 1.0f;
	g_pFormatPlayer[3].rhw = 1.0f;
	//頂点カラー設定
	g_pFormatPlayer[0].col =
		D3DCOLOR_RGBA(255, 255, 255, 255);
	g_pFormatPlayer[1].col =
		D3DCOLOR_RGBA(255, 255, 255, 255);
	g_pFormatPlayer[2].col =
		D3DCOLOR_RGBA(255, 255, 255, 255);
	g_pFormatPlayer[3].col =
		D3DCOLOR_RGBA(255, 255, 255, 255);
	//テクスチャ座標設定
	g_pFormatPlayer[0].tex =
		D3DXVECTOR2(0.0f, 0.0f);																						//左上
	g_pFormatPlayer[1].tex =
		D3DXVECTOR2(1.0f, 0.0f);																						//右上
	g_pFormatPlayer[2].tex =
		D3DXVECTOR2(0.0f, 1.0f);																						//左下
	g_pFormatPlayer[3].tex =
		D3DXVECTOR2(1.0f, 1.0f);																						//右下
}

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【Playerポリゴン座標変更関数】
//Playerポリゴンの座標の変更処理を行う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void PosChangePlayer(
	float moveX,																										//X移動量
	float moveY,																										//Y移動量
	float moveZ,																										//Z移動量
	float zoomX,																										//X拡張量
	float zoomY,																										//Y拡張量
	float zoomZ,																										//Z拡張量
	float angle)																										//回転量
{
	D3DXMATRIX	PosMatrix;																								//Playerポリゴンの現在位置格納用単位行列
	D3DXMATRIX	MoveMatrix;																								//Playerポリゴンの移動量格納用単位行列
	D3DXMATRIX	ZoomMatrix;																								//Playerポリゴンの拡張量格納用単位行列
	D3DXMATRIX	RotationMatrix;																							//Playerポリゴンの回転量格納用単位行列

	//行列初期化
	D3DXMatrixIdentity(&MoveMatrix);
	D3DXMatrixIdentity(&PosMatrix);
	D3DXMatrixIdentity(&ZoomMatrix);
	D3DXMatrixIdentity(&RotationMatrix);

	//D3DXMatrixTranslation関数を使用してMoveMatrixに移動量を格納する
	D3DXMatrixTranslation(
		&MoveMatrix,
		moveX,
		moveY,
		moveZ);
	//D3DXMatrixScaling関数を使用してZoomMatrixに拡張量を格納する
	D3DXMatrixScaling(
		&ZoomMatrix,
		zoomX,
		zoomY,
		zoomZ);
	//D3DXMatrixRotationZ関数を使用してRotationMatrixに回転量を格納する
	D3DXMatrixRotationZ(
		&RotationMatrix,
		D3DXToRadian(angle));

	for (int i = 0; i < NUM_VERTEX; i++) {
		PosMatrix = g_pBasePosMATRIXPlayer[i] * ZoomMatrix * RotationMatrix * MoveMatrix;								//現在地の行列に計算した今までの行列を加算して格納する
		g_pFormatPlayer[i].pos.x = PosMatrix._41;																		//演算結果をポリゴンのX座標に格納する
		g_pFormatPlayer[i].pos.y = PosMatrix._42;																		//演算結果をポリゴンのY座標に格納する
		g_pFormatPlayer[i].pos.z = PosMatrix._43;																		//演算結果をポリゴンのZ座標に格納する
	}
}
GetKeyboardTrigger関数説明(その他キーが関わる関数も)

コード:

実際に動作は確認できる

bool GetKeyboardPress(int nKey);		//押している間true
bool GetKeyboardTrigger(int nKey);		//押した瞬間true
bool GetKeyboardRepeat(int nKey);		//押している間true(Trigger時には反応せず、Pressと違ってTrigger判定の後少しラグがある)
bool GetKeyboardRelease(int nKey);		//離した瞬間true
現在上記のPlayer.cppでは押した瞬間のジャンプができている状態ですが、これをどうにかして押している間調整が効くジャンプに変えたいと思っています。ですがやり方がいまいちわかりません。
押している間に調整が効き、一定の高さ(指定)までしかジャンプできないといったシステムを作るにはどうすればいいでしょうか?

アバター
Dixq (管理人)
管理人
記事: 1661
登録日時: 13年前
住所: 北海道札幌市
連絡を取る:

Re: 長押しで調整ができるジャンプのアルゴリズム

#2

投稿記事 by Dixq (管理人) » 5年前

コードは読んでいませんが、マリオのようなことがしたいのであれば、速度vを用いればよいでしょう。
まず2Dで考えてみます。
vは常に減算されています。
v -= 0.01;
のような計算をしますが、ボタンを押している間は常に
v = 1;
のような値が入っています。y座標は常に速度を加算します。
y += v;
するとボタンを押している間は上に飛ぶはずで離した瞬間から減速(速度の減算)が始まり、
上のパラメータの例では、ボタンを離してから100フレーム目がジャンプの頂点になるはずです。
そこからドンドン下に落ちていくはずです。
(y座標が+が下の環境であればプラスマイナスを読み替えてください)
これを3Dに適用してはどうでしょう

うまお

Re: 長押しで調整ができるジャンプのアルゴリズム

#3

投稿記事 by うまお » 5年前

Dixq (管理人) さんが書きました:
5年前
コードは読んでいませんが、マリオのようなことがしたいのであれば、速度vを用いればよいでしょう。
まず2Dで考えてみます。
vは常に減算されています。
v -= 0.01;
のような計算をしますが、ボタンを押している間は常に
v = 1;
のような値が入っています。y座標は常に速度を加算します。
y += v;
するとボタンを押している間は上に飛ぶはずで離した瞬間から減速(速度の減算)が始まり、
上のパラメータの例では、ボタンを離してから100フレーム目がジャンプの頂点になるはずです。
そこからドンドン下に落ちていくはずです。
(y座標が+が下の環境であればプラスマイナスを読み替えてください)
これを3Dに適用してはどうでしょう
作成途中のものは2Dなので言われているままの形で考えてみたのですが、
if (GetKeyboardPress(DIK_SPACE) && g_bJump) {
g_nSideLength -= 1;
}
if (!g_bJump) {
g_nSideLength += 0.01;
}
g_Pos.y += g_nSideLength;
ここまではボタンを押していない間はg_nSideLength に0.01を足し、押している際はg_nSideLength に1を引いている状態(言われているものをマイナスしただけ)でわかるのですが、100フレーム後をどうやって計算し、if文で比較すればいいのでしょうか?

アバター
Dixq (管理人)
管理人
記事: 1661
登録日時: 13年前
住所: 北海道札幌市
連絡を取る:

Re: 長押しで調整ができるジャンプのアルゴリズム

#4

投稿記事 by Dixq (管理人) » 5年前

コードを読んでもよく分かりませんが、g_nSideLengthは何をする値ですか?
基本的に2Dにおける移動は
x,y座標、速度v、角度angleがあれば常に以下で計算できます。

x += cos(angle)*v;
y += sin(angle)*v;

このvをある程度上に向けた状態からボタンを離すと徐々に減らし、頂点を境にマイナスになればいいのです。
速度vなる変数を用意して計算してみてください。

うまお

Re: 長押しで調整ができるジャンプのアルゴリズム

#5

投稿記事 by うまお » 5年前

Dixq (管理人) さんが書きました:
5年前
コードを読んでもよく分かりませんが、g_nSideLengthは何をする値ですか?
基本的に2Dにおける移動は
x,y座標、速度v、角度angleがあれば常に以下で計算できます。

x += cos(angle)*v;
y += sin(angle)*v;

このvをある程度上に向けた状態からボタンを離すと徐々に減らし、頂点を境にマイナスになればいいのです。
速度vなる変数を用意して計算してみてください。
g_nSideLengthはそちらで言うところの速度vと同じものです。
横方向の移動もコードに張り付けてありましたが、そちらで慣性付きの移動を実装できたのでジャンプもそのような形と同じなのではないのかと思い作った次第であります。

また、スペースを押している間はvを増やすのはわかるのですが、「離して減った際に頂点を境にマイナスになる」のではなく、スペースを長押しでジャンプしていき、「丁度マイナスしていったら頂点になる位置」で長押しを利かなくする処理をどうやって判別するかを聞きたいです。

アバター
Dixq (管理人)
管理人
記事: 1661
登録日時: 13年前
住所: 北海道札幌市
連絡を取る:

Re: 長押しで調整ができるジャンプのアルゴリズム

#6

投稿記事 by Dixq (管理人) » 5年前

スーパーマリオブラザーズ3のマリオのジャンプを想定して答えていいでしょうか。
恐らく頂点になる位置で長押しを効かなくしているわけではなく、実際にはその少し手前で効かなくしていると思います。
ジャンプボタンを押している間は上方向に上がる速度vを一定にし、ある時間(T)を境にvの代入をやめます。
私が前述の通り説明した理屈で実装すると、vの代入をやめた時点からジャンプの減速が始まります。
頂点に達するまでの時間は正確には分かりませんが、分からなくても問題ないと思います。
このTの時間を決めればよいだけだと思います。
時間Tを過ぎたら着地するまで次のジャンプは受け付けません。

・・・と文章で言ってもわかりにくいのでサンプルコードを書いてみます。

アバター
Dixq (管理人)
管理人
記事: 1661
登録日時: 13年前
住所: 北海道札幌市
連絡を取る:

Re: 長押しで調整ができるジャンプのアルゴリズム

#7

投稿記事 by Dixq (管理人) » 5年前

サンプルコードを書いてみました。
Zを長押しするか、Zをチョン押しするかで高さが変わります。
Escボタンで状態をリセットできます。

コード:

#include "DxLib.h"

const static int T = 40; //ジャンプボタン有効時間
const static int V = -6; //ジャンプ初期速度
const static int R = 20; //ボールの半径

static int counter;
static bool isAvailableJumpKey;
static bool isJumping;
static float x,y,v;

void initialize() {
    counter = 0;
    isAvailableJumpKey = true;
    isJumping = false;
    x = 320;
    y = 480;
    v = V;
}

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
    ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen(DX_SCREEN_BACK);
    initialize();
    while(!ScreenFlip()&&!ProcessMessage()&&!ClearDrawScreen()) {
        bool isPressZ = CheckHitKey(KEY_INPUT_Z)==1;
        if (isPressZ || isJumping) {
            counter++;
            isJumping = true;
        }
        if (isJumping) {
            y += v;
            v += 0.1f;
            if (isAvailableJumpKey) {
                if (isPressZ && counter < T) {
                    v = V;
                }
                else {
                    isAvailableJumpKey = false;
                }
            }
        }
        
        DrawCircle((int)x, (int)y, R, GetColor(255, 255, 255), TRUE);

        if (CheckHitKey(KEY_INPUT_ESCAPE)) {
            initialize();
        }
    }
    DxLib_End();
    return 0;
}
実行結果

返信

“C言語何でも質問掲示板” へ戻る