シューティングゲームを作ろうとしていますが、なかなかうまくできません。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
STAR_HARUKI7

シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#1

投稿記事 by STAR_HARUKI7 » 14年前

シューティングゲームを作ろうとしているのですが、自機を表示させ、上下左右には動かせるようにはしたのですが、弾をどのようにして出せばいいのかわかりません。

このホームページで参考しようと思ったのですが、プログラムは『 EmptyProject.cpp』を使っています。またキーは『keycheck関数』を自ら作り、キー情報をとっています。

一応スペースキーで弾を発射させようと考えています。

directXを使っていて、 EmptyProject2005を使用しています。

アバター
h2so5
副管理人
記事: 2212
登録日時: 14年前
住所: 東京
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#2

投稿記事 by h2so5 » 14年前

どこが分からないのかが良く分からないのですが、
スペースキーを押したら自機の位置に弾の画像を表示

フレームごとに弾を移動

で出来ると思います。

STAR_HARUKI7

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#3

投稿記事 by STAR_HARUKI7 » 14年前

すみません。具体的に説明します。

●弾の画像を表示させたのですが、どのようにして弾を動かせばいいのかわからない。
また、弾を連続で発射できるようにしたい。
しかし、画像をただ移動させただけだと弾が発射された感じではなく、ただ動かしただけにしか見えなくなる(当たり前ですが…)。


返信してくれた人への質問。
●フレームは聞くのですが、どういうものなのか、どういう使い方をするのか知りません。

アバター
h2so5
副管理人
記事: 2212
登録日時: 14年前
住所: 東京
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#4

投稿記事 by h2so5 » 14年前

ここを見た方が早いと思います。
STAR_HARUKI7さんの疑問にすべて答えていると思いますので。
http://www.dixq.net/rp/
STAR_HARUKI7 さんが書きました:しかし、画像をただ移動させただけだと弾が発射された感じではなく、ただ動かしただけにしか見えなくなる(当たり前ですが…)。
「発射された感じ」が具体的にどのような動作なのかが説明できないと、
プログラムしようがないと思います。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#5

投稿記事 by softya(ソフト屋) » 14年前

少なくともゲームプログラミングの基本的な知識がまったく不足していると思われますので、DirectXの前にこちらのDXライブラリのサイトの基本入門から始められるか
「C言語~ゲームプログラミングの館~ [DXライブラリ]」
http://dixq.net/g/
何らかの書籍を買われたほうが良いと思います。

参考。
「ノースブレインのゲームプログラミング入門」
http://www.northbrain.org/shop/Novice_Landing.htm
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

STAR_HARUKI

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#6

投稿記事 by STAR_HARUKI » 14年前

参考してみましたが、プログラムが違うみたいでエラーがたくさん出ました。

EmptyProjectなので、参考サイトでは実行が難しいかと。


C言語に、どう発展させて、弾を発射させるようにするには分からないです。
構造体とかで作れるのでしょうか?

弾を動かす処理を加えても、フラグで画像を表示、非表示にしても、弾が発射している感じがしません。
※ブロック崩しの弾の動きでも応用できないかと思ったのですが、無理でした。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#7

投稿記事 by softya(ソフト屋) » 14年前

STAR_HARUKI さんが書きました:参考してみましたが、プログラムが違うみたいでエラーがたくさん出ました。
EmptyProjectなので、参考サイトでは実行が難しいかと。
C言語に、どう発展させて、弾を発射させるようにするには分からないです。
構造体とかで作れるのでしょうか?
弾を動かす処理を加えても、フラグで画像を表示、非表示にしても、弾が発射している感じがしません。
※ブロック崩しの弾の動きでも応用できないかと思ったのですが、無理でした。
もちろん、そのままコピーしたら動きませんよ。
そうではなくて、どうやって弾を発射する仕組みを作るかを学んでくださいって意味でh2so5さんも私も紹介しています。
根本的なところはDirectXであろうがDXライブラリであろうが別の言語やライブラリでも変わりませんが、そこさえ理解出来れば応用は自在にできるようになります。

>構造体とかで作れるのでしょうか?
構造体であることは弾の発射と直接的な関係はありません。
単に管理が楽だから構造体を使っているんですよ。

現状のソースコードをcodeタグで囲って貼ってもらったほうが説明しやすいかも知れませんのでお願いします。
youtubeとかに現状のゲームの動いている動画をアップしてもらってもアドバイスできるかと思いますが、ソースコードを見せてもらうのが一番です。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

STAR_HARUKI

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#8

投稿記事 by STAR_HARUKI » 14年前

cppプロジェクトです。

コード:

//--------------------------------------------------------------------------------------
// File: EmptyProject.cpp
//
// Empty starting point for new Direct3D applications
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
#include <stdio.h>
#include <tchar.h>

#include "dxstdafx.h"
#include "resource.h"

//-------------------------------
//プロトタイプ宣言
//-------------------------------

//-------------------------------
//その他のインクルード
//-------------------------------
#include "keycheck.h"//キーボードのキーチェック


//-------------------------------
//その他のディファイン
//-------------------------------
#define BULLET_MAX 200//弾の最大数

	//---------------------------------------------------------------------
	//関数
	//-------------------------------
	int gamemode;//ゲームモード管理変数『0:タイトル 1:ゲーム画面 2:ゲームクリア 3:ゲームオーバー』
	int times = 60,ti = 0,te = 0,ts = 0;//制限時間管理用変数
	int i;//for分で使用

	//---------------------------------------------------------------------
	//テクスチャ関数
	//-------------------------------
	LPDIRECT3DTEXTURE9		pTexture;//自機用
	LPDIRECT3DTEXTURE9		pText_tama;//自弾用


	//スプライトの作成
	LPD3DXSPRITE			pSprite;//自機用

	//---------------------------------------------------------------------
	//座標関数
	//-------------------------------
	D3DXVECTOR3				gPos = D3DXVECTOR3(290,420,0);//自機用の画像指定位置
	D3DXVECTOR3				gPos_tm = D3DXVECTOR3(310,410,0);//自機用の画像指定位置
	

	//-------------------------
	//マトリクス
	//-------------------------
	D3DXMATRIX	matrix;//行列

	//----------
	//弾の構造体
	//----------
	typedef struct _bullet
	{
		int			x,y;//座標
		int			active;//有効フラグ
		int			type;//弾の種類
	}bullet_t;

	bullet_t bullets[BULLET_MAX];//弾構造体の宣言



	//----------------------------------------------------------------------
	//フォント作成 変数宣言
	//--------------------------------
	LPD3DXFONT				pFont;//フォント0タイプ=主に、[文字表示]など
	LPD3DXFONT				pFonta;//フォントAタイプ=主に、[制限時間]など


//--------------------------------------------------------------------------------------
// Create any D3DPOOL_MANAGED resources here 
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{
    return S_OK;
}


//--------------------------------------------------------------------------------------
// Create any D3DPOOL_DEFAULT resources here 
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, 
                                const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{
    return S_OK;
}


//--------------------------------------------------------------------------------------
// Handle updates to the scene
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
	//	キー状態を調べる関数	
	keycheck( );


	//--------------------------------
	//弾に関する処理
	//-------------------------------
	//
	for(i = 0;i < 10;i++)
	{
		bullets[i].x = 310;
		bullets[i].y = 410;
		bullets[i].active = false;
		bullets[i].type = 0;
	}

	//-------------------------------------------------------------------
	//自機を移動させる処理
	//-------------------------------------------------------------------
	if(KEY_LEFT == PUSH || KEY_LEFT == HOLD)
	{
		gPos.x -= 4;
	}
	if(KEY_RIGHT == PUSH || KEY_RIGHT == HOLD)
	{
		gPos.x += 4;
	}
	if(KEY_UP == PUSH || KEY_UP == HOLD)
	{
		gPos.y -= 4;
	}
	if(KEY_DOWN == PUSH || KEY_DOWN == HOLD)
	{
		gPos.y += 4;
	}


	//-------------------------------
	//画面上から消えないようにする
	//-------------------------------
	if(gPos.x < 0)//画面の左
	{
		gPos.x = 0;
	}
	if(gPos.x >= 590)//画面の右
	{
		gPos.x = 590;
	}
	if(gPos.y < 0)//画面の上
	{
		gPos.y = 0;
	}
	if(gPos.y >= 430)//画面の下
	{
		gPos.y = 430;
	}


	

	if(KEY_SPACE == PUSH)
	{
		for(i = 0;i < 10;i++)
		{
			if(bullets[i].active == false)
			{
				bullets[i].active = true;
				if(bullets[i].active == true)
				{
					bullets[i].y -= 8;//
					if(bullets[i].y < 20)
					{
						bullets[i].y = 310;
						bullets[i].active = false;
					}
				}
			}
		}
	}


	//--------------------
	//マトリクス
	//--------------------

	//移動行列を作成
	D3DXMatrixTranslation( &matrix,bullets[i].x,bullets[i].y,0);

}


//--------------------------------------------------------------------------------------
// Render the scene 
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
    HRESULT hr;

    // Clear the render target and the zbuffer 
    V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 0, 128, 255), 1.0f, 0) );

    // Render the scene
    if( SUCCEEDED( pd3dDevice->BeginScene() ) )
    {
			//ここから描画処理を行う

			//スプライトの開始
			pSprite->Begin(D3DXSPRITE_ALPHABLEND);

			//スプライトで2D描画
			pSprite->Draw( pTexture, NULL,NULL,&gPos,D3DCOLOR_ARGB(255,255,255,255));

			if(bullets[i].active == true)
			{
				//テクスチャの描画前に行列にセットする
				pSprite->SetTransform(&matrix);
				//スプライトで2D描画=弾
				pSprite->Draw( pText_tama, NULL,NULL,NULL,D3DCOLOR_ARGB(255,255,255,255));
			}
			

			//スプライトの終了
			pSprite->End();


			//========================================
			//各フォント
			//========================================
		
			//フォント1
			RECT rectf;							//フォント位置を保持する構造体変数
			SetRect ( &rectf,10,10,640,480);		//変数への位置セット
			//フォントの描画
				pFont -> DrawText(NULL,		//標準機能で描画
				_T("仮画像による動き"),			//表示文字列
				-1,								//表示文字数
				&rectf,						//表示位置
				NULL,							//表示スタイル
				D3DCOLOR_ARGB(255,255,255,255));	//表示色
			
			
			//フォント2
			RECT rectfa;							//フォント位置を保持する構造体変数
			SetRect ( &rectfa,10,30,640,480);		//変数への位置セット
			//フォントの描画
				pFont -> DrawText(NULL,		//標準機能で描画
				_T("ゲーム画面で"),			//表示文字列
				-1,								//表示文字数
				&rectfa,						//表示位置
				NULL,							//表示スタイル
				D3DCOLOR_ARGB(255,255,255,0));	//表示色


			/*///////////////////////////////////////////
			////	変数の内容を表示するフォント
			//フォント1
			RECT recta;							//フォント位置を保持する構造体変数
			SetRect ( &recta,580,10,640,480);		//変数への位置セット
			
			TCHAR strnk[255];								
			_stprintf( strnk , _T("%d\n"),times);
			//	フォントで表示
			pFonta->DrawText( NULL, strnk,-1,&recta,NULL,D3DCOLOR_ARGB(255,0,255,0));*/


        V( pd3dDevice->EndScene() );
    }
}


//--------------------------------------------------------------------------------------
// Handle messages to the application 
//--------------------------------------------------------------------------------------
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, 
                          bool* pbNoFurtherProcessing, void* pUserContext )
{
    return 0;
}


//--------------------------------------------------------------------------------------
// Release resources created in the OnResetDevice callback here 
//--------------------------------------------------------------------------------------
void CALLBACK OnLostDevice( void* pUserContext )
{
}


//--------------------------------------------------------------------------------------
// Release resources created in the OnCreateDevice callback here
//--------------------------------------------------------------------------------------
void CALLBACK OnDestroyDevice( void* pUserContext )
{
	//テクスチャの解放
	SAFE_RELEASE(pTexture);
	SAFE_RELEASE(pText_tama);

	//スプライトの解放
	SAFE_RELEASE(pSprite);


	//	フォントの解放
	SAFE_RELEASE( pFont );
	SAFE_RELEASE( pFonta );
}



//--------------------------------------------------------------------------------------
// Initialize everything and go into a render loop
//--------------------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
{
    // Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif

    // Set the callback functions
    DXUTSetCallbackDeviceCreated( OnCreateDevice );
    DXUTSetCallbackDeviceReset( OnResetDevice );
    DXUTSetCallbackDeviceLost( OnLostDevice );
    DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
    DXUTSetCallbackMsgProc( MsgProc );
    DXUTSetCallbackFrameRender( OnFrameRender );
    DXUTSetCallbackFrameMove( OnFrameMove );
   
    // TODO: Perform any application-level initialization here

    // Initialize DXUT and create the desired Win32 window and Direct3D device for the application
    DXUTInit( true, true, true ); // Parse the command line, handle the default hotkeys, and show msgboxes
    DXUTSetCursorSettings( true, true ); // Show the cursor and clip it when in full screen
    DXUTCreateWindow( L"EmptyProject" );
    DXUTCreateDevice( D3DADAPTER_DEFAULT, true, 640, 480);

	//スプライトの作成
	D3DXCreateSprite( DXUTGetD3DDevice(), &pSprite);


	//----------------------------------------------------------------------------
	//テクスチャのロード
	//------------------------------------------------------------------
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\jiki01.png"),&pTexture );//自機(仮画像)
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\tama01.png"),&pText_tama);//弾(仮画像)



	//----------------------------------------------------------
	//フォントの作成  各パターン
	//----------------------------------------------------

	////フォントの作成(Aパターン)
		D3DXCreateFont(
			DXUTGetD3DDevice(),		//direct3Dデバイス
			16,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("ARP浪漫明朝体U"),	//フォント名
			&pFont);					//作成されたフォントが格納される変数

		//フォントの作成(Iパターン)
		D3DXCreateFont(
			DXUTGetD3DDevice(),		//direct3Dデバイス
			30,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("Broadway BT"),	//フォント名
			&pFonta);					//作成されたフォントが格納される変数


	/*//
	gPos_tm = D3DXVECTOR3(310,410,0);*/


    // Start the render loop
    DXUTMainLoop();

    // TODO: Perform any application-level cleanup here

    return DXUTGetExitCode();
}
返答にも書きましたがcodeタグをご利用下さい。読みやすさが全然違います。 by softya(ソフト屋)

一応、自機の弾発射のプログラムを参考に自分なりに変更したり、加えました。
※画像が表示されません。たぶん何かがおかしくしている。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#9

投稿記事 by softya(ソフト屋) » 14年前

codeタグを追加させてもらいました。

気になる点が幾つかあります。
・自機の座標であるgPosの情報を使わず弾を発射していますがこれが違和感の原因でないでしょうか?gPosからの相対座標で発射してみてはどうでしょう。
・連続発射のガードがされていないので一度に10発の弾が発射されています。発射したら数フレーム発射をガードすることと発射処理でbreak;で抜けたほうが良いと思います。
・発射処理と弾の移動処理が混ざって記述されています。必ず分けて記述してください。
bullets.active = true;までが発射処理で、それ以降は移動処理で発射の処理の中に書いてはいけません。

どうしてもDirectXでやりたい場合は止めませんが、もっと基本的なことをDirectXよりも簡単なこのサイトのDXライブラリの講座(既に紹介)で勉強されてはどうでしょうか?
ゲームアルゴリズムを組み立てる以前の基本の所が出来ていないと思います。
あとDirectXは、何処のサイトや書籍で勉強されているのでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

STAR_HARUKI

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#10

投稿記事 by STAR_HARUKI » 14年前

【0からのゲームプログラミング】
http://www.plustarnet.com/aspil/Programming/
【DirectXプログラミング講座】
http://www.activebasic.com/help_center/ ... index.html
【ゲームプログラミングの館】
http://dixq.net/g/29.html
と、
新・C言語入門 シニア編 (C言語実用マスターシリーズ) です。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#11

投稿記事 by softya(ソフト屋) » 14年前

【0からのゲームプログラミング】
http://www.plustarnet.com/aspil/Programming/
はC++前提ですからC言語の知識だけだと混乱すると思います。
基本的にDirectXの説明は大半がC++なんですよね。

【DirectXプログラミング講座】
http://www.activebasic.com/help_center/ ... index.html
これはVisualBasicでの説明ですね。

【ゲームプログラミングの館】
http://dixq.net/g/29.html
はDXライブラリで前提です。
DXライブラリは、内部にDirectXを隠蔽したライブラリで唯一C言語の知識だけで組むことが出来ます。

どうしてもDirectXである必要がないのであれば、DXライブラリで
「C言語~ゲームプログラミングの館~ [DXライブラリ]」
http://dixq.net/g/
「龍神録プログラミングの館」
http://dixq.net/rp/
と順番に理解されてはどうですか?
DirectXは、それからでも遅くないと思います。

私の説明「気になる点が幾つかあります。」に対応できるだけの知識があるのなら問題有りませんが。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

STAR_HARUKI

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#12

投稿記事 by STAR_HARUKI » 14年前

codeのやり方が分かりません。
ごめんなさい。

※一部省略
//--------------------------
//弾の発射
//----------------
if(KEY_SPACE == PUSH)
{
for(i = 0;i < 10;i++)
{
if(bullets.active == false)
{
bullets.active = true;
}
break;
}
}


if(bullets.active == true)
{
gPos_tm.y -= 20;//弾の座標を減らす
if(gPos_tm.y < 0)
{
gPos_tm.y = 410;
bullets.active = false;
}
}

なんとかスペースキーを押したら弾が出て、消えての繰り返しで、移動しましたが、発射のようにはいきませんでした。
たぶん、諦めた方がいいのかもしれませんね。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#13

投稿記事 by softya(ソフト屋) » 14年前

codeタグの使い方は、赤い枠内のフォーラムルールを御覧ください。

そうですね。
弾が発射されるって事がどういう事なのか具体的なイメージが出来ないでいるものと思われます。
発射する場合は次のことが必要です。
(1)発射禁止カウンタが有効なら-1して発射処理をスキップ。これはNG。
(2)自機の座標を弾の座標にコピー。これはNG。
(3)弾の生存フラグを有効にする。これはOK。
(4)発射禁止カウンタに値を設定して一定期間弾が発射されない様にする。これはNG。

それ以外にも問題が幾つもあります。
弾の表示の移動マトリクスとか弾の移動処理(gPos_tmの処理)そのものとか、やはりもう少し簡単なものから始められてはどうでしょうか?
今の現状のコードは、gPos_tmの意味と使い方の理解も出来ていないと思います。
どうやって弾のスプライトの座標に反映するかも分かっていないので、例えば弾を静止状態で良いので画面内に5つ別の場所に表示させてみてください。どうです出来ますか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

STAR_HARUKI

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#14

投稿記事 by STAR_HARUKI » 14年前

あの、デバッグをした後、警告のひとつに「無意味なif分です」とか何とか言われていた場所があったことに、気付いてそのif分を削除したら、弾の発射みたいに描画されました。
・・・・・・せっかく、返信していただいたのにごめんなさいm(__)m

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#15

投稿記事 by softya(ソフト屋) » 14年前

STAR_HARUKI さんが書きました:あの、デバッグをした後、警告のひとつに「無意味なif分です」とか何とか言われていた場所があったことに、気付いてそのif分を削除したら、弾の発射みたいに描画されました。
・・・・・・せっかく、返信していただいたのにごめんなさいm(__)m
いえ、思うとおりに制御できているなら問題んですが、今までのコードを見る限り問題山積だと思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

STAR_HARUKI

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#16

投稿記事 by STAR_HARUKI » 14年前

確かにそうなんですが・・・・・

※Codeの使い方を確認しました。
今までお騒がせしましたm(__)m

コード:

        //--------------------------------
	//弾に関する処理
	//-------------------------------
	//
	for(i = 0;i < 10;i++)
	{
		bullets[i].x = 310;//
		bullets[i].y = 410;//
		bullets[i].active = 0;//
		bullets[i].type = 0;//
	}

        //--------------------------
	//弾の発射
	//----------------
	if(KEY_SPACE == PUSH)//スペースキーが押されたら
	{
		if(bullets[i].active == 0)
		{
			bullets[i].active = 1;//弾の表示
			bullets[i].type = 0;//弾のタイプ
		}
	}
	
	switch(bullets[i].type)
	{
	case 0://
		if(bullets[i].active == 1)
		{
			gPos_tm.y -= 10;//弾の座標を減らす
			if(gPos_tm.y < 0)
			{
				gPos_tm.y = 410;
				bullets[i].active = 0;
			}
		}
		break;
	case 1://
		break;
	}
弾を画面から消えないと次の弾が出ないようにしているんですが、
それを弾が発射したら次の弾も表示させるにも
弾の表示と弾の移動にはif分が使えない(⇒理由/if分を加えると弾の画像が出なくなる)ので、どうしたらそういう処理を加えればいいのか分かりません。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#17

投稿記事 by softya(ソフト屋) » 14年前

下記のコードは、iの値を理解されてますでしょうか?結構致命的なバグなのですが。
あとgPos_tmは1つしか無いのに10個の弾の座標はどう管理するつもりでしょうか?

コード:

        //--------------------------
    //弾の発射
    //----------------
    if(KEY_SPACE == PUSH)//スペースキーが押されたら
    {
        if(bullets[i].active == 0)
        {
            bullets[i].active = 1;//弾の表示
            bullets[i].type = 0;//弾のタイプ
        }
    }
    
    switch(bullets[i].type)
    {
    case 0://
        if(bullets[i].active == 1)
        {
            gPos_tm.y -= 10;//弾の座標を減らす
            if(gPos_tm.y < 0)
            {
                gPos_tm.y = 410;
                bullets[i].active = 0;
            }
        }
        break;
    case 1://
        break;
    }
【追記】
それと学校の課題であるとか締切りがある、どうしてもDirectXで無いといけないなど理由があれば正直に書いてください。
こちら側もそれを意識して答えます。
そうでもないなら、もっとC言語の基礎的なことから再勉強された方が良いと思います(課題だとしても課題終了後には再勉強された方が良いでしょう)。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

STAR_HARUKI

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#18

投稿記事 by STAR_HARUKI » 14年前

正直に話すと、
学校の課題で、オリジナル(的な要素を入れた)の作品を作ることになったのです。

しかし、1年生でシンプルテンプレート(directXとは無関係)でシューティングゲームを授業で作ったことがあるのですが、directXではプログラムが通用せず、応用できません。

でも、作品のテーマはシューティングに(今後の自分のスキルを上げたいと思い選択)しました。

それと、今回はdirectXを使用して作成することになっています。
ただ、3Dを使用することもあるのですが、僕は選択では選ばず、学ばなかったので、2Dにしています。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#19

投稿記事 by softya(ソフト屋) » 14年前

STAR_HARUKI さんが書きました:正直に話すと、
学校の課題で、オリジナル(的な要素を入れた)の作品を作ることになったのです。

しかし、1年生でシンプルテンプレート(directXとは無関係)でシューティングゲームを授業で作ったことがあるのですが、directXではプログラムが通用せず、応用できません。

でも、作品のテーマはシューティングに(今後の自分のスキルを上げたいと思い選択)しました。

それと、今回はdirectXを使用して作成することになっています。
ただ、3Dを使用することもあるのですが、僕は選択では選ばず、学ばなかったので、2Dにしています。
DirectX限定ですね。了解しました。
ちなみに締切りはしばらく大丈夫なのでしょうか?それとプログラム内容の方の質問にお答え頂けますか?
※ なぜ返答にこだわるかというと、質問した内容のうち一部しか返答がない方は見落としが多いため返答から情報を汲み取ることに失敗している場合が多いです。
そのためにプログラムのバグに気づかないとか、同じことを繰り返している方が多いのでご自身のためになりません。
なんども読み返して見落としがないか確認をお願いします。

今提示されているコードは、すごくC言語の基本的なところである値の有効範囲やプログラムの流れのところで問題がある箇所が多いです。これはC言語の基礎の基礎の部分ですので、少なくともforループとか基本の教科書を読んだり、C言語の参考書を学校以外でも読むなど勉強を並行で行ってください。

あと、これから出かけるので私は即答はできないかも知れませんが、ご了承下さい。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

STAR_HARUKI

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#20

投稿記事 by STAR_HARUKI » 14年前

第1段階(α版)の締め切りが4月28日(木)。
たぶん、4月29日~5月8日までゴールデンウィーク休みに入るため。
第2段階(β版)が5月30日。
第3段階(MASTER版)が6月24日←最終
という感じです。

α版はゲームとして動き、面白さ(まずはプレイしたらシューティングゲームだよねって言われるような感じにするのを目標としています)を出す。
β版はゲームの微調整(ここは自分でしていこうと思います。てか、しないとダメですよね)
マスター版が最終的に完成し、提出する形になります。

ちなみに、弾の処理ですが、確かに、1個しか作っていなかったので、10個作れるように、弾の座標を構造体と一緒に管理し、
そして、最大10個としているので、if文を使って表示させました。
また、マトリクス(回転や拡大なども管理出来る)関数を使っているので、それもif文を使いました。

連続して弾が出せるようになりました。
弾を出すのに、C言語の本を読んだけれど、出すのに時間がかかってしまいました。

コード:

//--------------------------------------------------------------------------------------
// File: EmptyProject.cpp
//
// Empty starting point for new Direct3D applications
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
//古い文字列操作関数に対する警告を回避する
#pragma warning (disable : 4995)
#pragma warning (disable : 4996)

#include <stdio.h>
#include <tchar.h>

#include "dxstdafx.h"
#include "resource.h"

//-------------------------------
//プロトタイプ宣言
//-------------------------------

//-------------------------------
//その他のインクルード
//-------------------------------
#include "keycheck.h"


//-------------------------------
//その他のディファイン
//最大値を指定させる
//-------------------------------
#define BULLET_MAX 10//弾の最大数


	//-------------------------------------------------------------------------------
	//関数
	//-------------------------------
	int gamemode = 1;//ゲームモード管理変数『0:タイトル 1:ゲーム画面 2:ゲームクリア 3:ゲームオーバー』
	int times = 60,ti = 0,te = 0,ts = 0;//制限時間管理用変数
	//int tm = 0;//弾の
	int count;//弾の発射数
	int i;
	int score;//得点
	int active_te = 1;

	float	gRealTime = 0;//実時間用変数

	//-------------------------------------------------------------------------------
	//テクスチャ関数
	//-------------------------------
	LPDIRECT3DTEXTURE9		pTexture;//自機用
	LPDIRECT3DTEXTURE9		pText_tama;//自弾用
	LPDIRECT3DTEXTURE9		pText_teki;//敵用


	//スプライトの作成
	LPD3DXSPRITE			pSprite;

	//-------------------------------------------------------------------------------
	//座標関数
	//-------------------------------
	D3DXVECTOR3				gPos = D3DXVECTOR3(280,420,0);//自機用の画像指定位置
	D3DXVECTOR3				gPos_te = D3DXVECTOR3(280,100,0);//敵用の画像指定位置
	

	//-------------------------------------------------------
	//マトリクス
	//-------------------------
	
	D3DXMATRIX	matrix_ji;//自機
	D3DXMATRIX	matrix_te;//自機

	//------------------------------
	//弾の構造体
	//------------------
	typedef struct _bullet
	{
		//int			x,y;//座標
		D3DXVECTOR3		gPos_tm;//自機弾用の画像指定位置
		int				active;//有効フラグ 0:OFF 1:ON
		int				type;//弾の種類
		D3DXMATRIX		matrix;//行列
	};

	_bullet bullets[BULLET_MAX];//弾構造体の宣言


	//--------------------------------------------------------------------------------
	//フォント作成 変数宣言
	//--------------------------------
	LPD3DXFONT				pFont;//フォント0タイプ=《ARP浪漫明朝体U》主に、[文字表示]など
	LPD3DXFONT				pFonta;//フォントAタイプ=《Broadway BT》主に、[制限時間]など






//--------------------------------------------------------------------------------------
// Create any D3DPOOL_MANAGED resources here 
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{
    return S_OK;
}


//--------------------------------------------------------------------------------------
// Create any D3DPOOL_DEFAULT resources here 
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, 
                                const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{
    return S_OK;
}


//--------------------------------------------------------------------------------------
// Handle updates to the scene
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
	//	キー状態を調べる関数	
	keycheck( );

	switch(gamemode)
	{
	case 0://
		break;
	case 1://

		gRealTime += DXUTGetElapsedTime();//フレームタイムを加算していく
	

		//////////////////////////////////////////
		//制限時間を1秒減らす  適当なfor分
		//////////////////////////////////////////
		for(ti = 0;ti < 10;ti++)
		{
			te++;
			if(te > 3600)
			{
				times--;
			}
		}



		//-------------------------------------------------------------------
		//自機を移動させる処理 (押された時、押しっぱなしになった時)
		//-------------------------------------------------------------------
		if(KEY_LEFT == PUSH || KEY_LEFT == HOLD)
		{
			gPos.x -= 4;
		}
		if(KEY_RIGHT == PUSH || KEY_RIGHT == HOLD)
		{
			gPos.x += 4;
		}
		if(KEY_UP == PUSH || KEY_UP == HOLD)
		{
			gPos.y -= 4;
		}
		if(KEY_DOWN == PUSH || KEY_DOWN == HOLD)
		{
			gPos.y += 4;
		}


		//-------------------------------
		//自機の画像が
		//画面から消えないようにする
		//-------------------------------
		if(gPos.x < 0)//画面の左
		{
			gPos.x = 0;
		}
		if(gPos.x >= 585)//画面の右
		{
			gPos.x = 585;
		}
		if(gPos.y < 0)//画面の上
		{
			gPos.y = 0;
		}
		if(gPos.y >= 425)//画面の下
		{
			gPos.y = 425;
		}


		//--------------------------
		//弾の発射
		//----------------
		if(KEY_SPACE == PUSH)//スペースキーが押されたら
		{
			for (int i = 0; i < 10; i++)
			{
				if(bullets[i].active == 0)
				{
					bullets[i].active = 1;//弾の表示
					//自機の中央に表示させる
					bullets[i].gPos_tm.x = gPos.x + 29;
					bullets[i].gPos_tm.y = gPos.y + 15;

					break;
				}
			}
		}
		
		
		// for文で弾の数だけやる
		for(int i = 0;i < 10; i++)
		{
			switch(bullets[i].type)
			{
			case 0://
				if(bullets[i].active == 1)
				{
					// 弾の座標はbullet構造体の中に入れる
					bullets[i].gPos_tm.y -= 10;//弾の座標を減らす
					if(bullets[i].gPos_tm.y < 0)
					{
						bullets[i].gPos_tm.y = gPos.y;
						bullets[i].active = 0;
					}
				}
				break;
			case 1://
				break;
			}
		}

		//--------------------------
		//敵の当たり判定
		//----------------
		for(int i = 0;i < 10; i++)
		{
			if(bullets[i].gPos_tm.x >= gPos_te.x)
			{
				if(bullets[i].gPos_tm.x <= gPos_te.x + 30)//画像の中心部が初期設定になっているので半分の値を代入
				{
					if(bullets[i].gPos_tm.y >= gPos_te.y)
					{
						if(bullets[i].gPos_tm.y <= gPos_te.y + 30)//画像の中心部が初期設定になっているので半分の値を代入
						{
							if(active_te == 1)
							{
								//弾が当たったら、フラグをOFFにして、弾を最初の位置に戻す
								active_te = 0;
								bullets[i].active = 0;
								bullets[i].gPos_tm.y = 410;
							}
						}
					}
				}
			}
		}
		


		


		//-------------------------
		//マトリクスを作成
		//-------------------------

		// マトリクスもBullet構造体に入れる。
		// for文で弾の数だけまとめてMatrix計算する
		for(int i = 0;i < 10; i++)
		{
			//<matrix用=弾>
			//移動行列を作成
			D3DXMatrixTranslation( &bullets[i].matrix,bullets[i].gPos_tm.x,bullets[i].gPos_tm.y,0);
		}

		//<matrix_ji用=自機>
		//移動行列を作成
		D3DXMatrixTranslation( &matrix_ji,gPos.x,gPos.y,0);

		//<matrix_te用=敵>
		//移動行列を作成
		D3DXMatrixTranslation( &matrix_te,gPos_te.x,gPos_te.y,0);


		break;
	case 2://
		break;
	case 3://
		break;
	case 4://
		break;
	}


}


