Add graze
This commit is contained in:
parent
6eec1f6181
commit
a0f27fe378
6 changed files with 121 additions and 60 deletions
|
|
@ -41,3 +41,12 @@ script = ExtResource("4_ubrrh")
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
script = ExtResource("2_b2dol")
|
script = ExtResource("2_b2dol")
|
||||||
player = NodePath("../Player")
|
player = NodePath("../Player")
|
||||||
|
|
||||||
|
[node name="GrazeLabel" type="RichTextLabel" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
z_index = 5
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 10
|
||||||
|
anchor_right = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
fit_content = true
|
||||||
|
|
|
||||||
|
|
@ -32,11 +32,13 @@ func _on_match_state(p_state : NakamaRTAPI.MatchData):
|
||||||
if data["forcePlayerPos"]:
|
if data["forcePlayerPos"]:
|
||||||
player.set_position_data(
|
player.set_position_data(
|
||||||
Vector2(
|
Vector2(
|
||||||
float(data["playerPos"]["x"]),
|
float(data["playerHitPos"]["x"]),
|
||||||
float(data["playerPos"]["y"])
|
float(data["playerHitPos"]["y"])
|
||||||
),
|
),
|
||||||
float(data["playerPos"]["radius_multiplier"])
|
float(data["playerHitPos"]["radius_multiplier"]),
|
||||||
|
float(data["playerGrazePos"]["radius_multiplier"])
|
||||||
)
|
)
|
||||||
|
%GrazeLabel.text = "Graze: " + str(data["graze"])
|
||||||
|
|
||||||
# Handle player death if there is an ongoing death timer
|
# Handle player death if there is an ongoing death timer
|
||||||
if int(data["deathTimer"]) > 0:
|
if int(data["deathTimer"]) > 0:
|
||||||
|
|
@ -61,6 +63,7 @@ func _on_match_state(p_state : NakamaRTAPI.MatchData):
|
||||||
# Reimplemented from ScalableSprite2D here atm
|
# Reimplemented from ScalableSprite2D here atm
|
||||||
var scale_ratio = ((b["radius_multiplier"] * 2) * Globals.SERVER_SIZE.x) / bullet.texture.get_width()
|
var scale_ratio = ((b["radius_multiplier"] * 2) * Globals.SERVER_SIZE.x) / bullet.texture.get_width()
|
||||||
bullet.scale = Vector2(scale_ratio, scale_ratio)
|
bullet.scale = Vector2(scale_ratio, scale_ratio)
|
||||||
|
bullet.z_index = 4
|
||||||
|
|
||||||
%BulletManager.add_child(bullet)
|
%BulletManager.add_child(bullet)
|
||||||
%BulletManager.bullets.append(bullet)
|
%BulletManager.bullets.append(bullet)
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,10 @@ extends Node2D
|
||||||
|
|
||||||
@export var speed = 80
|
@export var speed = 80
|
||||||
var velocity := Vector2.ZERO
|
var velocity := Vector2.ZERO
|
||||||
var collision: DanmakuCircle = DanmakuCircle.new()
|
var hurt_collision: DanmakuCircle = DanmakuCircle.new()
|
||||||
|
var graze_collision: DanmakuCircle = DanmakuCircle.new()
|
||||||
|
|
||||||
# This is temporary, it should be defined per-sprite when I get to the skin system
|
const PLAYER_BODY_WIDTH_MULTIPLIER = 0.18 # This is temporary, it should be defined per-sprite when I get to the skin system
|
||||||
const PLAYER_BODY_WIDTH_MULTIPLIER = 0.18
|
|
||||||
|
|
||||||
var alive: bool = true
|
var alive: bool = true
|
||||||
|
|
||||||
|
|
@ -31,16 +31,22 @@ func _physics_process(delta: float):
|
||||||
var attempted_position := position + (velocity * delta)
|
var attempted_position := position + (velocity * delta)
|
||||||
attempted_position = attempted_position.clamp(Vector2(0, 0), Globals.SERVER_SIZE)
|
attempted_position = attempted_position.clamp(Vector2(0, 0), Globals.SERVER_SIZE)
|
||||||
|
|
||||||
set_position_data(attempted_position, null)
|
set_position_data(attempted_position, null, null)
|
||||||
|
|
||||||
func set_position_data(pos: Vector2, hurtcircle_scale_multiplier):
|
func set_position_data(pos: Vector2, hurtcircle_scale_multiplier, grazecircle_scale_multiplier):
|
||||||
position = pos
|
position = pos
|
||||||
collision.set_position(pos.x, pos.y)
|
hurt_collision.set_position(pos.x, pos.y)
|
||||||
|
graze_collision.set_position(pos.x, pos.y)
|
||||||
|
|
||||||
if hurtcircle_scale_multiplier:
|
if hurtcircle_scale_multiplier:
|
||||||
collision.set_radius(Globals.SERVER_SIZE.x*hurtcircle_scale_multiplier)
|
hurt_collision.set_radius(Globals.SERVER_SIZE.x*hurtcircle_scale_multiplier)
|
||||||
$HurtcircleSprite.scale_sprite(hurtcircle_scale_multiplier*2)
|
$HurtcircleSprite.scale_sprite(hurtcircle_scale_multiplier*2)
|
||||||
|
|
||||||
|
if grazecircle_scale_multiplier:
|
||||||
|
graze_collision.set_radius(Globals.SERVER_SIZE.x*grazecircle_scale_multiplier)
|
||||||
|
$GrazecircleSprite.scale_sprite(grazecircle_scale_multiplier*2)
|
||||||
|
|
||||||
|
|
||||||
func kill():
|
func kill():
|
||||||
if alive == false:
|
if alive == false:
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,30 @@
|
||||||
[gd_scene load_steps=6 format=3 uid="uid://cd3tqt7hr5pqs"]
|
[gd_scene load_steps=7 format=3 uid="uid://cd3tqt7hr5pqs"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://bhwiun72wpk6e" path="res://danmaku!/player.gd" id="1_r7xhp"]
|
[ext_resource type="Script" uid="uid://bhwiun72wpk6e" path="res://danmaku!/player.gd" id="1_r7xhp"]
|
||||||
[ext_resource type="Texture2D" uid="uid://bs3fntlmlqpt2" path="res://icon.svg" id="2_04s0l"]
|
[ext_resource type="Texture2D" uid="uid://bs3fntlmlqpt2" path="res://icon.svg" id="2_04s0l"]
|
||||||
[ext_resource type="Texture2D" uid="uid://c3deywcu4du2b" path="res://test-collision.png" id="3_gf44i"]
|
[ext_resource type="Texture2D" uid="uid://c3deywcu4du2b" path="res://test-collision.png" id="3_gf44i"]
|
||||||
[ext_resource type="Script" uid="uid://v6jris184o8u" path="res://danmaku!/ScalableSprite2D.gd" id="3_u0x7w"]
|
[ext_resource type="Script" uid="uid://v6jris184o8u" path="res://danmaku!/ScalableSprite2D.gd" id="3_u0x7w"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://brcxly3s7d1jt" path="res://test-graze.png" id="5_273wv"]
|
||||||
[ext_resource type="AudioStream" uid="uid://c5n7x6q67tp78" path="res://test-death-noise.mp3" id="5_poktv"]
|
[ext_resource type="AudioStream" uid="uid://c5n7x6q67tp78" path="res://test-death-noise.mp3" id="5_poktv"]
|
||||||
|
|
||||||
[node name="Player" type="Node2D"]
|
[node name="Player" type="Node2D"]
|
||||||
script = ExtResource("1_r7xhp")
|
script = ExtResource("1_r7xhp")
|
||||||
|
|
||||||
[node name="BodySprite" type="Sprite2D" parent="."]
|
[node name="BodySprite" type="Sprite2D" parent="."]
|
||||||
|
z_index = 1
|
||||||
texture = ExtResource("2_04s0l")
|
texture = ExtResource("2_04s0l")
|
||||||
script = ExtResource("3_u0x7w")
|
script = ExtResource("3_u0x7w")
|
||||||
|
|
||||||
[node name="HurtcircleSprite" type="Sprite2D" parent="."]
|
[node name="HurtcircleSprite" type="Sprite2D" parent="."]
|
||||||
|
z_index = 3
|
||||||
texture = ExtResource("3_gf44i")
|
texture = ExtResource("3_gf44i")
|
||||||
script = ExtResource("3_u0x7w")
|
script = ExtResource("3_u0x7w")
|
||||||
|
|
||||||
|
[node name="GrazecircleSprite" type="Sprite2D" parent="."]
|
||||||
|
z_index = 2
|
||||||
|
texture = ExtResource("5_273wv")
|
||||||
|
script = ExtResource("3_u0x7w")
|
||||||
|
|
||||||
[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."]
|
[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."]
|
||||||
stream = ExtResource("5_poktv")
|
stream = ExtResource("5_poktv")
|
||||||
volume_db = -20.0
|
volume_db = -20.0
|
||||||
|
|
|
||||||
BIN
client/test-graze.png
Normal file
BIN
client/test-graze.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 978 B |
133
server/main.go
133
server/main.go
|
|
@ -13,7 +13,6 @@ import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"math"
|
"math"
|
||||||
"math/rand"
|
|
||||||
"slices"
|
"slices"
|
||||||
|
|
||||||
"github.com/heroiclabs/nakama-common/runtime"
|
"github.com/heroiclabs/nakama-common/runtime"
|
||||||
|
|
@ -32,22 +31,26 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
STAGE_WIDTH float64 = 90.0
|
STAGE_WIDTH float64 = 90.0
|
||||||
STAGE_HEIGHT float64 = 160.0
|
STAGE_HEIGHT float64 = 160.0
|
||||||
BULLET_KILL_BUFFER_WIDTH float64 = 16.0
|
BULLET_KILL_BUFFER_WIDTH float64 = 16.0
|
||||||
PLAYER_COL_RADIUS_MULTIPLIER float64 = 0.01
|
PLAYER_HIT_COL_RADIUS_MULTIPLIER float64 = 0.01
|
||||||
PLAYER_DEATH_TIMER_MAX int = 180
|
PLAYER_GRAZE_COL_RADIUS_MULTIPLIER float64 = 0.04
|
||||||
|
PLAYER_DEATH_TIMER_MAX int = 180
|
||||||
|
GRAZE_ADDITION_MULTIPLIER int = 1000
|
||||||
)
|
)
|
||||||
|
|
||||||
// Interface for registering match handlers
|
// Interface for registering match handlers
|
||||||
type BattleRoyaleMatch struct{}
|
type BattleRoyaleMatch struct{}
|
||||||
|
|
||||||
type PlayerStageState struct {
|
type PlayerStageState struct {
|
||||||
col *C.Circle
|
hitCol *C.Circle
|
||||||
|
grazeCol *C.Circle
|
||||||
bullets []*C.Bullet
|
bullets []*C.Bullet
|
||||||
updatePlayerPos bool
|
updatePlayerPos bool
|
||||||
health int
|
health int
|
||||||
graze int
|
graze int
|
||||||
|
score int
|
||||||
deathTimer int
|
deathTimer int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -58,10 +61,12 @@ type PlayerUpdate struct {
|
||||||
|
|
||||||
type GameTickUpdate struct {
|
type GameTickUpdate struct {
|
||||||
Tick int64 `json:"tick"`
|
Tick int64 `json:"tick"`
|
||||||
PlayerPos map[string]interface{} `json:"playerPos"`
|
PlayerHitPos map[string]interface{} `json:"playerHitPos"`
|
||||||
|
PlayerGrazePos map[string]interface{} `json:"playerGrazePos"`
|
||||||
NewBullets []map[string]interface{} `json:"newBullets"`
|
NewBullets []map[string]interface{} `json:"newBullets"`
|
||||||
ForcePlayerPos bool `json:"forcePlayerPos"`
|
ForcePlayerPos bool `json:"forcePlayerPos"`
|
||||||
DeathTimer int `json:"deathTimer"`
|
DeathTimer int `json:"deathTimer"`
|
||||||
|
Graze int `json:"graze"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type PresenceState struct { // present time! hahahahahahahah!
|
type PresenceState struct { // present time! hahahahahahahah!
|
||||||
|
|
@ -115,7 +120,8 @@ func (m *BattleRoyaleMatch) MatchJoin(ctx context.Context, logger runtime.Logger
|
||||||
lobbyState.presences[presences[i].GetSessionId()] = &PresenceState{
|
lobbyState.presences[presences[i].GetSessionId()] = &PresenceState{
|
||||||
presence: presences[i],
|
presence: presences[i],
|
||||||
stageState: PlayerStageState{
|
stageState: PlayerStageState{
|
||||||
col: C.new_circle(C.double(STAGE_WIDTH*0.5), C.double(STAGE_HEIGHT-STAGE_HEIGHT*0.1), C.double(STAGE_WIDTH*PLAYER_COL_RADIUS_MULTIPLIER)),
|
hitCol: C.new_circle(C.double(STAGE_WIDTH*0.5), C.double(STAGE_HEIGHT-STAGE_HEIGHT*0.1), C.double(STAGE_WIDTH*PLAYER_HIT_COL_RADIUS_MULTIPLIER)),
|
||||||
|
grazeCol: C.new_circle(C.double(STAGE_WIDTH*0.5), C.double(STAGE_HEIGHT-STAGE_HEIGHT*0.1), C.double(STAGE_WIDTH*PLAYER_GRAZE_COL_RADIUS_MULTIPLIER)),
|
||||||
bullets: []*C.Bullet{},
|
bullets: []*C.Bullet{},
|
||||||
updatePlayerPos: true,
|
updatePlayerPos: true,
|
||||||
health: 3,
|
health: 3,
|
||||||
|
|
@ -143,7 +149,8 @@ func (m *BattleRoyaleMatch) MatchLeave(ctx context.Context, logger runtime.Logge
|
||||||
for _, bullet := range playerState.stageState.bullets {
|
for _, bullet := range playerState.stageState.bullets {
|
||||||
C.destroy_bullet(bullet)
|
C.destroy_bullet(bullet)
|
||||||
}
|
}
|
||||||
C.destroy_circle(playerState.stageState.col)
|
C.destroy_circle(playerState.stageState.hitCol)
|
||||||
|
C.destroy_circle(playerState.stageState.grazeCol)
|
||||||
delete(lobbyState.presences, sessionID)
|
delete(lobbyState.presences, sessionID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -215,8 +222,11 @@ func (m *BattleRoyaleMatch) MatchLoop(ctx context.Context, logger runtime.Logger
|
||||||
update.X = math.Max(0, math.Min(update.X, STAGE_WIDTH))
|
update.X = math.Max(0, math.Min(update.X, STAGE_WIDTH))
|
||||||
update.Y = math.Max(0, math.Min(update.Y, STAGE_HEIGHT))
|
update.Y = math.Max(0, math.Min(update.Y, STAGE_HEIGHT))
|
||||||
|
|
||||||
lobbyState.presences[msg.GetSessionId()].stageState.col.x = C.double(update.X)
|
lobbyState.presences[msg.GetSessionId()].stageState.hitCol.x = C.double(update.X)
|
||||||
lobbyState.presences[msg.GetSessionId()].stageState.col.y = C.double(update.Y)
|
lobbyState.presences[msg.GetSessionId()].stageState.hitCol.y = C.double(update.Y)
|
||||||
|
|
||||||
|
lobbyState.presences[msg.GetSessionId()].stageState.grazeCol.x = C.double(update.X)
|
||||||
|
lobbyState.presences[msg.GetSessionId()].stageState.grazeCol.y = C.double(update.Y)
|
||||||
|
|
||||||
if clampedX || clampedY {
|
if clampedX || clampedY {
|
||||||
lobbyState.presences[msg.GetSessionId()].stageState.updatePlayerPos = true
|
lobbyState.presences[msg.GetSessionId()].stageState.updatePlayerPos = true
|
||||||
|
|
@ -240,65 +250,90 @@ func (m *BattleRoyaleMatch) MatchLoop(ctx context.Context, logger runtime.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
if v.stageState.deathTimer == 0 { // If the player's death timer has run out, reset them. 0 is a special deathTimer tick that indicates reset to the clients.
|
if v.stageState.deathTimer == 0 { // If the player's death timer has run out, reset them. 0 is a special deathTimer tick that indicates reset to the clients.
|
||||||
v.stageState.col.x = C.double(STAGE_WIDTH * 0.5)
|
v.stageState.hitCol.x = C.double(STAGE_WIDTH * 0.5)
|
||||||
v.stageState.col.y = C.double(STAGE_HEIGHT - STAGE_HEIGHT*0.1)
|
v.stageState.hitCol.y = C.double(STAGE_HEIGHT - STAGE_HEIGHT*0.1)
|
||||||
|
|
||||||
|
v.stageState.grazeCol.x = C.double(STAGE_WIDTH * 0.5)
|
||||||
|
v.stageState.grazeCol.y = C.double(STAGE_HEIGHT - STAGE_HEIGHT*0.1)
|
||||||
|
|
||||||
v.stageState.updatePlayerPos = true
|
v.stageState.updatePlayerPos = true
|
||||||
} else { // If the player is alive, check if the player collided with a bullet and kill them if so
|
} else if v.stageState.deathTimer == -1 { // If the player is alive, check if the player collided with a bullet and kill them if so
|
||||||
if slices.ContainsFunc(v.stageState.bullets, func(b *C.Bullet) bool {
|
if slices.ContainsFunc(v.stageState.bullets, func(b *C.Bullet) bool {
|
||||||
return bool(C.bullet_collides_with(b, C.int64_t(tick), v.stageState.col))
|
return bool(C.bullet_collides_with(b, C.int64_t(tick), v.stageState.hitCol))
|
||||||
}) {
|
}) {
|
||||||
v.stageState.deathTimer = PLAYER_DEATH_TIMER_MAX
|
v.stageState.deathTimer = PLAYER_DEATH_TIMER_MAX
|
||||||
|
} else if slices.ContainsFunc(v.stageState.bullets, func(b *C.Bullet) bool { // Otherwise, check the graze col and increment the graze and score
|
||||||
|
return bool(C.bullet_collides_with(b, C.int64_t(tick), v.stageState.grazeCol))
|
||||||
|
}) {
|
||||||
|
v.stageState.graze += GRAZE_ADDITION_MULTIPLIER
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var newBulletsToBroadcast = []map[string]interface{}{}
|
var newBulletsToBroadcast = []map[string]interface{}{}
|
||||||
|
|
||||||
// Test bullet spawning, only when player is alive
|
if tick%30 == 0 && v.stageState.deathTimer == -1 {
|
||||||
if tick%10 == 0 && v.stageState.deathTimer == -1 {
|
numBullets := 20
|
||||||
velx := (rand.Float64() * STAGE_WIDTH) / float64(lobbyState.tickRate)
|
spreadAngle := 60.0 // Spread in degrees
|
||||||
vely := (rand.Float64() * STAGE_WIDTH) / float64(lobbyState.tickRate)
|
startAngle := 90 - (spreadAngle / 2)
|
||||||
radius_multiplier := 0.01 + rand.Float64()*(0.1-0.01)
|
bulletSpeed := STAGE_WIDTH / float64(lobbyState.tickRate) / 3
|
||||||
vel_x_sign := 2*rand.Intn(2) - 1
|
bulletRadiusMult := 0.03
|
||||||
vel_y_sign := 2*rand.Intn(2) - 1
|
|
||||||
|
|
||||||
bullet := C.new_bullet(
|
// Define a single spawn point near the top of the screen
|
||||||
C.uint8_t(BULLET_LINEAR),
|
spawnX := STAGE_WIDTH / 2 // Centered horizontally
|
||||||
C.int64_t(tick),
|
spawnY := STAGE_HEIGHT * 0.1 // 10% from the top
|
||||||
C.double(STAGE_WIDTH*rand.Float64()),
|
|
||||||
C.double(STAGE_HEIGHT*rand.Float64()),
|
|
||||||
C.double(radius_multiplier*STAGE_WIDTH),
|
|
||||||
C.double(float64(vel_x_sign)*velx),
|
|
||||||
C.double(float64(vel_y_sign)*vely),
|
|
||||||
)
|
|
||||||
|
|
||||||
v.stageState.bullets = append(v.stageState.bullets, bullet)
|
for i := 0; i < numBullets; i++ {
|
||||||
|
angle := startAngle + (spreadAngle/float64(numBullets-1))*float64(i)
|
||||||
|
angleRad := angle * (math.Pi / 180.0)
|
||||||
|
|
||||||
var x, y C.double
|
velx := bulletSpeed * math.Cos(angleRad)
|
||||||
C.bullet_get_current_pos(bullet, C.int64_t(tick), &x, &y)
|
vely := bulletSpeed * math.Sin(angleRad)
|
||||||
|
|
||||||
bulletData := map[string]interface{}{
|
bullet := C.new_bullet(
|
||||||
"class": BULLET_LINEAR,
|
C.uint8_t(BULLET_LINEAR),
|
||||||
"tick": tick,
|
C.int64_t(tick),
|
||||||
"x": float64(x),
|
C.double(spawnX), // Fixed X start position
|
||||||
"y": float64(y),
|
C.double(spawnY), // Fixed Y start position
|
||||||
"radius_multiplier": float64(radius_multiplier),
|
C.double(bulletRadiusMult*STAGE_WIDTH), // Fixed radius
|
||||||
"vel_x": float64(vel_x_sign) * velx,
|
C.double(velx),
|
||||||
"vel_y": float64(vel_y_sign) * vely,
|
C.double(vely),
|
||||||
|
)
|
||||||
|
|
||||||
|
v.stageState.bullets = append(v.stageState.bullets, bullet)
|
||||||
|
|
||||||
|
var x, y C.double
|
||||||
|
C.bullet_get_current_pos(bullet, C.int64_t(tick), &x, &y)
|
||||||
|
|
||||||
|
bulletData := map[string]interface{}{
|
||||||
|
"class": BULLET_LINEAR,
|
||||||
|
"tick": tick,
|
||||||
|
"x": float64(x),
|
||||||
|
"y": float64(y),
|
||||||
|
"radius_multiplier": bulletRadiusMult,
|
||||||
|
"vel_x": velx,
|
||||||
|
"vel_y": vely,
|
||||||
|
}
|
||||||
|
|
||||||
|
newBulletsToBroadcast = append(newBulletsToBroadcast, bulletData)
|
||||||
}
|
}
|
||||||
|
|
||||||
newBulletsToBroadcast = append(newBulletsToBroadcast, bulletData)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var tickData = GameTickUpdate{
|
var tickData = GameTickUpdate{
|
||||||
Tick: tick,
|
Tick: tick,
|
||||||
PlayerPos: map[string]interface{}{
|
PlayerHitPos: map[string]interface{}{
|
||||||
"x": v.stageState.col.x,
|
"x": v.stageState.hitCol.x,
|
||||||
"y": v.stageState.col.y,
|
"y": v.stageState.hitCol.y,
|
||||||
"radius_multiplier": PLAYER_COL_RADIUS_MULTIPLIER,
|
"radius_multiplier": PLAYER_HIT_COL_RADIUS_MULTIPLIER,
|
||||||
|
},
|
||||||
|
PlayerGrazePos: map[string]interface{}{
|
||||||
|
"x": v.stageState.grazeCol.x,
|
||||||
|
"y": v.stageState.grazeCol.y,
|
||||||
|
"radius_multiplier": PLAYER_GRAZE_COL_RADIUS_MULTIPLIER,
|
||||||
},
|
},
|
||||||
NewBullets: newBulletsToBroadcast,
|
NewBullets: newBulletsToBroadcast,
|
||||||
ForcePlayerPos: v.stageState.updatePlayerPos,
|
ForcePlayerPos: v.stageState.updatePlayerPos,
|
||||||
DeathTimer: v.stageState.deathTimer,
|
DeathTimer: v.stageState.deathTimer,
|
||||||
|
Graze: v.stageState.graze,
|
||||||
}
|
}
|
||||||
|
|
||||||
v.stageState.updatePlayerPos = false
|
v.stageState.updatePlayerPos = false
|
||||||
|
|
|
||||||
Reference in a new issue