BADGE 2
BACKCreate a present which can be unwrapped
10. Comment out the code we have made so far except for the new Physics() line - use // or select and CTRL / in Atom.
Make a variable (var) called box and assign a new Rectangle() with a width parameter of 300 and height parameter of 300. Chain on the centerReg() method with stage as the parameter. Also chain on the mov() method with 0 and -50 as parameters to move the box up 50 pixels.
Make a variable (var) called box and assign a new Rectangle() with a width parameter of 300 and height parameter of 300. Chain on the centerReg() method with stage as the parameter. Also chain on the mov() method with 0 and -50 as parameters to move the box up 50 pixels.
Hahaha - wasn't that productive! In the first section we were just getting used to physics. Now, we are starting our app by making a present.
The present will have a box and wrapping.
The wrapping will be made of physics and mapped ZIM objects.
The box will be removed when we press on the wrapping.
HIGHLIGHT MORE ANSWER
11. ZIM Shapes have a colorCommand property. Call the linearGradient() method of the colorCommand property of the box.
This will make a gradient color on the shape when we pass in the many parameters:
The first parameter is an Array [ ] that holds the two colors we are transitioning between. Set the first color to frame.red and the second color to convertColor("crimson"). Separate the colors with a comma (,).
The second parameter is an Array with the decimal starting values for the gradient transition from 0-1. Set the first value of the array to .5 meaning there will be pure red from 0 to .5 of the distance. Set the second value to .9 which means there will be pure crimson from .9 to 1 of the distance.
The third and fourth parameters are the x and y starting point in the shape for the gradient distance. Set these to 0,0 which is at the left and top of the shape.
The fifth and sixth parameters are the x and y ending point in the shape for the gradient distance. Set these to 0,box.height which is at the left and bottom of the shape.
Check the app in the Browser to see if there is a shaded red box on the stage.
The first parameter is an Array [ ] that holds the two colors we are transitioning between. Set the first color to frame.red and the second color to convertColor("crimson"). Separate the colors with a comma (,).
The second parameter is an Array with the decimal starting values for the gradient transition from 0-1. Set the first value of the array to .5 meaning there will be pure red from 0 to .5 of the distance. Set the second value to .9 which means there will be pure crimson from .9 to 1 of the distance.
The third and fourth parameters are the x and y starting point in the shape for the gradient distance. Set these to 0,0 which is at the left and top of the shape.
The fifth and sixth parameters are the x and y ending point in the shape for the gradient distance. Set these to 0,box.height which is at the left and bottom of the shape.
Check the app in the Browser to see if there is a shaded red box on the stage.
The gradient methods only use hex colors in the format of #rrggbb (red, green, blue).
ZIM stores a bunch of colors as properties on the frame - such as frame.red.
These properties evaluate to hex colors - you can zog(frame.red) to see the value.
Crimson is not a hex color but rather an HTML color string.
We can use the ZIM convertColor() function to convert many HTML color strings to hex numbers.
HIGHLIGHT MORE ANSWER
ZIM Learn References
12. Make a variable (var) called wrapping and assign (=) a new Container()
with width and height parameters of stageW, stageH.
Chain to the container the addTo() method with a parameter of stage.
And also chain on the cur() method to set the cursor the "pointer" by default.
A Container is used to hold multiple objects. Containers have efficiency advantages.
For instance, we can animate or add and remove the container and all objects inside will adjust.
We can loop through containers or add events to containers and operate on their children.
HIGHLIGHT MORE ANSWER
In the next few steps we will prepare to make the wrappings.
We will have a vertical ribbon that is the height of the box.
We will have two shorter horizontal ribbons on either side of the vertical ribbon.
There will be a bow made of two circles at the top of the box.
All of these will be physics shapes that are mapped to ZIM shapes.
We could manually make and place all these shapes one after another. But a main principle of coding is Abstraction. Abstraction means to take out common code and put it in one place. This leads to efficiency and consistency.
We are going to abstract the making and mapping of the shapes to a loop function. What will be left are the specific details such as color, dimensions, position and shape. We will store common properties in variables and we will store values unique to each shape in an Array that we will access each time we loop.
Recognizing and using this type of procedure takes practice and will help you be a good coder.
13. Make the following variables with the var keyword:
We could manually make and place all these shapes one after another. But a main principle of coding is Abstraction. Abstraction means to take out common code and put it in one place. This leads to efficiency and consistency.
We are going to abstract the making and mapping of the shapes to a loop function. What will be left are the specific details such as color, dimensions, position and shape. We will store common properties in variables and we will store values unique to each shape in an Array that we will access each time we loop.
Recognizing and using this type of procedure takes practice and will help you be a good coder.
- wrapColor and assign (=) a value of frame.green
- bow and assign (=) a value of 50 for the bow radius
- ribbon and assign (=) a value of 40 for the ribbon thickness
- smallRibbon and assign (=) a value of (box.width-ribbon)/2
14. Make an Array [ ] called wrappingData that has FIVE elements separated by commas (,).
Each element will be an Array [ ] that represents one of the shapes we are making (three ribbon rectangles and two bow circles).
The first two elements of the shape arrays will be the width and height for rectangles - or radius and null if the shape is a circle.
The last two elements of the shape array will be the x and y positions of the shape. Here are the five arrays - remember to separate them with commas (,) in the outer wrappingData array:
- [ribbon, box.height, box.x, box.y]
- [smallRibbon, ribbon, box.x-(box.width-smallRibbon)/2, box.y]
- [smallRibbon, ribbon, box.x+(box.width-smallRibbon)/2, box.y]
- [bow, null, box.x-bow, box.y-box.height/2-bow]
- [bow, null, box.x+bow, box.y-box.height/2-bow]
The calculations in the arrays are basic x, y, width and height calculations, like the calculations in grade 3.
Note that all x and y calculations are from the center of the objects.
HIGHLIGHT MORE ANSWER
ZIM Learn References
15. Loop through the wrappingData array using the loop() function.
The first parameter is wrappingData.
The second parameter is function(){} - the function to run each time we loop.
With the ( ) of this function, collect a parameter called data that will be given the shape data by the loop function.
Inside the { } of the function, zog() the data to see the five arrays in the console (F12).
HIGHLIGHT MORE ANSWER
16 a) Make a Conditional using an if ( ) { } else { } statement.
In the ( ) test to see of there is something in the second element of the data array.
This would be if the shape were a Rectangle. Just use if (data[1])...
data[1] is the second element of the array because the index starts at 0.
16 b) if there is data in the second element, then in the first { }, make a physics body rectangle and a ZIM Rectangle:
16 b) if there is data in the second element, then in the first { }, make a physics body rectangle and a ZIM Rectangle:
- Make a variable body and assign (=) the results of physics.makeRectangle()
- Pass a parameter of {width:data[0], height:data[1], dynamic:false, angular:2, density:5}
- This is called a Configuration Object with property:value using the ZIM DUO technique.
- The width and height are based on the data at positions 0 and 1 (the width and height in the shape array).
- The physics body is set to be NOT dynamic so it initially will not move - we will change that later.
- The angular friction is set to 2 so that it is a little slower than normal (1) to rotate.
- The density is set to 5 so that it is harder than normal (1) to move.
- Make a variable shape and assign (=) a new Rectangle()
- Pass parameters of data[0], data[1], wrapColor
- Chain on a centerReg() method with a parameter of wrapping
- Note that we are centering it on wrapping and not the stage.
- Make a variable body and assign (=) the results of physics.makeCircle()
- Pass a parameter of {radius:data[0], dynamic:false, angular:2, density:5}
- The radius is based on the data at position 0 (the radius in the shape array).
- The physics body is set to be NOT dynamic so it initially will not move - we will change that later.
- The angular friction is set to 2 so that it is a little slower than normal (1) to rotate.
- The density is set to 5 so that it is harder than normal (1) to move.
- Make a variable shape and assign (=) a new Circle()
- Pass parameters of data[0], wrapColor
- Chain on a centerReg() method with a parameter of wrapping
- Note that we are centering it on wrapping and not the stage.
17 a) ABOVE the loop from step 15 create a variable (var) called wrappingBodies and assign (=) an empty Array, [ ].
This will hold the physics bodies that we want to drag, as later, there will be physics objects that we do not drag.
17 b) INSIDE, at the bottom of the loop function, add the body to the wrappingBodies array by using the JavaScript push() method. Put the array object first (wrappingBodies) followed by the dot (.) and the method push() and pass body as its parameter.
17 c) Assign (=) the third and fourth element of the data array to the body's x and y property using the dot (.) syntax. Remember that arrays start their index number at 0 so that will be data[2] and data[3]. This will position the physics body at the desired location.
17 d) Map the ZIM shape to the physics body using the addMap() method of physics. Put the object first (physics), then the dot (.) followed by the method (addMap()) and pass in parameters of body and shape separated by a comma (,).
17 e) Test in a Browser and we should now have a wrapped present.
17 b) INSIDE, at the bottom of the loop function, add the body to the wrappingBodies array by using the JavaScript push() method. Put the array object first (wrappingBodies) followed by the dot (.) and the method push() and pass body as its parameter.
17 c) Assign (=) the third and fourth element of the data array to the body's x and y property using the dot (.) syntax. Remember that arrays start their index number at 0 so that will be data[2] and data[3]. This will position the physics body at the desired location.
17 d) Map the ZIM shape to the physics body using the addMap() method of physics. Put the object first (physics), then the dot (.) followed by the method (addMap()) and pass in parameters of body and shape separated by a comma (,).
17 e) Test in a Browser and we should now have a wrapped present.
To summarize, in an outer array, we created data arrays to specify only the unique (specific) aspects of dimension and position for each part of the wrapping.
We then looped through the outer array and did all the abstracted (general) things that are common to building and mapping.
We created a physics body and shape based on the data array.
The wrapping bodies had their dynamic parameters set to false so they currently do not move.
We placed the wrapping shape at the location of the physic body using the addMap() method of the ZIM physics_0.1.2 module.
A little more on abstraction, it may seem that the data was abstracted from the general functionality as the data is placed above and comes first. But it is actually the other way around - the common functionality is abstracted and is more abstract. Adding to confusion is that a Number is a very abstract. Numbers represent a way to measure our dimensions and generally, everything that exists. So it is tempting to argue that the numbers were abstracted from the functionality and are more abstract. The problem with this argument is that the numbers we are left with after abstracting the common functionality, are for specific purposes. It is more clear to think of abstraction as abstracting things in common (common factors - factoring). This leads to efficiency and consistency because we are not repeating. We are not abstracting the numbers for the number's sake - that would lead to Chaos.
Functions (and their guises of classes and loops) are tools for abstraction. The general aspects are in the function and the specific aspects are passed in as parameters or taken from some sort of input. This could be user input or data stored in variables or arrays.
HIGHLIGHT MORE ANSWER
A little more on abstraction, it may seem that the data was abstracted from the general functionality as the data is placed above and comes first. But it is actually the other way around - the common functionality is abstracted and is more abstract. Adding to confusion is that a Number is a very abstract. Numbers represent a way to measure our dimensions and generally, everything that exists. So it is tempting to argue that the numbers were abstracted from the functionality and are more abstract. The problem with this argument is that the numbers we are left with after abstracting the common functionality, are for specific purposes. It is more clear to think of abstraction as abstracting things in common (common factors - factoring). This leads to efficiency and consistency because we are not repeating. We are not abstracting the numbers for the number's sake - that would lead to Chaos.
Functions (and their guises of classes and loops) are tools for abstraction. The general aspects are in the function and the specific aspects are passed in as parameters or taken from some sort of input. This could be user input or data stored in variables or arrays.
ZIM Learn References
18. Place an on() method on the wrapping container to capture a "mousedown" event as the first parameter
and run a function(){} as the second parameter.
We are going to capture this event only once - so set the third parameter to null
and the fourth parameter to true.
This tells the CreateJS on() method to only capture the event and run the function once!
Inside the function (between the { }), zog() the string "once"
and test in a browser by clicking the wrapping and checking the console (F12) for the string to show.
HIGHLIGHT MORE ANSWER
ZIM Learn References
An object literal { } is a structure that holds properties and their values.
The syntax of an object literal is to add the property followed by a colon (:) and then the value.
Multiple properties are separated by a comma (,). These all go between the curly braces { }.
For example:
var obj = {prop:"value", prop2:"value"};
We saw an object literal when we used a configuration object and the ZIM DUO technique in step 16. In this step, we use it to say what properties we would like to animate inside the ZIM animate() method.
19. Use the animate() method of the box
to fade out the box. The first parameter of animate is an animation object literal { }
that holds the properties that we want to animate.
In this case the property is the alpha and the value is 0.
Start with the object to animate (box) then a dot (.) and the method (animate())
and pass {alpha:0} as the first parameter
followed by a comma (,) and then 1000 as the second parameter
which is the time in milliseconds (ms) for the animation to run. There are many parameters for animate!
HIGHLIGHT MORE ANSWER
var obj = {prop:"value", prop2:"value"};
We saw an object literal when we used a configuration object and the ZIM DUO technique in step 16. In this step, we use it to say what properties we would like to animate inside the ZIM animate() method.
20 a) INSIDE the mousedown event function, loop() through the wrappingBodies and set each body to be dynamic - which allows it to move and receive forces.
Put the loop() function there with the first parameter being the wrappingBodies array
and the second parameter being function(){}.
Each body in the array is then passed to the function so receive it in the ( ) with a body parameter.
This is us collecting the parameter not sending parameter.
As such, we can name the parameter what we want - and body makes sense, as each time we loop
it will give us one of the physics bodies that were store in the array in part 17 b).
20 b) INSIDE the loop function { } use the SetType() method of the body to change the type of the body to dynamic. Put the object first (body) followed by the dot (.) and then the method SetType(). Unfortunately, Box2D methods start with capital letters which is not our usual convention. Pass in the parameter of b2Body.b2_dynamicBody which is a constant stored on the b2Body class. A constant is like a variable but it represents something that will not change. We tend not to use constants in JS5 but usually, they are all UPPERCASE.
20 c) Test the app in a Browser and now the wrapping objects should fall when they are pressed.
HIGHLIGHT MORE ANSWER
20 b) INSIDE the loop function { } use the SetType() method of the body to change the type of the body to dynamic. Put the object first (body) followed by the dot (.) and then the method SetType(). Unfortunately, Box2D methods start with capital letters which is not our usual convention. Pass in the parameter of b2Body.b2_dynamicBody which is a constant stored on the b2Body class. A constant is like a variable but it represents something that will not change. We tend not to use constants in JS5 but usually, they are all UPPERCASE.
20 c) Test the app in a Browser and now the wrapping objects should fall when they are pressed.
HIGHLIGHT MORE ANSWER
21. Set the wrapping bodies to drag using the drag() method of physics.
Put the object first (physics) and dot (.) the method (drag()) with a parameter of wrappingBodies.
If you pass no parameter, all physics objects will drag.
Here, we want only the wrapping bodies to drag as we are about to add physics balls that will not be draggable.
HIGHLIGHT MORE ANSWER
ZIM Learn References
22. INSIDE the mousedown event at the bottom of the event function, add a call to a makeBalls() function.
Define the makeBalls function below underneath the drag() method.
Leave some new lines in between as this is the start of a new section -
perhaps give it a commented // ~~~~~~~~ BALLS or some such divider title.
Under that, create a function using the function keyword followed by the function name (makeBalls)
and ( ) and then the function body { }.
Inside the body { } zog() "making balls"
CLAIM YOUR BADGE
This is the end of the second Badge! Congrats - it was a long one - good job getting here.
Claim you badge and show your friends, family, teacher, guru, etc.
HIGHLIGHT MORE ANSWER
ZIM Learn References
(SHOW YOUR TEACHER)