//--------------------------------------------------------------------------------------
// Render the scene 
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
    HRESULT hr;

    // Clear the render target and the zbuffer 
    V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 0, 128, 255), 1.0f, 0) );

    // Render the scene
    if( SUCCEEDED( pd3dDevice->BeginScene() ) )
    {
			//ここから描画処理を行う

			//スプライトの開始
			pSprite->Begin(D3DXSPRITE_ALPHABLEND);

		switch(gamemode)
		{
		case 0://
			break;
		case 1://

			//自機
			//テクスチャの表示領域
			RECT	rect_tex;
			SetRect(&rect_tex,0,0,60,60);
			//テクスチャの描画前に行列をセットする
			pSprite->SetTransform(&matrix_ji);
			//スプライトで2D描画
			pSprite->Draw( pTexture,&rect_tex,NULL,NULL,D3DCOLOR_ARGB(255,255,255,255));

			for(int i = 0;i < 10; i++)
			{
				if(bullets[i].active == 1)
				{
					//弾
					//テクスチャの表示領域
					RECT	rect_tex_ta;
					SetRect(&rect_tex_ta,0,0,10,10);
					//テクスチャの描画前に行列にセットする
					pSprite->SetTransform(&bullets[i].matrix);
					//中心をセット
					D3DXVECTOR3 center_ta = D3DXVECTOR3(10.f / 2.f,10.f / 2.f,0.f);
					//スプライトで2D描画=弾
					pSprite->Draw( pText_tama,&rect_tex_ta,&center_ta,NULL,D3DCOLOR_ARGB(255,255,255,255));
				}
			}
			if( active_te == 1)
			{
				//敵
				//テクスチャの表示領域
				RECT	rect_tex_te;
				SetRect(&rect_tex_te,0,0,60,60);
				//テクスチャの描画前に行列にセットする
				pSprite->SetTransform(&matrix_te);
				//スプライトで2D描画=弾
				pSprite->Draw( pText_teki,&rect_tex_te,NULL,NULL,D3DCOLOR_ARGB(255,255,255,255));
			}

			
			break;
		case 2://
			break;
		case 3://
			break;
		case 4://
			break;
		}

			//スプライトの終了
			pSprite->End();


			//========================================
			//各フォント
			//========================================
		
			//フォント1
			RECT rectf;							//フォント位置を保持する構造体変数
			SetRect ( &rectf,10,10,640,480);		//変数への位置セット
			//フォントの描画
				pFont -> DrawText(NULL,		//標準機能で描画
				_T("仮画像による動き"),			//表示文字列
				-1,								//表示文字数
				&rectf,						//表示位置
				NULL,							//表示スタイル
				D3DCOLOR_ARGB(255,255,255,255));	//表示色
			
			
			//フォント2
			RECT rectfa;							//フォント位置を保持する構造体変数
			SetRect ( &rectfa,10,30,640,480);		//変数への位置セット
			//フォントの描画
				pFont -> DrawText(NULL,		//標準機能で描画
				_T("ゲーム画面で"),			//表示文字列
				-1,								//表示文字数
				&rectfa,						//表示位置
				NULL,							//表示スタイル
				D3DCOLOR_ARGB(255,255,255,0));	//表示色


        V( pd3dDevice->EndScene() );
    }
}


//--------------------------------------------------------------------------------------
// Handle messages to the application 
//--------------------------------------------------------------------------------------
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, 
                          bool* pbNoFurtherProcessing, void* pUserContext )
{
    return 0;
}


//--------------------------------------------------------------------------------------
// Release resources created in the OnResetDevice callback here 
//--------------------------------------------------------------------------------------
void CALLBACK OnLostDevice( void* pUserContext )
{
}


//--------------------------------------------------------------------------------------
// Release resources created in the OnCreateDevice callback here
//--------------------------------------------------------------------------------------
void CALLBACK OnDestroyDevice( void* pUserContext )
{
	//テクスチャの解放
	SAFE_RELEASE(pTexture);
	SAFE_RELEASE(pText_tama);
	SAFE_RELEASE(pText_teki);
	//スプライトの解放
	SAFE_RELEASE(pSprite);

	//	フォントの解放
	SAFE_RELEASE( pFont );
	SAFE_RELEASE( pFonta );
}



//--------------------------------------------------------------------------------------
// Initialize everything and go into a render loop
//--------------------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
{
    // Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif

    // Set the callback functions
    DXUTSetCallbackDeviceCreated( OnCreateDevice );
    DXUTSetCallbackDeviceReset( OnResetDevice );
    DXUTSetCallbackDeviceLost( OnLostDevice );
    DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
    DXUTSetCallbackMsgProc( MsgProc );
    DXUTSetCallbackFrameRender( OnFrameRender );
    DXUTSetCallbackFrameMove( OnFrameMove );
   
    // TODO: Perform any application-level initialization here

    // Initialize DXUT and create the desired Win32 window and Direct3D device for the application
    DXUTInit( true, true, true ); // Parse the command line, handle the default hotkeys, and show msgboxes
    DXUTSetCursorSettings( true, true ); // Show the cursor and clip it when in full screen
    DXUTCreateWindow( L"EmptyProject" );
    DXUTCreateDevice( D3DADAPTER_DEFAULT, true, 640, 480);

	//スプライトの作成
	D3DXCreateSprite( DXUTGetD3DDevice(), &pSprite);


	//----------------------------------------------------------------------------
	//テクスチャのロード
	//------------------------------------------------------------------
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\jiki02.png"),&pTexture );//自機(仮画像)
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\tama03.png"),&pText_tama);//弾(仮画像)
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\teki01.png"),&pText_teki);//敵(仮画像)



	//----------------------------------------------------------
	//フォントの作成  各パターン
	//----------------------------------------------------

	////フォントの作成(Aパターン)
		D3DXCreateFont(
			DXUTGetD3DDevice(),		//direct3Dデバイス
			16,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("ARP浪漫明朝体U"),	//フォント名
			&pFont);					//作成されたフォントが格納される変数

		//フォントの作成(Iパターン)
		D3DXCreateFont(
			DXUTGetD3DDevice(),		//direct3Dデバイス
			30,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("Broadway BT"),	//フォント名
			&pFonta);					//作成されたフォントが格納される変数

	//-----------------------------------------------------------------------
	//1度しか実行しないもの
	//--------------------------------------------------
	
	//--------------------------------
	//弾に関する処理
	//-------------------------------
	// WinMainとかに移動
	for(i = 0;i < 10;i++)
	{
		bullets[i].gPos_tm.x = 280;
		bullets[i].gPos_tm.y = 430;
		bullets[i].active = 0;
		bullets[i].type = 0;
	}


	//--------------------------------------------------------------
	//初期化
	//-----------------------------
	bullets[i].gPos_tm = D3DXVECTOR3(280,430,0);
	score = 0;


    // Start the render loop
    DXUTMainLoop();

    // TODO: Perform any application-level cleanup here

    return DXUTGetExitCode();
}

※制限時間は気にしないでください。
実行しても出す処理を加えていません。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#21

投稿記事 by softya(ソフト屋) » 14年前

遅くなってすみません。
ソースコードを見ました。

まず、一度にたまを10発一度に発射してますが、BULLET_MAXをせっかく定義しているので使ってください。
for (int i = 0; i < 10; i++)
じゃなくて
for (int i = 0; i < BULLET_MAX; i++)
でお願いします。
あと、「敵の当たり判定」が最後に弾の生存をチェックしてますが処理が遅くなるので先にチェックするクセを今後のために付けてくださいね。

それと、こちらでは動作確認できないので現状問題あれば言って下さいね。昨日までの問題は解決していると思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

STAR_HARUKI

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#22

投稿記事 by STAR_HARUKI » 14年前

そうですね。
せっかく最大10個をBULLET_MAXに置きかけているので・・・・・・。
BULLET_MAXに変更しました。

また、「敵の当たり判定」が最後に弾の生存をチェックしてますが処理が遅くなるので先にチェックするクセ
というのは、

コード:

if(enemy[i].active_te == 1)
							{
								//弾が当たったら、フラグをOFFにする
								enemy[i].active_te = 0;
								bullets[i].active = 0;
							}
の部分でしょうか?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#23

投稿記事 by softya(ソフト屋) » 14年前

そうですね。
当たり判定後に生存チェックしてますが、生存チェックしてから当たり判定しないと敵や弾が増えると処理負荷が無駄に増えてしまいます。
特に弾幕系を作る場合には結構問題で、シューティングゲームの処理落ちの原因の大半は当たり判定ですので。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

STAR_HARUKI

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#24

投稿記事 by STAR_HARUKI » 14年前

コード:

//--------------------------------------------------------------------------------------
// File: EmptyProject.cpp
//
// Empty starting point for new Direct3D applications
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
//古い文字列操作関数に対する警告を回避する
#pragma warning (disable : 4995)
#pragma warning (disable : 4996)

#include <stdio.h>
#include <tchar.h>

#include "dxstdafx.h"
#include "resource.h"

//-------------------------------
//プロトタイプ宣言
//-------------------------------

//-------------------------------
//その他のインクルード
//-------------------------------
#include "keycheck.h"


//-------------------------------
//その他のディファイン
//最大値とかを指定させる
//-------------------------------
#define BULLET_MAX 10//弾の最大数
#define ENEMY_MAX 10//敵の最大数


	//-------------------------------------------------------------------------------
	//関数
	//-------------------------------
	int gamemode = 1;//ゲームモード管理変数『0:タイトル 1:ゲーム画面 2:ゲームクリア 3:ゲームオーバー』
	int times = 60,ti = 0,te = 0,ts = 0;//制限時間管理用変数
	int count;//弾の発射数
	int i;
	int score;//得点

	//float	gRealTime = 0;//実時間用変数
	//RECT	ScoreRect[7];//

	//-------------------------------------------------------------------------------
	//テクスチャ関数
	//-------------------------------
	LPDIRECT3DTEXTURE9		pTexture;//自機用
	LPDIRECT3DTEXTURE9		pText_tama;//自弾用
	LPDIRECT3DTEXTURE9		pText_teki;//敵用
	LPDIRECT3DTEXTURE9		pText_sc;//得点用


	//スプライトの作成
	LPD3DXSPRITE			pSprite;

	//-------------------------------------------------------------------------------
	//座標関数
	//-------------------------------
	D3DXVECTOR3				gPos = D3DXVECTOR3(280,420,0);//自機用の画像指定位置
	//D3DXVECTOR3				gPos_te = D3DXVECTOR3(280,100,0);//敵用の画像指定位置
	

	//-------------------------------------------------------
	//マトリクス
	//-------------------------
	
	D3DXMATRIX	matrix_ji;//自機
	//D3DXMATRIX	matrix_te;//自機

	//------------------------------
	//弾の構造体
	//------------------
	typedef struct _bullet
	{
		D3DXVECTOR3		gPos_tm;//自機弾用の画像指定位置
		int				active;//有効フラグ 0:OFF 1:ON
		int				type;//弾の種類
		D3DXMATRIX		matrix;//行列
	};

	_bullet bullets[BULLET_MAX];//弾構造体の宣言

	//-------------------------------------
	//敵の構造体
	//--------------------------
	typedef struct _enemy
	{
		D3DXVECTOR3		gPos_te;//敵の座標
		int				active_te;//有効フラグ 0:OFF 1:ON
		int				type;//敵の種類
		D3DXMATRIX		matrix_te;//敵の行列
	};

	_enemy enemy[ENEMY_MAX];//敵構造体の宣言


	//--------------------------------------------------------------------------------
	//フォント作成 変数宣言
	//--------------------------------
	LPD3DXFONT				pFont;//フォント0タイプ=《ARP浪漫明朝体U》主に、[文字表示]など
	LPD3DXFONT				pFonta;//フォントAタイプ=《Broadway BT》主に、[制限時間]など
	LPD3DXFONT				pFontb;//フォントBタイプ=《HGep037》主に、[ステータス表示]など

//////////////////////////////////////////////////
//
/*スコア(得点表示)*/
void setScoreRect(int vala,RECT *inScoreRect)
{
	SetRect(inScoreRect,0,vala * 32,32,(vala + 1) * 32);//
}
//
////////////////////////////////////////////////////////////



//--------------------------------------------------------------------------------------
// Create any D3DPOOL_MANAGED resources here 
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{
    return S_OK;
}


//--------------------------------------------------------------------------------------
// Create any D3DPOOL_DEFAULT resources here 
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, 
                                const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{
    return S_OK;
}


//--------------------------------------------------------------------------------------
// Handle updates to the scene
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
	//	キー状態を調べる関数	
	keycheck( );

	switch(gamemode)
	{
	case 0://
		break;
	case 1://

		//gRealTime += DXUTGetElapsedTime();//フレームタイムを加算していく
	


	/////////////////////////////////////////////////////////////
	///////////////////////////////
		/*//スコア 得点  //
		int vala;

		vala = (int)score % 10;
		setScoreRect(vala,&ScoreRect[0]);

		vala = (int)score / 10 % 10;
		setScoreRect(vala,&ScoreRect[1]);

		vala = (int)score / 10 / 10 % 10;
		setScoreRect(vala,&ScoreRect[2]);

		vala = (int)score / 10 / 10 / 10 % 10;
		setScoreRect(vala,&ScoreRect[3]);

		vala = (int)score / 10 / 10 / 10 / 10 % 10;
		setScoreRect(vala,&ScoreRect[4]);

		vala = (int)score / 10 / 10 / 10 / 10 / 10 % 10;
		setScoreRect(vala,&ScoreRect[5]);

		vala = (int)score / 10 / 10 / 10 / 10 / 10 / 10 % 10;
		setScoreRect(vala,&ScoreRect[6]);*/
	////////////////////////////////////////////////////////////////////


		//-------------------------------------------------------------------
		//自機を移動させる処理 (押された時、押しっぱなしになった時)
		//-------------------------------------------------------------------
		if(KEY_LEFT == PUSH || KEY_LEFT == HOLD)
		{
			gPos.x -= 4;
		}
		if(KEY_RIGHT == PUSH || KEY_RIGHT == HOLD)
		{
			gPos.x += 4;
		}
		if(KEY_UP == PUSH || KEY_UP == HOLD)
		{
			gPos.y -= 4;
		}
		if(KEY_DOWN == PUSH || KEY_DOWN == HOLD)
		{
			gPos.y += 4;
		}


		//-------------------------------
		//自機の画像が
		//画面から消えないようにする
		//-------------------------------
		if(gPos.x < 0)//画面の左
		{
			gPos.x = 0;
		}
		if(gPos.x >= 585)//画面の右
		{
			gPos.x = 585;
		}
		if(gPos.y < 0)//画面の上
		{
			gPos.y = 0;
		}
		if(gPos.y >= 425)//画面の下
		{
			gPos.y = 425;
		}

		if(KEY_Z == PUSH)
		{
			score += 1;
		}
		if(KEY_X == PUSH)
		{
			score += 2;
		}
		if(KEY_A == PUSH)
		{
			score += 3;
		}

		//--------------------------
		//弾の発射
		//----------------
		if(KEY_SPACE == PUSH)//スペースキーが押されたら
		{
			for (int i = 0; i < BULLET_MAX; i++)
			{
				if(bullets[i].active == 0)
				{
					bullets[i].active = 1;//弾の表示
					//自機の中央に表示させる
					bullets[i].gPos_tm.x = gPos.x + 29;
					bullets[i].gPos_tm.y = gPos.y + 15;

					break;
				}
			}
		}
		
		
		// for文で弾の数だけやる
		for(int i = 0;i < BULLET_MAX; i++)
		{
			switch(bullets[i].type)
			{
			case 0://
				if(bullets[i].active == 1)
				{
					// 弾の座標はbullet構造体の中に入れる
					bullets[i].gPos_tm.y -= 10;//弾の座標を減らす
					if(bullets[i].gPos_tm.y < 0)
					{
						bullets[i].gPos_tm.y = gPos.y;
						bullets[i].active = 0;
					}
				}
				break;
			case 1://
				break;
			}
		}

		//--------------------------
		//敵の当たり判定
		//----------------
		for(int i = 0;i < BULLET_MAX; i++)
		{
			if(bullets[i].gPos_tm.x >= enemy[i].gPos_te.x)
			{
				if(bullets[i].gPos_tm.x <= enemy[i].gPos_te.x + 70)//画像の中心部が初期設定になっているので半分の値を代入
				{
					if(bullets[i].gPos_tm.y >= enemy[i].gPos_te.y)
					{
						if(bullets[i].gPos_tm.y <= enemy[i].gPos_te.y + 35)//画像の中心部が初期設定になっているので半分の値を代入
						{
							if(enemy[i].active_te == 1)
							{
								if(i == 0)
								{
									//弾が当たったら、フラグをOFFにする
									enemy[i].active_te = 0;
									bullets[i].active = 0;
								}
								else if(i != 0)
								{
									break;
								}
							}
						}
					}
				}
			}
		}

		//----------------------------------
		//敵の動き
		//---------------------
		for(int i = 0;i< ENEMY_MAX;i++)
		{
			if(enemy[i].active_te == 1)
			{
				enemy[i].gPos_te.x += 5;
				if(enemy[i].gPos_te.x > 500)
				{
					enemy[i].gPos_te.x -= 5;
				}
			}
		}
		


		//-------------------------
		//マトリクスを作成
		//-------------------------

		// マトリクスもBullet構造体に入れる。
		// for文で弾の数だけまとめてMatrix計算する
		for(int i = 0;i < BULLET_MAX; i++)
		{
			//<matrix用=弾>
			//移動行列を作成
			D3DXMatrixTranslation( &bullets[i].matrix,bullets[i].gPos_tm.x,bullets[i].gPos_tm.y,0);
		}

		//<matrix_ji用=自機>
		//移動行列を作成
		D3DXMatrixTranslation( &matrix_ji,gPos.x,gPos.y,0);

		for(int i = 0;i < ENEMY_MAX; i++)
		{
			//<matrix_te用=敵>
			//移動行列を作成
			D3DXMatrixTranslation( &enemy[i].matrix_te,enemy[i].gPos_te.x,enemy[i].gPos_te.y,0);
		}


		break;
	case 2://
		break;
	case 3://
		break;
	case 4://
		break;
	}


}


//--------------------------------------------------------------------------------------
// Render the scene 
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
    HRESULT hr;

    // Clear the render target and the zbuffer 
    V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 0, 128, 255), 1.0f, 0) );

    // Render the scene
    if( SUCCEEDED( pd3dDevice->BeginScene() ) )
    {
			//ここから描画処理を行う

			//スプライトの開始
			pSprite->Begin(D3DXSPRITE_ALPHABLEND);

		switch(gamemode)
		{
		case 0://
			break;
		case 1://

			//自機
			//テクスチャの表示領域
			RECT	rect_tex;
			SetRect(&rect_tex,0,0,60,60);
			//テクスチャの描画前に行列をセットする
			pSprite->SetTransform(&matrix_ji);
			//スプライトで2D描画
			pSprite->Draw( pTexture,&rect_tex,NULL,NULL,D3DCOLOR_ARGB(255,255,255,255));

			for(int i = 0;i < BULLET_MAX; i++)
			{
				if(bullets[i].active == 1)
				{
					//弾
					//テクスチャの表示領域
					RECT	rect_tex_ta;
					SetRect(&rect_tex_ta,0,0,10,10);
					//テクスチャの描画前に行列にセットする
					pSprite->SetTransform(&bullets[i].matrix);
					//中心をセット
					D3DXVECTOR3 center_ta = D3DXVECTOR3(10.f / 2.f,10.f / 2.f,0.f);
					//スプライトで2D描画=弾
					pSprite->Draw( pText_tama,&rect_tex_ta,&center_ta,NULL,D3DCOLOR_ARGB(255,255,255,255));
				}
			}
			for(int i = 0;i < 10; i++)
			{
				if( enemy[0].active_te == 1)
				{
					//敵
					//テクスチャの表示領域
					RECT	rect_tex_te;
					SetRect(&rect_tex_te,0,0,70,35);
					//テクスチャの描画前に行列にセットする
					pSprite->SetTransform(&enemy[i].matrix_te);
					//スプライトで2D描画=弾
					pSprite->Draw( pText_teki,&rect_tex_te,NULL,NULL,D3DCOLOR_ARGB(255,255,255,255));
				}
				else
				{
				}

			}
			/*////////////////////////////////////
			//得点
			//各桁の表示
			for(int s= 0; s < 7; s++)
			{
				D3DXVECTOR3 ScorePos;
				ScorePos.x = 30.f - (float)s * 32.f;
				ScorePos.y = 20.f;
				ScorePos.z = 0.f;

				pSprite->Draw(pText_sc,&ScoreRect[s],NULL,&ScorePos,D3DCOLOR_ARGB(255,255,164,0));
			}*/



			
			break;
		case 2://
			break;
		case 3://
			break;
		case 4://
			break;
		}

			//スプライトの終了
			pSprite->End();


			//========================================
			//各フォント
			//========================================
		
			//フォント1
			RECT rectf;							//フォント位置を保持する構造体変数
			SetRect ( &rectf,10,10,640,480);		//変数への位置セット
			//フォントの描画
			pFont -> DrawText(NULL,		//標準機能で描画
			_T("仮画像による動き"),			//表示文字列
			-1,								//表示文字数
			&rectf,						//表示位置
			NULL,							//表示スタイル
			D3DCOLOR_ARGB(255,255,255,255));	//表示色
			
			
			//フォント2
			RECT rectfa;							//フォント位置を保持する構造体変数
			SetRect ( &rectfa,10,30,640,480);		//変数への位置セット
			//フォントの描画
			pFont -> DrawText(NULL,		//標準機能で描画
			_T("ゲーム画面で"),			//表示文字列
			-1,								//表示文字数
			&rectfa,						//表示位置
			NULL,							//表示スタイル
			D3DCOLOR_ARGB(255,255,255,0));	//表示色



			//変数内容の表示
			/*TCHAR str[255];
			_stprintf(str,_T("%d"),score);
			RECT rect_ti;
			SetRect(&rect_ti,580,0,640,480);
			pFont->DrawText(NULL,str,-1,&rect_ti,NULL,D3DCOLOR_RGBA(255,255,255,255));*/

        V( pd3dDevice->EndScene() );
    }
}


//--------------------------------------------------------------------------------------
// Handle messages to the application 
//--------------------------------------------------------------------------------------
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, 
                          bool* pbNoFurtherProcessing, void* pUserContext )
{
    return 0;
}


//--------------------------------------------------------------------------------------
// Release resources created in the OnResetDevice callback here 
//--------------------------------------------------------------------------------------
void CALLBACK OnLostDevice( void* pUserContext )
{
}


//--------------------------------------------------------------------------------------
// Release resources created in the OnCreateDevice callback here
//--------------------------------------------------------------------------------------
void CALLBACK OnDestroyDevice( void* pUserContext )
{
	//テクスチャの解放
	SAFE_RELEASE(pTexture);
	SAFE_RELEASE(pText_tama);
	SAFE_RELEASE(pText_teki);
	SAFE_RELEASE(pText_sc);
	//スプライトの解放
	SAFE_RELEASE(pSprite);
	//	フォントの解放
	SAFE_RELEASE( pFont );
	SAFE_RELEASE( pFonta );
	SAFE_RELEASE( pFontb );
}



//--------------------------------------------------------------------------------------
// Initialize everything and go into a render loop
//--------------------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
{
    // Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif

    // Set the callback functions
    DXUTSetCallbackDeviceCreated( OnCreateDevice );
    DXUTSetCallbackDeviceReset( OnResetDevice );
    DXUTSetCallbackDeviceLost( OnLostDevice );
    DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
    DXUTSetCallbackMsgProc( MsgProc );
    DXUTSetCallbackFrameRender( OnFrameRender );
    DXUTSetCallbackFrameMove( OnFrameMove );
   
    // TODO: Perform any application-level initialization here

    // Initialize DXUT and create the desired Win32 window and Direct3D device for the application
    DXUTInit( true, true, true ); // Parse the command line, handle the default hotkeys, and show msgboxes
    DXUTSetCursorSettings( true, true ); // Show the cursor and clip it when in full screen
    DXUTCreateWindow( L"EmptyProject" );
    DXUTCreateDevice( D3DADAPTER_DEFAULT, true, 640, 480);

	//スプライトの作成
	D3DXCreateSprite( DXUTGetD3DDevice(), &pSprite);


	//----------------------------------------------------------------------------
	//テクスチャのロード
	//------------------------------------------------------------------
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\jiki02.png"),&pTexture );//自機(本画像)
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\tama03.png"),&pText_tama);//弾(仮画像)
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\teki001.png"),&pText_teki);//敵(仮画像)
	//D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\kazu01.png"),&pText_sc);//得点(本画像)



	//----------------------------------------------------------
	//フォントの作成  各パターン
	//----------------------------------------------------

	////フォントの作成(Aパターン)
		D3DXCreateFont(
			DXUTGetD3DDevice(),		//direct3Dデバイス
			16,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("ARP浪漫明朝体U"),	//フォント名
			&pFont);					//作成されたフォントが格納される変数

		//フォントの作成(Iパターン)
		D3DXCreateFont(
			DXUTGetD3DDevice(),		//direct3Dデバイス
			30,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("Broadway BT"),	//フォント名
			&pFonta);					//作成されたフォントが格納される変数

		//フォントの作成(Bパターン)
		D3DXCreateFont(
			DXUTGetD3DDevice(),		//direct3Dデバイス
			30,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("HGep037"),	//フォント名
			&pFontb);					//作成されたフォントが格納される変数

	//-----------------------------------------------------------------------
	//1度しか実行しないもの
	//--------------------------------------------------
	
	//--------------------------------
	//弾の構造体に関する処理
	//-------------------------------
	for(i = 0;i < BULLET_MAX;i++)
	{
		bullets[i].gPos_tm.x = 280;
		bullets[i].gPos_tm.y = 430;
		bullets[i].active = 0;
		bullets[i].type = 0;
	}
	//--------------------------------
	//敵の構造体に関する処理
	//-------------------------------
	for(i = 0;i < 10;i++)
	{
		enemy[i].gPos_te.x = 0;
		enemy[i].gPos_te.y = 50;
		enemy[i].active_te = 1;
		enemy[i].type = 0;
	}


	//--------------------------------------------------------------
	//初期化
	//-----------------------------
	bullets[i].gPos_tm = D3DXVECTOR3(280,430,0);
	score = 0;


    // Start the render loop
    DXUTMainLoop();

    // TODO: Perform any application-level cleanup here

    return DXUTGetExitCode();
}

ちょっと敵の当たり判定の弾のことはちょっと置いておいて、
※前回のプログラムの追加された部分

敵を表示させるために構造体を作り、座標やフラグなどもENEMYで管理しました。
しかし、一応今の段階では、敵が1体表示され、左から右に移動します。また、途中で止まり、弾が敵と当たったら消える。

これをふまえて、敵をシューティングゲームで敵がランダム(出来たら)に出現して敵が弾(画像で敵専用の弾を作りました。画像名:tama04.png)を打ってくる処理を加えようと思うのですが。

まずは、おかしな点から指摘をお願いしますm(__)m

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#25

投稿記事 by softya(ソフト屋) » 14年前

とりあえず。こちらで動かしてみたいのでヘッダとかも添付してもらえると答えやすくなります。
画像は適当に代用します。
これをふまえて、敵をシューティングゲームで敵がランダム(出来たら)に出現して敵が弾(画像で敵専用の弾を作りました。画像名:tama04.png)を打ってくる処理を加えようと思うのですが。
敵のランダム出現は狙ってならOKですが、一般的なシューティングはデータとして出現パターンや移動パターンを持っていますがよろしいですか?
それと敵の弾の配列も必要だと思います。
もうひとつは関数が少なすぎですね。後々ソースコードが長くなり、こんがらかって来るのと当たり判定など共通化出来るものは関数化を考えてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

STAR_HARUKI
記事: 36
登録日時: 14年前
住所: 新潟県新潟市
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#26

投稿記事 by STAR_HARUKI » 14年前

添付

3つですべてです。
添付ファイル
keycheck.h
(783 バイト) ダウンロード数: 161 回
EmptyProject.cpp
(18.16 KiB) ダウンロード数: 156 回
keycheck.cpp
(7.66 KiB) ダウンロード数: 159 回

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#27

投稿記事 by softya(ソフト屋) » 14年前

ソースコードを受け取りました。
DXUTフレームワークは始めて使うので環境を準備しますね。
敵のランダム出現は狙ってならOKですが、一般的なシューティングはデータとして出現パターンや移動パターンを持っていますがよろしいですか?
それと敵の弾の配列も必要だと思います。
もうひとつは関数が少なすぎですね。後々ソースコードが長くなり、こんがらかって来るのと当たり判定など共通化出来るものは関数化を考えてください。
これに付いては問題ないのでしょうか?
実際に作業するのはSTAR_HARUKI さんですので、何もリアクションがないとこちらも動けないです。

【追記】
DXUTのバージョンが合わないので、うまくコンパイル出来ません。
ご利用中のDirectX SDKのバージョンや日付を教えてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

STAR_HARUKI
記事: 36
登録日時: 14年前
住所: 新潟県新潟市
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#28

投稿記事 by STAR_HARUKI » 14年前

Microsoft Visual Studio 2005
Version 8.0.50727.867 (vsvista.050727-8600)
Microsoft .NET Framework
Version 2.0.50727 SP2

インストールされている Edition: Professional

Microsoft Visual Basic 2005 77971-009-0000007-41109
Microsoft Visual Basic 2005

Microsoft Visual C# 2005 77971-009-0000007-41109
Microsoft Visual C# 2005

Microsoft Visual C++ 2005 77971-009-0000007-41109
Microsoft Visual C++ 2005

Microsoft Visual J# 2005 77971-009-0000007-41109
Microsoft Visual J# 2005

