Skapat grundprojekt: Huvudmeny och Spel-scen as med hoppmakanik och AABB kollisions-grund
This commit is contained in:
65
internal/game/game.go
Normal file
65
internal/game/game.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package game
|
||||
|
||||
import (
|
||||
"mountain/internal/scenes"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
)
|
||||
|
||||
// SceneType represents the different scenes in the game.
|
||||
type SceneType int
|
||||
|
||||
const (
|
||||
SceneMainMenu SceneType = iota
|
||||
ScenePlay
|
||||
)
|
||||
|
||||
// Scene interface defines standard methods a state/scene must have.
|
||||
type Scene interface {
|
||||
Update() error
|
||||
Draw(screen *ebiten.Image)
|
||||
}
|
||||
|
||||
// Game implements ebiten.Game interface.
|
||||
type Game struct {
|
||||
currentScene Scene
|
||||
currentSceneType SceneType
|
||||
}
|
||||
|
||||
func NewGame() *Game {
|
||||
g := &Game{}
|
||||
g.ChangeScene(SceneMainMenu)
|
||||
return g
|
||||
}
|
||||
|
||||
func (g *Game) Update() error {
|
||||
// Handle global input for scene switching maybe?
|
||||
if g.currentSceneType == SceneMainMenu && ebiten.IsKeyPressed(ebiten.KeyEnter) {
|
||||
g.ChangeScene(ScenePlay)
|
||||
}
|
||||
|
||||
if g.currentScene != nil {
|
||||
return g.currentScene.Update()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *Game) Draw(screen *ebiten.Image) {
|
||||
if g.currentScene != nil {
|
||||
g.currentScene.Draw(screen)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *Game) Layout(outsideWidth, outsideHeight int) (screenWidth, screenHeight int) {
|
||||
return 800, 600
|
||||
}
|
||||
|
||||
func (g *Game) ChangeScene(s SceneType) {
|
||||
g.currentSceneType = s
|
||||
switch s {
|
||||
case SceneMainMenu:
|
||||
g.currentScene = scenes.NewMenuScene()
|
||||
case ScenePlay:
|
||||
g.currentScene = scenes.NewPlayScene()
|
||||
}
|
||||
}
|
||||
26
internal/scenes/menu.go
Normal file
26
internal/scenes/menu.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package scenes
|
||||
|
||||
import (
|
||||
"image/color"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
"github.com/hajimehoshi/ebiten/v2/ebitenutil"
|
||||
)
|
||||
|
||||
type MenuScene struct {
|
||||
}
|
||||
|
||||
func NewMenuScene() *MenuScene {
|
||||
return &MenuScene{}
|
||||
}
|
||||
|
||||
func (m *MenuScene) Update() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MenuScene) Draw(screen *ebiten.Image) {
|
||||
screen.Fill(color.RGBA{0x20, 0x20, 0x20, 0xff})
|
||||
|
||||
ebitenutil.DebugPrintAt(screen, "REGIN : MOUNTAIN OF TREASURES", 300, 250)
|
||||
ebitenutil.DebugPrintAt(screen, "Tryck ENTER for att starta", 310, 300)
|
||||
}
|
||||
115
internal/scenes/play.go
Normal file
115
internal/scenes/play.go
Normal file
@@ -0,0 +1,115 @@
|
||||
package scenes
|
||||
|
||||
import (
|
||||
_ "image/jpeg"
|
||||
_ "image/png"
|
||||
"log"
|
||||
|
||||
"github.com/go-gl/mathgl/mgl64"
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
"github.com/hajimehoshi/ebiten/v2/ebitenutil"
|
||||
)
|
||||
|
||||
const (
|
||||
Gravity = 0.5
|
||||
JumpForce = -10.0
|
||||
MoveSpeed = 4.0
|
||||
FloorHeight = 500.0
|
||||
)
|
||||
|
||||
type Player struct {
|
||||
Pos mgl64.Vec3 // 3D Kordinater: X (vänster/höger), Y (upp/ner), Z (djup)
|
||||
Vel mgl64.Vec3 // Hastighet
|
||||
|
||||
Width, Height float64 // För (AABB)
|
||||
|
||||
Sprite *ebiten.Image
|
||||
}
|
||||
|
||||
type PlayScene struct {
|
||||
player Player
|
||||
groundImg *ebiten.Image
|
||||
isGrounded bool
|
||||
}
|
||||
|
||||
func NewPlayScene() *PlayScene {
|
||||
pImg, _, err := ebitenutil.NewImageFromFile("assets/images/player.jpg")
|
||||
if err != nil {
|
||||
log.Println("Kunde inte ladda spelar-sprite:", err)
|
||||
// Fallback till en tom bild ifall bilden saknas
|
||||
pImg = ebiten.NewImage(32, 32)
|
||||
}
|
||||
|
||||
gImg, _, err := ebitenutil.NewImageFromFile("assets/images/ground.jpg")
|
||||
if err != nil {
|
||||
log.Println("Kunde inte ladda mark-sprite:", err)
|
||||
gImg = ebiten.NewImage(800, 100)
|
||||
}
|
||||
|
||||
w, h := pImg.Bounds().Dx(), pImg.Bounds().Dy()
|
||||
|
||||
return &PlayScene{
|
||||
player: Player{
|
||||
Pos: mgl64.Vec3{400.0, 100.0, 0.0},
|
||||
Vel: mgl64.Vec3{0, 0, 0},
|
||||
Width: float64(w),
|
||||
Height: float64(h),
|
||||
Sprite: pImg,
|
||||
},
|
||||
groundImg: gImg,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *PlayScene) Update() error {
|
||||
// === Input (X axis) ===
|
||||
s.player.Vel[0] = 0 // Återställ rörelse varje frame
|
||||
|
||||
if ebiten.IsKeyPressed(ebiten.KeyLeft) || ebiten.IsKeyPressed(ebiten.KeyA) {
|
||||
s.player.Vel[0] = -MoveSpeed
|
||||
}
|
||||
if ebiten.IsKeyPressed(ebiten.KeyRight) || ebiten.IsKeyPressed(ebiten.KeyD) {
|
||||
s.player.Vel[0] = MoveSpeed
|
||||
}
|
||||
|
||||
// === Hoppa (Y axis) ===
|
||||
if (ebiten.IsKeyPressed(ebiten.KeyUp) || ebiten.IsKeyPressed(ebiten.KeySpace)) && s.isGrounded {
|
||||
s.player.Vel[1] = JumpForce
|
||||
s.isGrounded = false
|
||||
}
|
||||
|
||||
// === Fysik / Euler integrering ===
|
||||
// 1. Applicera gravitation
|
||||
if !s.isGrounded {
|
||||
s.player.Vel[1] += Gravity
|
||||
}
|
||||
|
||||
// 2. Applicera Velocity till Position
|
||||
s.player.Pos = s.player.Pos.Add(s.player.Vel)
|
||||
|
||||
// === "Kollision" med golvet (väldigt simpel 2D-kollision för att simulera ytan på the floor på 2D-skärmen) ===
|
||||
if s.player.Pos[1]+s.player.Height >= FloorHeight {
|
||||
s.player.Pos[1] = FloorHeight - s.player.Height
|
||||
s.player.Vel[1] = 0
|
||||
s.isGrounded = true
|
||||
} else {
|
||||
s.isGrounded = false
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *PlayScene) Draw(screen *ebiten.Image) {
|
||||
// === 3D -> 2D Rendering Pipeline (Side View mode) ===
|
||||
|
||||
// Rita bakgrund/mark (Väldigt statiskt i det här fallet)
|
||||
gOp := &ebiten.DrawImageOptions{}
|
||||
gOp.GeoM.Translate(0, FloorHeight)
|
||||
screen.DrawImage(s.groundImg, gOp)
|
||||
|
||||
// Rita Spelaren baserat på dess 3D-kordinater översatta till (X, Y) på 2D-skärmen (vi skippar Z i denna view)
|
||||
pOp := &ebiten.DrawImageOptions{}
|
||||
pOp.GeoM.Translate(s.player.Pos[0], s.player.Pos[1])
|
||||
screen.DrawImage(s.player.Sprite, pOp)
|
||||
|
||||
ebitenutil.DebugPrint(screen, "Spelar Scene: SIDOVY. Styr med PILAR och Space.")
|
||||
}
|
||||
Reference in New Issue
Block a user