RPGのマップ表示の仕方
Posted: 2011年12月05日(月) 10:10
たとえばこんなマップがあるとして、
このマップを未探検のときは以下のようにマップが表示されます
しかし、次のようにキャラが移動するとマップが徐々に表示されていきます
こういうのをDXLib&C++で作りたいのですがどのようにしたらいいか教えてください。
画像の表示は出来ますが、方法が全く思いつきません。
画像の表示は出来ますが、方法が全く思いつきません。
ここは一瞬一瞬なら作れると思います。暗闇の中をキャラの周りだけが明るくなるステージみたいな状況です。ふりかけ さんが書きました:マスクデータにはプレイヤーキャラクターの視野を(たぶん白黒で)描画します。それを真のマップ(1枚目の画像のような)
と合成します。これで今見えている地形が作れると思います。
たぶんここが無理です。ふりかけ さんが書きました:これを探索済みマップ用のキャンバスに描画します(スプライトのように透過色を利用して)。
3DRPGを作ってるので、ステージを真上から見た状態をPrntScrしてマップを作りました。non さんが書きました:マップをどのように作っているのかで
が・・・・頑張ります。softya(ソフト屋) さんが書きました:他の人の参考にもなるので出来たコードを貼れるまで行って欲しいですね。
extern int LoadSoftImage( const TCHAR *FileName ) ; // ソフトウエアで扱うイメージの読み込み( -1:エラー -1以外:イメージハンドル )
extern int BltSoftImageWithTransColor( int SrcX, int SrcY, int SrcSizeX, int SrcSizeY, int SrcSIHandle, int DestX, int DestY, int DestSIHandle, int Tr, int Tg, int Tb, int Ta ) ; // ソフトウエアで扱うイメージを透過色処理付きで転送する
#include "DXLib.h"
struct S_CharaData
{
int X, Y;
};
class C_Test {
int CharaHandle, MapHandle;
int ScHandle;
S_CharaData CharaData;
int KeyCnt;
int MapFlag;
public:
void Load(void);
void InIt(void);
void Move(char *KeyBuf);
void Draw(char *KeyBuf);
void Save(void);
};
void C_Test::Load(void)
{
FILE *lf;
lf = fopen( "data2\\data0.test" , "rb" );
fread( &CharaData, sizeof(CharaData), 1, lf);
fclose(lf);
}
void C_Test::InIt(void)
{
CharaHandle = LoadGraph("data2\\キャラ.png");
MapHandle = LoadGraph("data2\\マップ.png");
// 透明抜き用のスクリーン作成
ScHandle = MakeScreen(600,480,TRUE);
// 作成したスクリーンを描画対象にする
SetDrawScreen( ScHandle ) ;
// セーブファイルから読み込み
if( -1 == LoadGraphScreen(0,0,"data2\\blind2.png",TRUE) ) {
// 元の画像を読み込み
LoadGraphScreen(0,0,"data2\\blind.bmp",FALSE);
}
// 描画対象を裏画面に戻す
SetDrawScreen( DX_SCREEN_BACK ) ;
}
void C_Test::Move(char *KeyBuf)
{
//カーソルキー↑が押されていたら上移動
if(KeyBuf[KEY_INPUT_UP]==1)
{
CharaData.Y -= 3;
}
//カーソルキー↓が押されていたら下移動
if(KeyBuf[KEY_INPUT_DOWN]==1)
{
CharaData.Y += 3;
}
//カーソルキー←が押されていたら左移動
if(KeyBuf[KEY_INPUT_LEFT]==1)
{
CharaData.X -= 3;
}
//カーソルキー→が押されていたら右移動
if(KeyBuf[KEY_INPUT_RIGHT]==1)
{
CharaData.X += 3;
}
}
void C_Test::Draw(char *KeyBuf)
{
//ステージ描画
DrawGraph( 0, 0, MapHandle, FALSE );
DrawGraph( CharaData.X-25, CharaData.Y-25, CharaHandle, TRUE );
// マッピング処理
{
// 作成したスクリーンを描画対象にする
SetDrawScreen( ScHandle ) ;
// 透明抜きするために描画するとαチャンネルを0になるように設定。
SetDrawBlendMode( DX_BLENDMODE_MUL, 0 ); // 0 を指定するとαチャンネルは必ず 0 になる
// 円形に透明に繰り抜く
DrawCircle( (CharaData.X-25)/2, (CharaData.Y-25)/2, 25, GetColor(255,255,255), TRUE );
// ノーマルブレンドに戻す。
SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 255 );
// 描画対象を裏画面に戻す
SetDrawScreen( DX_SCREEN_BACK ) ;
}
// BltSoftImageWithTransColor(0, 0, 50, 50, SeeSightHandle, (CharaData.X-25)/2, (CharaData.Y-25)/2, BlindHandle,0,0,0,255);
// BltSoftImage(0, 0, 50, 50, SeeSightHandle, (CharaData.X-25)/2, (CharaData.Y-25)/2, BlindHandle );
if(KeyBuf[KEY_INPUT_M]==1)
{
KeyCnt++;
if(KeyCnt == 1) MapFlag = 1 - MapFlag;
} else {
KeyCnt = 0;
}
if( MapFlag == 1 )
{
DrawExtendGraph( 150, 120, 450, 360, MapHandle, FALSE );
DrawExtendGraph( 150, 120, 450, 360, ScHandle, TRUE );
//DrawExtendGraph( 150, 120, 450, 360, BlindHandle, FALSE );
// DrawSoftImage( 0, 0, BlindHandle);
}
}
void C_Test::Save()
{
FILE *sf;
sf = fopen( "data2\\data0.test" , "wb" );
fwrite( &CharaData, sizeof(CharaData), 1, sf);
fclose(sf);
// 作成したスクリーンを描画対象にする
SetDrawScreen( ScHandle ) ;
// 保存する
SaveDrawScreenToPNG( 0, 0, 600, 480, "data2\\blind2.png" );
// 描画対象を裏画面に戻す
SetDrawScreen( DX_SCREEN_BACK ) ;
}
C_Test Test;
char KeyBuf[256];
int KeyCnt;
int SaveFlag;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
{
//画面作成
SetGraphMode( 600, 480, 32);
// ウインドウモード
ChangeWindowMode( TRUE );
if(DxLib_Init() == -1) return -1;
//バックバッファに描画
if(SetDrawScreen(DX_SCREEN_BACK) != 0) return -1;
Test.Load();
Test.InIt();
}
//メインループ(ESCで終了)
while(ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0)
{
GetHitKeyStateAll(KeyBuf);
//画面の初期化
ClearDrawScreen();
Test.Move(KeyBuf);
Test.Draw(KeyBuf);
if(KeyBuf[KEY_INPUT_S]==1)
{
KeyCnt++;
if(KeyCnt == 1) SaveFlag = 1 - SaveFlag;
} else {
KeyCnt = 0;
}
if( SaveFlag == 1 )
{
Test.Save();
return 0;
}
//フリップ
ScreenFlip();
}
DxLib_End();
return 0;
}出来ればお願いします。史上最悪のデスペナ さんが書きました:ありがとうございます!
リファイン後のプログラムを載せた方がいいでしょうか?
了解です。softya(ソフト屋) さんが書きました:出来ればお願いします。
ゲームに実装するときはクライアントがウィンドウサイズを変更できるようにしているのでsoftya(ソフト屋) さんが書きました:特に問題なのはスクリーンのサイズが決め打ちなことですね。
出来れば画像データのサイズを見てスクリーンサイズを設定して欲しいです。
このリンク先に書かれていた通りSetDrawValidAlphaChannelGraphCreateFlag() 関数に TRUE を引き渡しても駄目でした。softya(ソフト屋) さんが書きました:ここを参考にしました。↓
「MakeGraph() による背景の透明化」
http://hpcgi2.nifty.com/natupaji/bbs/pa ... ew&no=2278
ウィンドウサイズに合わせるとこまでしかまだ出来ていません史上最悪のデスペナ さんが書きました:ゲームに実装するときはクライアントがウィンドウサイズを変更できるようにしているので
ウィンドウサイズに合わせ、かつ、マウスで移動できるようにしたものを貼り付けます。
UIサイズをクライアントが変更出来るかできないかも設定できるようにしておきます。
今回のゲーム用マップに関しましては円で十分です。softya(ソフト屋) さんが書きました:そういう要望であるなら根本的に考えなおさないと難しいですね。
ただ消すだけで「透明抜き」さえしなければ難しくないですよ。史上最悪のデスペナ さんが書きました:今回のゲーム用マップに関しましては円で十分です。softya(ソフト屋) さんが書きました:そういう要望であるなら根本的に考えなおさないと難しいですね。
もし、今後「DXライブラリでペイントのようなソフトが作りたいのですがいろんな形の消しゴム機能の作り方が分かりません」
という方が現れましたら、その方に教えてあげてください。
もちろん透明抜きですsoftya(ソフト屋) さんが書きました:ただ消すだけで「透明抜き」さえしなければ難しくないですよ。
ペイントの消しゴムにマスクしての消しゴム機能なんて有りましたっけ?史上最悪のデスペナ さんが書きました:もちろん透明抜きですsoftya(ソフト屋) さんが書きました:ただ消すだけで「透明抜き」さえしなければ難しくないですよ。
よく考えたら「マウスで移動でき、UIサイズを変更出来るかできないか設定できる」っていうのは私が作らなくてもいいような気がしましたので史上最悪のデスペナ さんが書きました:ウィンドウサイズに合わせ、かつ、マウスで移動できるようにしたものを貼り付けます。
UIサイズをクライアントが変更出来るかできないかも設定できるようにしておきます。
自分で使う場合は自分の分かりやすいとこ(クラス)に組み込む予定ですが、softya(ソフト屋) さんが書きました:EasyDrawFuncはなぜクラスではないのでしょうか?