stackoverflow や他のサイトでゲームの衝突検出について読んでいます。彼らの多くは、BSP、境界楕円、統合などについて語っています。しかし、NES では、ゲームで床と壁の衝突検出を行うことができました。壁の衝突を検出するために多くの計算を行ったとは信じがたいと思います。
私の質問は、タイルだけで構成されたレベルを考えると、処理能力がほとんどないマリオやロックマンのようなゲームで壁や床との衝突をどのように検出したのでしょうか?
- 彼らは動きの経路をたどり、最も近い接続タイルを特定しましたか? (少し調べて)(アプリオリ)
- 彼らは床との衝突を判断してから、キャラクターを調整する最善の方法を見つけましたか? (事後) これは可変タイムステップでは危険です。十分に速ければ、タイルを飛び越えることができます。NES ゲームのタイムステップはテレビのリフレッシュ レートと同期していると思いますが。
- 地面にいるとき、重力は常にキャラクターに影響を与えていますか? それとも、タイルの上を歩いていると決めたときに「オフ」にしますか? 崖の端から歩いて降りるときはどうですか?それ以外の場合は、下にあるタイルを特定する何らかの方法が必要になります。
- タイルに衝突した場合、そのタイルの端を見つけて、キャラクターをその側に移動しますか (進行方向によって異なります)。
- スーパーメトロイドやマリオのような傾斜したタイルはどうですか?
- 下をジャンプして上に着地できる「プラットフォーム」はどうでしょうか。「事後」に行う場合、これらのタイルとの衝突にどのように対処しますか?
特定の方向にヒットする最初のタイルを検索するため、基本的に「アプリオリ」な衝突コードをいくつか作成しました。何か良い方法はないかと考えているところです。(代わりに事後衝突検出を使用するだけかもしれません)
たとえば、下に移動するためのタイルの衝突をチェックするコード (私は垂直方向の動きをチェックしてから水平方向の動きをチェックします):
def tile_search_down(self, char, level):
y_off = char.vert_speed
assert y_off > 0
# t_ are tile coordintes
# must be int.. since we're adding to it.
t_upper_edge_y = int( math.ceil((char.y+char.h) / self.tile_height ) ) #lowest edge
while (t_upper_edge_y*self.tile_height) < (char.y+char.h+y_off): # lowest edge + offset
t_upper_edge_x = int( math.floor(char.x/self.tile_width) )
while (t_upper_edge_x*self.tile_width) < (char.x+char.w):
t_x = t_upper_edge_x
t_y = t_upper_edge_y
if self.is_tile_top_solid(t_x, t_y, plane):
char.y = t_y*self.tile_height - char.h
char.vert_speed = 0.0
char.on_ground = True
return
t_upper_edge_x += 1
t_upper_edge_y += 1
char.y += y_off