• Ingen resultater fundet

We have now finished in adapting our CP-net to the SceneBeans animation

ru n

in p ut (x ) ;

o u t p ut () ;

a c tio n

ru n T o D rin kS ta n d x ; w in in p u t (x ) ;

o ut p u t () ;

a c tio n

ru nT o Finis h x ;

lo s e

in p ut (x ) ;

o u t p ut () ;

a ctio n

ru n T o Finis h x ; in it

i p ut

o ut p ut () ;

a c tio n

ru n ne rs .s e tA nim a tio n

"c :/a n im a tio n .x m l" ;

S ta rt

R U N N E R

1 ` ru n ne r(1) + +

1 ` ru n ne r(2 ) D rin k

S ta nd

R U N N E R W in n e r

R U N N E R

Lo s e r

R U N N E R

F la g

F LA G

u p

N o t in ite d

U N IT

() I nite d U N IT

Fig. 6. Runner CP-net annotated for the SceneBeans animation.

1 fun runToDrinkStand x =

2 let val _ = if x = r(1)

3 then runners.invokeCommand "runToDrinkStand-r(1)"

4 else runners.invokeCommand "runToDrinkStand-r(2)"

5 val _ = runners.waitForEvent "command-executed"

6 in ()

7 done

Two things are worth to notice in this function. Firstly, we use the function invokeCommand to execute a predefined command in SceneBeans; this is executed asynchronously. Secondly, we use the function waitForEvent to wait for a named event; in our case the event command-executed. The reason for why not just use invokeCommand is that it is executed asynchronously, so a situation could occur where two behaviors are executed concurrently. This might be the wanted behavior in some cases but not in our example.

We have now finished in adapting our CP-net to the SceneBeans animation.

The final thing that needs to be done is to specify the commands in SceneBeans

which we called from our CP-net. The XML code for this animation can be seen

in Listing 1.15. For the purpose of this tutorial it is not important to read and

understand the code. It is included for the reader to see the connection between

the CP-net and the SceneBeans specification.

Listing 1.15. SceneBeans Specification of the Runners

1 <animation height="150" width="400">

2 <forall var="i" values="1 2">

3 <behaviour algorithm="move" event="command-executed"

4 id="runToDrinkStand-r(${i})">

5 <param name="from" value="10"/>

6 <param name="to" value="150 + 30 * ${i}"/>

7 <param name="duration" value="1"/>

8 </behaviour>

9 <event event="command-executed" object="runToDrinkStand-r(${i})">

10 <announce event="command-executed"/>

11 </event>

12 <behaviour algorithm="move" event="command-executed"

13 id="runToFinish-r(${i})">

14 <param name="from" value="150 + 30 * ${i}"/>

15 <param name="to" value="340 + 10 * ${i}"/>

16 <param name="duration" value="1"/>

17 </behaviour>

18 <event event="command-executed" object="runToFinish-r(${i})">

19 <announce event="command-executed"/>

20 </event>

21 <command name="runToDrinkStand-r(${i})">

22 <reset behaviour="runToDrinkStand-r(${i})"/>

23 <start behaviour="runToDrinkStand-r(${i})"/>

24 </command>

25 <command name="runToFinish-r(${i})">

26 <reset behaviour="runToFinish-r(${i})"/>

27 <start behaviour="runToFinish-r(${i})"/>

28 </command>

29 </forall>

30 <draw>

31 <forall var="i" values="1 2">

32 <transform type="translate">

33 <param name="translation" value="(0,50)"/>

34 <animate behaviour="runToDrinkStand-r(${i})" param="x"/>

35 <animate behaviour="runToFinish-r(${i})" param="x"/>

36 <transform type="scale">

37 <param name="x" value="0.4"/>

38 <param name="y" value=".4"/>

39 <primitive type="sprite">

40 <param name="src"

41 value="file:///c:/Runners/runner-${i}.gif"/>

42 </primitive>

43 </transform>

44 </transform>

45 </forall>

46 <transform type="translate">

47 <param name="translation" value="(150,10)"/>

48 <transform type="scale">

49 <param name="x" value="0.4"/>

50 <param name="y" value=".4"/>

51 <transform type="scale">

52 <param name="y" value="0.9"/>

53 <primitive type="sprite">

54 <param name="src"

55 value="file:///c:/Runners/drink-stand.jpg"/>

56 </primitive>

57 </transform>

58 </transform>

59 </transform>

60 <transform type="translate">

61 <param name="translation" value="(10,50)"/>

62 <transform type="scale">

63 <param name="x" value="0.4"/>

64 <param name="y" value=".4"/>

65 <primitive type="sprite">

66 <param name="src"

67 value="file:///c:/Runners/start.JPG"/>

68 </primitive>

69 </transform>

70 </transform>

71 <transform type="translate">

72 <param name="translation" value="(350,50)"/>

73 <transform type="scale">

74 <param name="x" value="0.4"/>

75 <param name="y" value=".4"/>

76 <primitive type="sprite">

77 <param name="src"

78 value="file:///c:/Runners/stop.JPG"/>

79 </primitive>

80 </transform>

81 </transform>

82 </draw>

83 </animation>

Lines 3-8 and 12-17 in the XML file describe the behaviors that exist in the

animation; i.e. both runners can run from start to the drink stand and from

the drink stand to finish. Lines 9-11 and 18-20 describes that events will be

generated after each behavior is executed; e.g. after runner one goes from start

to the drink stand an event is generated saying that the behavior has completed

to signal to the CP-net it can proceed on simulating. Lines 21-28 specify the commands which can be executed on our SceneBeans; i.e. the commands we call from the CP-net, e.g., runToDrinkStand-r(1). Lines 30-82 describes the figures that is in the animation; i.e. the two runners, start and finish signs and the drink stand. Also, this part describes how the figures are related to the defined behaviors; i.e. runner number one have the two behaviors runToDrinkStand-r(1) and runToFinish-r(1).

Fig. 7. SceneBeans XML editor.

The actual SceneBeans animation can be built in SClub, which is an extended

version of BRITNeY animation, which provides, among other things, an XML

editor for specifying SceneBeans animations. This editor interprets the XML file

while it is being constructed so it is possible to preview the animation and test

commands as you go along. Figure 7 shows the runners animation being built and tested. In the figure you can see that the editor is aware of which constructs to suggest depending on the context of position of the cursor. Also, you can see the defined commands and events. These can be executed by double-clicking on them.

This is all that is needed to make a simple animation using the SceneBeans

plug-in. Obviously, this is a very small example but the techniques used to make

this animation are well suited for large scale animations.