mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2025-01-26 19:27:31 -05:00
Do not advance state in render (#269)
* Do not advance state in render * Update advance logic for sprite and region
This commit is contained in:
parent
49b9a190f2
commit
c01bedaedf
@ -1,7 +1,7 @@
|
|||||||
package d2asset
|
package d2asset
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"errors"
|
||||||
"path"
|
"path"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ func createArchiveManager(config *d2corecommon.Configuration) *archiveManager {
|
|||||||
return &archiveManager{cache: createCache(ArchiveBudget), config: config}
|
return &archiveManager{cache: createCache(ArchiveBudget), config: config}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (am *archiveManager) loadArchiveForFilePath(filePath string) (*d2mpq.MPQ, error) {
|
func (am *archiveManager) loadArchiveForFile(filePath string) (*d2mpq.MPQ, error) {
|
||||||
am.mutex.Lock()
|
am.mutex.Lock()
|
||||||
defer am.mutex.Unlock()
|
defer am.mutex.Unlock()
|
||||||
|
|
||||||
@ -39,7 +39,24 @@ func (am *archiveManager) loadArchiveForFilePath(filePath string) (*d2mpq.MPQ, e
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, fmt.Errorf("file not found: %s", filePath)
|
return nil, errors.New("file not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (am *archiveManager) fileExistsInArchive(filePath string) (bool, error) {
|
||||||
|
am.mutex.Lock()
|
||||||
|
defer am.mutex.Unlock()
|
||||||
|
|
||||||
|
if err := am.cacheArchiveEntries(); err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, archiveEntry := range am.entries {
|
||||||
|
if archiveEntry.hashEntryMap.Contains(filePath) {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (am *archiveManager) loadArchive(archivePath string) (*d2mpq.MPQ, error) {
|
func (am *archiveManager) loadArchive(archivePath string) (*d2mpq.MPQ, error) {
|
||||||
|
@ -2,6 +2,7 @@ package d2asset
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"log"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/D2Shared/d2data/d2cof"
|
"github.com/OpenDiablo2/D2Shared/d2data/d2cof"
|
||||||
"github.com/OpenDiablo2/D2Shared/d2data/d2datadict"
|
"github.com/OpenDiablo2/D2Shared/d2data/d2datadict"
|
||||||
@ -102,7 +103,20 @@ func LoadFile(filePath string) ([]byte, error) {
|
|||||||
return nil, ErrNoInit
|
return nil, ErrNoInit
|
||||||
}
|
}
|
||||||
|
|
||||||
return singleton.fileManager.loadFile(filePath)
|
data, err := singleton.fileManager.loadFile(filePath)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("error loading file %s (%v)", filePath, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func FileExists(filePath string) (bool, error) {
|
||||||
|
if singleton == nil {
|
||||||
|
return false, ErrNoInit
|
||||||
|
}
|
||||||
|
|
||||||
|
return singleton.fileManager.fileExists(filePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadAnimation(animationPath, palettePath string) (*Animation, error) {
|
func LoadAnimation(animationPath, palettePath string) (*Animation, error) {
|
||||||
|
@ -115,7 +115,12 @@ type compositeMode struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Composite) createMode(animationMode, weaponClass string, direction int) (*compositeMode, error) {
|
func (c *Composite) createMode(animationMode, weaponClass string, direction int) (*compositeMode, error) {
|
||||||
cof, err := loadCOF(fmt.Sprintf("%s/%s/COF/%s%s%s.COF", c.object.Base, c.object.Token, c.object.Token, animationMode, weaponClass))
|
cofPath := fmt.Sprintf("%s/%s/COF/%s%s%s.COF", c.object.Base, c.object.Token, c.object.Token, animationMode, weaponClass)
|
||||||
|
if exists, _ := FileExists(cofPath); !exists {
|
||||||
|
return nil, errors.New("composite not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
cof, err := loadCOF(cofPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -249,9 +254,11 @@ func loadCompositeLayer(object *d2datadict.ObjectLookupRecord, layerKey, layerVa
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, animationPath := range animationPaths {
|
for _, animationPath := range animationPaths {
|
||||||
animation, err := LoadAnimationWithTransparency(animationPath, palettePath, transparency)
|
if exists, _ := FileExists(animationPath); exists {
|
||||||
if err == nil {
|
animation, err := LoadAnimationWithTransparency(animationPath, palettePath, transparency)
|
||||||
return animation, nil
|
if err == nil {
|
||||||
|
return animation, nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ func (fm *fileManager) loadFile(filePath string) ([]byte, error) {
|
|||||||
return value.([]byte), nil
|
return value.([]byte), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
archive, err := fm.archiveManager.loadArchiveForFilePath(filePath)
|
archive, err := fm.archiveManager.loadArchiveForFile(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -40,6 +40,11 @@ func (fm *fileManager) loadFile(filePath string) ([]byte, error) {
|
|||||||
return data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (fm *fileManager) fileExists(filePath string) (bool, error) {
|
||||||
|
filePath = fm.fixupFilePath(filePath)
|
||||||
|
return fm.archiveManager.fileExistsInArchive(filePath)
|
||||||
|
}
|
||||||
|
|
||||||
func (fm *fileManager) fixupFilePath(filePath string) string {
|
func (fm *fileManager) fixupFilePath(filePath string) string {
|
||||||
filePath = strings.ReplaceAll(filePath, "{LANG}", fm.config.Language)
|
filePath = strings.ReplaceAll(filePath, "{LANG}", fm.config.Language)
|
||||||
if strings.ToUpper(d2resource.LanguageCode) == "CHI" {
|
if strings.ToUpper(d2resource.LanguageCode) == "CHI" {
|
||||||
|
@ -232,7 +232,7 @@ func (v *CharacterSelect) moveSelectionBox() {
|
|||||||
v.d2HeroTitle.SetText(v.gameStates[v.selectedCharacter].HeroName)
|
v.d2HeroTitle.SetText(v.gameStates[v.selectedCharacter].HeroName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *CharacterSelect) Update(tickTime float64) {
|
func (v *CharacterSelect) Advance(tickTime float64) {
|
||||||
if !v.showDeleteConfirmation {
|
if !v.showDeleteConfirmation {
|
||||||
if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) {
|
if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) {
|
||||||
if !v.mouseButtonPressed {
|
if !v.mouseButtonPressed {
|
||||||
|
@ -120,7 +120,7 @@ func (v *Credits) Render(screen *d2surface.Surface) {
|
|||||||
const secondsPerCycle = float64(0.02)
|
const secondsPerCycle = float64(0.02)
|
||||||
|
|
||||||
// Update runs the update logic on the credits scene
|
// Update runs the update logic on the credits scene
|
||||||
func (v *Credits) Update(tickTime float64) {
|
func (v *Credits) Advance(tickTime float64) {
|
||||||
v.cycleTime += tickTime
|
v.cycleTime += tickTime
|
||||||
for v.cycleTime >= secondsPerCycle {
|
for v.cycleTime >= secondsPerCycle {
|
||||||
v.cycleTime -= secondsPerCycle
|
v.cycleTime -= secondsPerCycle
|
||||||
|
@ -93,7 +93,7 @@ func (v Game) Render(screen *d2surface.Surface) {
|
|||||||
v.gameControls.Render(screen)
|
v.gameControls.Render(screen)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Game) Update(tickTime float64) {
|
func (v *Game) Advance(tickTime float64) {
|
||||||
v.mapEngine.Advance(tickTime)
|
v.mapEngine.Advance(tickTime)
|
||||||
|
|
||||||
rx, ry := v.mapEngine.WorldToOrtho(v.hero.AnimatedEntity.LocationX/5, v.hero.AnimatedEntity.LocationY/5)
|
rx, ry := v.mapEngine.WorldToOrtho(v.hero.AnimatedEntity.LocationX/5, v.hero.AnimatedEntity.LocationY/5)
|
||||||
|
@ -244,7 +244,12 @@ func (v *MainMenu) Render(screen *d2surface.Surface) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update runs the update logic on the main menu
|
// Update runs the update logic on the main menu
|
||||||
func (v *MainMenu) Update(tickTime float64) {
|
func (v *MainMenu) Advance(tickTime float64) {
|
||||||
|
v.diabloLogoLeftBack.Advance(tickTime)
|
||||||
|
v.diabloLogoRightBack.Advance(tickTime)
|
||||||
|
v.diabloLogoLeft.Advance(tickTime)
|
||||||
|
v.diabloLogoRight.Advance(tickTime)
|
||||||
|
|
||||||
if v.ShowTrademarkScreen {
|
if v.ShowTrademarkScreen {
|
||||||
if v.uiManager.CursorButtonPressed(d2ui.CursorButtonLeft) {
|
if v.uiManager.CursorButtonPressed(d2ui.CursorButtonLeft) {
|
||||||
if v.leftButtonHeld {
|
if v.leftButtonHeld {
|
||||||
|
@ -206,7 +206,7 @@ func (v *MapEngineTest) Render(screen *d2surface.Surface) {
|
|||||||
screen.PopN(6)
|
screen.PopN(6)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *MapEngineTest) Update(tickTime float64) {
|
func (v *MapEngineTest) Advance(tickTime float64) {
|
||||||
v.mapEngine.Advance(tickTime)
|
v.mapEngine.Advance(tickTime)
|
||||||
|
|
||||||
ctrlPressed := v.uiManager.KeyPressed(ebiten.KeyControl)
|
ctrlPressed := v.uiManager.KeyPressed(ebiten.KeyControl)
|
||||||
|
@ -35,6 +35,17 @@ type HeroRenderInfo struct {
|
|||||||
DeselectSfx *d2audio.SoundEffect
|
DeselectSfx *d2audio.SoundEffect
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (hri *HeroRenderInfo) Advance(elapsed float64) {
|
||||||
|
advanceSprite(hri.IdleSprite, elapsed)
|
||||||
|
advanceSprite(hri.IdleSelectedSprite, elapsed)
|
||||||
|
advanceSprite(hri.ForwardWalkSprite, elapsed)
|
||||||
|
advanceSprite(hri.ForwardWalkSpriteOverlay, elapsed)
|
||||||
|
advanceSprite(hri.SelectedSprite, elapsed)
|
||||||
|
advanceSprite(hri.SelectedSpriteOverlay, elapsed)
|
||||||
|
advanceSprite(hri.BackWalkSprite, elapsed)
|
||||||
|
advanceSprite(hri.BackWalkSpriteOverlay, elapsed)
|
||||||
|
}
|
||||||
|
|
||||||
type SelectHeroClass struct {
|
type SelectHeroClass struct {
|
||||||
uiManager *d2ui.Manager
|
uiManager *d2ui.Manager
|
||||||
soundManager *d2audio.Manager
|
soundManager *d2audio.Manager
|
||||||
@ -471,12 +482,12 @@ func (v *SelectHeroClass) Render(screen *d2surface.Surface) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *SelectHeroClass) Update(tickTime float64) {
|
func (v *SelectHeroClass) Advance(tickTime float64) {
|
||||||
canSelect := true
|
canSelect := true
|
||||||
for _, info := range v.heroRenderInfo {
|
for _, info := range v.heroRenderInfo {
|
||||||
|
info.Advance(tickTime)
|
||||||
if info.Stance != d2enum.HeroStanceIdle && info.Stance != d2enum.HeroStanceIdleSelected && info.Stance != d2enum.HeroStanceSelected {
|
if info.Stance != d2enum.HeroStanceIdle && info.Stance != d2enum.HeroStanceIdleSelected && info.Stance != d2enum.HeroStanceSelected {
|
||||||
canSelect = false
|
canSelect = false
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
allIdle := true
|
allIdle := true
|
||||||
@ -652,3 +663,9 @@ func drawSprite(sprite *d2render.Sprite, target *d2surface.Surface) {
|
|||||||
sprite.Render(target)
|
sprite.Render(target)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func advanceSprite(sprite *d2render.Sprite, elapsed float64) {
|
||||||
|
if sprite != nil {
|
||||||
|
sprite.Advance(elapsed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -52,7 +52,10 @@ type Engine struct {
|
|||||||
|
|
||||||
// CreateEngine creates and instance of the OpenDiablo2 engine
|
// CreateEngine creates and instance of the OpenDiablo2 engine
|
||||||
func CreateEngine() *Engine {
|
func CreateEngine() *Engine {
|
||||||
result := &Engine{timeScale: 1.0}
|
result := &Engine{
|
||||||
|
lastTime: d2helper.Now(),
|
||||||
|
timeScale: 1.0,
|
||||||
|
}
|
||||||
|
|
||||||
result.Settings = d2corecommon.LoadConfiguration()
|
result.Settings = d2corecommon.LoadConfiguration()
|
||||||
if err := result.Settings.Save(); err != nil {
|
if err := result.Settings.Save(); err != nil {
|
||||||
@ -137,8 +140,8 @@ func (v *Engine) updateScene() {
|
|||||||
v.ResetLoading()
|
v.ResetLoading()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update updates the internal state of the engine
|
// Advance updates the internal state of the engine
|
||||||
func (v *Engine) Update() {
|
func (v *Engine) Advance() {
|
||||||
if ebiten.IsKeyPressed(ebiten.KeyAlt) && ebiten.IsKeyPressed(ebiten.KeyEnter) {
|
if ebiten.IsKeyPressed(ebiten.KeyAlt) && ebiten.IsKeyPressed(ebiten.KeyEnter) {
|
||||||
if !v.fullscreenKey {
|
if !v.fullscreenKey {
|
||||||
ebiten.SetFullscreen(!ebiten.IsFullscreen())
|
ebiten.SetFullscreen(!ebiten.IsFullscreen())
|
||||||
@ -169,13 +172,13 @@ func (v *Engine) Update() {
|
|||||||
deltaTime := (currentTime - v.lastTime) * v.timeScale
|
deltaTime := (currentTime - v.lastTime) * v.timeScale
|
||||||
v.lastTime = currentTime
|
v.lastTime = currentTime
|
||||||
|
|
||||||
v.CurrentScene.Update(deltaTime)
|
v.CurrentScene.Advance(deltaTime)
|
||||||
v.UIManager.Update()
|
v.UIManager.Advance(deltaTime)
|
||||||
d2term.Advance(deltaTime)
|
d2term.Advance(deltaTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw draws the game
|
// Draw draws the game
|
||||||
func (v Engine) Draw(target *d2surface.Surface) {
|
func (v Engine) Render(target *d2surface.Surface) {
|
||||||
if v.loadingProgress < 1.0 {
|
if v.loadingProgress < 1.0 {
|
||||||
v.LoadingSprite.SetCurrentFrame(int(d2helper.Max(0, d2helper.Min(uint32(v.LoadingSprite.GetFrameCount()-1), uint32(float64(v.LoadingSprite.GetFrameCount()-1)*v.loadingProgress)))))
|
v.LoadingSprite.SetCurrentFrame(int(d2helper.Max(0, d2helper.Min(uint32(v.LoadingSprite.GetFrameCount()-1), uint32(float64(v.LoadingSprite.GetFrameCount()-1)*v.loadingProgress)))))
|
||||||
v.LoadingSprite.Render(target)
|
v.LoadingSprite.Render(target)
|
||||||
|
@ -5,6 +5,7 @@ import "github.com/OpenDiablo2/OpenDiablo2/d2render/d2surface"
|
|||||||
// Drawable represents an instance that can be drawn
|
// Drawable represents an instance that can be drawn
|
||||||
type Drawable interface {
|
type Drawable interface {
|
||||||
Render(target *d2surface.Surface)
|
Render(target *d2surface.Surface)
|
||||||
|
Advance(elapsed float64)
|
||||||
GetSize() (width, height int)
|
GetSize() (width, height int)
|
||||||
SetPosition(x, y int)
|
SetPosition(x, y int)
|
||||||
GetPosition() (x, y int)
|
GetPosition() (x, y int)
|
||||||
|
@ -7,5 +7,5 @@ type Scene interface {
|
|||||||
Load() []func()
|
Load() []func()
|
||||||
Unload()
|
Unload()
|
||||||
Render(target *d2surface.Surface)
|
Render(target *d2surface.Surface)
|
||||||
Update(tickTime float64)
|
Advance(tickTime float64)
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ type MapRegion struct {
|
|||||||
startY float64
|
startY float64
|
||||||
imageCacheRecords map[uint32]*ebiten.Image
|
imageCacheRecords map[uint32]*ebiten.Image
|
||||||
seed int64
|
seed int64
|
||||||
currentFrame byte
|
currentFrame int
|
||||||
lastFrameTime float64
|
lastFrameTime float64
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,18 +154,6 @@ func (mr *MapRegion) loadEntities() []MapEntity {
|
|||||||
return entities
|
return entities
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mr *MapRegion) updateAnimations() {
|
|
||||||
now := d2helper.Now()
|
|
||||||
framesToAdd := math.Floor((now - mr.lastFrameTime) / 0.1)
|
|
||||||
if framesToAdd > 0 {
|
|
||||||
mr.lastFrameTime += 0.1 * framesToAdd
|
|
||||||
mr.currentFrame += byte(math.Floor(framesToAdd))
|
|
||||||
if mr.currentFrame > 9 {
|
|
||||||
mr.currentFrame = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mr *MapRegion) getStartTilePosition() (float64, float64) {
|
func (mr *MapRegion) getStartTilePosition() (float64, float64) {
|
||||||
return float64(mr.tileRect.Left) + mr.startX, float64(mr.tileRect.Top) + mr.startY
|
return float64(mr.tileRect.Left) + mr.startX, float64(mr.tileRect.Top) + mr.startY
|
||||||
}
|
}
|
||||||
@ -224,8 +212,17 @@ func (mr *MapRegion) isVisbile(viewport *Viewport) bool {
|
|||||||
return viewport.IsTileRectVisible(mr.tileRect)
|
return viewport.IsTileRectVisible(mr.tileRect)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mr *MapRegion) advance(tickTime float64) {
|
func (mr *MapRegion) advance(elapsed float64) {
|
||||||
mr.updateAnimations()
|
frameLength := 0.1
|
||||||
|
|
||||||
|
mr.lastFrameTime += elapsed
|
||||||
|
framesAdvanced := int(mr.lastFrameTime / frameLength)
|
||||||
|
mr.lastFrameTime -= float64(framesAdvanced) * frameLength
|
||||||
|
|
||||||
|
mr.currentFrame += framesAdvanced
|
||||||
|
if mr.currentFrame > 9 {
|
||||||
|
mr.currentFrame = 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mr *MapRegion) getTileWorldPosition(tileX, tileY int) (float64, float64) {
|
func (mr *MapRegion) getTileWorldPosition(tileX, tileY int) (float64, float64) {
|
||||||
@ -322,7 +319,7 @@ func (mr *MapRegion) renderFloor(tile d2ds1.FloorShadowRecord, viewport *Viewpor
|
|||||||
if !tile.Animated {
|
if !tile.Animated {
|
||||||
img = mr.getImageCacheRecord(tile.Style, tile.Sequence, 0, tile.RandomIndex)
|
img = mr.getImageCacheRecord(tile.Style, tile.Sequence, 0, tile.RandomIndex)
|
||||||
} else {
|
} else {
|
||||||
img = mr.getImageCacheRecord(tile.Style, tile.Sequence, 0, mr.currentFrame)
|
img = mr.getImageCacheRecord(tile.Style, tile.Sequence, 0, byte(mr.currentFrame))
|
||||||
}
|
}
|
||||||
if img == nil {
|
if img == nil {
|
||||||
log.Printf("Render called on uncached floor {%v,%v}", tile.Style, tile.Sequence)
|
log.Printf("Render called on uncached floor {%v,%v}", tile.Style, tile.Sequence)
|
||||||
|
@ -178,7 +178,7 @@ func (v *Button) Activate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Render renders the button
|
// Render renders the button
|
||||||
func (v Button) Render(target *d2surface.Surface) {
|
func (v *Button) Render(target *d2surface.Surface) {
|
||||||
target.PushCompositeMode(ebiten.CompositeModeSourceAtop)
|
target.PushCompositeMode(ebiten.CompositeModeSourceAtop)
|
||||||
target.PushFilter(ebiten.FilterNearest)
|
target.PushFilter(ebiten.FilterNearest)
|
||||||
target.PushTranslation(v.x, v.y)
|
target.PushTranslation(v.x, v.y)
|
||||||
@ -199,8 +199,12 @@ func (v Button) Render(target *d2surface.Surface) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v *Button) Advance(elapsed float64) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// GetEnabled returns the enabled state
|
// GetEnabled returns the enabled state
|
||||||
func (v Button) GetEnabled() bool {
|
func (v *Button) GetEnabled() bool {
|
||||||
return v.enabled
|
return v.enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,7 +214,7 @@ func (v *Button) SetEnabled(enabled bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetSize returns the size of the button
|
// GetSize returns the size of the button
|
||||||
func (v Button) GetSize() (int, int) {
|
func (v *Button) GetSize() (int, int) {
|
||||||
return v.width, v.height
|
return v.width, v.height
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,12 +225,12 @@ func (v *Button) SetPosition(x, y int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetPosition returns the location of the button
|
// GetPosition returns the location of the button
|
||||||
func (v Button) GetPosition() (x, y int) {
|
func (v *Button) GetPosition() (x, y int) {
|
||||||
return v.x, v.y
|
return v.x, v.y
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetVisible returns the visibility of the button
|
// GetVisible returns the visibility of the button
|
||||||
func (v Button) GetVisible() bool {
|
func (v *Button) GetVisible() bool {
|
||||||
return v.visible
|
return v.visible
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,7 +240,7 @@ func (v *Button) SetVisible(visible bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetPressed returns the pressed state of the button
|
// GetPressed returns the pressed state of the button
|
||||||
func (v Button) GetPressed() bool {
|
func (v *Button) GetPressed() bool {
|
||||||
return v.pressed
|
return v.pressed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ func CreateCheckbox(checkState bool) Checkbox {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v Checkbox) Render(target *d2surface.Surface) {
|
func (v *Checkbox) Render(target *d2surface.Surface) {
|
||||||
target.PushCompositeMode(ebiten.CompositeModeSourceAtop)
|
target.PushCompositeMode(ebiten.CompositeModeSourceAtop)
|
||||||
target.PushTranslation(v.x, v.y)
|
target.PushTranslation(v.x, v.y)
|
||||||
target.PushFilter(ebiten.FilterNearest)
|
target.PushFilter(ebiten.FilterNearest)
|
||||||
@ -52,7 +52,12 @@ func (v Checkbox) Render(target *d2surface.Surface) {
|
|||||||
target.Render(v.Image)
|
target.Render(v.Image)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (v Checkbox) GetEnabled() bool {
|
|
||||||
|
func (v *Checkbox) Advance(elapsed float64) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Checkbox) GetEnabled() bool {
|
||||||
return v.enabled
|
return v.enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,18 +65,18 @@ func (v *Checkbox) SetEnabled(enabled bool) {
|
|||||||
v.enabled = enabled
|
v.enabled = enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v Checkbox) SetPressed(pressed bool) {
|
func (v *Checkbox) SetPressed(pressed bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Checkbox) SetCheckState(checkState bool) {
|
func (v *Checkbox) SetCheckState(checkState bool) {
|
||||||
v.checkState = checkState
|
v.checkState = checkState
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v Checkbox) GetCheckState() bool {
|
func (v *Checkbox) GetCheckState() bool {
|
||||||
return v.checkState
|
return v.checkState
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v Checkbox) GetPressed() bool {
|
func (v *Checkbox) GetPressed() bool {
|
||||||
return v.checkState
|
return v.checkState
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,15 +92,15 @@ func (v *Checkbox) Activate() {
|
|||||||
v.onClick()
|
v.onClick()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v Checkbox) GetPosition() (int, int) {
|
func (v *Checkbox) GetPosition() (int, int) {
|
||||||
return v.x, v.y
|
return v.x, v.y
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v Checkbox) GetSize() (int, int) {
|
func (v *Checkbox) GetSize() (int, int) {
|
||||||
return v.width, v.height
|
return v.width, v.height
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v Checkbox) GetVisible() bool {
|
func (v *Checkbox) GetVisible() bool {
|
||||||
return v.visible
|
return v.visible
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +72,13 @@ func (v *Manager) Render(target *d2surface.Surface) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update updates all of the UI elements
|
// Update updates all of the UI elements
|
||||||
func (v *Manager) Update() {
|
func (v *Manager) Advance(elapsed float64) {
|
||||||
|
for _, widget := range v.widgets {
|
||||||
|
if widget.GetVisible() {
|
||||||
|
widget.Advance(elapsed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
v.cursorButtons = 0
|
v.cursorButtons = 0
|
||||||
if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) {
|
if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) {
|
||||||
if !v.waitForLeftMouseUp {
|
if !v.waitForLeftMouseUp {
|
||||||
|
@ -69,7 +69,7 @@ func (v *Scrollbar) Activate() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v Scrollbar) GetLastDirChange() int {
|
func (v *Scrollbar) GetLastDirChange() int {
|
||||||
return v.lastDirChange
|
return v.lastDirChange
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,6 +96,10 @@ func (v *Scrollbar) Render(target *d2surface.Surface) {
|
|||||||
v.scrollbarSprite.RenderSegmented(target, 1, 1, 4+offset)
|
v.scrollbarSprite.RenderSegmented(target, 1, 1, 4+offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v *Scrollbar) Advance(elapsed float64) {
|
||||||
|
v.scrollbarSprite.Advance(elapsed)
|
||||||
|
}
|
||||||
|
|
||||||
func (v *Scrollbar) GetSize() (width, height int) {
|
func (v *Scrollbar) GetSize() (width, height int) {
|
||||||
return 10, int(v.height)
|
return 10, int(v.height)
|
||||||
}
|
}
|
||||||
@ -134,10 +138,10 @@ func (v *Scrollbar) SetCurrentOffset(currentOffset int) {
|
|||||||
v.currentOffset = currentOffset
|
v.currentOffset = currentOffset
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v Scrollbar) GetMaxOffset() int {
|
func (v *Scrollbar) GetMaxOffset() int {
|
||||||
return v.maxOffset
|
return v.maxOffset
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v Scrollbar) GetCurrentOffset() int {
|
func (v *Scrollbar) GetCurrentOffset() int {
|
||||||
return v.currentOffset
|
return v.currentOffset
|
||||||
}
|
}
|
@ -52,7 +52,7 @@ func repeatingKeyPressed(key ebiten.Key) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v TextBox) Render(target *d2surface.Surface) {
|
func (v *TextBox) Render(target *d2surface.Surface) {
|
||||||
if !v.visible {
|
if !v.visible {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -63,6 +63,10 @@ func (v TextBox) Render(target *d2surface.Surface) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v *TextBox) Advance(elapsed float64) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func (v *TextBox) Update() {
|
func (v *TextBox) Update() {
|
||||||
if !v.visible || !v.enabled {
|
if !v.visible || !v.enabled {
|
||||||
return
|
return
|
||||||
@ -80,7 +84,7 @@ func (v *TextBox) Update() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v TextBox) GetText() string {
|
func (v *TextBox) GetText() string {
|
||||||
return v.text
|
return v.text
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,7 +112,7 @@ func (v *TextBox) SetText(newText string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v TextBox) GetSize() (width, height int) {
|
func (v *TextBox) GetSize() (width, height int) {
|
||||||
return v.bgSprite.GetCurrentFrameSize()
|
return v.bgSprite.GetCurrentFrameSize()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,11 +124,11 @@ func (v *TextBox) SetPosition(x, y int) {
|
|||||||
v.bgSprite.SetPosition(v.x, v.y+26)
|
v.bgSprite.SetPosition(v.x, v.y+26)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v TextBox) GetPosition() (x, y int) {
|
func (v *TextBox) GetPosition() (x, y int) {
|
||||||
return v.x, v.y
|
return v.x, v.y
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v TextBox) GetVisible() bool {
|
func (v *TextBox) GetVisible() bool {
|
||||||
return v.visible
|
return v.visible
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,7 +136,7 @@ func (v *TextBox) SetVisible(visible bool) {
|
|||||||
v.visible = visible
|
v.visible = visible
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v TextBox) GetEnabled() bool {
|
func (v *TextBox) GetEnabled() bool {
|
||||||
return v.enabled
|
return v.enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,7 +148,7 @@ func (v *TextBox) SetPressed(pressed bool) {
|
|||||||
// no op
|
// no op
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v TextBox) GetPressed() bool {
|
func (v *TextBox) GetPressed() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,6 +156,6 @@ func (v *TextBox) OnActivated(callback func()) {
|
|||||||
// no op
|
// no op
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v TextBox) Activate() {
|
func (v *TextBox) Activate() {
|
||||||
//no op
|
//no op
|
||||||
}
|
}
|
||||||
|
@ -9,10 +9,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Sprite struct {
|
type Sprite struct {
|
||||||
x int
|
x int
|
||||||
y int
|
y int
|
||||||
lastFrameTime float64
|
animation *d2asset.Animation
|
||||||
animation *d2asset.Animation
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadSprite(animationPath, palettePath string) (*Sprite, error) {
|
func LoadSprite(animationPath, palettePath string) (*Sprite, error) {
|
||||||
@ -21,7 +20,7 @@ func LoadSprite(animationPath, palettePath string) (*Sprite, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Sprite{lastFrameTime: d2helper.Now(), animation: animation}, nil
|
return &Sprite{animation: animation}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func MustLoadSprite(animationPath, palettePath string) *Sprite {
|
func MustLoadSprite(animationPath, palettePath string) *Sprite {
|
||||||
@ -34,10 +33,6 @@ func MustLoadSprite(animationPath, palettePath string) *Sprite {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Sprite) Render(target *d2surface.Surface) error {
|
func (s *Sprite) Render(target *d2surface.Surface) error {
|
||||||
if err := s.advance(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, frameHeight := s.animation.GetCurrentFrameSize()
|
_, frameHeight := s.animation.GetCurrentFrameSize()
|
||||||
|
|
||||||
target.PushTranslation(s.x, s.y-frameHeight)
|
target.PushTranslation(s.x, s.y-frameHeight)
|
||||||
@ -46,10 +41,6 @@ func (s *Sprite) Render(target *d2surface.Surface) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Sprite) RenderSegmented(target *d2surface.Surface, segmentsX, segmentsY, frameOffset int) error {
|
func (s *Sprite) RenderSegmented(target *d2surface.Surface, segmentsX, segmentsY, frameOffset int) error {
|
||||||
if err := s.advance(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var currentY int
|
var currentY int
|
||||||
for y := 0; y < segmentsY; y++ {
|
for y := 0; y < segmentsY; y++ {
|
||||||
var currentX int
|
var currentX int
|
||||||
@ -127,22 +118,18 @@ func (s *Sprite) GetDirection() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Sprite) SetCurrentFrame(frameIndex int) error {
|
func (s *Sprite) SetCurrentFrame(frameIndex int) error {
|
||||||
s.lastFrameTime = d2helper.Now()
|
|
||||||
return s.animation.SetCurrentFrame(frameIndex)
|
return s.animation.SetCurrentFrame(frameIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Sprite) Rewind() {
|
func (s *Sprite) Rewind() {
|
||||||
s.lastFrameTime = d2helper.Now()
|
|
||||||
s.animation.SetCurrentFrame(0)
|
s.animation.SetCurrentFrame(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Sprite) PlayForward() {
|
func (s *Sprite) PlayForward() {
|
||||||
s.lastFrameTime = d2helper.Now()
|
|
||||||
s.animation.PlayForward()
|
s.animation.PlayForward()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Sprite) PlayBackward() {
|
func (s *Sprite) PlayBackward() {
|
||||||
s.lastFrameTime = d2helper.Now()
|
|
||||||
s.animation.PlayBackward()
|
s.animation.PlayBackward()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,11 +157,6 @@ func (s *Sprite) SetBlend(blend bool) {
|
|||||||
s.animation.SetBlend(blend)
|
s.animation.SetBlend(blend)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Sprite) advance() error {
|
func (s *Sprite) Advance(elapsed float64) error {
|
||||||
lastFrameTime := d2helper.Now()
|
return s.animation.Advance(elapsed)
|
||||||
if err := s.animation.Advance(lastFrameTime - s.lastFrameTime); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
s.lastFrameTime = lastFrameTime
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
4
main.go
4
main.go
@ -67,10 +67,10 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func update(screen *ebiten.Image) error {
|
func update(screen *ebiten.Image) error {
|
||||||
d2Engine.Update()
|
d2Engine.Advance()
|
||||||
if !ebiten.IsDrawingSkipped() {
|
if !ebiten.IsDrawingSkipped() {
|
||||||
surface := d2surface.CreateSurface(screen)
|
surface := d2surface.CreateSurface(screen)
|
||||||
d2Engine.Draw(surface)
|
d2Engine.Render(surface)
|
||||||
if surface.GetDepth() > 0 {
|
if surface.GetDepth() > 0 {
|
||||||
panic("detected surface stack leak")
|
panic("detected surface stack leak")
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user