ボスを残像させる方法2

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

ボスを残像させる方法2

#1

投稿記事 by kai » 16年前

何度もすみません。
http://www.play21.jp/board/formz.cgi?ac ... &rln=39828
の続きなんですが
struct.h内に追加

typedef struct{
	int PlayerX[ AFTIMAGENUM ], PlayerY[ AFTIMAGENUM ] ;
}boss_t;


graph.cpp内変更

#define AFTIMAGENUM	65;
for(i = AFTIMAGENUM - 1 ; i >= 0 ; i -= 8 ){
	SetDrawBlendMode( DX_BLENDMODE_ALPHA, 255 - 255 * i / AFTIMAGENUM) ;//αブレンドする
	DrawRotaGraphFdF(boss.PlayerX,boss.PlayerY,//ボスを描画
		1.0f,0.0f,img_dot_boss01[0],TRUE);
	SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 0 );//ブレンドモードをリセットする。
}
// 残像データを一つづつずらす
for( i = AFTIMAGENUM - 1 ; i > 0 ; i -- ){
	boss.PlayerX = boss.PlayerX[i-1] ;
	boss.PlayerY = boss.PlayerY[i-1] ;
}

と修正してみたのですが、これでも残像できなかったのですが
どこが原因で残像できなくて困ってます。どうしたらできるかアドバイス再びお願いします・・

Justy

Re:ボスを残像させる方法2

#2

投稿記事 by Justy » 16年前


>どこが原因で残像できなくて困ってます

 どううまくいっていないのかわかりませんが、
ボスの最新座標(現在の座標)はどこに入っていますか?

softya

Re:ボスを残像させる方法2

#3

投稿記事 by softya » 16年前

まず、問題点の調べ方を教えます。
1.boss.PlayerX[0]とかちゃんと表示できる座標になっているか確認してください。
2.同様にboss.PlayerY[0]についても調べます。
3.さらに[1]~[3]あたりまで調べてみましょう。

質問です。boss.PlayerX[0]とboss.PlayerY[0]は、正しい値でしたか?
正しく無い場合は、原因は何だと思いますか?
[1]~[3]の値は正しいですか?
boss.PlayerX[0]とboss.PlayerX[AFTIMAGENUM-1]では、どちらが元の位置に近い残像でしょうか?

ちなみにboss.PlayerX,Yは意味的にかなり変なので、
boss.ImageX,Yあたりに変更する事をお勧めします。

kai

Re:ボスを残像させる方法2

#4

投稿記事 by kai » 16年前

ボスの最新座標はboss_shot.cpp内のcalc_boss()に
int i;
// キャラクターの位置をセット
for( i = 0 ; i < AFTIMAGENUM ; i ++ ){
boss.PlayerX=int(boss.x);
boss.PlayerY=int(boss.y);
}
と入れてるのですが、これだと
上下に動くものボス+動かないボスが表示されるだけで困ってます。(薄くもなってません)
ましてや左右の移動は残像していません・・

softya

Re:ボスを残像させる方法2

#5

投稿記事 by softya » 16年前

すいません質問の答えになっていません。

(1)質問です。boss.PlayerX[0]とboss.PlayerY[0]は、正しい値でしたか?
(2)正しく無い場合は、原因は何だと思いますか?
(3)[1]~[3]の値は正しいですか?
(4)boss.PlayerX[0]とboss.PlayerX[AFTIMAGENUM-1]では、どちらが元の位置に近い残像でしょうか?
にそれぞれお答えください。値も書いてくださいね。
ここをちゃんと理解しないと残像は作れませんよ。

kai

Re:ボスを残像させる方法2

#6

投稿記事 by kai » 16年前

すみません。No:40331はJustyさんに対しての回答です。
>softyaさん
(1)boss.PlayerX[0]とboss.PlayerY[0]の値の調べ方が分からないのですが
 具体的にどうすればいいのでしょうか?
 またboss.PlayerX[0]とboss.PlayerY[0]というプラグラムを使ってないのですが
 使えということでしょうか?

Justy

Re:ボスを残像させる方法2

#7

投稿記事 by Justy » 16年前


>calc_boss()に~と入れてるのですが

 boss.PlayerXや boss.PlayerYの役割は「過去の座標の履歴」です。

 ですがこれは、配列全体を最新のボスの座標で塗りつぶしてしまっていますね。

 これを行うのは最初の1回目としては初期化と考えればわかるのですが、
2回目以降もこの処理を行っているとすれば、この配列は「過去の座標の履歴」にならず、
「残像データを一つずつずらす」処理も全く意味のないものになってしまいます。

 残像データを一つずつずら」しているのは AFTIMAGENUM+1フレーム前の座標を忘れ、
新しい最新の座標を受け入れる為の処理です。

 その上で softyaさんの質問 (4)に関連しますが、ボスの最新の座標を毎フレーム
配列のどこか1カ所に入れれば「過去の座標の履歴」は完成します。

softya

Re:ボスを残像させる方法2

#8

投稿記事 by softya » 15年前

>(1)boss.PlayerX[0]とboss.PlayerY[0]の値の調べ方が分からないのですが
> 具体的にどうすればいいのでしょうか?

