Elixirで作る「DDJ-FLX4のジョグ対応ブロックくずし」 その7 対策をする、そしてプロジェクトを3分割のつづきddj_server 編
のつづき
やっとゲームロジックらしいことを書きます
今回はあたり判定をつくります
あたり判定はこちらで再利用します
ソースを書く
ddj_block/lib/game.ex
defmodule Game do
@doc """
Collided detection.
## Examples
iex> Game.collided?(1, 1, 10, 10, 5, 5, 5, 5)
true
"""
def collided?(x1, y1, w1, h1, x2, y2, w2, h2) do
x1 <= x2 + w2 && x1 + w1 >= x2 && y1 <= y2 + h2 && y1 + h1 >= y2
end
def collided?(x1, y1, w1, h1, judgments) do
judgments
|> Enum.map(fn judgement ->
[x2, y2, w2, h2] = judgement
collided?(x1, y1, w1, h1, x2, y2, w2, h2)
end)
|> Enum.any?()
end
def collided_with_filter(x1, y1, w1, h1, judgments) do
judgments =
judgments
|> Enum.map(fn judgement ->
[x2, y2, w2, h2] = judgement
[collided?(x1, y1, w1, h1, x2, y2, w2, h2), judgement]
end)
collided = judgments
|> Enum.any?(fn [x, _] -> x end)
judgments =
judgments
|> Enum.filter(fn [x, _] -> !x end)
|> Enum.map(fn [_, x] -> x end)
{collided, judgments}
end
end
-
collided?(x1, y1, w1, h1, judgments) の部分を作りました
これは、複数のあたり判定可能にしました -
collided_with_filter(x1, y1, w1, h1, judgments)
上記の判定にさらにブロック崩しでまだあるブロックの座標を返却する
テストコードを書く
ddj_block/test/game_test.exs
defmodule GameTest do
use ExUnit.Case
# あたり判定テスト
test_params = [
[100, 100, 10, 10, 90, 90, 10, 10, true],
[100, 100, 10, 10, 90, 110, 10, 10, true],
[100, 100, 10, 10, 110, 90, 10, 10, true],
[100, 100, 10, 10, 110, 110, 10, 10, true],
[100, 100, 10, 10, 89, 89, 10, 10, false],
[100, 100, 10, 10, 89, 111, 10, 10, false],
[100, 100, 10, 10, 111, 89, 10, 10, false],
[100, 100, 10, 10, 111, 111, 10, 10, false],
[100, 100, 10, 10, 91, 91, 10, 10, true],
[100, 100, 10, 10, 91, 109, 10, 10, true],
[100, 100, 10, 10, 109, 91, 10, 10, true],
[100, 100, 10, 10, 109, 109, 10, 10, true],
[100, 100, 10, 10, 88, 88, 10, 10, false],
[100, 100, 10, 10, 88, 112, 10, 10, false],
[100, 100, 10, 10, 112, 88, 10, 10, false],
[100, 100, 10, 10, 112, 112, 10, 10, false],
[100, 100, 10, 10, 89, 90, 10, 10, false],
[100, 100, 10, 10, 90, 111, 10, 10, false],
[100, 100, 9, 10, 110, 90, 10, 10, false],
[100, 100, 10, 9, 110, 110, 10, 10, false],
[90, 90, 10, 10, 100, 100, 10, 10, true],
[90, 110, 10, 10, 100, 100, 10, 10, true],
[110, 90, 10, 10, 100, 100, 10, 10, true],
[110, 110, 10, 10, 100, 100, 10, 10, true],
[89, 89, 10, 10, 100, 100, 10, 10, false],
[89, 111, 10, 10, 100, 100, 10, 10, false],
[111, 89, 10, 10, 100, 100, 10, 10, false],
[111, 111, 10, 10, 100, 100, 10, 10, false],
[91, 91, 10, 10, 100, 100, 10, 10, true],
[91, 109, 10, 10, 100, 100, 10, 10, true],
[109, 91, 10, 10, 100, 100, 10, 10, true],
[109, 109, 10, 10, 100, 100, 10, 10, true],
[88, 88, 10, 10, 100, 100, 10, 10, false],
[88, 112, 10, 10, 100, 100, 10, 10, false],
[112, 88, 10, 10, 100, 100, 10, 10, false],
[112, 112, 10, 10, 100, 100, 10, 10, false],
[89, 90, 10, 10, 100, 100, 10, 10, false],
[90, 111, 10, 10, 100, 100, 10, 10, false],
[110, 90, 10, 10, 100, 100, 9, 10, false],
[110, 110, 10, 10, 100, 100, 10, 9, false]
]
for test_param <- test_params do
@test_param test_param
test "collided #{inspect(@test_param)}" do
[x1, y1, w1, h1, x2, y2, w2, h2, ret] = @test_param
assert Game.collided?(x1, y1, w1, h1, x2, y2, w2, h2) == ret
end
end
test "collided list false and true return true" do
x1 = 100
y1 = 100
w1 = 10
h1 = 10
judgments = [
[111, 111, 10, 10],
[91, 91, 10, 10]
]
assert Game.collided?(x1, y1, w1, h1, judgments)
end
test "collided list false and false return false" do
x1 = 100
y1 = 100
w1 = 10
h1 = 10
judgments = [
[89, 89, 10, 10],
[89, 111, 10, 10]
]
refute Game.collided?(x1, y1, w1, h1, judgments)
end
test "collided_with_filter false and true return true" do
x1 = 100
y1 = 100
w1 = 10
h1 = 10
judgments = [
[111, 111, 10, 10],
[91, 91, 10, 10]
]
assert Game.collided_with_filter(x1, y1, w1, h1, judgments) ==
{true, [ [111, 111, 10, 10]]}
end
test "collided_with_filter false and false return false" do
x1 = 100
y1 = 100
w1 = 10
h1 = 10
judgments = [
[89, 89, 10, 10],
[89, 111, 10, 10]
]
assert Game.collided_with_filter(x1, y1, w1, h1, judgments) ==
{false, [[89, 89, 10, 10], [89, 111, 10, 10]]}
end
end
複数のあたり判定のテストを追加しました
今回はここまで