Add simple gui client to examples
This commit is contained in:
parent
ad7ef13926
commit
dc72204140
73
examples/08_gui_snapshot.rb
Executable file
73
examples/08_gui_snapshot.rb
Executable file
|
@ -0,0 +1,73 @@
|
|||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'gosu'
|
||||
require_relative '../lib/teeworlds_client'
|
||||
|
||||
class Entitiy
|
||||
attr_reader :x, :y
|
||||
|
||||
def initialize(attr = {})
|
||||
@x = attr[:x]
|
||||
@y = attr[:y]
|
||||
end
|
||||
end
|
||||
|
||||
class Tee < Entitiy
|
||||
attr_reader :w, :h
|
||||
|
||||
def initialize(attr = {})
|
||||
@w = 32
|
||||
@h = 32
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
WINDOW_WIDTH = 800
|
||||
WINDOW_HEIGHT = 500
|
||||
|
||||
class Gui < Gosu::Window
|
||||
def initialize
|
||||
super WINDOW_WIDTH, WINDOW_HEIGHT
|
||||
self.caption = 'ruby teeworlds client'
|
||||
@client = TeeworldsClient.new
|
||||
@client.connect('localhost', 8303, detach: true)
|
||||
@tees = {}
|
||||
end
|
||||
|
||||
def update
|
||||
@client.on_snapshot do |_, snap|
|
||||
snap.items.each do |item|
|
||||
next unless item.instance_of?(NetObj::Character)
|
||||
|
||||
player = item.to_h
|
||||
@tees[player[:id]] = Tee.new(player)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def center_around_tee(tee)
|
||||
wc = WINDOW_WIDTH / 2
|
||||
hc = WINDOW_HEIGHT / 2
|
||||
x = -tee.x + wc
|
||||
y = -tee.y + hc
|
||||
Entitiy.new(x:, y:)
|
||||
end
|
||||
|
||||
def draw
|
||||
return if @tees.empty?
|
||||
|
||||
offset = center_around_tee(@tees.first.last)
|
||||
@tees.each do |_id, tee|
|
||||
draw_rect(
|
||||
tee.x + offset.x,
|
||||
tee.y + offset.y,
|
||||
tee.w,
|
||||
tee.h,
|
||||
Gosu::Color.argb(0xff_00ff00)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Gui.new.show
|
|
@ -155,11 +155,15 @@ class GameClient
|
|||
|
||||
def on_snapshot(chunk)
|
||||
u = SnapshotUnpacker.new
|
||||
game_tick = u.snap_single(chunk)
|
||||
return if game_tick.nil?
|
||||
snapshot = u.snap_single(chunk)
|
||||
|
||||
return if snapshot.game_tick.nil?
|
||||
|
||||
context = Context.new(nil, chunk:)
|
||||
return if call_hook(:snapshot, context, snapshot).nil?
|
||||
|
||||
# ack every snapshot no matter how broken
|
||||
@ack_game_tick = game_tick
|
||||
@ack_game_tick = snapshot.game_tick
|
||||
return unless (@pred_game_tick - @ack_game_tick).abs > 10
|
||||
|
||||
@pred_game_tick = @ack_game_tick + 1
|
||||
|
|
|
@ -63,6 +63,7 @@ class SnapItemBase
|
|||
|
||||
def to_h
|
||||
hash = {}
|
||||
hash[:id] = @id
|
||||
@field_names.each_with_index do |name, index|
|
||||
hash[name] = @fields[index]
|
||||
end
|
||||
|
|
|
@ -20,6 +20,14 @@ require_relative 'events/death'
|
|||
require_relative 'events/hammer_hit'
|
||||
require_relative '../packer'
|
||||
|
||||
class Snapshot
|
||||
attr_accessor :game_tick, :items
|
||||
|
||||
def initialize(items)
|
||||
@items = items
|
||||
end
|
||||
end
|
||||
|
||||
class SnapshotUnpacker
|
||||
def snap_single(chunk)
|
||||
u = Unpacker.new(chunk.data)
|
||||
|
@ -104,6 +112,7 @@ class SnapshotUnpacker
|
|||
invalid = false
|
||||
item_type = u.get_int
|
||||
id_parsed = u.parsed.last
|
||||
snap_items = []
|
||||
while item_type
|
||||
obj = nil
|
||||
if NetObj::PlayerInput.match_type?(item_type)
|
||||
|
@ -146,6 +155,7 @@ class SnapshotUnpacker
|
|||
puts "no match #{item_type}"
|
||||
end
|
||||
if obj
|
||||
snap_items.push(obj)
|
||||
notes += obj.notes
|
||||
notes.push([
|
||||
:green,
|
||||
|
@ -166,12 +176,14 @@ class SnapshotUnpacker
|
|||
id_parsed = u.parsed.last
|
||||
end
|
||||
|
||||
hexdump_lines(data.pack('C*'), 1, notes, legend: :inline).each do |hex|
|
||||
puts " #{hex}"
|
||||
end
|
||||
# hexdump_lines(data.pack('C*'), 1, notes, legend: :inline).each do |hex|
|
||||
# puts " #{hex}"
|
||||
# end
|
||||
|
||||
exit 1 if invalid
|
||||
|
||||
game_tick
|
||||
snapshot = Snapshot.new(snap_items)
|
||||
snapshot.game_tick = game_tick
|
||||
snapshot
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue