lol
This commit is contained in:
parent
ddb02ea56b
commit
a69ed0b0b9
9
go.mod
9
go.mod
@ -2,9 +2,10 @@ module goonscape
|
||||
|
||||
go 1.23.0
|
||||
|
||||
require github.com/gen2brain/raylib-go/raylib v0.0.0-20240916050633-6bc3d79c96ad
|
||||
|
||||
require (
|
||||
github.com/ebitengine/purego v0.8.0 // indirect
|
||||
github.com/gen2brain/raylib-go/raylib v0.0.0-20240916050633-6bc3d79c96ad // indirect
|
||||
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect
|
||||
golang.org/x/sys v0.25.0 // indirect
|
||||
github.com/ebitengine/purego v0.7.1 // indirect
|
||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect
|
||||
golang.org/x/sys v0.20.0 // indirect
|
||||
)
|
||||
|
12
go.sum
12
go.sum
@ -1,8 +1,8 @@
|
||||
github.com/ebitengine/purego v0.8.0 h1:JbqvnEzRvPpxhCJzJJ2y0RbiZ8nyjccVUrSM3q+GvvE=
|
||||
github.com/ebitengine/purego v0.8.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
||||
github.com/ebitengine/purego v0.7.1 h1:6/55d26lG3o9VCZX8lping+bZcmShseiqlh2bnUDiPA=
|
||||
github.com/ebitengine/purego v0.7.1/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ=
|
||||
github.com/gen2brain/raylib-go/raylib v0.0.0-20240916050633-6bc3d79c96ad h1:kmIjqc2wOOn+MXw/pyuoYhhzfRFsZ+ESfkMWVt+WE7Y=
|
||||
github.com/gen2brain/raylib-go/raylib v0.0.0-20240916050633-6bc3d79c96ad/go.mod h1:BaY76bZk7nw1/kVOSQObPY1v1iwVE1KHAGMfvI6oK1Q=
|
||||
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk=
|
||||
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY=
|
||||
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
||||
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=
|
||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
|
||||
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
|
263
main.go
263
main.go
@ -0,0 +1,263 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
rl "github.com/gen2brain/raylib-go/raylib"
|
||||
)
|
||||
|
||||
type Tile struct {
|
||||
X, Y int
|
||||
Height float32
|
||||
Walkable bool
|
||||
}
|
||||
|
||||
const (
|
||||
MapWidth = 100
|
||||
MapHeight = 100
|
||||
TileSize = 32
|
||||
)
|
||||
|
||||
// Initialize the map with some height data
|
||||
func InitMap() [][]Tile {
|
||||
mapGrid := make([][]Tile, MapWidth)
|
||||
for x := 0; x < MapWidth; x++ {
|
||||
mapGrid[x] = make([]Tile, MapHeight)
|
||||
for y := 0; y < MapHeight; y++ {
|
||||
mapGrid[x][y] = Tile{
|
||||
X: x,
|
||||
Y: y,
|
||||
Height: float32((x + y) % 10), // Example height
|
||||
Walkable: true, // Set to false for obstacles
|
||||
}
|
||||
}
|
||||
}
|
||||
return mapGrid
|
||||
}
|
||||
|
||||
type Player struct {
|
||||
X, Y int // Current tile position
|
||||
PosX, PosY float32 // Actual position for smooth movement
|
||||
TargetPath []Tile
|
||||
Speed float32
|
||||
}
|
||||
|
||||
func DrawMap(mapGrid [][]Tile) {
|
||||
for x := 0; x < MapWidth; x++ {
|
||||
for y := 0; y < MapHeight; y++ {
|
||||
tile := mapGrid[x][y]
|
||||
// Simple top-down view: color based on height
|
||||
color := rl.Color{R: uint8(tile.Height * 25), G: 100, B: 100, A: 255}
|
||||
rl.DrawRectangle(int32(tile.X*TileSize), int32(tile.Y*TileSize-int(tile.Height)), TileSize, TileSize, color)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func DrawPlayer(player Player, mapGrid [][]Tile) {
|
||||
// Get current tile height
|
||||
currentTile := mapGrid[player.X][player.Y]
|
||||
// Draw player at PosX, PosY adjusted by height
|
||||
rl.DrawCircle(int32(player.PosX), int32(player.PosY-currentTile.Height), 10, rl.Red)
|
||||
}
|
||||
|
||||
func GetTileAtMouse(mapGrid [][]Tile) (Tile, bool) {
|
||||
if !rl.IsMouseButtonPressed(rl.MouseLeftButton) {
|
||||
return Tile{}, false
|
||||
}
|
||||
mouseX := rl.GetMouseX()
|
||||
mouseY := rl.GetMouseY()
|
||||
tileX := mouseX / TileSize
|
||||
tileY := (mouseY + int32(mapGrid[tileX][0].Height)) / TileSize
|
||||
if tileX >= 0 && tileX < MapWidth && tileY >= 0 && tileY < MapHeight {
|
||||
return mapGrid[tileX][tileY], true
|
||||
}
|
||||
return Tile{}, false
|
||||
}
|
||||
|
||||
// pathfinding
|
||||
type Node struct {
|
||||
Tile Tile
|
||||
Parent *Node
|
||||
G, H, F float32
|
||||
}
|
||||
|
||||
func FindPath(mapGrid [][]Tile, start, end Tile) []Tile {
|
||||
openList := []*Node{}
|
||||
closedList := make(map[[2]int]bool)
|
||||
|
||||
startNode := &Node{Tile: start, G: 0, H: heuristic(start, end)}
|
||||
startNode.F = startNode.G + startNode.H
|
||||
openList = append(openList, startNode)
|
||||
|
||||
for len(openList) > 0 {
|
||||
// Find node with lowest F
|
||||
current := openList[0]
|
||||
currentIndex := 0
|
||||
for i, node := range openList {
|
||||
if node.F < current.F {
|
||||
current = node
|
||||
currentIndex = i
|
||||
}
|
||||
}
|
||||
|
||||
// Move current to closed list
|
||||
openList = append(openList[:currentIndex], openList[currentIndex+1:]...)
|
||||
closedList[[2]int{current.Tile.X, current.Tile.Y}] = true
|
||||
|
||||
// Check if reached the end
|
||||
if current.Tile.X == end.X && current.Tile.Y == end.Y {
|
||||
path := []Tile{}
|
||||
node := current
|
||||
for node != nil {
|
||||
path = append([]Tile{node.Tile}, path...)
|
||||
node = node.Parent
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
// Generate neighbors
|
||||
neighbors := GetNeighbors(mapGrid, current.Tile)
|
||||
for _, neighbor := range neighbors {
|
||||
if !neighbor.Walkable || closedList[[2]int{neighbor.X, neighbor.Y}] {
|
||||
continue
|
||||
}
|
||||
|
||||
tentativeG := current.G + distance(current.Tile, neighbor)
|
||||
inOpen := false
|
||||
var existingNode *Node
|
||||
for _, node := range openList {
|
||||
if node.Tile.X == neighbor.X && node.Tile.Y == neighbor.Y {
|
||||
existingNode = node
|
||||
inOpen = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !inOpen || tentativeG < existingNode.G {
|
||||
newNode := &Node{
|
||||
Tile: neighbor,
|
||||
Parent: current,
|
||||
G: tentativeG,
|
||||
H: heuristic(neighbor, end),
|
||||
}
|
||||
newNode.F = newNode.G + newNode.H
|
||||
if !inOpen {
|
||||
openList = append(openList, newNode)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No path found
|
||||
return nil
|
||||
}
|
||||
|
||||
func heuristic(a, b Tile) float32 {
|
||||
return float32(abs(a.X-b.X) + abs(a.Y-b.Y))
|
||||
}
|
||||
|
||||
func distance(a, b Tile) float32 {
|
||||
_ = a
|
||||
_ = b
|
||||
return 1.0 //uniform cost for now
|
||||
}
|
||||
|
||||
func GetNeighbors(mapGrid [][]Tile, tile Tile) []Tile {
|
||||
directions := [][2]int{
|
||||
{1, 0}, {-1, 0}, {0, 1}, {0, -1},
|
||||
{1, 1}, {-1, -1}, {1, -1}, {-1, 1},
|
||||
}
|
||||
neighbors := []Tile{}
|
||||
for _, dir := range directions {
|
||||
nx, ny := tile.X+dir[0], tile.Y+dir[1]
|
||||
if nx >= 0 && nx < MapWidth && ny >= 0 && ny < MapHeight {
|
||||
neighbors = append(neighbors, mapGrid[nx][ny])
|
||||
}
|
||||
}
|
||||
return neighbors
|
||||
}
|
||||
|
||||
func abs(x int) int {
|
||||
if x < 0 {
|
||||
return -x
|
||||
}
|
||||
return x
|
||||
}
|
||||
|
||||
// end pathfinding
|
||||
|
||||
func UpdatePlayer(player *Player, deltaTime float32, mapGrid [][]Tile) {
|
||||
if len(player.TargetPath) > 0 {
|
||||
targetTile := player.TargetPath[0]
|
||||
targetX := float32(targetTile.X * TileSize)
|
||||
targetY := float32(targetTile.Y*TileSize - int(targetTile.Height))
|
||||
|
||||
// Calculate direction
|
||||
dirX := targetX - player.PosX
|
||||
dirY := targetY - player.PosY
|
||||
distance := float32(math.Sqrt(float64(dirX*dirX + dirY*dirY)))
|
||||
|
||||
if distance < player.Speed*deltaTime {
|
||||
// Snap to target tile
|
||||
player.PosX = targetX
|
||||
player.PosY = targetY
|
||||
player.X = targetTile.X
|
||||
player.Y = targetTile.Y
|
||||
// Remove the reached tile from the path
|
||||
player.TargetPath = player.TargetPath[1:]
|
||||
} else {
|
||||
// Move towards target
|
||||
player.PosX += (dirX / distance) * player.Speed * deltaTime
|
||||
player.PosY += (dirY / distance) * player.Speed * deltaTime
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func HandleInput(player *Player, mapGrid [][]Tile) {
|
||||
clickedTile, clicked := GetTileAtMouse(mapGrid)
|
||||
if clicked {
|
||||
path := FindPath(mapGrid, mapGrid[player.X][player.Y], clickedTile)
|
||||
if path != nil {
|
||||
// Exclude the first tile (current position)
|
||||
if len(path) > 1 {
|
||||
player.TargetPath = path[1:]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
rl.InitWindow(800, 600, "RuneScape-like Game")
|
||||
defer rl.CloseWindow()
|
||||
|
||||
mapGrid := InitMap()
|
||||
|
||||
player := Player{
|
||||
X: 10,
|
||||
Y: 10,
|
||||
PosX: float32(10 * TileSize),
|
||||
PosY: float32(10*TileSize - int(mapGrid[10][10].Height)),
|
||||
Speed: 100.0, // pixels per second
|
||||
}
|
||||
|
||||
rl.SetTargetFPS(60)
|
||||
|
||||
for !rl.WindowShouldClose() {
|
||||
deltaTime := rl.GetFrameTime()
|
||||
|
||||
// Handle input
|
||||
HandleInput(&player, mapGrid)
|
||||
|
||||
// Update player position
|
||||
UpdatePlayer(&player, deltaTime, mapGrid)
|
||||
|
||||
// Draw everything
|
||||
rl.BeginDrawing()
|
||||
rl.ClearBackground(rl.RayWhite)
|
||||
|
||||
DrawMap(mapGrid)
|
||||
DrawPlayer(player, mapGrid)
|
||||
|
||||
rl.EndDrawing()
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user