[Ohrrpgce] Slice tutorial
James Paige
Bob at HamsterRepublic.com
Mon Jan 19 09:12:10 PST 2009
On Sat, Jan 17, 2009 at 10:30:32AM -0800, Adam Perry wrote:
> James,
>
> I see the documentation for the new slice commands in the xml plotdict.
> Two things, though:
>
> - The business of containers, slices, and such isn't intuitive. Could you
> (or someone) create a short tutorial explaining, minimally, how to get a
> sprite on the screen and manipulate it?
> - All of these commands need to find their way into the wiki as well.
>
> I'm sure I'm not the only one who's excited about slices but doesn't know
> where to start.
Well, lets start here.
A slice is a rectangular thing. It has an X/Y position, a Width and a
height, and it can be attached to the screen (root) or it can be
attached to any other slice.
A great way to get used to what slices are capable of is to try out the
"Screen Layout Editor" in custom. Right now it is not yet actually
capable of being used to lay out screens, but it does let you connect
slices together and see what happens when you move them around or resize
them.
Anyway, on to coding examples. Suppose you want to put a large enemy
sprite on the screen.
variable(sl)
sl := load large enemy sprite(0)
We have now added a slice containing a copy of large enemy sprite #0 to
the slice tree. The slice tree gets redrawn automatically, all we need
to do is add things to it, and move them around. Here is how we move a
slice:
set slice x(sl, slice x(sl) + 10)
That moves the sprite 10 pixels to the right.
You may notice in the plotscripting dictionary that there are two sets
of functions for working with slice x and y
"slice x" "set slice x"
"slice y" "set slice y"
"slice screen x" "set slice screen x"
"slice screen y" "set slice screen y"
At first glance these might seem to be totally redundant. Indeed, if you
check out the values for our newly loaded large enemy sprite, you will
notice that the x/y and screen x/screen y are the same.
The difference is, the slixe x/y values are relative to the slice's
parent. Every slice has a parent. When we first load a sprite, the
default parent for it is "sprite layer" which is a "special" slice. the
sprite layer slice has an x/y of 0,0 and a width/height of 320,200 just
the same size as the screen.
One of the really cool things about slices is that you can attach them
to parents. For example, lets load a small enemy sprite that resembles a
top-hat and put it on the large enemy sprite we loaded before.
variable(hat)
hat := load small enemy sprite(0)
set parent(hat, sl)
set slice x(hat, 23)
set slice y(hat, -28)
I'm just guessin on the x/y here, because I don't know exactly where
the head of your large enemy sprite will be, but the point is that we
have detached the hat sprite from the screen, and attached it to the
large enemy sprite. Now if we say:
set slice y(sl, slice y(sl) + 5)
then BOTH the enemy sprite AND his hat will move together.
Now suppose that in this way we have set up 5 different enemy sprites,
each of them wearing a hat. That makes a total of 10 slices on screen.
Does that mean that we need to keep 10 variables to store their handles?
Well, not really. Sure, you could be tucking the slice handles away in
a fake array using "write global", but you don't really need to.
The fact is, the children of a parent slice are already kinda like an
array. SO lets see how you loop through them without needing to know
their handles in advance.
variable(handle)
handle := first child(sprite layer)
while(handle) do, begin
#do something to each handle here
handle := next sibling(handle)
end
So first we use the "first child" command. This takes any slice and
gives us the handle to its first child, or 0 if there are no children.
Slice handles are always non-zero, so then we can say "while(handle)"
for our loop.
At the end of the loop, we use the "next sibling" command to get the
next slice handle, or 0 if there are no more (and as you know, a 0 will
cause the "while" loop to stop)
Now if we loop through our hat-wearing enemy sprites in this way, the
while loop is going to loop through 5 times, once for each enemy.
Why not for the hats? The hats are NOT children of the "sprite layer"
anymore. Remember? we re-parented them with the "set parent" command.
The hats are now childrewn of the enemy sprites (and thusly they are
grandchildren of the sprite layer)
So what if we want to loop through all the hats and manipulate them?
variable(handle, hat)
handle := first child(sprite layer)
while(handle) do, begin
hat := first child(handle)
if(hat) then, begin
#do something to each hat here
end
handle := next sibling(handle)
end
See? We can use the "first child" command on the enemy sprite's slice
handle and get the hat. Now suppose we wanted to allow enemies to maybe
wear more than one hat... or glasses... or gloves or something.
variable(handle, clothing)
handle := first child(sprite layer)
while(handle) do, begin
clothing := first child(handle)
while(clothing) do, begin
# do something with each article of clothing here
clothing := next sibling(clothing)
end
handle := next sibling(handle)
end
And yes, children can have children which can have children, and so-on,
until you create a family tree of slices that is so big you run out of
memory.
One other thing to note is that if you delete a slice using "free slice"
(or "free sprite") then all of its children will be deleted too, as if
you are chopping the whole branch off of the family tree.
Okay. Does all of the above make sense? If not, let me know what I need
to clarify, and if so we can move on to talking about containers and
rects.
---
James
More information about the Ohrrpgce
mailing list