Lagt till bas-karta med sky-blue bakgrund och fungerande plattformshopp
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package scenes
|
package scenes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"image/color"
|
||||||
_ "image/jpeg"
|
_ "image/jpeg"
|
||||||
_ "image/png"
|
_ "image/png"
|
||||||
"log"
|
"log"
|
||||||
@@ -27,16 +28,16 @@ type Player struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type PlayScene struct {
|
type PlayScene struct {
|
||||||
player Player
|
player Player
|
||||||
groundImg *ebiten.Image
|
groundImg *ebiten.Image
|
||||||
isGrounded bool
|
platforms []Platform
|
||||||
|
isGrounded bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPlayScene() *PlayScene {
|
func NewPlayScene() *PlayScene {
|
||||||
pImg, _, err := ebitenutil.NewImageFromFile("assets/images/player.jpg")
|
pImg, _, err := ebitenutil.NewImageFromFile("assets/images/player.jpg")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Kunde inte ladda spelar-sprite:", err)
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,8 +47,44 @@ func NewPlayScene() *PlayScene {
|
|||||||
gImg = ebiten.NewImage(800, 100)
|
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()
|
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{
|
return &PlayScene{
|
||||||
player: Player{
|
player: Player{
|
||||||
Pos: mgl64.Vec3{400.0, 100.0, 0.0},
|
Pos: mgl64.Vec3{400.0, 100.0, 0.0},
|
||||||
@@ -57,6 +94,7 @@ func NewPlayScene() *PlayScene {
|
|||||||
Sprite: pImg,
|
Sprite: pImg,
|
||||||
},
|
},
|
||||||
groundImg: gImg,
|
groundImg: gImg,
|
||||||
|
platforms: mapPlatforms,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,28 +121,61 @@ func (s *PlayScene) Update() error {
|
|||||||
s.player.Vel[1] += Gravity
|
s.player.Vel[1] += Gravity
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Applicera Velocity till Position
|
// 2. Planera Y förflyttning
|
||||||
s.player.Pos = s.player.Pos.Add(s.player.Vel)
|
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) ===
|
// === "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 {
|
if nextY+s.player.Height >= FloorHeight {
|
||||||
s.player.Pos[1] = FloorHeight - s.player.Height
|
nextY = FloorHeight - s.player.Height
|
||||||
s.player.Vel[1] = 0
|
s.player.Vel[1] = 0
|
||||||
s.isGrounded = true
|
s.isGrounded = true
|
||||||
} else {
|
|
||||||
s.isGrounded = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s.player.Pos[0] += s.player.Vel[0]
|
||||||
|
s.player.Pos[1] = nextY
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *PlayScene) Draw(screen *ebiten.Image) {
|
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) ===
|
// === 3D -> 2D Rendering Pipeline (Side View mode) ===
|
||||||
|
|
||||||
// Rita bakgrund/mark (Väldigt statiskt i det här fallet)
|
// Rita ut marken över hela skärmens bredd (Tiling)
|
||||||
gOp := &ebiten.DrawImageOptions{}
|
if s.groundImg != nil {
|
||||||
gOp.GeoM.Translate(0, FloorHeight)
|
gWidth := float64(s.groundImg.Bounds().Dx())
|
||||||
screen.DrawImage(s.groundImg, gOp)
|
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)
|
// 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 := &ebiten.DrawImageOptions{}
|
||||||
|
|||||||
26
internal/scenes/play_map.go
Normal file
26
internal/scenes/play_map.go
Normal file
@@ -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
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user