I'm pretty close to finish this program using Canvas. This program is simply a ball that falls down from top to bottom and there's a basket that catches it, that is it. However, I have the following issues.
1) When I press the left or right arrows from keyboard for more than couple of times somehow the basket will go all the way to either left or right and disappear.
2) When the ball hits the basket nothing happens (my Collision detection function doesn't work properly). However, I should say that my collision detection works just fine when the balls hits the ground (alert message shows up saying "Ball hit the ground").
Is there a way to show a message on the top of the canvas like "1 point" every time the basket catches a ball ( if there are 5 balls then I should get a message to say "5 points")
Can someone tell me what I am doing wrong please? Thank you so much in advance!!
LIVE CODE HERE
http://codepen.io/HenryGranados/pen/QNOZRa
Here's my code :
//create the constructor for the class pad
function Pad() {
//initialisation code will go here
//create private variables for the x and y coordinates
var x = 200,
y = 200,
vx = 0,
vy = 0,
padX = (canvas.width - 20) / 2;
rightPressed = false,
leftPressed = false;
//create the draw function to give us the draw method
//it accepts one parameter which is the context from the canvas it is drawn on
Pad.prototype.draw = function (context) {
//save the state of the drawing context before we change it
context.save();
//set the coordinates of the drawing area of the new shape to x and y
context.translate(x, y);
//start the line (path)
context.beginPath();
context.fillStyle = "#800000"; // This is the basket
context.moveTo(15, 20);
context.bezierCurveTo(20, 100, 150, 100, 150, 20);
//close the path
context.closePath();
context.fill();
//go ahead and draw the line
context.stroke();
//restore the state of the context to what it was before our drawing
context.restore();
}
//create a public property called X (note caps!)
Object.defineProperty(this, 'X',
{
//getter
get: function () {
//return the value of x (lower case)
return x;
},
//setter
set: function (value) {
//ste the value of x (lower case)
x = value;
}
}
)
//create a public property called Y (note caps!)
Object.defineProperty(this, 'Y',
{
//getter
get: function () {
//return the value of y (lower case)
return y;
},
//setter
set: function (value) {
//ste the value of y (lower case)
y = value;
}
}
)
padX = function () {
if (rightPressed && padX < canvas.width - 20) {
padX += 5;
}
else if (leftPressed && padX > 0) {
padX -= 5;
}
}
Pad.prototype.move = function () {
//change the x axis by the x velocity
x += vx;
//change the y axis by the y velocity
y += vy;
}
Pad.prototype.setVector = function (vector) {
//set the vx value based on this vector
vx = vector.VX;
//set the vy value based on this vector
vy = vector.VY;
}
//public method to set the vector of the saucer
Pad.prototype.accelerate = function (Acceleration) {
//set vx
vx += Acceleration.AX;
////set vy
//vy += Acceleration.AY;
}
//create a public property called Top
Object.defineProperty(this, 'Top',
{
//getter
get: function () {
//return the y posn less the height
return y - 10;
}
}
)
//create a public property called Bottom
Object.defineProperty(this, 'Bottom',
{
//getter
get: function () {
//return the y posn plus the height
return y + 10;
}
}
)
//create a public property called Left
Object.defineProperty(this, 'Left',
{
//getter
get: function () {
//return the x posn less the width
return x - 80;
}
}
)
//create a public property called Right
Object.defineProperty(this, 'Right',
{
//getter
get: function () {
//return the x posn plus the width
return x + 80;
}
}
)
}
(1) There are at least two options to solve this problem
in your Pad.move
function you could limit the change of x
. You change it only when its within canvas width:
Pad.prototype.move = function() {
//change the x axis by the x velocity
var canvasWidth = 400,
padWidth = 150;
if (x + vx < canvasWidth - padWidth && x + vx >= 0)
x += vx;
//change the y axis by the y velocity
y += vy;
}
or similarly as you create ground you could create walls on both sides and collide pad
with them.
(2) There is no collision handling between ball and pad:
place it in function drawFrame()
:
if (collision.Overlapping(ball, pad)) {
context.strokeText('ball hit pad!',20,100)
//..do some other stuff here
}
(3)Which brings us to showing message on canvas, you can just draw text on canvas
var ctx = canvas.getContext("2d");
ctx.font = "30px Arial";
ctx.fillText("Hello World",10,50);
Demo: http://codepen.io/anon/pen/RaxwLp?editors=1011 Pad was blocked because when key is pressed acceleration is always increased, so in order to move in opposite direction first it must go to 0 which takes quite some time. I have added keyup event and when key is released acceleration is zeroed:
if(leftPressed){
acceleraton.HThrust(.01);
}else if(rightPressed){
acceleraton.HThrust(-.01);
}else{
acceleraton.Halt();
}