-
Notifications
You must be signed in to change notification settings - Fork 83
Home
#Rapid Router (codename: ocargo) Documentation Things you need to know about the app.
##How do the Blockly/Python programs control the character animations? In short, when the Play button is clicked, code written by user is compiled into Commands which are placed in the stack of a Program. The Program is then run and each of the Command is executed, modifying state in Model and populating animationQueue at the same time. The animations are performed one subarray at a time, any Pauses will stop the animation before the next subarray.
More in-depth explanation with reference to code: When the Play button is clicked, runProgramAndPrepareAnimation() is executed which tells the controller to compile the code. Both BlocklyCompiler and PythonCompiler translates Blockly/Python code into Commands which are then pushed into the stack of the Program. Procedures are also compiled at this stage and placed in Program. Any compilation error will be caught and users will be informed where in the program an error was thrown. The program is run with the command at the top of the stack. During the execution of each command, a corresponding function is called in Model which does the condition checks and changes the state of the model, it also appends animationObject to animationQueue when needed. There are two timers in model, one is timestamp and the other is movementTimestamp. timestamp is used to separate animations into groups so that user can pause in between the steps, this allows if-then-else or loop blocks to be highlighted and makes it clearer for users to understand the flow of the program. On the other hand, movementTimestamp is like the virtual time in the game, it only gets incremented when the character moves. movementTimestamp is useful for when the cow levels go live because the cow will not disappear before the van even gets there. At the end of the animation there will be a popup showing the score if van successfully delivered, or help messages if user got stuck.
##Drawing ###Grid coordinate system
The map of the game is a 10 by 8 grid. The origin of the map is bottom left corner. Location of different map elements are specified using this coordinate system. These coordinates are hereafter called grid coordinates.
Our game is animated using RaphaelJS, a javascript library for creating and animating svgs. All the elements on the map are drawn on a Raphael canvas object. The origin of a Raphael object is the top left corner. When creating an object on the canvas, the top left corner of the border of the object is placed on the specified coordinates. For example, the van shown in the picture was created using the following code.
paper.image(ocargo.Drawing.raphaelImageDir + CHARACTER_URL, 100, 100, CHAR_HEIGHT, CHAR_WIDTH);
Road letter is a set of letter combination that represents the orientation of the road segment placed. Straight road segments are either placed horizontally(H) or vertically(V). Orientation of turns are determined relative to the centre point of the turn. L-shape turn is represented by UR as there are connections to the top and right node from the centre node. T-shape junction is considered to be down as the middle branch points downwards. The mapping of letters to orientation is shown in the table below.
Road letters | Picture |
---|---|
H | |
V | |
UL | |
UR | |
DL | |
DR | |
up | |
down | |
left | |
right |
###Character's height and width Height and width referenced in the code refers to the character when it's facing right. However, when you create a Raphael object for the character, you need to specify the size the other way round as all the characters are by default facing up.
paper.image(ocargo.Drawing.raphaelImageDir + CHARACTER_URL, 0, 0, CHAR_HEIGHT, CHAR_WIDTH);
###How is the character placed on the map? The character is always placed on the left lane facing away from the origin node. calculateCharacterInitialPosition() returns the location where the character should be first placed, then the character is rotated about the centre of the grid to be on the right side of the grid. At last, the svg is rotated 90 degrees clockwise to face away from the CFC as it originally faces up.
###Is it the same for CFC? Yes, the only difference is that the offset for CFC is constant.
##Animation ###animationQueue animationQueue is a 2D array which stores animation object that specifies what animation or sound to be played next. stepAnimation() will perform all the animations in the same subarray, and wait until the animation with the longest duration to finish before moving on to the next subarray.
###Animate character's movement ####TurnLeft/TurnRight/TurnAround Each turning animation is equivalent to a rotation of the character svg about a point, which lies on either side of the svg and share the same y-coordinate as the centre. Note that these points are relative to the character svg canvas instead of the entire map. As the size and shape of the svg will affect the location of the points, the coodrinates can be determined by calling getRotationPointXForXXXX() and getRotationPointY() methods, these will take into account the height and width of the svg canvas of the characters. Below shows the calculation in detail.
coorinates of centre of svg = (height/2, width/2)
rotationPointX = centre.x + radius
rotationPointY = centre.y
###Glossary
##MOOooooooo ###Introduction In earlier levels, children have to take into account red traffic lights that block the van, they can either use conditionals or loops to avoid running a red light. However, traffic lights have deterministic behaviour and are placed at predefined places; they are therefore predictable. The aim of this new episode is to introduce the advanced programming concept of handling unexpected events into the game. Rapid Router is extended with support for fully non-deterministic obstacles in the form of cows that can randomly cross the road. Furthermore, we integrate an advanced event handling mechanism into the Blockly language. These extensions allow us to build new levels that teach children how unexpected events can be handled in a modular fashion, which is transferable to real programming concepts such as exception, interrupt, and event handling.
###GamePlay
There are two types of cow that will appear at random location on the road, say hi to Clarice(white) and Jersey Clarice(brown). They are very naughty and all they do is cross the road at random times to block the van and prevent the driver from doing their job.
So what can you do when they are in your way? Scare them away! The van can now either sound the horn or puff up (enlarge itself for a short amount of time) to frighten the cows. However, each cow only has one weakness, so users will have to experiment which action to use for different cows.
####Blocks
New blocks are added in this episode to enable event handlers which takes care of unpredicable events such as cow crossing the road. The drop down menu on the block allow user to choose which event to react to, user can then drag an event action block into the slot to specify what the van should do if said event occurs. The event block can be placed anywhere on the workspace like a prodecure block, this is because the program written by the user do not need to actively check for those conditions to be true, this will be done implicitly, therefore it does not matter where the block is. The block shown in the image above show that the van should sound the horn when it sees a white cow ahead.
####Animation #####Sound horn When van sounds the horn, there's no visual animation for it. But if you turn on your speaker or put on your headphone, you will be able to hear it as the van moves.
#####Puff up
For puffing up, it takes two or more road segments to complete the animation. The van remains puff up if there's another event which triggers the same action.
###Implementation
###LevelEditor
###Future work