DXライブラリ ゲーム作成について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
nakada
記事: 12
登録日時: 8年前

DXライブラリ ゲーム作成について

#1

投稿記事 by nakada » 8年前

DXライブラリを使って横スクロールのゲームを作成しています

ポインタを使ってキャラクターを表示して左右に動かすことはできます
実行してもエラーはでないのですが、ジャンプ処理がうまくいきません

何が間違っているのか教えてください
よろしくお願いします。

#define _USE_MATH_DEFINES
#define _CRT_SECURE_NO_WARNINGS

#include "DxLib.h"
#include <math.h>
#include <string.h>

// ショットの最大数
#define MAX_SHOT 10000

typedef struct
{
int x;
int y;
char filename[128];
int img;
}Player;

//プロトタイプ宣言
void GameInit(Player *pz, int x, int y, char *name);
void Update(Player *pz);
void Jump(Player *pz, int x, int y);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow)
{
//変数宣言
Player marimo2;

SetGraphMode(640, 480, 16);
if (DxLib_Init() == -1) // DXライブラリ初期化処理
{
return -1; // エラーが起きたら直ちに終了
}

//ゲームの初期化
GameInit(&marimo2, 30, 400, "marimo2.jpg");
Jump(&marimo2, 30, 400);

// ループ
while (ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0)
{
ClsDrawScreen();//画面消去

//ジャンプ処理
Jump(&marimo2, 30, 400);

//キャラクター更新(位置、速度、球数etc)
Update(&marimo2);

//待ち時間
WaitTimer(10);
}

WaitKey();
DxLib_End();// DXライブラリ使用の終了処理

return 0;// ソフトの終了
}

//初期化
void GameInit(Player *pz, int x, int y, char *name)
{
//初期値を設定
pz->x = x;
pz->y = y;
strcpy(pz->filename, name);

//画像ファイルの読み込み
pz->img = LoadGraph(pz->filename);
}

//更新
void Update(Player *pz)
{
//位置の更新
if (CheckHitKey(KEY_INPUT_RIGHT) == 1)
{
//右が押されたら
pz->x++;
}
else if (CheckHitKey(KEY_INPUT_LEFT) == 1)
{
pz->x--;
}

//描画処理
DrawGraph(pz->x, pz->y, pz->img, TRUE);

}

//ジャンプ処理
void Jump(Player *pz, int x, int y)
{
int JumpPower = 0;
// キー入力取得
int Key = 0;
int OldKey = Key;
Key = GetJoypadInputState(DX_INPUT_KEY_PAD1);

if (Key & PAD_INPUT_RIGHT) x += 3; // 右を押していたら右に進む
if (Key & PAD_INPUT_LEFT) x -= 3; // 左を押していたら左に進む

//落下処理
y -= JumpPower;

//落下速度を与える
JumpPower -= 1;

// もし地面についていたら止まる
if (y > 400){
y = 400;
JumpPower = 0;
}

// ジャンプボタンを押していて、地面についていたらジャンプ
if ((Key & PAD_INPUT_B) && y == 400) JumpPower = 20;

}

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: DXライブラリ ゲーム作成について

#2

投稿記事 by みけCAT » 8年前

nakada さんが書きました:何が間違っているのか教えてください
とりあえず自明な間違いから。
  • コードをcodeタグで囲まずに貼り付けている
  • あってはいけない場所に全角の&がある
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: DXライブラリ ゲーム作成について

#3

投稿記事 by みけCAT » 8年前

  • 文字列リテラル(から変換されるポインタ)をconst char*ではなくchar*型の引数に渡している
  • Jump関数において
    • 引数x, yおよび変数JumpPowerの無駄な操作が行われている
    • pzを全く使用していない
という点もおかしいですね。JumpPower(にあたるもの)もPlayerのメンバに追加するべきでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

nakada
記事: 12
登録日時: 8年前

Re: DXライブラリ ゲーム作成について

#4

投稿記事 by nakada » 8年前

すみません。
&が全角なのはなおしました。
一つ目の間違いが具体的にどこなのか分かりません。
またconstをつけるとWinMainのGameInitの呼び出しにエラーの波線が
出るのはなぜですか?
Jump関数についてはx,yをそれぞれpz->x,pz->yにすれば良いのでしょうか。
よく理解しておらず勉強不足で本当にすみません。

