なんとなくだらだらと。方向性はまだ決まってない。
当方のプログラムでは、山田巧さん作成のDXライブラリを利用させていただいてます。
本サイト http://homepage2.nifty.com/natupaji/DxLib/index.html
DX Library Copyright (C) 2001-2008 Takumi Yamada.
× [PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
ま~~~~~た、2chアクセス禁止だよ!!!
例の反・民主党荒らしのキチガイ、パソコンショップの店頭まわって書き込んでるらしく、 e-mobileの会社側では手に負えないみたい。 タダ同然で配りまくるから、こういうことになるんだよな。 そんなことはどうでもいいんだけど。 2日ほどサボったけど、サボってたわけでもない。いろいろ考えてたら手が動かなかっただけ。 とりあえずは、ボールのクラスを作る。 現在座標(X,Y)と、移動方向Yaw、ベクトル強さをSpdで持つ。 Playerクラスから必要そうなところをコピペしてたら、なんとなく同じクラスからの派生でも いいような気がしてくる。 Ball.h // Ball.h #pragma once class Ball { double Bx,By; // ボール現在位置 double Yaw; // ボール進行方向 double Spd; // ボールの速度 int HomeX,HomeY; // ホームポジション(試合開始時、ピッチ中央) public: void Init(int HomeX, int HomeY); int getBx(){return static_cast<int>(Bx);} int getBy(){return static_cast<int>(By);} double getSpd(){return Spd;} void Kick(int LocX, int LocY, double Spd); void Move(); }; void Ball::Init(int hx, int hy){ Bx = HomeX = hx; By = HomeY = hy; } // ボールを蹴る(目標地点に向かう蹴り出し方向を決める) void Ball::Kick(int LocX, int LocY, double Spd) { Yaw = atan2(LocY - By, LocX - Bx); this->Spd = Spd; } void Ball::Move() { double c = cos(Yaw); double s = sin(Yaw); Bx += c*Spd; By += s*Spd; Spd *= 0.98; // 地面との摩擦により、転がるスピードが落ちる if(Spd < 0.001) Spd = 0.0; } 実質、ボール蹴り出しの Kick() と、移動の Move() だけだな。 Kick() は、目標地点に向かう角度を決めて、Sin・Cos でX、Yに成分分解する。 そして Spd ベクトル長さで蹴り出しの強さを決める。 もう目標地点はいらない。目標地点に届かなくても行き過ぎても知らない。 Move() は、蹴り出した方向にSpd ベクトル分移動する。 Spd に1.0よりちょっと小さい値を掛けて、Spdを少しづつ減少させる。 一定値以下になると止まるように値を丸める。 禿げるほどいろいろ考えた割には、シンプルに収まった。 そういうものかもしれないな。案ずるより生むが安し。 main.cpp void Game() { enum GameState {GAMEINIT, PLAY}; static GameState gs = GAMEINIT; int lx = 0,m = 0; switch(gs){ case GAMEINIT: for(int i=0; i<10; i++){ if(player[i].getStatus()!=WAIT)player[i].Move(); else ++m; } ball.Move(); if((m==10)&&(ball.getSpd()==0.0)) gs = PLAY; break; case PLAY: // プレイヤーを動かす for(int i=0; i<10; i++){ if(player[i].getStatus()!=WAIT){ player[i].GoLocate(CHASE_BALL,ball.getBx(),ball.getBy()); player[i].Move(); if(( (player[i].getPx()-ball.getBx())*(player[i].getPx()-ball.getBx()) +(player[i].getPy()-ball.getBy())*(player[i].getPy()-ball.getBy()))<25){ if(player[i].getTeam()==BLUE) lx = 600; else lx = 0; ball.Kick(lx, GetRand(300), 4.0); player[i].setStatus(WAIT); } } else ++m; } // もし誰も動いてなければ、誰かひとりランダムで決めてボールに走らせる if(m>=10){ player[GetRand(10)].GoLocate(CHASE_BALL,ball.getBx(),ball.getBy()); } ball.Move(); break; } } こういう、この手のプログラムはお手の物。 ほとんど動作確認のテスト用。 まずは状態 GameState で今の状況を設定する。最初はGAMEINIT 。 初期化したプレイヤー・ボールが全部定位置に戻ったら PLAY 状態にする。 プレイヤーがWait 状態じゃなければプレイヤーを指示どおり動かす。このへんは後述。 Wait状態ならカウンタを+1して次のプレイヤーへ。 全員Wait状態なら、誰かひとり(ランダムに!)選んでボールに向かわせる。 ひとり選ばれたプレイヤーが、ボールを見ながら追いかける。 ボールとの距離が平方距離で25以下まで近づいたら、ボールを蹴る。 平方距離っていうのは、あの有名なピタゴラスの定理 直角三角形斜辺の平方は、他の2辺の長さの2乗和に等しい h=√(a^2 + b^2) h^2 = a^2 + b^2 平方根を出すのはPC的にもちょっと手間だし、今回そんなに厳密な値が必要でもないから 下の式のまま放ったらかして、5の2乗距離25より小さいかどうかで判定しているだけ。 で、この距離より近くなれば、ボールを蹴って本人は休む。1/10の確率で連続出勤になるけど。 ボールの蹴り出しは、青チームなら右(X=600)、赤チームなら左(X=0)で、縦は0~300まで ランダムで決める。 まあテストプログラムなので、追いかけてボールを蹴るサマが見られたらそれでいい。 PR |
カレンダー
カテゴリー
フリーエリア
最新記事
(01/29)
(01/28)
(01/26)
(12/28)
(12/27)
(12/25)
(12/20)
(09/09)
(09/09)
(09/09)
(09/08)
(09/08)
(09/08)
(09/06)
(09/05)
(08/27)
(08/27)
(08/27)
(08/25)
(08/23)
ブログ内検索
P R
アクセス解析
カウンター
|