画像移動がおかしいのですが

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

画像移動がおかしいのですが

#1

投稿記事 by lome » 9年前

C++、DXライブラリの使用
Aliceという画像をキーボードで動かしたいのですが

コード:

int x, y;
	x = 100; y = 100;
	if (CheckHitKey(KEY_INPUT_LEFT) == 1) x -= 8;
	if (CheckHitKey(KEY_INPUT_RIGHT) == 1) x += 8;
	if (CheckHitKey(KEY_INPUT_UP) == 1) y -= 8;
	if (CheckHitKey(KEY_INPUT_DOWN) == 1) y += 8;

	int Alice2;     // 画像格納用ハンドル
	Alice2 = LoadGraph("Alice2.jpg"); // 画像のロード
	DrawRotaGraph(x, y, 0.3, 0.0, Alice2, TRUE); //画像の描画
というのを書きました
実行はしっかりされ、画像もしっかり映るのですが
なぜかこのコードだと座標が+8されてはリセットされまた+8されてはリセットされ、と
一定地点から動いてくれません
文章がいみわからないと思うのですが
ご教授お願いします
https://gyazo.com/54ce04d131ec831aea8776dda9d1b6f5

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

Re: 画像移動がおかしいのですが

#2

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

明らかにコンパイルできないコードが貼ってあるので実際のコードがわかりませんが、
素直に座標を毎フレームリセットするコードを書いているから座標が毎フレームリセットされるだけではないでしょうか?
でも、まさか画像を毎フレームロードするコードを書いているなんて思いたくないので、この推測もきっと間違いですよね。
まずは、コンパイルして実行可能ファイルを作れる本物のコードを提示していただけないでしょうか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

LEMO
記事: 23
登録日時: 9年前
住所: 関東地方ですね

Re: 画像移動がおかしいのですが

#3

投稿記事 by LEMO » 9年前

lemoです
ご指摘ありがとうございます
今回書いたコードは「新・ゲームプログラミングの館」さんのsp.3の記事を使わせてもらっていて
いくつかにわかれているのですが
他のところは正常に動作しているので、main.cppとGame.cpp、Game.h、あと、Scene.cpp&.hを載せておきます
はじめの投稿に載せたコードはGame.cppの中のコードです

Game.cpp

コード:

#include "Game.h"
#include "SceneMgr.h"
#include "DxLib.h"

int GraphHandle;


//更新
void Game_Update() {
	if (CheckHitKey(KEY_INPUT_ESCAPE) != 0) { //Escキーが押されていたら
		SceneMgr_ChangeScene(eScene_Menu);//シーンをメニューに変更
	}
}

//描画
void Game_Draw() {
	int x, y;
	x = 100; y = 100;
	if (CheckHitKey(KEY_INPUT_LEFT) == 1) x -= 8;
	if (CheckHitKey(KEY_INPUT_RIGHT) == 1) x += 8;
	if (CheckHitKey(KEY_INPUT_UP) == 1) y -= 8;
	if (CheckHitKey(KEY_INPUT_DOWN) == 1) y += 8;

	int Alice2;     // 画像格納用ハンドル
	Alice2 = LoadGraph("Alice2.jpg"); // 画像のロード
	DrawRotaGraph(x, y, 0.3, 0.0, Alice2, TRUE); //画像の描画


	DrawString(0, 0, "このようになぜか座標が毎回リセットされてしまいます", GetColor(255, 255, 255));
	DrawString(0, 20, "このGIFはでたらめに押しまくっています", GetColor(255, 255, 255));

}
Game.h

コード:

#pragma once

//更新
void Game_Update();

//描画
void Game_Draw();

main.cpp

コード:

#include "DxLib.h"
#include "SceneMgr.h"

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
	ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen(DX_SCREEN_BACK); //ウィンドウモード変更と初期化と裏画面設定
	SetMainWindowText("EN Test");
	while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0) {//画面更新 & メッセージ処理 & 画面消去

		SceneMgr_Update();  //更新
		SceneMgr_Draw();    //描画

	}

	DxLib_End(); // DXライブラリ終了処理
	return 0;
}
SceneMgr.cpp

コード:

#include "DxLib.h"
#include "Config.h"
#include "Game.h"
#include "Menu.h"
#include "SceneMgr.h"

static eScene Scene = eScene_Menu;    //シーン管理変数

									  //更新
void SceneMgr_Update() {
	switch (Scene) {       //シーンによって処理を分岐
	case eScene_Menu:    //現在の画面がメニューなら
		Menu_Update();   //メニュー画面の更新処理をする
		break;//以下略
	case eScene_Game:
		Game_Update();
		break;
	case eScene_Config:
		Config_Update();
		break;
	}
}

//描画
void SceneMgr_Draw() {
	switch (Scene) {      //シーンによって処理を分岐
	case eScene_Menu:   //現在の画面がメニュー画面なら
		Menu_Draw();    //メニュー画面の描画処理をする
		break;//以下略
	case eScene_Game:
		Game_Draw();
		break;
	case eScene_Config:
		Config_Draw();
		break;
	}
}