Microsoft Visual Web Developer 2005 77971-009-0000007-41109
Microsoft Visual Web Developer 2005

Microsoft Web Application Projects 2005 77971-009-0000007-41109
Microsoft Web Application Projects 2005
バージョン 8.0.50727.867

Crystal Reports AAC6G-J0CSA4B-U7000AN
Crystal Reports for Visual Studio 2005


―――――――――――――――
Microsoft DirectX SDK (April 2007)
を使っています。


【追記】
関数化という部分が分からないので、どうすればいいのか分かりません。
また、出現パターンや移動パターンは別なcppとhファイルを使って、メインのcppにインクルードして行動別にプログラムを分けていくということなのでしょうか?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#29

投稿記事 by softya(ソフト屋) » 14年前

関数化という部分が分からないので、どうすればいいのか分かりません。
また、出現パターンや移動パターンは別なcppとhファイルを使って、メインのcppにインクルードして行動別にプログラムを分けていくということなのでしょうか?
後々同じような処理をまとめないとOnFrameMove()に処理が多くなりすぎますので、関数を作る勉強は並行で行って下さいね。
無駄に同じ様な処理を書くとバグの原因にもなります。
出来ないというのであれば、今やれる範囲の知識で出来ることをしてください。

>また、出現パターンや移動パターンは別なcppとhファイルを使って、メインのcppにインクルードして行動別にプログラムを分けていくということなのでしょうか?
それが出来るなら関数化も出来るはずね。
ちなみに、こうしなければいけないという決まりはありません。
構造体配列で出現タイミングや行動パターンを定義することは難しくないはずです。

ただ、その前に複数の敵のコントロールや敵が弾を打つ処理を作らなければいけません。
私の感覚からすれば、もう4月28日まで時間がありませんので今出来る事を急いでやり始めてください。
間に合わない場合には私には責任を取れませんので、私の回答を待つのではなくSTAR_HARUKI さんがやれること急いでやるべきだと思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

STAR_HARUKI
記事: 36
登録日時: 14年前
住所: 新潟県新潟市
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#30

投稿記事 by STAR_HARUKI » 14年前

そうですね。分かりました。
出来るところからしていきます。


出現パターンや移動パターンを持っていますがよろしいですか?
ってどういう意味ですか?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#31

投稿記事 by softya(ソフト屋) » 14年前

>出現パターンや移動パターンを持っていますがよろしいですか?
>ってどういう意味ですか?

多くのシューティングゲームは敵の出現タイミング、出現パターンや移動パターンなどを固定で持っています。これはバランス調整のためでもあります。
これらをランダムにするとデバッグが困難、バランス調整が困難になる可能性が高いです。
それでもやりますか?って意味でお聞きしました。

[追記]
DierctXの2007AprilのDXUTの導入は失敗しました。
私がWin7であるとか色々理由はあると思いますが、こちらも余り時間が掛けれないので動かせないままでサポートさせていただきます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

STAR_HARUKI
記事: 36
登録日時: 14年前
住所: 新潟県新潟市
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#32

投稿記事 by STAR_HARUKI » 14年前

※上のコメント削除しました。


【追記】
ランダムは危険性が大きいってことなんですね。分かりました。

パターンを作るほうで、よろしくお願いしますm(__)m。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#33

投稿記事 by softya(ソフト屋) » 14年前

STAR_HARUKI さんが書きました:※上のコメント削除しました。


【追記】
ランダムは危険性が大きいってことなんですね。分かりました。

パターンを作るほうで、よろしくお願いしますm(__)m。
STAR_HARUKIさんが進めるところを進めて、疑問に思ってことを聞いてくださいね。
こちらはあくまでお手伝いですので、STAR_HARUKIさんが動かないと何も進みません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

STAR_HARUKI
記事: 36
登録日時: 14年前
住所: 新潟県新潟市
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#34

投稿記事 by STAR_HARUKI » 14年前

敵の出現パターンを作る場合、
普通のEmptyProject.cpp
で作ったほうがいいのでしょうか?
それとも別に
出現パターンを新たにcppを作って管理したほうがいいのでしょうか?

またパターンを作る場合、プログラムの基礎はどのようにしたらいいですか?
if分とかfor分で作れますか?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#35

投稿記事 by softya(ソフト屋) » 14年前

STAR_HARUKI さんが書きました:敵の出現パターンを作る場合、
普通のEmptyProject.cpp
で作ったほうがいいのでしょうか?
それとも別に
出現パターンを新たにcppを作って管理したほうがいいのでしょうか?
ファイル分割や関数化の作業が自分で出来るそうしたほうが良いですが、期間内にそこまで勉強できないと感じるならEmptyProject.cpp内に作成してください。
STAR_HARUKI さんが書きました: またパターンを作る場合、プログラムの基礎はどのようにしたらいいですか?
if分とかfor分で作れますか?
出現パターンは構造体配列で良いと思います。出現パターンの値は宣言時の初期値で宜しいかと。
それよりも既にこの話を初めて1週間以上経過してあと2週間を切っていますので、このままのペースでは到底間に合いませんので出来るだけ先生や同級生にも聞くようにしてください。
それが無理なら、家でもは何処でも一日に何度もやり取りしないと進みませんが、私や他の皆さんも何処まで付き合えるか分かりません。
やはり、ネットでのやりとりは情報面で無理がありますからね。出来ることできないことを考えて全力で進めることをお勧めします。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

STAR_HARUKI
記事: 36
登録日時: 14年前
住所: 新潟県新潟市
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#36

投稿記事 by STAR_HARUKI » 14年前

コード:

//--------------------------------------------------------------------------------------
// File: EmptyProject.cpp
//
// Empty starting point for new Direct3D applications
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
//古い文字列操作関数に対する警告を回避する
#pragma warning (disable : 4995)
#pragma warning (disable : 4996)

#include <stdio.h>
#include <tchar.h>

#include "dxstdafx.h"
#include "resource.h"

//-------------------------------
//プロトタイプ宣言
//-------------------------------

//-------------------------------
//その他のインクルード
//-------------------------------
#include "keycheck.h"


//-------------------------------
//その他のディファイン
//最大値とかを指定させる
//-------------------------------
/*自機用*/
#define MYSHIP 1			//自機の最大数
#define MYSHIP_SPEED 4		//自機用の移動速度
/*自機用の弾*/
#define BULLET_SPEED 10		//自機用弾の移動速度
#define BULLET_MAX 10		//弾の最大数
/*敵用*/
#define ENEMY_MAX 10		//敵の最大数
#define ENEMY_SPEED 3		//敵の動く最大速度
/*敵用の弾*/
#define ENEMY_BLT_MAX 10	//敵の弾の最大数
#define ENEMY_BLT_SPEED 8	//敵用弾の移動速度


	//-------------------------------------------------------------------------------
	//関数
	//-------------------------------
	int gamemode = 1;//ゲームモード管理変数『0:タイトル 1:ゲーム画面 2:ゲームクリア 3:ゲームオーバー』
	int times = 60,ti = 0,te = 0,ts = 0;//制限時間管理用変数
	int count;//弾の発射数
	int i;
	int score;//得点
	//int active_ji = 1;//自機用フラグ

	//-------------------------------------------------------------------------------
	//テクスチャ関数
	//-------------------------------
	LPDIRECT3DTEXTURE9		pTexture;//自機用
	LPDIRECT3DTEXTURE9		pText_tama;//自弾用
	LPDIRECT3DTEXTURE9		pText_teki;//敵用
	LPDIRECT3DTEXTURE9		pText_sc;//得点用
	LPDIRECT3DTEXTURE9		pText_teta;//敵弾用
	LPDIRECT3DTEXTURE9		pText_icon;//アイテム用
	LPDIRECT3DTEXTURE9		pText_back;//背景用


	//スプライトの作成
	LPD3DXSPRITE			pSprite;

	//-------------------------------------------------------------------------------
	//座標関数
	//-------------------------------
	D3DXVECTOR3				gPos_map = D3DXVECTOR3(0,0,0);//背景画像用の画像指定位置
	

	//-------------------------------------------------------
	//マトリクス
	//-------------------------
	
	D3DXMATRIX	matrix_ji;//自機
	D3DXMATRIX	matrix_back;//背景


	//------------------------------
	//自機の構造体
	//------------------
	typedef struct _myship
	{
		D3DXVECTOR3		gPos;//敵用の画像指定位置
		int				active;//有効フラグ 0:OFF 1:ON
		D3DXMATRIX		matrix;//行列
	};

	_myship myship[MYSHIP];//弾構造体の宣言

	//------------------------------
	//弾の構造体
	//------------------
	typedef struct _bullet
	{
		D3DXVECTOR3		gPos_tm;//自機弾用の画像指定位置
		int				active;//有効フラグ 0:OFF 1:ON
		int				type;//弾の種類
		D3DXMATRIX		matrix;//行列
	};

	_bullet bullets[BULLET_MAX];//弾構造体の宣言

	//-------------------------------------
	//敵の構造体
	//--------------------------
	typedef struct _enemy
	{
		D3DXVECTOR3		gPos_te;//敵の座標
		int				active_te;//有効フラグ 0:OFF 1:ON
		int				type;//敵の種類
		D3DXMATRIX		matrix_te;//敵の行列
	};

	_enemy enemy[ENEMY_MAX];//敵構造体の宣言

	//------------------------------
	//敵の弾の構造体
	//------------------
	typedef struct _enemy_blt
	{
		D3DXVECTOR3		gPos;//敵用の画像指定位置
		int				active;//有効フラグ 0:OFF 1:ON
		int				type;//弾の種類
		D3DXMATRIX		matrix;//行列
	};

	_enemy_blt enemy_blt[ENEMY_BLT_MAX];//弾構造体の宣言



	//--------------------------------------------------------------------------------
	//フォント作成 変数宣言
	//--------------------------------
	LPD3DXFONT				pFont;//フォント0タイプ=《ARP浪漫明朝体U》主に、[文字表示]など
	LPD3DXFONT				pFonta;//フォントAタイプ=《Broadway BT》主に、[制限時間]など
	LPD3DXFONT				pFontb;//フォントBタイプ=《HGep037》主に、[ステータス表示]など
	LPD3DXFONT				pFontc;//フォントCタイプ=《Nife Fiter》主に、[]など
	LPD3DXFONT				pFontd;//フォントDタイプ=《BackSeatAlphabetWidth》主に、[スコア(得点)]など
	LPD3DXFONT				pFonte;//フォントEタイプ=《D3 Cosmism》主に、[時間]など




//--------------------------------------------------------------------------------------
// Create any D3DPOOL_MANAGED resources here 
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{
    return S_OK;
}


//--------------------------------------------------------------------------------------
// Create any D3DPOOL_DEFAULT resources here 
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, 
                                const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{
    return S_OK;
}


//--------------------------------------------------------------------------------------
// Handle updates to the scene
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
	//	キー状態を調べる関数	
	keycheck( );

	switch(gamemode)
	{
	case 0://
		break;
	case 1://

		//-------------------------------------------------------------------
		//自機を移動させる処理 (押された時、押しっぱなしになった時)
		//-------------------------------------------------------------------
		if(KEY_LEFT == PUSH || KEY_LEFT == HOLD)
		{
			myship[0].gPos.x -= MYSHIP_SPEED;
		}
		if(KEY_RIGHT == PUSH || KEY_RIGHT == HOLD)
		{
			myship[0].gPos.x += MYSHIP_SPEED;
		}
		if(KEY_UP == PUSH || KEY_UP == HOLD)
		{
			myship[0].gPos.y -= MYSHIP_SPEED;
		}
		if(KEY_DOWN == PUSH || KEY_DOWN == HOLD)
		{
			myship[0].gPos.y += MYSHIP_SPEED;
		}


		//-------------------------------
		//自機の画像が
		//画面から消えないようにする
		//-------------------------------
		if(myship[0].gPos.x < 0)//画面の左
		{
			myship[0].gPos.x = 0;
		}
		if(myship[0].gPos.x >= 585)//画面の右
		{
			myship[0].gPos.x = 585;
		}
		if(myship[0].gPos.y < 0)//画面の上
		{
			myship[0].gPos.y = 0;
		}
		if(myship[0].gPos.y >= 425)//画面の下
		{
			myship[0].gPos.y = 425;
		}




		//--------------------------
		//弾の発射
		//----------------
		if(KEY_SPACE == PUSH)//スペースキーが押されたら
		{
			for (int i = 0; i < BULLET_MAX; i++)
			{
				if(bullets[i].active == 0)
				{
					bullets[i].active = 1;//弾の表示
					//自機の中央に表示させる
					bullets[i].gPos_tm.x = myship[0].gPos.x + 29;
					bullets[i].gPos_tm.y = myship[0].gPos.y + 15;
					break;//処理を抜け出す
				}
			}
		}



		// for文で弾の数だけやる
		for(int i = 0;i < BULLET_MAX; i++)
		{
			switch(bullets[i].type)
			{
			case 0://
				if(bullets[i].active == 1)
				{
					// 弾の座標はbullet構造体の中に入れる
					bullets[i].gPos_tm.y -= BULLET_SPEED;//弾の座標を減らす
					if(bullets[i].gPos_tm.y < 0)
					{
						bullets[i].gPos_tm.y = myship[i].gPos.y;
						bullets[i].active = 0;
					}
				}
				break;
			case 1://
				break;
			}
		}

	//--------------------------
	//自機用の弾と敵の当たり判定
	//----------------
		for(int i = 0;i < BULLET_MAX; i++)
		{
			if(bullets[i].gPos_tm.x >= enemy[i].gPos_te.x)
			{
				if(bullets[i].gPos_tm.x <= enemy[i].gPos_te.x + 70)//画像の中心部が初期設定になっているので半分の値を代入
				{
					if(bullets[i].gPos_tm.y >= enemy[i].gPos_te.y)
					{
						if(bullets[i].gPos_tm.y <= enemy[i].gPos_te.y + 35)//画像の中心部が初期設定になっているので半分の値を代入
						{
							if(enemy[i].active_te == 1)
							{
									//弾が当たったら、フラグをOFFにする
									enemy[i].active_te = 0;
									bullets[i].active = 0;
									enemy_blt[i].active = 0;
									score += 100;//敵を倒すことが出来たら得点UP!
							}
						}
					}
				}
			}
		}

	//----------------------------------
	//敵の動き
	//---------------------

			for(int i = 0;i< ENEMY_MAX;i++)
			{
				if(enemy[i].active_te == 1)
				{
					enemy[i].gPos_te.x += ENEMY_SPEED;
					if(enemy[i].active_te == 0)
					{
						//break;
					}
				}
				break;
			}
		

	//--------------------------
	//敵用弾の発射
	//----------------

		for (int i = 0; i < ENEMY_BLT_MAX; i++)
		{
			if(enemy_blt[i].active == 0)
			{
				enemy_blt[i].active = 1;//弾の表示
				//自機の中央に表示させる
				enemy_blt[i].gPos.x = enemy[i].gPos_te.x + 30;
				enemy_blt[i].gPos.y = enemy[i].gPos_te.y + 20;

				//敵が自機用の弾に当たって倒されたら
				//これ以上敵用の弾が出ないようにする。
				if(enemy[i].active_te == 0)
				{
					enemy_blt[i].active = 0;
				}
			}
		}
		
		
		// for文で弾の数だけやる
		for(int i = 0;i < ENEMY_BLT_MAX; i++)
		{
			switch(enemy_blt[i].type)
			{
			case 0://
				if(enemy_blt[i].active == 1)
				{
					// 弾の座標はbullet構造体の中に入れる
					enemy_blt[i].gPos.y += ENEMY_BLT_SPEED;//弾の座標を増やす
					if(enemy_blt[i].gPos.y > 640)
					{
						enemy_blt[i].gPos.y = enemy[i].gPos_te.y;
						enemy_blt[i].active = 0;
					}
				}
				break;
			case 1://
				break;
			}
		}


	//--------------------------
	//自機用の弾と敵の当たり判定
	//----------------
		for(int i = 0;i < ENEMY_BLT_MAX;i++)
		{
			if(enemy_blt[i].gPos.x > bullets[i].gPos_tm.x + 5)
			{
				if(enemy_blt[i].gPos.x < bullets[i].gPos_tm.x + 55)
				{
					if(enemy_blt[i].gPos.y > bullets[i].gPos_tm.y + 15)
					{
						if(enemy_blt[i].gPos.y < bullets[i].gPos_tm.y + 50)
						{
							if(myship[i].active == 1)//自機に当たったら、敵用の弾と自機を消す
							{
								myship[i].active = 0;
								enemy_blt[i].active = 0;
							}
						}
					}
				}
			}
		}


		


	//-------------------------
	//マトリクスを作成
	//-------------------------

		// for文で弾の数だけまとめてMatrix計算する
		for(int i = 0;i < BULLET_MAX; i++)
		{	
			//<matrix用=弾>
			//移動行列を作成
			D3DXMatrixTranslation( &bullets[i].matrix,bullets[i].gPos_tm.x,bullets[i].gPos_tm.y,0);
		}

		for(int i = 0;i < MYSHIP;i++)
		{
			//<matrix_ji用=自機>
			//移動行列を作成
			D3DXMatrixTranslation( &myship[i].matrix,myship[i].gPos.x,myship[i].gPos.y,0);
		}

		for(int i = 0;i < ENEMY_MAX; i++)
		{
			//<matrix_te用=敵>
			//移動行列を作成
			D3DXMatrixTranslation( &enemy[i].matrix_te,enemy[i].gPos_te.x,enemy[i].gPos_te.y,0);
		}

		//敵の弾を敵弾の数だけ
		for(int i = 0;i < ENEMY_BLT_MAX; i++)
		{
			//<matrix_te用=敵>
			//移動行列を作成
			D3DXMatrixTranslation( &enemy_blt[i].matrix,enemy_blt[i].gPos.x,enemy_blt[i].gPos.y,0);
		}


		//<matrix_te用=敵>
		//移動行列を作成
		D3DXMatrixTranslation( &matrix_back,0,0,0);

		break;
	case 2://
		break;
	case 3://
		break;
	case 4://
		break;
	}


}


//--------------------------------------------------------------------------------------
// Render the scene 
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
    HRESULT hr;

    // Clear the render target and the zbuffer 
    V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 0, 128, 255), 1.0f, 0) );

    // Render the scene
    if( SUCCEEDED( pd3dDevice->BeginScene() ) )
    {
			//ここから描画処理を行う

			//スプライトの開始
			pSprite->Begin(D3DXSPRITE_ALPHABLEND);

		switch(gamemode)
		{
		case 0://
			break;
		case 1://

			//背景画像
			//テクスチャの表示領域
			RECT	rect_back;
			SetRect(&rect_back,0,0,640,480);
			//テクスチャの描画前に行列をセットする
			pSprite->SetTransform(&matrix_back);
			//スプライトで2D描画=背景
			pSprite->Draw( pText_back,&rect_back,NULL,&gPos_map,D3DCOLOR_ARGB(255,255,255,255));


			for(int i = 0;i < MYSHIP;i++)
			{
				if(myship[i].active == 1)
				{
					//自機
					//テクスチャの表示領域
					RECT	rect_tex;
					SetRect(&rect_tex,0,0,60,60);
					//テクスチャの描画前に行列をセットする
					pSprite->SetTransform(&myship[i].matrix);
					//スプライトで2D描画=自機
					pSprite->Draw( pTexture,&rect_tex,NULL,NULL,D3DCOLOR_ARGB(255,255,255,255));
				}
			}
			for(int i = 0;i < BULLET_MAX; i++)
			{
				if(bullets[i].active == 1)
				{
					//弾
					//テクスチャの表示領域
					RECT	rect_tex_ta;
					SetRect(&rect_tex_ta,0,0,10,10);
					//テクスチャの描画前に行列にセットする
					pSprite->SetTransform(&bullets[i].matrix);
					//中心をセット
					D3DXVECTOR3 center_ta = D3DXVECTOR3(10.f / 2.f,10.f / 2.f,0.f);
					//スプライトで2D描画=弾
					pSprite->Draw( pText_tama,&rect_tex_ta,&center_ta,NULL,D3DCOLOR_ARGB(255,255,255,255));
				}
			}
			for(int i = 0;i < 10; i++)
			{
				if( enemy[i].active_te == 1)
				{
					//敵
					//テクスチャの表示領域
					RECT	rect_tex_te;
					SetRect(&rect_tex_te,0,0,70,35);
					//テクスチャの描画前に行列にセットする
					pSprite->SetTransform(&enemy[i].matrix_te);
					//スプライトで2D描画=敵
					pSprite->Draw( pText_teki,&rect_tex_te,NULL,NULL,D3DCOLOR_ARGB(255,255,255,255));
				}
				else
				{
					//何も記入しない
				}
			}
			for(int i = 0;i < 10; i++)
			{
				if( enemy_blt[i].active == 1)
				{
					//敵
					//テクスチャの表示領域
					RECT	rect_tex_teta;
					SetRect(&rect_tex_teta,0,0,12,12);
					//テクスチャの描画前に行列にセットする
					pSprite->SetTransform(&enemy_blt[i].matrix);
					//スプライトで2D描画=敵の弾
					pSprite->Draw( pText_teta,&rect_tex_teta,NULL,NULL,D3DCOLOR_ARGB(255,255,255,255));
				}
				else
				{
					//何も記入しない
				}
			}
			
			break;
		case 2://
			break;
		case 3://
			break;
		case 4://
			break;
		}

			//スプライトの終了
			pSprite->End();


		//========================================
		//各フォント
		//========================================
		
			//フォント1
			RECT rectf;							//フォント位置を保持する構造体変数
			SetRect ( &rectf,10,10,640,480);	//変数への位置セット
			//フォントの描画
			pFont -> DrawText(NULL,			//標準機能で描画
			_T(""),							//表示文字列
			-1,								//表示文字数
			&rectf,							//表示位置
			NULL,							//表示スタイル
			D3DCOLOR_ARGB(255,255,255,255));//表示色
			
			
			//フォント2
			RECT rectfa;						//フォント位置を保持する構造体変数
			SetRect ( &rectfa,10,30,640,480);	//変数への位置セット
			//フォントの描画
			pFontd -> DrawText(NULL,		//標準機能で描画
			_T(""),							//表示文字列
			-1,								//表示文字数
			&rectfa,						//表示位置
			NULL,							//表示スタイル
			D3DCOLOR_ARGB(255,0,255,0));	//表示色

			//フォント3
			RECT rectfc;						//フォント位置を保持する構造体変数
			SetRect ( &rectfc,380,0,640,480);	//変数への位置セット
			//フォントの描画
			pFontb -> DrawText(NULL,		//標準機能で描画
			_T("SCORE"),					//表示文字列
			-1,								//表示文字数
			&rectfc,						//表示位置
			NULL,							//表示スタイル
			D3DCOLOR_ARGB(255,0,255,255));	//表示色*/


			//変数内容の表示
			TCHAR str[255];
			_stprintf(str,_T("%07d"),score);
			RECT rect_ti;
			SetRect(&rect_ti,470,0,640,480);
			pFontd->DrawText(NULL,str,-1,&rect_ti,NULL,D3DCOLOR_RGBA(255,255,255,255));


        V( pd3dDevice->EndScene() );
    }
}


//--------------------------------------------------------------------------------------
// Handle messages to the application 
//--------------------------------------------------------------------------------------
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, 
                          bool* pbNoFurtherProcessing, void* pUserContext )
{
    return 0;
}


//--------------------------------------------------------------------------------------
// Release resources created in the OnResetDevice callback here 
//--------------------------------------------------------------------------------------
void CALLBACK OnLostDevice( void* pUserContext )
{
}


//--------------------------------------------------------------------------------------
// Release resources created in the OnCreateDevice callback here
//--------------------------------------------------------------------------------------
void CALLBACK OnDestroyDevice( void* pUserContext )
{
	//テクスチャの解放
	SAFE_RELEASE(pTexture);
	SAFE_RELEASE(pText_tama);
	SAFE_RELEASE(pText_teki);
	SAFE_RELEASE(pText_sc);
	SAFE_RELEASE(pText_teta);
	SAFE_RELEASE(pText_back);
	//スプライトの解放
	SAFE_RELEASE(pSprite);
	//	フォントの解放
	SAFE_RELEASE( pFont );
	SAFE_RELEASE( pFonta );
	SAFE_RELEASE( pFontb );
	SAFE_RELEASE( pFontc );
	SAFE_RELEASE( pFontd );
	SAFE_RELEASE( pFonte );
}



//--------------------------------------------------------------------------------------
// Initialize everything and go into a render loop
//--------------------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
{
    // Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif

    // Set the callback functions
    DXUTSetCallbackDeviceCreated( OnCreateDevice );
    DXUTSetCallbackDeviceReset( OnResetDevice );
    DXUTSetCallbackDeviceLost( OnLostDevice );
    DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
    DXUTSetCallbackMsgProc( MsgProc );
    DXUTSetCallbackFrameRender( OnFrameRender );
    DXUTSetCallbackFrameMove( OnFrameMove );
   
    // TODO: Perform any application-level initialization here

    // Initialize DXUT and create the desired Win32 window and Direct3D device for the application
    DXUTInit( true, true, true ); // Parse the command line, handle the default hotkeys, and show msgboxes
    DXUTSetCursorSettings( true, true ); // Show the cursor and clip it when in full screen
    DXUTCreateWindow( L"EmptyProject" );
    DXUTCreateDevice( D3DADAPTER_DEFAULT, true, 640, 480);

	//スプライトの作成
	D3DXCreateSprite( DXUTGetD3DDevice(), &pSprite);


	//----------------------------------------------------------------------------
	//テクスチャのロード
	//------------------------------------------------------------------
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\jiki02.png"),&pTexture );//自機(画像)
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\tama03.png"),&pText_tama);//自機用の弾(画像)
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\teki001.png"),&pText_teki);//敵(画像)
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\tama04.png"),&pText_teta);//敵用の弾(画像)
	//D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\"),&pText_icon);//宝箱(画像)
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\back.png"),&pText_back);//背景(画像)



	//----------------------------------------------------------
	//フォントの作成  各パターン
	//----------------------------------------------------

	////フォントの作成0パターン)
		D3DXCreateFont(
			DXUTGetD3DDevice(),			//direct3Dデバイス
			16,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("ARP浪漫明朝体U"),	//フォント名
			&pFont);					//作成されたフォントが格納される変数

		//フォントの作成(Aパターン)
		D3DXCreateFont(
			DXUTGetD3DDevice(),			//direct3Dデバイス
			30,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("Broadway BT"),			//フォント名
			&pFonta);					//作成されたフォントが格納される変数

		//フォントの作成(Bパターン)
		D3DXCreateFont(	
			DXUTGetD3DDevice(),			//direct3Dデバイス
			23,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("HGep022"),				//フォント名
			&pFontb);					//作成されたフォントが格納される変数

		//フォントの作成(Cパターン)
		D3DXCreateFont(
			DXUTGetD3DDevice(),			//direct3Dデバイス	
			30,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("Nife Fiter"),			//フォント名
			&pFontc);					//作成されたフォントが格納される変数

		//フォントの作成(Dパターン)
		D3DXCreateFont(
			DXUTGetD3DDevice(),			//direct3Dデバイス
			30,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("BackSeatAlphabetWidth"),//フォント名
			&pFontd);					//作成されたフォントが格納される変数


		//フォントの作成(Eパターン)
		D3DXCreateFont(
			DXUTGetD3DDevice(),			//direct3Dデバイス
			30,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("D3 Cosmism"),			//フォント名
			&pFonte);					//作成されたフォントが格納される変数

		//次のフォント

	//-----------------------------------------------------------------------
	//1度しか実行しないもの
	//--------------------------------------------------

	//--------------------------------
	//自機の構造体に関する処理
	//-------------------------------
	for(i = 0;i < 1;i++)
	{
		myship[i].gPos.x = 280;
		myship[i].gPos.y = 420;
		myship[i].active = 1;
	}
	//--------------------------------
	//弾の構造体に関する処理
	//-------------------------------
	for(i = 0;i < BULLET_MAX;i++)
	{
		bullets[i].gPos_tm.x = 280;
		bullets[i].gPos_tm.y = 430;
		bullets[i].active = 0;
		bullets[i].type = 0;
	}
	//--------------------------------
	//敵の構造体に関する処理
	//-------------------------------
	for(i = 0;i < ENEMY_MAX;i++)
	{
		enemy[i].gPos_te.x = -100;
		enemy[i].gPos_te.y = 50;
		enemy[i].active_te = 1;
		enemy[i].type = 0;
	}
	//--------------------------------
	//敵の弾に関する処理
	//-------------------------------
	for(i = 0;i < ENEMY_BLT_MAX;i++)
	{
		enemy_blt[i].gPos.x = 280;
		enemy_blt[i].gPos.y = 430;
		enemy_blt[i].active = 0;
		enemy_blt[i].type = 0;
	}


	//--------------------------------------------------------------
	//初期化
	//-----------------------------
	bullets[i].gPos_tm = D3DXVECTOR3(280,430,0);
	score = 0;


    // Start the render loop
    DXUTMainLoop();

    // TODO: Perform any application-level cleanup here

    return DXUTGetExitCode();
}
敵の動きで1番目は出て、移動し、弾が当たったら消えるのですが、
その消えた後、2番目が出て来ないのですが、原因が分かりません。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#37

投稿記事 by softya(ソフト屋) » 14年前

ざっと見たところ問題点が幾つかあります。
・敵の発生座標が全て同じで、同じタイミングで発生。
・敵が画面外に退場したときの処理が書いていない。
・自機用の弾と敵の当たり判定で、全ての敵と全ての自機用の弾の当たり判定が行われていない。forはBULLET_MAX分とENEMY_MAX分の2重ループになるはず。
bulletsとenemyをiで同列に扱ってはいけません。
・自機用の弾と敵の当たり判定で、自機用の弾の生存判定が行われていない。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

STAR_HARUKI
記事: 36
登録日時: 14年前
住所: 新潟県新潟市
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#38

投稿記事 by STAR_HARUKI » 14年前

コード:

//--------------------------------------------------------------------------------------
// File: EmptyProject.cpp
//
// Empty starting point for new Direct3D applications
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
//古い文字列操作関数に対する警告を回避する
#pragma warning (disable : 4995)
#pragma warning (disable : 4996)

#include <stdio.h>
#include <tchar.h>

#include "dxstdafx.h"
#include "resource.h"

//---------------------------------------------
//プロトタイプ宣言
//-------------------------------

//---------------------------------------------
//その他のインクルード
//-------------------------------
#include "keycheck.h"


