Update tileset and settings, enhance logging
- Updated tileset configuration in 'tileset.tsj' to include new tiles and adjust dimensions. - Added 'settings.json' for key bindings related to climbing and movement actions. - Enhanced game logging in 'game.log' to track game start events and map loading. - Updated the game binary to the latest version.
This commit is contained in:
@@ -1,17 +1,21 @@
|
||||
package scenes
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image"
|
||||
"image/color"
|
||||
_ "image/jpeg"
|
||||
_ "image/png"
|
||||
"log"
|
||||
"sort"
|
||||
|
||||
"mountain/internal/entities"
|
||||
"mountain/internal/input"
|
||||
|
||||
"github.com/go-gl/mathgl/mgl64"
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
"github.com/hajimehoshi/ebiten/v2/ebitenutil"
|
||||
"github.com/hajimehoshi/ebiten/v2/inpututil"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -21,6 +25,14 @@ const (
|
||||
ViewSize = 380 // 800 width, we have 2 viewports (380 each with 20 padding)
|
||||
)
|
||||
|
||||
type PlayState int
|
||||
|
||||
const (
|
||||
StatePlaying PlayState = iota
|
||||
StatePaused
|
||||
StateSettings
|
||||
)
|
||||
|
||||
type Player struct {
|
||||
Pos mgl64.Vec3 // 3D Kordinater: X (vänster/höger), Y (upp/ner), Z (djup)
|
||||
Vel mgl64.Vec3 // Hastighet
|
||||
@@ -44,6 +56,11 @@ type PlayScene struct {
|
||||
player *Player
|
||||
leftView *ebiten.Image
|
||||
rightView *ebiten.Image
|
||||
state PlayState
|
||||
|
||||
// Settings UI state
|
||||
sortedActions []string
|
||||
selectedIndex int
|
||||
}
|
||||
|
||||
func NewPlayScene() *PlayScene {
|
||||
@@ -82,18 +99,112 @@ func NewPlayScene() *PlayScene {
|
||||
}
|
||||
|
||||
return &PlayScene{
|
||||
world: w,
|
||||
player: player,
|
||||
leftView: ebiten.NewImage(ViewSize, ViewSize),
|
||||
rightView: ebiten.NewImage(ViewSize, ViewSize),
|
||||
world: w,
|
||||
player: player,
|
||||
leftView: ebiten.NewImage(ViewSize, ViewSize),
|
||||
rightView: ebiten.NewImage(ViewSize, ViewSize),
|
||||
state: StatePlaying,
|
||||
sortedActions: make([]string, 0),
|
||||
selectedIndex: 0,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *PlayScene) Update() error {
|
||||
switch s.state {
|
||||
case StatePlaying:
|
||||
return s.updatePlaying()
|
||||
case StatePaused:
|
||||
return s.updatePaused()
|
||||
case StateSettings:
|
||||
return s.updateSettings()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *PlayScene) updatePaused() error {
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyEscape) {
|
||||
s.state = StatePlaying
|
||||
}
|
||||
// Menu logic for pausing
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyEnter) {
|
||||
if s.selectedIndex == 0 {
|
||||
s.state = StatePlaying
|
||||
} else if s.selectedIndex == 1 {
|
||||
s.state = StateSettings
|
||||
s.initSettings()
|
||||
}
|
||||
}
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyUp) || inpututil.IsKeyJustPressed(ebiten.KeyW) {
|
||||
s.selectedIndex--
|
||||
if s.selectedIndex < 0 {
|
||||
s.selectedIndex = 1
|
||||
}
|
||||
}
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyDown) || inpututil.IsKeyJustPressed(ebiten.KeyS) {
|
||||
s.selectedIndex++
|
||||
if s.selectedIndex > 1 {
|
||||
s.selectedIndex = 0
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *PlayScene) initSettings() {
|
||||
s.sortedActions = make([]string, 0, len(input.Manager.Actions))
|
||||
for k := range input.Manager.Actions {
|
||||
s.sortedActions = append(s.sortedActions, k)
|
||||
}
|
||||
sort.Strings(s.sortedActions)
|
||||
s.selectedIndex = 0
|
||||
}
|
||||
|
||||
func (s *PlayScene) updateSettings() error {
|
||||
if input.Manager.IsRecording() {
|
||||
if input.Manager.UpdateRecording() {
|
||||
// Recording finished
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyEscape) {
|
||||
s.state = StatePaused
|
||||
s.selectedIndex = 1 // back to settings button
|
||||
return nil
|
||||
}
|
||||
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyUp) || inpututil.IsKeyJustPressed(ebiten.KeyW) {
|
||||
s.selectedIndex--
|
||||
if s.selectedIndex < 0 {
|
||||
s.selectedIndex = len(s.sortedActions) - 1
|
||||
}
|
||||
}
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyDown) || inpututil.IsKeyJustPressed(ebiten.KeyS) {
|
||||
s.selectedIndex++
|
||||
if s.selectedIndex >= len(s.sortedActions) {
|
||||
s.selectedIndex = 0
|
||||
}
|
||||
}
|
||||
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyEnter) {
|
||||
action := s.sortedActions[s.selectedIndex]
|
||||
input.Manager.StartRecording(action)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *PlayScene) updatePlaying() error {
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyEscape) {
|
||||
s.state = StatePaused
|
||||
s.selectedIndex = 0
|
||||
return nil
|
||||
}
|
||||
|
||||
p := s.player
|
||||
|
||||
currentMoveSpeed := MoveSpeed
|
||||
if ebiten.IsKeyPressed(ebiten.KeyControl) {
|
||||
if input.Manager.IsActionPressed("Run") {
|
||||
currentMoveSpeed = MoveSpeed * 1.8 // Lite snabbare när man springer
|
||||
}
|
||||
|
||||
@@ -108,62 +219,60 @@ func (s *PlayScene) Update() error {
|
||||
entIn := s.world.GetEntityAt(currentGridX, currentGridY, currentGridZ)
|
||||
|
||||
isClimbing := false
|
||||
if entIn != nil && entIn.IsClimbable() && ebiten.IsKeyPressed(ebiten.KeyShift) {
|
||||
if entIn != nil && entIn.IsClimbable() && input.Manager.IsActionPressed("ClimbMode") {
|
||||
isClimbing = true
|
||||
}
|
||||
|
||||
if isClimbing {
|
||||
p.Vel[1] = 0 // Ingen gravitation när man klättrar
|
||||
|
||||
// W, A, S, D styr X och Y axlar
|
||||
if ebiten.IsKeyPressed(ebiten.KeyA) {
|
||||
if input.Manager.IsActionPressed("ClimbLeft") {
|
||||
p.Vel[0] = -currentMoveSpeed
|
||||
p.FacingRight = false
|
||||
isMoving = true
|
||||
}
|
||||
if ebiten.IsKeyPressed(ebiten.KeyD) {
|
||||
if input.Manager.IsActionPressed("ClimbRight") {
|
||||
p.Vel[0] = currentMoveSpeed
|
||||
p.FacingRight = true
|
||||
isMoving = true
|
||||
}
|
||||
if ebiten.IsKeyPressed(ebiten.KeyW) {
|
||||
if input.Manager.IsActionPressed("ClimbUp") {
|
||||
p.Vel[1] = -currentMoveSpeed // Uppåt
|
||||
isMoving = true
|
||||
}
|
||||
if ebiten.IsKeyPressed(ebiten.KeyS) {
|
||||
if input.Manager.IsActionPressed("ClimbDown") {
|
||||
p.Vel[1] = currentMoveSpeed // Nedåt
|
||||
isMoving = true
|
||||
}
|
||||
// Upp/ner pilarna styr Z-axeln
|
||||
if ebiten.IsKeyPressed(ebiten.KeyUp) {
|
||||
p.Vel[2] = -currentMoveSpeed
|
||||
if input.Manager.IsActionPressed("ClimbIn") {
|
||||
p.Vel[2] = -currentMoveSpeed // Inåt (mot djupet Z-)
|
||||
isMoving = true
|
||||
}
|
||||
if ebiten.IsKeyPressed(ebiten.KeyDown) {
|
||||
p.Vel[2] = currentMoveSpeed
|
||||
if input.Manager.IsActionPressed("ClimbOut") {
|
||||
p.Vel[2] = currentMoveSpeed // Utåt (från djupet Z+)
|
||||
isMoving = true
|
||||
}
|
||||
} else {
|
||||
if ebiten.IsKeyPressed(ebiten.KeyLeft) || ebiten.IsKeyPressed(ebiten.KeyA) {
|
||||
if input.Manager.IsActionPressed("MoveLeft") {
|
||||
p.Vel[0] = -currentMoveSpeed
|
||||
p.FacingRight = false
|
||||
isMoving = true
|
||||
}
|
||||
if ebiten.IsKeyPressed(ebiten.KeyRight) || ebiten.IsKeyPressed(ebiten.KeyD) {
|
||||
if input.Manager.IsActionPressed("MoveRight") {
|
||||
p.Vel[0] = currentMoveSpeed
|
||||
p.FacingRight = true
|
||||
isMoving = true
|
||||
}
|
||||
if ebiten.IsKeyPressed(ebiten.KeyUp) || ebiten.IsKeyPressed(ebiten.KeyW) {
|
||||
if input.Manager.IsActionPressed("MoveUp") {
|
||||
p.Vel[2] = -currentMoveSpeed
|
||||
isMoving = true
|
||||
}
|
||||
if ebiten.IsKeyPressed(ebiten.KeyDown) || ebiten.IsKeyPressed(ebiten.KeyS) {
|
||||
if input.Manager.IsActionPressed("MoveDown") {
|
||||
p.Vel[2] = currentMoveSpeed
|
||||
isMoving = true
|
||||
}
|
||||
|
||||
if ebiten.IsKeyPressed(ebiten.KeySpace) && p.IsGrounded {
|
||||
if input.Manager.IsActionPressed("Jump") && p.IsGrounded {
|
||||
p.Vel[1] = JumpForce
|
||||
p.IsGrounded = false
|
||||
}
|
||||
@@ -173,29 +282,99 @@ func (s *PlayScene) Update() error {
|
||||
}
|
||||
}
|
||||
|
||||
// === FYSIK OCH KOLLISION ===
|
||||
|
||||
// Få tag på det nuvarande objektet i spelarens mitt-punkt för att veta om vi står i något klättringsbart
|
||||
currGridX := int((p.Pos[0] + p.Width/2) / entities.TileSize)
|
||||
currGridY := int((p.Pos[1] + p.Height/2) / entities.TileSize)
|
||||
currGridZ := int((p.Pos[2] + p.Width/2) / entities.TileSize)
|
||||
|
||||
currentEnt := s.world.GetEntityAt(currGridX, currGridY, currGridZ)
|
||||
isCurrentClimbable := currentEnt != nil && currentEnt.IsClimbable()
|
||||
|
||||
// 1. Hantera kollision för X-axeln (vänster/höger)
|
||||
nextX := p.Pos[0] + p.Vel[0]
|
||||
nextY := p.Pos[1] + p.Vel[1]
|
||||
nextZ := p.Pos[2] + p.Vel[2]
|
||||
if p.Vel[0] != 0 {
|
||||
targetGridX := int((nextX + p.Width/2) / entities.TileSize)
|
||||
entX := s.world.GetEntityAt(targetGridX, currGridY, currGridZ)
|
||||
|
||||
gridY := int((nextY + p.Height) / entities.TileSize)
|
||||
gridX := int((nextX + p.Width/2) / entities.TileSize)
|
||||
gridZ := int((nextZ + p.Width/2) / entities.TileSize)
|
||||
if entX != nil && entX.IsBlocking() {
|
||||
isTargetClimbable := entX.IsClimbable()
|
||||
|
||||
entY := s.world.GetEntityAt(gridX, gridY, gridZ)
|
||||
if entY != nil && entY.IsBlocking() && p.Vel[1] >= 0 {
|
||||
nextY = float64(gridY)*entities.TileSize - p.Height - 0.1
|
||||
p.Vel[1] = 0
|
||||
p.IsGrounded = true
|
||||
} else {
|
||||
p.IsGrounded = false
|
||||
// Auto-klättra om målet är klättringsbart ELLER om vi redan står i något klättringsbart (t.ex framför en vägg på en stege)
|
||||
if isTargetClimbable || isCurrentClimbable {
|
||||
nextX = p.Pos[0] // Avbryt rörelse framåt
|
||||
p.Vel[0] = 0
|
||||
p.Pos[1] -= MoveSpeed * 0.6 // Långsam rörelse uppåt ("klättra upp")
|
||||
p.IsGrounded = false
|
||||
} else {
|
||||
// Vanlig vägg - stoppa rörelse helt
|
||||
nextX = p.Pos[0]
|
||||
p.Vel[0] = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p.Pos[0] = nextX
|
||||
p.Pos[1] = nextY
|
||||
|
||||
// 2. Hantera kollision för Z-axeln (djup in/ut)
|
||||
nextZ := p.Pos[2] + p.Vel[2]
|
||||
if p.Vel[2] != 0 {
|
||||
// Uppdatera currGridX eftersom vi kan ha rört oss
|
||||
currGridX = int((p.Pos[0] + p.Width/2) / entities.TileSize)
|
||||
targetGridZ := int((nextZ + p.Width/2) / entities.TileSize)
|
||||
entZ := s.world.GetEntityAt(currGridX, currGridY, targetGridZ)
|
||||
|
||||
if entZ != nil && entZ.IsBlocking() {
|
||||
isTargetClimbable := entZ.IsClimbable()
|
||||
|
||||
if isTargetClimbable || isCurrentClimbable {
|
||||
nextZ = p.Pos[2] // Avbryt rörelse framåt
|
||||
p.Vel[2] = 0
|
||||
p.Pos[1] -= MoveSpeed * 0.6 // Långsam rörelse uppåt ("klättra upp")
|
||||
p.IsGrounded = false
|
||||
} else {
|
||||
// Vanlig vägg - stoppa rörelse helt
|
||||
nextZ = p.Pos[2]
|
||||
p.Vel[2] = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
p.Pos[2] = nextZ
|
||||
|
||||
// Kolla ifall vi står på en portal
|
||||
standEnt := s.world.GetEntityAt(gridX, gridY, gridZ)
|
||||
// 3. Hantera kollision för Y-axeln (upp/ner + gravitation)
|
||||
nextY := p.Pos[1] + p.Vel[1]
|
||||
|
||||
gridX := int((p.Pos[0] + p.Width/2) / entities.TileSize)
|
||||
gridZ := int((p.Pos[2] + p.Width/2) / entities.TileSize)
|
||||
|
||||
if p.Vel[1] >= 0 {
|
||||
// Faller (eller står still) - kolla kollision med marken (fötterna)
|
||||
gridYFeet := int((nextY + p.Height) / entities.TileSize)
|
||||
entY := s.world.GetEntityAt(gridX, gridYFeet, gridZ)
|
||||
|
||||
if entY != nil && entY.IsBlocking() {
|
||||
nextY = float64(gridYFeet)*entities.TileSize - p.Height - 0.1
|
||||
p.Vel[1] = 0
|
||||
p.IsGrounded = true
|
||||
} else {
|
||||
p.IsGrounded = false
|
||||
}
|
||||
} else {
|
||||
// Hoppar eller klättrar uppåt - kolla kollision med taket (huvudet)
|
||||
p.IsGrounded = false
|
||||
gridYHead := int(nextY / entities.TileSize)
|
||||
entY := s.world.GetEntityAt(gridX, gridYHead, gridZ)
|
||||
|
||||
// Vi studsar i taket om det är solid OCH inte är klättringsbart
|
||||
if entY != nil && entY.IsBlocking() && !entY.IsClimbable() {
|
||||
nextY = float64(gridYHead+1)*entities.TileSize + 0.1
|
||||
p.Vel[1] = 0
|
||||
}
|
||||
}
|
||||
p.Pos[1] = nextY
|
||||
|
||||
// Kolla ifall vi står på en portal (mittpunkten)
|
||||
standEnt := s.world.GetEntityAt(gridX, int((p.Pos[1]+p.Height/2)/entities.TileSize), gridZ)
|
||||
if prt, ok := standEnt.(*entities.Portal); ok {
|
||||
log.Println("Byter rum till: ", prt.TargetMap)
|
||||
newW, err := entities.LoadWorldFromTiled("assets/maps/" + prt.TargetMap + ".tmj")
|
||||
@@ -236,87 +415,109 @@ func (s *PlayScene) Draw(screen *ebiten.Image) {
|
||||
camY := s.player.Pos[1] - float64(ViewSize)/2.0
|
||||
camZ := s.player.Pos[2] - float64(ViewSize)/2.0
|
||||
|
||||
// Vänster vy: Sido-vy (renderar objekt vid spelarens Z och "inåt", max 3 djup)
|
||||
// Rendera från djupast till spelarens Z (mindre Z är djupare inåt bild/scen)
|
||||
// Vänster vy: Sido-vy (renderar objekt vid spelarens Z, max -3 till +3 djup)
|
||||
leftDepthStart := playerGridZ - 3
|
||||
if leftDepthStart < 0 {
|
||||
leftDepthStart = 0
|
||||
}
|
||||
for zLevel := leftDepthStart; zLevel <= playerGridZ; zLevel++ {
|
||||
tint := float32(1.0)
|
||||
leftDepthEnd := playerGridZ + 3
|
||||
if leftDepthEnd >= s.world.Depth {
|
||||
leftDepthEnd = s.world.Depth - 1
|
||||
}
|
||||
|
||||
for zLevel := leftDepthStart; zLevel <= leftDepthEnd; zLevel++ {
|
||||
alpha := float32(1.0)
|
||||
if zLevel < playerGridZ {
|
||||
// Förskugga och gör transparent lager längre "in"
|
||||
diff := float32(playerGridZ - zLevel)
|
||||
tint = 1.0 - (diff * 0.2)
|
||||
alpha = 1.0 - (diff * 0.25)
|
||||
if tint < 0.2 {
|
||||
tint = 0.2
|
||||
}
|
||||
diff := float32(zLevel - playerGridZ)
|
||||
|
||||
if diff < 0 {
|
||||
// Bakom spelaren: självande alpha
|
||||
alpha = 1.0 + (diff * 0.2) // diff är negativt, så detta minskar alpha
|
||||
if alpha < 0.2 {
|
||||
alpha = 0.2
|
||||
}
|
||||
}
|
||||
|
||||
for x := 0; x < s.world.Width; x++ {
|
||||
for y := 0; y < s.world.Height; y++ {
|
||||
ent := s.world.GetEntityAt(x, y, zLevel)
|
||||
if ent != nil {
|
||||
px := float64(x)*entities.TileSize - camX
|
||||
py := float64(y)*entities.TileSize - camY
|
||||
ent.DrawSide(s.leftView, px, py, tint, alpha)
|
||||
}
|
||||
} else if diff > 0 {
|
||||
// Framför spelaren: självande alpha
|
||||
alpha = 1.0 - (diff * 0.3)
|
||||
if alpha < 0.1 {
|
||||
alpha = 0.1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Höger vy: Ovan-vy (renderar ner i marken så att det känns som det går "in" i bilden)
|
||||
// -1: Två block inåt jord/hål (Djupast)
|
||||
// 0: Ett block inåt jord/hål
|
||||
// +1: Samma (eller 1 över)
|
||||
// För att saker under spelaren ska ligga bakom byter vi tecken. "upp" i z/y är nu inåt.
|
||||
// Vi visar tre block nedåt i Y: playerGridY+3, Y+2, Y+1, Y
|
||||
topLevels := []int{playerGridY + 3, playerGridY + 2, playerGridY + 1, playerGridY}
|
||||
for i, yLevel := range topLevels {
|
||||
if yLevel >= 0 && yLevel < s.world.Height {
|
||||
tint := float32(1.0)
|
||||
alpha := float32(1.0)
|
||||
|
||||
// Sätt färger baserat på relativ nivå ("inåt") där de djupaste (Y+3) är mörkare
|
||||
// Index 0 är djupast i marken
|
||||
if i == 0 { // -2 block (långt under fötter)
|
||||
tint = 0.6
|
||||
alpha = 0.4
|
||||
} else if i == 1 { // -1 block (nyss under fötter)
|
||||
tint = 0.8
|
||||
alpha = 0.6
|
||||
} else if i == 2 { // marken spelaren står på
|
||||
tint = 1.0
|
||||
alpha = 1.0
|
||||
} else if i == 3 { // spelarens fothöjd (0)
|
||||
tint = 1.2
|
||||
alpha = 1.0
|
||||
}
|
||||
|
||||
// Rendera spelaren på rätt Z-lager (vid diff == 0)
|
||||
if zLevel == playerGridZ {
|
||||
for x := 0; x < s.world.Width; x++ {
|
||||
for z := 0; z < s.world.Depth; z++ {
|
||||
ent := s.world.GetEntityAt(x, yLevel, z)
|
||||
for y := 0; y < s.world.Height; y++ {
|
||||
ent := s.world.GetEntityAt(x, y, zLevel)
|
||||
if ent != nil {
|
||||
px := float64(x)*entities.TileSize - camX
|
||||
pz := float64(z)*entities.TileSize - camZ
|
||||
ent.DrawTop(s.rightView, px, pz, tint, alpha)
|
||||
py := float64(y)*entities.TileSize - camY
|
||||
ent.DrawSide(s.leftView, px, py, 1.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
s.drawPlayerSide(s.leftView, camX, camY)
|
||||
} else {
|
||||
for x := 0; x < s.world.Width; x++ {
|
||||
for y := 0; y < s.world.Height; y++ {
|
||||
ent := s.world.GetEntityAt(x, y, zLevel)
|
||||
if ent != nil {
|
||||
px := float64(x)*entities.TileSize - camX
|
||||
py := float64(y)*entities.TileSize - camY
|
||||
ent.DrawSide(s.leftView, px, py, alpha)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Rendera spelaren på toppen (efter marken och spelarens lager är ritat)
|
||||
if i == 3 {
|
||||
s.drawPlayerTop(s.rightView, camX, camZ)
|
||||
}
|
||||
}
|
||||
|
||||
s.drawPlayerSide(s.leftView, camX, camY)
|
||||
// Höger vy: Ovan-vy (renderar Y-lager runt spelaren)
|
||||
// Positivt 'diff' i Y-axel betyder djupare in i marken (Längre bort = mer transparent)
|
||||
// Negativt 'diff' i Y-axel betyder högre upp mot kameran (Närmare = mer transparent så man ser igenom)
|
||||
for diff := 3; diff >= -3; diff-- {
|
||||
yLevel := playerGridY + diff
|
||||
if yLevel >= 0 && yLevel < s.world.Height {
|
||||
alpha := float32(1.0)
|
||||
|
||||
if diff > 0 {
|
||||
// Under marknivån: sjunkande alpha
|
||||
alpha = 1.0 - (float32(diff) * 0.2)
|
||||
if alpha < 0.2 {
|
||||
alpha = 0.2
|
||||
}
|
||||
} else if diff < 0 {
|
||||
// Över marknivån: sjunkande alpha
|
||||
alpha = 1.0 - (float32(-diff) * 0.3)
|
||||
if alpha < 0.1 {
|
||||
alpha = 0.1
|
||||
}
|
||||
}
|
||||
|
||||
if diff == 0 {
|
||||
for x := 0; x < s.world.Width; x++ {
|
||||
for z := 0; z < s.world.Depth; z++ {
|
||||
ent := s.world.GetEntityAt(x, yLevel, z)
|
||||
if ent != nil {
|
||||
px := float64(x)*entities.TileSize - camX
|
||||
pz := float64(z)*entities.TileSize - camZ
|
||||
ent.DrawTop(s.rightView, px, pz, 1.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
s.drawPlayerTop(s.rightView, camX, camZ)
|
||||
} else {
|
||||
for x := 0; x < s.world.Width; x++ {
|
||||
for z := 0; z < s.world.Depth; z++ {
|
||||
ent := s.world.GetEntityAt(x, yLevel, z)
|
||||
if ent != nil {
|
||||
px := float64(x)*entities.TileSize - camX
|
||||
pz := float64(z)*entities.TileSize - camZ
|
||||
ent.DrawTop(s.rightView, px, pz, alpha)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
opL := &ebiten.DrawImageOptions{}
|
||||
opL.GeoM.Translate(10, 100)
|
||||
@@ -327,6 +528,13 @@ func (s *PlayScene) Draw(screen *ebiten.Image) {
|
||||
screen.DrawImage(s.rightView, opR)
|
||||
|
||||
ebitenutil.DebugPrint(screen, "VÄNSTER (Sido vy) HÖGER (Top vy: Slice av din Hojd)")
|
||||
|
||||
// Rita UI ovanpå allt, beroende på state
|
||||
if s.state == StatePaused {
|
||||
s.drawPauseUI(screen)
|
||||
} else if s.state == StateSettings {
|
||||
s.drawSettingsUI(screen)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *PlayScene) drawPlayerSide(screen *ebiten.Image, camX, camY float64) {
|
||||
@@ -359,10 +567,105 @@ func (s *PlayScene) drawPlayerSide(screen *ebiten.Image, camX, camY float64) {
|
||||
|
||||
func (s *PlayScene) drawPlayerTop(screen *ebiten.Image, camX, camZ float64) {
|
||||
p := s.player
|
||||
|
||||
sx := p.AnimationFrame * 96
|
||||
srcRect := image.Rect(sx, 0, sx+96, 96)
|
||||
var activeSprite *ebiten.Image
|
||||
|
||||
if p.Vel[0] != 0 || p.Vel[2] != 0 || p.Vel[1] != 0 {
|
||||
activeSprite = p.SpriteRun
|
||||
} else {
|
||||
activeSprite = p.SpriteIdle
|
||||
}
|
||||
|
||||
subImg := activeSprite.SubImage(srcRect).(*ebiten.Image)
|
||||
|
||||
op := &ebiten.DrawImageOptions{}
|
||||
if !p.FacingRight {
|
||||
op.GeoM.Scale(-1, 1)
|
||||
op.GeoM.Translate(96, 0)
|
||||
}
|
||||
|
||||
drawX := p.Pos[0] - camX - 32
|
||||
drawZ := p.Pos[2] - camZ - 64
|
||||
op.GeoM.Translate(drawX, drawZ)
|
||||
screen.DrawImage(p.SpriteTop, op)
|
||||
|
||||
// Rita med lite tint i toppen kanske? Vi ritar bara ut imagen
|
||||
screen.DrawImage(subImg, op)
|
||||
}
|
||||
|
||||
func (s *PlayScene) drawPauseUI(screen *ebiten.Image) {
|
||||
// Mörka ner bakgrunden något
|
||||
overlay := ebiten.NewImage(800, 600)
|
||||
overlay.Fill(color.RGBA{0, 0, 0, 150})
|
||||
screen.DrawImage(overlay, &ebiten.DrawImageOptions{})
|
||||
|
||||
ebitenutil.DebugPrintAt(screen, "--- PAUSAD ---", 350, 200)
|
||||
|
||||
options := []string{"Fortsatt", "Installningar"}
|
||||
for i, opt := range options {
|
||||
prefix := " "
|
||||
if i == s.selectedIndex {
|
||||
prefix = "> "
|
||||
}
|
||||
ebitenutil.DebugPrintAt(screen, prefix+opt, 350, 250+(i*30))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *PlayScene) drawSettingsUI(screen *ebiten.Image) {
|
||||
overlay := ebiten.NewImage(800, 600)
|
||||
overlay.Fill(color.RGBA{0, 0, 0, 200})
|
||||
screen.DrawImage(overlay, &ebiten.DrawImageOptions{})
|
||||
|
||||
ebitenutil.DebugPrintAt(screen, "--- INSTALLNINGAR ---", 300, 30)
|
||||
|
||||
if input.Manager.IsRecording() {
|
||||
ebitenutil.DebugPrintAt(screen, ">> SPELAR IN: HÅLL IN TANGENTER OCH TRYCK ENTER FOR ATT SPARA <<", 180, 60)
|
||||
ebitenutil.DebugPrintAt(screen, "ESC for att avbryta", 300, 80)
|
||||
} else {
|
||||
ebitenutil.DebugPrintAt(screen, "Tryck Enter for att ga in i redigeringslage, ESC for att abryta", 180, 60)
|
||||
}
|
||||
|
||||
startY := 120
|
||||
for i, action := range s.sortedActions {
|
||||
prefix := " "
|
||||
if i == s.selectedIndex {
|
||||
prefix = "> "
|
||||
}
|
||||
|
||||
// Bygg en sträng för att visa nuvarande tangenter
|
||||
bindingStr := ""
|
||||
bindings := input.Manager.Actions[action]
|
||||
if input.Manager.IsRecording() && input.Manager.GetRecordingAction() == action {
|
||||
// Visar vilka knappar som spelas in just nu
|
||||
recKeys := input.Manager.GetRecordingKeys()
|
||||
if len(recKeys) == 0 {
|
||||
bindingStr = "[Vantar pa dig...]"
|
||||
} else {
|
||||
names := []string{}
|
||||
for _, rk := range recKeys {
|
||||
names = append(names, input.KeyName(rk))
|
||||
}
|
||||
bindingStr = fmt.Sprintf("[TRYCK ENTER FOR ATT SPARA: %v]", names)
|
||||
}
|
||||
} else {
|
||||
if len(bindings) > 0 {
|
||||
for bi, b := range bindings {
|
||||
if bi > 0 {
|
||||
bindingStr += " ELLER "
|
||||
}
|
||||
names := []string{}
|
||||
for _, k := range b {
|
||||
names = append(names, input.KeyName(k))
|
||||
}
|
||||
bindingStr += fmt.Sprintf("%v", names)
|
||||
}
|
||||
} else {
|
||||
bindingStr = "[Ingen]"
|
||||
}
|
||||
}
|
||||
|
||||
line := fmt.Sprintf("%s%-15s : %s", prefix, action, bindingStr)
|
||||
ebitenutil.DebugPrintAt(screen, line, 100, startY+(i*25))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user