Friday, March 8, 2013

Entity Hierarchies

I've added Entity parenting to the engine!

A powerful component of some game engines--whether they're 2D or 3D--is the ability to give things (enemies, fireballs, particles, whatever) parent-child relationships such that transformations (moving, scaling, rotating) to the parent automatically affect all children. 

For example, an enemy might cast a spell that makes 4 fireballs swarm around him. Instead of the programmer manually calculating the position these fireballs--which can get quite complicated as the player moves around--a system might be set up so that the fireballs are position and moved with respect to the enemy. So, from a programming standpoint, the fireballs simply spin around (0, 0), and when the enemy moves, the fireballs move with it.

I have a video, as always, that demonstrates this new feature. Check it out!


Additional notes on the video:
  • You'll notice that I have a new character sprite. Say goodbye to Link and say hello to...well, it's a temporary design and will most likely change, so there's no point giving him a name.
  • Those test triggers (the white diamonds) appear to show off some sort of particle system. Although you might call them 'particles', they're actually just entities just like everything else, meaning they support the complete feature set thus far.
The entire scenario demonstrated in the video is entirely designed within the level editor via the scripting interface. For example, here's the part of the script that creates the tiny little balls at the end:

local section = e.Section;
local target = section:FindEntities("ball")
for ball in enum(target) do
  for i = 1, 8 do
    local angle = 2 * math.pi * i / 8
    local r = 32
    local x = math.cos(angle) * r
    local y = math.sin(angle) * r
    local t = { w = 8, h = 8, texture = "small_ball", 
                x = 0, y = 0 }
    local smallBall = section:CreateEntity(t)
    ball:AppendChild(smallBall)
    smallBall:Control(
     sequence(
       delay((i - 1) / 8),
         range("finish", .5, interp("position", v2(0,0), v2(x,y),                        "easeIn"))))
     smallBall:SetModel("Circle")
     smallBall:AddCollisionCategory("wall")
  end
end

Notes on the script:
  • The Section.FindEntities method returns all entities with a given tag. In a previous script, I had tagged all of the large balls with the tag 'ball'.
  • Entity.AppendChild is how parenting is set up
  • Note that the small balls are created with x = 0 and y = 0. This is because the small balls are positioned relative to their parents, not the world.

No comments:

Post a Comment