diff --git a/internal/scenes/play.go b/internal/scenes/play.go index 7837fcb..0c99147 100644 --- a/internal/scenes/play.go +++ b/internal/scenes/play.go @@ -1,6 +1,7 @@ package scenes import ( + "image/color" _ "image/jpeg" _ "image/png" "log" @@ -27,17 +28,17 @@ type Player struct { } type PlayScene struct { - player Player - groundImg *ebiten.Image - isGrounded bool + player Player + groundImg *ebiten.Image + platforms []Platform + 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) + pImg = ebiten.NewImage(32, 32) } gImg, _, err := ebitenutil.NewImageFromFile("assets/images/ground.jpg") @@ -46,8 +47,44 @@ func NewPlayScene() *PlayScene { gImg = ebiten.NewImage(800, 100) } + wallImg, _, _ := ebitenutil.NewImageFromFile("assets/images/wall.png") + stairImg, _, _ := ebitenutil.NewImageFromFile("assets/images/stairs.png") + w, h := pImg.Bounds().Dx(), pImg.Bounds().Dy() + // Skapa en enkel karta med plattformar för att hoppa på + var mapPlatforms []Platform + + if wallImg != nil { + pW := float64(wallImg.Bounds().Dx()) + pH := float64(wallImg.Bounds().Dy()) + mapPlatforms = append(mapPlatforms, Platform{ + Pos: mgl64.Vec3{300.0, 400.0, 0.0}, + Width: pW, + Height: pH, + Sprite: wallImg, + Scale: 0.2, // Skala ner väggen eftersom dina bildfiler (125k/325k) förmodligen är stora + }) + mapPlatforms = append(mapPlatforms, Platform{ + Pos: mgl64.Vec3{450.0, 300.0, 0.0}, + Width: pW, + Height: pH, + Sprite: wallImg, + Scale: 0.2, + }) + } + if stairImg != nil { + sW := float64(stairImg.Bounds().Dx()) + sH := float64(stairImg.Bounds().Dy()) + mapPlatforms = append(mapPlatforms, Platform{ + Pos: mgl64.Vec3{150.0, 480.0, 0.0}, + Width: sW, + Height: sH, + Sprite: stairImg, + Scale: 0.5, + }) + } + return &PlayScene{ player: Player{ Pos: mgl64.Vec3{400.0, 100.0, 0.0}, @@ -57,6 +94,7 @@ func NewPlayScene() *PlayScene { Sprite: pImg, }, groundImg: gImg, + platforms: mapPlatforms, } } @@ -83,28 +121,61 @@ func (s *PlayScene) Update() error { s.player.Vel[1] += Gravity } - // 2. Applicera Velocity till Position - s.player.Pos = s.player.Pos.Add(s.player.Vel) + // 2. Planera Y förflyttning + nextY := s.player.Pos[1] + s.player.Vel[1] + s.isGrounded = false + + // Kolla om vi landar på en plattform (endast när vi faller) + if s.player.Vel[1] >= 0 { + for _, p := range s.platforms { + if p.CheckCollisionTop(&s.player, nextY) { + nextY = p.Pos[1] - s.player.Height + s.player.Vel[1] = 0 + s.isGrounded = true + break + } + } + } // === "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 + if nextY+s.player.Height >= FloorHeight { + nextY = FloorHeight - s.player.Height s.player.Vel[1] = 0 s.isGrounded = true - } else { - s.isGrounded = false } + s.player.Pos[0] += s.player.Vel[0] + s.player.Pos[1] = nextY + return nil } func (s *PlayScene) Draw(screen *ebiten.Image) { + // Gör bakgrunden ljusblå (Sky blue) + screen.Fill(color.RGBA{135, 206, 235, 255}) + // === 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 ut marken över hela skärmens bredd (Tiling) + if s.groundImg != nil { + gWidth := float64(s.groundImg.Bounds().Dx()) + if gWidth == 0 { + gWidth = 32 // Undvik division med noll ifall bilden är tom + } + for x := 0.0; x < 800.0; x += gWidth { + gOp := &ebiten.DrawImageOptions{} + gOp.GeoM.Translate(x, FloorHeight) + screen.DrawImage(s.groundImg, gOp) + } + } + + // Lägg ut karta/plattformar + for _, p := range s.platforms { + platOp := &ebiten.DrawImageOptions{} + platOp.GeoM.Scale(p.Scale, p.Scale) + platOp.GeoM.Translate(p.Pos[0], p.Pos[1]) + screen.DrawImage(p.Sprite, platOp) + } // Rita Spelaren baserat på dess 3D-kordinater översatta till (X, Y) på 2D-skärmen (vi skippar Z i denna view) pOp := &ebiten.DrawImageOptions{} @@ -112,4 +183,4 @@ func (s *PlayScene) Draw(screen *ebiten.Image) { screen.DrawImage(s.player.Sprite, pOp) ebitenutil.DebugPrint(screen, "Spelar Scene: SIDOVY. Styr med PILAR och Space.") -} \ No newline at end of file +} diff --git a/internal/scenes/play_map.go b/internal/scenes/play_map.go new file mode 100644 index 0000000..1ac927e --- /dev/null +++ b/internal/scenes/play_map.go @@ -0,0 +1,26 @@ +package scenes + +import ( +"github.com/go-gl/mathgl/mgl64" +"github.com/hajimehoshi/ebiten/v2" +) + +type Platform struct { +Pos mgl64.Vec3 +Width float64 +Height float64 +Sprite *ebiten.Image +Scale float64 +} + +// Kolla ifall spelaren nuddar ovansidan av plattformen (Fallande) +func (p *Platform) CheckCollisionTop(player *Player, nextY float64) bool { +// AABB (Axis-Aligned Bounding Box) X-kollision +if player.Pos[0] < p.Pos[0]+(p.Width*p.Scale) && player.Pos[0]+player.Width > p.Pos[0] { +// Kolla om spelaren är på väg ner och "korsar" toppen av plattformen +if player.Pos[1]+player.Height <= p.Pos[1] && nextY+player.Height >= p.Pos[1] { +return true +} +} +return false +}