More updates to credits. Added tick time

This commit is contained in:
Tim Sarbin 2019-10-26 02:11:28 -04:00
parent bbcb811836
commit a535d447af
6 changed files with 162 additions and 26 deletions

View File

@ -209,7 +209,7 @@ func (v *Engine) Update() {
return
}
v.CurrentScene.Update()
v.CurrentScene.Update(float64(1) / ebiten.CurrentTPS())
v.UIManager.Update()
}

View File

@ -1,7 +1,9 @@
package Scenes
import (
"encoding/binary"
"bytes"
"fmt"
"image/color"
"strings"
"unicode/utf16"
"unicode/utf8"
@ -14,37 +16,63 @@ import (
"github.com/hajimehoshi/ebiten"
)
type labelItem struct {
Label *UI.Label
IsHeading bool
Available bool
}
// Credits represents the credits scene
type Credits struct {
uiManager *UI.Manager
soundManager *Sound.Manager
fileProvider Common.FileProvider
sceneProvider SceneProvider
creditsBackground *Common.Sprite
exitButton *UI.Button
creditsText []string
uiManager *UI.Manager
soundManager *Sound.Manager
fileProvider Common.FileProvider
sceneProvider SceneProvider
creditsBackground *Common.Sprite
exitButton *UI.Button
creditsText []string
labels []*labelItem
cycleTime float64
cyclesTillNextLine int
doneWithCredits bool
}
// CreateCredits creates an instance of the credits scene
func CreateCredits(fileProvider Common.FileProvider, sceneProvider SceneProvider, uiManager *UI.Manager, soundManager *Sound.Manager) *Credits {
result := &Credits{
fileProvider: fileProvider,
uiManager: uiManager,
soundManager: soundManager,
sceneProvider: sceneProvider,
fileProvider: fileProvider,
uiManager: uiManager,
soundManager: soundManager,
sceneProvider: sceneProvider,
labels: make([]*labelItem, 0),
cycleTime: 0,
doneWithCredits: false,
cyclesTillNextLine: 0,
}
return result
}
func utf16BytesToString(b []byte, o binary.ByteOrder) string {
utf := make([]uint16, (len(b)+(2-1))/2)
for i := 0; i+(2-1) < len(b); i += 2 {
utf[i/2] = o.Uint16(b[i:])
func utf16BytesToString(b []byte) (string, error) {
if len(b)%2 != 0 {
return "", fmt.Errorf("Must have even length byte slice")
}
if len(b)/2 < len(utf) {
utf[len(utf)-1] = utf8.RuneError
u16s := make([]uint16, 1)
ret := &bytes.Buffer{}
b8buf := make([]byte, 4)
lb := len(b)
for i := 0; i < lb; i += 2 {
u16s[0] = uint16(b[i]) + (uint16(b[i+1]) << 8)
r := utf16.Decode(u16s)
n := utf8.EncodeRune(b8buf, r[0])
ret.Write(b8buf[:n])
}
return string(utf16.Decode(utf))
return ret.String(), nil
}
// Load is called to load the resources for the credits scene
@ -61,7 +89,7 @@ func (v *Credits) Load() []func() {
v.uiManager.AddWidget(v.exitButton)
},
func() {
fileData := utf16BytesToString(v.fileProvider.LoadFile(ResourcePaths.CreditsText), binary.LittleEndian)
fileData, _ := utf16BytesToString(v.fileProvider.LoadFile(ResourcePaths.CreditsText))
v.creditsText = strings.Split(fileData, "\r\n")
},
}
@ -75,11 +103,37 @@ func (v *Credits) Unload() {
// Render renders the credits scene
func (v *Credits) Render(screen *ebiten.Image) {
v.creditsBackground.DrawSegments(screen, 4, 3, 0)
for _, label := range v.labels {
if label.Available {
continue
}
label.Label.Draw(screen)
}
}
// Update runs the update logic on the credits scene
func (v *Credits) Update() {
const secondsPerCycle = (float64(4) / float64(100000))
// Update runs the update logic on the credits scene
func (v *Credits) Update(tickTime float64) {
v.cycleTime += tickTime / float64(1000)
for v.cycleTime >= secondsPerCycle {
v.cycleTime -= secondsPerCycle
v.cyclesTillNextLine--
if !v.doneWithCredits && v.cyclesTillNextLine <= 0 {
v.addNextItem()
}
for _, label := range v.labels {
if label.Available {
continue
}
if label.Label.Y-1 < -15 {
label.Available = true
continue
}
label.Label.Y--
}
}
}
func (v *Credits) onExitButtonClicked() {
@ -87,3 +141,84 @@ func (v *Credits) onExitButtonClicked() {
mainMenu.ShowTrademarkScreen = false
v.sceneProvider.SetNextScene(mainMenu)
}
func (v *Credits) addNextItem() {
if len(v.creditsText) == 0 {
v.doneWithCredits = true
return
}
text := strings.Trim(v.creditsText[0], " ")
v.creditsText = v.creditsText[1:]
if len(text) == 0 {
v.cyclesTillNextLine = 18
return
}
isHeading := text[0] == '*'
isNextHeading := len(v.creditsText) > 0 && v.creditsText[1][0] == '*'
isNextSpace := len(v.creditsText) > 0 && len(strings.Trim(v.creditsText[1], " ")) == 0
var label = v.getNewFontLabel(isHeading)
if isHeading {
label.SetText(text[1:])
} else {
label.SetText(text)
}
isDoubled := false
if !isHeading && !isNextHeading && !isNextSpace {
isDoubled = true
// Gotta go side by side
label.MoveTo(390-int(label.Width), 605)
text2 := strings.Trim(v.creditsText[0], " ")
v.creditsText = v.creditsText[1:]
isNextHeading = len(v.creditsText[1]) > 0 && v.creditsText[1][0] == '*'
label2 := v.getNewFontLabel(isHeading)
label2.SetText(text2)
label2.MoveTo(410, 605)
} else {
label.MoveTo(400-int(label.Width/2), 605)
}
if isHeading && isNextHeading {
v.cyclesTillNextLine = 40
} else if isNextHeading {
if isDoubled {
v.cyclesTillNextLine = 40
} else {
v.cyclesTillNextLine = 70
}
} else if isHeading {
v.cyclesTillNextLine = 40
} else {
v.cyclesTillNextLine = 18
}
}
func (v *Credits) getNewFontLabel(isHeading bool) *UI.Label {
for _, label := range v.labels {
if label.Available {
label.Available = false
return label.Label
}
}
newLabelItem := &labelItem{
Available: false,
IsHeading: isHeading,
Label: UI.CreateLabel(v.fileProvider, ResourcePaths.FontFormal10, Palettes.Sky),
}
if isHeading {
newLabelItem.Label.Color = color.RGBA{255, 88, 82, 255}
} else {
newLabelItem.Label.Color = color.RGBA{198, 178, 150, 255}
}
v.labels = append(v.labels, newLabelItem)
return newLabelItem.Label
}

View File

@ -142,7 +142,7 @@ func (v *MainMenu) Render(screen *ebiten.Image) {
}
// Update runs the update logic on the main menu
func (v *MainMenu) Update() {
func (v *MainMenu) Update(tickTime float64) {
if v.ShowTrademarkScreen {
if v.uiManager.CursorButtonPressed(UI.CursorButtonLeft) {
v.leftButtonHeld = true

View File

@ -9,5 +9,5 @@ type Scene interface {
Load() []func()
Unload()
Render(screen *ebiten.Image)
Update()
Update(tickTime float64)
}

View File

@ -58,7 +58,8 @@ func CreateFont(font string, palette Palettes.Palette, fileProvider Common.FileP
func (v *Font) GetTextMetrics(text string) (width, height uint32) {
width = uint32(0)
height = uint32(0)
for _, ch := range text {
for i := 0; i < len(text); i++ {
ch := text[i]
metric := v.metrics[uint8(ch)]
width += uint32(metric.Width)
_, h := v.fontSprite.GetFrameSize(int(ch))