のつづきです
Elixirで作る「DDJ-FLX4のジョグ対応ブロックくずし」 の最終回です
DDJ-FLX4を毎回セッテイングがめんどくさい&DDJ-FLX4がなくても動作チェックしたい
結論はWebSocketで通信できれば、なんでも良いです
ライブラリの相性問題でWebSocket対応した為可能になりました
OSはUbuntu22.04で動かしていますが、ひょっとしたら他のOSでもライブラリさえ動けば動作するかも
方法ブラウザーから通信する
仕様
- ws://localhost:4000/socket/websocket?token=undefined&vsn=2.0.0'に接続
-
["","","ddj:lobby","phx_join",{}]
送信してサーバーに接続処理を行う - aキーを押すと
-1.0
を送信'["","","ddj:lobby","new_msg",{"body":-1.0"}]'
- dキーを押すと
1.0
を送信'["","","ddj:lobby","new_msg",{"body":1.0"}]'
- データー受信時
<div id="msg">
に受信結果を表示
ソース
ddj_client/client_test.html
<html>
<script>
const ws = new WebSocket('ws://localhost:4000/socket/websocket?token=undefined&vsn=2.0.0')
// 接続後にphx_joinを送る
ws.onopen = () => {
ws.send('["","","ddj:lobby","phx_join",{}]');
};
const MOVE_LEFT_AMOUNT = "-1.0";
const MOVE_RIGHT_AMOUNT = "1.0";
const keyBindings = {
a: MOVE_LEFT_AMOUNT,
d: MOVE_RIGHT_AMOUNT,
};
// htmlロード後
window.addEventListener('load', function () {
document.addEventListener("keypress", event => {
const value = keyBindings[event.key];
if (value !== undefined) {
send(value);
}
})
});
function send(msg) {
data = '["","","ddj:lobby","new_msg",{"body":"' + msg + '"}]'
ws.send(data)
}
// 受信時にdevタグの内容に追加
ws.onmessage = (event) => {
const msg = document.querySelector("#msg")
msg.innerHTML = event.data + "<br>" + msg.innerHTML
};
</script>
<div id="msg">
</div>
</html>
バグが見つかったので修正
一生消えないブロックができました
対策
- ボールを大きくする
- ボールの速度変更
- ボールがプレイヤーにあたった時のx軸は反射はしない修正
ddj_block/lib/block.ex
defmodule Block do
def main(nil) do
blocks =
1..3
|> Enum.flat_map(fn y -> creat_blocks(y) end)
%{
wall: [
[0.0, 0.0, 10.0, 900.0],
[790.0, 0.0, 10.0, 900.0],
[0.0, 0.0, 900.0, 10.0],
[0.0, 900.0, 900.0, 10.0]
],
blocks: blocks,
player: [[350.0, 790.0, 100.0, 10.0]],
- ball: [[350.0, 400.0, 10.0, 10.0]],
- ball_speed_x: -2.0,
- ball_speed_y: -2.0
+ ball: [[350.0, 400.0, 50.0, 50.0]],
+ ball_speed_x: 0.5,
+ ball_speed_y: 4.0
}
end
def main(%{} = data) do
[[x, y, w, h]] = data.ball
wall_lr = data.wall |> Enum.slice(0..1)
wall_t = data.wall |> Enum.slice(2..3)
{collided, blocks} = Game.collided_with_filter(x, y, w, h, data.blocks)
ball_speed_y =
if Game.collided?(x, y, w, h, wall_t ++ data.player) or collided,
do: data.ball_speed_y * -1.0,
else: data.ball_speed_y * 1.0
ball_speed_x =
- if Game.collided?(x, y, w, h, wall_lr ++ data.player) or collided,
+ if Game.collided?(x, y, w, h, wall_lr) or collided,
do: data.ball_speed_x * -1.0,
else: data.ball_speed_x * 1.0
[[bx, by, bw, bh]] = data.ball
ball = [[bx + ball_speed_x, by + ball_speed_y, bw, bh]]
[[px, py, pw, ph]] = data.player
player = [[px + DdjBlock.get_state() * 20, py, pw, ph]]
DdjBlock.set_state(0.0)
Map.merge(data, %{
ball_speed_y: ball_speed_y,
ball_speed_x: ball_speed_x,
ball: ball,
player: player,
blocks: blocks
})
end
def creat_blocks(y) do
1..5
|> Enum.map(fn x ->
[120.0 * x, 100.0 * y, 100.0, 50.0]
end)
end
end
操作動画
ブラウザーにフォーカスしてからaキーとdキーで操作できます
github
気づいいる問題点:ddj_block起動時にたまに落ちる(理由不明)
おわり
コラム一覧