166 lines
4.3 KiB
Go
166 lines
4.3 KiB
Go
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
|
|
}
|