//---------------------------------------------
//その他のディファイン
//最大値とかを指定させる
//-------------------------------
/*自機用*/
#define MYSHIP 1			//自機の最大数
#define MYSHIP_SPEED 4		//自機用の移動速度
/*自機用の弾*/
#define BULLET_SPEED 11		//自機用弾の移動速度
#define BULLET_MAX 10		//弾の最大数
/*敵用*/
#define ENEMY_MAX 10		//敵の最大数
#define ENEMY_SPEED 3		//敵の動く最大速度
/*敵用の弾*/
#define ENEMY_BLT_MAX 10	//敵の弾の最大数
#define ENEMY_BLT_SPEED 12	//敵用弾の移動速度


	//--------------------------------------------------------------------------------------
	//関数
	//-------------------------------
	int gamemode = 1;//ゲームモード管理変数『0:タイトル 1:ゲーム画面 2:ゲームクリア 3:ゲームオーバー』
	int times = 60,ti = 0,te = 0,ts = 0;//制限時間管理用変数
	int count;//弾の発射数
	int i;
	int score;//得点
	//int active_ji = 1;//自機用フラグ

	//--------------------------------------------------------------------------------------
	//テクスチャ関数
	//-------------------------------
	LPDIRECT3DTEXTURE9		pTexture;//自機用
	LPDIRECT3DTEXTURE9		pText_tama;//自弾用
	LPDIRECT3DTEXTURE9		pText_teki;//敵用
	LPDIRECT3DTEXTURE9		pText_teta;//敵弾用
	LPDIRECT3DTEXTURE9		pText_icon;//アイテム用
	LPDIRECT3DTEXTURE9		pText_back;//背景用


	//スプライトの作成
	LPD3DXSPRITE			pSprite;

	//--------------------------------------------------------------------------------------
	//座標関数
	//-------------------------------
	D3DXVECTOR3				gPos_map = D3DXVECTOR3(0,0,0);//背景画像用の画像指定位置
	

	//--------------------------------------------------------------------------------------
	//マトリクス
	//-------------------------
	
	D3DXMATRIX	matrix_ji;//自機
	D3DXMATRIX	matrix_back;//背景


	//---------------------------------------------
	//自機の構造体 ※基本「0」で!
	//---------------------------------
	typedef struct _myship
	{
		D3DXVECTOR3		gPos;//敵用の画像指定位置
		int				active;//有効フラグ 0:OFF 1:ON
		D3DXMATRIX		matrix;//行列
	};

	_myship myship[MYSHIP];//弾構造体の宣言

	//---------------------------------------------
	//弾の構造体
	//------------------
	typedef struct _bullet
	{
		D3DXVECTOR3		gPos_tm;//自機弾用の画像指定位置
		int				active;//有効フラグ 0:OFF 1:ON
		int				type;//弾の種類
		D3DXMATRIX		matrix;//行列
	};

	_bullet bullets[BULLET_MAX];//弾構造体の宣言

	//---------------------------------------------
	//敵の構造体
	//--------------------------
	typedef struct _enemy
	{
		D3DXVECTOR3		gPos_te;//敵の座標
		int				active_te;//有効フラグ 0:OFF 1:ON
		int				type;//敵の種類
		D3DXMATRIX		matrix_te;//敵の行列
	};

	_enemy enemy[ENEMY_MAX];//敵構造体の宣言

	//---------------------------------------------
	//敵の弾の構造体
	//------------------
	typedef struct _enemy_blt
	{
		D3DXVECTOR3		gPos;//敵用の画像指定位置
		int				active;//有効フラグ 0:OFF 1:ON
		int				type;//弾の種類
		D3DXMATRIX		matrix;//行列
	};

	_enemy_blt enemy_blt[ENEMY_BLT_MAX];//弾構造体の宣言



	//--------------------------------------------------------------------------------------
	//フォント作成 変数宣言
	//--------------------------------
	LPD3DXFONT				pFont;//フォント0タイプ=《ARP浪漫明朝体U》主に、[文字表示]など
	LPD3DXFONT				pFonta;//フォントAタイプ=《Broadway BT》主に、[制限時間]など
	LPD3DXFONT				pFontb;//フォントBタイプ=《HGep037》主に、[ステータス表示]など
	LPD3DXFONT				pFontc;//フォントCタイプ=《Nife Fiter》主に、[]など
	LPD3DXFONT				pFontd;//フォントDタイプ=《BackSeatAlphabetWidth》主に、[スコア(得点)]など
	LPD3DXFONT				pFonte;//フォントEタイプ=《D3 Cosmism》主に、[時間]など




//--------------------------------------------------------------------------------------
// Create any D3DPOOL_MANAGED resources here 
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{
    return S_OK;
}


//--------------------------------------------------------------------------------------
// Create any D3DPOOL_DEFAULT resources here 
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, 
                                const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{
    return S_OK;
}


//--------------------------------------------------------------------------------------
// Handle updates to the scene
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
	//	キー状態を調べる関数
	keycheck( );

	switch(gamemode)
	{
	case 0://
		break;
	case 1://

		//--------------------------------------------------------------------------------------
		//自機を移動させる処理 (押された時、押しっぱなしになった時)
		//-------------------------------------------------------------------
		if(KEY_LEFT == PUSH || KEY_LEFT == HOLD)
		{
			myship[0].gPos.x -= MYSHIP_SPEED;
		}
		if(KEY_RIGHT == PUSH || KEY_RIGHT == HOLD)
		{
			myship[0].gPos.x += MYSHIP_SPEED;
		}
		if(KEY_UP == PUSH || KEY_UP == HOLD)
		{
			myship[0].gPos.y -= MYSHIP_SPEED;
		}
		if(KEY_DOWN == PUSH || KEY_DOWN == HOLD)
		{
			myship[0].gPos.y += MYSHIP_SPEED;
		}


		//--------------------------------------------------------------------------------------
		//自機の画像が
		//画面から消えないようにする
		//-------------------------------
		if(myship[0].gPos.x < 0)//画面の左
		{
			myship[0].gPos.x = 0;
		}
		if(myship[0].gPos.x >= 585)//画面の右
		{
			myship[0].gPos.x = 585;
		}
		if(myship[0].gPos.y < 0)//画面の上
		{
			myship[0].gPos.y = 0;
		}
		if(myship[0].gPos.y >= 425)//画面の下
		{
			myship[0].gPos.y = 425;
		}




		//--------------------------------------------------------------------------------------
		//弾の発射
		//----------------------------------
		if(KEY_SPACE == PUSH)//スペースキーが押されたら
		{
			for (int i = 0; i < BULLET_MAX; i++)
			{
				if(bullets[i].active == 0)
				{
					bullets[i].active = 1;//弾の表示
					//自機の中央に表示させる
					bullets[i].gPos_tm.x = myship[0].gPos.x + 29;
					bullets[i].gPos_tm.y = myship[0].gPos.y + 15;
					break;//処理を抜け出す
				}
			}
		}



		// for文で弾の数だけやる
		for(int i = 0;i < BULLET_MAX; i++)
		{
			switch(bullets[i].type)
			{
			case 0://
				if(bullets[i].active == 1)
				{
					// 弾の座標はbullet構造体の中に入れる
					bullets[i].gPos_tm.y -= BULLET_SPEED;//弾の座標を減らす
					if(bullets[i].gPos_tm.y < 0)
					{
						bullets[i].gPos_tm.y = myship[i].gPos.y;
						bullets[i].active = 0;
					}
				}
				break;
			case 1://
				break;
			}
		}

	//--------------------------------------------------------------------------------------
	//自機用の弾と敵の当たり判定
	//-------------------------------------------
		for(int i = 0;i < BULLET_MAX; i++)
		{
			for(int j = 0;j < ENEMY_MAX;j++)
			{
				if(bullets[i].gPos_tm.x >= enemy[j].gPos_te.x)
				{
					if(bullets[i].gPos_tm.x <= enemy[j].gPos_te.x + 70)//画像の中心部が初期設定になっているので半分の値を代入
					{
						if(bullets[i].gPos_tm.y >= enemy[j].gPos_te.y)
						{
							if(bullets[i].gPos_tm.y <= enemy[j].gPos_te.y + 35)//画像の中心部が初期設定になっているので半分の値を代入
							{
								if(enemy[j].active_te == 1)
								{
										//弾が当たったら、フラグをOFFにする
										enemy[j].active_te = 0;
										bullets[i].active = 0;
										enemy_blt[j].active = 0;
										score += 100;//敵を倒すことが出来たら得点UP!
								}
							}
						}
					}
				}
			}
		}

	//--------------------------------------------------------------------------------------
	//敵の動き
	//------------------------------------------

			for(int i = 0;i< ENEMY_MAX;i++)
			{
				if(enemy[i].active_te == 1)
				{
					enemy[i].gPos_te.x += ENEMY_SPEED;
					if(enemy[i].gPos_te.x > 640)
					{
						enemy[i].gPos_te.x = -50;
						enemy[i].active_te = 1;
					}
				}
				break;
			}
		

	//--------------------------------------------------------------------------------------
	//敵用弾の発射
	//-----------------------------------------

		for (int i = 0; i < ENEMY_BLT_MAX; i++)
		{
			if(enemy_blt[i].active == 0)
			{
				enemy_blt[i].active = 1;//弾の表示
				//自機の中央に表示させる
				enemy_blt[i].gPos.x = enemy[i].gPos_te.x + 30;
				enemy_blt[i].gPos.y = enemy[i].gPos_te.y + 20;

				//敵が自機用の弾に当たって倒されたら
				//これ以上敵用の弾が出ないようにする。
				if(enemy[i].active_te == 0)
				{
					enemy_blt[i].active = 0;
				}
			}
		}
		
		
		// for文で弾の数だけやる
		for(int i = 0;i < ENEMY_BLT_MAX; i++)
		{
			switch(enemy_blt[i].type)
			{
			case 0://
				if(enemy_blt[i].active == 1)
				{
					// 弾の座標はbullet構造体の中に入れる
					enemy_blt[i].gPos.y += ENEMY_BLT_SPEED;//弾の座標を増やす
					if(enemy_blt[i].gPos.y > 640)
					{
						enemy_blt[i].gPos.y = enemy[i].gPos_te.y;
						enemy_blt[i].active = 0;
					}
				}
				break;
			case 1://
				break;
			}
		}


	//--------------------------------------------------------------------------------------
	//敵用の弾と自機の当たり判定
	//-----------------------------------------
		for(int i = 0;i < ENEMY_BLT_MAX;i++)
		{
			for(int j = 0;j < MYSHIP;j++)
			{
				if(enemy_blt[i].gPos.x > myship[0].gPos.x + 5)
				{
					if(enemy_blt[i].gPos.x < myship[0].gPos.x + 55)
					{
						if(enemy_blt[i].gPos.y >  myship[0].gPos.y + 15)
						{
							if(enemy_blt[i].gPos.y <  myship[0].gPos.y + 50)
							{
								if(myship[0].active == 1)//自機に当たったら、敵用の弾と自機を消す
								{
									myship[0].active = 0;//自機を非表示
									enemy_blt[i].active = 0;//敵用の弾を非表示
								}
							}
						}
					}
				}
			}
		}

		if(myship[0].active == 0 && enemy_blt[i].active == 0)
		{
			for(int k = 0;k < BULLET_MAX;k++)
			{
				bullets[k].active = 0;//弾を非表示
			}
		}


		


	//--------------------------------------------------------------------------------------
	//マトリクスを作成
	//---------------------------------------

		// for文で弾の数だけまとめてMatrix計算する
		for(int i = 0;i < BULLET_MAX; i++)
		{	
			//<matrix用=弾>
			//移動行列を作成
			D3DXMatrixTranslation( &bullets[i].matrix,bullets[i].gPos_tm.x,bullets[i].gPos_tm.y,0);
		}

		for(int i = 0;i < MYSHIP;i++)
		{
			//<matrix_ji用=自機>
			//移動行列を作成
			D3DXMatrixTranslation( &myship[i].matrix,myship[i].gPos.x,myship[i].gPos.y,0);
		}

		for(int i = 0;i < ENEMY_MAX; i++)
		{
			//<matrix_te用=敵>
			//移動行列を作成
			D3DXMatrixTranslation( &enemy[i].matrix_te,enemy[i].gPos_te.x,enemy[i].gPos_te.y,0);
		}

		//敵の弾を敵弾の数だけ
		for(int i = 0;i < ENEMY_BLT_MAX; i++)
		{
			//<matrix_te用=敵>
			//移動行列を作成
			D3DXMatrixTranslation( &enemy_blt[i].matrix,enemy_blt[i].gPos.x,enemy_blt[i].gPos.y,0);
		}


		//背景画像も動かないようにMatrix関数で固定させる。
		//<matrix_te用=背景画像>
		//移動行列を作成
		D3DXMatrixTranslation( &matrix_back,0,0,0);

		break;
	case 2://
		break;
	case 3://
		break;
	case 4://
		break;
	}


}


//--------------------------------------------------------------------------------------
// Render the scene 
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
    HRESULT hr;

    // Clear the render target and the zbuffer 
    V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 0, 128, 255), 1.0f, 0) );

    // Render the scene
    if( SUCCEEDED( pd3dDevice->BeginScene() ) )
    {
			//ここから描画処理を行う

			//スプライトの開始
			pSprite->Begin(D3DXSPRITE_ALPHABLEND);

		switch(gamemode)
		{
		case 0://
			break;
		case 1://

			//背景画像(1枚しかないので、if文で指定しない)
			//テクスチャの表示領域
			RECT	rect_back;
			SetRect(&rect_back,0,0,640,480);
			//テクスチャの描画前に行列をセットする
			pSprite->SetTransform(&matrix_back);
			//スプライトで2D描画=背景
			pSprite->Draw( pText_back,&rect_back,NULL,&gPos_map,D3DCOLOR_ARGB(255,255,255,255));


			for(int i = 0;i < MYSHIP;i++)
			{
				if(myship[i].active == 1)
				{
					//自機
					//テクスチャの表示領域
					RECT	rect_tex;
					SetRect(&rect_tex,0,0,60,60);
					//テクスチャの描画前に行列をセットする
					pSprite->SetTransform(&myship[i].matrix);
					//スプライトで2D描画=自機
					pSprite->Draw( pTexture,&rect_tex,NULL,NULL,D3DCOLOR_ARGB(255,255,255,255));
				}
			}
			for(int i = 0;i < BULLET_MAX; i++)
			{
				if(bullets[i].active == 1)
				{
					//弾
					//テクスチャの表示領域
					RECT	rect_tex_ta;
					SetRect(&rect_tex_ta,0,0,10,10);
					//テクスチャの描画前に行列にセットする
					pSprite->SetTransform(&bullets[i].matrix);
					//中心をセット
					D3DXVECTOR3 center_ta = D3DXVECTOR3(10.f / 2.f,10.f / 2.f,0.f);
					//スプライトで2D描画=弾
					pSprite->Draw( pText_tama,&rect_tex_ta,&center_ta,NULL,D3DCOLOR_ARGB(255,255,255,255));
				}
			}
			for(int i = 0;i < 10; i++)
			{
				if( enemy[i].active_te == 1)
				{
					//敵
					//テクスチャの表示領域
					RECT	rect_tex_te;
					SetRect(&rect_tex_te,0,0,70,35);
					//テクスチャの描画前に行列にセットする
					pSprite->SetTransform(&enemy[i].matrix_te);
					//スプライトで2D描画=敵
					pSprite->Draw( pText_teki,&rect_tex_te,NULL,NULL,D3DCOLOR_ARGB(255,255,255,255));
				}
			}
			for(int i = 0;i < 10; i++)
			{
				if( enemy_blt[i].active == 1)
				{
					//敵用の弾
					//テクスチャの表示領域
					RECT	rect_tex_teta;
					SetRect(&rect_tex_teta,0,0,12,12);
					//テクスチャの描画前に行列にセットする
					pSprite->SetTransform(&enemy_blt[i].matrix);
					//スプライトで2D描画=敵の弾
					pSprite->Draw( pText_teta,&rect_tex_teta,NULL,NULL,D3DCOLOR_ARGB(255,255,255,255));
				}
			}
			
			break;
		case 2://
			break;
		case 3://
			break;
		case 4://
			break;
		}

			//スプライトの終了
			pSprite->End();


		//========================================
		//各フォント
		//========================================
		
			//フォント1
			RECT rectf;							//フォント位置を保持する構造体変数
			SetRect ( &rectf,10,10,640,480);	//変数への位置セット
			//フォントの描画
			pFont -> DrawText(NULL,			//標準機能で描画
			_T(""),							//表示文字列
			-1,								//表示文字数
			&rectf,							//表示位置
			NULL,							//表示スタイル
			D3DCOLOR_ARGB(255,255,255,255));//表示色
			
			
			//フォント2
			RECT rectfa;						//フォント位置を保持する構造体変数
			SetRect ( &rectfa,10,30,640,480);	//変数への位置セット
			//フォントの描画
			pFontd -> DrawText(NULL,		//標準機能で描画
			_T(""),							//表示文字列
			-1,								//表示文字数
			&rectfa,						//表示位置
			NULL,							//表示スタイル
			D3DCOLOR_ARGB(255,0,255,0));	//表示色


		//----------------------
		//得点(スコア)
		//---------------

			//フォント3
			RECT rectfc;						//フォント位置を保持する構造体変数
			SetRect ( &rectfc,380,0,640,480);	//変数への位置セット
			//フォントの描画
			pFontb -> DrawText(NULL,		//標準機能で描画
			_T("SCORE"),					//表示文字列
			-1,								//表示文字数
			&rectfc,						//表示位置
			NULL,							//表示スタイル
			D3DCOLOR_ARGB(255,0,255,255));	//表示色*/

			//変数内容の表示
			TCHAR str[255];
			_stprintf(str,_T("%07d"),score);
			RECT rect_ti;
			SetRect(&rect_ti,470,0,640,480);
			pFontd->DrawText(NULL,str,-1,&rect_ti,NULL,D3DCOLOR_RGBA(255,255,255,255));


        V( pd3dDevice->EndScene() );
    }
}


//--------------------------------------------------------------------------------------
// Handle messages to the application 
//--------------------------------------------------------------------------------------
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, 
                          bool* pbNoFurtherProcessing, void* pUserContext )
{
    return 0;
}


//--------------------------------------------------------------------------------------
// Release resources created in the OnResetDevice callback here 
//--------------------------------------------------------------------------------------
void CALLBACK OnLostDevice( void* pUserContext )
{
}


//--------------------------------------------------------------------------------------
// Release resources created in the OnCreateDevice callback here
//--------------------------------------------------------------------------------------
void CALLBACK OnDestroyDevice( void* pUserContext )
{
	//テクスチャの解放
	SAFE_RELEASE(pTexture);//自機
	SAFE_RELEASE(pText_tama);//自機用の弾
	SAFE_RELEASE(pText_teki);//敵
	SAFE_RELEASE(pText_teta);//敵用の弾
	SAFE_RELEASE(pText_back);//背景
	//スプライトの解放
	SAFE_RELEASE(pSprite);
	//	フォントの解放
	SAFE_RELEASE( pFont );
	SAFE_RELEASE( pFonta );
	SAFE_RELEASE( pFontb );
	SAFE_RELEASE( pFontc );
	SAFE_RELEASE( pFontd );
	SAFE_RELEASE( pFonte );
}



//--------------------------------------------------------------------------------------
// Initialize everything and go into a render loop
//--------------------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
{
    // Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif

    // Set the callback functions
    DXUTSetCallbackDeviceCreated( OnCreateDevice );
    DXUTSetCallbackDeviceReset( OnResetDevice );
    DXUTSetCallbackDeviceLost( OnLostDevice );
    DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
    DXUTSetCallbackMsgProc( MsgProc );
    DXUTSetCallbackFrameRender( OnFrameRender );
    DXUTSetCallbackFrameMove( OnFrameMove );
   
    // TODO: Perform any application-level initialization here

    // Initialize DXUT and create the desired Win32 window and Direct3D device for the application
    DXUTInit( true, true, true ); // Parse the command line, handle the default hotkeys, and show msgboxes
    DXUTSetCursorSettings( true, true ); // Show the cursor and clip it when in full screen
    DXUTCreateWindow( L"EmptyProject" );
    DXUTCreateDevice( D3DADAPTER_DEFAULT, true, 640, 480);

	//スプライトの作成
	D3DXCreateSprite( DXUTGetD3DDevice(), &pSprite);


	//--------------------------------------------------------------------------------------
	//テクスチャのロード
	//------------------------------------------------------------------
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\jiki02.png"),&pTexture );//自機(画像)
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\tama03.png"),&pText_tama);//自機用の弾(画像)
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\teki001.png"),&pText_teki);//敵(画像)
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\tama04.png"),&pText_teta);//敵用の弾(画像)
	//D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\"),&pText_icon);//宝箱(画像)
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\back.png"),&pText_back);//背景(画像)



	//--------------------------------------------------------------------------------------
	//フォントの作成  各パターン
	//----------------------------------------------------

	////フォントの作成0パターン)
		D3DXCreateFont(
			DXUTGetD3DDevice(),			//direct3Dデバイス
			16,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("ARP浪漫明朝体U"),	//フォント名
			&pFont);					//作成されたフォントが格納される変数

		//フォントの作成(Aパターン)
		D3DXCreateFont(
			DXUTGetD3DDevice(),			//direct3Dデバイス
			30,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("Broadway BT"),			//フォント名
			&pFonta);					//作成されたフォントが格納される変数

		//フォントの作成(Bパターン)
		D3DXCreateFont(	
			DXUTGetD3DDevice(),			//direct3Dデバイス
			23,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("HGep022"),				//フォント名
			&pFontb);					//作成されたフォントが格納される変数

		//フォントの作成(Cパターン)
		D3DXCreateFont(
			DXUTGetD3DDevice(),			//direct3Dデバイス	
			30,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("Nife Fiter"),			//フォント名
			&pFontc);					//作成されたフォントが格納される変数

		//フォントの作成(Dパターン)
		D3DXCreateFont(
			DXUTGetD3DDevice(),			//direct3Dデバイス
			30,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("BackSeatAlphabetWidth"),//フォント名
			&pFontd);					//作成されたフォントが格納される変数


		//フォントの作成(Eパターン)
		D3DXCreateFont(
			DXUTGetD3DDevice(),			//direct3Dデバイス
			30,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("D3 Cosmism"),			//フォント名
			&pFonte);					//作成されたフォントが格納される変数

		//次のフォント

	//--------------------------------------------------------------------------------------
	//1度しか実行しないもの
	//--------------------------------------------------

	//------------------------------------------------
	//自機の構造体に関する処理
	//-------------------------------
	for(i = 0;i < 1;i++)
	{
		myship[i].gPos.x = 280;
		myship[i].gPos.y = 420;
		myship[i].active = 1;
	}
	//------------------------------------------------
	//弾の構造体に関する処理
	//-------------------------------
	for(i = 0;i < BULLET_MAX;i++)
	{
		bullets[i].gPos_tm.x = 280;
		bullets[i].gPos_tm.y = 430;
		bullets[i].active = 0;
		bullets[i].type = 0;
	}
	//------------------------------------------------
	//敵の構造体に関する処理
	//-------------------------------
	for(i = 0;i < ENEMY_MAX;i++)
	{
		enemy[i].gPos_te.x = -100;
		enemy[i].gPos_te.y = 50;
		enemy[i].active_te = 1;
		enemy[i].type = 0;
	}
	//------------------------------------------------
	//敵の弾に関する処理
	//-------------------------------
	for(i = 0;i < ENEMY_BLT_MAX;i++)
	{
		enemy_blt[i].gPos.x = 280;
		enemy_blt[i].gPos.y = 430;
		enemy_blt[i].active = 0;
		enemy_blt[i].type = 0;
	}


	//--------------------------------------------------------------------------------------
	//初期化
	//-----------------------------
	bullets[i].gPos_tm = D3DXVECTOR3(280,430,0);
	score = 0;


    // Start the render loop
    DXUTMainLoop();

    // TODO: Perform any application-level cleanup here

    return DXUTGetExitCode();
}
自機が敵の弾に当たったら、自機が消え、さらに自機の弾を発射出来なくしました。
また、2重ループに変更しました。
敵が画面外に退場したとき、倒されるまでループさせる。
を直しました。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#39

投稿記事 by softya(ソフト屋) » 14年前

私の指摘で直した部分を明確にしてくださいね。
softya(ソフト屋) さんが書きました:ざっと見たところ問題点が幾つかあります。
・敵の発生座標が全て同じで、同じタイミングで発生。
・敵が画面外に退場したときの処理が書いていない。
・自機用の弾と敵の当たり判定で、全ての敵と全ての自機用の弾の当たり判定が行われていない。forはBULLET_MAX分とENEMY_MAX分の2重ループになるはず。
bulletsとenemyをiで同列に扱ってはいけません。
・自機用の弾と敵の当たり判定で、自機用の弾の生存判定が行われていない。

どこを直したのでしょうか?
それと今現在どんな問題があるのでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

STAR_HARUKI
記事: 36
登録日時: 14年前
住所: 新潟県新潟市
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#40

投稿記事 by STAR_HARUKI » 14年前

softya(ソフト屋) さんが書きました:私の指摘で直した部分を明確にしてくださいね。
softya(ソフト屋) さんが書きました:ざっと見たところ問題点が幾つかあります。
・敵の発生座標が全て同じで、同じタイミングで発生。
・敵が画面外に退場したときの処理が書いていない。
・自機用の弾と敵の当たり判定で、全ての敵と全ての自機用の弾の当たり判定が行われていない。forはBULLET_MAX分とENEMY_MAX分の2重ループになるはず。
bulletsとenemyをiで同列に扱ってはいけません。
・自機用の弾と敵の当たり判定で、自機用の弾の生存判定が行われていない。

どこを直したのでしょうか?
それと今現在どんな問題があるのでしょうか?



敵が画面外に退場したときの処理を書いた。
自機用の弾と敵の当たり判定で、自機用の弾の生存判定を行った。
自機用の弾と敵の当たり判定で、全ての敵と全ての自機用の弾の当たり判定を行った。

ココが分からないです。
・敵の発生座標が全て同じで、同じタイミングで発生。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#41

投稿記事 by softya(ソフト屋) » 14年前

問題はここですね。

コード:

    for(i = 0;i < ENEMY_MAX;i++)
    {
        enemy[i].gPos_te.x = -100;
        enemy[i].gPos_te.y = 50;
        enemy[i].active_te = 1;
        enemy[i].type = 0;
    }
初期化で同時発生していて座標も同じです。
簡単にタイミングをずらしたかったら、
enemy[0].gPos_te.y = 50;
enemy[1].gPos_te.y = 10;
        :
などと座標を設定してください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

STAR_HARUKI
記事: 36
登録日時: 14年前
住所: 新潟県新潟市
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#42

投稿記事 by STAR_HARUKI » 14年前

初期化のせいで敵が同時に出現してしまうのは、座標をずらして確認しました。

でも、1番目の敵を倒したら2番目の敵が出現するようにするにはどうしたらいいのでしょうか?分からないので、詰まってしまって・・・・・・。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#43

投稿記事 by softya(ソフト屋) » 14年前

STAR_HARUKI さんが書きました:初期化のせいで敵が同時に出現してしまうのは、座標をずらして確認しました。
でも、1番目の敵を倒したら2番目の敵が出現するようにするにはどうしたらいいのでしょうか?分からないので、詰まってしまって・・・・・・。
生存フラグをみて死んでいたら、新たに座標と生存フラグを設定して発生させるだけですよ。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

STAR_HARUKI
記事: 36
登録日時: 14年前
住所: 新潟県新潟市
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#44

投稿記事 by STAR_HARUKI » 14年前

コード:

//--------------------------------------------------------------------------------------
// File: EmptyProject.cpp
//
// Empty starting point for new Direct3D applications
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
//古い文字列操作関数に対する警告を回避する
#pragma warning (disable : 4995)
#pragma warning (disable : 4996)

#include <stdio.h>
#include <tchar.h>

#include "dxstdafx.h"
#include "resource.h"

//---------------------------------------------
//プロトタイプ宣言
//-------------------------------

//---------------------------------------------
//その他のインクルード
//-------------------------------
#include "keycheck.h"


//---------------------------------------------
//その他のディファイン
//最大値とかを指定させる
//-------------------------------
/*自機用*/
#define MYSHIP 1			//自機の最大数
#define MYSHIP_SPEED 4		//自機用の移動速度
/*自機用の弾*/
#define BULLET_SPEED 11		//自機用弾の移動速度
#define BULLET_MAX 10		//弾の最大数
/*敵用*/
#define ENEMY_MAX 10		//敵の最大数
#define ENEMY_SPEED 3		//敵の動く最大速度
/*敵用の弾*/
#define ENEMY_BLT_MAX 10	//敵の弾の最大数
#define ENEMY_BLT_SPEED 12	//敵用弾の移動速度


	//--------------------------------------------------------------------------------------
	//関数
	//-------------------------------
	int gamemode = 1;//ゲームモード管理変数『0:タイトル 1:ゲーム画面 2:ゲームクリア 3:ゲームオーバー』
	int times = 60,ti = 0,te = 0,ts = 0;//制限時間管理用変数
	int count;//弾の発射数
	int i;
	int score;//得点
	//int active_ji = 1;//自機用フラグ

	//--------------------------------------------------------------------------------------
	//テクスチャ関数
	//-------------------------------
	LPDIRECT3DTEXTURE9		pTexture;//自機用
	LPDIRECT3DTEXTURE9		pText_tama;//自弾用
	LPDIRECT3DTEXTURE9		pText_teki;//敵用
	LPDIRECT3DTEXTURE9		pText_teta;//敵弾用
	LPDIRECT3DTEXTURE9		pText_icon;//アイテム用
	LPDIRECT3DTEXTURE9		pText_back;//背景用


	//スプライトの作成
	LPD3DXSPRITE			pSprite;

	//--------------------------------------------------------------------------------------
	//座標関数
	//-------------------------------
	D3DXVECTOR3				gPos_map = D3DXVECTOR3(0,0,0);//背景画像用の画像指定位置
	

	//--------------------------------------------------------------------------------------
	//マトリクス
	//-------------------------
	
	D3DXMATRIX	matrix_ji;//自機
	D3DXMATRIX	matrix_back;//背景


	//---------------------------------------------
	//自機の構造体 ※基本「0」で!
	//---------------------------------
	typedef struct _myship
	{
		D3DXVECTOR3		gPos;//敵用の画像指定位置
		int				active;//有効フラグ 0:OFF 1:ON
		D3DXMATRIX		matrix;//行列
	};

	_myship myship[MYSHIP];//弾構造体の宣言

	//---------------------------------------------
	//弾の構造体
	//------------------
	typedef struct _bullet
	{
		D3DXVECTOR3		gPos_tm;//自機弾用の画像指定位置
		int				active;//有効フラグ 0:OFF 1:ON
		int				type;//弾の種類
		D3DXMATRIX		matrix;//行列
	};

	_bullet bullets[BULLET_MAX];//弾構造体の宣言

	//---------------------------------------------
	//敵の構造体
	//--------------------------
	typedef struct _enemy
	{
		D3DXVECTOR3		gPos_te;//敵の座標
		int				active_te;//有効フラグ 0:OFF 1:ON
		int				type;//敵の種類
		D3DXMATRIX		matrix_te;//敵の行列
	};

	_enemy enemy[ENEMY_MAX];//敵構造体の宣言

	//---------------------------------------------
	//敵の弾の構造体
	//------------------
	typedef struct _enemy_blt
	{
		D3DXVECTOR3		gPos;//敵用の画像指定位置
		int				active;//有効フラグ 0:OFF 1:ON
		int				type;//弾の種類
		D3DXMATRIX		matrix;//行列
	};

	_enemy_blt enemy_blt[ENEMY_BLT_MAX];//弾構造体の宣言



	//--------------------------------------------------------------------------------------
	//フォント作成 変数宣言
	//--------------------------------
	LPD3DXFONT				pFont;//フォント0タイプ=《ARP浪漫明朝体U》主に、[文字表示]など
	LPD3DXFONT				pFonta;//フォントAタイプ=《Broadway BT》主に、[制限時間]など
	LPD3DXFONT				pFontb;//フォントBタイプ=《HGep037》主に、[ステータス表示]など
	LPD3DXFONT				pFontc;//フォントCタイプ=《Nife Fiter》主に、[]など
	LPD3DXFONT				pFontd;//フォントDタイプ=《BackSeatAlphabetWidth》主に、[スコア(得点)]など
	LPD3DXFONT				pFonte;//フォントEタイプ=《D3 Cosmism》主に、[時間]など




