Difference between revisions of "Animating Props"

From SCI Wiki
Jump to navigationJump to search
 
(8 intermediate revisions by the same user not shown)
Line 22: Line 22:
  
  
This will show you how to use [[scicd:Classes/Cycle.html#Cycle|<span class="Revference">Cycle</span>]] objects to create animations.
+
This will show you how to use [[scicompdoc:Classes/Cycle.html#Cycle|<span class="Reference">Cycle</span>]] objects to create animations.
  
 
==<br /> A simple animation ==
 
==<br /> A simple animation ==
Line 39: Line 39:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
This uses the [[scicd:Classes/Forward.html#Forward|<span class="Revference">Forward</span>]] cycler to cycle forward through the loops cels. So when you run the game, the blue box will now cycle between blue, red and yellow. Easy!
+
This uses the [[scicompdoc:Classes/Forward.html#Forward|<span class="Reference">Forward</span>]] cycler to cycle forward through the loops cels. So when you run the game, the blue box will now cycle between blue, red and yellow. Easy!
  
 
To adjust the speed, you can set a different cycleSpeed on the object:
 
To adjust the speed, you can set a different cycleSpeed on the object:
Line 75: Line 75:
 
Now we’ll write code that triggers off the ego performing the V_DO verb on the N_BOX. In that, we’ll make the box cels cycle from beginning to end. To do that, we’ll need to do a few things:
 
Now we’ll write code that triggers off the ego performing the V_DO verb on the N_BOX. In that, we’ll make the box cels cycle from beginning to end. To do that, we’ll need to do a few things:
  
    Remove the (theBox:setCycle(Forward)) we added in the previous section (in the room’s init()).
+
* Remove the (theBox:setCycle(Forward)) we added in the previous section (in the room’s init()).
    Make theBox use loop 1 by default (since that’s where our shrinking box is).
+
* Make ''theBox'' use loop 1 by default (since that’s where our shrinking box is).
    Add a doVerb method to theBox, and tell the box to cycle from beginning to end.
+
* Add a doVerb method to ''theBox'', and tell the box to cycle from beginning to end.<br />
 
+
&nbsp;
 +
<div class="CodeBlockHeader">Code:</div>
 +
<syntaxhighlight lang="sci">
 
(instance theBox of Prop
 
(instance theBox of Prop
 
     (properties
 
     (properties
Line 105: Line 107:
 
     )
 
     )
 
)
 
)
 +
</syntaxhighlight>
  
 
Compile and run the game to test it.
 
Compile and run the game to test it.
  
That’s nice, but what if we want to display a message after the box has shrunk? This is where Script objects come in (not to be confused with script files). With a Script we can choreograph a sequence of events. We’ll make a Script that has a state for shrinking the box, followed by a state for displaying a message. We’ll attach this Script to theBox.
+
That’s nice, but what if we want to display a message after the box has shrunk? This is where [[scicompdoc:Classes/Script.html#Script|<span class="Reference">Script</span>]] objects come in (not to be confused with script files). With a Script we can choreograph a sequence of events. We’ll make a Script that has a state for shrinking the box, followed by a state for displaying a message. We’ll attach this Script to ''theBox''.
  
First, create a new Script object (you can use Insert Object->Script for convenience):
+
First, create a new Script object (you can use ''Insert Object->Script'' for convenience):
  
 +
<div class="CodeBlockHeader">Code:</div>
 +
<syntaxhighlight lang="sci">
 
(instance shrinkBoxScript of Script
 
(instance shrinkBoxScript of Script
 
     (properties)
 
     (properties)
Line 122: Line 127:
 
     )
 
     )
 
)
 
)
 +
</syntaxhighlight>
  
Then, replace our previous handling of theBox doVerb with a call to set the Script on the box:
+
Then, replace our previous handling of ''theBox'' doVerb with a call to set the Script on the box:
  
 +
<div class="CodeBlockHeader">Code:</div>
 +
<syntaxhighlight lang="sci">
 
(method (doVerb theVerb)
 
(method (doVerb theVerb)
 
     (switch theVerb
 
     (switch theVerb
Line 135: Line 143:
 
     )
 
     )
 
)
 
)
 +
</syntaxhighlight>
  
 
Now add some meat to the shrinkBoxScript.
 
Now add some meat to the shrinkBoxScript.
  
 +
<div class="CodeBlockHeader">Code:</div>
 +
<syntaxhighlight lang="sci">
 
(instance shrinkBoxScript of Script
 
(instance shrinkBoxScript of Script
 
     (properties)
 
     (properties)
Line 159: Line 170:
 
     )
 
     )
 
)
 
)
 +
</syntaxhighlight>
  
Ok, what is all that? First of all, case 0 will be executed as soon as the Script is set on the box. So that will start the cycle to shrink the box. Note that we added a self parameter to the setCycle call. This is a common thing for setCycle (and setMotion). It means that self will be cued() when the cycle is finished. And what happenes when a Script is cued()? It’s changeState() is called with an incremented newState. So basically this is saying: “when we reach the End of the cycle, go to the next state”.
+
Ok, what is all that? First of all, ''case 0'' will be executed as soon as the Script is set on the box. So that will start the cycle to shrink the box. Note that we added a '''self''' parameter to the setCycle call. This is a common thing for setCycle (and setMotion). It means that '''self''' will be ''cued()'' when the cycle is finished. And what happenes when a Script is cued()? It’s changeState() is called with an incremented ''newState''. So basically this is saying: “when we reach the End of the cycle, go to the next state”.
  
 
The next state sets the Script’s seconds to 2. So after 2 seconds, changeState will be called again with an incremented newState. In this final case, we print some text to notify the player what happened (of course, we should probably use a message here).
 
The next state sets the Script’s seconds to 2. So after 2 seconds, changeState will be called again with an incremented newState. In this final case, we print some text to notify the player what happened (of course, we should probably use a message here).
Line 166: Line 178:
 
We also put calls to handsOff and handsOn so that the player can’t go and do something else while this short Script is executing (for instance, to prevent them from touching the box again and re-triggering the Script).
 
We also put calls to handsOff and handsOn so that the player can’t go and do something else while this short Script is executing (for instance, to prevent them from touching the box again and re-triggering the Script).
  
Now, the player can keep touching theBox and it will appear large again and shrink down. Because that’s what the End cycle does: Starts from cel 0 and goes to the end. So maybe we should handle that case.
+
Now, the player can keep touching ''theBox'' and it will appear large again and shrink down. Because that’s what the <span class="Reference">End</span> cycle does: Starts from cel 0 and goes to the end. So maybe we should handle that case.
  
 
Go to the top of the script and add a local variable:
 
Go to the top of the script and add a local variable:
  
 +
<div class="CodeBlockHeader">Code:</div>
 +
<syntaxhighlight lang="sci">
 
(local
 
(local
 
     hasBoxShrunk = FALSE
 
     hasBoxShrunk = FALSE
 
)
 
)
 +
</syntaxhighlight>
  
 
Then modify theBox:doVerb() like so:
 
Then modify theBox:doVerb() like so:
  
 +
<div class="CodeBlockHeader">Code:</div>
 +
<syntaxhighlight lang="sci">
 
(method (doVerb theVerb)
 
(method (doVerb theVerb)
 
     (switch theVerb
 
     (switch theVerb
Line 191: Line 208:
 
     )
 
     )
 
)
 
)
 +
</syntaxhighlight>
  
 
Now the box can only shrink once, and we can respond to V_DO with something else when the box is already shrunk.
 
Now the box can only shrink once, and we can respond to V_DO with something else when the box is already shrunk.
  
 +
==<br /> switchto ==
  
 +
This might be a good time to introduce the switchto statement. It’s just like a switch statement, except the cases are implicitly number from 0 upwards. This can be useful if you’re adding and removing lots of cases as you create your room scripts.
  
 +
This is what shrinkBoxScript’s changeState method looks like if we use a switchto:
  
 +
<div class="CodeBlockHeader">Code:</div>
 +
<syntaxhighlight lang="sci">
 +
(method (changeState newState)
 +
    (= state newState)
 +
    (switchto state
 +
        (
 +
            (gGame handsOff:)
 +
            ; We could also say (theBox setCycle: EndLoop self)
 +
            (client setCycle: EndLoop self)
 +
        )
 +
        (
 +
            (= seconds 2)
 +
        )
 +
        (
 +
            (Prints {The box shrunk!})
 +
            (gGame handsOn:)
 +
        )
 +
    )
 +
)
 +
</syntaxhighlight>
  
 
+
It doesn’t look much different, but there’s no chance we miss a state number when we’re adding and removing states.
 
 
 
 
 
 
 
 
 
 
 
 
  
 
&nbsp;
 
&nbsp;

Latest revision as of 22:59, 30 July 2016

SCI Tutorials

Chapter: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12


Animating Props
Author: Phil Fortier


This will show you how to use Cycle objects to create animations.


A simple animation

Remember that blue box? Go back to the box view, and add a third cel. Color shift it so it’s yellow (or do whatever you want).

Go to your script file, and add at a setCycle method call to the box’s initialization:

Code:
(theBox
    approachVerbs: V_DO
    setCycle: Forward
    init:
)

This uses the Forward cycler to cycle forward through the loops cels. So when you run the game, the blue box will now cycle between blue, red and yellow. Easy!

To adjust the speed, you can set a different cycleSpeed on the object:

Code:
(instance theBox of Prop
    (properties
        view 123
        x 150
        y 100
        signal ignAct
        loop 0
        cel 0
        noun N_BOX
        priority 0
        approachX 130
        approachY 110
        cycleSpeed 15   ; Large numbers are slower.
    )
)


Triggering Off Animation Events

Let’s do something a little more complicated. Let’s make the box shrink when the player touches it. Go back to view 123, and create a new loop. When you create a new loop, by default it should contain the first cel of the previous loop (it has to contain something). That’s great, it’s our blue box.

Add three more cels to the loop. They should all have blue boxes in them by default.

Click on the second cel and resize the borders while holding down the SHIFT key (this makes resizing the borders grow or shrink the view inside). Make the box a little smaller. Click on the third cel and make it even smaller, and so on. You should end up with something like this:

ShrinkingBox.png
 

Now we’ll write code that triggers off the ego performing the V_DO verb on the N_BOX. In that, we’ll make the box cels cycle from beginning to end. To do that, we’ll need to do a few things:

  • Remove the (theBox:setCycle(Forward)) we added in the previous section (in the room’s init()).
  • Make theBox use loop 1 by default (since that’s where our shrinking box is).
  • Add a doVerb method to theBox, and tell the box to cycle from beginning to end.

 

Code:
(instance theBox of Prop
    (properties
        view 123
        x 150
        y 100
        signal ignAct
        loop 1
        cel 0
        noun N_BOX
        priority 0
        approachX 130
        approachY 110
        cycleSpeed 15
    )

    (method (doVerb theVerb)
        (switch theVerb
            (V_DO
                (self setCycle: EndLoop)
            )
            (else
                (super doVerb: theVerb &rest)
            )
        )
    )
)

Compile and run the game to test it.

That’s nice, but what if we want to display a message after the box has shrunk? This is where Script objects come in (not to be confused with script files). With a Script we can choreograph a sequence of events. We’ll make a Script that has a state for shrinking the box, followed by a state for displaying a message. We’ll attach this Script to theBox.

First, create a new Script object (you can use Insert Object->Script for convenience):

Code:
(instance shrinkBoxScript of Script
    (properties)

    (method (changeState newState)
        (= state newState)
        (switch state
            (0)
        )
    )
)

Then, replace our previous handling of theBox doVerb with a call to set the Script on the box:

Code:
(method (doVerb theVerb)
    (switch theVerb
        (V_DO
            (self setScript: shrinkBoxScript)
        )
        (else
            (super doVerb: theVerb &rest)
        )
    )
)

Now add some meat to the shrinkBoxScript.

Code:
(instance shrinkBoxScript of Script
    (properties)

    (method (changeState newState)
        (= state newState)
        (switch state
            (0
                (gGame handsOff:)
                ; We could also say (theBox setCycle: EndLoop self)
                (client setCycle: EndLoop self)
            )
            (1
                (= seconds 2)
            )
            (2
                (Prints {The box shrunk!})
                (gGame handsOn:)
            )
        )
    )
)

Ok, what is all that? First of all, case 0 will be executed as soon as the Script is set on the box. So that will start the cycle to shrink the box. Note that we added a self parameter to the setCycle call. This is a common thing for setCycle (and setMotion). It means that self will be cued() when the cycle is finished. And what happenes when a Script is cued()? It’s changeState() is called with an incremented newState. So basically this is saying: “when we reach the End of the cycle, go to the next state”.

The next state sets the Script’s seconds to 2. So after 2 seconds, changeState will be called again with an incremented newState. In this final case, we print some text to notify the player what happened (of course, we should probably use a message here).

We also put calls to handsOff and handsOn so that the player can’t go and do something else while this short Script is executing (for instance, to prevent them from touching the box again and re-triggering the Script).

Now, the player can keep touching theBox and it will appear large again and shrink down. Because that’s what the End cycle does: Starts from cel 0 and goes to the end. So maybe we should handle that case.

Go to the top of the script and add a local variable:

Code:
(local
    hasBoxShrunk = FALSE
)

Then modify theBox:doVerb() like so:

Code:
(method (doVerb theVerb)
    (switch theVerb
        (V_DO
            (if (not hasBoxShrunk)
                (= hasBoxShrunk TRUE)
                (self setScript: shrinkBoxScript)
            else
                (Prints {What a small box!})
            )
        )
        (else
            (super doVerb: theVerb &rest)
        )
    )
)

Now the box can only shrink once, and we can respond to V_DO with something else when the box is already shrunk.


switchto

This might be a good time to introduce the switchto statement. It’s just like a switch statement, except the cases are implicitly number from 0 upwards. This can be useful if you’re adding and removing lots of cases as you create your room scripts.

This is what shrinkBoxScript’s changeState method looks like if we use a switchto:

Code:
(method (changeState newState)
    (= state newState)
    (switchto state
        (
            (gGame handsOff:)
            ; We could also say (theBox setCycle: EndLoop self)
            (client setCycle: EndLoop self)
        )
        (
            (= seconds 2)
        )
        (
            (Prints {The box shrunk!})
            (gGame handsOn:)
        )
    )
)

It doesn’t look much different, but there’s no chance we miss a state number when we’re adding and removing states.

 

< Previous: The Priority Screen Next: Managing the Player’s Inventory >