Archived
1
0
Fork 0

Working shared linear integrator, visualized on client

This commit is contained in:
Sebastian Benjamin 2025-02-05 23:14:39 -08:00
parent 972ab12c64
commit f85469dad4
8 changed files with 127 additions and 52 deletions

View file

@ -4,14 +4,61 @@ var nakama_client: NakamaClient
var nakama_session: NakamaSession
var nakama_socket: NakamaSocket
const SERVER_WIDTH = 90.0
const SERVER_HEIGHT = 160.0
var predicted_tick = 0
var delta_counter = 0
var lerp_factor := 0.0
var bullets = []
func _ready() -> void:
print("Attempting auth.")
await attempt_auth()
print("Attempting to create debug match.")
await create_and_join_debug_match()
nakama_socket.received_match_state.connect(self._on_match_state)
func _process(delta: float) -> void:
pass
delta_counter += delta
if delta_counter >= 0.05:
predicted_tick += 1
delta_counter = 0 # Reset counter
lerp_factor = delta_counter / 0.05 # Normalize factor between 0 and 1
for bullet in bullets:
var prev_pos = bullet.get_current_pos(predicted_tick)
var next_pos = bullet.get_current_pos(predicted_tick + 1)
var interpolated_pos = prev_pos.lerp(next_pos, lerp_factor)
bullet.position = world_to_screen(interpolated_pos)
#var screen_size = get_viewport().size
#bullets = bullets.filter(func(bullet):
# return bullet.position.x >= 0 and bullet.position.x <= screen_size.x and \
# bullet.position.y >= 0 and bullet.position.y <= screen_size.y
#)
func _on_match_state(p_state : NakamaRTAPI.MatchData):
match p_state.op_code:
2: # Spawn bullet
var data = JSON.parse_string(p_state.data)
var bullet = DanmakuBullet.new()
bullet.setup_bullet(
int(data["class"]),
int(data["tick"]),
data["x"],
data["y"],
data["vel_x"],
data["vel_y"])
bullet.position = world_to_screen(bullet.get_current_pos(int(data["tick"])))
bullet.texture = load("res://test-bullet.png")
add_child(bullet)
bullets.append(bullet)
delta_counter = 0
predicted_tick = int(data["tick"])
func attempt_auth() -> void:
nakama_client = Nakama.create_client("defaultkey", "127.0.0.1", 7350, "http")
@ -36,3 +83,13 @@ func create_and_join_debug_match() -> void:
if debug_br_match.is_exception():
print("An error occurred when joining debug BR match: %s" % response)
return
func world_to_screen(server_pos: Vector2) -> Vector2:
var screen_size = get_viewport().size
var scale_x = screen_size.x / SERVER_WIDTH
var scale_y = screen_size.y / SERVER_HEIGHT
var client_x = server_pos.x * scale_x
var client_y = server_pos.y * scale_y
return Vector2(client_x, client_y)

View file

@ -4,11 +4,11 @@ compatibility_minimum = 4.1
reloadable = true
[libraries]
linux.debug.x86_64 = "res://../godot_wrapper/target/debug/libgodot_wrapper.so"
linux.release.x86_64 = "res://../godot_wrapper/target/release/libgodot_wrapper.so"
windows.debug.x86_64 = "res://../godot_wrapper/target/debug/godot_wrapper.dll"
windows.release.x86_64 = "res://../godot_wrapper/target/release/godot_wrapper.dll"
macos.debug = "res://../godot_wrapper/target/debug/libgodot_wrapper.dylib"
macos.release = "res://../godot_wrapper/target/release/libgodot_wrapper.dylib"
macos.debug.arm64 = "res://../godot_wrapper/target/debug/libgodot_wrapper.dylib"
macos.release.arm64 = "res://../godot_wrapper/target/release/libgodot_wrapper.dylib"
linux.debug.x86_64 = "res://../godot-extension/target/release/libgodot_extension.so"
linux.release.x86_64 = "res://../godot-extension/target/release/libgodot_extension.so"
windows.debug.x86_64 = "res://../godot-extension/target/release/godot_extension.dll"
windows.release.x86_64 = "res://../godot-extension/target/release/godot_extension.dll"
macos.debug = "res://../godot-extension/target/release/libgodot_extension.dylib"
macos.release = "res://../godot-extension/target/release/libgodot_extension.dylib"
macos.debug.arm64 = "res://../godot-extension/target/release/libgodot_extension.dylib"
macos.release.arm64 = "res://../godot-extension/target/release/libgodot_extension.dylib"