デバッガで変数の値を調べる事ができます。
実行中のプログラムを目的の場所で止めるにはブレークポイントを使います。
下記サイトを参考にしてください。
たぶん、VC6.0用の説明なので、分からないところがあれば聞いてください。
http://www.nitoyon.com/vc/tutorial/debug/

あるいは、下記のようなコードを埋め込む事でVisualStudioの出力ウィンドウに変数の内容を表示することが出来ます。
{
	TCHAR strbuf[256];
	sprintf( strbuf, _T("boss.PlayerX[0]=%d boss.PlayerY[0]=%d\n"), boss.PlayerX[0], boss.PlayerY[0] );
	OutputDebugString( strbuf );
}

> またboss.PlayerX[0]とboss.PlayerY[0]というプラグラムを使ってないのですが
> 使えということでしょうか?

Justyさんの解説にもありますが、配列をうまく使わないと残像を作り出す事は出来ません。
そもそも残像ってどういう仕組みなんだって根本の話になりますので、前回の質問の回答をよく読みなおしてみてください。
あるいは、理解しやすくするために、もっとシンプルにして1つ前の位置の残像だけだすプログラムを作ってみるのも一つの手です(配列は使いません)。

Tatu

Re:ボスを残像させる方法2

#9

投稿記事 by Tatu » 15年前

サンプルコードを作ってみたので参考にしてみてください。

#include "DxLib.h"

char stateKey[256];//キーがおされているかを格納する配列

//キャラの構造体
typedef struct{
	//座標と速度
	int x,y,vx,vy;
}ch_t;

//残像用の構造体
typedef struct{
	//座標
	int x,y;
}zanzou_t;

int i;//for文カウンタ用変数
int img_ch;//キャラの画像変数
int func_state;//状態変数 0:初期化 1:通常処理
ch_t ch;//キャラ
zanzou_t zanzou[64];//64個の残像
int color;//色変数

//ループで必ず行う3大処理
int ProcessLoop(){
	if(ProcessMessage()!=0)return -1;//プロセス処理がエラーなら-1を返す
	if(ClearDrawScreen()!=0)return -1;//画面クリア処理がエラーなら-1を返す
	GetHitKeyStateAll(stateKey);//現在のキー入力処理を行う
	return 0;
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){
	ChangeWindowMode(TRUE);//ウィンドウモード
	if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化

	while(ProcessLoop()==0){//メインループ
		//初期化
		if(func_state==0){
			//画像読み込み(画像は自分で用意してください)
			img_ch=LoadGraph("ch.png");
			//白色の用意
			color=GetColor(255,255,255);
			//キャラの位置初期化
			//グローバル変数は自動的に0になるため速度は書かなくてよい
			ch.x=320;
			ch.y=240;
			//残像の初期化
			for(i=0;i<64;i++){
				zanzou.x=ch.x;
				zanzou.y=ch.y;
			}
			//以降は通常処理へ
			func_state=1;
		}
		//通常処理
		else{
			//矢印キーによりキャラの速度を変化させる
			if(stateKey[KEY_INPUT_RIGHT]){
				ch.vx++;
			}
			if(stateKey[KEY_INPUT_DOWN]){
				ch.vy++;
			}
			if(stateKey[KEY_INPUT_LEFT]){
				ch.vx--;
			}
			if(stateKey[KEY_INPUT_UP]){
				ch.vy--;
			}
			//速度が大きすぎるときは小さくする
			if(ch.vx<-640) ch.vx=-640;
			if(ch.vx>640) ch.vx=640;
			if(ch.vy<-480) ch.vy=-480;
			if(ch.vy>480) ch.vy=480;
			//移動させる
			ch.x+=ch.vx;
			ch.y+=ch.vy;
			//画面枠を超えたら画面の反対に移動させる
			if(ch.x<0) ch.x+=640;
			if(ch.x>640) ch.x-=640;
			if(ch.y<0) ch.y+=480;
			if(ch.y>480) ch.y-=480;
			//残像を動かす
			//添え字が小さいほど後ろ側にある
			//この処理は前(キャラ)側から引っ張るのではなく、
			//後ろから押すような感じ
			for(i=0;i<63;i++){
				zanzou.x=zanzou[i+1].x;
				zanzou.y=zanzou[i+1].y;
			}
			//いちばん前の残像はキャラの位置に合わせる
			zanzou[63].x=ch.x;
			zanzou[63].y=ch.y;
			//アルファブレンドモードにセット
			SetDrawBlendMode(DX_BLENDMODE_ALPHA,32);
			//残像を描画
			for(i=0;i<64;i++){
				DrawRotaGraph(zanzou.x,zanzou.y,1,0,img_ch,TRUE);
			}
			//描画モードを元に戻す
			SetDrawBlendMode(DX_BLENDMODE_NOBLEND,0);
			//キャラを描画
			DrawRotaGraph(ch.x,ch.y,1,0,img_ch,TRUE);
			//キャラの速度を表示する
			DrawFormatString(0,0,color,"vx=%d",ch.vx);
			DrawFormatString(0,16,color,"vy=%d",ch.vy);
		}
		if(stateKey[KEY_INPUT_ESCAPE])break;//エスケープが入力されたらブレイク
		ScreenFlip();//裏画面反映

	}
	DxLib_End();//DXライブラリ終了処理
	return 0;
}

閉鎖

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