WIP: Multiplayer broken state
This commit is contained in:
parent
e59a36a922
commit
cd8befccba
|
@ -1,6 +1,9 @@
|
|||
[gd_scene load_steps=2 format=3 uid="uid://ug3u6jf36dst"]
|
||||
[gd_scene load_steps=3 format=3 uid="uid://ug3u6jf36dst"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://j1oei8suq5sj" path="res://scenes/morse_banner.gd" id="1_a1ve8"]
|
||||
[ext_resource type="Script" uid="uid://b1k6j1jti114u" path="res://scenes/multi_morse_banner.gd" id="1_a1ve8"]
|
||||
|
||||
[sub_resource type="AudioStreamGenerator" id="AudioStreamGenerator_a1ve8"]
|
||||
mix_rate = 22050.0
|
||||
|
||||
[node name="MorseBanner" type="Control"]
|
||||
custom_minimum_size = Vector2(200, 100)
|
||||
|
@ -11,3 +14,8 @@ anchor_bottom = 1.0
|
|||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_a1ve8")
|
||||
|
||||
[node name="Player" type="AudioStreamPlayer" parent="."]
|
||||
stream = SubResource("AudioStreamGenerator_a1ve8")
|
||||
volume_db = -100.0
|
||||
stream_paused = true
|
||||
|
|
|
@ -78,6 +78,10 @@ text = "Freq:"
|
|||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
|
||||
[node name="PlayerContainer" type="VBoxContainer" parent="MorseView/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
|
||||
[node name="MorseButton" type="Button" parent="MorseView/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
|
@ -87,3 +91,5 @@ text = "MORSE"
|
|||
[connection signal="pressed" from="ConnectView/VBoxContainer/HBoxContainer/CreateButton" to="." method="_on_create_button_pressed"]
|
||||
[connection signal="pressed" from="ConnectView/VBoxContainer/RefreshButton" to="." method="_on_refresh_button_pressed"]
|
||||
[connection signal="item_clicked" from="ConnectView/VBoxContainer/FreqList" to="." method="_on_freq_list_join"]
|
||||
[connection signal="button_down" from="MorseView/VBoxContainer/MorseButton" to="." method="_on_morse_button_button_down"]
|
||||
[connection signal="button_up" from="MorseView/VBoxContainer/MorseButton" to="." method="_on_morse_button_button_up"]
|
||||
|
|
|
@ -1,14 +1,59 @@
|
|||
@tool
|
||||
class_name MultiMorseBanner
|
||||
extends Control
|
||||
|
||||
static var sample_hz := 22050.0
|
||||
static var vol_on := -30
|
||||
var phase := 0.0
|
||||
|
||||
var num: int
|
||||
var tone_hz: int
|
||||
var color_on := Color(0, 128, 0)
|
||||
var color_off := Color(0, 0, 0)
|
||||
var last_delta := 0.0
|
||||
@export_range(0.1, 120.0) var display_sec := 5.0
|
||||
@export var stretch_display := false
|
||||
var playback;
|
||||
|
||||
func _ready() -> void:
|
||||
$Player.stream.mix_rate = sample_hz
|
||||
$Player.volume_db = -100
|
||||
$Player.play()
|
||||
playback = $Player.get_stream_playback()
|
||||
fill_buffer()
|
||||
|
||||
var morse_step_perc := 0.45
|
||||
const MMB_SCENE := preload("res://scenes/MultiMorseBanner.tscn")
|
||||
|
||||
class LocalMorseState:
|
||||
var states: Array[int] = []
|
||||
var curr_state := false
|
||||
var last_change: int = 0
|
||||
var start_time := 0
|
||||
|
||||
func reset() -> void:
|
||||
last_change = Time.get_ticks_msec()
|
||||
start_time = last_change
|
||||
states = []
|
||||
|
||||
func set_state(state: bool) -> void:
|
||||
if state == curr_state:
|
||||
return
|
||||
curr_state = state
|
||||
|
||||
var now := Time.get_ticks_msec()
|
||||
states.push_back(now - last_change)
|
||||
last_change = now
|
||||
|
||||
var morse_state := LocalMorseState.new()
|
||||
|
||||
static func new_banner(num: int, color: Color, tone: int):
|
||||
var mmb = MMB_SCENE.instantiate()
|
||||
mmb.num = num
|
||||
mmb.color_on = color
|
||||
mmb.tone_hz = tone
|
||||
|
||||
return mmb
|
||||
|
||||
func _draw_morse_rect(x: float, width: float, state: bool):
|
||||
var rect := Rect2(max(x, 0.0), morse_step_perc * size.y, width, (0.5 - morse_step_perc) * size.y)
|
||||
|
@ -22,18 +67,18 @@ func _draw():
|
|||
if Engine.is_editor_hint():
|
||||
return
|
||||
|
||||
var morse_on := MorseState.curr_state
|
||||
var first_time := Time.get_ticks_msec() - MorseState.last_change
|
||||
var morse_on := morse_state.curr_state
|
||||
var first_time := Time.get_ticks_msec() - morse_state.last_change
|
||||
var curr_x := float(size.x)
|
||||
|
||||
var px_per_s := 0.0
|
||||
if not stretch_display:
|
||||
px_per_s = size.x / display_sec
|
||||
else:
|
||||
px_per_s = size.x / (Time.get_ticks_msec() - MorseState.start_time) * 1000.0
|
||||
px_per_s = size.x / (Time.get_ticks_msec() - morse_state.start_time) * 1000.0
|
||||
|
||||
for n in [-1] + range(MorseState.states.size() - 1, -1, -1):
|
||||
var duration := first_time if n == -1 else MorseState.states[n]
|
||||
for n in [-1] + range(morse_state.states.size() - 1, -1, -1):
|
||||
var duration := first_time if n == -1 else morse_state.states[n]
|
||||
var rect_width: float = min(duration / 1000.0 * px_per_s, curr_x)
|
||||
curr_x -= rect_width
|
||||
if morse_on:
|
||||
|
@ -46,3 +91,21 @@ func _draw():
|
|||
func _process(_delta):
|
||||
last_delta += _delta
|
||||
queue_redraw()
|
||||
fill_buffer()
|
||||
|
||||
func set_morse_state(state: bool) -> void:
|
||||
morse_state.set_state(state)
|
||||
# morse_state = state
|
||||
if state:
|
||||
$Player.volume_db = vol_on
|
||||
else:
|
||||
$Player.volume_db = -100
|
||||
|
||||
func fill_buffer():
|
||||
var increment = tone_hz / sample_hz
|
||||
var frames_available = playback.get_frames_available()
|
||||
|
||||
for i in range(frames_available):
|
||||
playback.push_frame(Vector2.ONE * sin(phase * TAU))
|
||||
phase = fmod(phase + increment, 1.0)
|
||||
|
||||
|
|
|
@ -4,10 +4,32 @@ var server := "localhost"
|
|||
var port := "3784"
|
||||
var ws := WebSocketPeer.new()
|
||||
|
||||
var mb_scene := preload("res://scenes/MultiMorseBanner.tscn")
|
||||
var available_freqs = []
|
||||
var mmb_self: MultiMorseBanner
|
||||
var mmb_others: Dictionary[String, MultiMorseBanner]
|
||||
|
||||
class PlayerData:
|
||||
var num: int
|
||||
var color: Color
|
||||
var tone: int
|
||||
|
||||
func _init(num, color, tone):
|
||||
self.num = num
|
||||
self.color = color
|
||||
self.tone = tone
|
||||
|
||||
var player_data := [
|
||||
PlayerData.new(0, Color( 0, 255, 0), 880),
|
||||
PlayerData.new(1, Color(255, 0, 0), 880),
|
||||
PlayerData.new(2, Color( 0, 0, 255), 880),
|
||||
PlayerData.new(3, Color(255, 0, 255), 880),
|
||||
]
|
||||
|
||||
func _ready() -> void:
|
||||
# FIXME: connection handling / reconnect
|
||||
# FIXME: status / error messages
|
||||
# FIXME: randomize default join frquency
|
||||
# FIXME: automatic refresh
|
||||
print("ws://%s:%s" % [server, port])
|
||||
ws.connect_to_url("ws://%s:%s" % [server, port])
|
||||
|
||||
|
@ -31,6 +53,9 @@ func _handle_packet() -> void:
|
|||
print("parsed ", parsed)
|
||||
|
||||
match parsed["type"]:
|
||||
"hello":
|
||||
# fetch frequency list on first join
|
||||
_on_refresh_button_pressed()
|
||||
"join":
|
||||
_join_freq(parsed["freq"])
|
||||
|
||||
|
@ -42,7 +67,14 @@ func _handle_packet() -> void:
|
|||
var idx: int = %FreqList.add_item(text)
|
||||
%FreqList.set_item_metadata(idx, freq)
|
||||
|
||||
func _join_freq(freq: String):
|
||||
func _join_freq(freq: String, player_id: String, other_players: Array[String]):
|
||||
for child in %PlayerContainer.get_children():
|
||||
%PlayerContainer.remove_child(child)
|
||||
|
||||
mmb_self = make_player(0)
|
||||
for n, player_id in enumeerate(other_players):
|
||||
make_player(n + 1)
|
||||
|
||||
%FreqLabel.text = "%s MHz" % freq
|
||||
%ConnectView.hide()
|
||||
%MorseView.show()
|
||||
|
@ -67,3 +99,25 @@ func _on_freq_list_join(index: int, at_position: Vector2, mouse_button_index: in
|
|||
var join_cmd := {"cmd": "join", "freq": freq, "type": "cw-generator"}
|
||||
ws.send_text(JSON.stringify(join_cmd) + "\n")
|
||||
|
||||
func make_player(no: int):
|
||||
var pd: PlayerData
|
||||
if no < player_data.size():
|
||||
pd = player_data[no]
|
||||
else:
|
||||
pd = PlayerData.new(no, Color(randi_range(0, 255), randi_range(0, 255), randi_range(0, 255)), randi_range(440, 440 * 3))
|
||||
|
||||
var mmb = MultiMorseBanner.new_banner(pd.num, pd.color, pd.tone)
|
||||
%PlayerContainer.add_child(mmb)
|
||||
return mmb
|
||||
|
||||
|
||||
func _on_morse_button_button_down() -> void:
|
||||
if not mmb_self:
|
||||
return
|
||||
mmb_self.set_morse_state(true)
|
||||
|
||||
|
||||
func _on_morse_button_button_up() -> void:
|
||||
if not mmb_self:
|
||||
return
|
||||
mmb_self.set_morse_state(false)
|
||||
|
|
|
@ -92,7 +92,7 @@ class Client:
|
|||
|
||||
self.curr_freq = freq
|
||||
self.freqs[freq] = [self]
|
||||
await self._send(type="join", freq=self.curr_freq, others=[])
|
||||
await self._send(type="join", freq=self.curr_freq, self_id=self.id, others=[])
|
||||
|
||||
async def _join_room(self, data):
|
||||
if self.curr_freq:
|
||||
|
@ -108,9 +108,12 @@ class Client:
|
|||
await self._send_error(f"Frequency {freq} not available")
|
||||
return
|
||||
|
||||
self.curr_freq = freq
|
||||
self.freqs[freq].append(self)
|
||||
# FIXME: do we need locking here?
|
||||
await self._send(type="join", freq=self.curr_freq, players=[c.id for c in self._others(freq)])
|
||||
print("FREQ", self.curr_freq, freq, self.freqs)
|
||||
await self._send(type="join", freq=self.curr_freq, self_id=self.id, players=[c.id for c in self._others(freq)
|
||||
if not c.id == self.id])
|
||||
for other in self._others(freq):
|
||||
await self._send(type="player-joined", player=self.id)
|
||||
|
||||
|
|
Loading…
Reference in New Issue