Distance between points

In document Using Games to Learn HTML5 and JavaScript (Page 126-134)

There are two places in the slingshot program in which I use the distance between points or, more accurately, the square of the distance. I need to find out if the mouse cursor is on top of the ball and I want to make the initial velocity—the equivalent of the velocity out of the cannon— depending on the stretch, so to speak, of the slingshot, the distance (bx,by) to (s1x, s1y). The formula for the distance between two points x1,y1 and x2,y2 is the square root of the sum of the squares of (x1-x2) and (y1-y2). I decided to avoid the computation of taking a square root by just computing the sum of the squares. This provides the same test for the mouse cursor being on top of the ball. For the other task, I decided it was okay to use the

111 square of the distance for the initial velocity. I experimented with some numbers and, as I mentioned earlier, 700 seemed to work.

Building the application and making it your own

Lets now take a look at the code for the basic firing of a cannonball, without a cannon, based on horizontal and initial vertical speeds; the firing of a cannonball from a cannon, based on angle and initial speed out of the cannon; and the slingshot, based on angle and initial speed determined from the position of the mouse. As in previous chapters, Ill present the functions and what they call or are called by for each application. In this case, the tables are similar, though not identical, for all three applications. The calling is more varied than previous examples in that there are situations in which functions are invoked because they are named as methods of a programmer-defined object or as part of a declaration (var) statement. This is a characteristic of object-oriented, event-driven programming. Ill also present the complete code for each application in its own table, along with an explanation of what each line does.

Table 4-1 shows the functions for the basic cannonball application.

Table 4-1. Functions in the Simplest Cannonball Application

Function Invoked By / Called By Calls

init Action of the onLoad in body tag drawall drawall Invoked directly by init,

fire, change

Calls the draw method of all objects in the everything array. These are the functions drawball, drawrects.

fire Invoked by action of the onSubmit attribute in form

drawall

change Invoked by action of the setInterval function called in fire

drawall, calls the moveit method of cball, which is moveball

Ball Invoked directly by code in a var statement Myrectangle Invoked directly by code in a var statement drawball Invoked by call of the draw method for the

one Ball object

drawrects Invoked by call of the draw method for the target object

moveball Invoked by call of the moveit method for the one Ball object

112

Table 4-2 shows the complete code for the simplest application, with the ball moving in an arc and no actual cannon.

Table 4-2. The First Cannonball Application

Code Explanation

<html> Opening html tag

<head> Opening head tag

<title>Cannonball</title> Complete title element

<style> Opening style tag

form { Style for the form

width:330px; Width

margin:20px; External margin

background-color:brown; Color

padding:20px; Internal padding

} Close this style

</style> Close style element

<script> Opening script tag

var cwidth = 600; Set value for width of canvas, used for clearing var cheight = 400; Set value for height of canvas, used for clearing var ctx; Variable to hold canvas context

var everything = []; Array to hold all objects to be drawn. Initialized as an empty array

var tid; Variable to hold identifier for the timing event var horvelocity; Variable to hold the horizontal velocity (aka

displacement)

113 Code Explanation

var verticalvel1; Variable to hold vertical displacement at start of interval var verticalvel2; Variable to hold vertical displacement at end of interval,

after change by gravity

var gravity = 2; Amount of change in vertical displacement. Arbitrary.

Makes for a nice arc.

var iballx = 20; Initial horizontal coordinate for the ball var ibally = 300; Initial vertical coordinate for the ball

function Ball(sx,sy,rad,stylestring) { Start of function to define a Ball. object. Use the parameters to set the properties.

this.sx = sx; Set the sx property of THIS object

this.sy = sy; …sy

this.rad = rad; …rad

this.draw = drawball; …draw. Since drawball is the name of a function, this makes draw a method that can be invoked

this.moveit = moveball; …moveit set to the function moveball this.fillstyle = stylestring; …fillstyle

} Close the Ball function

function drawball() { Header for the drawball function

ctx.fillStyle=this.fillstyle; Set up the fillStyle using the property of this object ctx.beginPath(); Start a path

ctx.arc(this.sx,this.sy ,this.rad,0,Math.PI*2,true);

Set up to draw a circle

ctx.fill(); Draw the path as a filled path

114

Code Explanation

} Close the function

function moveball(dx,dy) { Header for the moveball function this.sx +=dx; Increment the sx property by dx this.sy +=dy; Increment the sy property by dy

} Close function

