Well, I've made some progress on learning the scene module, but now I've come across a rock.
Here is some code from the tutorial:
1 from scene import *
2 import sys
3 class MyScene (Scene):
4 def setup(self):
5 self.layer = Layer(Rect(self.size.w * 0.5 - 100, self.size.h * 0.5 - 100, 200, 200))
6 self.layer.background = Color(1, 0, 0)
7 self.layer.animate('alpha', 0.0, duration=1.0, autoreverse=True, repeat=sys.maxint)
8 def draw(self):
9 background(0, 0, 0)
12 def touch_began(self, touch):
13 new_frame = Rect(touch.location.x - 100, touch.location.y - 100, 200, 200)
14 self.layer.animate('frame', new_frame, duration=2.0, curve=curve_bounce_out)
I'm going to explain each line as it makes sense to me.
1-2)imports modules. Basic
3-4) beginning to create the scene
- creates a"piece of paper", if you will. We then draw a rectangle on it.
- making this rectangle red
- creating an animation. I do not know what all of the things in it means though. The sting at the beginning is unknown to me, as is the number after it. The rest are mainly about how long the animation lasts and does it repeat and so on.
- drawing what we just set up
- setting black to the background of the entire page/screen
- updates (think reloads) the drawing. Not sure what self.dt is. I know that dt is delta time (better known as change of time)
- redraws the drawing? NOTE if I were to make the rectangle into an image this causes the program to stop (error)
- if something touches the screen do...
- New location of the rectangle
14)new animation. I understand what curve is (it is the fancy movement). I don't get the rest though.
- run the scene.
If I wasn't clear enough let me know!
Thanks for any help you give,
I will begin with the quote from the documentation:
Layer.animate(attribute, to_value, duration=0.5, delay=0.0, curve=curve_sinodial, repeat=1, autoreverse=False, completion=None)
Create an Animation with the given parameters and add it to the layer’s animations.
Depending on the attribute (a string), to_value can be a number, a Rect or a Color.
Animatable attributes are frame, scale_x, scale_y, rotation, background, stroke, stroke_weight, tint and alpha.
The first value, the string that confuses you, is one of those 9 attributes listed in the docs, in the form of a string. In this case, alpha is the opacity of the layer, ranging from 1 (opaque) to 0 (transparent).
Basically the layer.animate says: attribute='alpha', to_value=0.0, duration=1.0, autoreverse=True, repeat=Large Int. In English, it might say "Animate the alpha value of the layer from the current value until the layer is invisible, the animation lasting for one second, then reverse it. Repeat until awesome."
self.dt is delay time of the current frame since the last frame, so you already hit the mark on this one.. I use it as a lag counter when I'm debugging. It should usually be like 0.01 or so ... You'll see very noticeable lag by 0.04. It all depends on the script really. Games can be very intensive.
When updating the layer, the value you input for dt can be different. dt in this case is the time since last invocation of the layer, so if you only invoke your layer once every 2000 frames, then dt would be much larger. Since you update your layer every frame, your dt should be (and is) self.dt
After updating your layer, you draw it. I am assuming update and draw are seperated to allow you to calculate other layers before you draw them all.
The reason you cannot draw an image in layer.animate is explained in the quote "to_value can be a number, a Rect or a Color".
I personally haven't tried experimenting with layers too much. I haven't had the need. But I am considering it for this RTS I am working on.
@eliskan explained most of this very well already, so let me just add some clarification on <code>update</code> vs. <code>draw</code>.
<code>update</code> essentially just goes through all the animations that have been added to a layer and updates the current values to intermediate values based on the time that has passed. In this example, it would update the <code>alpha</code> (transparency) attribute of the layer to some value between 0.0 and 1.0.
The elapsed time (since the last call to <code>update</code>) is passed as an argument because that allows more flexibility for animating multiple layers "in sync" or to slow down or pause all animations very easily. For example, if you were to pass <code>self.dt * 0.5</code> here, all animations would run at half their normal speed. If you passed 0.0, the animation would be paused.
The <code>draw</code> method then basically just translates the current state of the layer into drawing commands.
Wow you two! Thanks!
I think I understand it all now.
I only have two questions now:
- Where is the list of attributes? I've looked all over for it (I've obviously not looked where it is though:P). I only know of 'alpha' and 'frame' (which I haven't played with enough to find out what it does).
- How do you animate images then? I can't with the above method (at least not in it's current form).
Thanks and you guys are the best :)
- They're listed in the documentation about the animate function:
- You can't animate images directly. Instead, you'd typically fade out the layer with the old image and fade in a new layer with the replacement image. I've made a little example that hopefully makes this a bit clearer:
It basically just cross-fades to a new image when you touch the screen. Note the use of the completion parameter in order to remove the old layer from the scene when the fade-out animation completes.
You could of course make the transition fancier by playing with different animatable attributes, like scale_x/scale_y etc. You can also animate multiple attributes simultaneously, e.g. to do a fade-and-zoom-out transition...
Thanks omz! I'll look over the code you provided!
Also, I realized you can (using a rectangle) do "self.layer.image = 'name_of_image'" and then not set a background color for the rectangle. The image then takes the dimensions of the rectangle.
I'll post again if I have any further trouble. Thanks again!