スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

○●TOPページ●○

                              
   ´'゜*○.。☆TOPページ☆。.○*゜'`
                              
【プログラマーの筆記試験】
実際の筆記試験問題①実際の筆記試験問題②実際の筆記試験問題③
実際の筆記試験問題④実際の筆記試験問題⑤実際の筆記試験問題⑥
実際の筆記試験問題⑦

【プログラマーの面接】
実際の面接①  ●実際の面接②  実際の面接③
実際の面接④  実際の面接⑤

【作品提出について】      【テストセンター】
企業からのアドバイス              実際のテストセンター問題①

【参考書関連】          【ジャンプ感想】
筆記試験に関する本               ジャンプ感想一覧
英語に関する本
プログラミングに関する本           役に立つかもしれない解説
FlashBuilder4.7を用いたFlash/アプリ開発Tips

Muzieのマイページ (自作曲 公開中!)


※イベントは無事終了しました!
現在イベントで配布したゲームの体験版/VerUP版を製作中です!
2012/09/09 チルノオンリー 「あたい最強!-今日は一日あたいのターン!-」



※2013/7/8追記
下記のイベントに参加します…!
daikyu.jpg



【参考URL】みかんこーぼーお問い合わせ掲示板
配布したゲームに不具合などがあった場合は、
こちらに連絡をよろしくお願い致します。

【Twitter】conio - Twitter
※好きなBGMや小ネタ、ゲーム制作関連について、つぶやいたりしてます。

■みかんこーぼー 2014年 予定

2月  テキスト差分作成プログラム(仮)公開
3月
4月
5月
6月  アクションゲーム(仮)公開

※都合に応じて、突如 予定が追加されたり、
また、公開が速く(遅く)なったり、別の何かを公開してみたり する
可能性があります。
スポンサーサイト

アクションゲームの斜め坂の実装方法

現在、斜め坂の当たり判定周りを実装しています。
まず、根幹の処理をいくつか変えたので、それの説明。

-----------------------------
【1】めり込みの際の、押し込み廃止
【2】弾性力追加

-----------------------------


【1】めり込みの際の、押し込み廃止
主人公が右へ移動して、移動可能オブジェクトAと衝突したとします。

この時、今までは
こんな面倒な手順を取っていたのですが、
===================================
手順1:めり込んでいた分だけAを右に動かす
手順2:更に右に物体があった場合はそれも動かす
手順3:更に更に右側に移動不可の壁などがあった場合、
     手順1~手順2の移動をキャンセル

===================================
【参考画像】
Sample_20140905_1.jpg


上記手順を止めて、
めり込む場合は必ず、
めり込まない位置に戻す
という風にしました。

【参考画像】
Sample_20140905_2.jpg

これだと、押せるオブジェクトがあっても押せないじゃないか、という事になってしまいますが、
次の弾性力と合わせて説明します。


【2】弾性力追加
全ての物体に"跳ね返る度合い"の概念を追加しました。
オブジェクトが衝突した場合、この概念を用いて移動方向を決めます。

※下記ページを参考にしました。
【参考URL】EMANの物理学・力学・2物体の衝突

オブジェクトA、Bが衝突した場合、下記の様に計算します。
int t_SpeedA = t_ObjectA->m_DetailSpeedX;
int t_SpeedB = t_ObjectB->m_DetailSpeedX;
double t_ElastA = ( double )t_ObjectA->m_ElasticForce / 1000;
double t_ElastB = ( double )t_ObjectB->m_ElasticForce / 1000;
double t_RateA = t_ObjectA->m_Mass / t_ObjectB->m_Mass;
double t_RateB = t_ObjectB->m_Mass / t_ObjectA->m_Mass;

t_ObjectA->m_DetailSpeedX = t_SpeedA + ( int )( ( double )( -t_SpeedA + t_SpeedB )*( 1 + t_ElastA )/( t_RateA + 1 ) );
t_ObjectB->m_DetailSpeedX = t_SpeedB + ( int )( ( double )( -t_SpeedB + t_SpeedA )*( 1 + t_ElastB )/( t_RateB + 1 ) );



分かりにくいので、具体例。

■例1
主人公Aが移動速度2で、壁Bに衝突。
主人公Aの弾性係数は0とする。(跳ね返る弾力性が無い)


※壁Bは不動なので、質量を9999999などとして考えます。
(主人公の質量を10等にした場合、壁は質量が大きすぎて微動だにしない、という動作になる)

t_ObjectA->m_DetailSpeedX = 2 + ( -2 + 0 )*( 1 + 0 ) / ( 0 + 1 );
t_ObjectA->m_DetailSpeedX = 2 - 2;
t_ObjectA->m_DetailSpeedX = 0;
⇒主人公の移動速度は0となる

t_ObjectB->m_DetailSpeedX = 0 + ( -0 + 2 )*( 1 + 0 ) / ( 9999999 + 1 );
t_ObjectB->m_DetailSpeedX = 0 + 0
t_ObjectB->m_DetailSpeedX = 0
⇒壁の移動速度は0のまま変わらない


■例2
主人公Aが移動速度2で、壁Bに衝突。
主人公Aの弾性係数は1とする。(最大限跳ね返る)


t_ObjectA->m_DetailSpeedX = 2 + ( -2 + 0 )*( 1 + 1 ) / ( 0 + 1 );
t_ObjectA->m_DetailSpeedX = 2 - 4;
t_ObjectA->m_DetailSpeedX = -2;
⇒主人公の移動速度は-2となる
(壁にぶつかった速度と同じ速さで、反対方向に跳ね返る)

t_ObjectB->m_DetailSpeedX = 0 + ( -0 + 2 )*( 1 + 0 ) / ( 9999999 + 1 );
t_ObjectB->m_DetailSpeedX = 0 + 0
t_ObjectB->m_DetailSpeedX = 0
⇒壁の移動速度は0のまま変わらない


こんな感じですね!
で、めり込み解消の方にしか座標を修正しないのなら、オブジェクトを押せないのでは?
という点についてですが、


■1フレーム目
手順1:主人公が移動速度1で、箱Aに衝突する
手順2:弾性力の計算が行われ、箱Aの移動速度が1になる

■2フレーム目
手順3:箱Aが移動速度1で、箱Bに衝突する
手順4:弾性力の計算が行われ、箱Bの移動速度が1になる

■3フレーム目
手順5:箱Bが移動速度1で、壁に衝突する
手順6:弾性力の計算が行われ、箱Bの移動速度が0に

⇒主人公が箱を押している様な動作になる!



こんな感じで、「複数のオブジェクトを押している」動作になります。
1フレームで全部計算するのではなく、複数のフレームに分けて処理が行われます。

つまり、最終的な結果が出るまでに表示遅延が発生するのですが、
1秒間に64回画面を更新する場合に、4回で結果が出た場合、
1秒の16分の1、つまり0.0625秒程度の誤差になります。

肉眼で「あっ衝突後の位置が1回で更新されずに、1、2フレーム遅延して更新が完了している!」とか
分かる訳ないので、これで問題ない、という寸法です。



■斜め坂の実装方法
では、次に斜め坂の実装について。

斜め坂は、一次関数の直線と考えて、
オブジェクトの底との交点を求めて算出します。

※下記の2つルールを守って直線情報を定義します
ルール1:必ず右方向の直線になるように座標を指定
(始点のX座標を、終点のX座標より小さくする。
例えば、右上がりの直線情報は、
始点(200, 0 ) - 終点(0, 200)ではなく、始点(0,200 ) - 終点(200, 0)とする。
※左向きと右向きの直線が混在すると面倒だから、というだけの理由。)


ルール2:垂直な直線は存在しないものとする
(直線の傾きを出す所で、0除算が発生する為。
 垂直な直線を作りたい場合は、直線ではなく横幅1ドットの矩形として対応する)



例えば、オブジェクトAが右上がりの斜め坂に衝突する場合は、
⇒A ◢
----------------------------------------------
【1】まず、斜め坂を矩形(四角形)として衝突判定を行う
【2】衝突している場合、下記を求める
  ①斜め坂の始点(X座標)
  ②斜め坂の始点(Y座標)
  ③斜め坂の終点(X座標)
  ④斜め坂の終点(Y座標)
  ⑤斜め坂の傾き
  ⑥オブジェクトAの底辺
  ⑦オブジェクトAの右辺
  ⑧オブジェクトAの高さ(縦幅)

【3】上記から、オブジェクトAの右辺があるX座標での、斜め坂のY座標を求める
   傾き: (double)(④-②) / (③-①)
   斜め坂のY座標:②+(⑤×(⑦-①))

【4】「手順3で出したY座標 < ⑥オブジェクトAの底辺」であれば、
   "斜め坂にめり込んでいる"と判定
【5】めり込んでいる場合、「手順3のY座標 - ⑧オブジェクトAの高さ」を、
   オブジェクトAの新しいY座標とする

----------------------------------------------
こんな感じになります。

具体的に図を用いて計算してみます。


【2】各必要な値を求める
右方向へ進む緑色の長方形と、青色の坂道が衝突するとします。
この場合、必要な値は下記の様になります。

b_1010_1.png


【3】オブジェクトAの右辺がある位置での、
坂道のY座標を求める


右辺のある位置での坂道のY座標は、
始点のY座標 + 傾き×始点から右辺までの距離で出せます。
今回は下記の様になるので、
-------------------------------------
始点のY座標 … 2
傾き … -1
始点からオブジェクトAの右辺までの距離 … 3-2=1
-------------------------------------
2 + (-1×1) = 1となります。
※上記の図を見ても、オブジェクトAの右辺がある位置では、(X座標が3の所では)
 坂道のY座標は1である事が分かると思います。


【4】めり込んでいるかを判定
オブジェクトAの右辺の位置では、坂道のY座標は1でした。
つまり、オブジェクトAの底辺が1より大きければめり込んでいると判定します。

※図を見ても分かる様に、今回の例では2>1 (底辺>坂道のY座標)なので、
 めり込んでいると判定。


<追記予定!>

物理演算システムの改善と、現在の状況報告とか

現在の状況報告をします。
ゲーム制作に関しては、アクションゲーム制作を優先的に実施しています。


■現在の予定
・[進行中]アクションゲームの物理演算処理修正
・[中断]パズルゲーム改良版作成
・[中断]ローグライクゲーム制作
・[中断]アプリ制作
・[中断]シミュレーションゲーム制作
・[時々進行]3Dモデルアニメーション付けソフト?作成

やりたい事に対して、手が追いついてない感じです。
スケジュール管理をどうにかしないと…。助けて(´・ω・`)

