Cannon Ball! is a game I created that stemmed from a tutorial found in the book "The Essential Guide to HTML5". It's your typical Cannon shoots target game play. You control the cannon's angle & velocity with the arrow keys, and press space-bar to shoot. You have 5 chances to hit the grey square with your cannonball. The levels go on forever and you're given a score which adds up until you fail to hit the target in 5 tries.
Game Link: Cannon Ball!
Feel free to provide feedback such as bugs, or additions you'd like to see. Or just ask questions about my source and I'll answer them here.
Thinks I'd like to add:
- Fix issue where ball collision isn't detected well.
- High Score list.
- A reset button after you lose.
- On-screen score & instructions for manipulating the cannon.
var ctx,
myBall,
myCannon,
physics,
everything = [],
targets = [],
shotsLeft = [],
shot = 0,
gravity = 0.5,
velocity = 10,
score = 0,
inMotion = false,
level = 0;
/**
* DtoR - Degrees to Radian conversion
* @param degrees
* @returns radian equivilant
*/
function DtoR(degrees){
var radians = degrees * (Math.PI/180);
return radians;
}
/**
* Cannon
* @param sx - Bottom left corner X coord
* @param sy - Bottom left corner Y coord
* @param angle - Starting angle of cannon
* @param stylestring - "rgb(250,50,50)"
*/
function Cannon(sx, sy, angle, stylestring){
this.sx = sx;
this.sy = sy;
this.length = 100;
this.width = 25;
this.angle = angle;
this.fillStyle = stylestring;
this.draw = function(){
ctx.fillStyle = this.fillStyle;
ctx.save();
ctx.translate(this.sx,this.sy);
ctx.rotate(DtoR(-1 * (this.angle + 90))); //The minus one is to reverse the angle.
ctx.translate(-this.sx,-this.sy);
ctx.fillRect(this.sx,this.sy,this.width, this.length);
ctx.restore();
//Base of cannon
ctx.fillRect(this.sx-30,this.sy-30,50,60);
}
this.rotate = function(angle){
this.angle = angle || 30;
}
this.getAngle = function(){
return this.angle;
}
}
function Myrectangle(sx,sy,swidth,sheight,stylestring) {
this.sx = sx;
this.sy = sy;
this.swidth = swidth;
this.sheight = sheight;
this.fillstyle = stylestring;
this.draw = function drawrects() {
ctx.fillStyle = this.fillstyle;
ctx.fillRect(this.sx,this.sy,this.swidth,this.sheight);
};
}
function Ball(sx, sy, rad, stylestring){
this.sx = sx; //Starting X coord
this.sy = sy; //Starting Y coord
this.rad = rad; //Radius
this.fillstyle = stylestring;
this.draw = function(){
ctx.fillStyle = this.fillstyle;
ctx.beginPath();
ctx.arc(this.sx, this.sy, this.rad, 0, Math.PI*2, true);
ctx.fill();
};
this.moveit = function(dx, dy){
this.sx = this.sx + dx; //Increment X coord
this.sy = this.sy + dy; //Increment Y coord
};
}
function init(){
var canvas = document.getElementById('CannonBallCanvas');
if (canvas.getContext){
ctx = canvas.getContext('2d');
}
// Create Ground
ground = new Myrectangle(0,470,900,30,"rgb(154,205,0)");
everything.push(ground);
// Create Cannon Ball
myBall = new Ball(55, 460, 10, "rgb(250,0,0)");
everything.push(myBall);
// Create Cannon
myCannon = new Cannon(50, 450, 40, "rgb(150,105,105)");
everything.push(myCannon);
resetShotsLeft()
generateTargets();
//Draw our Canvas
redrawCanvas();
}
function reset(){
//Erase Canvas
ctx.clearRect(0,0,900,500);
resetShotsLeft()
generateTargets();
//Reset Cannon Ball
myBall.sx = 55;
myBall.sy = 460;
redrawCanvas();
}
function resetShotsLeft(){
// Shots Left
var startingX = 890;
shotsLeft.length = 0;
for(var i=1; i=target.sx) && (bx=target.sy)&&(by= target.sx) && ( bx-br =target.sy)&&(by-br=ground.sy) {
inMotion = false;
clearInterval(tid);
shotsLeft.pop(); //Remove a shot
if(shotsLeft.length < 1){ showYouLose(); return; } } redrawCanvas(); } function setVelocity(vel){ velocity = parseInt(vel); $("#vo").val(velocity); } $(function(){ init(); //setup Input events $("#vo").change(function(){ //Update the Velocity velocity = parseInt(this.value); }); $("#ang").change(function(){ //Update the angle myCannon.rotate(parseInt(this.value)); redrawCanvas(); }); $("#ang").val(myCannon.angle); //Set UI to initial angle $("#fire").click(function(){ if(shot > 2){
fire();
}
})
//Track arrow keystrokes
$(document).keydown(function(e){
var keyCode = e.keyCode;
if(inMotion === true){
return;
}
switch (keyCode){
case 37:
//console.log("Left");
//Lower velocity
setVelocity(velocity-1);
break;
case 38:
//console.log("Up");
//Raise angle
myCannon.rotate(myCannon.angle+1);
$("#ang").val(myCannon.angle+1);
redrawCanvas();
break;
case 39:
//console.log("right");
//increase velocity
setVelocity(velocity+1);
break;
case 40:
//console.log("down");
//Lower Angle
myCannon.rotate(myCannon.angle-1);
$("#ang").val(myCannon.angle-1);
redrawCanvas();
break;
case 32:
//console.log("Fire");
fire();
break;
}
});
});</pre>