// 引数 nextScene にシーンを変更する
void SceneMgr_ChangeScene(eScene NextScene) {
	Scene = NextScene;
}
SceneMgr.h

コード:

#pragma once

typedef enum {
	eScene_Menu,    //メニュー画面
	eScene_Game,    //ゲーム画面
	eScene_Config,  //設定画面
} eScene;

//更新
void SceneMgr_Update();

//描画
void SceneMgr_Draw();

// 引数 nextScene にシーンを変更する
void SceneMgr_ChangeScene(eScene nextScene);


どうでしょう?これで大丈夫でしょうか?
情報不足で申し訳ありませんでした

LEMO
記事: 23
登録日時: 9年前
住所: 関東地方ですね

Re: 画像移動がおかしいのですが

#4

投稿記事 by LEMO » 9年前

すみません
トピック投稿時にはlomeとの名前でやっていたのですが
トピック投稿をしてからLEMOという名前のアカウントを作らせていただきました
同一人物という認識でお願いします

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

Re: 画像移動がおかしいのですが

#5

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

C言語の基本を理解されていないようです。
関数内で定義した変数の状態は関数を抜けると維持できません。
sp.4で紹介しているようにファイルの先頭でstatic変数を宣言してそれを使ってください。
また、このコードのままだと関数を通るたびに画像をメモリにロードし、それを破棄しないまままた同じ画像をロードします。
酷いメモリリークが続き、いずれメモリが枯渇するでしょう。
画像はsp.5で紹介しているようにInitializeで一度だけやるようにしましょう。

LEMO
記事: 23
登録日時: 9年前
住所: 関東地方ですね

Re: 画像移動がおかしいのですが

#6

投稿記事 by LEMO » 9年前

ありがとうございます!
自分なりに改変してみたGame.cppです

Game.cpp

コード:

#include "Game.h"
#include "SceneMgr.h"
#include "DxLib.h"

static int mImageHandle;    //画像ハンドル格納用変数
int x, y;


							//初期化
void Game_Initialize() {
	mImageHandle = LoadGraph("images/Alice2.jpg");    //画像のロード
}

//終了処理
void Game_Finalize() {
	DeleteGraph(mImageHandle);    //画像の解放
}

//更新
void Game_Update() {
	if (CheckHitKey(KEY_INPUT_ESCAPE) != 0) { //Escキーが押されていたら
		SceneMgr_ChangeScene(eScene_Menu);//シーンをメニューに変更
	}
}
//描画
void Game_Draw() {

	if (CheckHitKey(KEY_INPUT_LEFT) == 1) x -= 8;
	if (CheckHitKey(KEY_INPUT_RIGHT) == 1) x += 8;
	if (CheckHitKey(KEY_INPUT_UP) == 1) y -= 8;
	if (CheckHitKey(KEY_INPUT_DOWN) == 1) y += 8;

	DrawRotaGraph(100 + x, 100 + y, 0.3, 0.0, mImageHandle, TRUE); //画像の描画
	DrawString(0, 0, "ゲーム画面です。", GetColor(255, 255, 255));
	DrawString(0, 20, "Escキーを押すとメニュー画面に戻ります。", GetColor(255, 255, 255));
}
上記のコードで一応画像の初期座標がx=100y=100でそこに+と-をしていくという方法を使ってしっかり動きました!
ですが、これが正しい書き方なのでしょうか?

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

Re: 画像移動がおかしいのですが

#7

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

ほぼ正解です。
厳密に言うなら

① x,yの宣言にもstaticを付けましょう。ファイルの先頭で宣言するものには基本的に全部付けましょう。
  理由は他のファイルから書き換えをできなくするためです。
  他のファイルからこの変数を書き換えたくなることが今後おそらく出てきます。でもそれをするのはご法度で、やり始めたら設計がもろくも崩れ去る前兆です。
  staticと書いておけば他のファイルからこの値を書き換えることができなくなります。

② 全ての計算はUpdateでやり、Draw関数内ではUpdateで計算された結果を表示するだけという設計思考で行ってください。
  よってキーの入力状態をチェックしてx,yを計算するのはUpdate関数の中でやるべきです。
  これはフレームレート調整やフレームスキップ、リプレイの実現等を行う時に恩恵があります。

③ キーの入力状態のチェックは是非ゲームプログラミングの館を参考にしてください。
  http://dixq.net/g/sp_02.html
  テンプレートやシングルトン等の意味の理解がまだ難しければコピペでいいです。
  理解すべきは、
  #include "Keyboard.h"
  とファイルの先頭に書けば、そのファイルで
  Keyboard::Instance()->GetPressingCount (KEY_INPUT_RETURN)
  とかするだけでキーボードの入力状態がチェック出来るということです。
  CheckHitKeyでは、今後メニュー画面を作りたい時などに1項目だけ移動したいとき等、
  キーの入力状態以上に、キーが押されて1フレーム目なのか、2フレーム目以上なのか区別したい場合が必ず出てきます。
  そのような計算がこのモジュール内で出来ていますので参照するだけでよいのです。

閉鎖

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