DXライブラリとC言語でゲーム制作。今回はボタンの押し具合で大ジャンプ・小ジャンプができるように改良。
【2025/09/11追記】無限ジャンプができるバグがあったのを修正、またジャンプ状態関連の列挙体をPlayer.cpp内ではなくDefine.hを作ってそこに書くように変更。
大ジャンプ・小ジャンプの土台
前回ジャンプを実装したものの常にジャンプの高さが一定だったので今回は大ジャンプ・小ジャンプができるようにしていく。
ジャンプの高さを変えられるゲームは概ねジャンプ中にジャンプボタンが離されたかで判定しているのが多いのでこれに倣って実装する。
まずジャンプした瞬間は大ジャンプとして処理。以降はジャンプボタンが押されたままであれば大ジャンプ維持、一度でもジャンプボタンが離されたら小ジャンプに移行する。なお大ジャンプか小ジャンプかの判定はジャンプで上昇中の時のみ行う。
実装
では実装。今回はジャンプしているかだけでなく大ジャンプ・小ジャンプ状態か、あるいは落下状態かの判定が必要なので前回定義した JumpFlag を以下のように変更する。
//プレイヤーの構造体
typedef struct {
//中略
char JumpStatus; //bool JumpFlagから変更。ジャンプ状態関連
//中略
}player_t;
//中略JumpStatusの型を int ではなく char にしているのはデータサイズ削減のため。charは文字列用の型だが整数としても扱うことができる。
また Define.h を追加し、ジャンプの状態関連の列挙体をそこに書く。Define.hを新たに作ったのは他のファイルでも参照したい共通の定義をするため(敵やNPCもジャンプ処理をすることになるので)。
Define.h
#ifndef DEF_DEFINE_H
#define DEF_DEFINE_H
//プレイヤーなどのジャンプ関連の列挙体
typedef enum {
NO_JUMP, //ジャンプしていない
JUMP_HIGH, //大ジャンプ
JUMP_LOW, //小ジャンプ
FALL //落下中
}Object_Jump;
extern Object_Jump object_jump;
#endifそして Player_Update() でジャンプ処理を行っている部分を以下のように変更。ジャンプ中かつ上昇中にジャンプボタンが離されたらY軸方向の速度を半分にして小ジャンプに移行するというもの。また MoveFlag やジャンプ状態によってプレイヤーの行動を決定する処理を変更・追加。
//以下のファイルをインクルード
#include "Define.h"
//更新
void Player_Update() {
//中略
//MoveFlagの分岐処理部分を以下のように変更
if (MoveFlag) {
//中略
}
else {
//ジャンプor落下中でなければプレイヤーの行動を待機にする
if(player.Action != PLAYER_JUMP && player.Action != PLAYER_FALL) player.Action = PLAYER_IDLE;
}
//プレイヤーがジャンプ・落下中でないかつジャンプボタンが押されていればジャンプ処理
if (player.Action != PLAYER_JUMP && player.Action != PLAYER_FALL && Input_GetGamepadDown(config.jump)) {
//大ジャンプフラグを立てる
player.JumpStatus = (char)JUMP_HIGH;
//Y軸方向の速度をセット
player.JumpPower = PLAYER_JUMP_POWER;
}
//ジャンプ状態(落下含む)であればプレイヤーの行動をジャンプにする
if (player.JumpStatus >= (char)JUMP_HIGH) {
if(player.Action != PLAYER_FALL) player.Action = PLAYER_JUMP;
}
//Y座標の計算
if (player.Action == PLAYER_JUMP || player.Action == PLAYER_FALL) {
//ジャンプ中にジャンプボタンが離されたかどうかで処理の分岐
//ジャンプボタンが離されたかつ上昇中かつ大ジャンプ中だった場合
if (Input_GetGamepadUp(config.jump) && player.JumpPower > 0 && player.JumpStatus == (char)JUMP_HIGH) {
//小ジャンプにする
player.JumpPower = player.JumpPower / 2.0f;
player.JumpStatus = (char)JUMP_LOW;
}
//中略
}
//中略列挙型enumの各変数の型は int なのでJumpStatusに状態を格納するときは (char)JUMP_HIGH のように変数の先頭に(char)を書いて型を変更すること。そうしないと値が0になったりするので注意。
ちなみに大ジャンプから小ジャンプの移行を落下中にもできるようにすると一度だけ落下速度を減少させることができるという「ズル」が可能になってしまう。なので判定はジャンプで上昇中のみに絞るのが大事。

コメント