無題

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

無題

#1

投稿記事 by みかんのかわ » 16年前

敵の行動パターンとして∞(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 );

Dixq (管理人)

Re:無題

#2

投稿記事 by Dixq (管理人) » 16年前

Xが1周期の間にYが2周期単振動したらいいのではないでしょうか?

Dixq (管理人)

Re:無題

#3

投稿記事 by Dixq (管理人) » 16年前

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;
}

Dixq (管理人)

Re:無題

#4

投稿記事 by Dixq (管理人) » 16年前

それともこんな感じでしょうか?
#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;
}
 

Dixq (管理人)

Re:無題

#5

投稿記事 by Dixq (管理人) » 16年前

上の計算何やってるかわからないかもしれないので、定義してみました。
#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:無題

#6

投稿記事 by みかんのかわ » 16年前

>Dixq (管理人)さま
すばやい解答をありがとうございます。
2番目のレスを実行してみたところ∞の形にうごきました。
良く考えてみると、y=cosθ,y=sinθ(sin,cosのグラフ)の動きを合わせて
(というと語弊がありそうですが…)
作っていたのを思い出しました。
yの運動量がxの運動量の半分になる(というか運動量が等しくないと)
ときれいな円運動でなくなるのだと波打った形になるのですね。
解決しました、ありがとうございました。
トピックの件失礼しました。今後気を付けたいと思います。

みかんのかわ

Re:無題

#7

投稿記事 by みかんのかわ » 16年前

すみません。間違えました。

× 良く考えてみると、y=cosθ,y=sinθ(sin,cosのグラフ)の動きを合わせて
(というと語弊がありそうですが…)
作っていたのを思い出しました。

○ 良く考えてみると、円運動はy=cosθ,y=sinθ(sin,cosのグラフ)の動きを合わせて
(というと語弊がありそうですが…)
作っていたのを思い出しました。


それではありがとうございました。

Dixq (管理人)

Re:無題

#8

投稿記事 by Dixq (管理人) » 16年前

運動量(P = mvで表される速さに質量をかけた量)では無いと思いますが・・。

普通に周期を半分にしただけです。
水平方向に1回単振動している間に、
鉛直方向に2回単振動すれば、
∞のようになるということです。

situmon

当たり判定

#9

投稿記事 by situmon » 16年前

シューティングゲームの館のファイルshoot2のShには
当たり判定の画像など一式がそろっています。
ということはシューティングゲームの館でも
正確な当たり判定が作れるのでしょうか?
そもそも当たり判定(敵と自機どちらも)はどのように
できているのかわかりません。他の章は
皆様が紹介してくださった本やサイトを見てわかるようになりました。
arrayさんに聞いたら龍神録プログラミングとは違うので
少し難しいといっていました。龍神録のプログラムはほぼ東方のシステム
がなりたっており、自分のアレンジがどうしてもやりにくいので・・・

Dixq (管理人)

Re:当たり判定

#10

投稿記事 by Dixq (管理人) » 16年前

当たり判定の画像って何でしょう?
シューティングゲームの館に限らず、当たり判定のプログラムを書けば何にでも実装可能だと思います。

後、当たり判定のプログラムには極基本的な程度ですが、数学的な知識が必要です。
situmonさんはかなりお若いとお聞きしましたが、ピタゴラスの定理などはご存知でしょうか?
斜辺の二乗は対辺と底辺の二乗の和に等しいという奴です。
三平方の定理とも言います。

これで、当たり判定を計算します。
詳しくはゲームプログラミングの館にあります。

http://dixq.net/g/#s11

これを見て意味がわかるでしょうか?
解ればこれを実装すればいいと思いますし、解らなければ、調べるか、また聞いて下さい。

situmon

Re:当たり判定

#11

投稿記事 by situmon » 16年前

atariのことです。
もしわからなかったらまたよろしくお願いします。
ですがこれでがんばってみたいです。

situmon

Re:当たり判定

#12

投稿記事 by situmon » 16年前

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){)です。

追記、
間違えがいろいろあり、直したところ成功し解決いたしました。
ありがとうございます。

閉鎖

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