8
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

DXLibで画像の透明部分を判定する

Last updated at Posted at 2018-03-13

DXライブラリにはLoadGraphDrawGraph,DrawExtendGraphといった便利な関数が充実しています。
画像の表示、変形表示などを行うにはこれで十分ですが、これらの関数はピクセル単位でアクセスしたい場面で力を発揮できません。
具体的には、キャラクターの一枚絵をクリックしてリアクションを引き出したいときなどでしょうか。「艦○れ」みたいな。
背景の透過部分では判定させずに、キャラクターの身体をクリックしたときだけ反応させたいようなケースでは、マウスの座標を取得し、画像のそのピクセルのアルファ値(透過度)を調べないといけません。

今回はそんな感じのサンプルコードを作ってみました。

#include<Dxlib.h>

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
	ChangeWindowMode(TRUE);
	if(DxLib_Init() < 0)return -1;

	int sHandle = LoadSoftImage("img.png");
	int gHandle = LoadGraph("img.png");
	
	while (!ProcessMessage() && !ScreenFlip() && !ClearDrawScreen()){
		//DrawSoftImageは負荷が非常に高いので、DrawGraphで描画する
		DrawGraph(0, 0, gHandle, TRUE);

		int mouseX = 0, mouseY = 0;
		GetMousePoint(&mouseX, &mouseY);
		int r = 0, g = 0, b = 0, a = 0;
		GetPixelSoftImage(sHandle, mouseX, mouseY, &r, &g, &b, &a);
		//アルファ値は0(透明)~255(不透明)
		if (a > 0){
			DrawFormatString(20, 20, 0xffffff, "ON BODY");
		}
	}

	DxLib_End();
	return 0;
}

「img.png」には適当な透過PNG画像を用意してください。

LoadSoftImageで読み込んだ画像にはピクセル単位でアクセスすることができます。
GetPixelSoftImageの引数にハンドルと座標とRGB値、そしてアルファ値を保存するアドレスを指定します。
取得できるアルファ値は0~255の整数となり、完全に透明な座標では0になります。

気をつけるべき点として、LoadSoftImageで読み込んだ画像をそのまま描画するDrawSoftImage使うべきではないということです。理由はマシンへの負荷が非常に高いからとされています。
著者の環境で検証したところ、描画する画像が40枚を超えた辺りで露骨に処理落ちし始めました。これでは実際のゲーム作りに耐えられませんね。

今回は使い慣れているLoadGraphで再度画像を読み込みましたが、CreateGraphFromSoftImageという関数を使うと、サンプルコード中の「sHandle」からDrawGraphで使えるハンドルを作成することができます。ゲームのロード時間を節約したいときなどは、こちらの方が効果的かもしれません。

他にもLoadSoftImageは一枚の画像から色違い(2Pカラー)を作成したり、面白い使い方ができそうです。

8
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?