cgo wrapper file
This commit is contained in:
parent
c41604e35b
commit
234b1df8f3
4 changed files with 117 additions and 53 deletions
|
|
@ -1,6 +1,6 @@
|
|||
[gd_scene load_steps=5 format=3 uid="uid://dsiowq0rnacln"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://cd3tqt7hr5pqs" path="res://danmaku!/Player.tscn" id="1_22cjd"]
|
||||
[ext_resource type="PackedScene" uid="uid://qvo806pvgbdn" path="res://danmaku!/Player.tscn" id="1_22cjd"]
|
||||
[ext_resource type="Script" uid="uid://ggkxv1cb1bjk" path="res://danmaku!/scaling.gd" id="1_o1mqp"]
|
||||
[ext_resource type="Script" uid="uid://cd67rrch5h4t7" path="res://danmaku!/network_manager.gd" id="2_b2dol"]
|
||||
[ext_resource type="Script" uid="uid://ddc5iqgtyv2ns" path="res://danmaku!/BulletManager.gd" id="4_ubrrh"]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
[gd_scene load_steps=7 format=3 uid="uid://cd3tqt7hr5pqs"]
|
||||
[gd_scene load_steps=7 format=3 uid="uid://qvo806pvgbdn"]
|
||||
|
||||
[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"]
|
||||
|
|
|
|||
79
server/ffi.go
Normal file
79
server/ffi.go
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
package main
|
||||
|
||||
/*
|
||||
#cgo CFLAGS: -I ${SRCDIR}/lib
|
||||
#cgo LDFLAGS: -L ${SRCDIR}/lib -l ffi_wrapper
|
||||
#include "ffi-wrapper.h"
|
||||
#include <stdlib.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
// Circles
|
||||
type Circle struct {
|
||||
cptr *C.Circle
|
||||
}
|
||||
|
||||
func NewCircle(x float64, y float64, rad float64) Circle {
|
||||
return Circle{
|
||||
cptr: C.new_circle(C.double(x), C.double(y), C.double(rad)),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Circle) UpdatePos(x float64, y float64) {
|
||||
c.cptr.x = C.double(x)
|
||||
c.cptr.y = C.double(y)
|
||||
}
|
||||
|
||||
func DestroyCircle(circle Circle) {
|
||||
if circle.cptr == nil {
|
||||
return
|
||||
}
|
||||
|
||||
C.destroy_circle(circle.cptr)
|
||||
}
|
||||
|
||||
func (c *Circle) GetPos() (float64, float64) {
|
||||
return float64(c.cptr.x), float64(c.cptr.y)
|
||||
}
|
||||
|
||||
// Bullets
|
||||
type Bullet struct {
|
||||
cptr *C.Bullet
|
||||
}
|
||||
|
||||
func NewLinearBullet(tick int64, spawnX float64, spawnY float64, radius float64, velX float64, velY float64) Bullet {
|
||||
return Bullet{
|
||||
cptr: C.new_bullet(
|
||||
C.uint8_t(0),
|
||||
C.int64_t(tick),
|
||||
C.double(spawnX),
|
||||
C.double(spawnY),
|
||||
C.double(radius),
|
||||
C.double(velX),
|
||||
C.double(velY),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
func DestroyBullet(bullet Bullet) {
|
||||
if bullet.cptr == nil {
|
||||
return
|
||||
}
|
||||
|
||||
C.destroy_bullet(bullet.cptr)
|
||||
}
|
||||
|
||||
func (b *Bullet) BeyondKillBoundary(tick int64) bool {
|
||||
return bool(C.bullet_beyond_kill_boundary(b.cptr, C.int64_t(tick)))
|
||||
}
|
||||
|
||||
func (b *Bullet) CollidesWith(circle Circle, tick int64) bool {
|
||||
return bool(C.bullet_collides_with(b.cptr, C.int64_t(tick), circle.cptr))
|
||||
}
|
||||
|
||||
func (b *Bullet) GetPos(tick int64) (float64, float64) {
|
||||
var x, y C.double
|
||||
C.bullet_get_current_pos(b.cptr, C.int64_t(tick), &x, &y)
|
||||
|
||||
return float64(x), float64(y)
|
||||
}
|
||||
|
|
@ -1,13 +1,5 @@
|
|||
package main
|
||||
|
||||
/*
|
||||
#cgo CFLAGS: -I ${SRCDIR}/lib
|
||||
#cgo LDFLAGS: -L ${SRCDIR}/lib -l ffi_wrapper
|
||||
#include "ffi-wrapper.h"
|
||||
#include <stdlib.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
|
|
@ -44,9 +36,9 @@ const (
|
|||
type BattleRoyaleMatch struct{}
|
||||
|
||||
type PlayerStageState struct {
|
||||
hitCol *C.Circle
|
||||
grazeCol *C.Circle
|
||||
bullets []*C.Bullet
|
||||
hitCol Circle
|
||||
grazeCol Circle
|
||||
bullets []Bullet
|
||||
updatePlayerPos bool
|
||||
health int
|
||||
graze int
|
||||
|
|
@ -120,9 +112,9 @@ func (m *BattleRoyaleMatch) MatchJoin(ctx context.Context, logger runtime.Logger
|
|||
lobbyState.presences[presences[i].GetSessionId()] = &PresenceState{
|
||||
presence: presences[i],
|
||||
stageState: PlayerStageState{
|
||||
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{},
|
||||
hitCol: NewCircle(STAGE_WIDTH*0.5, STAGE_HEIGHT-STAGE_HEIGHT*0.1, STAGE_WIDTH*PLAYER_HIT_COL_RADIUS_MULTIPLIER),
|
||||
grazeCol: NewCircle(STAGE_WIDTH*0.5, STAGE_HEIGHT-STAGE_HEIGHT*0.1, STAGE_WIDTH*PLAYER_GRAZE_COL_RADIUS_MULTIPLIER),
|
||||
bullets: []Bullet{},
|
||||
updatePlayerPos: true,
|
||||
health: 3,
|
||||
deathTimer: -1,
|
||||
|
|
@ -147,10 +139,10 @@ func (m *BattleRoyaleMatch) MatchLeave(ctx context.Context, logger runtime.Logge
|
|||
playerState, exists := lobbyState.presences[sessionID]
|
||||
if exists {
|
||||
for _, bullet := range playerState.stageState.bullets {
|
||||
C.destroy_bullet(bullet)
|
||||
DestroyBullet(bullet)
|
||||
}
|
||||
C.destroy_circle(playerState.stageState.hitCol)
|
||||
C.destroy_circle(playerState.stageState.grazeCol)
|
||||
DestroyCircle(playerState.stageState.hitCol)
|
||||
DestroyCircle(playerState.stageState.grazeCol)
|
||||
delete(lobbyState.presences, sessionID)
|
||||
}
|
||||
}
|
||||
|
|
@ -222,11 +214,8 @@ func (m *BattleRoyaleMatch) MatchLoop(ctx context.Context, logger runtime.Logger
|
|||
update.X = math.Max(0, math.Min(update.X, STAGE_WIDTH))
|
||||
update.Y = math.Max(0, math.Min(update.Y, STAGE_HEIGHT))
|
||||
|
||||
lobbyState.presences[msg.GetSessionId()].stageState.hitCol.x = C.double(update.X)
|
||||
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)
|
||||
lobbyState.presences[msg.GetSessionId()].stageState.hitCol.UpdatePos(update.X, update.Y)
|
||||
lobbyState.presences[msg.GetSessionId()].stageState.grazeCol.UpdatePos(update.X, update.Y)
|
||||
|
||||
if clampedX || clampedY {
|
||||
lobbyState.presences[msg.GetSessionId()].stageState.updatePlayerPos = true
|
||||
|
|
@ -236,9 +225,9 @@ func (m *BattleRoyaleMatch) MatchLoop(ctx context.Context, logger runtime.Logger
|
|||
// Compute and broadcast per-presence state
|
||||
for _, v := range lobbyState.presences {
|
||||
// Clean up bullets when they pass off the board
|
||||
v.stageState.bullets = slices.DeleteFunc(v.stageState.bullets, func(b *C.Bullet) bool {
|
||||
if C.bullet_beyond_kill_boundary(b, C.int64_t(tick)) {
|
||||
C.destroy_bullet(b)
|
||||
v.stageState.bullets = slices.DeleteFunc(v.stageState.bullets, func(b Bullet) bool {
|
||||
if b.BeyondKillBoundary(tick) {
|
||||
DestroyBullet(b)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -250,20 +239,16 @@ 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.
|
||||
v.stageState.hitCol.x = C.double(STAGE_WIDTH * 0.5)
|
||||
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.hitCol.UpdatePos(STAGE_WIDTH*0.5, STAGE_HEIGHT-STAGE_HEIGHT*0.1)
|
||||
v.stageState.grazeCol.UpdatePos(STAGE_WIDTH*0.5, STAGE_HEIGHT-STAGE_HEIGHT*0.1)
|
||||
v.stageState.updatePlayerPos = true
|
||||
} 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 {
|
||||
return bool(C.bullet_collides_with(b, C.int64_t(tick), v.stageState.hitCol))
|
||||
if slices.ContainsFunc(v.stageState.bullets, func(b Bullet) bool {
|
||||
return b.CollidesWith(v.stageState.hitCol, tick)
|
||||
}) {
|
||||
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))
|
||||
} else if slices.ContainsFunc(v.stageState.bullets, func(b Bullet) bool { // Otherwise, check the graze col and increment the graze and score
|
||||
return b.CollidesWith(v.stageState.grazeCol, tick)
|
||||
}) {
|
||||
v.stageState.graze += GRAZE_ADDITION_MULTIPLIER
|
||||
}
|
||||
|
|
@ -289,26 +274,24 @@ func (m *BattleRoyaleMatch) MatchLoop(ctx context.Context, logger runtime.Logger
|
|||
velx := bulletSpeed * math.Cos(angleRad)
|
||||
vely := bulletSpeed * math.Sin(angleRad)
|
||||
|
||||
bullet := C.new_bullet(
|
||||
C.uint8_t(BULLET_LINEAR),
|
||||
C.int64_t(tick),
|
||||
C.double(spawnX), // Fixed X start position
|
||||
C.double(spawnY), // Fixed Y start position
|
||||
C.double(bulletRadiusMult*STAGE_WIDTH), // Fixed radius
|
||||
C.double(velx),
|
||||
C.double(vely),
|
||||
bullet := NewLinearBullet(
|
||||
tick,
|
||||
spawnX,
|
||||
spawnY,
|
||||
bulletRadiusMult*STAGE_WIDTH,
|
||||
velx,
|
||||
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)
|
||||
x, y := bullet.GetPos(tick)
|
||||
|
||||
bulletData := map[string]interface{}{
|
||||
"class": BULLET_LINEAR,
|
||||
"tick": tick,
|
||||
"x": float64(x),
|
||||
"y": float64(y),
|
||||
"x": x,
|
||||
"y": y,
|
||||
"radius_multiplier": bulletRadiusMult,
|
||||
"vel_x": velx,
|
||||
"vel_y": vely,
|
||||
|
|
@ -318,16 +301,18 @@ func (m *BattleRoyaleMatch) MatchLoop(ctx context.Context, logger runtime.Logger
|
|||
}
|
||||
}
|
||||
|
||||
hitPosX, hitPosY := v.stageState.hitCol.GetPos()
|
||||
grazePosX, grazePosY := v.stageState.hitCol.GetPos()
|
||||
var tickData = GameTickUpdate{
|
||||
Tick: tick,
|
||||
PlayerHitPos: map[string]interface{}{
|
||||
"x": v.stageState.hitCol.x,
|
||||
"y": v.stageState.hitCol.y,
|
||||
"x": hitPosX,
|
||||
"y": hitPosY,
|
||||
"radius_multiplier": PLAYER_HIT_COL_RADIUS_MULTIPLIER,
|
||||
},
|
||||
PlayerGrazePos: map[string]interface{}{
|
||||
"x": v.stageState.grazeCol.x,
|
||||
"y": v.stageState.grazeCol.y,
|
||||
"x": grazePosX,
|
||||
"y": grazePosY,
|
||||
"radius_multiplier": PLAYER_GRAZE_COL_RADIUS_MULTIPLIER,
|
||||
},
|
||||
NewBullets: newBulletsToBroadcast,
|
||||
|
|
|
|||
Reference in a new issue