nakada
記事: 12
登録日時: 8年前

画像表示について

#5

投稿記事 by nakada » 8年前

二つ質問があります
一つ目は現段階はプレイヤーはDrawBoxで表示されていますが画像を使ってプレイヤーを表示させたいです。
DrawGraphを使って表示しようとしましたが、分かりませんでした。

このプログラムに合うDrawGraphのプログラムを教えていただけませんか?

二つ目はプレイヤーから弾を発射できるようにしたいです
前に作ったちいさいプログラムでは発射できたのですが
現在作成中のプログラムにどうしても組み込むことができません
大変ご迷惑をおかけしますが、
このプログラムに合う弾発射のプログラムを作っていただけないでしょうか


どちらか一つでも構いませんので
よろしくお願いします。


現在作成中のプログラム
[code=C]
#include "DxLib.h"

#define SCREEN_WIDTH (1280) // 画面の横幅
#define SCREEN_HEIGHT (480) // 画面の縦幅
#define CHIP_SIZE (32) // 一つのチップのサイズ
#define MAP_WIDTH (SCREEN_WIDTH / CHIP_SIZE) // マップの横幅
#define MAP_HEIGHT (SCREEN_HEIGHT / CHIP_SIZE) // マップの縦幅

#define G (0.3F) // キャラに掛かる重力加速度
#define JUMP_POWER (9.0F) // キャラのジャンプ力
#define SPEED (5.0F) // キャラの移動スピード
#define CHAR_SIZE (30) // プレイヤーのサイズ

// マップデータ
char MapData[MAP_HEIGHT][MAP_WIDTH] =
{
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,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,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,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 0,0,0,0,0, 1,1,1,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,1,
1,0,0,0,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,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,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,1,
1,1,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,1,
1,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,1,
1,0,0,0,1, 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,1,

1,0,0,0,0, 1,1,1,1,1, 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, 1,1,1,1,1, 0,0,0,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,1,1, 1,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, 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,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,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 PlX, PlY; // プレイヤーの座標(中心座標)
float PlDownSp; // プレイヤーの落下速度
char PlJumpFlag; // プレイヤーがジャンプ中か、のフラグ

int Input, EdgeInput; // 入力状態
int FrameStartTime; // 60FPS固定用、時間保存用変数



// マップチップの値を取得する関数
int GetChipParam(float X, float Y);

// キャラクタをマップとの当たり判定を考慮しながら移動する関数
int CharMove(float *X, float *Y, float *DownSP,
float MoveX, float MoveY, float Size, char *JumpFlag);

// アクションサンプルプログラムメイン関数
int ActMain(void);

// マップとの当たり判定( 戻り値 0:当たらなかった 1:左辺に当たった 2:右辺に当たった
// 3:上辺に当たった 4:下辺に当たった
// 注意:MoveX と MoveY 、どっちか片方が0じゃないとまともに動作しません(爆)
int MapHitCheck(float X, float Y, float *MoveX, float *MoveY);




// WinMain関数
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
ChangeWindowMode(TRUE);

// DXライブラリの初期化
if (DxLib_Init() == -1) return -1;

// アクションゲームのメイン関数を呼ぶ
ActMain();

// DXライブラリの後始末
DxLib_End();

// 終了
return 0;
}

