初投稿になります。
現在、管理人様並びに他所様が公開しているサンプルプログラムを参考に2Dゲームぽい物を試しに組んでみましたら、
操作するキャラクター(DrawBox)のジャンプ処理が管理人様のサンプルのようにジャンプはしますがスペースキーを長押ししますと
キャラクターが上へ上へと上がりそのまま画面外に出てしまいました。
この場合どう修正すればいいかが思いつかず、、、勉強不足で大変恐縮ですがご教授いただけますと幸いです。
綺麗でなないですが下記にてコードを記載いたします。
#include <algorithm> //std::maxを使用するため
#define NOMINMAX
#include "DxLib.h"
//当たり判定を行う関数
//
// ブロック 左 x1
// 上 y1
// 横幅 w1
// 縦幅 h1
//
// キャラクター 左 x2
// 上 y2
// 横幅 w2
// 縦幅 h2
int CheckHit(float x1, float y1, float w1, float h1, float x2, float y2, float w2, float h2)
{
float L1 = x1; // 左
float R1 = x1 + w1; // 右(左+横幅)
float L2 = x2; // 左
float R2 = x2 + w2; // 右(左+横幅)
if (R1 <= L2) return 0; //< 線上も当たらないことにする
if (R2 <= L1) return 0; //< 線上も当たらないことにする
float U1 = y1; // 上
float D1 = y1 + h1; // 下(上+縦幅)
float U2 = y2; // 上
float D2 = y2 + h2; // 下(上+縦幅)
if (D1 <= U2) return 0; //< 線上も当たらないことにする
if (D2 <= U1) return 0; //< 線上も当たらないことにする
// それ以外の場合は当たっている
return 1;
}
/*-----定義-----*/
//スクリーンの縦、横の大きさ
#define SCEEN_HEIGHT 640
#define SCEEN_WIDTH 480
//=================================================================
//ステージ用変数と定義
//=================================================================
//ステージの縦横幅
#define STAGE_HEIGHT 15
#define STAGE_WIDTH 20
//ブロックの大きさ
#define BLOCK_SIZE 32
int g_NUM_MAP_X = 20;
int g_NUM_MAP_Y = 15;
int g_stage[]= {
0,0,0,0,0, 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,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,
0,0,0,0,0, 0,0,0,0,0, 1,1,1,0,0, 0,0,0,0,0,
0,0,0,0,0, 0,0,0,1,0, 0,0,0,0,0, 0,0,0,0,0,
0,0,0,0,0, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, };
//=================================================================
//プレイヤー用変数と定義
//=================================================================
//プレイヤーの大きさ
#define PLAYER_SIZE 32
//プレイヤーのX,Y軸
float g_PlayerX;
float g_PlayerY;
//ジャンプ関数
float g_JumpPower;
//プレイヤーの前回位置
float g_old_x = 0.0f;
float g_old_y = 0.0f;
//キー入力用キャラ型
char g_Key[256];
//ーーーーーーーーーーー
//キャラの操作
//ーーーーーーーーーーー
void PlayerMove()
{
//キーボードの入力値を入手する
GetHitKeyStateAll(g_Key);
// 前回の位置を覚えておく(関数内宣言ではない)
//これが無くなると当たり判定がめちゃくちゃになる
g_old_x = g_PlayerX;
g_old_y = g_PlayerY;
//落下処理
g_PlayerY -= g_JumpPower;
//落下加速度を加える
g_JumpPower -= 1.0f;
//右矢印を押したら右に進
if (g_Key[KEY_INPUT_RIGHT]) {
g_PlayerX += 3;
}
//左矢印を押したら左に進
if (g_Key[KEY_INPUT_LEFT]) {
g_PlayerX -= 3;
}
//スペースを押したらジャンプ
if (g_Key[KEY_INPUT_SPACE]){
g_JumpPower = 7.0f;
//ボタンが機能しているか確認する為のボックス
DrawBox(0, 0, 32, 32, GetColor(255, 255, 0), TRUE);
}
// プレイヤーのy軸が449以上の場合止まる
// プレイヤーのy軸が0以下の場合止まる
if (g_PlayerY > 449)
{
g_PlayerY = 449;
}
else if (g_PlayerY < 0)
{
g_PlayerY = 0;
}
}
//ーーーーーーーーーーー
//キャラの更新
//ーーーーーーーーーーー
void PlayerUpdate()
{
PlayerMove();
}
//ーーーーーーーーーーー
//キャラ描画
//ーーーーーーーーーーー
void PlayerDraw()
{
// プレイヤー描画
DrawBox(g_PlayerX, g_PlayerY, g_PlayerX + BLOCK_SIZE, g_PlayerY+ BLOCK_SIZE, GetColor(255, 255, 0), TRUE);
}
//ーーーーーーーーーーー
//地形当たり判定
//ーーーーーーーーーーー
void StageHitCheck()
{
//ブロックの当たり判定
for (int height = 0; height < g_NUM_MAP_Y; height++)
{
for (int width = 0; width < g_NUM_MAP_X; width++)
{
int BlockNumber = g_stage[width + height * g_NUM_MAP_X];
if (BlockNumber > 0 && BlockNumber < 2)
{
if (CheckHit(width * BLOCK_SIZE, height * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE,g_PlayerX, g_PlayerY, PLAYER_SIZE, PLAYER_SIZE))
{
//上から当たっているか
if (g_PlayerY >= g_old_y)
{
if (height * BLOCK_SIZE - PLAYER_SIZE >= g_old_y)
{
g_old_y = height * BLOCK_SIZE - PLAYER_SIZE ;
g_PlayerY = g_old_y;
g_JumpPower = 0.0f;
}
else
{
int CollPlayerX = std::max(g_PlayerX, g_old_x);
CollPlayerX /= BLOCK_SIZE;
CollPlayerX *= BLOCK_SIZE;
g_PlayerX = CollPlayerX;
g_old_x = g_PlayerX;
}
}
//下から当たっている
else if (g_PlayerY < g_old_y)
{
if ((height + 1) * BLOCK_SIZE <= g_old_y)
{
g_old_y = (height + 1) * BLOCK_SIZE;
g_PlayerY = g_old_y;
g_JumpPower = 0.0f;
}
else
{
int CollPlayerX = std::max(g_PlayerX, g_old_x);
CollPlayerX /= BLOCK_SIZE;
CollPlayerX *= BLOCK_SIZE;
g_PlayerX = CollPlayerX;
g_old_x = g_PlayerX;
}
}
//当たり判定が機能しているか確認用
DrawBox(0, 0, 32, 32, GetColor(255, 0,0), TRUE);
}
}
}
}
}
//=================================================================
//メイン
//=================================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
ChangeWindowMode(TRUE);
SetGraphMode(640, 480, 16);
if (DxLib_Init() == -1) // DXライブラリ初期化処理
{
return -1; // エラーが起きたら直ちに終了
}
// 描画先画面を裏画面にセット
SetDrawScreen(DX_SCREEN_BACK);
// キャラクターの初期位置
g_PlayerX = 0.0f;
g_PlayerY = 449.0f;
// ループ
while (ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0)
{
// 画面を初期化する
ClearDrawScreen();
;
//ステージ描画
for (int width = 0; width < g_NUM_MAP_X; width++)
{
for (int height = 0; height < g_NUM_MAP_Y; height++)
{
int MapNumber = g_stage[width + height * g_NUM_MAP_X];
if (MapNumber == 0)
{
DrawBox(width * BLOCK_SIZE,
height * BLOCK_SIZE,
width * BLOCK_SIZE + BLOCK_SIZE,
height * BLOCK_SIZE + BLOCK_SIZE,
GetColor(255, 255, 255), FALSE);
}
if (MapNumber == 1)
{
DrawBox(width * BLOCK_SIZE,
height * BLOCK_SIZE,
width * BLOCK_SIZE + BLOCK_SIZE ,
height * BLOCK_SIZE + BLOCK_SIZE ,
GetColor(255, 255, 255), TRUE);
}
}
}
//当たり判定
StageHitCheck();
//プレイヤーの描画
PlayerDraw();
//プレイヤーの更新
PlayerUpdate();
// 裏画面の内容を表画面に反映させる
ScreenFlip();
}
DxLib_End(); // DXライブラリ使用の終了処理
return 0; // ソフトの終了
}