とりあえず、
自然消滅したり、やる気がなくなる事は無いので、
その一点だけはご安心を。



次に物理演算システムについて。
根幹から問題があった事が判明したので、
"間違っていた根幹をベースに作成していたソース"を削除/修正する事になりました。

何が間違っていたかというと、衝突判定ですね。

例えば、坂道の末端辺りに主人公が落下するとします。

【参考画像】
20140828_1.jpg

すると、坂道が主人公の頭上にワープします。
【参考画像】
20140828_2.jpg

一体、何が起こったか。


判定処理は下記の様になっています。
【3】以降は、問題が無くなるまでループして行われます。(再起関数)

【1】主人公の落下処理
【2】主人公と、床の衝突判定を実施
【3】めり込みを解消する方向(上)に、主人公を移動
【4】主人公に重なっているオブジェクトを、めり込みを解消する方向(上)に移動


例えば下記の状態でCと床の判定をした場合、
Cを上方向に修正、その修正したCとBが重なるのでBを上方向に修正、
更に修正したBとAが重なるので、Aを上方向に修正 ⇒ 床の上にCBAが乗っている様に見える
---------
A
B
C
床床床
---------
という感じになります。


上手く行けば問題は無いのですが、
衝突判定を総当たりにしてた為、
判定する順番(オブジェクトが登録された順番)によって、結果が変わるという
非常に面倒な不具合が発生しました。
※オブジェクトA,B,C,Dの順に登録されている場合、
AB、AC、BC、BD、CDの順番で判定が行われます。


