反射レーザーのアルゴリズムについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
KEYONN_
記事: 70
登録日時: 13年前

反射レーザーのアルゴリズムについて

#1

投稿記事 by KEYONN_ » 12年前

DXライブラリとC++で横スクロールSTGを作っています。
そこで、R-TYPEのような、反射レーザーのアルゴリズムを教えて頂きたい
のです。

現在のソースコードはこんな感じです。

コード:

void DrawAndMoveShot()
{
	int i;

	for(i=0;i<100;i++)
	{
		if(T[i].flag==1)
		{
			if(T[i].syurui ==0)
			{
				if(T[i].kind==0) T[i].x+=5;
				else{
					if(Map[2][(int)(T[i].y/16)][(int)(T[i].x/16)]==0)
					{
						T[i].vy*=-1;
					}
					T[i].x+=T[i].vx;
					T[i].y+=T[i].vy;
				}
			}else{
				T[i].x+=cos(T[i].angle*RAD)*T[i].speed ;
				T[i].y-=sin(T[i].angle*RAD)*T[i].speed;
			}
			switch(T[i].kind)
			{
			case TAMA:
				DrawBox(T[i].x,T[i].y,T[i].x+2,T[i].y+2,GetColor(255,0,0),TRUE);
				break;
			case LASER:
				DrawLine(T[i].x,T[i].y+16,T[i].x+32,T[i].y+16,GetColor(255,255,255));
				break;
			case REFLASER:
					//DrawCircle(T[i].x,T[i].y,5,GetColor(255,0,0),TRUE);
					for(int j=128;j>0;j--)
					{
						DrawPixel(xx[j],yy[j],GetColor(255,255,255));
					}
					
					for(int k=128;k>0;k--)
					{
						xx[k]=xx[k-1];
						yy[k]=yy[k-1];
					}
					//DrawPixel(T[i].x,T[i].y,GetColor(255,0,0));
					xx[0] = T[i].x;
					yy[0] = T[i].y;
					break;
			}
			if(T[i].x>320) T[i].flag=0;
		}
	}
}

アバター
KEYONN_
記事: 70
登録日時: 13年前

Re: 反射レーザーのアルゴリズムについて

#2

投稿記事 by KEYONN_ » 12年前

分からない点は、描画の仕方です。
あとは、壁に当たったら、vyをvy*=-1;にして、反射すればいいだけだとは
思いますが、当たり判定がおかしいです。

box
記事: 2002
登録日時: 13年前

Re: 反射レーザーのアルゴリズムについて

#3

投稿記事 by box » 12年前

KEYONN_ さんが書きました: 当たり判定がおかしいです。
どのようにおかしい、と判断されているのでしょうか。

ところで、コメントがないソースコードを読み解くのは、けっこうたいへんです。
また、変数や構造体の定義部の提示がないため、例えば「配列の要素数は適切に確保してあるか?」
というようなところが判断できないというのも困った点です。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

ふりかけ

Re: 反射レーザーのアルゴリズムについて

#4

投稿記事 by ふりかけ » 12年前

REFLASER はDrowPixel関数で描画しているようですが、描画の仕方が分からないとはどういう意味ですか。
提示されたコードには当たり判定に関する部分がないようなので、それについても答えようがないと思います。

アバター
KEYONN_
記事: 70
登録日時: 13年前

Re: 反射レーザーのアルゴリズムについて

#5

投稿記事 by KEYONN_ » 12年前

box さんが書きました:
KEYONN_ さんが書きました: 当たり判定がおかしいです。
どのようにおかしい、と判断されているのでしょうか。

ところで、コメントがないソースコードを読み解くのは、けっこうたいへんです。
また、変数や構造体の定義部の提示がないため、例えば「配列の要素数は適切に確保してあるか?」
というようなところが判断できないというのも困った点です。
どのようにおかしいかというと、壁ではない座標に弾が移動しても
(壁ではないy==0 か、y==240)反射してしまうのと、壁である座標でもそのまま通って
しまう事です。

あと、コメントと、変数と構造体の定義部の提示をします。


コード:

#include"DxLib.h"
#include<math.h>
#include<stdio.h>
#include<stdlib.h>

#define RAD (3.14159265/180)

typedef struct Bullet{
	double x;//x座標
	double y;//y座標
	int flag;//フラグ
	int kind;//種類(最初は銃、次にパワーアップしたら、レーザー,反射レーザー)
	int syurui;//種類(自機用か、敵用か)
	double angle;
	double speed;
	int vx,vy;
	double OldX,OldY;
}Bullet;

typedef struct Enemy{
	double x,y;//x,y座標
	int width,height;//幅、高さ
	int flag;//出現フラグ
	int kind;//種類
	int movekind;//動き方
	int hp;//HP(ヒットポイント)
	int tmp[100];//補助変数
}Enemy;

typedef struct Explosion{
	int x,y;
	int time;
	int count;
	int frame;
	int flag;
}Explosion;

#define TAMA 0
#define LASER 1 //自機のショットタイプの定数
#define REFLASER 2 //反射レーザー


int tbl[]={128,96,0,32,64};//ロール値

int sx=0,sy=0;//スクロール値
int image;//自機のイメージ
int image2;//背景のイメージ
int image3[100];//敵
int SE[100];//効果音

int x=50;//x座標
int y=(240-32)/2;//y座標
int roll=20;//roll値 (/10する)
Bullet T[100]={0};
Enemy E[100]={0};
Explosion Ex[100]={0};
int Map[3][30][300]={0};
int MChip[256];
int xx[128];
int yy[128];

void DrawAndMoveShot()
{
	int i;

	for(i=0;i<100;i++)
	{
		if(T[i].flag==1)
		{
			if(T[i].syurui ==0)//種類(自機用か、敵用かの場合分け)0なら自機用、1なら敵用
			{
				if(T[i].kind==0) T[i].x+=5;//kind(パワーアップの武器の種類)が0ならx+=5;する
				else{
					//レーザー用移動ソース部分
					if(Map[2][(int)(T[i].y/16)][(int)(T[i].x/16)]==0)
					{
						T[i].vy*=-1;
						//map[2][y/16][x/16]が
						//255以外だったら(0)なら反射する
						//なお、マップエディタはPlatinamを使用
					}
					T[i].x+=T[i].vx;//加速値を加算
					T[i].y+=T[i].vy;
				}
			}else{
				T[i].x+=cos(T[i].angle*RAD)*T[i].speed;
				T[i].y-=sin(T[i].angle*RAD)*T[i].speed;
				//指定した角度で移動
			}
			switch(T[i].kind)//パワーアップの武器の種類
			{
			case TAMA://TAMAなら四角を描画
				DrawBox(T[i].x,T[i].y,T[i].x+2,T[i].y+2,GetColor(255,0,0),TRUE);
				//
				break;
			case LASER:
				//レーザーなら、線を描画
				DrawLine(T[i].x,T[i].y+16,T[i].x+32,T[i].y+16,GetColor(255,255,255));
				break;
			case REFLASER:
				//反射レーザーなら、点を描画(45度なので、点だけでOK)
					//DrawCircle(T[i].x,T[i].y,5,GetColor(255,0,0),TRUE);

					//昔のVB6からソース移植(なので、あまり意味が分かってません)
					for(int j=128;j>0;j--)
					{
						DrawPixel(xx[j],yy[j],GetColor(255,255,255));
						//点を描画
					}
					
					for(int k=128;k>0;k--)
					{
						xx[k]=xx[k-1];
						yy[k]=yy[k-1];
					}
					//DrawPixel(T[i].x,T[i].y,GetColor(255,0,0));
					xx[0] = T[i].x;
					yy[0] = T[i].y;
					break;
			}
			if(T[i].x>320 || T[i].x<0 || T[i].y>240 || T[i].y<0) T[i].flag=0;
			//画面外なら弾を消す
		}
	}
}
添付ファイル
Main.zip
(774.74 KiB) ダウンロード数: 87 回
最後に編集したユーザー KEYONN_ on 2011年11月27日(日) 16:20 [ 編集 1 回目 ]