var cball = new Ball(iballx,ibally, 10,"rgb(250,0,0)");

Create a new Ball object at the indicated position, radius, and color. Assign it to the variable cball. Note that nothing is drawn at this time. The information is just set up for later use.

function Myrectangle(sx,sy,swidth, sheight,stylestring) {

Header for function to construct a Myrectangle object

this.sx = sx; Sets the sx property of THIS object

this.sy = sy; …sy

this.swidth = swidth; …swidth this.sheight = sheight; …sheight this.fillstyle = stylestring; …stylestring

this.draw = drawrects; … draw. This sets up a method that can be invoked.

this.moveit = moveball; ….moveit. This sets up a method that can be invoked.

It is not used in this program.

} Close Myrectangle function

function drawrects() { Header for drawrects function ctx.fillStyle = this.fillstyle; Set the fillStyle

ctx.fillRect(this.sx,this.sy, this.swidth,this.sheight);

Draw the rectangle using the object properties

} Close function

115 Code Explanation var target = new Myrectangle(300,100,

80,200,"rgb(0,5,90)");

Build a Myrectangle object and assign to target

var ground = new Myrectangle(0,300, 600,30,"rgb(10,250,0)");

Build a Myrectangle object and assign to ground

everything.push(target); Add target to everything everything.push(ground); Add ground

everything.push(cball); Add cball (which will be drawn last, so on top of other stuff

function init(){ Header for init function ctx = document.getElementById

('canvas').getContext('2d');

Set up ctx in order to draw on the canvas

drawall(); Draw everything

} Close init

function fire() { Head for fire function

cball.sx = iballx; Reposition cball in x cball.sy = ibally; Reposition cball in y horvelocity = Number(document.

f.hv.value);

Set horizontal velocity from form. Make a number

verticalvel1 = Number(document.

f.vv.value);

Set initial vertical velocity from form

drawall(); Draw everything

tid = setInterval (change,100);

Start timing event

return false; Return false to prevent refresh of HTML page

} Close function

116

Code Explanation

function drawall() { Function header for drawall ctx.clearRect

(0,0,cwidth,cheight);

Erase canvas

var i; Declare var i for the for loop for (i=0;i<everything.length;i++)

{

For each item in everything array…

everything[i].draw();} …invoke the object's draw method. Close for loop.

} Close function

function change() { Header for change function var dx = horvelocity; Set dx to be horvelocity verticalvel2 =

verticalvel1 + gravity;

Compute new vertical velocity (add gravity)

var dy = (verticalvel1 + verticalvel2)*.5;

Compute average velocity for the time interval

verticalvel1 = verticalvel2; Now set old to be new

cball.moveit(dx,dy); Move cball computed amount var bx = cball.sx; Set bx to simplify the if var by = cball.sy; ... and by

if ((bx>=target.sx)&&(bx<=

(target.sx+target.swidth))&&

Is the ball within the target horizontally…

(by>=target.sy)&&(by<=

(target.sy+target.sheight))) {

and vertically?

clearInterval(tid); If so, stop motion

} Close if true clause

if (by>=ground.sy) { Is the ball beyond ground?

117 Code Explanation

clearInterval(tid); If so, stop motion

} Close if true clause

drawall(); Draw everything

} Close change function

</script> Close script element

</head> Close head element

<body onLoad="init();"> Open body and set call to init

<canvas id="canvas" width=

"600" height="400">

Define canvas

Your browser doesn't support the HTML5 element canvas.

Warning to users of non-compliant browsers

</canvas> Close canvas

<br/> Line break

<form name="f" id="f"

onSubmit="return fire();">

Starting form tag, with name and id. This sets up call to fire.

Set velocities and fire cannonball. <br/>

Label and line break

Horizontal displacement <input name=

"hv" id="hv" value="10" type=

"number" min="-100" max="100" />

Label and specification of input field

<br> Line break

Initial vertical displacement <input name="vv" id="vv" value="-25"

type="number" min="-100" max="100"/>

Label and specification of input field

<input type="submit" value="FIRE"/> Submit input element

</form> Close form element

118

Code Explanation

</body> Close body element

</html> Close html element

You certainly can make improvements to this application, but it probably makes more sense to first make sure you understand it as is and then move on to the next.

In document Using Games to Learn HTML5 and JavaScript (Page 126-134)