DrawGraphされない

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

DrawGraphされない

#1

投稿記事 by ぷるまん » 8年前

画像が表示されません。
PCはWin10 home,開発環境はVisual Studio 2015 Professionalで、c++を使用しています。

画像情報を保存するImageというクラスを自作し、使っています。(以下の通り、実際に動かなかったコードから、使用していないものを省いています。)

Image.h

コード:

#pragma once
#include "DxLib.h"
class Image {
private:
	int handle,px, py;
public:
	Image();
	Image(const char* const pass);
	~Image();
	int Draw();
	void move();
};
Image.cpp

コード:

#include "Image.h"

Image::Image() : handle(NULL), px(0), py(0){
}

Image::Image(const char* const pass) : Image() {
	handle = LoadGraph(pass);
}

Image::~Image() {
	DeleteGraph(handle);
}

int Image::Draw() {
	DrawGraph(px,py, handle, TRUE);
	return 0;
}

void Image::move() {
	px++;
}
さらに、Imageクラスのインスタンスを1つメンバー変数に持ち、これを自動で動かしながら表示するクラスMoveImageを作成しました。(こちらも簡略化しています。)

MoveImage.h

コード:

#pragma once
#include "Image.h"
class MoveImage {
private:
	Image img;
public:
	MoveImage();
	MoveImage(const char* const pass);
	~MoveImage();
	int Draw();
};
MoveImage.cpp

コード:

#include "MoveImage.h"

MoveImage::MoveImage() {
	img = Image();
}

MoveImage::MoveImage(const char* const pass){
	img= Image(pass);
}

MoveImage::~MoveImage() {
}

int MoveImage::Draw() {
	img.move();
	img.Draw();
	return 0;
}
これらのクラスを使おうとしたところ、Imageは正しく表示されましたが、MoveImageが表示されません。
表示したコードは以下の通りです。

Main.cpp

コード:

#include "DxLib.h"
#include "Image.h"
#include "MoveImage.h"

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
	SetGraphMode(640,480,32);
	ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen(DX_SCREEN_BACK);

	Image img("res/image/gazou.png");
	MoveImage move("res/image/gazou.png");
	while (!ScreenFlip() && !ProcessMessage() && !ClearDrawScreen()) {
		img.Draw();
		move.Draw();
	}
	DxLib_End();	//おしまい
}
これを行うと、下のように初めに左上に画像が表示されて、それが右に動いていくはずなのですが、動くはずの画像が表示されないのです。

○ ○
○  ○
○   ○
○    ○
↑Image ↑MoveImage

どこが悪いのかわかりませんが、Imageクラスをメンバーに持つと、それが表示できないのです。
画像ハンドルには0でない数値がきちんと入っているので、LoadGraph出来ていないということはないと思います。
また、調べてみて多かったビット深度の問題も確認しました。(そもそもImageは表示できるので、そこは大丈夫だと思います。)

不足している情報があればお教えください。長文失礼いたしました。よろしくお願いします。

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

Re: DrawGraphされない

#2

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

画像が表示されないのは、

コード:

	img= Image(pass);
という行において、
  1. Image(pass)により、画像が読み込まれ、Imageクラスのhandleに格納される
  2. デフォルトの代入演算子により、1で作られたImageクラスのメンバ変数(handle, px, py)がimgにコピーされる
  3. Image(pass)は用済みなので消滅する。このときデストラクタが実行され、handleに格納された画像が消去される
という動作が実行されるからですね。
その結果、img.handleも消去された画像のハンドルなので、描画されません。

このコードはThe Rule of Threeに違反しています。
違反を解消するには、Imageクラスの代入演算子やコピーコンストラクタを明示的に定義し、ハンドルの値ではなく画像をコピーするようにするといいでしょう。
(残念ながら今のところ画像をコピーするうまい方法はよくわかりませんでした)

とりあえずこの不都合を解消するには、MoveImageクラスのコンストラクタで代入演算子を使わず直接Imageの初期化をするといいでしょう。
すなわち、

コード:

MoveImage::MoveImage() {
	img = Image();
}

MoveImage::MoveImage(const char* const pass){
	img= Image(pass);
}

コード:

MoveImage::MoveImage() : img() {
}

MoveImage::MoveImage(const char* const pass) : img(pass) {
}
とするといいでしょう。

このことを確かめるため、以下のようなコードを用意しました。
► スポイラーを表示
IMPROVEを定義せずにコンパイルした場合、もとのコードが実行され、

コード:

load res/image/gazou.png as id 0
load res/image/gazou.png as id 1
delete id 1
draw id 0 to (0, 0) (trans = 1)
draw id 1 to (1, 0) (trans = 1)
delete id 1
delete id 0
と出力されるので、消去された画像を描画しようとしていることがわかります。
一方、IMPROVEを定義してコンパイルした場合、改善したコードが実行され、

コード:

load res/image/gazou.png as id 0
load res/image/gazou.png as id 1
draw id 0 to (0, 0) (trans = 1)
draw id 1 to (1, 0) (trans = 1)
delete id 1
delete id 0
と出力されるので、描画する画像は消去されていないことがわかります。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

返信

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