お初です。早速なんですがキャラクターの透過処理で質問です。
シューティングゲームのサンプルゲームのキャラクター画像を使うと背景が綺麗に透過処理されるのですが自作したドットキャラクターを使うと白い部分が透過処理が行われません。どこをどう指定すればよいのでしょうか?なおサンプルと同じキャラクターの大きさではありません。
画像を添付します。
キャラクターの透過処理について
Re:キャラクターの透過処理について
画像は何のソフトで作っていらっしゃいますか?
http://siriasu.s10.xrea.com/webtips/tips03.htm
こちら参考になると思います。
私はXPの環境でペイントで透過処理したこと無いのですが、DXライブラリでの透過処理に限り、透過させたいところは「真っ黒にすれば透過処理される」という仕様ですので、ペイントでも透過処理させることは出来ます。
http://homepage2.nifty.com/natupaji/DxL ... .html#R3N1
(windows98のペイントのみ、GIFが透過処理できますが、それ以降はライセンスの関係で透過処理できなくなったらしいです。)
フォトショップ、GIMP、PictBearなどの高機能ソフトなら普通に範囲指定→カットすることで透過処理できます。(背景を透過処理する設定にする必要あり(上記リンク参照))
ちなみにペイントで透過処理させるならこう(背景真っ黒)

高機能ソフトで透過処理させるならこのようになります。

