なんとなくだらだらと。方向性はまだ決まってない。
当方のプログラムでは、山田巧さん作成のDXライブラリを利用させていただいてます。
本サイト http://homepage2.nifty.com/natupaji/DxLib/index.html
DX Library Copyright (C) 2001-2008 Takumi Yamada.
× [PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
気になってたAIを整備してみた。
ゴールキーパーは自分のゴールを守り、他のプレイヤーは一番近いヤツにボールを追わせる。 あとはAIを整備していけばそれなりに見られるようになる予感。 そこ以外は、もう足すものも無い引くものもない、ひじょうに原理主義な俺っぽいプログラム。 画面SSは代わり栄えしないなあ。 ダウンロード http://hiyayakko.sarashi.com/SimpleSoccer/SC07.zip (2009.08.15) ブログ書くためじゃなく、ホントに試行錯誤しながら余裕無いプログラム書いてるんで 動くようになったときに、どこをどこまで触ったのかほとんど覚えてない。 どのプレイヤーを動かすかを決めたりする、総合監督的な位置の GamePlay() 関数を ばっさり作り直したような気がする。 main.cpp void GamePlay() { int i,dist; int rc=-1,bc=-1,rc_dist=999999,bc_dist=999999; for(i=0;i<10;i++)player[i].setStatus(WAIT); for(i=0;i<10;i++){ // ゴールキーパー以外で、両軍ともにボールに一番近いプレイヤーを探す if(player[i].getPos()!=GOALKEEPER){ dist = Distance(player[i].getPx(),player[i].getPy(),ball.getBx(),ball.getBy()); if(player[i].getTeam()==RED){ if(dist<rc_dist){ rc=i; // このプレイヤーが今のところ一番近い rc_dist=dist; } } else { if(dist<bc_dist){ bc=i; // このプレイヤーが今のところ一番近い bc_dist=dist; } } } else { // ゴールキーパーは自分のエリアからある程度ボールが離れれば、自分のポジションに戻る if(player[i].getTeam()==RED){ if(ball.getBx()<400)player[i].GoHomePos(); } else { if(ball.getBx()>200)player[i].GoHomePos(); } } } if(bc!=-1) player[bc].GoLocate(CHASE_BALL,ball.getBx(),ball.getBy()); if(rc!=-1) player[rc].GoLocate(CHASE_BALL,ball.getBx(),ball.getBy()); // プレイヤーの移動処理 for(i=0;i<10;i++){ if(player[i].getPos()==GOALKEEPER){ if(Distance(player[i].getPx(),player[i].getPy(),ball.getBx(),ball.getBy())<6400){ player[i].GoLocate(CHASE_BALL,ball.getBx(),ball.getBy()); // ゴールキーパーだけ、守備範囲を広く取る } } else if(Distance(player[i].getPx(),player[i].getPy(),ball.getBx(),ball.getBy())<500) player[i].GoLocate(CHASE_BALL,ball.getBx(),ball.getBy()); player[i].Move(); // ボールを蹴られる位置にいるか。 dist = Distance(player[i].getPx(),player[i].getPy(),ball.getBx(),ball.getBy()); if(((player[i].getPos()==GOALKEEPER)&&(dist<81))||(dist<25)){ if((player[i].getPos()==GOALKEEPER)||(ball.getSpd()<2.0)){ // ボールの近くにいて、なおかつボールスピードが低いとき // スピード判定は、重なってるプレイヤー同士でもみもみして後攻有利になるので。 if(player[i].getTeam()==BLUE) { if(player[i].getPos()==GOALKEEPER) ball.Kick(600,GetRand(300),8.0); else if(ball.getBx()>400) ball.Kick(600,GetRand(80)+110,6.0); else ball.Kick(600,GetRand(300),4.0); } else { if(player[i].getPos()==GOALKEEPER) ball.Kick(0,GetRand(300),8.0); else if(ball.getBx()<200) ball.Kick(0,GetRand(80)+110,6.0); else ball.Kick(0,GetRand(300),4.0); } for(int j=0;j<10;j++)player[j].setStatus(WAIT); } } } // ボールの移動、ゴール処理 if(ball.Move()){ // ゴール!! if(ball.getBx()<300)game.addRedScore(); else game.addBlueScore(); // ボールを中央に戻し、プレイヤーも元のポジションに帰らせる for(int i=0; i<10; i++)player[i].GoHomePos(); ball.Init(300,150); game.setState(GAMEINIT); } } まずは、両軍からボールにいちばん近い人を探す。 rc はRed側から選ばれた人、rc_dist はその人とボールとの距離。blue側も同じく。 プレイヤー番号に -1 、距離に999999とか、ありえない数字を設定しておく。 ところで、red_C???? Cって何でつけたんだっけ? で、for 文で全員ボールからの距離を計る。 ゴールキーパー以外で最もボールに近い存在なら、プレイヤー番号と距離を書き換える。 赤軍と青軍で同じような処理を書くのが気に入らない。 ゴールキーパーの場合は、単純にボールの横軸だけ見てゴールから遠そうなら自分の ポジションに戻ろうとするだけ。 これで、青軍赤軍からそれぞれ最もボールに近いプレイヤーが追っかけ組に選ばれるわけだ。 今度はホントの本番の移動処理。 もういちど全プレイヤー for で判定する。 ゴールキーパーは平方距離で6400、その他のプレイヤーは500より近いところに ボールが来れば、 ボールを追いかけることにする。 ゴールキーパーの守備範囲がとんでもなく広い範囲に見えるけど、6400=80×80、ちょうど 画面中央にある円と同じ程度の広さだ。 プレイヤーは2500の円、50×50で四角マスの真ん中に立てばちょうど納まる円の広さが 自分の守備範囲だった はずなんだけど、いつのまにか守備範囲狭くなってるなあ。 で、そんなこんなでプレイヤーが動いて、ボールの近くにいたら問答無用で相手ゴール側に 蹴り返す。 赤軍も青軍も同じ思考回路で動いてるから、いつもいっしょに動くんだよなあ。 で、青軍が蹴る→赤軍が蹴るの判定順だと、いつでも赤軍有利な状況になってしまう。 ボールのスピードにちょっと注目して、蹴った瞬間のスピードには対応できないようにしてみた。 いろいろあってゴールキーパーは例外にしたけど。 そして、ゴールキーパーの蹴り返し判定範囲を拡大し、蹴る力もかなり大きくした。超ひいき。 赤軍青軍ゴールキーパーそれ以外で4通りの判定押し込んでるから、ちょっと単調に長い。 どうにかすれば、もうちょっとすっきりするとは思うんだけど。 なんか、ぼーっと見てて楽しい。 ゲームで遊ぶ人が介入しなくてもいいような感じ。環境プログラム。スクリーンセーバー。 プログラム的に青有利なはずだけど、絶対的な差がつくわけでもない。 一時的に1.5倍ぐらいの差が出ることはあっても、いつのまにか収束してる。 ゲームバランスも糞も無いはずなのに、自分の知らないところで神の手が動いてる。 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
アクセス解析
カウンター
|