From 5fe8960b575f5b0216faafe496a2a9927fb1bb9c Mon Sep 17 00:00:00 2001 From: davidovski Date: Tue, 23 Apr 2024 14:46:27 +0100 Subject: add menu --- level.go | 11 +++++- main.go | 131 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------ objects.go | 12 ++++-- 3 files changed, 137 insertions(+), 17 deletions(-) diff --git a/level.go b/level.go index bdbb8fc..5baef9e 100644 --- a/level.go +++ b/level.go @@ -5,6 +5,13 @@ import ( ) func StartGame(g *Game) { + //g.state = IN_GAME + g.player = NewPlayer(g, 4 * tileSize, 9 * tileSize) + g.objects = append(g.objects, g.player) + g.exit = NewExit(g, 21 * tileSize, 9 * tileSize) + g.objects = append(g.objects, g.exit) + + g.ResetAll() StartLevel1(g) } @@ -43,7 +50,7 @@ func noMoveable(g *Game) { func StartLevel1(g *Game ) { - g.SetInGame() + //g.SetInGame() tilemap := NewTilemap([][]int{ { @@ -206,6 +213,8 @@ func StartLevel5(g *Game) { //g.toPlace = append(g.toPlace, NewSpring(g, 0, 0)) g.exit.movable = true + g.toPlace = append(g.toPlace, g.exit) + g.RemoveObject(g.exit) g.toPlace = append(g.toPlace, NewSpring(g, 0, 0)) // after end g.QueueState(ReverseLevel) diff --git a/main.go b/main.go index 56f739a..4a3a9ed 100644 --- a/main.go +++ b/main.go @@ -13,6 +13,7 @@ import ( "github.com/hajimehoshi/ebiten/v2" _ "github.com/hajimehoshi/ebiten/v2/ebitenutil" "github.com/hajimehoshi/ebiten/v2/inpututil" + "github.com/hajimehoshi/ebiten/v2/vector" "github.com/hajimehoshi/ebiten/v2/text/v2" "github.com/hajimehoshi/ebiten/v2/examples/resources/fonts" "github.com/hajimehoshi/ebiten/v2/audio" @@ -43,6 +44,10 @@ const ( shadowOffset = 1 musicLoopLength = 230 + + menuFadeInTime = 80 + buttonOffset = 4.0 + buttonOffsetPressed = 2.0 ) var ( @@ -96,12 +101,15 @@ var ( fontFaceSource *text.GoTextFaceSource rewindSpeed = 2 + bx, by, bw, bh float32 + bo float32 = buttonOffset ) type State int const ( - IN_GAME State = iota + MENU State = iota + IN_GAME END PLACING PAUSED @@ -115,6 +123,7 @@ type RecPoint struct { vy float32 alpha float32 delta int + state int } type AudioPlayer struct { @@ -161,6 +170,7 @@ func (g * Game)RecordPoint() { vy: object.vy, alpha: object.alpha, delta: object.delta, + state: object.state, }) } g.recording = append(g.recording, points) @@ -181,6 +191,7 @@ func (g * Game)ReplayPoint() { obj.vy = point.vy obj.alpha = point.alpha obj.delta = point.delta + obj.state = point.state } } @@ -236,6 +247,7 @@ func (g * Game) ResetAll() { obj.vx = 0 obj.vy = 0 obj.delta = 0 + obj.highlight = false } g.recording = g.recording[:0]; } @@ -243,14 +255,8 @@ func (g * Game) ResetAll() { func (g *Game) Init() { g.surface = ebiten.NewImage(screenWidth, screenHeight) g.shaderName = "sky" + g.state = MENU - g.player = NewPlayer(g, 4 * tileSize, 9 * tileSize) - g.objects = append(g.objects, g.player) - g.exit = NewExit(g, 21 * tileSize, 9 * tileSize) - g.objects = append(g.objects, g.exit) - - g.ResetAll() - StartGame(g) g.audioPlayer.ambientAudio.SetVolume(0) @@ -271,8 +277,29 @@ func (g *Game) SetEditingMode() { func (g *Game) Update() error { g.time += 1 + if g.state == MENU { + if float32(g.time) > menuFadeInTime { + cx, cy := ebiten.CursorPosition() + onButton := float32(cx) > bx && float32(cy) > by && float32(cx) < bx + bw && float32(cy) < by + bh + if inpututil.IsMouseButtonJustPressed(ebiten.MouseButton0) { + if onButton { + bo = buttonOffsetPressed + } else { + bo = buttonOffset + } + } + if inpututil.IsMouseButtonJustReleased(ebiten.MouseButton0) { + bo = buttonOffset + if onButton { + g.animStart = g.time + 60 + StartGame(g) + } + } + } + } + - if g.state == IN_GAME || g.state == PLACING { + if g.state == MENU || g.state == IN_GAME || g.state == PLACING { if g.audioPlayer.ambientAudio.Position().Seconds() > musicLoopLength { g.audioPlayer.ambientAudio.Rewind() } @@ -351,12 +378,12 @@ func (g *Game) Update() error { if g.state == PLACING { g.UpdatePlacing() } - - if g.player.y > screenHeight { + if g.player != nil && g.player.y > screenHeight { g.KillPlayer() } + return nil } @@ -485,7 +512,50 @@ func (g *Game) DrawTheEnd(surface *ebiten.Image, alpha float32) { Size: textSize, Source: fontFaceSource, }, textOp) +} + +func (g *Game) DrawTitle(surface *ebiten.Image, alpha float32) { + textSize := 30.0 + tmp := ebiten.NewImage(screenWidth, screenHeight) + msg := fmt.Sprintf("LEVEL") + textOp := &text.DrawOptions{} + textOp.GeoM.Translate((screenWidth - textSize*5 ) / 2, (screenHeight - textSize) / 3) + textOp.ColorScale.ScaleWithColor(color.RGBA{216, 211, 210, 255}) + text.Draw(tmp, msg, &text.GoTextFace{ + Size: textSize, + Source: fontFaceSource, + }, textOp) + ShadowDraw(surface, tmp, 0, 0, alpha) +} +func (g *Game) DrawStart(surface *ebiten.Image, alpha float32) { + msg := fmt.Sprintf("play") + tmp := ebiten.NewImage(screenWidth, screenHeight) + var textSize float32 = 15.0 + + var x, y float32 = (screenWidth - textSize*5 ) / 2 + bo/2, (screenHeight + textSize) / 3 + screenHeight / 3 + bo/2 + var padding float32 = 5.0 + + c := color.RGBA{55, 53, 53, 255} + bx, by, bw, bh = x - padding, y - padding, (2*padding + float32(len(msg))*textSize) , (2.0*padding + textSize) + vector.DrawFilledRect(tmp, bx, by, bw, bh, c, false) + + c = color.RGBA{79, 78, 78, 255} + vector.DrawFilledRect(tmp, bx-bo, by-bo, bw, bh, c, false) + + textOp := &text.DrawOptions{} + textOp.GeoM.Translate(float64(x-bo), float64(y-bo)) + textOp.ColorScale.ScaleWithColor(color.RGBA{216, 211, 210, 255}) + //textOp.ColorScale.ScaleAlpha(alpha) + textOp.Filter = ebiten.FilterNearest + text.Draw(tmp, msg, &text.GoTextFace{ + Size: float64(textSize), + Source: fontFaceSource, + }, textOp) + + op := &ebiten.DrawImageOptions{} + op.ColorScale.ScaleAlpha(alpha) + surface.DrawImage(tmp, op) } func (g *Game) IsShowTheEnd() bool { @@ -497,6 +567,39 @@ func (g *Game) Draw(screen *ebiten.Image) { DrawBackground(screen, g.time) + if g.state == MENU { + var scale float32 = 1.0 + delta := float32(g.time) + if g.animStart > 0 { + delta = float32((g.animStart+menuFadeInTime) - g.time) + scale = 0.5 + } + + if g.tilemap != nil { + polation := float32(math.Pow(float64(delta*scale)/menuFadeInTime, 3))*screenHeight + g.tilemap.Draw(screen, 0, polation - 2) + } + + alpha := float32(delta) * scale / (menuFadeInTime/2.0) + if alpha > 1.0 { + alpha = 1.0 + } + g.DrawTitle(screen, alpha) + + alpha = float32(delta - (menuFadeInTime/2.0)) * scale / (menuFadeInTime/2.0) + if alpha > 1.0 { + alpha = 1.0 + } + g.DrawStart(screen, alpha) + + + if g.animStart > 0 && delta <= 0 { + g.animStart = 0 + g.SetInGame() + } + return + } + g.surface.Fill(color.RGBA{0, 0, 0, 0}) g.tilemap.Draw(g.surface, 0, -2) @@ -512,7 +615,7 @@ func (g *Game) Draw(screen *ebiten.Image) { } op := &ebiten.DrawImageOptions{} - op.GeoM.Translate(float64(g.offsetX), float64(g.offsetY-2)) + op.GeoM.Translate(float64(g.offsetX), float64(g.offsetY)) if g.IsShowTheEnd() { // draw THE END @@ -661,6 +764,10 @@ func (g *Game) SetInGame() { g.state = IN_GAME g.player.alpha = 1.0 g.StopRewinding() + + for _, object := range g.objects { + object.highlight = false + } } func (g *Game) SetPlacing() { diff --git a/objects.go b/objects.go index fe3028a..141bf65 100644 --- a/objects.go +++ b/objects.go @@ -159,7 +159,7 @@ func (o * GameObject) Update(tilemap Tilemap, others []*GameObject) { } if o.HasCollision(tilemap, others, direction) { - if ! o.onGround && o.vy > gravity*10 { + if ! o.onGround && o.vy > gravity*1210 { o.playLand() } o.onGround = true; @@ -217,14 +217,18 @@ func (o * GameObject) HasCollision(tilemap Tilemap, others []*GameObject, dir Di return false } - func ShadowDraw(screen *ebiten.Image, image *ebiten.Image, x, y float32, alpha float32) { + ShadowDrawOffset(screen, image, x, y, alpha, shadowOffset) + } + + +func ShadowDrawOffset(screen *ebiten.Image, image *ebiten.Image, x, y, alpha, offset float32) { op := &ebiten.DrawImageOptions{} - if alpha > 0{ + if alpha > 0 { op = &ebiten.DrawImageOptions{} op.ColorScale.ScaleAlpha(alpha) op.ColorScale.Scale(0, 0, 0, 1); - op.GeoM.Translate(float64(x+shadowOffset), float64(y + shadowOffset)) + op.GeoM.Translate(float64(x+offset), float64(y + offset)) screen.DrawImage(image, op) } op = &ebiten.DrawImageOptions{} -- cgit v1.2.1