//--------------------------------------------------------------------------------------
// Create any D3DPOOL_MANAGED resources here 
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{
    return S_OK;
}


//--------------------------------------------------------------------------------------
// Create any D3DPOOL_DEFAULT resources here 
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, 
                                const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{
    return S_OK;
}


//--------------------------------------------------------------------------------------
// Handle updates to the scene
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
	//	キー状態を調べる関数
	keycheck( );

	switch(gamemode)
	{
	case 0://
		break;
	case 1://

		//--------------------------------------------------------------------------------------
		//自機を移動させる処理 (押された時、押しっぱなしになった時)
		//-------------------------------------------------------------------
		if(KEY_LEFT == PUSH || KEY_LEFT == HOLD)
		{
			myship[0].gPos.x -= MYSHIP_SPEED;
		}
		if(KEY_RIGHT == PUSH || KEY_RIGHT == HOLD)
		{
			myship[0].gPos.x += MYSHIP_SPEED;
		}
		if(KEY_UP == PUSH || KEY_UP == HOLD)
		{
			myship[0].gPos.y -= MYSHIP_SPEED;
		}
		if(KEY_DOWN == PUSH || KEY_DOWN == HOLD)
		{
			myship[0].gPos.y += MYSHIP_SPEED;
		}


		//--------------------------------------------------------------------------------------
		//自機の画像が
		//画面から消えないようにする
		//-------------------------------
		if(myship[0].gPos.x < 0)//画面の左
		{
			myship[0].gPos.x = 0;
		}
		if(myship[0].gPos.x >= 585)//画面の右
		{
			myship[0].gPos.x = 585;
		}
		if(myship[0].gPos.y < 0)//画面の上
		{
			myship[0].gPos.y = 0;
		}
		if(myship[0].gPos.y >= 425)//画面の下
		{
			myship[0].gPos.y = 425;
		}




		//--------------------------------------------------------------------------------------
		//弾の発射
		//----------------------------------
		if(KEY_SPACE == PUSH)//スペースキーが押されたら
		{
			for (int i = 0; i < BULLET_MAX; i++)
			{
				if(bullets[i].active == 0)
				{
					bullets[i].active = 1;//弾の表示
					//自機の中央に表示させる
					bullets[i].gPos_tm.x = myship[0].gPos.x + 29;
					bullets[i].gPos_tm.y = myship[0].gPos.y + 15;
					break;//処理を抜け出す
				}
			}
		}



		// for文で弾の数だけやる
		for(int i = 0;i < BULLET_MAX; i++)
		{
			switch(bullets[i].type)
			{
			case 0://
				if(bullets[i].active == 1)
				{
					// 弾の座標はbullet構造体の中に入れる
					bullets[i].gPos_tm.y -= BULLET_SPEED;//弾の座標を減らす
					if(bullets[i].gPos_tm.y < 0)
					{
						bullets[i].gPos_tm.y = myship[i].gPos.y;
						bullets[i].active = 0;
					}
				}
				break;
			case 1://
				break;
			}
		}

	//--------------------------------------------------------------------------------------
	//自機用の弾と敵の当たり判定
	//-------------------------------------------
		for(int i = 0;i < BULLET_MAX; i++)
		{
			for(int j = 0;j < ENEMY_MAX;j++)
			{
				if(bullets[i].active == 1)
				{
					if(bullets[i].gPos_tm.x >= enemy[j].gPos_te.x)
					{
						if(bullets[i].gPos_tm.x <= enemy[j].gPos_te.x + 70)//画像の中心部が初期設定になっているので半分の値を代入
						{
							if(bullets[i].gPos_tm.y >= enemy[j].gPos_te.y)
							{
								if(bullets[i].gPos_tm.y <= enemy[j].gPos_te.y + 35)//画像の中心部が初期設定になっているので半分の値を代入
								{
									if(enemy[j].active_te == 1)
									{
										//弾が当たったら、フラグをOFFにする
										enemy[j].active_te = 0;
										bullets[i].active = 0;
										enemy_blt[j].active = 0;
										score += 100;//敵を倒すことが出来たら得点UP!

										if(enemy[j].active_te == 0)
										{
											enemy[j].active_te = 1;
											enemy[j].gPos_te.x = -80;
										}
									}
								}
							}
						}
					}
				}
			}
		}

	//--------------------------------------------------------------------------------------
	//敵の動き
	//------------------------------------------

			for(int i = 0;i< ENEMY_MAX;i++)
			{
				if(enemy[i].active_te == 1)
				{
					enemy[i].gPos_te.x += ENEMY_SPEED;
					if(enemy[i].gPos_te.x > 640)
					{
						enemy[i].gPos_te.x = -80;
					}

				}
			}


	//--------------------------------------------------------------------------------------
	//敵用弾の発射
	//-----------------------------------------

		for (int i = 0; i < ENEMY_BLT_MAX; i++)
		{
			for(int j = 0;j < ENEMY_MAX; j++)
			{
				if(enemy_blt[0].active == 0)
				{
					enemy_blt[0].active = 1;//弾の表示
					//自機の中央に表示させる
					enemy_blt[i].gPos.x = enemy[j].gPos_te.x + 30;
					enemy_blt[i].gPos.y = enemy[j].gPos_te.y + 20;

					//敵が自機用の弾に当たって倒されたら
					//これ以上敵用の弾が出ないようにする。
					if(enemy[j].active_te == 0)
					{
						enemy[j + 1].active_te = 1;
						enemy_blt[i].active = 0;
					}
				}
			}
		}
		
		
		// for文で弾の数だけやる
		for(int i = 0;i < ENEMY_BLT_MAX; i++)
		{
			switch(enemy_blt[i].type)
			{
			case 0://
				if(enemy_blt[i].active == 1)
				{
					// 弾の座標はbullet構造体の中に入れる
					enemy_blt[i].gPos.y += ENEMY_BLT_SPEED;//弾の座標を増やす
					if(enemy_blt[i].gPos.y > 640)
					{
						enemy_blt[i].gPos.y = enemy[i].gPos_te.y;
						enemy_blt[i].active = 0;
					}
				}
				break;
			case 1://
				break;
			}
		}


	//--------------------------------------------------------------------------------------
	//敵用の弾と自機の当たり判定
	//-----------------------------------------
		for(int i = 0;i < ENEMY_BLT_MAX;i++)
		{
			for(int j = 0;j < MYSHIP;j++)
			{
				if(enemy_blt[i].gPos.x > myship[0].gPos.x + 5)
				{
					if(enemy_blt[i].gPos.x < myship[0].gPos.x + 55)
					{
						if(enemy_blt[i].gPos.y >  myship[0].gPos.y + 15)
						{
							if(enemy_blt[i].gPos.y <  myship[0].gPos.y + 50)
							{
								if(myship[0].active == 1)//自機に当たったら、敵用の弾と自機を消す
								{
									myship[0].active = 0;//自機を非表示
									enemy_blt[i].active = 0;//敵用の弾を非表示
								}
							}
						}
					}
				}
			}
		}

		if(myship[0].active == 0 && enemy_blt[i].active == 0)
		{
			for(int k = 0;k < BULLET_MAX;k++)
			{
				bullets[k].active = 0;//弾を非表示
			}
		}


		


	//--------------------------------------------------------------------------------------
	//マトリクスを作成
	//---------------------------------------

		// for文で弾の数だけまとめてMatrix計算する
		for(int i = 0;i < BULLET_MAX; i++)
		{	
			//<matrix用=弾>
			//移動行列を作成
			D3DXMatrixTranslation( &bullets[i].matrix,bullets[i].gPos_tm.x,bullets[i].gPos_tm.y,0);
		}

		for(int i = 0;i < MYSHIP;i++)
		{
			//<matrix_ji用=自機>
			//移動行列を作成
			D3DXMatrixTranslation( &myship[i].matrix,myship[i].gPos.x,myship[i].gPos.y,0);
		}

		for(int i = 0;i < ENEMY_MAX; i++)
		{
			//<matrix_te用=敵>
			//移動行列を作成
			D3DXMatrixTranslation( &enemy[i].matrix_te,enemy[i].gPos_te.x,enemy[i].gPos_te.y,0);
		}

		//敵の弾を敵弾の数だけ
		for(int i = 0;i < ENEMY_BLT_MAX; i++)
		{
			//<matrix_te用=敵>
			//移動行列を作成
			D3DXMatrixTranslation( &enemy_blt[i].matrix,enemy_blt[i].gPos.x,enemy_blt[i].gPos.y,0);
		}


		//背景画像も動かないようにMatrix関数で固定させる。
		//<matrix_te用=背景画像>
		//移動行列を作成
		D3DXMatrixTranslation( &matrix_back,0,0,0);

		break;
	case 2://
		break;
	case 3://
		break;
	case 4://
		break;
	}


}


//--------------------------------------------------------------------------------------
// Render the scene 
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
    HRESULT hr;

    // Clear the render target and the zbuffer 
    V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 0, 128, 255), 1.0f, 0) );

    // Render the scene
    if( SUCCEEDED( pd3dDevice->BeginScene() ) )
    {
			//ここから描画処理を行う

			//スプライトの開始
			pSprite->Begin(D3DXSPRITE_ALPHABLEND);

		switch(gamemode)
		{
		case 0://
			break;
		case 1://

			//背景画像(1枚しかないので、if文で指定しない)
			//テクスチャの表示領域
			RECT	rect_back;
			SetRect(&rect_back,0,0,640,480);
			//テクスチャの描画前に行列をセットする
			pSprite->SetTransform(&matrix_back);
			//スプライトで2D描画=背景
			pSprite->Draw( pText_back,&rect_back,NULL,&gPos_map,D3DCOLOR_ARGB(255,255,255,255));


			for(int i = 0;i < MYSHIP;i++)
			{
				if(myship[i].active == 1)
				{
					//自機
					//テクスチャの表示領域
					RECT	rect_tex;
					SetRect(&rect_tex,0,0,60,60);
					//テクスチャの描画前に行列をセットする
					pSprite->SetTransform(&myship[i].matrix);
					//スプライトで2D描画=自機
					pSprite->Draw( pTexture,&rect_tex,NULL,NULL,D3DCOLOR_ARGB(255,255,255,255));
				}
			}
			for(int i = 0;i < BULLET_MAX; i++)
			{
				if(bullets[i].active == 1)
				{
					//弾
					//テクスチャの表示領域
					RECT	rect_tex_ta;
					SetRect(&rect_tex_ta,0,0,10,10);
					//テクスチャの描画前に行列にセットする
					pSprite->SetTransform(&bullets[i].matrix);
					//中心をセット
					D3DXVECTOR3 center_ta = D3DXVECTOR3(10.f / 2.f,10.f / 2.f,0.f);
					//スプライトで2D描画=弾
					pSprite->Draw( pText_tama,&rect_tex_ta,&center_ta,NULL,D3DCOLOR_ARGB(255,255,255,255));
				}
			}
			for(int i = 0;i < 10; i++)
			{
				if( enemy[i].active_te == 1)
				{
					//敵
					//テクスチャの表示領域
					RECT	rect_tex_te;
					SetRect(&rect_tex_te,0,0,70,35);
					//テクスチャの描画前に行列にセットする
					pSprite->SetTransform(&enemy[i].matrix_te);
					//スプライトで2D描画=敵
					pSprite->Draw( pText_teki,&rect_tex_te,NULL,NULL,D3DCOLOR_ARGB(255,255,255,255));
				}
			}
			for(int i = 0;i < 10; i++)
			{
				if( enemy_blt[i].active == 1)
				{
					//敵用の弾
					//テクスチャの表示領域
					RECT	rect_tex_teta;
					SetRect(&rect_tex_teta,0,0,12,12);
					//テクスチャの描画前に行列にセットする
					pSprite->SetTransform(&enemy_blt[i].matrix);
					//スプライトで2D描画=敵の弾
					pSprite->Draw( pText_teta,&rect_tex_teta,NULL,NULL,D3DCOLOR_ARGB(255,255,255,255));
				}
			}
			
			break;
		case 2://
			break;
		case 3://
			break;
		case 4://
			break;
		}

			//スプライトの終了
			pSprite->End();


		//========================================
		//各フォント
		//========================================
		
			//フォント1
			RECT rectf;							//フォント位置を保持する構造体変数
			SetRect ( &rectf,10,10,640,480);	//変数への位置セット
			//フォントの描画
			pFont -> DrawText(NULL,			//標準機能で描画
			_T(""),							//表示文字列
			-1,								//表示文字数
			&rectf,							//表示位置
			NULL,							//表示スタイル
			D3DCOLOR_ARGB(255,255,255,255));//表示色
			
			
			//フォント2
			RECT rectfa;						//フォント位置を保持する構造体変数
			SetRect ( &rectfa,10,30,640,480);	//変数への位置セット
			//フォントの描画
			pFontd -> DrawText(NULL,		//標準機能で描画
			_T(""),							//表示文字列
			-1,								//表示文字数
			&rectfa,						//表示位置
			NULL,							//表示スタイル
			D3DCOLOR_ARGB(255,0,255,0));	//表示色


		//----------------------
		//得点(スコア)
		//---------------

			//フォント3
			RECT rectfc;						//フォント位置を保持する構造体変数
			SetRect ( &rectfc,380,0,640,480);	//変数への位置セット
			//フォントの描画
			pFontb -> DrawText(NULL,		//標準機能で描画
			_T("SCORE"),					//表示文字列
			-1,								//表示文字数
			&rectfc,						//表示位置
			NULL,							//表示スタイル
			D3DCOLOR_ARGB(255,0,255,255));	//表示色*/

			//変数内容の表示
			TCHAR str[255];
			_stprintf(str,_T("%07d"),score);
			RECT rect_ti;
			SetRect(&rect_ti,470,0,640,480);
			pFontd->DrawText(NULL,str,-1,&rect_ti,NULL,D3DCOLOR_RGBA(255,255,255,255));


        V( pd3dDevice->EndScene() );
    }
}


//--------------------------------------------------------------------------------------
// Handle messages to the application 
//--------------------------------------------------------------------------------------
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, 
                          bool* pbNoFurtherProcessing, void* pUserContext )
{
    return 0;
}


//--------------------------------------------------------------------------------------
// Release resources created in the OnResetDevice callback here 
//--------------------------------------------------------------------------------------
void CALLBACK OnLostDevice( void* pUserContext )
{
}


//--------------------------------------------------------------------------------------
// Release resources created in the OnCreateDevice callback here
//--------------------------------------------------------------------------------------
void CALLBACK OnDestroyDevice( void* pUserContext )
{
	//テクスチャの解放
	SAFE_RELEASE(pTexture);//自機
	SAFE_RELEASE(pText_tama);//自機用の弾
	SAFE_RELEASE(pText_teki);//敵
	SAFE_RELEASE(pText_teta);//敵用の弾
	SAFE_RELEASE(pText_back);//背景
	//スプライトの解放
	SAFE_RELEASE(pSprite);
	//	フォントの解放
	SAFE_RELEASE( pFont );
	SAFE_RELEASE( pFonta );
	SAFE_RELEASE( pFontb );
	SAFE_RELEASE( pFontc );
	SAFE_RELEASE( pFontd );
	SAFE_RELEASE( pFonte );
}



//--------------------------------------------------------------------------------------
// Initialize everything and go into a render loop
//--------------------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
{
    // Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif

    // Set the callback functions
    DXUTSetCallbackDeviceCreated( OnCreateDevice );
    DXUTSetCallbackDeviceReset( OnResetDevice );
    DXUTSetCallbackDeviceLost( OnLostDevice );
    DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
    DXUTSetCallbackMsgProc( MsgProc );
    DXUTSetCallbackFrameRender( OnFrameRender );
    DXUTSetCallbackFrameMove( OnFrameMove );
   
    // TODO: Perform any application-level initialization here

    // Initialize DXUT and create the desired Win32 window and Direct3D device for the application
    DXUTInit( true, true, true ); // Parse the command line, handle the default hotkeys, and show msgboxes
    DXUTSetCursorSettings( true, true ); // Show the cursor and clip it when in full screen
    DXUTCreateWindow( L"EmptyProject" );
    DXUTCreateDevice( D3DADAPTER_DEFAULT, true, 640, 480);

	//スプライトの作成
	D3DXCreateSprite( DXUTGetD3DDevice(), &pSprite);


	//--------------------------------------------------------------------------------------
	//テクスチャのロード
	//------------------------------------------------------------------
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\jiki02.png"),&pTexture );//自機(画像)
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\tama03.png"),&pText_tama);//自機用の弾(画像)
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\teki001.png"),&pText_teki);//敵(画像)
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\tama04.png"),&pText_teta);//敵用の弾(画像)
	//D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\"),&pText_icon);//宝箱(画像)
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\back.png"),&pText_back);//背景(画像)



	//--------------------------------------------------------------------------------------
	//フォントの作成  各パターン
	//----------------------------------------------------

	////フォントの作成0パターン)
		D3DXCreateFont(
			DXUTGetD3DDevice(),			//direct3Dデバイス
			16,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("ARP浪漫明朝体U"),	//フォント名
			&pFont);					//作成されたフォントが格納される変数

		//フォントの作成(Aパターン)
		D3DXCreateFont(
			DXUTGetD3DDevice(),			//direct3Dデバイス
			30,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("Broadway BT"),			//フォント名
			&pFonta);					//作成されたフォントが格納される変数

		//フォントの作成(Bパターン)
		D3DXCreateFont(	
			DXUTGetD3DDevice(),			//direct3Dデバイス
			23,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("HGep022"),				//フォント名
			&pFontb);					//作成されたフォントが格納される変数

		//フォントの作成(Cパターン)
		D3DXCreateFont(
			DXUTGetD3DDevice(),			//direct3Dデバイス	
			30,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("Nife Fiter"),			//フォント名
			&pFontc);					//作成されたフォントが格納される変数

		//フォントの作成(Dパターン)
		D3DXCreateFont(
			DXUTGetD3DDevice(),			//direct3Dデバイス
			30,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("BackSeatAlphabetWidth"),//フォント名
			&pFontd);					//作成されたフォントが格納される変数


		//フォントの作成(Eパターン)
		D3DXCreateFont(
			DXUTGetD3DDevice(),			//direct3Dデバイス
			30,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("D3 Cosmism"),			//フォント名
			&pFonte);					//作成されたフォントが格納される変数

		//次のフォント

	//--------------------------------------------------------------------------------------
	//1度しか実行しないもの
	//--------------------------------------------------

	//------------------------------------------------
	//自機の構造体に関する処理
	//-------------------------------
	for(i = 0;i < 1;i++)
	{
		myship[i].gPos.x = 280;
		myship[i].gPos.y = 420;
		myship[i].active = 1;
	}
	//------------------------------------------------
	//弾の構造体に関する処理
	//-------------------------------
	for(i = 0;i < BULLET_MAX;i++)
	{
		bullets[i].gPos_tm.x = 280;
		bullets[i].gPos_tm.y = 430;
		bullets[i].active = 0;
		bullets[i].type = 0;
	}
	//------------------------------------------------
	//敵の構造体に関する処理
	//-------------------------------
	for(i = 0;i < ENEMY_MAX;i++)
	{
		enemy[0].gPos_te.x = -80;
		enemy[i].gPos_te.y = 50;
		enemy[0].active_te = 1;
		enemy[i].type = 0;
	}
	//------------------------------------------------
	//敵の弾に関する処理
	//-------------------------------
	for(i = 0;i < ENEMY_BLT_MAX;i++)
	{
		enemy_blt[i].gPos.x = 280;
		enemy_blt[i].gPos.y = 430;
		enemy_blt[i].active = 0;
		enemy_blt[i].type = 0;
	}


	//--------------------------------------------------------------------------------------
	//初期化
	//-----------------------------
	bullets[i].gPos_tm = D3DXVECTOR3(280,430,0);
	score = 0;


    // Start the render loop
    DXUTMainLoop();

    // TODO: Perform any application-level cleanup here

    return DXUTGetExitCode();
}
これでどうでしょう?
一応、1番目の敵が倒されたら2番目が出るようにしましたが・・・・・・。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#45

投稿記事 by softya(ソフト屋) » 14年前

こちらでは動かせませんので、これで良いかはSTAR_HARUKIさんご自身で判断されるべき事ですよ。
なんども書いてますが、問題があるなら問題点を書いてくださいね。

それと前から疑問なんですが、同時に敵がENEMY_MAX分発生しないならenemyは配列にする必要ないですよ。
STAR_HARUKIさんの意図がわからないので、どうしたいかはご自分で決めてください。

気になるとしたら、敵の弾の発射内に敵の出現処理が書かれていること。

コード:

                    //敵が自機用の弾に当たって倒されたら
                    //これ以上敵用の弾が出ないようにする。
                    if(enemy[j].active_te == 0)
                    {
                        enemy[j + 1].active_te = 1;
                        enemy_blt[i].active = 0;
                    }
後々、半月も経てばなぜここにあるか分からず自分でも困ることになると思います。
敵の再発生と敵の攻撃処理を兼用しないように。
それと enemy[j].active_te == 1だけが弾を発射すべきでは?
後で強引にねじ伏せてますが、お勧めできません。

それと敵の弾の発射に制限がないこと。

コード:

        for (int i = 0; i < ENEMY_BLT_MAX; i++)
        {
            for(int j = 0;j < ENEMY_MAX; j++)
            {
                if(enemy_blt[0].active == 0)
                {
                    enemy_blt[0].active = 1;//弾の表示
                    //自機の中央に表示させる
                    enemy_blt[i].gPos.x = enemy[j].gPos_te.x + 30;
                    enemy_blt[i].gPos.y = enemy[j].gPos_te.y + 20;
 
                    //敵が自機用の弾に当たって倒されたら
                    //これ以上敵用の弾が出ないようにする。
                    if(enemy[j].active_te == 0)
                    {
                        enemy[j + 1].active_te = 1;
                        enemy_blt[i].active = 0;
                    }
                }
            }
        }
この処理で、弾を一度にENEMY_BLT_MAX分同時発生させてます。
発生したらループを抜けるようにしたほうが良いです。


初期化で、初期化が不十分な事。

コード:

    for(i = 0;i < ENEMY_MAX;i++)
    {
        enemy[0].gPos_te.x = -80;
        enemy[i].gPos_te.y = 50;
        enemy[0].active_te = 1;
        enemy[i].type = 0;
    }
書くなら、せめてこうしてください。

コード:

    for(i = 0;i < ENEMY_MAX;i++)
    {
        enemy[i].gPos_te.x = -80;
        enemy[i].gPos_te.y = 50;
        enemy[i].active_te = 0;
        enemy[i].type = 0;
    }
    enemy[0].active_te = 1;
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

STAR_HARUKI
記事: 36
登録日時: 14年前
住所: 新潟県新潟市
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#46

投稿記事 by STAR_HARUKI » 14年前

ずいぶん前の話ですが、
動かなかったという話で、もしかしたら僕の説明不足かもしれないと思い
今頃載せました・・・・・・m(__)m

「dxsdk_apr2007.exe」
http://www.microsoft.com/downloads/en/d ... laylang=en

EmptyProject_2005.sln
を起動。
≪数字が8になっている≫

基本visual studio 2005でやっています。
2008もインストールしたのですが、使っていません。

毎回長いのを載せているので、多少、省きました。

コード:

//--------------------------------------------------------------------------------------

~~~~~~~~

		//--------------------------------------------------------------------------------------
		//弾の発射
		//----------------------------------
		if(KEY_SPACE == PUSH)//スペースキーが押されたら
		{
			for (int i = 0; i < BULLET_MAX; i++)
			{
				if(bullets[i].active == 0)
				{
					bullets[i].active = 1;//弾の表示
					//自機の中央に表示させる
					bullets[i].gPos_tm.x = myship[0].gPos.x + 29;
					bullets[i].gPos_tm.y = myship[0].gPos.y + 15;
					break;//処理を抜け出す
				}
			}
		}



		// for文で弾の数だけやる
		for(int i = 0;i < BULLET_MAX; i++)
		{
			switch(bullets[i].type)
			{
			case 0://
				if(bullets[i].active == 1)
				{
					// 弾の座標はbullet構造体の中に入れる
					bullets[i].gPos_tm.y -= BULLET_SPEED;//弾の座標を減らす
					if(bullets[i].gPos_tm.y < 0)
					{
						bullets[i].gPos_tm.y = myship[i].gPos.y;
						bullets[i].active = 0;
					}
				}
				break;
			case 1://
				break;
			}
		}

	//--------------------------------------------------------------------------------------
	//自機用の弾と敵の当たり判定
	//-------------------------------------------
		for(int i = 0;i < BULLET_MAX; i++)
		{
			for(int j = 0;j < ENEMY_MAX;j++)
			{
				if(bullets[i].active == 1)//弾がないのに当たり判定させないため
				{
					if(bullets[i].gPos_tm.x >= enemy[j].gPos_te.x)
					{
						if(bullets[i].gPos_tm.x <= enemy[j].gPos_te.x + 70)//画像の中心部が初期設定になっているので半分の値を代入
						{
							if(bullets[i].gPos_tm.y >= enemy[j].gPos_te.y)
							{
								if(bullets[i].gPos_tm.y <= enemy[j].gPos_te.y + 35)//画像の中心部が初期設定になっているので半分の値を代入
								{
									if(enemy[j].active_te == 1)//敵のフラグがONの状態で下記を代入
									{
										//弾が当たったら、フラグをOFFにする
										enemy[j].active_te = 0;
										bullets[i].active = 0;
										enemy_blt[j].active = 0;
										score += 100;//敵を倒すことが出来たら得点UP!

										if(enemy[j].active_te == 0)
										{
											enemy[j].active_te = 1;
											enemy[j].gPos_te.x = -80;
										}
									}
								}
							}
						}
					}
				}
			}
		}

	//--------------------------------------------------------------------------------------
	//敵の動き
	//------------------------------------------

			for(int i = 0;i< ENEMY_MAX;i++)
			{
				if(enemy[i].active_te == 1)
				{
					enemy[i].gPos_te.x += ENEMY_SPEED;
					if(enemy[i].gPos_te.x > 640)
					{
						enemy[i].gPos_te.x = -80;
					}

				}
			}


	//--------------------------------------------------------------------------------------
	//敵用弾の発射
	//-----------------------------------------

		for (int i = 0; i < ENEMY_BLT_MAX; i++)
		{
			for(int j = 0;j < ENEMY_MAX; j++)
			{
				if(enemy_blt[0].active == 0)
				{
					enemy_blt[0].active = 1;//弾の表示
					//自機の中央に表示させる
					enemy_blt[i].gPos.x = enemy[j].gPos_te.x + 30;
					enemy_blt[i].gPos.y = enemy[j].gPos_te.y + 20;

					//敵が自機用の弾に当たって倒されたら
					//これ以上敵用の弾が出ないようにする。
					if(enemy[j].active_te == 0)
					{
						enemy[j + 1].active_te = 1;
						enemy_blt[i].active = 0;
					}
				}
			}
		}
		
		
		// for文で弾の数だけやる
		for(int i = 0;i < ENEMY_BLT_MAX; i++)
		{
			switch(enemy_blt[i].type)
			{
			case 0://
				if(enemy_blt[i].active == 1)
				{
					// 弾の座標はbullet構造体の中に入れる
					enemy_blt[i].gPos.y += ENEMY_BLT_SPEED;//弾の座標を増やす
					if(enemy_blt[i].gPos.y > 640)
					{
						enemy_blt[i].gPos.y = enemy[i].gPos_te.y;
						enemy_blt[i].active = 0;
					}
				}
				break;
			case 1://
				break;
			}
		}


	//--------------------------------------------------------------------------------------
	//敵用の弾と自機の当たり判定
	//-----------------------------------------
		for(int i = 0;i < ENEMY_BLT_MAX;i++)
		{
			for(int j = 0;j < MYSHIP;j++)
			{
				if(enemy_blt[i].gPos.x > myship[0].gPos.x + 5)
				{
					if(enemy_blt[i].gPos.x < myship[0].gPos.x + 55)
					{
						if(enemy_blt[i].gPos.y >  myship[0].gPos.y + 15)
						{
							if(enemy_blt[i].gPos.y <  myship[0].gPos.y + 50)
							{
								if(myship[0].active == 1)//自機に当たったら、敵用の弾と自機を消す
								{
									myship[0].active = 0;//自機を非表示
									enemy_blt[i].active = 0;//敵用の弾を非表示
								}
							}
						}
					}
				}
			}
		}

		//敵の弾が自機に当たって自機が消えたら今までの弾も非表示
		for(int i = 0; i < ENEMY_BLT_MAX;i++)
		{
			if(myship[0].active == 0 && enemy_blt[i].active == 0)
			{
				for(int k = 0;k < BULLET_MAX;k++)
				{
					bullets[k].active = 0;//弾を非表示
				}
			}
		}


	//--------------------------------------------------------------------------------------
	//得点
	//---------------------------------------
		if(score > Hi_score)
		{
			Hi_score = score;
		}

~~~~~~~~

	//--------------------------------------------------------------------------------------
	//1度しか実行しないもの
	//--------------------------------------------------

	//------------------------------------------------
	//自機の構造体に関する処理
	//-------------------------------
	for(i = 0;i < 1;i++)
	{
		myship[i].gPos.x = 280;
		myship[i].gPos.y = 420;
		myship[i].active = 1;
	}
	//------------------------------------------------
	//弾の構造体に関する処理
	//-------------------------------
	for(i = 0;i < BULLET_MAX;i++)
	{
		bullets[i].gPos_tm.x = 280;
		bullets[i].gPos_tm.y = 430;
		bullets[i].active = 0;
		bullets[i].type = 0;
	}
	//------------------------------------------------
	//敵の構造体に関する処理
	//-------------------------------
	for(i = 0;i < ENEMY_MAX;i++)
	{
		enemy[i].gPos_te.x = -80;
		enemy[i].gPos_te.y = 50;
		enemy[i].active_te = 0;
		enemy[i].type = 0;
	}
	enemy[0].active_te = 1;//一番最初の敵のフラグをONにする
	//------------------------------------------------
	//敵の弾に関する処理
	//-------------------------------
	for(i = 0;i < ENEMY_BLT_MAX;i++)
	{
		enemy_blt[i].gPos.x = 280;
		enemy_blt[i].gPos.y = 430;
		enemy_blt[i].active = 0;
		enemy_blt[i].type = 0;
	}


	//--------------------------------------------------------------------------------------
	//初期化
	//-----------------------------
	bullets[i].gPos_tm = D3DXVECTOR3(280,430,0);
	score = 0;
	Hi_score = 10000;


    // Start the render loop
    DXUTMainLoop();

    // TODO: Perform any application-level cleanup here

    return DXUTGetExitCode();
}

