進級製作で苦戦しています

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

進級製作で苦戦しています

#1

投稿記事 by 円香 » 18年前

初めまして、こんにちは。
実は、進級製作でドンキーコングを作っているのですが、
マリオを動かすプログラムがよくわからないので、どなたか教えていただけないでしょうか?

とりあえず、一枚の画像で動くようにはしたのですが、走っているときは走っている画像、
止まっているときは止まっている画像、はしごを上っているときは上っている画像といったようにしたいんですが・・・。

よろしくお願いします。

今のところ、プログラムはこんな感じです。


#pragma warning(disable : 4995) // 警告除去
#include <tchar.h>
#include "dxstdafx.h"

// 関数プロトタイプ宣言
void CALLBACK FrameRender( LPDIRECT3DDEVICE9 pd3dDevice , double fTime , float fElapsedTime ); // 関数を作成
void CALLBACK FrameMove( LPDIRECT3DDEVICE9 pd3dDevice , double fTime , float fElapsedTime );
void CALLBACK DeviceDestroyed( void ); // デバイス削除時
void CALLBACK DeviceLost( void ); // デバイス消失時

// グローバル関数
LPDIRECT3DTEXTURE9 pTexture; // テクスチャへのポインタ
LPDIRECT3DTEXTURE9 pTexture2;
LPDIRECT3DTEXTURE9 pTexture3;
LPDIRECT3DTEXTURE9 pTexture4;
LPDIRECT3DTEXTURE9 pTexture5;
LPD3DXSPRITE pSprite; // スプライトへのポインタ
LPD3DXFONT pFont; // フォントオブジェクト
D3DXVECTOR3 pos = D3DXVECTOR3(200,200,0);
D3DXVECTOR3 dpos = D3DXVECTOR3(40,-13,0);
D3DXVECTOR3 tpos = D3DXVECTOR3(20,51,0);
D3DXVECTOR3 ppos = D3DXVECTOR3(160,35,0);

// メイン関数
int APIENTRY _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
DXUTSetCallbackFrameRender( FrameRender ); // コールバック関数の登録 (描画関数)
DXUTSetCallbackFrameMove( FrameMove ); // (更新関数)
DXUTSetCallbackDeviceDestroyed( DeviceDestroyed ); // (削除時関数)
DXUTSetCallbackDeviceLost( DeviceLost ); // (消失時関数)

DXUTInit();
DXUTCreateWindow(_T("DirectX 9.0 Graphice Sample05"));
DXUTCreateDevice(D3DADAPTER_DEFAULT, true, 512, 450);

D3DXCreateSprite( DXUTGetD3DDevice(), &pSprite );
D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("stage1.bmp"), &pTexture ); // テクスチャのロード
D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("mario_1.png"), &pTexture2 );
D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("donkey_1.png"), &pTexture3 );
D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("taru-s.png"), &pTexture4 );
D3DXCreateTextureFromFile( DXUTGetD3DDevice(), _T("peach_1.png"), &pTexture5 );
DXUTMainLoop();

return DXUTGetExitCode();
}
// 描画用コールバック関数
void CALLBACK FrameRender( LPDIRECT3DDEVICE9 pd3dDevice , double fTime , float fElapsedTime )
{
pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0); // クリアと背景色
DXUTGetD3DDevice()->BeginScene(); // シーンの開始
pSprite->Begin( D3DXSPRITE_ALPHABLEND ); // スプライトの開始
D3DXVECTOR3 center = D3DXVECTOR3(0,3,0); // 中心位置の指定

//  
pSprite->Draw( pTexture, NULL, center, NULL, D3DCOLOR_ARGB(255,255,255,255));
pSprite->Draw( pTexture2, NULL, NULL, &pos, D3DCOLOR_ARGB(255,255,255,255));
pSprite->Draw( pTexture3, NULL, NULL, &dpos, D3DCOLOR_ARGB(255,255,255,255));
pSprite->Draw( pTexture4, NULL, NULL, &tpos, D3DCOLOR_ARGB(255,255,255,255));
pSprite->Draw( pTexture5, NULL, NULL, &ppos, D3DCOLOR_ARGB(255,255,255,255));
pSprite->End(); // スプライトの終了
DXUTGetD3DDevice()->EndScene(); // シーンの終了
}

