1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2025-02-20 15:37:31 -05:00
OpenDiablo2/d2core/d2systems/scene_shape_system.go

154 lines
4.1 KiB
Go
Raw Normal View History

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
Components struct {
Transform d2components.TransformFactory
Color d2components.ColorFactory
Rectangle d2components.RectangleFactory
Texture d2components.TextureFactory
Size d2components.SizeFactory
Origin 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
changes to d2components, d2systems, d2ui, d2enum go.mod, go.sum: * updating akara, bugfix in akara.EntityManager.RemoveEntity d2core * adding d2core/d2label * adding d2core/d2bitmapfont d2ui * exporting some constants for use elsewhere d2components * added bitmap font component (for ui labels) * added FileLoaded tag component to simplify asset loading filters * added locale component * FilePath component renamed to File * sprite component now contains the sprite and palette path as strings * adding ui label component d2enum * added locale as file type for file "/data/local/use" d2systems * changed most info prints to debug prints * removed unused scene graph testing file (oops!) * terminal is now rendered above mouse cursor scene * adding ui widget system for use by the game object factory * adding test scene for ui labels created with the ui widget system d2systems/AppBootstrap * added command line args for profiler * `--testscene labels` launches the label test * now adds the local file for processing * game loop init logic now inside of Init method (the call to world.Update does this) d2systems/AssetLoader * loads the locale file and adds a locale component that other systems can use * adds a FileLoaded component after finished loading a file which other systems can use (like the loading scene) d2systems/FileSourceResolver * Now looks for and uses the locale for language/charset filepath substitution d2systems/GameClientBootstrap * game loop init moved to end of AppBootstrap.Init d2systems/GameObjectFactory * embedding UI widget factory system d2systems/BaseScene * made base scene a little more clear by breaking the process into more methods d2systems/LoadingScene * simplified the entity subscriptions by using the new FileLoaded component d2systems/SceneObjectFactory * adding method for adding labels, buttons to scenes (buttons still WIP) d2systems/SceneSpriteSystem * the sprite system now maintains a cache of rendered sprites
2020-12-08 10:42:19 -08:00
t.Debug("initializing sprite factory ...")
t.setupFactories()
t.setupSubscriptions()
t.loadQueue = make(spriteLoadQueue)
}
func (t *ShapeSystem) setupFactories() {
t.InjectComponent(&d2components.Color{}, &t.Components.Color.ComponentFactory)
t.InjectComponent(&d2components.Transform{}, &t.Components.Transform.ComponentFactory)
t.InjectComponent(&d2components.Texture{}, &t.Components.Texture.ComponentFactory)
t.InjectComponent(&d2components.Origin{}, &t.Components.Origin.ComponentFactory)
t.InjectComponent(&d2components.Size{}, &t.Components.Size.ComponentFactory)
t.InjectComponent(&d2components.Rectangle{}, &t.Components.Rectangle.ComponentFactory)
}
func (t *ShapeSystem) setupSubscriptions() {
shapesToRender := t.NewComponentFilter().
RequireOne(&d2components.Rectangle{}).
Require(&d2components.Texture{}).
Build()
shapesToUpdate := t.NewComponentFilter().
RequireOne(&d2components.Rectangle{}).
Require(&d2components.Transform{}, &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)
}
}
// ComponentFactory queues a sprite spriteation to be loaded
func (t *ShapeSystem) Rectangle(x, y, width, height int, color color.Color) akara.EID {
2020-12-04 00:11:19 -08:00
t.Debug("creating rectangle")
eid := t.NewEntity()
r := t.Components.Rectangle.Add(eid)
r.X, r.Y = float64(x), float64(y)
r.Width, r.Height = float64(width), float64(height)
c := t.Components.Color.Add(eid)
c.Color = color
texture := t.Components.Texture.Add(eid)
texture.Texture = t.RenderSystem.renderer.NewSurface(width, height)
texture.Texture.Clear(c.Color)
return eid
}
func (t *ShapeSystem) updateShape(eid akara.EID) {
transform, found := t.Components.Transform.Get(eid)
if !found {
return
}
size, found := t.Components.Size.Get(eid)
if !found {
return
}
texture, found := t.Components.Texture.Get(eid)
if !found || texture.Texture == nil {
return
}
rectangle, rectangleFound := t.Components.Rectangle.Get(eid)
if rectangleFound {
transform.Translation.X, transform.Translation.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.Components.Texture.Get(eid)
if !found || texture.Texture == nil {
return
}
col, found := t.Components.Color.Get(eid)
if !found {
return
}
texture.Texture.Clear(col.Color)
}