// アクションサンプルプログラムメイン
int ActMain(void)
{
// 描画先を裏画面にセット
SetDrawScreen(DX_SCREEN_BACK);

// 垂直同期信号を待たない
SetWaitVSyncFlag(FALSE);

// プレイヤーの座標を初期化
PlX = 320.0F; PlY = 240.0F;

// プレイヤーの落下速度を初期化
PlDownSp = 0.0F;

// ジャンプ中フラグを倒す
PlJumpFlag = FALSE;

// 入力状態の初期化
Input = 0;
EdgeInput = 0;

// 60FPS固定用、時間保存用変数を現在のカウント値にセット
FrameStartTime = GetNowCount();

// メインループ開始、ESCキーで外に出る
while (ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0)
{
// 画面のクリア
ClsDrawScreen();

// 1/60秒立つまで待つ
while (GetNowCount() - FrameStartTime < 1000 / 60) {}

// 現在のカウント値を保存
FrameStartTime = GetNowCount();

// 入力状態を更新
{
int i;

// パッド1とキーボードから入力を得る
i = GetJoypadInputState(DX_INPUT_KEY_PAD1);

// エッジを取った入力をセット
EdgeInput = i & ~Input;

// 入力状態の保存
Input = i;
}

// プレイヤーの移動処理
{
float MoveX, MoveY;

// 移動量の初期化
MoveX = 0.0F;
MoveY = 0.0F;

// 左右の移動を見る
if ((Input & PAD_INPUT_LEFT) != 0) MoveX -= SPEED;
if ((Input & PAD_INPUT_RIGHT) != 0) MoveX += SPEED;

// 地に足が着いている場合のみジャンプボタン(ボタン1 or Zキー)を見る
if (PlJumpFlag == FALSE && (EdgeInput & PAD_INPUT_A) != 0)
{
PlDownSp = -JUMP_POWER;
PlJumpFlag = TRUE;
}

// 落下処理
PlDownSp += G;

// 落下速度を移動量に加える
MoveY = PlDownSp;

// 移動量に基づいてキャラクタの座標を移動
CharMove(&PlX, &PlY, &PlDownSp, MoveX, MoveY, CHAR_SIZE, &PlJumpFlag);
}

// マップの描画
{
int i, j;

for (i = 0; i < MAP_HEIGHT; i++)
{
for (j = 0; j < MAP_WIDTH; j++)
{
// 1は当たり判定チップを表しているので1のところだけ描画
if (MapData[j] == 1)
{
DrawBox(j * CHIP_SIZE, i * CHIP_SIZE,
j * CHIP_SIZE + CHIP_SIZE, i * CHIP_SIZE + CHIP_SIZE,
GetColor(255, 255, 255), TRUE);
}
}
}
}

// キャラクタの描画
DrawBox((int)(PlX - CHAR_SIZE * 0.5F), (int)(PlY - CHAR_SIZE * 0.5F),
(int)(PlX + CHAR_SIZE * 0.5F) + 1, (int)(PlY + CHAR_SIZE * 0.5F) + 1,
GetColor(255, 0, 0), TRUE);

// 画面の更新
ScreenFlip();
}

// 終了
return 0;
}

// キャラクタをマップとの当たり判定を考慮しながら移動する
int CharMove(float *X, float *Y, float *DownSP,
float MoveX, float MoveY, float Size, char *JumpFlag)
{
float Dummy = 0.0F;
float hsize;

// キャラクタの左上、右上、左下、右下部分が当たり判定のある
// マップに衝突しているか調べ、衝突していたら補正する

// 半分のサイズを算出
hsize = Size * 0.5F;

// 先ず上下移動成分だけでチェック
{
// 左下のチェック、もしブロックの上辺に着いていたら落下を止める
if (MapHitCheck(*X - hsize, *Y + hsize, &Dummy, &MoveY) == 3) *DownSP = 0.0F;

// 右下のチェック、もしブロックの上辺に着いていたら落下を止める
if (MapHitCheck(*X + hsize, *Y + hsize, &Dummy, &MoveY) == 3) *DownSP = 0.0F;

// 左上のチェック、もしブロックの下辺に当たっていたら落下させる
if (MapHitCheck(*X - hsize, *Y - hsize, &Dummy, &MoveY) == 4) *DownSP *= -1.0F;

// 右上のチェック、もしブロックの下辺に当たっていたら落下させる
if (MapHitCheck(*X + hsize, *Y - hsize, &Dummy, &MoveY) == 4) *DownSP *= -1.0F;

// 上下移動成分を加算
*Y += MoveY;
}

// 後に左右移動成分だけでチェック
{
// 左下のチェック
MapHitCheck(*X - hsize, *Y + hsize, &MoveX, &Dummy);

// 右下のチェック
MapHitCheck(*X + hsize, *Y + hsize, &MoveX, &Dummy);

// 左上のチェック
MapHitCheck(*X - hsize, *Y - hsize, &MoveX, &Dummy);

// 右上のチェック
MapHitCheck(*X + hsize, *Y - hsize, &MoveX, &Dummy);

// 左右移動成分を加算
*X += MoveX;
}

// 接地判定
{
// キャラクタの左下と右下の下に地面があるか調べる
if (GetChipParam(*X - Size * 0.5F, *Y + Size * 0.5F + 1.0F) == 0 &&
GetChipParam(*X + Size * 0.5F, *Y + Size * 0.5F + 1.0F) == 0)
{
// 足場が無かったらジャンプ中にする
*JumpFlag = TRUE;
}
else
{
// 足場が在ったら接地中にする
*JumpFlag = FALSE;
}
}

// 終了
return 0;
}