View file

@ -18,3 +18,9 @@ config/icon="res://icon.svg"
[autoload]
Nakama="*res://addons/com.heroiclabs.nakama/Nakama.gd"
[importer_defaults]
animation_library={
"animation/fps": 120.0
}

BIN
client/test-bullet.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 743 B

View file

@ -0,0 +1,41 @@
use godot::prelude::*;
use shared::bullet::Bullet;
use godot::classes::{ Sprite2D, ISprite2D };
#[derive(GodotClass)]
#[class(base=Sprite2D)]
struct DanmakuBullet {
bullet_state: Bullet,
base: Base<Sprite2D>,
}
#[godot_api]
impl ISprite2D for DanmakuBullet {
fn init(base: Base<Sprite2D>) -> Self {
Self {
bullet_state: Bullet::new(0, 0, 0.0, 0.0, [0.0, 0.0]),
base,
}
}
}
#[godot_api]
impl DanmakuBullet {
#[func]
fn setup_bullet(&mut self, class: u8, spawn_time: i64, spawn_x: f64, spawn_y: f64, param_x: f64, param_y: f64) {
self.bullet_state = Bullet::new(class, spawn_time, spawn_x, spawn_y, [param_x, param_y]);
}
#[func]
fn get_current_pos(&self, tick: i64) -> Vector2 {
let (x, y) = self.bullet_state.get_current_pos(tick);
Vector2::new(x as f32, y as f32)
}
#[func]
fn beyond_kill_boundary(&self, tick: i64) -> bool {
self.bullet_state.beyond_kill_boundary(tick)
}
}

View file

@ -1,37 +0,0 @@
use godot::prelude::*;
use shared::bullet::Bullet;
#[derive(GodotClass)]
#[class(base=RefCounted)]
struct DanmakuBullet {
bullet_state: Bullet,
base: Base<RefCounted>,
}
#[godot_api]
impl BulletWrapper {
#[func]
fn new(class: u8, spawn_time: i64, spawn_x: f64, spawn_y: f64, parameters: [f64; 2]) -> Self {
Self {
bullet_state: Bullet::new(class, spawn_time, spawn_x, spawn_y, parameters),
base: Default::default(),
}
}
#[func]
fn get_current_pos(&self, tick: i64) -> (f64, f64) {
self.bullet_state.get_current_pos(tick)
}
#[func]
fn beyond_kill_boundary(&self, tick: i64) -> bool {
self.bullet_state.beyond_kill_boundary(tick)
}
}
struct BulletExtension;
#[gdextension]
unsafe impl ExtensionLibrary for BulletExtension {}

View file

@ -1 +1,7 @@
mod godot;
mod bullet;
use godot::prelude::*;
struct Danmaku;
#[gdextension]
unsafe impl ExtensionLibrary for Danmaku {}

View file

@ -154,17 +154,19 @@ func (m *BattleRoyaleMatch) MatchLoop(ctx context.Context, logger runtime.Logger
}
// Test bullet spawning
if tick%20 == 0 {
if tick%1 == 0 {
for _, v := range lobbyState.presences {
vel := rand.Float64()*(STAGE_WIDTH/float64(lobbyState.tickRate)) + 1.0
vel_x_sign := 2*rand.Intn(2) - 1
vel_y_sign := 2*rand.Intn(2) - 1
bullet := C.new_bullet(
C.uint8_t(BULLET_LINEAR),
C.int64_t(tick),
C.double(STAGE_WIDTH*rand.Float64()),
C.double(STAGE_HEIGHT*rand.Float64()),
C.double(vel),
C.double(vel),
C.double(float64(vel_x_sign)*vel),
C.double(float64(vel_y_sign)*vel),
)
var x, y C.double
@ -175,8 +177,8 @@ func (m *BattleRoyaleMatch) MatchLoop(ctx context.Context, logger runtime.Logger
"tick": tick,
"x": float64(x),
"y": float64(y),
"vel_x": vel,
"vel_y": vel,
"vel_x": float64(vel_x_sign) * vel,
"vel_y": float64(vel_y_sign) * vel,
}
data, err := json.Marshal(bulletData)