ページ 1 / 1
反射レーザーのアルゴリズムについて
Posted: 2011年11月26日(土) 18:33
by KEYONN_
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;
}
}
}
Re: 反射レーザーのアルゴリズムについて
Posted: 2011年11月26日(土) 20:07
by KEYONN_
分からない点は、描画の仕方です。
あとは、壁に当たったら、vyをvy*=-1;にして、反射すればいいだけだとは
思いますが、当たり判定がおかしいです。
Re: 反射レーザーのアルゴリズムについて
Posted: 2011年11月26日(土) 20:24
by box
KEYONN_ さんが書きました:
当たり判定がおかしいです。
どのようにおかしい、と判断されているのでしょうか。
ところで、コメントがないソースコードを読み解くのは、けっこうたいへんです。
また、変数や構造体の定義部の提示がないため、例えば「配列の要素数は適切に確保してあるか?」
というようなところが判断できないというのも困った点です。
Re: 反射レーザーのアルゴリズムについて
Posted: 2011年11月27日(日) 08:49
by ふりかけ
REFLASER はDrowPixel関数で描画しているようですが、描画の仕方が分からないとはどういう意味ですか。
提示されたコードには当たり判定に関する部分がないようなので、それについても答えようがないと思います。
Re: 反射レーザーのアルゴリズムについて
Posted: 2011年11月27日(日) 14:52
by KEYONN_
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;
//画面外なら弾を消す
}
}
}
Re: 反射レーザーのアルゴリズムについて
Posted: 2011年11月27日(日) 14:57
by KEYONN_
ふりかけ さんが書きました:REFLASER はDrowPixel関数で描画しているようですが、描画の仕方が分からないとはどういう意味ですか。
提示されたコードには当たり判定に関する部分がないようなので、それについても答えようがないと思います。
描画の仕方が分からないというのは、どうやって反射レーザーの軌道を描画すれば
いいのか分からないということです。
当たり判定に関しては、コメントがなかったので、分かりにくかったとは思いますが、
一応あります。
Re: 反射レーザーのアルゴリズムについて
Posted: 2011年11月27日(日) 17:19
by KEYONN_
今、いいアイデアが浮かびました。
始点をsx,sy、当たった点をcx,cy,終点をex,eyとして、
線を描画すればいいのではないかということです。
------------------------------------
/ \(cx,cy)
/ \
/ \
/(ex,cy) (sx,sy)
Re: 反射レーザーのアルゴリズムについて
Posted: 2011年11月27日(日) 17:47
by KEYONN_
コード:
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;
とりあえず、こんな感じで出来たので、解決にしておきます。
Re: 反射レーザーのアルゴリズムについて
Posted: 2011年11月27日(日) 17:50
by box
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]
は、配列の定義範囲外の領域です。
コードを見直す必要がありそうです。
Re: 反射レーザーのアルゴリズムについて
Posted: 2011年11月27日(日) 18:50
by KEYONN_
int xx[128];
int yy[128];
は、もう必要の無い変数なので、コードを見直す必要はなさそうです。
一応ソースファイルをアップロードしておきます。