-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathopponent.go
More file actions
111 lines (101 loc) · 3.51 KB
/
Copy pathopponent.go
File metadata and controls
111 lines (101 loc) · 3.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package main
import (
"image/color"
"math"
"time"
rl "github.com/gen2brain/raylib-go/raylib"
)
type Opponent struct {
Nodes []EntityNode
NodePositions []rl.Vector2
StopDuration time.Duration
StopTimeout time.Duration
StopTimer *time.Timer // Timer resets for timeout duration consistently like a reserve that player can use once each duration
Kind OpponentKind
Direction Direction
StartAfterFrames int32
IsAllowMove bool
IsDebug bool
}
func NewOpponent(position, speed rl.Vector2, dir Direction, col color.RGBA, kind OpponentKind) Opponent {
lastSnakeStartAfterFrames := snakeStartAfterFrames[min(int(snakeKindMaxCount), len(snakeStartAfterFrames)-1)] // Should use actual snake count from g.Level for index
b := Opponent{
Nodes: make([]EntityNode, opponentLength),
NodePositions: make([]rl.Vector2, opponentLength),
StopDuration: 0,
StopTimeout: 0,
StopTimer: &time.Timer{},
Kind: kind,
Direction: dir,
StartAfterFrames: lastSnakeStartAfterFrames + snakeStopFrames*2,
}
size := rl.Vector2{X: squareSize, Y: squareSize}
unitVector2 := DirectionUnitVectors[dir] // Either of x or y is a non-zero value.
for i := range b.Nodes {
dirOffset := rl.Vector2Multiply(unitVector2, rl.Vector2{X: float32(i), Y: float32(i)})
posOffset := rl.Vector2Multiply(dirOffset, rl.Vector2{X: size.X, Y: size.Y})
b.Nodes[i].Position = rl.Vector2Subtract(position, posOffset)
b.Nodes[i].Size = size
b.Nodes[i].Speed = speed
b.Nodes[i].Color = col
b.NodePositions[i] = rl.Vector2{X: math.MinInt32, Y: math.MinInt32}
}
b.updateNodePositionsFromNodePosition()
return b
}
func (b *Opponent) Update() {
b.updateNodePositionsFromNodePosition()
b.updateNodesArrayFromNodesSpeed()
}
func (b *Opponent) Draw(framesCounter int32) {
n := len(b.Nodes)
for i := 0; i < n; i++ {
switch i {
case 0: // Head
unitVec2 := DirectionUnitVectors[b.Direction]
halfSize := rl.Vector2Multiply(b.Nodes[0].Size, Vector2Half)
halfSize = rl.Vector2Multiply(Vector2NegativeOne, halfSize)
dispVec2 := rl.Vector2Multiply(unitVec2, halfSize) // If east, shift backdrop head towards *west*
r1 := b.Nodes[0].Rectangle()
r2 := r1 //Backdrop
r2.X += dispVec2.X
r2.Y += dispVec2.Y
rl.DrawRectangleRounded(r2, 0.0, 16, b.Nodes[0].Color) // Backdrop
rl.DrawRectangleRounded(r1, 0.98, 48, b.Nodes[0].Color) // Make front a rounded
case n - 1: // Tail
unitVec2 := DirectionUnitVectors[b.Direction]
halfSize := rl.Vector2Multiply(b.Nodes[0].Size, Vector2Half)
dispVec2 := rl.Vector2Multiply(unitVec2, halfSize) // If east, shift backdrop tail towards *east*
r1 := b.Nodes[n-1].Rectangle()
r2 := r1 //Backdrop
r2.X += dispVec2.X
r2.Y += dispVec2.Y
rl.DrawRectangleRounded(r2, 0.0, 16, b.Nodes[0].Color) // Backdrop
rl.DrawRectangleRounded(r1, 0.2, 48, b.Nodes[i].Color) // Make tail rounded but flatter
default:
rl.DrawRectangleRec(b.Nodes[i].Rectangle(), b.Nodes[i].Color)
}
}
}
func (b *Opponent) updateNodesArrayFromNodesSpeed() {
for i := range b.Nodes {
if i == 0 {
b.Nodes[i].Position = rl.Vector2Add(b.Nodes[i].Position, b.Nodes[i].Speed)
b.IsAllowMove = true
} else {
b.Nodes[i].Position = b.NodePositions[i-1]
}
}
}
func (b *Opponent) updateNodePositionsFromNodePosition() {
for i := range b.Nodes {
b.NodePositions[i] = b.Nodes[i].Position
}
}
const (
opponentLength = 3
)
var (
Vector2Half = rl.Vector2{X: 0.5, Y: 0.5}
Vector2NegativeOne = rl.Vector2{X: -1, Y: -1}
)