1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2025-02-03 23:26:41 -05:00

updating to use new BaseSystem.InjectComponent method

This commit is contained in:
gravestench 2020-12-01 22:24:31 -08:00
parent 7a8b07d1c1
commit 7c02b7051f
25 changed files with 701 additions and 289 deletions

View File

@ -0,0 +1,44 @@
//nolint:dupl,golint,stylecheck // component declarations are supposed to look the same
package d2components
import (
"image/color"
"github.com/gravestench/akara"
)
// static check that Color implements Component
var _ akara.Component = &Color{}
// Color is a flag component that is used to denote a "dirty" state
type Color struct {
color.Color
}
// New creates a new Color. By default, IsColor is false.
func (*Color) New() akara.Component {
return &Color{
color.Transparent,
}
}
// ColorFactory is a wrapper for the generic component factory that returns Color component instances.
// This can be embedded inside of a system to give them the methods for adding, retrieving, and removing a Color.
type ColorFactory struct {
Color *akara.ComponentFactory
}
// AddColor adds a Color component to the given entity and returns it
func (m *ColorFactory) AddColor(id akara.EID) *Color {
return m.Color.Add(id).(*Color)
}
// GetColor returns the Color component for the given entity, and a bool for whether or not it exists
func (m *ColorFactory) GetColor(id akara.EID) (*Color, bool) {
component, found := m.Color.Get(id)
if !found {
return nil, found
}
return component.(*Color), found
}

View File