// 更新用コールバック関数
void CALLBACK FrameMove( LPDIRECT3DDEVICE9 pd3dDevice , double fTime , float fElapsedTime )
{
if( DXUTIsKeyDown( VK_RIGHT ) ){
pos.x += fElapsedTime*100.0f; // x座標を1秒間に100増やす
}
if( DXUTIsKeyDown( VK_LEFT ) ){
pos.x -= fElapsedTime*100.0f;
}
if( DXUTIsKeyDown( VK_UP ) ){
pos.y -= fElapsedTime*100.0f;
}
if( DXUTIsKeyDown( VK_DOWN ) ){
pos.y += fElapsedTime*100.0f;
}
}

// デバイス削除時コールバック関数
void CALLBACK DeviceDestroyed( void )
{
SAFE_RELEASE(pTexture); // テクスチャの解放
SAFE_RELEASE(pTexture2);
SAFE_RELEASE(pTexture3);
SAFE_RELEASE(pTexture4);
SAFE_RELEASE(pTexture5);
SAFE_RELEASE(pSprite); // スプライトの解放
}

// デバイスの消失時コールバック関数
void CALLBACK DeviceLost( void )
{
pSprite->OnLostDevice(); // テクスチャの復旧
}

管理人

Re:進級製作で苦戦しています

#2

投稿記事 by 管理人 » 18年前

こんにちは。これはDirect3Dでしょうか?

Direct3Dは使ったこと無いので詳しくわかりませんが、とりあえず、走っている時は入力を受けているときなんですから、

例えば右・左ボタンを押しているときで、地面の上にいるときは、走る画像。

地面から離れているときはジャンプ中の画像。

という感じでプログラムしたらいいんではないのでしょうか?

歩く距離をカウントするカウンターを用意して、5カウント走ったら次の画像、5カウント走ったら次の画像を表示させて結果的に走るモーションを描いてはどうでしょうか?

ゲームプログラミングの館に歩くモーションの作り方が書いてあります。

ソースコードは初心者にとにかく解りやすく書いたもので、構造化やスマートになど一切気にしていない書き方なので、

考え方を理解した上で色々アレンジして書いてみてはいかがでしょうか?

ジャンプアクションや玉の発射、はねかえりなども

ゲームプログラミングの館で若干説明しておりますので参考にしてみてください。

マリオのファイヤ発射などはシューティングのように玉を制御すればいいように思います。

参考にならなかったらすみません。

管理人

Re:進級製作で苦戦しています

#3

投稿記事 by 管理人 » 18年前

即席でこんな感じ作ってみました。

ゲームプログラミングの館の環境でコンパイルしてみてください。
#include "DxLib.h"

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
	int image[24],x=640/2,y=480/2;//分割して保存するためのimage,描画する座標を示すx,y
	int graph_img;											 //その時表示すべき画像ハンドルを格納する変数
	char Key[256];											 //キーボードデータを格納するKey配列
	ChangeWindowMode( TRUE ) ;								 // ウインドウモードに変更
	if( DxLib_Init() == -1 ) return -1;						//DXライブラリ初期化 エラーが起きたら終了 
	SetDrawScreen( DX_SCREEN_BACK ) ;						  //描画先を裏画面に設定
	LoadDivGraph( "char.png" , 24 , 6 , 4 , 24 , 32 , image ) ;//画像を分割してimage配列に保存
	while(1){
		int xx[4]={7,6,7,8};
		char xpush;
		xpush=1;
		ClearDrawScreen();									 //裏画面のデータを全て削除
		GetHitKeyStateAll( Key ) ;							 //すべてのキーの状態を得る
		if( Key[ KEY_INPUT_RIGHT ]  == 1 )				   //右ボタンが押されたら
			x++ ;											  //xの値を1増やす
		else if( Key[ KEY_INPUT_LEFT ]  == 1 )					 //右ボタンが押されたら
			x-- ; //xの値を1増やす
		else//キーが押されてなかったら
			xpush=0;//キーが押されてないよ

		for(int i=0;i<4;i++)
			if(x%32>= i*8 && x%32< 8*(i+1))//32ピクセルで4つの画像をループ
				graph_img=image[xx];
		
		if(xpush==0)//キーが押されてなかったら
			graph_img=image[7];//たっている画像

		if( Key[ KEY_INPUT_ESCAPE ]  == 1 ) break ;			 //ESCボタンで終了
		if( ProcessMessage() == -1 ) break ;					//エラーが起きたら終了
		DrawGraph( x , y , graph_img , FALSE ) ;				//画像を描画
		ScreenFlip() ;										  //裏画面データを表画面へ反映
	}
	DxLib_End() ;											   // DXライブラリ使用の終了処理
	return 0 ;												  // ソフトの終了
}


