Cannonball: with cannon, angle, and speed

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

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.

119

Function Invoked By / Called By Calls

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

Picture Invoked directly by code in var statements drawAnImage Invoked by call of the draw method for a Picture

object

Table 4-4 shows the complete code for the second application, but only the changed lines have comments.

Table 4-4. The Second Cannonball Application

Code Explanation

<html>

<head>

<title>Cannonball</title>

<style>

form { width:330px;

margin:20px;

background-color:brown;

padding:20px;

}

</style>

<script type="text/javascript">

var cwidth = 600;

120

Code Explanation

var cheight = 400;

var ctx;

var everything = [];

var tid;

var horvelocity;

var verticalvel1;

var verticalvel2;

var gravity = 2;

var cannonx = 10; x location of cannon var cannony = 280; y location of cannon var cannonlength = 200; Cannon length (i.e., width)

var cannonht = 20; Cannon height

var ballrad = 10;

var targetx = 500; x position of target var targety = 50; y position of target

var targetw = 85; Target width

var targeth = 280; Target height

var htargetx = 450; x position of the hit target var htargety = 220; y position of the hit target var htargetw = 355; Hit target width

var htargeth = 96; Hit target height

121

Code Explanation

function Ball(sx,sy,rad,stylestring) { this.sx = sx;

this.sy = sy;

this.rad = rad;

this.draw = drawball;

this.moveit = moveball;

this.fillstyle = stylestring;

}

function drawball() {

ctx.fillStyle=this.fillstyle;

ctx.beginPath();

//ctx.fillStyle= rgb(0,0,0);

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

ctx.fill();

}

function moveball(dx,dy) { this.sx +=dx;

this.sy +=dy;

}

var cball = new Ball(cannonx+cannonlength, cannony+cannonht*.5,ballrad,"rgb(250,0,0)");

122

Code Explanation

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

this.sx = sx;

this.sy = sy;

this.swidth = swidth;

this.sheight = sheight;

this.fillstyle = stylestring;

this.draw = drawrects;

this.moveit = moveball;

}

function drawrects() {

ctx.fillStyle = this.fillstyle;

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

}

function Picture (sx,sy,swidth, sheight,filen) {

Header for function to set up Picture object

var imga = new Image(); Create an Image object

imga.src=filen; Set the file name

this.sx = sx; Set the sx property

this.sy = sy; … sy

this.img = imga; Set the img property to imga this.swidth = swidth; … swidth

123 Code Explanation

this.sheight = sheight; … sheight

this.draw = drawAnImage; … draw. This will be the draw method for objects of this type.

this.moveit = moveball; … This will be the moveit method. Not used.

} Close Picture function

function drawAnImage() { Header for drawAnImage function ctx.drawImage(this.img,this.sx,

this.sy,this.swidth,this.sheight);

Draw image using properties of this object

} Closes function

var target = new Picture(targetx,targety, targetw,targeth,"hill.jpg");

Construct new Picture object and assign to target variable

var htarget = new Picture(htargetx,

htargety, htargetw, htargeth, "plateau.jpg");

Construct new Picture object and assign to htarget variable

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

Construct new Myrectangle object and assign to ground

var cannon = new Myrectangle(cannonx,

cannony,cannonlength,cannonht,"rgb(40,40,0)");

Construct new Myrectangle object and assign to cannon

var targetindex = everything.length; Save what will be the index for target everything.push([target,false]); Add target to everything

everything.push([ground,false]); Add ground to everything

var ballindex = everything.length; Save what will be the index for cball everything.push([cball,false]); Add cball to everything

var cannonindex = everything.length; Save what will be the index for cannon everything.push([cannon,true,0,

cannonx,cannony+cannonht*.5]);

Add cannon to everything; reserve space for rotation

124

Code Explanation

function init(){

ctx = document.getElementById ('canvas').getContext('2d');

drawall();

}

function fire() {

var angle = Number(document.f .ang.value);

Extract angle from form, convert to number

var outofcannon = Number (document.f.vo.value);

Extract velocity out of cannon from form, convert to number

var angleradians = angle*Math .PI/180;

Convert to radians

horvelocity = outofcannon*Math .cos(angleradians);

Compute horizontal velocity

verticalvel1 = - outofcannon*Math .sin(angleradians);

Compute initial vertical velocity

everything[cannonindex][2]=

- angleradians;

Set information to rotate cannon

cball.sx = cannonx +

cannonlength*Math.cos(angleradians);

Set x for cball at mouth of what will be rotated cannon

cball.sy = cannony+cannonht*.5 - cannonlength*Math.sin(angleradians);

Set y for cball at mouth of what will be rotated cannon

drawall();

tid = setInterval(change,100);

return false;

125

Code Explanation

}

function drawall() {

ctx.clearRect(0,0,cwidth,cheight);

var i;

for (i=0;i<everything.length;i++) {

var ob = everything[i]; Extract array for object if (ob[1]) { Need to translate and rotate?

ctx.save(); Save original axes

ctx.translate(ob[3],ob[4]); Do indicated translation ctx.rotate(ob[2]); Do indicated rotation ctx.translate(-ob[3],-ob[4]); Translate back

ob[0].draw(); Draw object

ctx.restore(); } Restore axes

else { Else (no rotation)

ob[0].draw();} Do drawing

} Close for loop

} Close function

function change() {

var dx = horvelocity;

verticalvel2 =verticalvel1 + gravity;

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

126

Code Explanation

verticalvel1 = verticalvel2;

cball.moveit(dx,dy);

var bx = cball.sx;

var by = cball.sy;

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

(by>=target.sy)&&(by<=(target .sy+target.sheight))) {

clearInterval(tid);

everything.splice (targetindex,1,[htarget,false]);

Remove target and insert htarget

everything.splice (ballindex,1);

Remove the ball

drawall();

}

if (by>=ground.sy) {

clearInterval(tid);

}

drawall();

}

</script>

</head>

<body onLoad="init();">

127

Code Explanation

<canvas id="canvas" width="600"

height="400">

Your browser doesn't support the HTML5 element canvas.

</canvas>

<br/>

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

"return fire();">

Set velocity, angle and fire cannonball. <br/>

Velocity out of cannon <input name=

"vo" id="vo" value="10" type=

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

Label indicating that this is the velocity out of mouth of cannon

<br>

Angle <input name="ang" id="ang"

value="0" type="number" min=

"0" max="80"/>

Label indicating that this is the angle of the cannon

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

</form>

</body>

</html>

This application provides many possibilities for you to make it your own. You can change the cannon, the ball, the ground, and the target. If you don't want to use images, you can use drawings for the target and the hit target. You can draw other things on the canvas. You just need to make sure that the cannonball (or whatever you set your projectile to be) is on top or wherever you want it to be. You could, for example, make the ground cover up the ball. You can use an animated gif for any Image object, including the htarget. You could also use images for the cannon and the ball. One possibility is to use an animated gif file to represent a spinning cannonball. Remember that all image files referenced in the code must be in the same folder as the uploaded HTML file. If they are in a different place on the Web, make sure the reference is correct.

128

The support for audio and video in HTML5 varies across the browsers. You can look ahead to the presentation of video as a reward for completing the quiz in Chapter 6, and to the audio presented as part of the rock-paper-scissors game in Chapter 8. If you want to tackle this subject, it would be great to have a sound when the cannonball hits the target and a video clip showing the target exploding.

Moving away from the look of the game, you can invent a scoring system, perhaps keeping track of attempts versus hits.

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