// マップとの当たり判定( 戻り値 0:当たらなかった 1:左辺に当たった 2:右辺に当たった
// 3:上辺に当たった 4:下辺に当たった
// 注意:MoveX と MoveY 、どっちか片方が0じゃないとまともに動作しません(爆)
int MapHitCheck(float X, float Y,
float *MoveX, float *MoveY)
{
float afX, afY;

// 移動量を足す
afX = X + *MoveX;
afY = Y + *MoveY;

// 当たり判定のあるブロックに当たっているかチェック
if (GetChipParam(afX, afY) == 1)
{
float blx, bty, brx, bby;

// 当たっていたら壁から離す処理を行う

// ブロックの上下左右の座標を算出
blx = (float)((int)afX / CHIP_SIZE) * CHIP_SIZE; // 左辺の X 座標
brx = (float)((int)afX / CHIP_SIZE + 1) * CHIP_SIZE; // 右辺の X 座標

bty = (float)((int)afY / CHIP_SIZE) * CHIP_SIZE; // 上辺の Y 座標
bby = (float)((int)afY / CHIP_SIZE + 1) * CHIP_SIZE; // 下辺の Y 座標

// 上辺に当たっていた場合
if (*MoveY > 0.0F)
{
// 移動量を補正する
*MoveY = bty - Y - 1.0F;

// 上辺に当たったと返す
return 3;
}

// 下辺に当たっていた場合
if (*MoveY < 0.0F)
{
// 移動量を補正する
*MoveY = bby - Y + 1.0F;

// 下辺に当たったと返す
return 4;
}

// 左辺に当たっていた場合
if (*MoveX > 0.0F)
{
// 移動量を補正する
*MoveX = blx - X - 1.0F;

// 左辺に当たったと返す
return 1;
}

// 右辺に当たっていた場合
if (*MoveX < 0.0F)
{
// 移動量を補正する
*MoveX = brx - X + 1.0F;

// 右辺に当たったと返す
return 2;
}

// ここに来たら適当な値を返す
return 4;
}

// どこにも当たらなかったと返す
return 0;
}

// マップチップの値を取得する関数
int GetChipParam(float X, float Y)
{
int x, y;

// 整数値へ変換
x = (int)X / CHIP_SIZE;
y = (int)Y / CHIP_SIZE;

// マップからはみ出ていたら 0 を返す
if (x >= MAP_WIDTH || y >= MAP_HEIGHT || x < 0 || y < 0) return 0;

// 指定の座標に該当するマップの情報を返す
return MapData[y][x];
}
[/code]

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: DXライブラリ ゲーム作成について

#6

投稿記事 by softya(ソフト屋) » 8年前

今までの話の流れを分かり辛くしてしまったのはnakadaさん自身ですので、複数のトピックの流れを、このトピックでまとめ整理をお願いします。
私はみけCATさんの回答に対して必要十分な返答をせずに質問を繰り返してしまったので回答がついていないんだと思っています。
それとcodeタグの動作は必ずプレビューで確認してください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: DXライブラリ ゲーム作成について

#7

投稿記事 by みけCAT » 8年前

× [code=C] ← 全角の=を使ってはいけません

コード:

 ← 全て半角文字です
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

nakada
記事: 12
登録日時: 8年前

Re: DXライブラリ ゲーム作成について

#8

投稿記事 by nakada » 8年前

みけCAT さんが書きました:× [code=C] ← 全角の=を使ってはいけません

コード:

 ← 全て半角文字です[/quote]

ありがとうございます
すみませんでした

閉鎖

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