このプログラムで1番目の敵が倒せたら2番目の敵が出るようになっているのでしょうか?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#47

投稿記事 by softya(ソフト屋) » 14年前

ずいぶん前の話ですが、
動かなかったという話で、もしかしたら僕の説明不足かもしれないと思い
今頃載せました・・・・・・m(__)m

「dxsdk_apr2007.exe」
http://www.microsoft.com/downloads/en/d ... laylang=en

EmptyProject_2005.sln
を起動。
≪数字が8になっている≫
いえ、私の環境と違いすぎて動かないのです。
それ(dxsdk_apr2007)を導入すると別の支障も出来るので導入できません。
私はWindows7ですのでDirectX11環境が基本なのですが、それは4年前の環境ですので違いすぎるのです。
実行ファイルとデータを圧縮して添付してもらったら動きますので、よかったらそちらにしてください。

それと私が幾つか提示した問題点や疑問点にお答え下さい。
どうして良いのか分からないなら、それを書いてください。
ソースコードを見る限りほとんど反映されていません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

STAR_HARUKI
記事: 36
登録日時: 14年前
住所: 新潟県新潟市
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#48

投稿記事 by STAR_HARUKI » 14年前

softya(ソフト屋) さんが書きました:
それと私が幾つか提示した問題点や疑問点にお答え下さい。
どうして良いのか分からないなら、それを書いてください。
ソースコードを見る限りほとんど反映されていません。
すみません。
敵の座標らへんしか確認しておらず、その他の部分を確認していませんでした。
さっそく確認し、
今度はフルでコードを載せますm(__)m

STAR_HARUKI
記事: 36
登録日時: 14年前
住所: 新潟県新潟市
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#49

投稿記事 by STAR_HARUKI » 14年前

今後の自分のために、
分かりやすい方で、
敵を同時に複数発生させるのを、別に構造体を作理ました。

おっしゃった通り、敵の数ENEMY_MAX分表示することは無いので、最大数を10から1にして、敵を倒しても初期化された敵が表示するようにしました。

そして、敵用の弾の当たり判定や、自機用の弾と敵の画像の当たり判定を別で作り、自機に敵の弾が当たったらライフ(体力)をある数値減らす処理を加えました。

コード:

//--------------------------------------------------------------------------------------
// File: EmptyProject.cpp
//
// Empty starting point for new Direct3D applications
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
//古い文字列操作関数に対する警告を回避する
#pragma warning (disable : 4995)
#pragma warning (disable : 4996)

#include <stdio.h>
#include <tchar.h>

#include "dxstdafx.h"
#include "resource.h"

//---------------------------------------------
//プロトタイプ宣言
//-------------------------------

//---------------------------------------------
//その他のインクルード
//-------------------------------
#include "keycheck.h"


//---------------------------------------------
//その他のディファイン
//最大値とかを指定させる
//-------------------------------
/*自機用*/
#define MYSHIP 1			//自機の最大数
#define MYSHIP_SPEED 4		//自機用の移動速度
/*自機用の弾*/
#define BULLET_SPEED 11		//自機用弾の移動速度
#define BULLET_MAX 10		//弾の最大数
/*敵用*/
#define ENEMY_MAX 1		//敵の最大数
#define ENEMY_SPEED 3		//敵の動く最大速度
#define ENEMY_SPEED_B 4		//敵の動く最大速度パターンB
/*敵用の弾*/
#define ENEMY_BLT_MAX 10	//敵の弾の最大数
#define ENEMY_BLT_SPEED 12	//敵用弾の移動速度


	//--------------------------------------------------------------------------------------
	//関数
	//-------------------------------
	int gamemode = 0;//ゲームモード管理変数『0:タイトル 1:ゲーム画面 2:ゲームクリア 3:ゲームオーバー』
	int times = 60,ti = 0,te = 0,ts = 0;//制限時間管理用変数
	int count;//弾の発射数
	int i;
	int score;//得点
	int Hi_score;//最高得点
	int Life = 50;//体力


	//--------------------------------------------------------------------------------------
	//テクスチャ関数
	//-------------------------------
	LPDIRECT3DTEXTURE9		pTexture;//自機用
	LPDIRECT3DTEXTURE9		pText_tama;//自弾用
	LPDIRECT3DTEXTURE9		pText_teki;//敵用
	LPDIRECT3DTEXTURE9		pText_teta;//敵弾用
	LPDIRECT3DTEXTURE9		pText_icon;//アイテム用
	LPDIRECT3DTEXTURE9		pText_back;//背景用
	//LPDIRECT3DTEXTURE9		pText_logo_a;//ロゴ001用
	LPDIRECT3DTEXTURE9		pText_life;//自機ライフ用


	//スプライトの作成
	LPD3DXSPRITE			pSprite;

	//--------------------------------------------------------------------------------------
	//座標関数
	//-------------------------------
	D3DXVECTOR3				gPos_map = D3DXVECTOR3(0,0,0);//背景画像用の画像指定位置
	//D3DXVECTOR3				gPos_logo_a = D3DXVECTOR3(150,420,0);//ロゴ001画像用の画像指定位置


	//--------------------------------------------------------------------------------------
	//マトリクス
	//-------------------------
	
	D3DXMATRIX	matrix_ji;//自機
	D3DXMATRIX	matrix_back;//背景
	//D3DXMATRIX	matrix_logo_a;//ロゴ001


	//---------------------------------------------
	//自機の構造体 ※基本「0」で!
	//---------------------------------
	typedef struct _myship
	{
		D3DXVECTOR3		gPos;//敵用の画像指定位置
		int				active;//有効フラグ 0:OFF 1:ON
		D3DXMATRIX		matrix;//行列
	};

	_myship myship[MYSHIP];//弾構造体の宣言

	//---------------------------------------------
	//弾の構造体
	//------------------
	typedef struct _bullet
	{
		D3DXVECTOR3		gPos_tm;//自機弾用の画像指定位置
		int				active;//有効フラグ 0:OFF 1:ON
		int				type;//弾の種類
		D3DXMATRIX		matrix;//行列
	};

	_bullet bullets[BULLET_MAX];//弾構造体の宣言

	//---------------------------------------------
	//敵の構造体
	//--------------------------
	typedef struct _enemy
	{
		D3DXVECTOR3		gPos_te;//敵の座標
		int				active_te;//有効フラグ 0:OFF 1:ON
		int				type;//敵の種類
		D3DXMATRIX		matrix_te;//敵の行列
	};

	_enemy enemy[ENEMY_MAX];//敵構造体の宣言

	//---------------------------------------------
	//敵の構造体 2
	//--------------------------
	typedef struct _enemy_a
	{
		D3DXVECTOR3		gPos;//敵の座標
		int				active;//有効フラグ 0:OFF 1:ON
		int				type;//敵の種類
		D3DXMATRIX		matrix;//敵の行列
	};

	_enemy_a enemy_a[ENEMY_MAX];//敵構造体の宣言

	//---------------------------------------------
	//敵の弾の構造体
	//------------------
	typedef struct _enemy_blt
	{
		D3DXVECTOR3		gPos;//敵用の画像指定位置
		int				active;//有効フラグ 0:OFF 1:ON
		int				type;//弾の種類
		D3DXMATRIX		matrix;//行列
	};

	_enemy_blt enemy_blt[ENEMY_BLT_MAX];//弾構造体の宣言

	//---------------------------------------------
	//敵の弾の構造体 2
	//------------------
	typedef struct _enemy_blt2
	{
		D3DXVECTOR3		gPos;//敵用の画像指定位置
		int				active;//有効フラグ 0:OFF 1:ON
		int				type;//弾の種類
		D3DXMATRIX		matrix;//行列
	};

	_enemy_blt2 enemy_blt2[ENEMY_BLT_MAX];//弾構造体の宣言




	//--------------------------------------------------------------------------------------
	//フォント作成 変数宣言
	//--------------------------------
	LPD3DXFONT				pFont;///フォント0タイプ= ARP浪漫明朝体U》主に、[文字表示]など
	LPD3DXFONT				pFonta;//フォントAタイプ=《Broadway BT》主に、[制限時間]など
	LPD3DXFONT				pFontb;//フォントBタイプ=《HGep037》主に、[ステータス表示]など
	LPD3DXFONT				pFontc;//フォントCタイプ=《FancyBalloonsAlphabet》主に、[最高得点]など
	LPD3DXFONT				pFontd;//フォントDタイプ=《BackSeatAlphabetWidth》主に、[スコア(得点)]など
	LPD3DXFONT				pFonte;//フォントEタイプ=《D3 Cosmism》主に、[時間]など
	LPD3DXFONT				pFontf;//フォントFタイプ=《SHOWA73ARegular》主に、[タイトル画面文字]など
	LPD3DXFONT				pFontg;//フォントGタイプ=《富士ポップP》主に、[その他 小さな文字]など
	LPD3DXFONT				pFonth;//フォントHタイプ=《TAPEMAN》主に、[]など




//--------------------------------------------------------------------------------------
// Create any D3DPOOL_MANAGED resources here 
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{
    return S_OK;
}


//--------------------------------------------------------------------------------------
// Create any D3DPOOL_DEFAULT resources here 
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, 
                                const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{
    return S_OK;
}


//--------------------------------------------------------------------------------------
// Handle updates to the scene
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
	//	キー状態を調べる関数
	keycheck( );

	switch(gamemode)
	{
	case 0://【タイトル画面】
		if(gamemode == 0)
		{
			if(KEY_S == PUSH)//Sキーが押されたら下記の処理を実行!
			{
				gamemode = 1;//タイトル画面からゲーム画面へ
			}
		}

		//<matrix_te用=ロゴ001画像>
		//移動行列を作成
		//D3DXMatrixTranslation( &matrix_logo_a,0,0,0);

		break;
	case 1://【ゲーム画面】

		//--------------------------------------------------------------------------------------
		//自機を移動させる処理 (押された時、押しっぱなしになった時)
		//-------------------------------------------------------------------
		if(KEY_LEFT == PUSH || KEY_LEFT == HOLD)
		{
			myship[0].gPos.x -= MYSHIP_SPEED;
		}
		if(KEY_RIGHT == PUSH || KEY_RIGHT == HOLD)
		{
			myship[0].gPos.x += MYSHIP_SPEED;
		}
		if(KEY_UP == PUSH || KEY_UP == HOLD)
		{
			myship[0].gPos.y -= MYSHIP_SPEED;
		}
		if(KEY_DOWN == PUSH || KEY_DOWN == HOLD)
		{
			myship[0].gPos.y += MYSHIP_SPEED;
		}


		//--------------------------------------------------------------------------------------
		//自機の画像が
		//画面から消えないようにする
		//-------------------------------
		if(myship[0].gPos.x < 0)//画面の左
		{
			myship[0].gPos.x = 0;
		}
		if(myship[0].gPos.x >= 585)//画面の右
		{
			myship[0].gPos.x = 585;
		}
		if(myship[0].gPos.y < 0)//画面の上
		{
			myship[0].gPos.y = 0;
		}
		if(myship[0].gPos.y >= 425)//画面の下
		{
			myship[0].gPos.y = 425;
		}

		////////
		if(KEY_A == PUSH)
		{
			score += 1000;
		}



		//--------------------------------------------------------------------------------------
		//弾の発射
		//----------------------------------
		if(KEY_SPACE == PUSH)//スペースキーが押されたら
		{
			for (int i = 0; i < BULLET_MAX; i++)
			{
				if(bullets[i].active == 0)
				{
					bullets[i].active = 1;//弾の表示
					//自機の中央に表示させる
					bullets[i].gPos_tm.x = myship[0].gPos.x + 29;
					bullets[i].gPos_tm.y = myship[0].gPos.y + 15;
					break;//処理を抜け出す
				}
			}
		}



		// for文で弾の数だけやる
		for(int i = 0;i < BULLET_MAX; i++)
		{
			switch(bullets[i].type)
			{
			case 0://
				if(bullets[i].active == 1)
				{
					// 弾の座標はbullet構造体の中に入れる
					bullets[i].gPos_tm.y -= BULLET_SPEED;//弾の座標を減らす
					if(bullets[i].gPos_tm.y < 0)
					{
						bullets[i].gPos_tm.y = myship[i].gPos.y;
						bullets[i].active = 0;
					}
				}
				break;
			case 1://
				break;
			}
		}

	//--------------------------------------------------------------------------------------
	//自機用の弾と敵の当たり判定
	//-------------------------------------------
		for(int i = 0;i < BULLET_MAX; i++)
		{
			for(int j = 0;j < ENEMY_MAX;j++)
			{
				if(bullets[i].active == 1)//弾がないのに当たり判定させないため
				{
					if(bullets[i].gPos_tm.x >= enemy[j].gPos_te.x)
					{
						if(bullets[i].gPos_tm.x <= enemy[j].gPos_te.x + 70)//画像の中心部が初期設定になっているので半分の値を代入
						{
							if(bullets[i].gPos_tm.y >= enemy[j].gPos_te.y)
							{
								if(bullets[i].gPos_tm.y <= enemy[j].gPos_te.y + 35)//画像の中心部が初期設定になっているので半分の値を代入
								{
									if(enemy[j].active_te == 1)//敵のフラグがONの状態で下記を代入
									{
										//弾が当たったら、フラグをOFFにする
										enemy[j].active_te = 0;
										bullets[i].active = 0;
										if(enemy_blt[j].gPos.y >= 640)//自機用の弾に当たっても敵用の弾は画面外に出るまでは消さない
										{
											enemy_blt[j].active = 0;
										}
										score += 100;//敵を倒すことが出来たら得点UP!

										if(enemy[j].active_te == 0)
										{
											enemy[j].active_te = 1;
											enemy[j].gPos_te.x = -100;
										}
									}
								}
							}
						}
					}
				}
			}
		}


	//--------------------------------------------------------------------------------------
	//自機用の弾と敵の当たり判定  2
	//-------------------------------------------
		for(int i = 0;i < BULLET_MAX; i++)
		{
			for(int j = 0;j < ENEMY_MAX;j++)
			{
				if(bullets[i].active == 1)//弾がないのに当たり判定させないため
				{
					if(bullets[i].gPos_tm.x >= enemy_a[j].gPos.x)
					{
						if(bullets[i].gPos_tm.x <= enemy_a[j].gPos.x + 70)//画像の中心部が初期設定になっているので半分の値を代入
						{
							if(bullets[i].gPos_tm.y >= enemy_a[j].gPos.y)
							{
								if(bullets[i].gPos_tm.y <= enemy_a[j].gPos.y + 35)//画像の中心部が初期設定になっているので半分の値を代入
								{
									if(enemy_a[j].active == 1)//敵のフラグがONの状態で下記を代入
									{
										//弾が当たったら、フラグをOFFにする
										enemy_a[j].active = 0;
										bullets[i].active = 0;
										if(enemy_blt2[j].gPos.y >= 640)//自機用の弾に当たっても敵用の弾は画面外に出るまでは消さない
										{
											enemy_blt2[j].active = 0;
										}
										score += 100;//敵を倒すことが出来たら得点UP!

										if(enemy_a[j].active == 0)
										{
											enemy_a[j].active = 1;
											enemy_a[j].gPos.x = -100;
										}
									}
								}
							}
						}
					}
				}
			}
		}

	//--------------------------------------------------------------------------------------
	//敵の動き
	//------------------------------------------

		//敵の動き
		for(int i = 0;i< ENEMY_MAX;i++)
		{
			if(enemy[i].active_te == 1)
			{
				enemy[i].gPos_te.x += ENEMY_SPEED;
				if(enemy[i].gPos_te.x > 640)
				{
					enemy[i].gPos_te.x = -100;
				}

			}
		}

		//敵の動き B
		for(int i = 0;i< ENEMY_MAX;i++)
		{
			if(enemy_a[i].active == 1)
			{
				enemy_a[i].gPos.x -= ENEMY_SPEED_B;
				if(enemy_a[i].gPos.x < -70)
				{
					enemy_a[i].gPos.x = 680;
				}

			}
		}



	//--------------------------------------------------------------------------------------
	//敵用弾の発射
	//-----------------------------------------

		for (int i = 0; i < ENEMY_BLT_MAX; i++)
		{
			for(int j = 0;j < ENEMY_MAX; j++)
			{
				if(enemy_blt[0].active == 0)
				{
					enemy_blt[0].active = 1;//弾の表示
					//敵の中央に表示させる
					enemy_blt[i].gPos.x = enemy[j].gPos_te.x + 30;
					enemy_blt[i].gPos.y = enemy[j].gPos_te.y + 20;

					//敵が自機用の弾に当たって倒されたら
					//これ以上敵用の弾が出ないようにする。
					if(enemy[j].active_te == 0)
					{
						if(enemy_blt[i].gPos.y >= 640)//敵用の弾が画面の外に出たら
						{
							enemy_blt[i].active = 0;
						}
					}
					break;
				}
			}
		}
		
		// for文で弾の数だけやる
		for(int i = 0;i < ENEMY_BLT_MAX; i++)
		{
			switch(enemy_blt[i].type)
			{
			case 0://
				if(enemy_blt[i].active == 1)
				{
					// 弾の座標はbullet構造体の中に入れる
					enemy_blt[i].gPos.y += ENEMY_BLT_SPEED;//弾の座標を増やす
					if(enemy_blt[i].gPos.y > 640)
					{
						enemy_blt[i].gPos.y = enemy[i].gPos_te.y;
						enemy_blt[i].active = 0;
					}
				}
				break;
			case 1://
				break;
			}
		}

		//2体目の敵
		//敵用の弾
		for (int i = 0; i < ENEMY_BLT_MAX; i++)
		{
			for(int j = 0;j < ENEMY_MAX; j++)
			{
				if(enemy_blt2[0].active == 0)
				{
					enemy_blt2[0].active = 1;//弾の表示
					//敵の中央に表示させる
					enemy_blt2[i].gPos.x = enemy_a[j].gPos.x + 30;
					enemy_blt2[i].gPos.y = enemy_a[j].gPos.y + 20;

					//敵が自機用の弾に当たって倒されたら
					//これ以上敵用の弾が出ないようにする。
					if(enemy_a[j].active == 0)
					{
						if(enemy_blt2[i].gPos.y >= 640)//敵用の弾が画面の外に出たら
						{
							enemy_blt2[i].active = 0;
						}
					}
					break;
				}
			}
		}
		// for文で弾の数だけやる
		for(int i = 0;i < ENEMY_BLT_MAX; i++)
		{
			switch(enemy_blt2[i].type)
			{
			case 0://
				if(enemy_blt2[i].active == 1)
				{
					// 弾の座標はbullet構造体の中に入れる
					enemy_blt2[i].gPos.y += ENEMY_BLT_SPEED;//弾の座標を増やす
					if(enemy_blt2[i].gPos.y > 640)
					{
						enemy_blt2[i].gPos.y = enemy_a[i].gPos.y;
						enemy_blt2[i].active = 0;
					}
				}
				break;
			case 1://
				break;
			}
		}





	//--------------------------------------------------------------------------------------
	//敵用の弾と自機の当たり判定
	//-----------------------------------------
		for(int i = 0;i < ENEMY_BLT_MAX;i++)
		{
			for(int j = 0;j < MYSHIP;j++)
			{
				if(myship[0].active == 1)//自機に当たったら、敵用の弾と自機を消す
				{
					if(enemy_blt[i].gPos.x > myship[0].gPos.x + 5)
					{
						if(enemy_blt[i].gPos.x < myship[0].gPos.x + 55)
						{
							if(enemy_blt[i].gPos.y >  myship[0].gPos.y + 15)
							{
								if(enemy_blt[i].gPos.y <  myship[0].gPos.y + 50)
								{
									enemy_blt[i].active = 0;//敵用の弾を非表示
									if(enemy_blt[i].active == 0)
									{
										Life -= 5;//自機の体力から一定の数値を引く
										if(Life <= 0)
										{
											gamemode = 3;
										}
									}
								}
							}
						}
					}
				}
			}
		}

		//敵の弾が自機に当たって自機が消えたら今までの弾も非表示
		for(int i = 0; i < ENEMY_BLT_MAX;i++)
		{
			if(myship[0].active == 0 && enemy_blt[i].active == 0)
			{
				for(int k = 0;k < BULLET_MAX;k++)
				{
					bullets[k].active = 0;//弾を非表示
				}
			}
		}


	//--------------------------------------------------------------------------------------
	//敵用の弾と自機の当たり判定  2
	//-----------------------------------------
		for(int i = 0;i < ENEMY_BLT_MAX;i++)
		{
			for(int j = 0;j < MYSHIP;j++)
			{
				if(myship[0].active == 1)//自機に当たったら、敵用の弾と自機を消す
				{
					if(enemy_blt2[i].gPos.x > myship[0].gPos.x + 5)
					{
						if(enemy_blt2[i].gPos.x < myship[0].gPos.x + 55)
						{
							if(enemy_blt2[i].gPos.y >  myship[0].gPos.y + 15)
							{
								if(enemy_blt2[i].gPos.y <  myship[0].gPos.y + 50)
								{
									enemy_blt2[i].active = 0;//敵用の弾を非表示
									if(enemy_blt2[i].active == 0)
									{
										Life -= 5;//自機の体力から一定の数値を引く
										if(Life <= 0)
										{
											gamemode = 3;
										}
									}
								}
							}
						}
					}
				}
			}
		}

		//敵の弾が自機に当たって自機が消えたら今までの弾も非表示
		for(int i = 0; i < ENEMY_BLT_MAX;i++)
		{
			if(myship[0].active == 0 && enemy_blt2[i].active == 0)
			{
				for(int k = 0;k < BULLET_MAX;k++)
				{
					bullets[k].active = 0;//弾を非表示
				}
			}
		}


	//--------------------------------------------------------------------------------------
	//得点
	//---------------------------------------
		if(score > Hi_score)
		{
			Hi_score = score;
		}		


	//--------------------------------------------------------------------------------------
	//得点
	//---------------------------------------
		if(score >= 5000)//ある一定の得点を超えたらクリア画面にする
		{
			gamemode = 2;
		}


	//--------------------------------------------------------------------------------------
	//マトリクスを作成
	//---------------------------------------

		// for文で弾の数だけまとめてMatrix計算する
		for(int i = 0;i < BULLET_MAX; i++)
		{	
			//<matrix用=弾>
			//移動行列を作成
			D3DXMatrixTranslation( &bullets[i].matrix,bullets[i].gPos_tm.x,bullets[i].gPos_tm.y,0);
		}

		for(int i = 0;i < MYSHIP;i++)
		{
			//<matrix_ji用=自機>
			//移動行列を作成
			D3DXMatrixTranslation( &myship[i].matrix,myship[i].gPos.x,myship[i].gPos.y,0);
		}

		for(int i = 0;i < ENEMY_MAX; i++)
		{
			//<matrix_te用=敵>
			//移動行列を作成
			D3DXMatrixTranslation( &enemy[i].matrix_te,enemy[i].gPos_te.x,enemy[i].gPos_te.y,0);
		}

		for(int i = 0;i < ENEMY_MAX; i++)
		{
			//<matrix_te用=敵>
			//移動行列を作成
			D3DXMatrixTranslation( &enemy_a[i].matrix,enemy_a[i].gPos.x,enemy_a[i].gPos.y,0);
		}

		//敵の弾を敵弾の数だけ
		for(int i = 0;i < ENEMY_BLT_MAX; i++)
		{
			//<matrix_te用=敵>
			//移動行列を作成
			D3DXMatrixTranslation( &enemy_blt[i].matrix,enemy_blt[i].gPos.x,enemy_blt[i].gPos.y,0);
		}
		//敵の弾を敵弾の数だけ
		for(int i = 0;i < ENEMY_BLT_MAX; i++)
		{
			//<matrix_te用=敵>
			//移動行列を作成
			D3DXMatrixTranslation( &enemy_blt2[i].matrix,enemy_blt2[i].gPos.x,enemy_blt2[i].gPos.y,0);
		}


		//背景画像も動かないようにMatrix関数で固定させる。
		//<matrix_te用=背景画像>
		//移動行列を作成
		D3DXMatrixTranslation( &matrix_back,0,0,0);


		break;
	case 2://【ゲームクリア画面】

		if(gamemode == 2)
		{
			score = 0;
			for(int i = 0;i < ENEMY_MAX;i++)
			{
				if(KEY_RETURN == PUSH)
				{
					//タイトル画面に戻す
					gamemode = 0;
					//初期設定に戻す
					//敵1
					enemy[i].gPos_te.x = -80;
					enemy[i].gPos_te.y = 50;
					//敵2
					enemy_a[i].gPos.x = 690;
					enemy_a[i].gPos.y = 90;
					//敵用の弾
					enemy_blt[i].gPos.x = 280;
					enemy_blt[i].gPos.y = 430;
					//敵用の弾2
					enemy_blt2[i].gPos.x = 280;
					enemy_blt2[i].gPos.y = 430;
					//自機
					myship[i].gPos.x = 280;
					myship[i].gPos.y = 420;
					//体力(ライフ)
					Life = 50;
				}
			}
		}
		break;
	case 3://【ゲームオーバー画面】
		if(gamemode == 3)
		{
			score = 0;
			for(int i = 0;i < ENEMY_MAX;i++)
			{
				if(KEY_RETURN == PUSH)
				{
					//タイトル画面に戻す
					gamemode = 0;
					//初期設定に戻す
					//敵1
					enemy[i].gPos_te.x = -80;
					enemy[i].gPos_te.y = 50;
					//敵2
					enemy_a[i].gPos.x = 690;
					enemy_a[i].gPos.y = 90;
					//敵用の弾
					enemy_blt[i].gPos.x = 280;
					enemy_blt[i].gPos.y = 430;
					//敵用の弾2
					enemy_blt2[i].gPos.x = 280;
					enemy_blt2[i].gPos.y = 430;
					//自機
					myship[i].gPos.x = 280;
					myship[i].gPos.y = 420;
					//体力(ライフ)
					Life = 50;
				}
			}
		}
		break;
	case 4://
		break;
	}

}