@ -94,17 +94,11 @@ func (m *AppBootstrapSystem) setupSubscriptions() {
func (m *AppBootstrapSystem) setupFactories() {
m.Info("setting up component factories")
gameConfigID := m.RegisterComponent(&d2components.GameConfig{})
filePathID := m.RegisterComponent(&d2components.FilePath{})
fileTypeID := m.RegisterComponent(&d2components.FileType{})
fileHandleID := m.RegisterComponent(&d2components.FileHandle{})
fileSourceID := m.RegisterComponent(&d2components.FileSource{})
m.GameConfig = m.GetComponentFactory(gameConfigID)
m.FilePath = m.GetComponentFactory(filePathID)
m.FileType = m.GetComponentFactory(fileTypeID)
m.FileHandle = m.GetComponentFactory(fileHandleID)
m.FileSource = m.GetComponentFactory(fileSourceID)
m.InjectComponent(&d2components.GameConfig{}, &m.GameConfig)
m.InjectComponent(&d2components.FilePath{}, &m.FilePath)
m.InjectComponent(&d2components.FileType{}, &m.FileType)
m.InjectComponent(&d2components.FileHandle{}, &m.FileHandle)
m.InjectComponent(&d2components.FileSource{}, &m.FileSource)
}
func (m *AppBootstrapSystem) injectSystems() {

View File

@ -115,39 +115,22 @@ func (m *AssetLoaderSystem) setupSubscriptions() {
func (m *AssetLoaderSystem) setupFactories() {
m.Info("setting up component factories")
filePathID := m.RegisterComponent(&d2components.FilePath{})
fileTypeID := m.RegisterComponent(&d2components.FileType{})
fileHandleID := m.RegisterComponent(&d2components.FileHandle{})
fileSourceID := m.RegisterComponent(&d2components.FileSource{})
stringTableID := m.RegisterComponent(&d2components.StringTable{})
fontTableID := m.RegisterComponent(&d2components.FontTable{})
dataDictionaryID := m.RegisterComponent(&d2components.DataDictionary{})
paletteID := m.RegisterComponent(&d2components.Palette{})
paletteTransformID := m.RegisterComponent(&d2components.PaletteTransform{})
cofID := m.RegisterComponent(&d2components.Cof{})
dc6ID := m.RegisterComponent(&d2components.Dc6{})
dccID := m.RegisterComponent(&d2components.Dcc{})
ds1ID := m.RegisterComponent(&d2components.Ds1{})
dt1ID := m.RegisterComponent(&d2components.Dt1{})
wavID := m.RegisterComponent(&d2components.Wav{})
animationDataID := m.RegisterComponent(&d2components.AnimationData{})
m.FilePath = m.GetComponentFactory(filePathID)
m.FileType = m.GetComponentFactory(fileTypeID)
m.FileHandle = m.GetComponentFactory(fileHandleID)
m.FileSource = m.GetComponentFactory(fileSourceID)
m.StringTable = m.GetComponentFactory(stringTableID)
m.DataDictionary = m.GetComponentFactory(dataDictionaryID)
m.Palette = m.GetComponentFactory(paletteID)
m.PaletteTransform = m.GetComponentFactory(paletteTransformID)
m.FontTable = m.GetComponentFactory(fontTableID)
m.Cof = m.GetComponentFactory(cofID)
m.Dc6 = m.GetComponentFactory(dc6ID)
m.Dcc = m.GetComponentFactory(dccID)
m.Ds1 = m.GetComponentFactory(ds1ID)
m.Dt1 = m.GetComponentFactory(dt1ID)
m.Wav = m.GetComponentFactory(wavID)
m.AnimationData = m.GetComponentFactory(animationDataID)
m.InjectComponent(&d2components.FilePath{}, &m.FilePath)
m.InjectComponent(&d2components.FileType{}, &m.FileType)
m.InjectComponent(&d2components.FileHandle{}, &m.FileHandle)
m.InjectComponent(&d2components.FileSource{}, &m.FileSource)
m.InjectComponent(&d2components.StringTable{}, &m.StringTable)
m.InjectComponent(&d2components.FontTable{}, &m.FontTable)
m.InjectComponent(&d2components.DataDictionary{}, &m.DataDictionary)
m.InjectComponent(&d2components.Palette{}, &m.Palette)
m.InjectComponent(&d2components.PaletteTransform{}, &m.PaletteTransform)
m.InjectComponent(&d2components.Cof{}, &m.Cof)
m.InjectComponent(&d2components.Dc6{}, &m.Dc6)
m.InjectComponent(&d2components.Dcc{}, &m.Dcc)
m.InjectComponent(&d2components.Ds1{}, &m.Ds1)
m.InjectComponent(&d2components.Dt1{}, &m.Dt1)
m.InjectComponent(&d2components.Wav{}, &m.Wav)
m.InjectComponent(&d2components.AnimationData{}, &m.AnimationData)
}
// Update processes all of the Entities in the subscription of file entities that need to be processed

View File

@ -1,2 +1,2 @@
// Package d2systems provides all of the ECS systems
// Package d2systems provides all of the ECS baseSystems
package d2systems

View File

@ -95,15 +95,10 @@ func (m *FileHandleResolver) setupSubscriptions() {
func (m *FileHandleResolver) setupFactories() {
m.Info("setting up component factories")
filePathID := m.RegisterComponent(&d2components.FilePath{})
fileTypeID := m.RegisterComponent(&d2components.FileType{})
fileHandleID := m.RegisterComponent(&d2components.FileHandle{})
fileSourceID := m.RegisterComponent(&d2components.FileSource{})
m.FilePath = m.GetComponentFactory(filePathID)
m.FileType = m.GetComponentFactory(fileTypeID)
m.FileHandle = m.GetComponentFactory(fileHandleID)
m.FileSource = m.GetComponentFactory(fileSourceID)
m.InjectComponent(&d2components.FilePath{}, &m.FilePath)
m.InjectComponent(&d2components.FileType{}, &m.FileType)
m.InjectComponent(&d2components.FileHandle{}, &m.FileHandle)
m.InjectComponent(&d2components.FileSource{}, &m.FileSource)
}
// Update iterates over entities which have not had a file handle resolved.

View File

@ -70,13 +70,9 @@ func (m *FileSourceResolver) setupSubscriptions() {
func (m *FileSourceResolver) setupFactories() {
m.Info("setting up component factories")
filePathID := m.RegisterComponent(&d2components.FilePath{})
fileTypeID := m.RegisterComponent(&d2components.FileType{})
fileSourceID := m.RegisterComponent(&d2components.FileSource{})
m.FilePath = m.GetComponentFactory(filePathID)
m.FileType = m.GetComponentFactory(fileTypeID)
m.FileSource = m.GetComponentFactory(fileSourceID)
m.InjectComponent(&d2components.FilePath{}, &m.FilePath)
m.InjectComponent(&d2components.FileType{}, &m.FileType)
m.InjectComponent(&d2components.FileSource{}, &m.FileSource)
}
// Update iterates over entities from its subscription, and checks if it can be used as a file source

View File

@ -52,11 +52,8 @@ func (m *FileTypeResolver) setupLogger() {
}
func (m *FileTypeResolver) setupFactories() {
filePathID := m.RegisterComponent(&d2components.FilePath{})
fileTypeID := m.RegisterComponent(&d2components.FileType{})
m.FilePath = m.GetComponentFactory(filePathID)
m.FileType = m.GetComponentFactory(fileTypeID)
m.InjectComponent(&d2components.FilePath{}, &m.FilePath)
m.InjectComponent(&d2components.FileType{}, &m.FileType)
}
func (m *FileTypeResolver) setupSubscriptions() {

View File

@ -14,13 +14,13 @@ const (
var _ akara.System = &GameClientBootstrapSystem{}
// GameClientBootstrapSystem is responsible for setting up other
// systems that are common to both the game client and the headless game server
// baseSystems that are common to both the game client and the headless game server
type GameClientBootstrapSystem struct {
akara.BaseSubscriberSystem
*d2util.Logger
}
// Init injects the common systems required by both the game client and headless server
// Init injects the common baseSystems required by both the game client and headless server
func (m *GameClientBootstrapSystem) Init(world *akara.World) {
m.World = world

View File

@ -24,9 +24,9 @@ const (
// to be found in, and it also adds an entity for the initial config file to be loaded.
//
// This system is dependant on the FileTypeResolver, FileSourceResolver, and
// FileHandleResolver systems because this system subscribes to entities
// with components created by these other systems. Nothing will break if these
// other systems are not present in the world, but no config files will be loaded by
// FileHandleResolver baseSystems because this system subscribes to entities
// with components created by these other baseSystems. Nothing will break if these
// other baseSystems are not present in the world, but no config files will be loaded by
// this system either...
type GameConfigSystem struct {
akara.BaseSubscriberSystem
@ -62,19 +62,12 @@ func (m *GameConfigSystem) setupLogger() {
func (m *GameConfigSystem) setupFactories() {
m.Info("setting up component factories")
filePathID := m.RegisterComponent(&d2components.FilePath{})
fileTypeID := m.RegisterComponent(&d2components.FileType{})
fileHandleID := m.RegisterComponent(&d2components.FileHandle{})
fileSourceID := m.RegisterComponent(&d2components.FileSource{})
gameConfigID := m.RegisterComponent(&d2components.GameConfig{})
dirtyID := m.RegisterComponent(&d2components.Dirty{})
m.FilePath = m.GetComponentFactory(filePathID)
m.FileType = m.GetComponentFactory(fileTypeID)
m.FileHandle = m.GetComponentFactory(fileHandleID)
m.FileSource = m.GetComponentFactory(fileSourceID)
m.GameConfig = m.GetComponentFactory(gameConfigID)
m.Dirty = m.GetComponentFactory(dirtyID)
m.InjectComponent(&d2components.FilePath{}, &m.FilePath)
m.InjectComponent(&d2components.FileType{}, &m.FileType)
m.InjectComponent(&d2components.FileHandle{}, &m.FileHandle)
m.InjectComponent(&d2components.FileSource{}, &m.FileSource)
m.InjectComponent(&d2components.GameConfig{}, &m.GameConfig)
m.InjectComponent(&d2components.Dirty{}, &m.Dirty)
}
func (m *GameConfigSystem) setupSubscriptions() {

View File

@ -26,7 +26,7 @@ func Test_GameConfigSystem_Bootstrap(t *testing.T) {
cfgSys.AddFilePath(world.NewEntity()).Path = testDataPath
cfgSys.AddFilePath(world.NewEntity()).Path = "config.json"
// at this point the world has initialized the systems. when the world
// at this point the world has initialized the baseSystems. when the world
// updates it should process the config dir to a source and then
// use the source to resolve a file handle, and finally the config file
// will get loaded by the config system.

View File

@ -13,12 +13,13 @@ const (
// static check that GameObjectFactory implements the System interface
var _ akara.System = &GameObjectFactory{}
// GameObjectFactory is a wrapper system for subordinate systems that
// GameObjectFactory is a wrapper system for subordinate baseSystems that
// do the actual object creation work.
type GameObjectFactory struct {
akara.BaseSystem
*d2util.Logger
*SpriteFactory
*ShapeSystem
}
// Init will initialize the Game Object Factory by injecting all of the factory subsystems into the world
@ -40,9 +41,11 @@ func (t *GameObjectFactory) setupLogger() {
func (t *GameObjectFactory) injectSubSystems() {
t.Info("creating sprite factory")
t.SpriteFactory = NewSpriteFactorySubsystem(t.BaseSystem, t.Logger)
t.ShapeSystem = NewShapeSystem(t.BaseSystem, t.Logger)
}
// Update updates all the sub-systems
// Update updates all the sub-baseSystems
func (t *GameObjectFactory) Update() {
t.SpriteFactory.Update()
t.ShapeSystem.Update()
}

View File

@ -22,7 +22,7 @@ var _ akara.System = &InputSystem{}
type InputSystem struct {
akara.BaseSubscriberSystem
*d2util.Logger
inputService d2interface.InputService
d2interface.InputService
configs *akara.Subscription
interactives *akara.Subscription
d2components.GameConfigFactory
@ -34,7 +34,7 @@ type InputSystem struct {
func (m *InputSystem) Init(world *akara.World) {
m.World = world
m.inputService = ebiten_input.InputService{}
m.InputService = ebiten_input.InputService{}
m.setupLogger()
@ -54,11 +54,8 @@ func (m *InputSystem) setupLogger() {
func (m *InputSystem) setupFactories() {
m.Info("setting up component factories")
gameConfigID := m.RegisterComponent(&d2components.GameConfig{})
interactiveID := m.RegisterComponent(&d2components.Interactive{})
m.GameConfig = m.GetComponentFactory(gameConfigID)
m.Interactive = m.GetComponentFactory(interactiveID)
m.InjectComponent(&d2components.GameConfig{}, &m.GameConfig)
m.InjectComponent(&d2components.Interactive{}, &m.Interactive)
}
func (m *InputSystem) setupSubscriptions() {
@ -121,17 +118,17 @@ func (m *InputSystem) updateInputState() {
}
for _, key := range keysToCheck {
truth := m.inputService.IsKeyPressed(d2enum.Key(key))
truth := m.InputService.IsKeyPressed(d2enum.Key(key))
m.inputState.KeyVector.Set(key, truth)
}
for _, mod := range modifiersToCheck {
truth := m.inputService.IsKeyPressed(d2enum.Key(mod))
truth := m.InputService.IsKeyPressed(d2enum.Key(mod))
m.inputState.ModifierVector.Set(mod, truth)
}
for _, btn := range buttonsToCheck {
truth := m.inputService.IsMouseButtonPressed(d2enum.MouseButton(btn))
truth := m.InputService.IsMouseButtonPressed(d2enum.MouseButton(btn))
m.inputState.MouseButtonVector.Set(btn, truth)
}
}

View File

@ -35,11 +35,8 @@ func (m *MovementSystem) Init(world *akara.World) {
m.Info("initializing ...")
positionID := m.RegisterComponent(&d2components.Position{})
velocityID := m.RegisterComponent(&d2components.Velocity{})
m.Position = m.GetComponentFactory(positionID)
m.Velocity = m.GetComponentFactory(velocityID)
m.InjectComponent(&d2components.Position{}, &m.Position)
m.InjectComponent(&d2components.Velocity{}, &m.Velocity)
movable := m.NewComponentFilter().Require(
&d2components.Position{},

View File

@ -51,8 +51,8 @@ func TestMovementSystem_EntityAdded(t *testing.T) {
px, py := 10., 10.
vx, vy := 1., 0.
position.Set(px, py)
velocity.Set(vx, vy)
position.X, position.Y = px, py
velocity.X, velocity.Y = vx, vy
if len(moveSys.movableEntities.GetEntities()) != 1 {
t.Error("entity not added to the system")
@ -60,16 +60,16 @@ func TestMovementSystem_EntityAdded(t *testing.T) {
if p, found := moveSys.GetPosition(e); !found {
t.Error("position component not found")
} else if p.X() != px || p.Y() != py {
} else if p.X != px || p.Y != py {
fmtError := "position component values incorrect:\n\t expected %v, %v but got %v, %v"
t.Errorf(fmtError, px, py, p.X(), p.Y())
t.Errorf(fmtError, px, py, p.X, p.Y)
}
if v, found := moveSys.GetVelocity(e); !found {
t.Error("position component not found")
} else if v.X() != vx || v.Y() != vy {
} else if v.X != vx || v.Y != vy {
fmtError := "velocity component values incorrect:\n\t expected %v, %v but got %v, %v"
t.Errorf(fmtError, px, py, v.X(), v.Y())
t.Errorf(fmtError, px, py, v.X, v.Y)
}
}
@ -91,15 +91,15 @@ func TestMovementSystem_Update(t *testing.T) {
vx, vy := 1., -1.
// mutate the components a bit
position.Set(px, py)
velocity.Set(vx, vy)
position.X, position.Y = px, py
velocity.X, velocity.Y = vx, vy
// should apply the velocity to the position
_ = world.Update(time.Second)
if position.X() != px+vx || position.Y() != py+vy {
if position.X != px+vx || position.Y != py+vy {
fmtError := "expected position (%v, %v) but got (%v, %v)"
t.Errorf(fmtError, px+vx, py+vy, position.X(), position.Y())
t.Errorf(fmtError, px+vx, py+vy, position.X, position.Y)
}
}
@ -117,8 +117,8 @@ func benchN(n int, b *testing.B) {
p := movementSystem.AddPosition(e)
v := movementSystem.AddVelocity(e)
p.Set(0, 0)
v.Set(rand.Float64(), rand.Float64()) //nolint:gosec // it's just a test
p.X, p.Y = 0, 0
v.X, v.Y = rand.Float64(), rand.Float64() //nolint:gosec // it's just a test
}
benchName := strconv.Itoa(n) + "_entity update"

View File

@ -63,19 +63,12 @@ func (m *RenderSystem) setupLogger() {
}
func (m *RenderSystem) setupFactories() {
gameConfigID := m.RegisterComponent(&d2components.GameConfig{})
viewportID := m.RegisterComponent(&d2components.Viewport{})
mainViewportID := m.RegisterComponent(&d2components.MainViewport{})
renderableID := m.RegisterComponent(&d2components.Texture{})
priorityID := m.RegisterComponent(&d2components.Priority{})
alphaID := m.RegisterComponent(&d2components.Alpha{})
m.GameConfig = m.GetComponentFactory(gameConfigID)
m.Viewport = m.GetComponentFactory(viewportID)
m.MainViewport = m.GetComponentFactory(mainViewportID)
m.Texture = m.GetComponentFactory(renderableID)
m.Priority = m.GetComponentFactory(priorityID)
m.Alpha = m.GetComponentFactory(alphaID)
m.InjectComponent(&d2components.GameConfig{}, &m.GameConfig)
m.InjectComponent(&d2components.Viewport{}, &m.Viewport)
m.InjectComponent(&d2components.MainViewport{}, &m.MainViewport)
m.InjectComponent(&d2components.Texture{}, &m.Texture)
m.InjectComponent(&d2components.Priority{}, &m.Priority)
m.InjectComponent(&d2components.Alpha{}, &m.Alpha)
}
func (m *RenderSystem) setupSubscriptions() {
@ -98,7 +91,7 @@ func (m *RenderSystem) setupSubscriptions() {
// Update will initialize the renderer, start the game loop, and
// disable the system (to prevent it from being called during the game loop).
//
// The reason why this isn't in the init step is because we use other systems
// The reason why this isn't in the init step is because we use other baseSystems
// for loading the config file, and it may take more than one iteration
func (m *RenderSystem) Update() {
if m.renderer != nil {

View File

@ -4,6 +4,8 @@ import (
"fmt"
"image/color"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2geom/rectangle"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2scene"
"github.com/gravestench/akara"
@ -27,7 +29,7 @@ func NewBaseScene(key string) *BaseScene {
key: key,
Viewports: make([]akara.EID, 0),
GameObjects: make([]akara.EID, 0),
systems: &baseSystems{},
baseSystems: &baseSystems{},
backgroundColor: color.Transparent,
}
@ -44,18 +46,21 @@ type baseSystems struct {
*GameObjectFactory
}
// BaseScene encapsulates common behaviors for systems that are considered "scenes",
// BaseScene encapsulates common behaviors for baseSystems that are considered "scenes",
// such as the main menu, the in-game map, the console, etc.
//
// The base scene is responsible for generic behaviors common to all scenes,
// like initializing the default viewport, or rendering game objects to the viewports.
type BaseScene struct {
*akara.BaseSystem
*baseSystems
Geom struct {
Rectangle rectangle.Namespace
}
*d2util.Logger
key string
booted bool
paused bool
systems *baseSystems
Add *sceneObjectFactory
Viewports []akara.EID
GameObjects []akara.EID
@ -75,6 +80,8 @@ type BaseScene struct {
d2components.OriginFactory
d2components.AlphaFactory
d2components.DrawEffectFactory
d2components.RectangleFactory
d2components.ColorFactory
}
// Booted returns whether or not the scene has booted
@ -100,8 +107,6 @@ func (s *BaseScene) Init(world *akara.World) {
func (s *BaseScene) boot() {
s.Info("base scene booting ...")
s.setupFactories()
s.Add = &sceneObjectFactory{
BaseScene: s,
Logger: d2util.NewLogger(),
@ -110,45 +115,52 @@ func (s *BaseScene) boot() {
s.Add.SetPrefix(fmt.Sprintf("%s -> %s", s.key, "Object Factory"))
for idx := range s.Systems {
if rendersys, ok := s.Systems[idx].(*RenderSystem); ok && s.systems.RenderSystem == nil {
s.systems.RenderSystem = rendersys
if rendersys, ok := s.Systems[idx].(*RenderSystem); ok && s.baseSystems.RenderSystem == nil {
s.baseSystems.RenderSystem = rendersys
continue
}
if inputSys, ok := s.Systems[idx].(*InputSystem); ok && s.systems.InputSystem == nil {
s.systems.InputSystem = inputSys
if inputSys, ok := s.Systems[idx].(*InputSystem); ok && s.baseSystems.InputSystem == nil {
s.baseSystems.InputSystem = inputSys
continue
}
if objFactory, ok := s.Systems[idx].(*GameObjectFactory); ok && s.systems.GameObjectFactory == nil {
s.systems.GameObjectFactory = objFactory
if objFactory, ok := s.Systems[idx].(*GameObjectFactory); ok && s.baseSystems.GameObjectFactory == nil {
s.baseSystems.GameObjectFactory = objFactory
continue
}
}
if s.systems.RenderSystem == nil {
if s.baseSystems.RenderSystem == nil {
s.Info("waiting for render system ...")
return
}
if s.systems.RenderSystem.renderer == nil {
if s.baseSystems.RenderSystem.renderer == nil {
s.Info("waiting for renderer instance ...")
return
}
if s.systems.InputSystem == nil {
if s.baseSystems.InputSystem == nil {
s.Info("waiting for input system")
return
}
if s.systems.GameObjectFactory == nil {
if s.baseSystems.GameObjectFactory == nil {
s.Info("waiting for game object factory ...")
return
}
s.systems.SpriteFactory.RenderSystem = s.systems.RenderSystem
s.setupFactories()
s.createDefaultViewport()
s.baseSystems.SpriteFactory.RenderSystem = s.baseSystems.RenderSystem
const (
defaultWidth = 800
defaultHeight = 600
)
s.Add.Viewport(mainViewport, defaultWidth, defaultHeight)
s.Info("base scene booted!")
s.booted = true
@ -157,56 +169,22 @@ func (s *BaseScene) boot() {
func (s *BaseScene) setupFactories() {
s.Info("setting up component factories")
mainViewportID := s.RegisterComponent(&d2components.MainViewport{})
viewportID := s.RegisterComponent(&d2components.Viewport{})
viewportFilterID := s.RegisterComponent(&d2components.ViewportFilter{})
cameraID := s.RegisterComponent(&d2components.Camera{})
priorityID := s.RegisterComponent(&d2components.Priority{})
renderableID := s.RegisterComponent(&d2components.Texture{})
interactiveID := s.RegisterComponent(&d2components.Interactive{})
positionID := s.RegisterComponent(&d2components.Position{})
scaleID := s.RegisterComponent(&d2components.Scale{})
animationID := s.RegisterComponent(&d2components.Sprite{})
originID := s.RegisterComponent(&d2components.Origin{})
alphaID := s.RegisterComponent(&d2components.Alpha{})
sceneGraphNodeID := s.RegisterComponent(&d2components.SceneGraphNode{})
drawEffectID := s.RegisterComponent(&d2components.DrawEffect{})
s.MainViewport = s.GetComponentFactory(mainViewportID)
s.Viewport = s.GetComponentFactory(viewportID)
s.ViewportFilter = s.GetComponentFactory(viewportFilterID)
s.Camera = s.GetComponentFactory(cameraID)
s.Priority = s.GetComponentFactory(priorityID)
s.Texture = s.GetComponentFactory(renderableID)
s.Interactive = s.GetComponentFactory(interactiveID)
s.Position = s.GetComponentFactory(positionID)
s.Scale = s.GetComponentFactory(scaleID)
s.Sprite = s.GetComponentFactory(animationID)
s.Origin = s.GetComponentFactory(originID)
s.Alpha = s.GetComponentFactory(alphaID)
s.SceneGraphNode = s.GetComponentFactory(sceneGraphNodeID)
s.DrawEffect = s.GetComponentFactory(drawEffectID)
}
func (s *BaseScene) createDefaultViewport() {
s.Info("creating default viewport")
viewportID := s.NewEntity()
s.AddViewport(viewportID)
s.AddPriority(viewportID)
camera := s.AddCamera(viewportID)
width, height := camera.Size.XY()
s.AddSceneGraphNode(viewportID).SetParent(s.Graph)
sfc := s.systems.RenderSystem.renderer.NewSurface(int(width), int(height))
sfc.Clear(color.Transparent)
s.AddTexture(viewportID).Texture = sfc
s.AddMainViewport(viewportID)
s.Viewports = append(s.Viewports, viewportID)
s.InjectComponent(&d2components.MainViewport{}, &s.MainViewport)
s.InjectComponent(&d2components.Viewport{}, &s.Viewport)
s.InjectComponent(&d2components.ViewportFilter{}, &s.ViewportFilter)
s.InjectComponent(&d2components.Camera{}, &s.Camera)
s.InjectComponent(&d2components.Priority{}, &s.Priority)
s.InjectComponent(&d2components.Texture{}, &s.Texture)
s.InjectComponent(&d2components.Interactive{}, &s.Interactive)
s.InjectComponent(&d2components.Position{}, &s.Position)
s.InjectComponent(&d2components.Scale{}, &s.Scale)
s.InjectComponent(&d2components.Origin{}, &s.Origin)
s.InjectComponent(&d2components.Alpha{}, &s.Alpha)
s.InjectComponent(&d2components.SceneGraphNode{}, &s.SceneGraphNode)
s.InjectComponent(&d2components.DrawEffect{}, &s.DrawEffect)
s.InjectComponent(&d2components.Sprite{}, &s.SpriteFactory.Sprite)
s.InjectComponent(&d2components.Rectangle{}, &s.RectangleFactory.Rectangle)
s.InjectComponent(&d2components.Color{}, &s.Color)
}
// Key returns the scene's key
@ -229,12 +207,12 @@ func (s *BaseScene) Update() {
}
func (s *BaseScene) renderViewports() {
if s.systems.RenderSystem == nil {
if s.baseSystems.RenderSystem == nil {
s.Warning("render system not present")
return
}
if s.systems.RenderSystem.renderer == nil {
if s.baseSystems.RenderSystem.renderer == nil {
s.Warning("render system doesn't have a renderer instance")
return
}
@ -242,7 +220,8 @@ func (s *BaseScene) renderViewports() {
numViewports := len(s.Viewports)
if numViewports < 1 {
s.createDefaultViewport()
s.Warning("scene does not have a main viewport")
return
}
viewportObjects := s.binGameObjectsByViewport()
@ -307,7 +286,7 @@ func (s *BaseScene) renderViewport(idx int, objects []akara.EID) {
}
if sfc.Texture == nil {
sfc.Texture = s.systems.RenderSystem.renderer.NewSurface(int(cw), int(ch))
sfc.Texture = s.baseSystems.RenderSystem.renderer.NewSurface(int(cw), int(ch))
}
if idx == mainViewport {
@ -378,41 +357,44 @@ func (s *BaseScene) renderObject(target d2interface.Surface, id akara.EID) {
target.PushColor(color.Alpha{A: uint8(alpha.Alpha * maxAlpha)})
defer target.Pop()
segment, found := s.systems.SpriteFactory.GetSegmentedSprite(id)
segment, found := s.baseSystems.SpriteFactory.GetSegmentedSprite(id)
if found {
animation, found := s.GetSprite(id)
if !found {
return
}
var offsetY int
segmentsX, segmentsY := segment.Xsegments, segment.Ysegments
frameOffset := segment.FrameOffset
for y := 0; y < segmentsY; y++ {
var offsetX, maxFrameHeight int
for x := 0; x < segmentsX; x++ {
idx := x + y*segmentsX + frameOffset*segmentsX*segmentsY
if err := animation.SetCurrentFrame(idx); err != nil {
s.Error("SetCurrentFrame error" + err.Error())
}
target.PushTranslation(x+offsetX, y+offsetY)
target.Render(animation.GetCurrentFrameSurface())
target.Pop()
frameWidth, frameHeight := animation.GetCurrentFrameSize()
maxFrameHeight = d2math.MaxInt(maxFrameHeight, frameHeight)
offsetX += frameWidth - 1
}
offsetY += maxFrameHeight - 1
}
s.renderSegmentedSprite(target, id, segment)
return
}
target.Render(texture.Texture)
}
func (s *BaseScene) renderSegmentedSprite(target d2interface.Surface, id akara.EID, seg *d2components.SegmentedSprite) {
animation, found := s.GetSprite(id)
if !found {
return
}
var offsetY int
segmentsX, segmentsY := seg.Xsegments, seg.Ysegments
frameOffset := seg.FrameOffset
for y := 0; y < segmentsY; y++ {
var offsetX, maxFrameHeight int
for x := 0; x < segmentsX; x++ {
idx := x + y*segmentsX + frameOffset*segmentsX*segmentsY
if err := animation.SetCurrentFrame(idx); err != nil {
s.Error("SetCurrentFrame error" + err.Error())
}
target.PushTranslation(x+offsetX, y+offsetY)
target.Render(animation.GetCurrentFrameSurface())
target.Pop()
frameWidth, frameHeight := animation.GetCurrentFrameSize()
maxFrameHeight = d2math.MaxInt(maxFrameHeight, frameHeight)
offsetX += frameWidth - 1
}
offsetY += maxFrameHeight - 1
}
}

View File

@ -32,9 +32,14 @@ func NewLoadingScene() *LoadingScene {
type LoadingScene struct {
*BaseScene
loadingSprite akara.EID
filesToLoad *akara.Subscription
d2components.TextureFactory
booted bool
loadStages struct {
stage1 *akara.Subscription // has path, no type
stage2 *akara.Subscription // has type, no handle
stage3 *akara.Subscription // has handle, no asset
stage4 *akara.Subscription // is loaded
}
progress float64
booted bool
}
// Init the loading scene
@ -45,20 +50,62 @@ func (s *LoadingScene) Init(world *akara.World) {
s.backgroundColor = color.Black
s.setupFactories()
s.setupSubscriptions()
}
func (s *LoadingScene) setupFactories() {
renderableID := s.RegisterComponent(&d2components.Texture{})
s.Texture = s.GetComponentFactory(renderableID)
}
func (s *LoadingScene) setupSubscriptions() {
s.Info("setting up component subscriptions")
filesToLoad := s.NewComponentFilter().
stage1 := s.NewComponentFilter().
Require(
&d2components.FilePath{},
).
Forbid( // but we forbid files that are already loaded
&d2components.FileType{},
&d2components.FileHandle{},
&d2components.FileSource{},
&d2components.GameConfig{},
&d2components.StringTable{},
&d2components.DataDictionary{},
&d2components.Palette{},
&d2components.PaletteTransform{},
&d2components.Cof{},
&d2components.Dc6{},
&d2components.Dcc{},
&d2components.Ds1{},
&d2components.Dt1{},
&d2components.Wav{},
&d2components.AnimationData{},
).
Build()
stage2 := s.NewComponentFilter().
Require(
&d2components.FilePath{},
&d2components.FileType{},
).
Forbid( // but we forbid files that are already loaded
&d2components.FileHandle{},
&d2components.FileSource{},
&d2components.GameConfig{},
&d2components.StringTable{},
&d2components.DataDictionary{},
&d2components.Palette{},
&d2components.PaletteTransform{},
&d2components.Cof{},
&d2components.Dc6{},
&d2components.Dcc{},
&d2components.Ds1{},
&d2components.Dt1{},
&d2components.Wav{},
&d2components.AnimationData{},
).
Build()
stage3 := s.NewComponentFilter().
Require(
&d2components.FilePath{},
&d2components.FileType{},
&d2components.FileHandle{},
).
Forbid( // but we forbid files that are already loaded
@ -78,7 +125,30 @@ func (s *LoadingScene) setupSubscriptions() {
).
Build()
s.filesToLoad = s.World.AddSubscription(filesToLoad)
// we want to know about loaded files, too
stage4 := s.NewComponentFilter().
RequireOne(
&d2components.FileHandle{},
&d2components.FileSource{},
&d2components.GameConfig{},
&d2components.StringTable{},
&d2components.DataDictionary{},
&d2components.Palette{},
&d2components.PaletteTransform{},
&d2components.Cof{},
&d2components.Dc6{},
&d2components.Dcc{},
&d2components.Ds1{},
&d2components.Dt1{},
&d2components.Wav{},
&d2components.AnimationData{},
).
Build()
s.loadStages.stage1 = s.World.AddSubscription(stage1) // has path, no type
s.loadStages.stage2 = s.World.AddSubscription(stage2) // has type, no handle
s.loadStages.stage3 = s.World.AddSubscription(stage3) // has handle, no asset
s.loadStages.stage4 = s.World.AddSubscription(stage4) // is loaded
}
func (s *LoadingScene) boot() {
@ -111,6 +181,7 @@ func (s *LoadingScene) Update() {
s.boot()
}
s.updateLoadProgress()
s.updateViewportAlpha()
s.updateLoadingSpritePosition()
s.updateLoadingSpriteFrame()
@ -118,6 +189,16 @@ func (s *LoadingScene) Update() {
s.BaseScene.Update()
}
func (s *LoadingScene) updateLoadProgress() {
untyped := float64(len(s.loadStages.stage1.GetEntities()))
unhandled := float64(len(s.loadStages.stage2.GetEntities()))
unparsed := float64(len(s.loadStages.stage3.GetEntities()))
loaded := float64(len(s.loadStages.stage4.GetEntities()))
s.progress = 1 - ((untyped + unhandled + unparsed) / 3 / loaded)
_ = s.progress
}
func (s *LoadingScene) updateViewportAlpha() {
if len(s.Viewports) < 1 {
return
@ -128,12 +209,14 @@ func (s *LoadingScene) updateViewportAlpha() {
return
}
isLoading := len(s.filesToLoad.GetEntities()) > 0
isLoading := len(s.loadStages.stage1.GetEntities()) > 0 ||
len(s.loadStages.stage2.GetEntities()) > 0 ||
len(s.loadStages.stage3.GetEntities()) > 0
if isLoading {
alpha.Alpha = math.Min(alpha.Alpha+0.1, 1)
alpha.Alpha = math.Min(alpha.Alpha+0.125, 1)
} else {
alpha.Alpha = math.Max(alpha.Alpha-0.1, 0)
alpha.Alpha = math.Max(alpha.Alpha-0.125, 0)
}
}
@ -165,9 +248,13 @@ func (s *LoadingScene) updateLoadingSpritePosition() {
}
func (s *LoadingScene) updateLoadingSpriteFrame() {
//sprite, found := s.GetSprite(s.loadingSprite)
//if !found {
// return
//}
sprite, found := s.GetSprite(s.loadingSprite)
if !found {
return
}
numFrames := float64(sprite.GetFrameCount())
if err := sprite.SetCurrentFrame(int(s.progress * (numFrames - 1))); err != nil {
_ = sprite.SetCurrentFrame(0)
}
}

View File

@ -15,6 +15,12 @@ const (
sceneKeyMainMenu = "Main Menu"
)
const (
viewportMainBackground = iota + 1
viewportTrademark
viewport
)
// NewMainMenuScene creates a new main menu scene. This is the first screen that the user
// will see when launching the game.
func NewMainMenuScene() *MainMenuScene {
@ -57,6 +63,7 @@ func (s *MainMenuScene) boot() {
return
}
s.setupViewports()
s.createBackground()
s.createButtons()
s.createTrademarkScreen()
@ -65,6 +72,15 @@ func (s *MainMenuScene) boot() {
s.booted = true
}
func (s *MainMenuScene) setupViewports() {
s.Info("setting up viewports")
imgPath := d2resource.GameSelectScreen
palPath := d2resource.PaletteSky
s.sprites.mainBackground = s.Add.SegmentedSprite(0, 0, imgPath, palPath, 4, 3, 0)
}
func (s *MainMenuScene) createBackground() {
s.Info("creating background")
@ -113,10 +129,16 @@ func (s *MainMenuScene) createTrademarkScreen() {
alpha := s.AddAlpha(s.sprites.trademark)
go func() {
a := 1.0
for a > 0 {
a -= 0.125
alpha.Alpha = a
alpha.Alpha = 1.0
for alpha.Alpha > 0 {
alpha.Alpha *= 0.725
if alpha.Alpha <= 1e-3 {
alpha.Alpha = 0
return
}
time.Sleep(time.Second / 25)
}
@ -187,7 +209,6 @@ func (s *MainMenuScene) initLogoSprites() {
continue
}
sprite.SetEffect(d2enum.DrawEffectModulate)
sprite.PlayForward()
}

View File

@ -1,6 +1,9 @@
package d2systems
import (
"math"
"time"
"github.com/gravestench/akara"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
@ -11,6 +14,11 @@ const (
sceneKeyMouseCursor = "Mouse Cursor"
)
const (
fadeTimeout = time.Second * 4
fadeTime = time.Second
)
// NewMouseCursorScene creates a new main menu scene. This is the first screen that the user
// will see when launching the game.
func NewMouseCursorScene() *MouseCursorScene {
@ -28,8 +36,9 @@ var _ d2interface.Scene = &MouseCursorScene{}
// or start the map engine test.
type MouseCursorScene struct {
*BaseScene
booted bool
cursor akara.EID
booted bool
cursor akara.EID
lastTimeMoved time.Time
}
// Init the main menu scene
@ -70,6 +79,7 @@ func (s *MouseCursorScene) Update() {
}
s.updateCursorPosition()
s.handleCursorFade()
s.BaseScene.Update()
}
@ -80,6 +90,26 @@ func (s *MouseCursorScene) updateCursorPosition() {
return
}
cx, cy := s.systems.InputSystem.inputService.CursorPosition()
cx, cy := s.CursorPosition()
if int(position.X) != cx || int(position.Y) != cy {
s.lastTimeMoved = time.Now()
}
position.X, position.Y = float64(cx), float64(cy)
}
func (s *MouseCursorScene) handleCursorFade() {
alpha, found := s.GetAlpha(s.cursor)
if !found {
return
}
shouldFadeOut := time.Now().Sub(s.lastTimeMoved) > fadeTimeout
if shouldFadeOut {
alpha.Alpha = math.Max(alpha.Alpha*0.825, 0)
} else {
alpha.Alpha = math.Min(alpha.Alpha+0.125, 1)
}
}

View File

@ -1,6 +1,7 @@
package d2systems
import (
"image/color"
"path/filepath"
"github.com/gravestench/akara"
@ -14,7 +15,7 @@ type sceneObjectFactory struct {
*d2util.Logger
}
func (s *sceneObjectFactory) addBasicComponenets(id akara.EID) {
func (s *sceneObjectFactory) addBasicComponents(id akara.EID) {
node := s.AddSceneGraphNode(id)
node.SetParent(s.Graph)
@ -25,10 +26,10 @@ func (s *sceneObjectFactory) addBasicComponenets(id akara.EID) {
func (s *sceneObjectFactory) Sprite(x, y float64, imgPath, palPath string) akara.EID {
s.Infof("creating sprite: %s, %s", filepath.Base(imgPath), palPath)
eid := s.systems.SpriteFactory.Sprite(x, y, imgPath, palPath)
eid := s.baseSystems.SpriteFactory.Sprite(x, y, imgPath, palPath)
s.GameObjects = append(s.GameObjects, eid)
s.addBasicComponenets(eid)
s.addBasicComponents(eid)
return eid
}
@ -36,10 +37,50 @@ func (s *sceneObjectFactory) Sprite(x, y float64, imgPath, palPath string) akara
func (s *sceneObjectFactory) SegmentedSprite(x, y float64, imgPath, palPath string, xseg, yseg, frame int) akara.EID {
s.Infof("creating segmented sprite: %s, %s", filepath.Base(imgPath), palPath)
eid := s.systems.SpriteFactory.SegmentedSprite(x, y, imgPath, palPath, xseg, yseg, frame)
eid := s.baseSystems.SpriteFactory.SegmentedSprite(x, y, imgPath, palPath, xseg, yseg, frame)
s.GameObjects = append(s.GameObjects, eid)
s.addBasicComponenets(eid)
s.addBasicComponents(eid)
return eid
}
func (s *sceneObjectFactory) Viewport(priority, width, height int) akara.EID {
s.Infof("creating viewport #%d", priority)
eid := s.NewEntity()
s.AddViewport(eid)
s.AddPriority(eid).Priority = priority
if priority == mainViewport {
s.AddMainViewport(eid)
}
camera := s.AddCamera(eid)
camera.Size.X = float64(width)
camera.Size.Y = float64(height)
sfc := s.baseSystems.RenderSystem.renderer.NewSurface(width, height)
sfc.Clear(color.Transparent)
s.AddTexture(eid).Texture = sfc
s.Viewports = append(s.Viewports, eid)
s.addBasicComponents(eid)
return eid
}
func (s *sceneObjectFactory) Rectangle(x, y, width, height int, color color.Color) akara.EID {
s.Info("creating rectangle")
eid := s.baseSystems.ShapeSystem.Rectangle(x, y, width, height, color)
s.addBasicComponents(eid)
s.GameObjects = append(s.GameObjects, eid)
return eid
}

View File

@ -0,0 +1,151 @@
package d2systems
import (
"image/color"
"github.com/gravestench/akara"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2components"
)
// NewShapeSystem creates a new sprite factory which is intended
// to be embedded in the game object factory system.
func NewShapeSystem(b akara.BaseSystem, l *d2util.Logger) *ShapeSystem {
sys := &ShapeSystem{
Logger: l,
}
sys.BaseSystem = b
sys.World.AddSystem(sys)
return sys
}
// ShapeSystem is responsible for queueing sprites to be loaded (as spriteations),
// as well as binding the spriteation to a renderer if one is present (which generates the sprite surfaces).
type ShapeSystem struct {
akara.BaseSubscriberSystem
*d2util.Logger
RenderSystem *RenderSystem
d2components.PositionFactory
d2components.ColorFactory
d2components.RectangleFactory
d2components.TextureFactory
d2components.SizeFactory
d2components.OriginFactory
loadQueue spriteLoadQueue
shapesToRender *akara.Subscription
shapesToUpdate *akara.Subscription
}
// Init the sprite factory, injecting the necessary components
func (t *ShapeSystem) Init(world *akara.World) {
t.World = world
t.Info("initializing sprite factory ...")
t.setupFactories()
t.setupSubscriptions()
t.loadQueue = make(spriteLoadQueue)
}
func (t *ShapeSystem) setupFactories() {
t.InjectComponent(&d2components.Color{}, &t.ColorFactory.Color)
t.InjectComponent(&d2components.Position{}, &t.PositionFactory.Position)
t.InjectComponent(&d2components.Texture{}, &t.TextureFactory.Texture)
t.InjectComponent(&d2components.Origin{}, &t.OriginFactory.Origin)
t.InjectComponent(&d2components.Size{}, &t.SizeFactory.Size)
t.InjectComponent(&d2components.Rectangle{}, &t.RectangleFactory.Rectangle)
}
func (t *ShapeSystem) setupSubscriptions() {
shapesToRender := t.NewComponentFilter().
RequireOne(&d2components.Rectangle{}).
Require(&d2components.Texture{}).
Build()
shapesToUpdate := t.NewComponentFilter().
RequireOne(&d2components.Rectangle{}).
Require(&d2components.Position{}, &d2components.Size{}).
Build()
t.shapesToRender = t.AddSubscription(shapesToRender)
t.shapesToUpdate = t.AddSubscription(shapesToUpdate)
}
// Update processes the load queue which attempting to create spriteations, as well as
// binding existing spriteations to a renderer if one is present.
func (t *ShapeSystem) Update() {
for _, id := range t.shapesToUpdate.GetEntities() {
t.updateShape(id)
}
for _, id := range t.shapesToRender.GetEntities() {
t.renderShape(id)
}
}
// Sprite queues a sprite spriteation to be loaded
func (t *ShapeSystem) Rectangle(x, y, width, height int, color color.Color) akara.EID {
t.Info("creating rectangle")
eid := t.NewEntity()
r := t.AddRectangle(eid)
r.X, r.Y = float64(x), float64(y)
r.Width, r.Height = float64(width), float64(height)
c := t.AddColor(eid)
c.Color = color
texture := t.AddTexture(eid)
texture.Texture = t.RenderSystem.renderer.NewSurface(width, height)
texture.Texture.Clear(c.Color)
return eid
}
func (t *ShapeSystem) updateShape(eid akara.EID) {
position, found := t.GetPosition(eid)
if !found {
return
}
size, found := t.GetSize(eid)
if !found {
return
}
texture, found := t.GetTexture(eid)
if !found || texture.Texture == nil {
return
}
rectangle, rectangleFound := t.GetRectangle(eid)
if rectangleFound {
position.X, position.Y = rectangle.X, rectangle.Y
size.X, size.Y = rectangle.Width, rectangle.Height
tw, th := texture.Texture.GetSize()
if tw != int(size.X) || th != int(size.Y) {
texture.Texture.Renderer().NewSurface(int(size.X), int(size.Y))
}
}
}
func (t *ShapeSystem) renderShape(eid akara.EID) {
texture, found := t.GetTexture(eid)
if !found || texture.Texture == nil {
return
}
col, found := t.GetColor(eid)
if !found {
return
}
texture.Texture.Clear(col.Color)
}

View File

@ -66,25 +66,15 @@ func (t *SpriteFactory) Init(world *akara.World) {
}
func (t *SpriteFactory) setupFactories() {
filePathID := t.RegisterComponent(&d2components.FilePath{})
positionID := t.RegisterComponent(&d2components.Position{})
dc6ID := t.RegisterComponent(&d2components.Dc6{})
dccID := t.RegisterComponent(&d2components.Dcc{})
paletteID := t.RegisterComponent(&d2components.Palette{})
spriteID := t.RegisterComponent(&d2components.Sprite{})
textureID := t.RegisterComponent(&d2components.Texture{})
originID := t.RegisterComponent(&d2components.Origin{})
segmentedSpriteID := t.RegisterComponent(&d2components.SegmentedSprite{})
t.FilePath = t.GetComponentFactory(filePathID)
t.Position = t.GetComponentFactory(positionID)
t.Dc6 = t.GetComponentFactory(dc6ID)
t.Dcc = t.GetComponentFactory(dccID)
t.Palette = t.GetComponentFactory(paletteID)
t.Texture = t.GetComponentFactory(textureID)
t.Origin = t.GetComponentFactory(originID)
t.SpriteFactory.Sprite = t.GetComponentFactory(spriteID)
t.SegmentedSpriteFactory.SegmentedSprite = t.GetComponentFactory(segmentedSpriteID)
t.InjectComponent(&d2components.FilePath{}, &t.FilePath)
t.InjectComponent(&d2components.Position{}, &t.Position)
t.InjectComponent(&d2components.Dc6{}, &t.Dc6)
t.InjectComponent(&d2components.Dcc{}, &t.Dcc)
t.InjectComponent(&d2components.Palette{}, &t.Palette)
t.InjectComponent(&d2components.Texture{}, &t.Texture)
t.InjectComponent(&d2components.Origin{}, &t.Origin)
t.InjectComponent(&d2components.Sprite{}, &t.SpriteFactory.Sprite)
t.InjectComponent(&d2components.SegmentedSprite{}, &t.SegmentedSpriteFactory.SegmentedSprite)
}
func (t *SpriteFactory) setupSubscriptions() {

View File

@ -0,0 +1,107 @@
package d2systems
import (
"image/color"
"github.com/gravestench/akara"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2components"
)
const (
sceneKeyTerminal = "Terminal"
)
// static check that TerminalScene implements the scene interface
var _ d2interface.Scene = &TerminalScene{}
// NewTerminalScene creates a new main menu scene. This is the first screen that the user
// will see when launching the game.
func NewTerminalScene() *TerminalScene {
scene := &TerminalScene{
BaseScene: NewBaseScene(sceneKeyTerminal),
}
return scene
}
// TerminalScene represents the game's loading screen, where loading progress is displayed
type TerminalScene struct {
*BaseScene
booted bool
}
// Init the loading scene
func (s *TerminalScene) Init(world *akara.World) {
s.World = world
s.Info("initializing ...")
s.backgroundColor = color.Black
s.setupFactories()
s.setupSubscriptions()
}
func (s *TerminalScene) setupFactories() {
texture := s.RegisterComponent(&d2components.Texture{})
s.Texture = s.GetComponentFactory(texture)
}
func (s *TerminalScene) setupSubscriptions() {
s.Info("setting up component subscriptions")
//stage1 := s.NewComponentFilter().
// Require(
// &d2components.FilePath{},
// ).
// Forbid( // but we forbid files that are already loaded
// &d2components.FileType{},
// &d2components.FileHandle{},
// &d2components.FileSource{},
// &d2components.GameConfig{},
// &d2components.StringTable{},
// &d2components.DataDictionary{},
// &d2components.Palette{},
// &d2components.PaletteTransform{},
// &d2components.Cof{},
// &d2components.Dc6{},
// &d2components.Dcc{},
// &d2components.Ds1{},
// &d2components.Dt1{},
// &d2components.Wav{},
// &d2components.AnimationData{},
// ).
// Build()
//s.loadStages.stage1 = s.World.AddSubscription(stage1)
}
func (s *TerminalScene) boot() {
if !s.BaseScene.booted {
s.BaseScene.boot()
return
}
//s.createTerminalScene()
s.booted = true
}
// Update the loading scene
func (s *TerminalScene) Update() {
for _, id := range s.Viewports {
s.AddPriority(id).Priority = scenePriorityLoading
}
if s.Paused() {
return
}
if !s.booted {
s.boot()
}
s.BaseScene.Update()
}

12
go.mod
View File

@ -5,19 +5,15 @@ go 1.14
require (
github.com/JoshVarga/blast v0.0.0-20180421040937-681c804fb9f0
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20201108214237-06ea97f0c265 // indirect
github.com/alecthomas/units v0.0.0-20201120081800-1786d5ef83d4 // indirect
github.com/go-restruct/restruct v1.2.0-alpha
github.com/google/uuid v1.1.2
github.com/gravestench/akara v0.0.0-20201128054238-892de9d70d6b
github.com/hajimehoshi/ebiten/v2 v2.0.0
github.com/pkg/errors v0.9.1 // indirect
github.com/gravestench/akara v0.0.0-20201202061557-d347a52d5532
github.com/gravestench/pho v0.0.0-20201029002250-f9afbd637e4d
github.com/hajimehoshi/ebiten/v2 v2.0.1
github.com/pkg/profile v1.5.0
github.com/robertkrimen/otto v0.0.0-20200922221731-ef014fd054ac
github.com/stretchr/testify v1.4.0
golang.org/x/exp v0.0.0-20201008143054-e3b2a7f2fdc7 // indirect
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 // indirect
gopkg.in/alecthomas/kingpin.v2 v2.2.6
gopkg.in/sourcemap.v1 v1.0.5 // indirect
)

15
go.sum
View File

@ -6,6 +6,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafo
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/alecthomas/units v0.0.0-20201120081800-1786d5ef83d4 h1:EBTWhcAX7rNQ80RLwLCpHZBBrJuzallFHnF+yMXo928=
github.com/alecthomas/units v0.0.0-20201120081800-1786d5ef83d4/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
@ -21,14 +23,25 @@ github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gravestench/akara v0.0.0-20201128054238-892de9d70d6b h1:Ngfdn7O3wXQBzbOLsL6vQ9G4F7utUiKjQqKnwHbY5uI=
github.com/gravestench/akara v0.0.0-20201128054238-892de9d70d6b/go.mod h1:fTeda1SogMg5Lkd4lXMEd/Pk/a5/gQuLGaAI2rn1PBQ=
github.com/gravestench/akara v0.0.0-20201201101207-7cceed226bf1 h1:lcvisQZBoEH41Ed9dLrBApmF4+CKwXeL8T3+SdGfpvc=
github.com/gravestench/akara v0.0.0-20201201101207-7cceed226bf1/go.mod h1:fTeda1SogMg5Lkd4lXMEd/Pk/a5/gQuLGaAI2rn1PBQ=
github.com/gravestench/akara v0.0.0-20201202061557-d347a52d5532 h1:hGNjc5HCLUTk6kJpM3x6hfDcYxZ0I6LYDrKFR/4vZOQ=
github.com/gravestench/akara v0.0.0-20201202061557-d347a52d5532/go.mod h1:fTeda1SogMg5Lkd4lXMEd/Pk/a5/gQuLGaAI2rn1PBQ=
github.com/gravestench/pho v0.0.0-20201029002250-f9afbd637e4d h1:CP+/y9SAdv9LifYvicxYdQNmzugykEahAiUhYolMROM=
github.com/gravestench/pho v0.0.0-20201029002250-f9afbd637e4d/go.mod h1:yi5GHMLLWtHhs9tz3q1csUlgGKz5MhZoJcxV8NFBtkk=
github.com/hajimehoshi/bitmapfont/v2 v2.1.0/go.mod h1:2BnYrkTQGThpr/CY6LorYtt/zEPNzvE/ND69CRTaHMs=
github.com/hajimehoshi/ebiten v1.12.4 h1:ie1lGp9mwPeIopCMMZ6wY5O45mfXmZOuixGHxsTKSNc=
github.com/hajimehoshi/ebiten/v2 v2.0.0 h1:G8mhkKFtnDPPZ/ChaGWx4Bm0NusYEcafGCJ8QLxEaYs=
github.com/hajimehoshi/ebiten/v2 v2.0.0/go.mod h1:hpZZQ/kk8DZqft7QsQ5hZLRQXHSZPdKnaa0tcJ3CZFE=
github.com/hajimehoshi/ebiten/v2 v2.0.1 h1:94ucoKKoqiJOZxDod8gdMrroCDy0CO6Ct+Nc9kjsW98=
github.com/hajimehoshi/ebiten/v2 v2.0.1/go.mod h1:AbHP/SS226aFTex/izULVwW0D2AuGyqC4AVwilmRjOg=
github.com/hajimehoshi/file2byteslice v0.0.0-20200812174855-0e5e8a80490e/go.mod h1:CqqAHp7Dk/AqQiwuhV1yT2334qbA/tFWQW0MD2dGqUE=
github.com/hajimehoshi/go-mp3 v0.3.1/go.mod h1:qMJj/CSDxx6CGHiZeCgbiq2DSUkbK0UbtXShQcnfyMM=
github.com/hajimehoshi/oto v0.6.1/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2hrh6raOI=
github.com/hajimehoshi/oto v0.6.6 h1:HYSZ8cYZqOL4iHugvbcfhNN2smiSOsBMaoSBi4nnWcw=
github.com/hajimehoshi/oto v0.6.6/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2hrh6raOI=
github.com/hajimehoshi/oto v0.6.8 h1:yRb3EJQ4lAkBgZYheqmdH6Lr77RV9nSWFsK/jwWdTNY=
github.com/hajimehoshi/oto v0.6.8/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2hrh6raOI=
github.com/jakecoffman/cp v1.0.0/go.mod h1:JjY/Fp6d8E1CHnu74gWNnU0+b9VzEdUVPoJxg2PsTQg=
github.com/jfreymuth/oggvorbis v1.0.1/go.mod h1:NqS+K+UXKje0FUYUPosyQ+XTVvjmVjps1aEZH1sumIk=
github.com/jfreymuth/vorbis v1.0.0/go.mod h1:8zy3lUAm9K/rJJk223RKy6vjCZTWC61NA2QD06bfOE0=
@ -92,6 +105,8 @@ golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634 h1:bNEHhJCnrwMKNMmOx3yAynp5v
golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3 h1:kzM6+9dur93BcC2kVlYl34cHU+TYZLanmpSJHVMmL64=
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=