ページ 1 / 1
無題
Posted: 2009年1月21日(水) 17:29
by みかんのかわ
敵の行動パターンとして∞(8の字運動?)の動きを作ろうと考えています。
∞の中心からスタートし、円運動→1周したらy座標の動きを変えて再び円運動という流れにしようと考えています。
今円運動を実装するところまでできたのですが、1周した際に上手く角度を変える事
ができません。
まず一週したという条件をx,y座標でとろうとするとうまくできません。
通るときと通らないときがあるため、他の方法をさがそうと思うのですが思い付きません。
(このようなかんじで→if(enemy_x == centerX && enemy_y == centerY))
(1周する時間をはかり、その時間が来たら、という条件とかでもよいのかもしれませんが…)
次に、一周した時点でy座標を変えるところがよくわかっていません。
以下ソースの一部です。
よろしくお願いします。
// 円運動
float enemy_x = initX +
radius*cos( enemyAngleSpeed*time );
float enemy_y =initY +
radius*sin( enemyAngleSpeed*time );
Re:無題
Posted: 2009年1月21日(水) 17:31
by Dixq (管理人)
Xが1周期の間にYが2周期単振動したらいいのではないでしょうか?
Re:無題
Posted: 2009年1月21日(水) 17:37
by Dixq (管理人)
DXライブラリのサンプルプログラムです。
#include "DxLib.h"
#include <math.h>
#define PI2 (3.1415926*2)
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
ChangeWindowMode(TRUE);//ウィンドウモード
if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化
int t=0;
int x,y;
while(ProcessMessage()==0 && ClearDrawScreen()==0 && CheckHitKey(KEY_INPUT_ESCAPE)==0){
//↑メッセージ処理 ↑画面をクリア ↑ESCが押されていない
x = cos(PI2/120*(t%120))*200 +320;
y = sin(PI2/ 60*(t% 60))*100 +240;
DrawCircle(x,y,5,GetColor(255,255,255),TRUE);
t++;
ScreenFlip();
}
DxLib_End();
return 0;
}
Re:無題
Posted: 2009年1月21日(水) 17:43
by Dixq (管理人)
それともこんな感じでしょうか?
#include "DxLib.h"
#include <math.h>
#define PI2 (3.1415926*2)
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
ChangeWindowMode(TRUE);//ウィンドウモード
if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化
int t=0;
int x,y;
while(ProcessMessage()==0 && ClearDrawScreen()==0 && CheckHitKey(KEY_INPUT_ESCAPE)==0){
//↑メッセージ処理 ↑画面をクリア ↑ESCが押されていない
x = (t/120)%2 ? cos(PI2/120*(t%120))*100+320-100 : -cos(PI2/120*(t%120))*100+320+100;
y = sin(PI2/120*(t%120))*100 +240;
DrawCircle(x,y,5,GetColor(255,255,255),TRUE);
t++;
ScreenFlip();
}
DxLib_End();
return 0;
}
Re:無題
Posted: 2009年1月21日(水) 17:51
by Dixq (管理人)
上の計算何やってるかわからないかもしれないので、定義してみました。
#define T 120 //周期
#define XRANGE 100 //X方向の円の大きさ
#define YRANGE 100 //Y方向の円の大きさ
#define FDX 640 //横画面サイズ
#define FDY 480 //縦画面サイズ
x = (t/T)%2 ? cos(PI2/T*(t%T))*XRANGE+FDX/2-XRANGE : -cos(PI2/T*(t%T))*XRANGE+FDX/2+XRANGE;
y = sin(PI2/T*(t%T))*YRANGE +FDY/2;
なお、トピックにはわかりやすい名前を付けて下さい。
Re:無題
Posted: 2009年1月21日(水) 18:14
by みかんのかわ
>Dixq (管理人)さま
すばやい解答をありがとうございます。
2番目のレスを実行してみたところ∞の形にうごきました。
良く考えてみると、y=cosθ,y=sinθ(sin,cosのグラフ)の動きを合わせて
(というと語弊がありそうですが…)
作っていたのを思い出しました。
yの運動量がxの運動量の半分になる(というか運動量が等しくないと)
ときれいな円運動でなくなるのだと波打った形になるのですね。
解決しました、ありがとうございました。
トピックの件失礼しました。今後気を付けたいと思います。
Re:無題
Posted: 2009年1月21日(水) 18:16
by みかんのかわ
すみません。間違えました。
× 良く考えてみると、y=cosθ,y=sinθ(sin,cosのグラフ)の動きを合わせて
(というと語弊がありそうですが…)
作っていたのを思い出しました。
○ 良く考えてみると、円運動はy=cosθ,y=sinθ(sin,cosのグラフ)の動きを合わせて
(というと語弊がありそうですが…)
作っていたのを思い出しました。
それではありがとうございました。
Re:無題
Posted: 2009年1月21日(水) 18:24
by Dixq (管理人)
運動量(P = mvで表される速さに質量をかけた量)では無いと思いますが・・。
普通に周期を半分にしただけです。
水平方向に1回単振動している間に、
鉛直方向に2回単振動すれば、
∞のようになるということです。
当たり判定
Posted: 2009年2月01日(日) 22:35
by situmon
シューティングゲームの館のファイルshoot2のShには
当たり判定の画像など一式がそろっています。
ということはシューティングゲームの館でも
正確な当たり判定が作れるのでしょうか?
そもそも当たり判定(敵と自機どちらも)はどのように
できているのかわかりません。他の章は
皆様が紹介してくださった本やサイトを見てわかるようになりました。
arrayさんに聞いたら龍神録プログラミングとは違うので
少し難しいといっていました。龍神録のプログラムはほぼ東方のシステム
がなりたっており、自分のアレンジがどうしてもやりにくいので・・・
Re:当たり判定
Posted: 2009年2月02日(月) 03:50
by Dixq (管理人)
当たり判定の画像って何でしょう?
シューティングゲームの館に限らず、当たり判定のプログラムを書けば何にでも実装可能だと思います。
後、当たり判定のプログラムには極基本的な程度ですが、数学的な知識が必要です。
situmonさんはかなりお若いとお聞きしましたが、ピタゴラスの定理などはご存知でしょうか?
斜辺の二乗は対辺と底辺の二乗の和に等しいという奴です。
三平方の定理とも言います。
これで、当たり判定を計算します。
詳しくはゲームプログラミングの館にあります。
http://dixq.net/g/#s11
これを見て意味がわかるでしょうか?
解ればこれを実装すればいいと思いますし、解らなければ、調べるか、また聞いて下さい。
Re:当たり判定
Posted: 2009年2月02日(月) 19:35
by situmon
atariのことです。
もしわからなかったらまたよろしくお願いします。
ですがこれでがんばってみたいです。
Re:当たり判定
Posted: 2009年2月02日(月) 21:51
by situmon
void playerCollisionDetection(){
for(int i=0;i<ENEMY_TOTAL_NUM;i++){//ショットの全列分
for(int j=0;j<ENEMY_TOTAL_SHOT_NUM;j++){//1列全弾分
if(EnemyShot.EnemyShots[j].flag==1){//その弾が発射中なら
double x,y;
int range;
int img = 0;
switch(EnemyShot[j].img){
case 0:
case 1:
range=3.0;
break;
case 3:
case 4:
range=3.5;
break;
case 5:
case 6:
range=40.0;
break;
}
x=(int)(EnemyShot.EnemyShots[j].x-Player.x);
y=(int)(EnemyShot.EnemyShots[j].y-Player.y);
if(x*x+y*y<range*range){
//初期座標に戻す
Player.x=200.0;
Player.y=450.0;
EnemyShot.EnemyShots[j].flag=0;
if(CheckSoundMem(sound_enemy_death)==1)
StopSoundMem(sound_enemy_death);
PlaySoundMem(sound_enemy_death,DX_PLAYTYPE_BACK);
}
}
}
}
}
と書いたのですが、渦巻きショットのときにだけエラーが出てしまいます。(if(x*x+y*y<range*range){)です。
追記、
間違えがいろいろあり、直したところ成功し解決いたしました。
ありがとうございます。