簡単にいえば、主人公と坂道を判定して、
主人公を坂道の上に来るようにすればいい
所を、
先に主人公と床を判定してるもんだから、おかしな結果が出たのです。


あーなんてこった。
物体が移動する場合、
最も近い距離で衝突する物体から
衝突判定をすべき
だった。

ローグライクやシューティングゲームなんかでは、
とりあえず全部判定 ⇒ 衝突していれば移動不可、死ぬ
という風に、総当たりでやってたから、こんな単純な事に気付かなかった。

物理演算においては、"衝突判定の順番"も重要でした。
こんな単純なミスに数か月単位で苦悶してたとか愚の骨頂。

とりあえず、この問題については、
オブジェクトの右端、左端、上端、下端をそれぞれ昇順に並べて登録する様にしました。

----------------------------------
縦  横
64×64の正方形を、(0, 0)に配置
64×320の長方形を、(0, 100)に配置
480×64の長方形を、(-50, -50)に配置

RightList: 1363319
LeftList: -5000
TopList: -500100
BottomList: 63163429

----------------------------------

で、例えば64×64の正方形が下方向に移動する場合、
自分の登録されている位置から末端にかけて検索し、
衝突していれば移動距離を修正します。
※検索は、上辺が下辺よりも大きくなった時点で終了。

■具体例
64×64の正方形の上辺情報は、TopListの添え字1の所に格納されており、
下方向へ10移動しようとしているとします。

この場合、添字[1]から添字[5]に向かって検索していきます。
そして、下辺+移動速度 > TopListの値かつ、衝突しているものが無いか探します。

[0]:-50
[1]:0
[2]:70
[3]:150
[4]:200
[5]:240

移動速度を足すと63 + 10 = 73、
つまり、添字[1]以降で73以下の値があった場合、衝突判定を行います。
また、上辺の位置が73以上の値([3]の150)と遭遇した際は、
(昇順に並べられている為)、それ以上検索しても73以下の値は無いので、検索を終了します。

【参考画像】
20140828_3.jpg

とりあえず、衝突判定に関しては(今の所)問題ないので、
キャラクターの仮画像を作って、動作確認しています。

歩き、小走り、走り、ジャンプ、しゃがみ、壁擦り、ジャンプ攻撃、攻撃とか、
色々モーション多すぎて大変。
問題なければしっかりしたキャラクター画像に差し替えます。

20140828_4.jpg


画像が優に100枚を超えそうな予感。
少しだけ、アニメ制作会社の大変さが分かった気がした。
(比較にならんぐらい忙しそうだ…)


余談ですが、最近このBGMを聞いています。
わグルま!という最近サービス終了してしまったゲームのBGMなのですが、
とても不思議な雰囲気で、落ち着くのです。



上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。