//--------------------------------------------------------------------------------------
// Render the scene 
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
    HRESULT hr;

    // Clear the render target and the zbuffer 
    V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 0, 128, 255), 1.0f, 0) );

    // Render the scene
    if( SUCCEEDED( pd3dDevice->BeginScene() ) )
    {
			//ここから描画処理を行う

			//スプライトの開始
			pSprite->Begin(D3DXSPRITE_ALPHABLEND);

		switch(gamemode)
		{
		case 0://【タイトル画面】
			/*//ロゴ001
			//テクスチャの表示領域
			RECT	rect_logo_a;
			SetRect(&rect_logo_a,0,0,640,480);
			//テクスチャの描画前に行列をセットする
			pSprite->SetTransform(&matrix_logo_a);
			//スプライトで2D描画=自機
			pSprite->Draw( pText_logo_a,&rect_logo_a,NULL,&gPos_logo_a,D3DCOLOR_ARGB(255,255,255,255));*/
			break;
		case 1://【ゲーム画面】

			//背景画像(1枚しかないので、if文で指定しない)
			//テクスチャの表示領域
			RECT	rect_back;
			SetRect(&rect_back,0,0,640,480);
			//テクスチャの描画前に行列をセットする
			pSprite->SetTransform(&matrix_back);
			//スプライトで2D描画=背景
			pSprite->Draw( pText_back,&rect_back,NULL,&gPos_map,D3DCOLOR_ARGB(255,255,255,255));


			for(int i = 0;i < MYSHIP;i++)
			{
				if(myship[i].active == 1)
				{
					//自機
					//テクスチャの表示領域
					RECT	rect_tex;
					SetRect(&rect_tex,0,0,60,60);
					//テクスチャの描画前に行列をセットする
					pSprite->SetTransform(&myship[i].matrix);
					//スプライトで2D描画=自機
					pSprite->Draw( pTexture,&rect_tex,NULL,NULL,D3DCOLOR_ARGB(255,255,255,255));
				}
			}
			for(int i = 0;i < BULLET_MAX; i++)
			{
				if(bullets[i].active == 1)
				{
					//弾
					//テクスチャの表示領域
					RECT	rect_tex_ta;
					SetRect(&rect_tex_ta,0,0,10,10);
					//テクスチャの描画前に行列にセットする
					pSprite->SetTransform(&bullets[i].matrix);
					//中心をセット
					D3DXVECTOR3 center_ta = D3DXVECTOR3(10.f / 2.f,10.f / 2.f,0.f);
					//スプライトで2D描画=弾
					pSprite->Draw( pText_tama,&rect_tex_ta,&center_ta,NULL,D3DCOLOR_ARGB(255,255,255,255));
				}
			}
			for(int i = 0;i < ENEMY_MAX; i++)
			{
				if( enemy[i].active_te == 1)
				{
					//敵
					//テクスチャの表示領域
					RECT	rect_tex_te;
					SetRect(&rect_tex_te,0,0,70,35);
					//テクスチャの描画前に行列にセットする
					pSprite->SetTransform(&enemy[i].matrix_te);
					//スプライトで2D描画=敵
					pSprite->Draw( pText_teki,&rect_tex_te,NULL,NULL,D3DCOLOR_ARGB(255,255,255,255));
				}
			}
			for(int i = 0;i < ENEMY_MAX; i++)
			{
				if( enemy_a[i].active == 1)
				{
					//敵2
					//テクスチャの表示領域
					RECT	rect_te_a;
					SetRect(&rect_te_a,0,0,70,35);
					//テクスチャの描画前に行列にセットする
					pSprite->SetTransform(&enemy_a[i].matrix);
					//スプライトで2D描画=敵
					pSprite->Draw( pText_teki,&rect_te_a,NULL,NULL,D3DCOLOR_ARGB(255,255,255,255));
				}
			}
			for(int i = 0;i < 10; i++)
			{
				if( enemy_blt[i].active == 1)
				{
					//敵用の弾
					//テクスチャの表示領域
					RECT	rect_tex_teta;
					SetRect(&rect_tex_teta,0,0,12,12);
					//テクスチャの描画前に行列にセットする
					pSprite->SetTransform(&enemy_blt[i].matrix);
					//スプライトで2D描画=敵の弾
					pSprite->Draw( pText_teta,&rect_tex_teta,NULL,NULL,D3DCOLOR_ARGB(255,255,255,255));
				}
			}
			for(int i = 0;i < 10; i++)
			{
				if( enemy_blt2[i].active == 1)
				{
					//敵用の弾
					//テクスチャの表示領域
					RECT	rect_tex_teta;
					SetRect(&rect_tex_teta,0,0,12,12);
					//テクスチャの描画前に行列にセットする
					pSprite->SetTransform(&enemy_blt2[i].matrix);
					//スプライトで2D描画=敵の弾
					pSprite->Draw( pText_teta,&rect_tex_teta,NULL,NULL,D3DCOLOR_ARGB(255,255,255,255));
				}
			}

			break;
		case 2://【ゲームクリア画面】
			break;
		case 3://【ゲームオーバー画面】
			break;
		case 4://
			break;
		}

			//スプライトの終了
			pSprite->End();


		switch(gamemode)
		{
		case 0://【タイトル画面】
		//========================================
		//各フォント
		//========================================
	
			//フォント1
			RECT rectf;								//フォント位置を保持する構造体変数
			SetRect ( &rectf,10,100,640,480);		//変数への位置セット
			//フォントの描画
			pFont -> DrawText(NULL,					//標準機能で描画
			_T("ここにタイトル画面が入ります\nタイトル画像やタイトル画面文字も表示!!"),//表示文字列
			-1,										//表示文字数
			&rectf,									//表示位置
			NULL,									//表示スタイル
			D3DCOLOR_ARGB(255,255,255,255));		//表示色


			//フォント1
			RECT rectq;								//フォント位置を保持する構造体変数
			SetRect ( &rectq,10,180,640,480);		//変数への位置セット
			//フォントの描画
			pFont -> DrawText(NULL,					//標準機能で描画
			_T("〔S〕キーでゲームが始まります!"),	//表示文字列
			-1,										//表示文字数
			&rectq,									//表示位置
			NULL,									//表示スタイル
			D3DCOLOR_ARGB(255,255,50,50));			//表示色


			/*//フォント1
			RECT rectcp;							//フォント位置を保持する構造体変数
			SetRect ( &rectcp,0,420,640,480);		//変数への位置セット
			//フォントの描画
			pFontg -> DrawText(NULL,				//標準機能で描画
			_T("Copyright(C)"),						//表示文字列
			-1,										//表示文字数
			&rectcp,								//表示位置
			NULL,									//表示スタイル
			D3DCOLOR_ARGB(255,255,50,50));			//表示色*/




		//----------------------
		//得点(最高得点)
		//---------------

			//フォント3
			RECT recth;								//フォント位置を保持する構造体変数
			SetRect ( &recth,400,10,640,480);		//変数への位置セット
			//フォントの描画
			pFontf -> DrawText(NULL,				//標準機能で描画
			_T("HI-SCORE"),							//表示文字列
			-1,										//表示文字数
			&recth,									//表示位置
			NULL,									//表示スタイル
			D3DCOLOR_ARGB(255,255,0,255));			//表示色

			//変数内容の表示
			TCHAR str_hi[255];
			_stprintf(str_hi,_T("%08d"),Hi_score);
			RECT rect_hi;
			SetRect(&rect_hi,420,30,640,480);
			pFontc->DrawText(NULL,str_hi,-1,&rect_hi,NULL,D3DCOLOR_ARGB(255,0,255,0));
			break;

		case 1://【ゲーム画面】

		//----------------------
		//得点(スコア)
		//---------------

			//フォント3
			RECT rectfc;							//フォント位置を保持する構造体変数
			SetRect ( &rectfc,370,0,640,480);		//変数への位置セット
			//フォントの描画
			pFontb -> DrawText(NULL,				//標準機能で描画
			_T("SCORE"),							//表示文字列
			-1,										//表示文字数
			&rectfc,								//表示位置
			NULL,									//表示スタイル
			D3DCOLOR_ARGB(255,0,255,255));			//表示色

			//変数内容の表示
			TCHAR str[255];
			_stprintf(str,_T("%08d"),score);
			RECT rect_ti;
			SetRect(&rect_ti,460,0,640,480);
			pFontd->DrawText(NULL,str,-1,&rect_ti,NULL,D3DCOLOR_RGBA(255,255,255,255));



			//フォント1
			RECT rect;								//フォント位置を保持する構造体変数
			SetRect ( &rect,0,4,640,480);			//変数への位置セット
			//フォントの描画
			pFont -> DrawText(NULL,					//標準機能で描画
			_T("LIFE"),								//表示文字列
			-1,										//表示文字数
			&rect,									//表示位置
			NULL,									//表示スタイル
			D3DCOLOR_ARGB(255,255,255,255));		//表示色

			//フォント1
			//変数内容の表示
			TCHAR str_la[255];
			_stprintf(str_la,_T("%d"),Life);
			RECT rect_la;
			SetRect(&rect_la,80,4,640,480);
			pFont->DrawText(NULL,str_la,-1,&rect_la,NULL,D3DCOLOR_ARGB(255,255,0,0));

			break;
		case 2://【ゲームクリア】

			//フォント2
			RECT rectb;								//フォント位置を保持する構造体変数
			SetRect ( &rectb,10,30,640,480);		//変数への位置セット
			//フォントの描画
			pFont -> DrawText(NULL,					//標準機能で描画
			_T("ゲームクリア画面です!"),			//表示文字列
			-1,										//表示文字数
			&rectb,									//表示位置
			NULL,									//表示スタイル
			D3DCOLOR_ARGB(255,255,255,255));		//表示色

			//フォント
			RECT recten;							//フォント位置を保持する構造体変数
			SetRect ( &recten,10,80,640,480);		//変数への位置セット
			//フォントの描画
			pFont -> DrawText(NULL,					//標準機能で描画
			_T("〔Enter←〕でタイトル画面に!"),	//表示文字列
			-1,										//表示文字数
			&recten,								//表示位置
			NULL,									//表示スタイル
			D3DCOLOR_ARGB(255,255,255,255));		//表示色

			break;
		case 3://【ゲームオーバー】

			//フォント2
			RECT rectc;								//フォント位置を保持する構造体変数
			SetRect ( &rectc,10,30,640,480);		//変数への位置セット
			//フォントの描画
			pFont -> DrawText(NULL,					//標準機能で描画
			_T("ゲームオーバー画面です!"),			//表示文字列
			-1,										//表示文字数
			&rectc,									//表示位置
			NULL,									//表示スタイル
			D3DCOLOR_ARGB(255,255,255,255));		//表示色

			//フォント
			RECT recten2;							//フォント位置を保持する構造体変数
			SetRect ( &recten2,10,80,640,480);		//変数への位置セット
			//フォントの描画
			pFont -> DrawText(NULL,					//標準機能で描画
			_T("〔Enter←〕でタイトル画面に!"),	//表示文字列
			-1,										//表示文字数
			&recten2,								//表示位置
			NULL,									//表示スタイル
			D3DCOLOR_ARGB(255,255,255,255));		//表示色

			break;
		case 4://
			break;
		}

        V( pd3dDevice->EndScene() );
    }
}


//--------------------------------------------------------------------------------------
// Handle messages to the application 
//--------------------------------------------------------------------------------------
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, 
                          bool* pbNoFurtherProcessing, void* pUserContext )
{
    return 0;
}


//--------------------------------------------------------------------------------------
// Release resources created in the OnResetDevice callback here 
//--------------------------------------------------------------------------------------
void CALLBACK OnLostDevice( void* pUserContext )
{
}


//--------------------------------------------------------------------------------------
// Release resources created in the OnCreateDevice callback here
//--------------------------------------------------------------------------------------
void CALLBACK OnDestroyDevice( void* pUserContext )
{
	//----------------------------------------------------------
	//ロードした後は、解放しましょう♪
	//-------------------------------------


	//テクスチャの解放
	SAFE_RELEASE(pTexture);//自機
	SAFE_RELEASE(pText_tama);//自機用の弾
	SAFE_RELEASE(pText_teki);//敵
	SAFE_RELEASE(pText_teta);//敵用の弾
	SAFE_RELEASE(pText_back);//背景
	//SAFE_RELEASE(pText_logo_a);//ロゴ001
	//SAFE_RELEASE(pText_life);//自機ライフ用

	//スプライトの解放
	SAFE_RELEASE(pSprite);

	//	フォントの解放
	SAFE_RELEASE( pFont );
	SAFE_RELEASE( pFonta );
	SAFE_RELEASE( pFontb );
	SAFE_RELEASE( pFontc );
	SAFE_RELEASE( pFontd );
	SAFE_RELEASE( pFonte );
	SAFE_RELEASE( pFontf );
	SAFE_RELEASE( pFontg );
	SAFE_RELEASE( pFonth );
}



//--------------------------------------------------------------------------------------
// Initialize everything and go into a render loop
//--------------------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
{
    // Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif

    // Set the callback functions
    DXUTSetCallbackDeviceCreated( OnCreateDevice );
    DXUTSetCallbackDeviceReset( OnResetDevice );
    DXUTSetCallbackDeviceLost( OnLostDevice );
    DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
    DXUTSetCallbackMsgProc( MsgProc );
    DXUTSetCallbackFrameRender( OnFrameRender );
    DXUTSetCallbackFrameMove( OnFrameMove );
   
    // TODO: Perform any application-level initialization here

    // Initialize DXUT and create the desired Win32 window and Direct3D device for the application
    DXUTInit( true, true, true ); // Parse the command line, handle the default hotkeys, and show msgboxes
    DXUTSetCursorSettings( true, true ); // Show the cursor and clip it when in full screen
    DXUTCreateWindow( L"EmptyProject" );
    DXUTCreateDevice( D3DADAPTER_DEFAULT, true, 640, 480);

	//スプライトの作成
	D3DXCreateSprite( DXUTGetD3DDevice(), &pSprite);


	//--------------------------------------------------------------------------------------
	//テクスチャのロード
	//------------------------------------------------------------------
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\jiki02.png"),&pTexture );//自機(画像)
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\tama01.png"),&pText_tama);//自機用の弾(画像)
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\teki001.png"),&pText_teki);//敵(画像)
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\tama04.png"),&pText_teta);//敵用の弾(画像)
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\back.png"),&pText_back);//背景(画像)
	//D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\"),&pText_icon);//宝箱(画像)
	//D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\logo001.png"),&pText_logo_a);//ロゴ001(画像)
	//D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\heart01.png"),&pText_life);//自機ライフ(画像)



	//--------------------------------------------------------------------------------------
	//フォントの作成  各パターン
	//----------------------------------------------------

	////フォントの作成0パターン)
		D3DXCreateFont(
			DXUTGetD3DDevice(),			//direct3Dデバイス
			22,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("ARP浪漫明朝体U"),	//フォント名
			&pFont);					//作成されたフォントが格納される変数

		//フォントの作成(Aパターン)
		D3DXCreateFont(
			DXUTGetD3DDevice(),			//direct3Dデバイス
			30,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("Broadway BT"),			//フォント名
			&pFonta);					//作成されたフォントが格納される変数

		//フォントの作成(Bパターン)
		D3DXCreateFont(	
			DXUTGetD3DDevice(),			//direct3Dデバイス
			23,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("HGep022"),				//フォント名
			&pFontb);					//作成されたフォントが格納される変数

		//フォントの作成(Cパターン)
		D3DXCreateFont(
			DXUTGetD3DDevice(),			//direct3Dデバイス	
			30,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("FancyBalloonsAlphabet"),			//フォント名
			&pFontc);					//作成されたフォントが格納される変数

		//フォントの作成(Dパターン)
		D3DXCreateFont(
			DXUTGetD3DDevice(),			//direct3Dデバイス
			30,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("BackSeatAlphabetWidth"),//フォント名
			&pFontd);					//作成されたフォントが格納される変数


		//フォントの作成(Eパターン)
		D3DXCreateFont(
			DXUTGetD3DDevice(),			//direct3Dデバイス
			30,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("D3 Cosmism"),			//フォント名
			&pFonte);					//作成されたフォントが格納される変数

		//フォントの作成(Fパターン)
		D3DXCreateFont(
			DXUTGetD3DDevice(),			//direct3Dデバイス
			23,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("SHOWA73ARegular"),			//フォント名
			&pFontf);					//作成されたフォントが格納される変数

		//フォントの作成(Gパターン)
		D3DXCreateFont(
			DXUTGetD3DDevice(),			//direct3Dデバイス
			20,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("富士ポップP"),			//フォント名
			&pFontg);					//作成されたフォントが格納される変数


		//フォントの作成(Hパターン)
		D3DXCreateFont(
			DXUTGetD3DDevice(),			//direct3Dデバイス
			23,							//フォントサイズ
			0,							//平均文字幅
			FW_NORMAL,					//太さ
			1,							//ミップマップレベル
			false,						//斜体フラグ
			DEFAULT_CHARSET,			//文字セット
			OUT_DEFAULT_PRECIS,			//精度
			DEFAULT_QUALITY,			//品質
			DEFAULT_PITCH,				//ピッチ
			_T("TAPEMAN"),			//フォント名
			&pFonth);					//作成されたフォントが格納される変数

		//次のフォント


	//--------------------------------------------------------------------------------------
	//1度しか実行しないもの
	//--------------------------------------------------

	//------------------------------------------------
	//自機の構造体に関する処理
	//-------------------------------
	for(i = 0;i < 1;i++)
	{
		myship[i].gPos.x = 280;
		myship[i].gPos.y = 420;
		myship[i].active = 1;
	}
	//------------------------------------------------
	//弾の構造体に関する処理
	//-------------------------------
	for(i = 0;i < BULLET_MAX;i++)
	{
		bullets[i].gPos_tm.x = 280;
		bullets[i].gPos_tm.y = 430;
		bullets[i].active = 0;
		bullets[i].type = 0;
	}
	//------------------------------------------------
	//敵の構造体に関する処理
	//-------------------------------
	for(i = 0;i < ENEMY_MAX;i++)
	{
		enemy[i].gPos_te.x = -80;
		enemy[i].gPos_te.y = 50;
		enemy[i].active_te = 0;
		enemy[i].type = 0;

		enemy_a[i].gPos.x = 690;
		enemy_a[i].gPos.y = 90;
		enemy_a[i].active = 0;
		enemy_a[i].type = 0;
	}
	enemy[0].active_te = 1;//一番最初の敵のフラグをONにする
	enemy_a[0].active = 1;
	//------------------------------------------------
	//敵の弾に関する処理
	//-------------------------------
	for(i = 0;i < ENEMY_BLT_MAX;i++)
	{
		enemy_blt[i].gPos.x = 280;
		enemy_blt[i].gPos.y = 430;
		enemy_blt[i].active = 0;
		enemy_blt[i].type = 0;
	}
	enemy_blt[0].active = 1;

	//------------------------------------------------
	//敵の弾に関する処理
	//-------------------------------
	for(i = 0;i < ENEMY_BLT_MAX;i++)
	{
		enemy_blt2[i].gPos.x = 280;
		enemy_blt2[i].gPos.y = 430;
		enemy_blt2[i].active = 0;
		enemy_blt2[i].type = 0;
	}
	enemy_blt2[0].active = 1;

	//--------------------------------------------------------------------------------------
	//初期化
	//-----------------------------
	bullets[i].gPos_tm = D3DXVECTOR3(280,430,0);
	score = 0;
	Hi_score = 12500;


    // Start the render loop
    DXUTMainLoop();

    // TODO: Perform any application-level cleanup here

    return DXUTGetExitCode();
}

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#50

投稿記事 by softya(ソフト屋) » 14年前

ソースはこれから見ますが、当初の締切は明日28日だった思いますが大丈夫でしょうか?
それと毎度同じ質問ですが、今の問題は何ですか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

STAR_HARUKI
記事: 36
登録日時: 14年前
住所: 新潟県新潟市
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#51

投稿記事 by STAR_HARUKI » 14年前

28日がGWで休みなので27日(本日)になりました。
連絡が遅くなってごめんなさい。
一応、ゲーム画面が出て、クリア・オーバーの画面に切り替わればα版としては成立するので、大丈夫だと思います。

問題は、弾なんですが、1つしか出していないのですが、
2つや3つ方向(角度を少し変えて)の表示の場合です。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#52

投稿記事 by softya(ソフト屋) » 14年前

STAR_HARUKI さんが書きました:28日がGWで休みなので27日(本日)になりました。
連絡が遅くなってごめんなさい。
一応、ゲーム画面が出て、クリア・オーバーの画面に切り替わればα版としては成立するので、大丈夫だと思います。

問題は、弾なんですが、1つしか出していないのですが、
2つや3つ方向(角度を少し変えて)の表示の場合です。
ソースを見る限り、こちらが前に指摘したことが直っていません。
こちらの指摘が分からないのであれば聞いてください。
直したいところも沢山ありますが、今のままだと指摘しても直ると思えません。

それと時間が取れるのであれば、龍神録をぜひ勉強してください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

STAR_HARUKI
記事: 36
登録日時: 14年前
住所: 新潟県新潟市
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#53

投稿記事 by STAR_HARUKI » 14年前

分からないところ


敵の再発生と敵の攻撃処理を兼用しないように。
それと enemy[j].active_te == 1だけが弾を発射すべきでは?
それと敵の弾の発射に制限がないこと。
この処理で、弾を一度にENEMY_BLT_MAX分同時発生させてます。
発生したらループを抜けるようにしたほうが良いです。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#54

投稿記事 by softya(ソフト屋) » 14年前

指摘の大半ですね。

・敵の再発生と敵の攻撃処理を兼用しないように。
下記の部分です。
敵が死んだら、すかさず敵のX座標をずらして再発生しています。
これは何のためですか? 少なくとも再発生が必要なら別の処理に分けてください。

コード:

                                        //弾が当たったら、フラグをOFFにする
                                        enemy[j].active_te = 0;
                                        bullets[i].active = 0;
                                        if(enemy_blt[j].gPos.y >= 640)//自機用の弾に当たっても敵用の弾は画面外に出るまでは消さない
                                        {
                                            enemy_blt[j].active = 0;
                                        }
                                        score += 100;//敵を倒すことが出来たら得点UP!
 
                                        if(enemy[j].active_te == 0) 
                                        {
                                            enemy[j].active_te = 1; ← ここで再発生してます。
                                            enemy[j].gPos_te.x = -100;
                                        }
・それと enemy[j].active_te == 1だけが弾を発射すべきでは?
それは、ここです。
敵が生きているのを確認せずに敵の弾を発生させておいて、なぜか敵が死んでいて640以上なら弾を消しています(これは無意味です)。
そもそも敵が死んでいたら弾を発生すべきではありません。

コード:

                if(enemy_blt[0].active == 0) ← この条件では敵が死んでいても発生します。
                {
                    enemy_blt[0].active = 1;//弾の表示
                    //敵の中央に表示させる
                    enemy_blt[i].gPos.x = enemy[j].gPos_te.x + 30;
                    enemy_blt[i].gPos.y = enemy[j].gPos_te.y + 20;
 
                    //敵が自機用の弾に当たって倒されたら
                    //これ以上敵用の弾が出ないようにする。
                    if(enemy[j].active_te == 0) ← ここで初めて死んでいるか確認。
                    {
                        if(enemy_blt[i].gPos.y >= 640)//敵用の弾が画面の外に出たら ← なぜ640以上なのでしょうか?
                        {
                            enemy_blt[i].active = 0;
                        }
                    }
                    break;
                }
・それと敵の弾の発射に制限がないこと。
・この処理で、弾を一度にENEMY_BLT_MAX分同時発生させてます。
・発生したらループを抜けるようにしたほうが良いです。
これらは同じ場所で上でも指摘した部分のループの問題です。

コード:

        for (int i = 0; i < ENEMY_BLT_MAX; i++) ← このループは必ず回ります。
        {
            for(int j = 0;j < ENEMY_MAX; j++) 
            {
                if(enemy_blt[0].active == 0) ← これはうまく動かないからenemy_blt[0]でねじ伏せたのでは?
                {
                    enemy_blt[0].active = 1;//弾の表示
                    //敵の中央に表示させる
                    enemy_blt[i].gPos.x = enemy[j].gPos_te.x + 30;
                    enemy_blt[i].gPos.y = enemy[j].gPos_te.y + 20;
 
                    //敵が自機用の弾に当たって倒されたら
                    //これ以上敵用の弾が出ないようにする。
                    if(enemy[j].active_te == 0)
                    {
                        if(enemy_blt[i].gPos.y >= 640)//敵用の弾が画面の外に出たら
                        {
                            enemy_blt[i].active = 0;
                        }
                    }
                    break; ← breakでは、for(int j = 0;j < ENEMY_MAX; j++)のループしか抜けないので、ENEMY_BLT_MAXのループは回ります。
                }
            }
        }
抜けるか弾の発生を止めるための方法を考えてください。弾の発生処理を関数化してbreakではなくreturnで抜けることも方法です。
あと毎フレーム連続で弾を発生させているんで弾の発生周期しだいですが、弾を発生させたら次の周期まで止めるカウントを敵の構造体内に持つ必要があります。

その他の問題
それと2つの敵の配列を持つぐらいなら、1つの配列で動くように工夫しないと後々困ることになります。
すでにこんがらかってきてますが。

結局同時に2つの敵を発生させるなら,、こう書いたほうがシンプルです。

コード:

#define ENEMY_MAX 2     //敵の最大数
   _enemy enemy[ENEMY_MAX];//敵構造体の宣言

        enemy[0].gPos_te.x = -80;
        enemy[0].gPos_te.y = 50;
        enemy[0].active_te = 1;
        enemy[0].type = 0;

        enemy[1].gPos_te.x = 690;
        enemy[1].gPos_te.y = 90;
        enemy[1].active_te = 1;
        enemy[1].type = 0;
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: シューティングゲームを作ろうとしていますが、なかなかうまくできません。

#55

投稿記事 by softya(ソフト屋) » 14年前

こちらで指摘点を直してみました。
最初の方にある
#include "DXUT.h"
は新しいDXUTに対応させるための物ですのでコメントアウトてください。

これを理解してもらえたら、次の段階に進めましょう。
・enemyとenemy_blt配列はひとつにマトメました。
・敵の弾の発射の問題点を修正。
・生存を必ず先に確認するようにしました。
・添字が間違っていたところを直しました。
・配列の添字を分かりやすくするためにi,j,kを止めました。

コード:

//--------------------------------------------------------------------------------------
// File: EmptyProject.cpp
//
// Empty starting point for new Direct3D applications
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
//古い文字列操作関数に対する警告を回避する
#pragma warning (disable : 4995)
#pragma warning (disable : 4996)

#include <stdio.h>
#include <tchar.h>

#include "DXUT.h"	/*新しいDXUTの対応用。古いDXUTでははずして下さい。*/
#include "dxstdafx.h"
#include "resource.h"

//---------------------------------------------
//プロトタイプ宣言
//-------------------------------

//---------------------------------------------
//その他のインクルード
//-------------------------------
#include "keycheck.h"


//---------------------------------------------
//その他のディファイン
//最大値とかを指定させる
//-------------------------------
/*自機用*/
#define MYSHIP 1            //自機の最大数
#define MYSHIP_SPEED 4      //自機用の移動速度
/*自機用の弾*/
#define BULLET_SPEED 11     //自機用弾の移動速度
#define BULLET_MAX 10       //弾の最大数
/*敵用*/
#define ENEMY_MAX 2     //敵の最大数
#define ENEMY_SPEED 3       //敵の動く最大速度
#define ENEMY_SPEED_B 4     //敵の動く最大速度パターンB
/*敵用の弾*/
#define ENEMY_BLT_MAX 20    //敵の弾の最大数
#define ENEMY_BLT_SPEED 6  //敵用弾の移動速度


//--------------------------------------------------------------------------------------
//関数
//-------------------------------
int gamemode = 0;//ゲームモード管理変数『0:タイトル 1:ゲーム画面 2:ゲームクリア 3:ゲームオーバー』
int times = 60,ti = 0,te = 0,ts = 0;//制限時間管理用変数
int count;//弾の発射数
int i;
int score;//得点
int Hi_score;//最高得点
int Life = 50;//体力


//--------------------------------------------------------------------------------------
//テクスチャ関数
//-------------------------------
LPDIRECT3DTEXTURE9      pTexture;//自機用
LPDIRECT3DTEXTURE9      pText_tama;//自弾用
LPDIRECT3DTEXTURE9      pText_teki;//敵用
LPDIRECT3DTEXTURE9      pText_teta;//敵弾用
LPDIRECT3DTEXTURE9      pText_icon;//アイテム用
LPDIRECT3DTEXTURE9      pText_back;//背景用
//LPDIRECT3DTEXTURE9        pText_logo_a;//ロゴ001用
LPDIRECT3DTEXTURE9      pText_life;//自機ライフ用


//スプライトの作成
LPD3DXSPRITE            pSprite;

//--------------------------------------------------------------------------------------
//座標関数
//-------------------------------
D3DXVECTOR3             gPos_map = D3DXVECTOR3(0,0,0);//背景画像用の画像指定位置
//D3DXVECTOR3               gPos_logo_a = D3DXVECTOR3(150,420,0);//ロゴ001画像用の画像指定位置


//--------------------------------------------------------------------------------------
//マトリクス
//-------------------------

D3DXMATRIX  matrix_ji;//自機
D3DXMATRIX  matrix_back;//背景
//D3DXMATRIX    matrix_logo_a;//ロゴ001


//---------------------------------------------
//自機の構造体 ※基本「0」で!
//---------------------------------
typedef struct _myship
{
	D3DXVECTOR3     gPos;//敵用の画像指定位置
	int             active;//有効フラグ 0:OFF 1:ON
	D3DXMATRIX      matrix;//行列
};

_myship myship[MYSHIP];//弾構造体の宣言

//---------------------------------------------
//弾の構造体
//------------------
typedef struct _bullet
{
	D3DXVECTOR3     gPos_tm;//自機弾用の画像指定位置
	int             active;//有効フラグ 0:OFF 1:ON
	int             type;//弾の種類
	D3DXMATRIX      matrix;//行列
};

_bullet bullets[BULLET_MAX];//弾構造体の宣言

//---------------------------------------------
//敵の構造体
//--------------------------
typedef struct _enemy
{
	D3DXVECTOR3     gPos_te;//敵の座標
	int             active_te;//有効フラグ 0:OFF 1:ON
	int				shot_wait;//発車待ち
	int             type;//敵の種類
	D3DXMATRIX      matrix_te;//敵の行列
};

_enemy enemy[ENEMY_MAX];//敵構造体の宣言

//---------------------------------------------
//敵の弾の構造体
//------------------
typedef struct _enemy_blt
{
	D3DXVECTOR3     gPos;//敵用の画像指定位置
	int             active;//有効フラグ 0:OFF 1:ON
	int             type;//弾の種類
	D3DXMATRIX      matrix;//行列
};

_enemy_blt enemy_blt[ENEMY_MAX][ENEMY_BLT_MAX];//弾構造体の宣言



//--------------------------------------------------------------------------------------
//フォント作成 変数宣言
//--------------------------------
LPD3DXFONT              pFont;///フォント0タイプ= ARP浪漫明朝体U》主に、[文字表示]など
LPD3DXFONT              pFonta;//フォントAタイプ=《Broadway BT》主に、[制限時間]など
LPD3DXFONT              pFontb;//フォントBタイプ=《HGep037》主に、[ステータス表示]など
LPD3DXFONT              pFontc;//フォントCタイプ=《FancyBalloonsAlphabet》主に、[最高得点]など
LPD3DXFONT              pFontd;//フォントDタイプ=《BackSeatAlphabetWidth》主に、[スコア(得点)]など
LPD3DXFONT              pFonte;//フォントEタイプ=《D3 Cosmism》主に、[時間]など
LPD3DXFONT              pFontf;//フォントFタイプ=《SHOWA73ARegular》主に、[タイトル画面文字]など
LPD3DXFONT              pFontg;//フォントGタイプ=《富士ポップP》主に、[その他 小さな文字]など
LPD3DXFONT              pFonth;//フォントHタイプ=《TAPEMAN》主に、[]など




//--------------------------------------------------------------------------------------
// Create any D3DPOOL_MANAGED resources here 
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{
	return S_OK;
}


//--------------------------------------------------------------------------------------
// Create any D3DPOOL_DEFAULT resources here 
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, 
							   const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{
	return S_OK;
}


