ページ 1 / 1
画像移動がおかしいのですが
Posted: 2016年8月21日(日) 18:02
by lome
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
Re: 画像移動がおかしいのですが
Posted: 2016年8月21日(日) 18:27
by みけCAT
明らかにコンパイルできないコードが貼ってあるので実際のコードがわかりませんが、
素直に座標を毎フレームリセットするコードを書いているから座標が毎フレームリセットされるだけではないでしょうか?
でも、まさか画像を毎フレームロードするコードを書いているなんて思いたくないので、この推測もきっと間違いですよね。
まずは、コンパイルして実行可能ファイルを作れる本物のコードを提示していただけないでしょうか?
Re: 画像移動がおかしいのですが
Posted: 2016年8月21日(日) 18:41
by LEMO
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);
どうでしょう?これで大丈夫でしょうか?
情報不足で申し訳ありませんでした
Re: 画像移動がおかしいのですが
Posted: 2016年8月21日(日) 18:43
by LEMO
すみません
トピック投稿時にはlomeとの名前でやっていたのですが
トピック投稿をしてからLEMOという名前のアカウントを作らせていただきました
同一人物という認識でお願いします
Re: 画像移動がおかしいのですが
Posted: 2016年8月21日(日) 22:25
by Dixq (管理人)
C言語の基本を理解されていないようです。
関数内で定義した変数の状態は関数を抜けると維持できません。
sp.4で紹介しているようにファイルの先頭でstatic変数を宣言してそれを使ってください。
また、このコードのままだと関数を通るたびに画像をメモリにロードし、それを破棄しないまままた同じ画像をロードします。
酷いメモリリークが続き、いずれメモリが枯渇するでしょう。
画像はsp.5で紹介しているようにInitializeで一度だけやるようにしましょう。
Re: 画像移動がおかしいのですが
Posted: 2016年8月22日(月) 00:39
by LEMO
ありがとうございます!
自分なりに改変してみた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でそこに+と-をしていくという方法を使ってしっかり動きました!
ですが、これが正しい書き方なのでしょうか?
Re: 画像移動がおかしいのですが
Posted: 2016年8月22日(月) 21:22
by Dixq (管理人)
ほぼ正解です。
厳密に言うなら
① 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フレーム目以上なのか区別したい場合が必ず出てきます。
そのような計算がこのモジュール内で出来ていますので参照するだけでよいのです。