考え方は無数にあるので、この考え方でなくてももちろんいいと思います。
これは今いる座標32ピクセル毎に4つの画像をループして表示しています。
何も入力が無かったらたっている画像を表示します。

左右に動きますが、左は向きません。

マリオの場合は、カウンタを用意した方がよいと思います。
走っていると座標は同じだけど背景が動いているために走っているようにみせるってことが多いでしょうから。

入力を受け付け始めて特定カウントたつと、走る画像をループして表示するようにしてみてください。

バグ

Re:進級製作で苦戦しています

#4

投稿記事 by バグ » 18年前

ドンキーコングとは懐かしい…
私の記憶にあるオリジナルのドンキーコングに登場したマリオの動きは、管理人さんの言うようにカウンタを持たせてアニメーションさせているように見える動きをしていたと思います。

横方向キーをチョン押しするとスプライトが1ドットスライドしてグラフィックが切り替わってそのままになっていたはずなので、間違いないんじゃないかな?

ジャンプは空中制御のできないタイプなので、納得のいく軌道さえ作れば問題ないでしょうし…あ、壁に向かってジャンプしたら、横方向の移動量の正負が反転して跳ね返ってきてたんで、これは画面外へのはみ出し防止処理かな?

それから、ハシゴ移動中は完全に登りきるか、降りきってしまうまでは上下移動しかできなかったはずなので、やられ判定を処理しつつ、上下以外のキー入力を受け付けなければできそうですね。

管理人

Re:進級製作で苦戦しています

#5

投稿記事 by 管理人 » 18年前

あ、すみません、ドンキーコングとマリオって知りません・・・。

スーパードンキーコングってマリオの出てこない奴か、スーパーマリオブラザーズってマリオとルイジーしか出てこないやつどっちかしかやったことないので、

想像しているゲームとは違うのかも・・。

管理人

Re:進級製作で苦戦しています

#6

投稿記事 by 管理人 » 18年前

もしかしてこれですか??

http://qtchicks.hp.infoseek.co.jp/dk.html

このゲームは見たこと無い;
1981年って生まれる3年前だ^^;

バグ

Re:進級製作で苦戦しています

#7

投稿記事 by バグ » 18年前

>>管理人さん
それです(笑)
ちなみに、ファミコン版はステージが1つ削られてます。
1ではドンキーコングにさらわれたレディをマリオが助けにいくというシナリオだったのですが、2作目のドンキーコングJrでは、ドンキーコングの息子が主人公になり、マリオにとらわれた親を助けに行くというストーリーになっています。はい、マリオが悪役になってます(笑)

ちなみに、ドンキーコング3というのもありますが、これはあまり知られていないみたいで、知っている人が少ないです。結構面白かったんですけどね。ちなみに3にはマリオは出てこなかったはずです。

管理人

Re:進級製作で苦戦しています

#8

投稿記事 by 管理人 » 18年前

>マリオが悪役になってます

えぇ~!マリオって主人公のイメージが^^;
ドンキーもマリオも最初は同じゲームに登場してたんですねぇ。

閉鎖

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