アバター
KEYONN_
記事: 70
登録日時: 13年前

Re: 反射レーザーのアルゴリズムについて

#6

投稿記事 by KEYONN_ » 12年前

ふりかけ さんが書きました:REFLASER はDrowPixel関数で描画しているようですが、描画の仕方が分からないとはどういう意味ですか。
提示されたコードには当たり判定に関する部分がないようなので、それについても答えようがないと思います。
描画の仕方が分からないというのは、どうやって反射レーザーの軌道を描画すれば
いいのか分からないということです。

当たり判定に関しては、コメントがなかったので、分かりにくかったとは思いますが、
一応あります。

アバター
KEYONN_
記事: 70
登録日時: 13年前

Re: 反射レーザーのアルゴリズムについて

#7

投稿記事 by KEYONN_ » 12年前

今、いいアイデアが浮かびました。
始点をsx,sy、当たった点をcx,cy,終点をex,eyとして、
線を描画すればいいのではないかということです。

------------------------------------
  /  \(cx,cy)
 /   \
/    \
/(ex,cy) (sx,sy)

アバター
KEYONN_
記事: 70
登録日時: 13年前

Re: 反射レーザーのアルゴリズムについて

#8

投稿記事 by KEYONN_ » 12年前

コード:

case REFLASER:
				//反射レーザーなら、線を描画	
					
				{
					static int sx,sy,cx,cy,ex,ey;
					
					sx=T[i].x;
					sy=T[i].y;
					if(sy<16)
					{//上に当たった時
						cx=sx-16;
						cy=0;
						ey=sy;
						ex=sx-32;
					}else if(sy>240-16)
					{//下に当たった時
						cx=sx-16;
						cy=240;
						ey=sy;
						ex=sx-32;
					}else{
						if(T[i].VY<0)//VYがマイナスなら
						{
						ey=sy+32;
						ex=sx-32;
						cx=(ex+sx)/2;
						cy=(ey+sy)/2;
						}else{//VYがプラスなら
						ey=sy-32;
						ex=sx-32;
						cx=(ex+sx)/2;
						cy=(ey+sy)/2;
						}
					}
					
					
					ex=sx-32;
					
					DrawLine(sx,sy,cx,cy,GetColor(255,255,255));
					DrawLine(cx,cy,ex,ey,GetColor(255,255,255));


				}
					break;
とりあえず、こんな感じで出来たので、解決にしておきます。
添付ファイル
Screen_Shot.jpg
Screen_Shot.jpg (31.46 KiB) 閲覧数: 4959 回

box
記事: 2002
登録日時: 13年前

Re: 反射レーザーのアルゴリズムについて

#9

投稿記事 by box » 12年前

KEYONN_ さんが書きました:

コード:

int xx[128];
int yy[128];
この定義で
KEYONN_ さんが書きました:

コード:

					for(int j=128;j>0;j--)
					{
						DrawPixel(xx[j],yy[j],GetColor(255,255,255));
						//点を描画
					}
					for(int k=128;k>0;k--)
					{
						xx[k]=xx[k-1];
						yy[k]=yy[k-1];
					}
}
このコードを書くのはまずいです。
KEYONN_ さんが書きました:

コード:

int xx[128];
int yy[128];
この定義でアクセスできるのは
xx[0]~xx[127], yy[0]~yy[127]
です。
xx[128], yy[128]
は、配列の定義範囲外の領域です。
コードを見直す必要がありそうです。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
KEYONN_
記事: 70
登録日時: 13年前

Re: 反射レーザーのアルゴリズムについて

#10

投稿記事 by KEYONN_ » 12年前

int xx[128];
int yy[128];
は、もう必要の無い変数なので、コードを見直す必要はなさそうです。

一応ソースファイルをアップロードしておきます。
添付ファイル
Main.zip
(774.64 KiB) ダウンロード数: 112 回

閉鎖

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