lol
This commit is contained in:
		
							
								
								
									
										9
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								go.mod
									
									
									
									
									
								
							@ -2,9 +2,10 @@ module goonscape
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
go 1.23.0
 | 
					go 1.23.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require github.com/gen2brain/raylib-go/raylib v0.0.0-20240916050633-6bc3d79c96ad
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require (
 | 
					require (
 | 
				
			||||||
	github.com/ebitengine/purego v0.8.0 // indirect
 | 
						github.com/ebitengine/purego v0.7.1 // indirect
 | 
				
			||||||
	github.com/gen2brain/raylib-go/raylib v0.0.0-20240916050633-6bc3d79c96ad // indirect
 | 
						golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect
 | 
				
			||||||
	golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect
 | 
						golang.org/x/sys v0.20.0 // indirect
 | 
				
			||||||
	golang.org/x/sys v0.25.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.7.1 h1:6/55d26lG3o9VCZX8lping+bZcmShseiqlh2bnUDiPA=
 | 
				
			||||||
github.com/ebitengine/purego v0.8.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
 | 
					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 h1:kmIjqc2wOOn+MXw/pyuoYhhzfRFsZ+ESfkMWVt+WE7Y=
 | 
				
			||||||
github.com/gen2brain/raylib-go/raylib v0.0.0-20240916050633-6bc3d79c96ad/go.mod h1:BaY76bZk7nw1/kVOSQObPY1v1iwVE1KHAGMfvI6oK1Q=
 | 
					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-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=
 | 
				
			||||||
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY=
 | 
					golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
 | 
				
			||||||
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
 | 
					golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
 | 
				
			||||||
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 | 
					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()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user