You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
165 lines
4.3 KiB
165 lines
4.3 KiB
package world |
|
|
|
import ( |
|
"image/color" |
|
"math/rand" |
|
|
|
"github.com/hajimehoshi/ebiten/v2" |
|
) |
|
|
|
const MapSize = 128 |
|
const tileDivisions = 4 |
|
const numTiles = MapSize * MapSize * tileDivisions * tileDivisions |
|
|
|
func environmentTile(r, g, b uint8) *ebiten.Image { |
|
img := ebiten.NewImage(TileSizeEnvironment, TileSizeEnvironment) |
|
img.Fill(color.RGBA{r, g, b, 255}) |
|
return img |
|
} |
|
|
|
var ( |
|
lightBlueTile1 = environmentTile(174, 208, 218) |
|
lightBlueTile2 = environmentTile(203, 234, 229) |
|
lightBlueTile3 = environmentTile(154, 202, 206) |
|
lightBlueTiles = []*ebiten.Image{lightBlueTile1, lightBlueTile1, lightBlueTile2, lightBlueTile2, lightBlueTile2, lightBlueTile2, lightBlueTile2, lightBlueTile2, lightBlueTile2, lightBlueTile3} |
|
|
|
mediumBlueTile1 = environmentTile(0, 38, 117) |
|
mediumBlueTile2 = environmentTile(9, 69, 131) |
|
mediumBlueTile3 = environmentTile(25, 71, 148) |
|
mediumBlueTiles = []*ebiten.Image{mediumBlueTile1, mediumBlueTile2, mediumBlueTile3} |
|
|
|
darkBlueTile1 = environmentTile(0, 9, 88) |
|
darkBlueTile2 = environmentTile(2, 3, 67) |
|
darkBlueTile3 = environmentTile(0, 0, 72) |
|
darkBlueTiles = []*ebiten.Image{darkBlueTile1, darkBlueTile1, darkBlueTile2, darkBlueTile3} |
|
|
|
redTile1 = environmentTile(109, 5, 0) |
|
redTile2 = environmentTile(135, 13, 8) |
|
redTile3 = environmentTile(118, 0, 6) |
|
redTiles = []*ebiten.Image{redTile1, redTile1, redTile2, redTile3} |
|
) |
|
|
|
func NewGameMap(seed int64) []Tile { |
|
r := rand.New(rand.NewSource(seed)) |
|
|
|
tiles := make([]Tile, numTiles) |
|
{ |
|
tx, ty := float64(0), float64(0) |
|
for i := range tiles { |
|
tiles[i].X, tiles[i].Y = tx, ty |
|
tiles[i].Walkable = true |
|
|
|
tx++ |
|
if tx == MapSize*4 { |
|
tx = 0 |
|
ty++ |
|
} |
|
} |
|
} |
|
|
|
for x := 0.0; x < MapSize; x++ { |
|
for y := 0.0; y < MapSize; y++ { |
|
index := TileIndex(x, y) |
|
tiles[index].Sprite = lightBlueTiles[r.Intn(len(lightBlueTiles))] |
|
} |
|
} |
|
|
|
setWalkable := func(tx, ty float64, walkable bool) { |
|
tileIndexes := PathTilesAtMapTile(tx, ty) |
|
for _, index := range tileIndexes { |
|
tiles[index].Walkable = walkable |
|
} |
|
} |
|
|
|
numMediumBlue := r.Intn(10) + 7 |
|
for i := 0; i < numMediumBlue; i++ { |
|
bx, by := float64(r.Intn(132)-4), float64(r.Intn(132)-4) |
|
bSizeX := float64(r.Intn(TileSize) + 7) |
|
bSizeY := float64(r.Intn(TileSize) + 7) |
|
for offsetX := 0.0; offsetX < bSizeX; offsetX++ { |
|
for offsetY := 0.0; offsetY < bSizeY; offsetY++ { |
|
tx, ty := bx+offsetX, by+offsetY |
|
index := TileIndex(tx, ty) |
|
if index == -1 { |
|
continue |
|
} |
|
setWalkable(tx, ty, false) |
|
tiles[index].Sprite = mediumBlueTiles[r.Intn(len(mediumBlueTiles))] |
|
} |
|
} |
|
} |
|
|
|
numDarkBlue := r.Intn(7) + 4 |
|
for i := 0; i < numDarkBlue; i++ { |
|
bx, by := float64(r.Intn(132)-4), float64(r.Intn(132)-4) |
|
bSizeX := float64(r.Intn(12) + 7) |
|
bSizeY := float64(r.Intn(12) + 7) |
|
for offsetX := 0.0; offsetX < bSizeX; offsetX++ { |
|
for offsetY := 0.0; offsetY < bSizeY; offsetY++ { |
|
tx, ty := bx+offsetX, by+offsetY |
|
index := TileIndex(tx, ty) |
|
if index == -1 { |
|
continue |
|
} |
|
setWalkable(tx, ty, false) |
|
tiles[index].Sprite = darkBlueTiles[r.Intn(len(darkBlueTiles))] |
|
} |
|
} |
|
} |
|
|
|
numStreaks := r.Intn(3) + 5 |
|
for i := 0; i < numStreaks; i++ { |
|
bx, by := float64(r.Intn(132)-4), float64(r.Intn(132)-4) |
|
vertical := r.Intn(2) == 0 |
|
|
|
bSize := float64(rand.Intn(14) + 32) |
|
for offset := 0.0; offset < bSize; offset++ { |
|
var tx, ty float64 |
|
if vertical { |
|
tx, ty = bx, by+offset |
|
} else { |
|
tx, ty = bx+offset, by |
|
} |
|
index := TileIndex(tx, ty) |
|
if index == -1 || !tiles[index].Walkable { |
|
continue |
|
} |
|
setWalkable(tx, ty, false) |
|
tiles[index].Sprite = redTiles[r.Intn(len(redTiles))] |
|
} |
|
} |
|
|
|
return tiles |
|
} |
|
|
|
func PathTileIndex(x, y float64) int { |
|
if x < 0 || y < 0 || x >= MapSize*tileDivisions || y >= MapSize*tileDivisions { |
|
return -1 |
|
} |
|
return int(y*MapSize*tileDivisions) + int(x) |
|
} |
|
|
|
func TileIndex(x, y float64) int { |
|
if x < 0 || y < 0 || x >= MapSize || y >= MapSize { |
|
return -1 |
|
} |
|
return int(y*tileDivisions*MapSize*tileDivisions) + int(x*tileDivisions) |
|
} |
|
|
|
func ValidXY(x, y int) bool { |
|
return x >= 0 && y >= 0 && x < MapSize && y < MapSize |
|
} |
|
|
|
func PathTilesAtMapTile(tx, ty float64) []int { |
|
pi := TileIndex(tx, ty) |
|
|
|
tiles := make([]int, 16) |
|
i := 0 |
|
for offsetY := 0; offsetY < 4; offsetY++ { |
|
for offsetX := 0; offsetX < 4; offsetX++ { |
|
tiles[i] = pi + (offsetY * MapSize * 4) + offsetX |
|
i++ |
|
} |
|
} |
|
return tiles |
|
}
|
|
|