Page 1 of 5
love.scene (yet another scene graph library)
Posted: Tue Aug 25, 2020 8:38 am
by ivan
Love2D Scene Graph
This is a tiny (~10K) scene graph compatible with Love2D 11.3. This library is used to power all of the games behind
2dengine.com so the code is generalized and fairly well tested.
Features
- View or a "viewport" is a clipped rectangular area where the scene is rendered.
- Cameras allow you to pan, zoom and transform the view
- Sprites are nodes in the scene which can be translated, scaled or rotated. Each sprite is assigned a
drawable graphic, usually an image, quad or text. Sprites can also be assigned a specific color, alpha value and blending mode
- Layers are basically groups of nodes, containing either sprites or other nested layers. Layers are helpful in ordering nodes along the Z-axis. Layers are used to build things like parallax, huds, minimaps and so on.
Repository and docs
https://github.com/2dengine/love.scene
https://2dengine.com/?p=scene
Example
Code: Select all
love.scene = require("scene")
local view = love.scene.newView()
local sprite = view:newSprite(0, 0)
local image = love.graphics.newImage("myimage.png")
sprite:setGraphic(image)
function love.draw()
view:draw()
end
Re: love.scene (yet another scene graph library)
Posted: Tue Aug 25, 2020 3:30 pm
by yetneverdone
Cool! I'm thinking if i could easily implement it for my game. Im in need of this for z-sorting feature.
Can you give an example or explanation on how to use the z ordering of layers based on sprite's y-position.
Re: love.scene (yet another scene graph library)
Posted: Tue Aug 25, 2020 3:46 pm
by ivan
Thanks for taking a look yetneverdone!
It really depends on how you want to handle this.
Most of the time you want to use multiple layers:
Code: Select all
local background = view:newLayer(0, 0)
local middleground = view:newLayer(0, 0)
local foreground = view:newLayer(0, 0)
local bgsprite = background:newSprite(0, 0)
Note that sprites are sorted in the order they are created so:
Code: Select all
local under = view:newSprite(0, 0)
local above = view:newSprite(0, 0)
The easiest option is to create your sprites in the desired order.
In the rare event you want to change the depth dynamically you can use "setIndex":
Code: Select all
sprite:setIndex(1) --moves it to the bottom
or you can switch layers:
There is also a sorting function for layers.
This is useful for isometric games where the depth is affected by the Y position.
Code: Select all
layer:sort(function(a, b)
-- return true if a is below b
end)
Thanks again for taking a look!
Re: love.scene (yet another scene graph library)
Posted: Tue Aug 25, 2020 3:51 pm
by yetneverdone
Thank you!
How about integrating this with another camera lib?
Also i see that
is a special case like
?
Re: love.scene (yet another scene graph library)
Posted: Tue Aug 25, 2020 4:09 pm
by ivan
I have never used any camera libs, so I'm not sure.
I should mention that the "view" object works very much like the viewport of a camera.
You can adjust the size and position of the viewport on the screen by setting its bounds:
Typically you want to set this to the size of your game window.
You can change what is displayed inside the viewport using the "setScene" method:
Code: Select all
view:setScene(x, y, w, h) -- where w(idth) and h(eight) are optional
x and y is the scene origin which is the same as moving/panning the camera. The scene origin is typically the center of the viewport, and NOT the upper left corner!
w and h is the section of the scene (frustum) which is displayed inside the viewport.
Naturally, you can scale and rotate the view object too.
Re: love.scene (yet another scene graph library)
Posted: Tue Aug 25, 2020 4:13 pm
by ivan
The following two lines do the same thing:
Code: Select all
view:newSprite(0, 0)
love.scene.newSprite(view, 0, 0)
It's just a question of whatever syntax you prefer.
Re: love.scene (yet another scene graph library)
Posted: Thu Dec 31, 2020 3:00 am
by yetneverdone
Hi, taking a look at this library again as I am experiencing issue with my rendering system.
So is `view` the same as what camera provides?
So as I understand it, one `scene.sprite` can only have one `sprite/image`?
My project is ECS-based so the `images` in my game are passed as reference to a `sprite` component and then my `RenderSprite` system handles drawing them. So Im thinking that if I am going to integrate this library instead of my own, I would need my `RenderSprite` system to handle the creation of `layers` and then when `entities` are passed into the system, i would register the `images` to the `sprite` right? On the top of my head something like:
Code: Select all
local spr_player = love.graphics.newImage("sprite.png")
local spr_enemy = love.graphics.newImage("enemy.png")
local e_player = Entity():give("sprite", spr_player) --also other components
local e_enemy = Entity():give("sprite", spr_enemy) --also other components
--in RenderSprite
--in init
self.view = love.scene.newView()
self.layers = {
background = self.view:newLayer(),
main = self.view:newLayer(),
foreground = self.view:newLayer()
}
--when entities are registered
self.layers.main:newSprite(e_player.sprite.sprite) --e_player is registered first
self.layer.main:newSprite(e_enemy.sprite.sprite)
--in update
self.layers.main:sort(function(a, b)
-- sort by entity's z-component, higher z should be behind lower z as z corresponds to the y-position in the screen.
end)
--in draw
self.layers.background:draw()
self.layers.main:draw()
self.layers.foreground:draw()
Re: love.scene (yet another scene graph library)
Posted: Thu Dec 31, 2020 4:00 pm
by ivan
yetneverdone wrote: ↑Thu Dec 31, 2020 3:00 am
So is `view` the same as what camera provides?
view is like the "viewport" of a camera. You can move it around and resize it using:
So as I understand it, one `scene.sprite` can only have one `sprite/image`?
You can assign ONE drawable object to each sprite. This could be an image, mesh, text, particlesystem, etc.
Assigning a drawable to a sprite is very similar to love.draw:
Code: Select all
love.graphics.draw(img, x, y, r, sx, sy, ox, oy)
sprite:setGraphic(img, x, y, r, sx, sy, ox, oy)
Your code looks fine, except for the last part.
We only "draw" the view object:
Re: love.scene (yet another scene graph library)
Posted: Sat Jan 02, 2021 7:07 am
by yetneverdone
Ive started testing this lib and it's kinda tricky integrating this with an existing camera system.
Also, no `setScale` for view? Also can you elaborate more on the `setScene`? Thank you
Re: love.scene (yet another scene graph library)
Posted: Sat Jan 02, 2021 8:10 am
by ivan
yetneverdone wrote: ↑Sat Jan 02, 2021 7:07 am
Ive started testing this lib and it's kinda tricky integrating this with an existing camera system.
You don't need a separate camera system - the "view" object works as a camera.
yetneverdone wrote: ↑Sat Jan 02, 2021 7:07 am
Also, no `setScale` for view? Also can you elaborate more on the `setScene`? Thank you
setScene determines the visible range of the viewport. So if you write:
The viewport will cover an area of 800 by 600 centered around 0, 0. This will change the scale of the viewport automatically.
If you want to set the scale by hand, then don't use the last two parameters:
Code: Select all
view:setScene(0, 0)
view:setScale(2, 2)
If you want to change the actual size of the viewport within the game window you can use "setDimensions" or "setBounds":
Either one of these functions will create a rectangular viewport 200 by 200 pixels in the top-left corner of the game window (0, 0).