@@ -14,6 +14,7 @@ import (
1414 core "github.com/rfwlab/rfw/v1/core"
1515 dom "github.com/rfwlab/rfw/v1/dom"
1616 events "github.com/rfwlab/rfw/v1/events"
17+ draw "github.com/rfwlab/rfw/v1/game/draw"
1718 hostclient "github.com/rfwlab/rfw/v1/hostclient"
1819 js "github.com/rfwlab/rfw/v1/js"
1920 "github.com/rfwlab/rfw/v1/netcode"
@@ -62,8 +63,7 @@ type multiplayerComponent struct {
6263 cancelFuncs []func ()
6364 stop chan struct {}
6465 sessionID string
65- canvas js.Value
66- ctx js.Value
66+ surface draw.Canvas
6767}
6868
6969// NewMultiplayerComponent renders the multiplayer arena example page.
@@ -82,11 +82,12 @@ func (c *multiplayerComponent) OnMount() {
8282 doc := dom .Doc ()
8383 canvas := doc .ByID ("mp-canvas" )
8484 if ! canvas .IsNull () && ! canvas .IsUndefined () {
85- canvas .Set ("width" , int (arenaWidth ))
86- canvas .Set ("height" , int (arenaHeight ))
87- c .canvas = canvas .Value
88- c .ctx = canvas .Call ("getContext" , "2d" )
89- c .ctx .Set ("lineWidth" , 2 )
85+ if surface , ok := draw .NewCanvas (canvas ); ok {
86+ surface .SetSize (arenaWidth , arenaHeight )
87+ c .surface = surface
88+ } else {
89+ c .surface = draw.Canvas {}
90+ }
9091 }
9192
9293 c .cancelFuncs = []func (){
@@ -109,6 +110,7 @@ func (c *multiplayerComponent) OnUnmount() {
109110 }
110111 c .cancelFuncs = nil
111112 c .client = nil
113+ c .surface = draw.Canvas {}
112114}
113115
114116func (c * multiplayerComponent ) loop () {
@@ -222,39 +224,33 @@ func (c *multiplayerComponent) consumeShoot() bool {
222224}
223225
224226func (c * multiplayerComponent ) render (state mpSnapshot ) {
225- if ! c .ctx . Truthy () {
227+ if ! c .surface . Valid () {
226228 return
227229 }
228- c .ctx .Set ("fillStyle" , "#0f172a" )
229- c .ctx .Call ("fillRect" , 0 , 0 , arenaWidth , arenaHeight )
230230
231- c .ctx .Set ("fillStyle" , "#f8fafc" )
231+ commands := make ([]draw.Command , 0 , 1 + len (state .Bullets )+ len (state .Players )* 3 )
232+ commands = append (commands , draw .Rectangle (0 , 0 , arenaWidth , arenaHeight ).Fill (arenaBackground ))
233+
232234 for _ , bullet := range state .Bullets {
233- c .ctx .Call ("beginPath" )
234- c .ctx .Call ("arc" , bullet .X , bullet .Y , bulletRadius , 0 , math .Pi * 2 , false )
235- c .ctx .Call ("fill" )
235+ commands = append (commands , draw .Disc (bullet .X , bullet .Y , bulletRadius ).Fill (bulletColor ))
236236 }
237237
238238 for id , player := range state .Players {
239- c .ctx .Set ("fillStyle" , player .Color )
240- c .ctx .Call ("beginPath" )
241- c .ctx .Call ("arc" , player .X , player .Y , playerRadius , 0 , math .Pi * 2 , false )
242- c .ctx .Call ("fill" )
239+ marker := draw .Disc (player .X , player .Y , playerRadius ).Fill (player .Color )
243240 if id == c .sessionID {
244- c .ctx .Set ("strokeStyle" , "#ffffff" )
245- c .ctx .Call ("stroke" )
241+ marker .Stroke (activePlayerStroke , outlineWidth )
246242 }
243+ commands = append (commands , marker )
247244 if ! player .Alive {
248- c .ctx .Set ("strokeStyle" , "rgba(15, 23, 42, 0.7)" )
249- c .ctx .Call ("beginPath" )
250- c .ctx .Call ("moveTo" , player .X - playerRadius , player .Y - playerRadius )
251- c .ctx .Call ("lineTo" , player .X + playerRadius , player .Y + playerRadius )
252- c .ctx .Call ("moveTo" , player .X - playerRadius , player .Y + playerRadius )
253- c .ctx .Call ("lineTo" , player .X + playerRadius , player .Y - playerRadius )
254- c .ctx .Call ("stroke" )
245+ commands = append (commands ,
246+ draw .Segment (player .X - playerRadius , player .Y - playerRadius , player .X + playerRadius , player .Y + playerRadius ).Stroke (eliminatedStroke , outlineWidth ),
247+ draw .Segment (player .X - playerRadius , player .Y + playerRadius , player .X + playerRadius , player .Y - playerRadius ).Stroke (eliminatedStroke , outlineWidth ),
248+ )
255249 }
256250 }
257251
252+ c .surface .Draw (commands ... )
253+
258254 c .updateHUD (state )
259255}
260256
@@ -301,14 +297,14 @@ func (c *multiplayerComponent) updateHUD(state mpSnapshot) {
301297 message := ""
302298 if state .Winner != "" {
303299 if state .Winner == c .sessionID {
304- message = "Hai vinto! Ultimo in piedi ."
300+ message = "You won! Last player standing ."
305301 } else if winner , ok := state .Players [state .Winner ]; ok {
306- message = fmt .Sprintf ("Vince il giocatore %s " , shortID (winner .ID ))
302+ message = fmt .Sprintf ("Player %s wins " , shortID (winner .ID ))
307303 } else {
308- message = "Partita conclusa ."
304+ message = "Match finished ."
309305 }
310306 } else if player , ok := state .Players [c .sessionID ]; ok && ! player .Alive {
311- message = "Game over! Premi WASD per muoverti quando inizia un nuovo round."
307+ message = "Game over! Press WASD to move when the next round starts ."
312308 }
313309 statusEl .SetText (message )
314310}
@@ -330,8 +326,13 @@ func shortID(id string) string {
330326}
331327
332328const (
333- bulletRadius = 6.0
334- playerRadius = 18.0
335- arenaWidth = 800.0
336- arenaHeight = 520.0
329+ bulletRadius = 6.0
330+ playerRadius = 18.0
331+ arenaWidth = 800.0
332+ arenaHeight = 520.0
333+ outlineWidth = 2.0
334+ arenaBackground = "#0f172a"
335+ bulletColor = "#f8fafc"
336+ activePlayerStroke = "#ffffff"
337+ eliminatedStroke = "rgba(15, 23, 42, 0.7)"
337338)
0 commit comments