1 # A satellite sits on the map and beams controls to the player
7 struct Satellite(pos:Vector2, beam_end=Vector2(0,0), facing=Vector2(1,0))
10 func draw_beam(s:Satellite)
11 DrawLineEx(s.pos, s.beam_end, 5, Color(0x80,0x80,0xff,0xcc))
13 func draw(s:Satellite)
14 texture := Texture.load((./assets/Satellite.png))
15 texture.draw(s.pos, Satellite.SIZE, angle=s.facing.angle() + Num32.TAU/8)
17 func update(s:&Satellite, boxes:[@Box], player:&Player)
21 s.facing = (player.pos - s.pos).norm()
22 s.beam_end = s.raycast(boxes, player.pos)
23 if s.beam_end.dist(player.pos).near(0)
24 player.has_signal = yes
26 func vertical_edge_hit(pos,dir:Vector2, edge_x:Num32, y_min,y_max:Num32 -> Vector2?)
27 t := (edge_x - pos.x)/dir.x
29 y := pos.y + (t*dir.y)
30 return none if y < y_min or y > y_max
31 return Vector2(edge_x, y)
33 func horizontal_edge_hit(pos,dir:Vector2, edge_y:Num32, x_min,x_max:Num32 -> Vector2?)
34 t := (edge_y - pos.y)/dir.y
36 x := pos.x + (t*dir.x)
37 return none if x < x_min or x > x_max
38 return Vector2(x, edge_y)
40 func raycast(s:Satellite, boxes:[@Box], end:Vector2, epsilon=Num32(0.1) -> Vector2)
41 return end if s.pos == end
42 dist := s.pos.dist(end)
43 forward := (end - s.pos).norm()
46 skip if b.color.a < 0xff
47 x_min := b.pos.x - b.size.x/2
48 x_max := b.pos.x + b.size.x/2
49 y_min := b.pos.y - b.size.y/2
50 y_max := b.pos.y + b.size.y/2
53 hit = Satellite.horizontal_edge_hit(s.pos, forward, y_min, x_min, x_max)
54 if hit then end = end _min_.dist(s.pos) hit
55 hit = Satellite.horizontal_edge_hit(s.pos, forward, y_max, x_min, x_max)
56 if hit then end = end _min_.dist(s.pos) hit
58 hit = Satellite.vertical_edge_hit(s.pos, forward, x_min, y_min, y_max)
59 if hit then end = end _min_.dist(s.pos) hit
60 hit = Satellite.vertical_edge_hit(s.pos, forward, x_max, y_min, y_max)
61 if hit then end = end _min_.dist(s.pos) hit