アイテムと武器の変更
難しいところが出てきて、ちょっとやる気が減ってたというのもちょこっとあるけど、仕事が忙しかったのでなかなか進まなかった。
PowerUp アイテムのActor、これを継承する
DoubleLaserPowerUp 武器強化のアイテム
DoubleLaserWeapon 弾2個分 同時に生成する武器
単純に弾を2個同時につくっているのにびっくりした。 さらなる弾強化の3つ同時も同様にやる。
貫通レーザーとかも、当たった時に消さずにそのまま残すだけでできそう。
この武器変更の仕組みはシューティングで使いまわせそう。
ここまでのプロジェクト(205K)
2009/11/19
18:30
アステロイド追加
アステロイドActorを追加。
新しい種類のActorの追加のやり方がわかる。これで、敵の種類が増えても大丈夫。
追加の際に、重ならないように出現場所をWorldクラスのFindSpawnPoint()であいてる場所を探す。
衝突判定後、AdjustVelocities()でActorの速度を調整する。
しかしこれが難しくてわからない。
円の衝突をモデル化すると、衝突時、ぶつかり合う円の中心同士を結んだベクトルがあり、衝突面は、このベクトルに直行したものになる。衝突面に対して、入射角度と反射角度は同じになるので、衝突面方向、中心同士を結んだ方向に速度の成分を分けて考える。というぐらいまでで、どうしてこういう計算になるんだろうか?
ここはとりあえずわからないので飛ばす。やっぱりわからんとこ出てきたなあ。
ここまでのプロジェクト(205KB)
新しい種類のActorの追加のやり方がわかる。これで、敵の種類が増えても大丈夫。
追加の際に、重ならないように出現場所をWorldクラスのFindSpawnPoint()であいてる場所を探す。
衝突判定後、AdjustVelocities()でActorの速度を調整する。
しかしこれが難しくてわからない。
円の衝突をモデル化すると、衝突時、ぶつかり合う円の中心同士を結んだベクトルがあり、衝突面は、このベクトルに直行したものになる。衝突面に対して、入射角度と反射角度は同じになるので、衝突面方向、中心同士を結んだ方向に速度の成分を分けて考える。というぐらいまでで、どうしてこういう計算になるんだろうか?
ここはとりあえずわからないので飛ばす。やっぱりわからんとこ出てきたなあ。
ここまでのプロジェクト(205KB)
private static void AdjustVelocities(Actor actor1, Actor actor2) {
if(actor1.Mass <= 0f || actor2.Mass <= 0f) {
return;
}
Vector2 collisionNormal = Vector2.Normalize(actor2.Position - actor1.Position);
Vector2 collisionTangent = new Vector2(-collisionNormal.Y, collisionNormal.X);
float velocityNormal1 = Vector2.Dot(actor1.Velocity, collisionNormal);
float velocityTangent1 = Vector2.Dot(actor1.Velocity, collisionNormal);
float velocityNormal2 = Vector2.Dot(actor2.Velocity, collisionNormal);
float velocityTangent2 = Vector2.Dot(actor2.Velocity, collisionTangent);
float velocityNormal1New = ((velocityNormal1 * (actor1.Mass - actor2.Mass))
+ (2f * actor2.Mass * velocityNormal2)) / (actor1.Mass + actor2.Mass);
float velocityNormal2New = ((velocityNormal2 * (actor2.Mass - actor1.Mass))
+ (2f * actor1.Mass * velocityNormal1)) / (actor1.Mass + actor2.Mass);
actor1.Velocity = (velocityNormal1New * collisionNormal) +(velocityTangent1 * collisionTangent);
actor2.Velocity = (velocityNormal2New * collisionNormal) +(velocityTangent2 * collisionTangent);
}
2009/11/12
13:34
当たり判定 線分と円
Actorの持っている円形の領域と線分との当たり判定
学校で習ったベクトルがようやく役にたつとき!
基本的な考え方は、線分ABと点Cを中心とした円を考える。点C線分ABにおろした垂線が、円の中心との最短距離になる。こいつと円の半径を比較して、半径の方が小さかったら当たってない、大きかったらあたっていることになる。また、垂線との交点Hが線分ABの間にないときは、最短距離が、ACになったりBCになったりする。
こんな感じ
この場合はHCよりもACの方が短い。
問題はHCの長さを求める計算だけど、まず点Hの場所をベクトルを使って求める。
ベクトルAHはベクトルABをt倍したものとできるので、tを求めれば場所がわかる。
という式の変形でtが求められる。
tが負の場合、または1以上の場合は線分ABからはみ出てるので調整する
交点は当たり判定通知用の構造体、CircleLineCollisionResultにしまう。
円の半径と、距離を比較して結果を出す。
学校で習ったベクトルがようやく役にたつとき!
こんな感じ
問題はHCの長さを求める計算だけど、まず点Hの場所をベクトルを使って求める。
ベクトルAHはベクトルABをt倍したものとできるので、tを求めれば場所がわかる。
という式の変形でtが求められる。
public static bool CircleLineCollide(Vector2 center, float radius,Vector2 lineStart, Vector2 lineEnd, ref CircleLineCollisionResult result) {
Vector2 AC = center - lineStart;
Vector2 AB = lineEnd - lineStart;
float ab2 = AB.LengthSquared();
if(ab2 <= 0f) {
return false;
}
float acab = Vector2.Dot(AC, AB);
float t = acab / ab2;
tが負の場合、または1以上の場合は線分ABからはみ出てるので調整する
if(t < 0.0f) {
t = 0.0f;//点Hが点Aの場所になる
} else if(t > 1.0f) {
t = 1.0f;//点Hが点Bの場所になる
}
交点は当たり判定通知用の構造体、CircleLineCollisionResultにしまう。
円の半径と、距離を比較して結果を出す。
result.Point = lineStart + t * AB;
result.Normal = center - result.Point;
float h2 = result.Normal.LengthSquared();
float r2 = radius * radius;
if(h2 > r2) {
result.Collision = false;
} else {
result.Normal.Normalize();
result.Distance = (radius - (center - result.Point).Length());
result.Collision = true;
}
return result.Collision;
} きれいに書いてみたかったのでTEXを使ってみた。環境をつくるのがめんどい。図はGRAPESを使ってみました。使い方が独特だけど、簡単に図形がかけてよい感じ。
2009/11/10
22:44
弾の発射 Actorの動的な追加
Projectile 射出体(弾)のActor
LaserProjectile 通常弾の実装
Weapon 武器を表す Shipが持っている
LaserWeapon 通常弾の実装
このへんがちょっとわかりにくい。
ProjectileはActorなのでGamePlayScreenが自機と同じようにUpdate()とかDraw()を呼び出してくれる。他のActorと当たった時の処理もここ。
WeaponはUpdate()やDraw()にかかわらない部分、弾の発射間隔のカウントとかをする。 同時発射数が決まってるとかだったらここでやるのだろうか?
だんだん要素が増えてきてしんどい。
ここまでのプロジェクト(190KB)
2009/11/09
11:53
登録:
投稿 (Atom)





