-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtiles.go
216 lines (186 loc) · 5.72 KB
/
tiles.go
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
package main
import (
"image"
"math/rand"
"github.com/hajimehoshi/ebiten"
)
/* TODO: Make tiles become holes?
*/
/*this comment is here bc vscode go linter is trash and keeps making an extra / * every time I save*/
const (
wallOffset = 6 // How big the walls are, start tiles at this
)
var (
numberOfTiles Vec2i
)
// TileType is a type for the tyletype enum
type TileType int
const (
// SmallTile ... TILETYPE ENUM [1]
SmallTile TileType = iota + 1
// BigTile ... TILETYPE ENUM [2]
BigTile
// WallTile ... TILETYPE ENUM [3]
WallTile
// Empty ... TILETYPE ENUM [4]
Empty // Used for holes or big tiles
)
func (t TileType) String() string {
return [...]string{"Unknown", "SmallTile", "BigTile", "WallTile", "Empty"}[t]
}
// ^ TILETYPE ENUM ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Tile be the tiles in the game
type Tile struct {
position Vec2f
size Vec2i
tileType TileType
rotation float64
scale Vec2f
sprite Sprite
image *ebiten.Image // Spritesheet
imageRect image.Rectangle
}
var (
smallTileSize = newVec2i(16, 17)
bigTileSize = newVec2i(31, 32)
wallTileSize = newVec2i(16, 29)
)
func createTile(position Vec2f, tileType TileType, image *ebiten.Image) Tile {
var sprite Sprite
size := smallTileSize
switch tileType {
case (SmallTile):
numberOfSmallTiles := 6
randomStart := newVec2i(rand.Intn(numberOfSmallTiles)*17, 0)
randomEnd := newVec2i(randomStart.x+smallTileSize.x, randomStart.y+smallTileSize.y)
sprite = createSprite(randomStart, randomEnd, smallTileSize, image)
case (BigTile):
sprite = createSprite(newVec2i(0, 18), newVec2i(31, 50), bigTileSize, image)
size = bigTileSize
case (WallTile):
sprite = createSprite(newVec2i(0, 51), newVec2i(16, 80), wallTileSize, image)
size = wallTileSize
}
return Tile{
position: position,
size: size,
tileType: tileType,
scale: Vec2f{1, 1},
sprite: sprite,
image: image,
}
}
func (t *Tile) render(screen *ebiten.Image) {
if t.tileType != Empty {
op := &ebiten.DrawImageOptions{}
op.GeoM.Rotate(t.rotation)
op.GeoM.Scale(t.scale.x, t.scale.y)
op.GeoM.Translate(t.position.x, t.position.y)
op.Filter = ebiten.FilterNearest // Maybe fix rotation grossness?
if t.imageRect.Empty() {
// If empty, give rect based on sprite
t.imageRect = image.Rect(
t.sprite.startPosition.x,
t.sprite.startPosition.y,
t.sprite.endPosition.x,
t.sprite.endPosition.y,
)
}
screen.DrawImage(t.image.SubImage(t.imageRect).(*ebiten.Image), op)
}
}
// Generate the wall tiles at the top of the screen
func generateWalls(image *ebiten.Image) []Tile {
numberOfWalls := screenWidth / wallTileSize.x
offset := newVec2f(17, 0) // Offset of the walls
t := make([]Tile, numberOfWalls)
for i := 0; i < numberOfWalls; i++ {
// wallTileSize.x-1 to make them overlap on the x axis by 1 pixel
t[i] = createTile(newVec2f(float64(i*(wallTileSize.x-1))+offset.x, offset.y), WallTile, image)
}
return t
}
func getNumberOfTilesPossible() Vec2i {
numberOfTiles = newVec2i(screenHeight/smallTileSize.y, screenWidth/smallTileSize.x)
return numberOfTiles
}
// Generate the tiles for the game
func generateTiles(image *ebiten.Image) [][]Tile {
numberOfTiles := getNumberOfTilesPossible()
numberOfTiles.x--
offset := newVec2f(17, float64(wallTileSize.y)) // Offset of the tiles
t := [][]Tile{}
for i := 0; i < numberOfTiles.x; i++ {
t = append(t, []Tile{})
for j := 0; j < numberOfTiles.y; j++ {
// smallTileSize.x-1 to make them overlap on the x axis by 1 pixel
t[i] = append(t[i], createTile(newVec2f(float64(j*(smallTileSize.x-1))+offset.x, float64(i*(smallTileSize.y-2))+offset.y), SmallTile, image))
}
}
return t
}
func generateBigTiles(tiles [][]Tile, image *ebiten.Image) {
y := numberOfTiles.x - 2 // arrays start at 0, and for some reason it needs 1 more, so -2
x := numberOfTiles.y - 2 // ^
// middle
makeBigTile(newVec2i(y/2, x/2), tiles, image)
// top left tile
makeBigTile(newVec2i(1, 1), tiles, image)
// next to ^
makeBigTile(newVec2i(1, 4), tiles, image)
// below ^
makeBigTile(newVec2i(4, 4), tiles, image)
// next to ^
makeBigTile(newVec2i(4, 7), tiles, image)
// We have to flip X and Y because the way tiles were generated
// bottom right tile
makeBigTile(newVec2i(y-1, x-1), tiles, image)
// next to ^
makeBigTile(newVec2i(y-1, x-4), tiles, image)
// above ^
makeBigTile(newVec2i(y-4, x-4), tiles, image)
// next to ^
makeBigTile(newVec2i(y-4, x-7), tiles, image)
// top right tile
makeBigTile(newVec2i(1, x-1), tiles, image)
// next to ^
makeBigTile(newVec2i(1, x-4), tiles, image)
// below ^
makeBigTile(newVec2i(4, x-4), tiles, image)
// next to ^
makeBigTile(newVec2i(4, x-7), tiles, image)
// bottom left tile
makeBigTile(newVec2i(y-1, 1), tiles, image)
// next to ^
makeBigTile(newVec2i(y-1, 4), tiles, image)
// above ^
makeBigTile(newVec2i(y-4, 4), tiles, image)
// next to ^
makeBigTile(newVec2i(y-4, 7), tiles, image)
}
func makeBigTile(tilePosition Vec2i, tiles [][]Tile, image *ebiten.Image) {
// Actual tile
tiles[tilePosition.x][tilePosition.y] = createTile(
tiles[tilePosition.x][tilePosition.y].position,
BigTile,
image,
)
// Make empties
tiles[tilePosition.x+1][tilePosition.y].tileType = Empty // Don't need to waste time making a new tile
tiles[tilePosition.x][tilePosition.y+1].tileType = Empty
tiles[tilePosition.x+1][tilePosition.y+1].tileType = Empty
}
func renderTiles(g *Game, screen *ebiten.Image) {
for _, w := range g.walls {
w.render(screen)
}
for i := 0; i < len(g.tiles); i++ {
for j := 0; j < len(g.tiles[i]); j++ {
g.tiles[i][j].render(screen)
}
}
}
func getRandomTile(g *Game, lessen Vec2i) (Tile, Vec2i) {
index := newVec2i(rand.Intn(len(g.tiles)-lessen.x), rand.Intn(len(g.tiles[0])-lessen.y))
return g.tiles[index.x][index.y], index
}