最初のうちは「真っ黒」にする事で透過処理させるほうが簡単かと思います。(少しでも色が混ざった黒だと透過処理されません。輝度はR,G,B,=0,0,0にしてください)そのうちボカシやアルファブレンドを使いたくなってくると思いますのでその時高機能ソフトで編集してもいいと思います。
http://siriasu.s10.xrea.com/webtips/tips03.htm
こちら参考になると思います。
私はXPの環境でペイントで透過処理したこと無いのですが、DXライブラリでの透過処理に限り、透過させたいところは「真っ黒にすれば透過処理される」という仕様ですので、ペイントでも透過処理させることは出来ます。
http://homepage2.nifty.com/natupaji/DxL ... .html#R3N1
(windows98のペイントのみ、GIFが透過処理できますが、それ以降はライセンスの関係で透過処理できなくなったらしいです。)
フォトショップ、GIMP、PictBearなどの高機能ソフトなら普通に範囲指定→カットすることで透過処理できます。(背景を透過処理する設定にする必要あり(上記リンク参照))
ちなみにペイントで透過処理させるならこう(背景真っ黒)
高機能ソフトで透過処理させるならこのようになります。
最初のうちは「真っ黒」にする事で透過処理させるほうが簡単かと思います。(少しでも色が混ざった黒だと透過処理されません。輝度はR,G,B,=0,0,0にしてください)そのうちボカシやアルファブレンドを使いたくなってくると思いますのでその時高機能ソフトで編集してもいいと思います。
Re:キャラクターの透過処理について
丁寧な回答ありがとうございました。高機能ソフト(GIMP)で透過処理をさせる事が出来ました。
もう一つ質問なのですが選択できるタイトル画面を製作する場合はどのようにすればよいのでしょうか?
例えばエンターキーを押して開始する(エンターを押さなければデモに移項)だけのゲームでは以下のような記述をしています。
void TitleMain(void)
{
// エンターが押されたらば
if ( DDGetKeyInfo(VK_RETURN) == DDGETKEYINFO_DOWN )
{
gGameMode =MODE_GAME;// モードをゲーム中へ
PlayInit(); // 1ゲーム初期化
}
// 1200カウントでデモスタート
if (gDemoCnt>1200)
{
gGameMode = MODE_GAME; // モードをゲーム中へ
PlayInit(); // 1ゲーム初期化
gDemoMode=ON;
gDemoCnt=0;
gShip.dir=3;
}
// ボス移動
if (gDemoCnt%120==0)
{
gBoss.x=rand()%(WIDHMAX-BOSS_XSIZE);
gBoss.y=rand()%(HEIGHTMAX-BOSS_YSIZE);
}
}
void TitleDraw(void){
int sy;
DDRectBlt(DDSCREEN,0,0,sBG);
// ボスの表示
if (gDemoCnt>300) // デモカウントが300以上で
{
if (gDemoCnt%20>=10)
DDRectBltSprite( DDSCREEN, (int)gBoss.x, (int)gBoss.y,
BOSS_XSIZE, BOSS_YSIZE,
sBoss, 0, BOSS_YSIZE,
BOSS_XSIZE, BOSS_YSIZE );
else // 通常
DDRectBltSprite( DDSCREEN, (int)gBoss.x, (int)gBoss.y,
BOSS_XSIZE, BOSS_YSIZE,
sBoss, 0, 0,
BOSS_XSIZE, BOSS_YSIZE );
}
// タイトルの表示
// カウンタにより縮小表示
sy = gDemoCnt/2+1;
if (sy>TITLE_YSIZE)
sy=TITLE_YSIZE;
DDRectBltSprite( DDSCREEN, 70, 50,TITLE_XSIZE, sy,
sTitle1, 0, 0, TITLE_XSIZE, TITLE_YSIZE );
DDRectBltSprite(DDSCREEN,170,250,sTitle2);
}
// ------------------------------------------------
// タイトル 初期化
// ------------------------------------------------
void TitleInit(void)
{
gDemoMode=OFF;
gDemoCnt=0;
}
void GameMain()
{
ShipMove();
BeamMove();
BeamSet();
Beam2Set();
EnemySet();
EnemyMove();
BeamEnemyHit();
EbeamMove();
EbeamSet();
EbeamShipHit();
EnemyShipHit();
BGScroll();
BossMove();
BossSet();
BossBeamSet();
BeamBossHit();
ShipBossHit();
// エンターが押されたら
if (DDGetKeyInfo(VK_RETURN) == DDGETKEYINFO_DOWN )
{
gGameMode = MODE_OVER; // モードをタイトルへ
DAPlaySE( sndSE3, false );
TitleInit();
}
// シップのヒットポイントが0以下になったらば
if (gShip.hp<=0)
{
gGameMode = MODE_OVER; // モードをゲームオーバーへ
DAStop( sndBGM );
gDemoCnt = 0; // デモカウンタをクリア
}
if (gDemoMode==ON && gShip.hp<=0)
{
gGameMode = MODE_TITLE; // モードをゲームオーバーへ
DAStop( sndBGM );
gDemoCnt = 0; // デモカウンタをクリア
gDemoMode=OFF;
}
// デモ中にエンターが押されたら
if ( gDemoMode==ON && DDGetKeyInfo(VK_RETURN) == DDGETKEYINFO_DOWN )
{
gGameMode = MODE_TITLE; // モードをタイトルへ
DAPlaySE( sndSE3, false );
TitleInit();
}
}
もう一つ質問なのですが選択できるタイトル画面を製作する場合はどのようにすればよいのでしょうか?
例えばエンターキーを押して開始する(エンターを押さなければデモに移項)だけのゲームでは以下のような記述をしています。
void TitleMain(void)
{
// エンターが押されたらば
if ( DDGetKeyInfo(VK_RETURN) == DDGETKEYINFO_DOWN )
{
gGameMode =MODE_GAME;// モードをゲーム中へ
PlayInit(); // 1ゲーム初期化
}
// 1200カウントでデモスタート
if (gDemoCnt>1200)
{
gGameMode = MODE_GAME; // モードをゲーム中へ
PlayInit(); // 1ゲーム初期化
gDemoMode=ON;
gDemoCnt=0;
gShip.dir=3;
}
// ボス移動
if (gDemoCnt%120==0)
{
gBoss.x=rand()%(WIDHMAX-BOSS_XSIZE);
gBoss.y=rand()%(HEIGHTMAX-BOSS_YSIZE);
}
}
void TitleDraw(void){
int sy;
DDRectBlt(DDSCREEN,0,0,sBG);
// ボスの表示
if (gDemoCnt>300) // デモカウントが300以上で
{
if (gDemoCnt%20>=10)
DDRectBltSprite( DDSCREEN, (int)gBoss.x, (int)gBoss.y,
BOSS_XSIZE, BOSS_YSIZE,
sBoss, 0, BOSS_YSIZE,
BOSS_XSIZE, BOSS_YSIZE );
else // 通常
DDRectBltSprite( DDSCREEN, (int)gBoss.x, (int)gBoss.y,
BOSS_XSIZE, BOSS_YSIZE,
sBoss, 0, 0,
BOSS_XSIZE, BOSS_YSIZE );
}
// タイトルの表示
// カウンタにより縮小表示
sy = gDemoCnt/2+1;
if (sy>TITLE_YSIZE)
sy=TITLE_YSIZE;
DDRectBltSprite( DDSCREEN, 70, 50,TITLE_XSIZE, sy,
sTitle1, 0, 0, TITLE_XSIZE, TITLE_YSIZE );
DDRectBltSprite(DDSCREEN,170,250,sTitle2);
}
// ------------------------------------------------
// タイトル 初期化
// ------------------------------------------------
void TitleInit(void)
{
gDemoMode=OFF;
gDemoCnt=0;
}
void GameMain()
{
ShipMove();
BeamMove();
BeamSet();
Beam2Set();
EnemySet();
EnemyMove();
BeamEnemyHit();
EbeamMove();
EbeamSet();
EbeamShipHit();
EnemyShipHit();
BGScroll();
BossMove();
BossSet();
BossBeamSet();
BeamBossHit();
ShipBossHit();
// エンターが押されたら
if (DDGetKeyInfo(VK_RETURN) == DDGETKEYINFO_DOWN )
{
gGameMode = MODE_OVER; // モードをタイトルへ
DAPlaySE( sndSE3, false );
TitleInit();
}
// シップのヒットポイントが0以下になったらば
if (gShip.hp<=0)
{
gGameMode = MODE_OVER; // モードをゲームオーバーへ
DAStop( sndBGM );
gDemoCnt = 0; // デモカウンタをクリア
}
if (gDemoMode==ON && gShip.hp<=0)
{
gGameMode = MODE_TITLE; // モードをゲームオーバーへ
DAStop( sndBGM );
gDemoCnt = 0; // デモカウンタをクリア
gDemoMode=OFF;
}
// デモ中にエンターが押されたら
if ( gDemoMode==ON && DDGetKeyInfo(VK_RETURN) == DDGETKEYINFO_DOWN )
{
gGameMode = MODE_TITLE; // モードをタイトルへ
DAPlaySE( sndSE3, false );
TitleInit();
}
}
Re:キャラクターの透過処理について
すみません、つまり今何が出来なくて困っていますか?
選択項目を表示して選択させる場合はゲームプログラミングの館の33章
http://dixq.net/g/#33
等を参考にされてみてはいかがでしょうか。
回答が希望するものじゃなかったらすみません(_ _|||)
選択項目を表示して選択させる場合はゲームプログラミングの館の33章
http://dixq.net/g/#33
等を参考にされてみてはいかがでしょうか。
回答が希望するものじゃなかったらすみません(_ _|||)
Re:キャラクターの透過処理について
解決してよかったですね。
押している=1
押していない=0
だけでは「たった今押された」という判定が出来ませんよね。
これ我流なんで、いい方法かどうか解りませんけど、「たった今押した」ってことは
前回の入力状態が0で今の入力状態が1のときですよね。つまり
GetHitKeyStateAll( Key ) ;
で得た入力状態をstatic char old_Key[256]に前の状態として保存しておく事で判定出来、
if( old_Key[○○]==0 && Key[○○]==1 )
の時
Key[○○]=2;
とする関数を一つ作っておくんです。
するとKey[○○]に2が入っているとたった今入力した事がわかり、1回のプッシュで1回の処理が出来ます。
いい方法かどうかわかりませんが参考までに。
押している=1
押していない=0
だけでは「たった今押された」という判定が出来ませんよね。
これ我流なんで、いい方法かどうか解りませんけど、「たった今押した」ってことは
前回の入力状態が0で今の入力状態が1のときですよね。つまり
GetHitKeyStateAll( Key ) ;
で得た入力状態をstatic char old_Key[256]に前の状態として保存しておく事で判定出来、
if( old_Key[○○]==0 && Key[○○]==1 )
の時
Key[○○]=2;
とする関数を一つ作っておくんです。
するとKey[○○]に2が入っているとたった今入力した事がわかり、1回のプッシュで1回の処理が出来ます。
いい方法かどうかわかりませんが参考までに。