//--------------------------------------------------------------------------------------
// Handle updates to the scene
//--------------------------------------------------------------------------------------
#ifdef DXUTD3D9	/*新しいDXUT対応のため*/
void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void* pUserContext )
#else
void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
#endif
{
	//  キー状態を調べる関数
	keycheck( );

	switch(gamemode)
	{
	case 0://【タイトル画面】
		if(gamemode == 0)
		{
			if(KEY_S == PUSH)//Sキーが押されたら下記の処理を実行!
			{
				gamemode = 1;//タイトル画面からゲーム画面へ
			}
		}

		//<matrix_te用=ロゴ001画像>
		//移動行列を作成
		//D3DXMatrixTranslation( &matrix_logo_a,0,0,0);

		break;
	case 1://【ゲーム画面】

		//--------------------------------------------------------------------------------------
		//自機を移動させる処理 (押された時、押しっぱなしになった時)
		//-------------------------------------------------------------------
		if(KEY_LEFT == PUSH || KEY_LEFT == HOLD)
		{
			myship[0].gPos.x -= MYSHIP_SPEED;
		}
		if(KEY_RIGHT == PUSH || KEY_RIGHT == HOLD)
		{
			myship[0].gPos.x += MYSHIP_SPEED;
		}
		if(KEY_UP == PUSH || KEY_UP == HOLD)
		{
			myship[0].gPos.y -= MYSHIP_SPEED;
		}
		if(KEY_DOWN == PUSH || KEY_DOWN == HOLD)
		{
			myship[0].gPos.y += MYSHIP_SPEED;
		}


		//--------------------------------------------------------------------------------------
		//自機の画像が
		//画面から消えないようにする
		//-------------------------------
		if(myship[0].gPos.x < 0)//画面の左
		{
			myship[0].gPos.x = 0;
		}
		if(myship[0].gPos.x >= 585)//画面の右
		{
			myship[0].gPos.x = 585;
		}
		if(myship[0].gPos.y < 0)//画面の上
		{
			myship[0].gPos.y = 0;
		}
		if(myship[0].gPos.y >= 425)//画面の下
		{
			myship[0].gPos.y = 425;
		}

		////////
		if(KEY_A == PUSH)
		{
			score += 1000;
		}



		//--------------------------------------------------------------------------------------
		//自弾の発射
		//----------------------------------
		if(KEY_SPACE == PUSH)//スペースキーが押されたら
		{
			for (int b = 0; b < BULLET_MAX; b++)
			{
				if(bullets[b].active == 0)
				{
					bullets[b].active = 1;//弾の表示
					//自機の中央に表示させる
					bullets[b].gPos_tm.x = myship[0].gPos.x + 29;
					bullets[b].gPos_tm.y = myship[0].gPos.y + 15;
					break;//処理を抜け出す
				}
			}
		}

		//--------------------------------------------------------------------------------------
		//自弾の移動
		//----------------------------------

		// for文で弾の数だけやる
		for(int b = 0;b < BULLET_MAX; b++)
		{
			if(bullets[b].active == 1)//弾が有効
			{
				switch(bullets[b].type)
				{
				case 0://
					// 弾の座標はbullet構造体の中に入れる
					bullets[b].gPos_tm.y -= BULLET_SPEED;//弾の座標を減らす
					if(bullets[b].gPos_tm.y < 0)
					{
						bullets[b].gPos_tm.y = myship[0].gPos.y;
						bullets[b].active = 0;
					}
					break;
				case 1://
					break;
				}
			}
		}

		//--------------------------------------------------------------------------------------
		//自機用の弾と敵の当たり判定
		//-------------------------------------------
		for(int b = 0;b < BULLET_MAX; b++)
		{
			if(bullets[b].active == 1)//弾がないのに当たり判定させないため
			{
				for(int em = 0;em < ENEMY_MAX;em++)
				{
					if( enemy[em].active_te == 1 )	//敵が有効
					{
						if(bullets[b].gPos_tm.x >= enemy[em].gPos_te.x)
						{
							if(bullets[b].gPos_tm.x <= enemy[em].gPos_te.x + 70)//画像の中心部が初期設定になっているので半分の値を代入
							{
								if(bullets[b].gPos_tm.y >= enemy[em].gPos_te.y)
								{
									if(bullets[b].gPos_tm.y <= enemy[em].gPos_te.y + 35)//画像の中心部が初期設定になっているので半分の値を代入
									{
										//弾が当たったら、フラグをOFFにする
										enemy[em].active_te = 0;
										bullets[b].active = 0;
										score += 100;//敵を倒すことが出来たら得点UP!
									}
								}
							}
						}
					}
				}
			}
		}


		//--------------------------------------------------------------------------------------
		//敵の再発生
		//-------------------------------------------
		
		for(int em = 0;em < ENEMY_MAX;em++)
		{
			if( enemy[em].active_te == 0 )	//敵が無効
			{
				enemy[em].active_te = 1;
				if( enemy[em].type==0 ) {
					enemy[em].gPos_te.x = -100;
				} else {
					enemy[em].gPos_te.x = 710;
				}
			}
		}
		
		
		//--------------------------------------------------------------------------------------
		//敵の動き
		//------------------------------------------

		//敵の動き
		for(int em = 0;em< ENEMY_MAX;em++)
		{
			if(enemy[em].active_te == 1)
			{
				if( enemy[em].type==0 ) {
					enemy[em].gPos_te.x += ENEMY_SPEED;
					if(enemy[em].gPos_te.x > 640)
					{
						enemy[em].gPos_te.x = -100;
					}
				} else {
					enemy[em].gPos_te.x -= ENEMY_SPEED_B;
					if(enemy[em].gPos_te.x < -70)
					{
						enemy[em].gPos_te.x = 680;
					}
				}

			}
		}

		//--------------------------------------------------------------------------------------
		//敵用弾の発射
		//-----------------------------------------

		for(int em = 0;em < ENEMY_MAX; em++)
		{
			if(enemy[em].active_te == 1)
			{
				//	弾の発射待ち?
				if( enemy[em].shot_wait > 0 ) {
					enemy[em].shot_wait--;//発射しない
				} else {
					for (int eb = 0; eb < ENEMY_BLT_MAX; eb++)
					{
						if(enemy_blt[em][eb].active == 0)//無効な弾
						{
							enemy_blt[em][eb].active = 1;//弾の表示
							//敵の中央に表示させる
							enemy_blt[em][eb].gPos.x = enemy[em].gPos_te.x + 30;
							enemy_blt[em][eb].gPos.y = enemy[em].gPos_te.y + 20;
							//敵の弾の発射を抑制
							enemy[em].shot_wait = 20;//発射を抑制するフレーム数
							break;
						}
					}
				}
			}
		}


		//--------------------------------------------------------------------------------------
		//敵用弾の移動
		//-----------------------------------------

		// for文で弾の数だけやる
		for(int em = 0;em < ENEMY_MAX; em++)
		{
			if(enemy[em].active_te == 1)
			{
				for (int eb = 0; eb < ENEMY_BLT_MAX; eb++)
				{
					if(enemy_blt[em][eb].active == 1)
					{
						switch(enemy_blt[em][eb].type)
						{
						case 0://
							// 弾の座標はbullet構造体の中に入れる
							enemy_blt[em][eb].gPos.y += ENEMY_BLT_SPEED;//弾の座標を増やす
							if(enemy_blt[em][eb].gPos.y > 640)
							{
								enemy_blt[em][eb].gPos.y = enemy[em].gPos_te.y;
								enemy_blt[em][eb].active = 0;
							}
							break;
						case 1://
							break;
					}
					}
				}
			}
		}

		//--------------------------------------------------------------------------------------
		//敵用の弾と自機の当たり判定
		//-----------------------------------------
		for(int eb = 0;eb < ENEMY_BLT_MAX;eb++)
		{
			for(int em = 0;em < ENEMY_MAX; em++)
			{
				if( enemy_blt[em][eb].active == 1)//有効な弾だけ
				{
					for(int j = 0;j < MYSHIP;j++)
					{
						if(myship[0].active == 1)//有効な自機
						{
							//自機に当たったら、敵用の弾と自機を消す
							if(enemy_blt[em][eb].gPos.x > myship[0].gPos.x + 5)
							{
								if(enemy_blt[em][eb].gPos.x < myship[0].gPos.x + 55)
								{
									if(enemy_blt[em][eb].gPos.y >  myship[0].gPos.y + 15)
									{
										if(enemy_blt[em][eb].gPos.y <  myship[0].gPos.y + 50)
										{
											enemy_blt[em][eb].active = 0;//敵用の弾を非表示
											Life -= 5;//自機の体力から一定の数値を引く
											if(Life <= 0)
											{
												gamemode = 3;
											}
										}
									}
								}
							}
						}
					}
				}
			}
		}

		//敵の弾が自機に当たって自機が消えたら今までの弾も非表示
		for(int eb = 0; eb < ENEMY_BLT_MAX;eb++)
		{
			for(int em = 0;em < ENEMY_MAX; em++)
			{
				if(myship[0].active == 0 && enemy_blt[em][eb].active == 0)
				{
					for(int b = 0;b < BULLET_MAX;b++)
					{
						bullets[b].active = 0;//弾を非表示
					}
				}
			}
		}


		//--------------------------------------------------------------------------------------
		//得点
		//---------------------------------------
		if(score > Hi_score)
		{
			Hi_score = score;
		}       


		//--------------------------------------------------------------------------------------
		//得点
		//---------------------------------------
		if(score >= 5000)//ある一定の得点を超えたらクリア画面にする
		{
			gamemode = 2;
		}


		//--------------------------------------------------------------------------------------
		//マトリクスを作成
		//---------------------------------------

		// for文で弾の数だけまとめてMatrix計算する
		for(int b = 0;b < BULLET_MAX; b++)
		{   
			//<matrix用=弾>
			//移動行列を作成
			D3DXMatrixTranslation( &bullets[b].matrix,bullets[b].gPos_tm.x,bullets[b].gPos_tm.y,0);
		}

		for(int i = 0;i < MYSHIP;i++)
		{
			//<matrix_ji用=自機>
			//移動行列を作成
			D3DXMatrixTranslation( &myship[i].matrix,myship[i].gPos.x,myship[i].gPos.y,0);
		}

		for(int em = 0;em < ENEMY_MAX; em++)
		{
			//<matrix_te用=敵>
			//移動行列を作成
			D3DXMatrixTranslation( &enemy[em].matrix_te,enemy[em].gPos_te.x,enemy[em].gPos_te.y,0);
		}


		//敵の弾を敵弾の数だけ
		for(int eb = 0;eb < ENEMY_BLT_MAX; eb++)
		{
			for(int em = 0;em < ENEMY_MAX; em++)
			{
				//<matrix_te用=敵>
				//移動行列を作成
				D3DXMatrixTranslation( &enemy_blt[em][eb].matrix,enemy_blt[em][eb].gPos.x,enemy_blt[em][eb].gPos.y,0);
			}
		}

		//背景画像も動かないようにMatrix関数で固定させる。
		//<matrix_te用=背景画像>
		//移動行列を作成
		D3DXMatrixTranslation( &matrix_back,0,0,0);


		break;
	case 2://【ゲームクリア画面】

		if(gamemode == 2)
		{
			score = 0;
			for(int em = 0;em < ENEMY_MAX;em++)
			{
				if(KEY_RETURN == PUSH)
				{
					//タイトル画面に戻す
					gamemode = 0;
					/*
					//初期設定に戻す
					//敵1
					enemy[em].gPos_te.x = -80;
					enemy[em].gPos_te.y = 50;
					//敵用の弾
					enemy_blt[em][eb].gPos.x = 280;
					enemy_blt[em][eb].gPos.y = 430;
					//自機
					myship[em].gPos.x = 280;
					myship[em].gPos.y = 420;
					*/
					//体力(ライフ)
					Life = 50;
				}
			}
		}
		break;
	case 3://【ゲームオーバー画面】
		if(gamemode == 3)
		{
			score = 0;
			for(int em = 0;em < ENEMY_MAX;em++)
			{
				if(KEY_RETURN == PUSH)
				{
					//タイトル画面に戻す
					gamemode = 0;
					/*
					//初期設定に戻す
					//敵1
					enemy[em].gPos_te.x = -80;
					enemy[em].gPos_te.y = 50;
					//敵用の弾
					enemy_blt[em][eb].gPos.x = 280;
					enemy_blt[em][eb].gPos.y = 430;
					//自機
					myship[em].gPos.x = 280;
					myship[em].gPos.y = 420;
					*/
					//体力(ライフ)
					Life = 50;
				}
			}
		}
		break;
	case 4://
		break;
	}

}


//--------------------------------------------------------------------------------------
// Render the scene 
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
	HRESULT hr;

	// Clear the render target and the zbuffer 
	V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 0, 128, 255), 1.0f, 0) );

	// Render the scene
	if( SUCCEEDED( pd3dDevice->BeginScene() ) )
	{
		//ここから描画処理を行う

		//スプライトの開始
		pSprite->Begin(D3DXSPRITE_ALPHABLEND);

		switch(gamemode)
		{
		case 0://【タイトル画面】
			/*//ロゴ001
			//テクスチャの表示領域
			RECT    rect_logo_a;
			SetRect(&rect_logo_a,0,0,640,480);
			//テクスチャの描画前に行列をセットする
			pSprite->SetTransform(&matrix_logo_a);
			//スプライトで2D描画=自機
			pSprite->Draw( pText_logo_a,&rect_logo_a,NULL,&gPos_logo_a,D3DCOLOR_ARGB(255,255,255,255));*/
			break;
		case 1://【ゲーム画面】

			//背景画像(1枚しかないので、if文で指定しない)
			//テクスチャの表示領域
			RECT    rect_back;
			SetRect(&rect_back,0,0,640,480);
			//テクスチャの描画前に行列をセットする
			pSprite->SetTransform(&matrix_back);
			//スプライトで2D描画=背景
			pSprite->Draw( pText_back,&rect_back,NULL,&gPos_map,D3DCOLOR_ARGB(255,255,255,255));


			for(int i = 0;i < MYSHIP;i++)
			{
				if(myship[i].active == 1)
				{
					//自機
					//テクスチャの表示領域
					RECT    rect_tex;
					SetRect(&rect_tex,0,0,60,60);
					//テクスチャの描画前に行列をセットする
					pSprite->SetTransform(&myship[i].matrix);
					//スプライトで2D描画=自機
					pSprite->Draw( pTexture,&rect_tex,NULL,NULL,D3DCOLOR_ARGB(255,255,255,255));
				}
			}
			for(int b = 0;b < BULLET_MAX; b++)
			{
				if(bullets[b].active == 1)
				{
					//弾
					//テクスチャの表示領域
					RECT    rect_tex_ta;
					SetRect(&rect_tex_ta,0,0,10,10);
					//テクスチャの描画前に行列にセットする
					pSprite->SetTransform(&bullets[b].matrix);
					//中心をセット
					D3DXVECTOR3 center_ta = D3DXVECTOR3(10.f / 2.f,10.f / 2.f,0.f);
					//スプライトで2D描画=弾
					pSprite->Draw( pText_tama,&rect_tex_ta,&center_ta,NULL,D3DCOLOR_ARGB(255,255,255,255));
				}
			}
			for(int em = 0;em < ENEMY_MAX; em++)
			{
				if( enemy[em].active_te == 1)
				{
					//敵
					//テクスチャの表示領域
					RECT    rect_tex_te;
					SetRect(&rect_tex_te,0,0,70,35);
					//テクスチャの描画前に行列にセットする
					pSprite->SetTransform(&enemy[em].matrix_te);
					//スプライトで2D描画=敵
					pSprite->Draw( pText_teki,&rect_tex_te,NULL,NULL,D3DCOLOR_ARGB(255,255,255,255));
				}
			}
			for(int eb = 0;eb < ENEMY_BLT_MAX; eb++)
			{
				for(int em = 0;em < ENEMY_MAX; em++)
				{
					if( enemy_blt[em][eb].active == 1)
					{
						//敵用の弾
						//テクスチャの表示領域
						RECT    rect_tex_teta;
						SetRect(&rect_tex_teta,0,0,12,12);
						//テクスチャの描画前に行列にセットする
						pSprite->SetTransform(&enemy_blt[em][eb].matrix);
						//スプライトで2D描画=敵の弾
						pSprite->Draw( pText_teta,&rect_tex_teta,NULL,NULL,D3DCOLOR_ARGB(255,255,255,255));
					}
				}
			}

			break;
		case 2://【ゲームクリア画面】
			break;
		case 3://【ゲームオーバー画面】
			break;
		case 4://
			break;
		}

		//スプライトの終了
		pSprite->End();


		switch(gamemode)
		{
		case 0://【タイトル画面】
			//========================================
			//各フォント
			//========================================

			//フォント1
			RECT rectf;                             //フォント位置を保持する構造体変数
			SetRect ( &rectf,10,100,640,480);       //変数への位置セット
			//フォントの描画
			pFont -> DrawText(NULL,                 //標準機能で描画
				_T("ここにタイトル画面が入ります\nタイトル画像やタイトル画面文字も表示!!"),//表示文字列
				-1,                                     //表示文字数
				&rectf,                                 //表示位置
				NULL,                                   //表示スタイル
				D3DCOLOR_ARGB(255,255,255,255));        //表示色


			//フォント1
			RECT rectq;                             //フォント位置を保持する構造体変数
			SetRect ( &rectq,10,180,640,480);       //変数への位置セット
			//フォントの描画
			pFont -> DrawText(NULL,                 //標準機能で描画
				_T("〔S〕キーでゲームが始まります!"), //表示文字列
				-1,                                     //表示文字数
				&rectq,                                 //表示位置
				NULL,                                   //表示スタイル
				D3DCOLOR_ARGB(255,255,50,50));          //表示色


			/*//フォント1
			RECT rectcp;                            //フォント位置を保持する構造体変数
			SetRect ( &rectcp,0,420,640,480);       //変数への位置セット
			//フォントの描画
			pFontg -> DrawText(NULL,                //標準機能で描画
			_T("Copyright(C)"),                     //表示文字列
			-1,                                     //表示文字数
			&rectcp,                                //表示位置
			NULL,                                   //表示スタイル
			D3DCOLOR_ARGB(255,255,50,50));          //表示色*/




			//----------------------
			//得点(最高得点)
			//---------------

			//フォント3
			RECT recth;                             //フォント位置を保持する構造体変数
			SetRect ( &recth,400,10,640,480);       //変数への位置セット
			//フォントの描画
			pFontf -> DrawText(NULL,                //標準機能で描画
				_T("HI-SCORE"),                         //表示文字列
				-1,                                     //表示文字数
				&recth,                                 //表示位置
				NULL,                                   //表示スタイル
				D3DCOLOR_ARGB(255,255,0,255));          //表示色

			//変数内容の表示
			TCHAR str_hi[255];
			_stprintf(str_hi,_T("%08d"),Hi_score);
			RECT rect_hi;
			SetRect(&rect_hi,420,30,640,480);
			pFontc->DrawText(NULL,str_hi,-1,&rect_hi,NULL,D3DCOLOR_ARGB(255,0,255,0));
			break;

		case 1://【ゲーム画面】

			//----------------------
			//得点(スコア)
			//---------------

			//フォント3
			RECT rectfc;                            //フォント位置を保持する構造体変数
			SetRect ( &rectfc,370,0,640,480);       //変数への位置セット
			//フォントの描画
			pFontb -> DrawText(NULL,                //標準機能で描画
				_T("SCORE"),                            //表示文字列
				-1,                                     //表示文字数
				&rectfc,                                //表示位置
				NULL,                                   //表示スタイル
				D3DCOLOR_ARGB(255,0,255,255));          //表示色

			//変数内容の表示
			TCHAR str[255];
			_stprintf(str,_T("%08d"),score);
			RECT rect_ti;
			SetRect(&rect_ti,460,0,640,480);
			pFontd->DrawText(NULL,str,-1,&rect_ti,NULL,D3DCOLOR_RGBA(255,255,255,255));



			//フォント1
			RECT rect;                              //フォント位置を保持する構造体変数
			SetRect ( &rect,0,4,640,480);           //変数への位置セット
			//フォントの描画
			pFont -> DrawText(NULL,                 //標準機能で描画
				_T("LIFE"),                             //表示文字列
				-1,                                     //表示文字数
				&rect,                                  //表示位置
				NULL,                                   //表示スタイル
				D3DCOLOR_ARGB(255,255,255,255));        //表示色

			//フォント1
			//変数内容の表示
			TCHAR str_la[255];
			_stprintf(str_la,_T("%d"),Life);
			RECT rect_la;
			SetRect(&rect_la,80,4,640,480);
			pFont->DrawText(NULL,str_la,-1,&rect_la,NULL,D3DCOLOR_ARGB(255,255,0,0));

			break;
		case 2://【ゲームクリア】

			//フォント2
			RECT rectb;                             //フォント位置を保持する構造体変数
			SetRect ( &rectb,10,30,640,480);        //変数への位置セット
			//フォントの描画
			pFont -> DrawText(NULL,                 //標準機能で描画
				_T("ゲームクリア画面です!"),            //表示文字列
				-1,                                     //表示文字数
				&rectb,                                 //表示位置
				NULL,                                   //表示スタイル
				D3DCOLOR_ARGB(255,255,255,255));        //表示色

			//フォント
			RECT recten;                            //フォント位置を保持する構造体変数
			SetRect ( &recten,10,80,640,480);       //変数への位置セット
			//フォントの描画
			pFont -> DrawText(NULL,                 //標準機能で描画
				_T("〔Enter←〕でタイトル画面に!"),    //表示文字列
				-1,                                     //表示文字数
				&recten,                                //表示位置
				NULL,                                   //表示スタイル
				D3DCOLOR_ARGB(255,255,255,255));        //表示色

			break;
		case 3://【ゲームオーバー】

			//フォント2
			RECT rectc;                             //フォント位置を保持する構造体変数
			SetRect ( &rectc,10,30,640,480);        //変数への位置セット
			//フォントの描画
			pFont -> DrawText(NULL,                 //標準機能で描画
				_T("ゲームオーバー画面です!"),         //表示文字列
				-1,                                     //表示文字数
				&rectc,                                 //表示位置
				NULL,                                   //表示スタイル
				D3DCOLOR_ARGB(255,255,255,255));        //表示色

			//フォント
			RECT recten2;                           //フォント位置を保持する構造体変数
			SetRect ( &recten2,10,80,640,480);      //変数への位置セット
			//フォントの描画
			pFont -> DrawText(NULL,                 //標準機能で描画
				_T("〔Enter←〕でタイトル画面に!"),    //表示文字列
				-1,                                     //表示文字数
				&recten2,                               //表示位置
				NULL,                                   //表示スタイル
				D3DCOLOR_ARGB(255,255,255,255));        //表示色

			break;
		case 4://
			break;
		}

		V( pd3dDevice->EndScene() );
	}
}


//--------------------------------------------------------------------------------------
// Handle messages to the application 
//--------------------------------------------------------------------------------------
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, 
						 bool* pbNoFurtherProcessing, void* pUserContext )
{
	return 0;
}


//--------------------------------------------------------------------------------------
// Release resources created in the OnResetDevice callback here 
//--------------------------------------------------------------------------------------
void CALLBACK OnLostDevice( void* pUserContext )
{
}


//--------------------------------------------------------------------------------------
// Release resources created in the OnCreateDevice callback here
//--------------------------------------------------------------------------------------
void CALLBACK OnDestroyDevice( void* pUserContext )
{
	//----------------------------------------------------------
	//ロードした後は、解放しましょう♪
	//-------------------------------------


	//テクスチャの解放
	SAFE_RELEASE(pTexture);//自機
	SAFE_RELEASE(pText_tama);//自機用の弾
	SAFE_RELEASE(pText_teki);//敵
	SAFE_RELEASE(pText_teta);//敵用の弾
	SAFE_RELEASE(pText_back);//背景
	//SAFE_RELEASE(pText_logo_a);//ロゴ001
	//SAFE_RELEASE(pText_life);//自機ライフ用

	//スプライトの解放
	SAFE_RELEASE(pSprite);

	//  フォントの解放
	SAFE_RELEASE( pFont );
	SAFE_RELEASE( pFonta );
	SAFE_RELEASE( pFontb );
	SAFE_RELEASE( pFontc );
	SAFE_RELEASE( pFontd );
	SAFE_RELEASE( pFonte );
	SAFE_RELEASE( pFontf );
	SAFE_RELEASE( pFontg );
	SAFE_RELEASE( pFonth );
}



//--------------------------------------------------------------------------------------
// Initialize everything and go into a render loop
//--------------------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
{
	// Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
	_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif

	// Set the callback functions
	DXUTSetCallbackDeviceCreated( OnCreateDevice );
	DXUTSetCallbackDeviceReset( OnResetDevice );
	DXUTSetCallbackDeviceLost( OnLostDevice );
	DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
	DXUTSetCallbackMsgProc( MsgProc );
	DXUTSetCallbackFrameRender( OnFrameRender );
	DXUTSetCallbackFrameMove( OnFrameMove );

	// TODO: Perform any application-level initialization here

#ifdef DXUTD3D9	/*新しいDXUT対応のため*/
	// Initialize DXUT and create the desired Win32 window and Direct3D device for the application
	DXUTInit( true, true ); // Parse the command line and show msgboxes
	DXUTSetHotkeyHandling( true, true, true );  // handle the default hotkeys
	DXUTSetCursorSettings( true, true ); // Show the cursor and clip it when in full screen
	DXUTCreateWindow( L"EmptyProject" );
	DXUTCreateDevice( true, 640, 480 );
#else
	// Initialize DXUT and create the desired Win32 window and Direct3D device for the application
	DXUTInit( true, true, true ); // Parse the command line, handle the default hotkeys, and show msgboxes
	DXUTSetCursorSettings( true, true ); // Show the cursor and clip it when in full screen
	DXUTCreateWindow( L"EmptyProject" );
	DXUTCreateDevice( D3DADAPTER_DEFAULT, true, 640, 480);
#endif

	//スプライトの作成
	D3DXCreateSprite( DXUTGetD3DDevice(), &pSprite);


	//--------------------------------------------------------------------------------------
	//テクスチャのロード
	//------------------------------------------------------------------
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\jiki02.png"),&pTexture );//自機(画像)
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\tama01.png"),&pText_tama);//自機用の弾(画像)
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\teki001.png"),&pText_teki);//敵(画像)
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\tama04.png"),&pText_teta);//敵用の弾(画像)
	D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\back.png"),&pText_back);//背景(画像)
	//D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\"),&pText_icon);//宝箱(画像)
	//D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\logo001.png"),&pText_logo_a);//ロゴ001(画像)
	//D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("image\\heart01.png"),&pText_life);//自機ライフ(画像)



	//--------------------------------------------------------------------------------------
	//フォントの作成  各パターン
	//----------------------------------------------------

	////フォントの作成0パターン)
	D3DXCreateFont(
		DXUTGetD3DDevice(),         //direct3Dデバイス
		22,                         //フォントサイズ
		0,                          //平均文字幅
		FW_NORMAL,                  //太さ
		1,                          //ミップマップレベル
		false,                      //斜体フラグ
		DEFAULT_CHARSET,            //文字セット
		OUT_DEFAULT_PRECIS,         //精度
		DEFAULT_QUALITY,            //品質
		DEFAULT_PITCH,              //ピッチ
		_T("ARP浪漫明朝体U"),  //フォント名
		&pFont);                    //作成されたフォントが格納される変数

	//フォントの作成(Aパターン)
	D3DXCreateFont(
		DXUTGetD3DDevice(),         //direct3Dデバイス
		30,                         //フォントサイズ
		0,                          //平均文字幅
		FW_NORMAL,                  //太さ
		1,                          //ミップマップレベル
		false,                      //斜体フラグ
		DEFAULT_CHARSET,            //文字セット
		OUT_DEFAULT_PRECIS,         //精度
		DEFAULT_QUALITY,            //品質
		DEFAULT_PITCH,              //ピッチ
		_T("Broadway BT"),          //フォント名
		&pFonta);                   //作成されたフォントが格納される変数

	//フォントの作成(Bパターン)
	D3DXCreateFont( 
		DXUTGetD3DDevice(),         //direct3Dデバイス
		23,                         //フォントサイズ
		0,                          //平均文字幅
		FW_NORMAL,                  //太さ
		1,                          //ミップマップレベル
		false,                      //斜体フラグ
		DEFAULT_CHARSET,            //文字セット
		OUT_DEFAULT_PRECIS,         //精度
		DEFAULT_QUALITY,            //品質
		DEFAULT_PITCH,              //ピッチ
		_T("HGep022"),              //フォント名
		&pFontb);                   //作成されたフォントが格納される変数

	//フォントの作成(Cパターン)
	D3DXCreateFont(
		DXUTGetD3DDevice(),         //direct3Dデバイス  
		30,                         //フォントサイズ
		0,                          //平均文字幅
		FW_NORMAL,                  //太さ
		1,                          //ミップマップレベル
		false,                      //斜体フラグ
		DEFAULT_CHARSET,            //文字セット
		OUT_DEFAULT_PRECIS,         //精度
		DEFAULT_QUALITY,            //品質
		DEFAULT_PITCH,              //ピッチ
		_T("FancyBalloonsAlphabet"),            //フォント名
		&pFontc);                   //作成されたフォントが格納される変数

	//フォントの作成(Dパターン)
	D3DXCreateFont(
		DXUTGetD3DDevice(),         //direct3Dデバイス
		30,                         //フォントサイズ
		0,                          //平均文字幅
		FW_NORMAL,                  //太さ
		1,                          //ミップマップレベル
		false,                      //斜体フラグ
		DEFAULT_CHARSET,            //文字セット
		OUT_DEFAULT_PRECIS,         //精度
		DEFAULT_QUALITY,            //品質
		DEFAULT_PITCH,              //ピッチ
		_T("BackSeatAlphabetWidth"),//フォント名
		&pFontd);                   //作成されたフォントが格納される変数


	//フォントの作成(Eパターン)
	D3DXCreateFont(
		DXUTGetD3DDevice(),         //direct3Dデバイス
		30,                         //フォントサイズ
		0,                          //平均文字幅
		FW_NORMAL,                  //太さ
		1,                          //ミップマップレベル
		false,                      //斜体フラグ
		DEFAULT_CHARSET,            //文字セット
		OUT_DEFAULT_PRECIS,         //精度
		DEFAULT_QUALITY,            //品質
		DEFAULT_PITCH,              //ピッチ
		_T("D3 Cosmism"),           //フォント名
		&pFonte);                   //作成されたフォントが格納される変数

	//フォントの作成(Fパターン)
	D3DXCreateFont(
		DXUTGetD3DDevice(),         //direct3Dデバイス
		23,                         //フォントサイズ
		0,                          //平均文字幅
		FW_NORMAL,                  //太さ
		1,                          //ミップマップレベル
		false,                      //斜体フラグ
		DEFAULT_CHARSET,            //文字セット
		OUT_DEFAULT_PRECIS,         //精度
		DEFAULT_QUALITY,            //品質
		DEFAULT_PITCH,              //ピッチ
		_T("SHOWA73ARegular"),          //フォント名
		&pFontf);                   //作成されたフォントが格納される変数

	//フォントの作成(Gパターン)
	D3DXCreateFont(
		DXUTGetD3DDevice(),         //direct3Dデバイス
		20,                         //フォントサイズ
		0,                          //平均文字幅
		FW_NORMAL,                  //太さ
		1,                          //ミップマップレベル
		false,                      //斜体フラグ
		DEFAULT_CHARSET,            //文字セット
		OUT_DEFAULT_PRECIS,         //精度
		DEFAULT_QUALITY,            //品質
		DEFAULT_PITCH,              //ピッチ
		_T("富士ポップP"),           //フォント名
		&pFontg);                   //作成されたフォントが格納される変数


	//フォントの作成(Hパターン)
	D3DXCreateFont(
		DXUTGetD3DDevice(),         //direct3Dデバイス
		23,                         //フォントサイズ
		0,                          //平均文字幅
		FW_NORMAL,                  //太さ
		1,                          //ミップマップレベル
		false,                      //斜体フラグ
		DEFAULT_CHARSET,            //文字セット
		OUT_DEFAULT_PRECIS,         //精度
		DEFAULT_QUALITY,            //品質
		DEFAULT_PITCH,              //ピッチ
		_T("TAPEMAN"),          //フォント名
		&pFonth);                   //作成されたフォントが格納される変数

	//次のフォント


	//--------------------------------------------------------------------------------------
	//1度しか実行しないもの
	//--------------------------------------------------

	//------------------------------------------------
	//自機の構造体に関する処理
	//-------------------------------
	for(i = 0;i < MYSHIP;i++)
	{
		myship[i].gPos.x = 280;
		myship[i].gPos.y = 420;
		myship[i].active = 1;
	}
	//------------------------------------------------
	//弾の構造体に関する処理
	//-------------------------------
	for(int b = 0;b < BULLET_MAX;b++)
	{
		bullets[b].gPos_tm.x = 280;
		bullets[b].gPos_tm.y = 430;
		bullets[b].active = 0;
		bullets[b].type = 0;
	}
	//------------------------------------------------
	//敵の構造体に関する処理
	//-------------------------------
	enemy[0].gPos_te.x = -80;
	enemy[0].gPos_te.y = 50;
	enemy[0].active_te = 1;
	enemy[1].shot_wait = 0;
	enemy[0].type = 0;

	enemy[1].gPos_te.x = 690;
	enemy[1].gPos_te.y = 90;
	enemy[1].active_te = 1;
	enemy[1].shot_wait = 0;
	enemy[1].type = 1;

	//------------------------------------------------
	//敵の弾に関する処理
	//-------------------------------
	for(int eb = 0;eb < ENEMY_BLT_MAX;eb++)
	{
		for(int em = 0;em < ENEMY_MAX; em++)
		{
			enemy_blt[em][eb].gPos.x = 280;
			enemy_blt[em][eb].gPos.y = 430;
			enemy_blt[em][eb].active = 0;
			enemy_blt[em][eb].type = 0;
		}
	}


	//--------------------------------------------------------------------------------------
	//初期化
	//-----------------------------
	bullets[i].gPos_tm = D3DXVECTOR3(280,430,0);
	score = 0;
	Hi_score = 12500;


	// Start the render loop
	DXUTMainLoop();

	// TODO: Perform any application-level cleanup here

	return DXUTGetExitCode();
}
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

閉鎖

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