Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I'm trying to figure out how to stop this particle system after 30 seconds. Is there a way for it to stop cold, so the particles freeze where they are? And is there alternate way for the particles to die out, so that any particle that has already started completes it's path off screen?
I'm not an advanced coder and found this system online, I appreciate any help. Thanks.
var INTENSITY = 200;
(function(ns) {
ns = ns || window;
function ParticleSystem(ctx, width, height, intensity) {
this.particles = [];
intensity = intensity;
this.addParticle = function() {
this.particles.push(new Snow(ctx, width));
}
while (intensity--) {
this.addParticle();
}
this.render = function() {
ctx.save();
ctx.clearRect(0,0,width,height);
for (var i = 0, particle; particle = this.particles[i]; i++) {
particle.render();
}
ctx.restore();
}
this.update = function() {
for (var i = 0, particle; particle = this.particles[i]; i++) {
particle.x += particle.vx;
particle.y += particle.vy + 1;
if (particle.y > height - 1) {
particle.vx = 0;
particle.vy = 0;
particle.y = height;
if (particle.killAt && particle.killAt < +new Date) this.particles.splice(i--, 1);
else if (!particle.killAt) {
particle.killAt = +new Date + 5000;
this.addParticle();
}
}
}
}
}
function Snow(ctx, width) {
this.vx = ((Math.random() - 0.5) * 5);
this.vy = (Math.random() * 4) + 0.25;
this.x = Math.floor((Math.random() * width));
this.y = -Math.random() * 30;
this.alpha = (Math.random() * 0.99) + 0.15;
this.radius = Math.random() * 3;
this.color = 'rgba(255,255,255,1)';
this.render = function() {
ctx.globalAlpha = this.alpha;
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.fill();
}
}
ns.precCanvas = function() {
var myCanvas = document.getElementById('myCanvas');
var ctx = myCanvas.getContext('2d');
var width = myCanvas.width = 300;
var height = myCanvas.height = 610;
var particleSystem = new ParticleSystem(ctx, width, height, INTENSITY);
(function draw() {
requestAnimationFrame(draw);
particleSystem.update();
particleSystem.render();
})();
}
})(window);
precCanvas();
You'll need to store the animationId returned by requestAnimationFrame and then at a later time stop the animation. Replace your precCanvas function with this:
ns.precCanvas = function() {
var myCanvas = document.getElementById('myCanvas');
var ctx = myCanvas.getContext('2d');
var width = myCanvas.width = 300;
var height = myCanvas.height = 610;
var particleSystem = new ParticleSystem(ctx, width, height, INTENSITY);
var animationId;
function draw() {
animationId = requestAnimationFrame(draw);
particleSystem.update();
particleSystem.render();
}
function stop() {
window.cancelAnimationFrame(animationId);
}
setTimeout(stop, 30 * 1000);
draw();
}
A working fiddle here.
Related
Please check out this code :
(function() {
var cnv = document.getElementById('canvas');
if (cnv.getContext) {
var ctx = cnv.getContext('2d');
} else {
alert('God Damn it ...');
}
function initialize() {
window.addEventListener('resize', resizeCanvas, false);
resizeCanvas();
}
function draw() {
for (var i = 0; i < 25; i++) {
width = Math.random() * cnv.width;
height = Math.random() * cnv.height;
ctx.beginPath();
ctx.arc(width, height, 15, 0, Math.PI * 2);
ctx.strokeStyle = '#E1E1E1';
ctx.lineWidth = 1;
ctx.stroke();
}
}
function resizeCanvas() {
cnv.width = window.innerWidth;
cnv.height = window.innerHeight;
draw();
}
initialize();
})();
I have created 25 Circle shape with random position and I want to create an animation that scales up or down in a interval time. I know about setInterval but how should I call my shape to do something on it?
The first thing you will want to do is to have a place to store the position of your circles, since they are all going to be the same radius we can just store the x and y position. For that we can create a Circle function ("class") and have an array of circles:
var circles = []; // Array to store our circles
var minRadius = 1; // The smallest radius we can hit
var maxRadius = 100; // The largest radius we can hit
var currentRadius = 15;// The current radius of all our circles
var scaleBy = 1; // How the radius changes
var cnv = document.getElementById('canvas');
// ...
function initialize() {
window.addEventListener('resize', resizeCanvas, false);
resizeCanvas();
// Populating the array of circles to use when drawing
for (var i = 0; i < 25; i++) { // Make sure to do this after re-sizing the canvas
width = Math.random() * cnv.width;
height = Math.random() * cnv.height;
circles.push(new Circle(width, height));
}
}
// ...
function Circle(x, y){
this.x = x;
this.y = y;
}
Circle.prototype.draw = function(){
ctx.beginPath();
ctx.arc(this.x, this.y, currentRadius, 0, Math.PI * 2);
ctx.strokeStyle = '#E1E1E1';
ctx.lineWidth = 5;
ctx.stroke();
}
Now that you have some circles when you call draw you can iterate through the array and call circle.draw() for each circle element in your array:
function draw() {
// Clear the screen and draw the circles in our array
ctx.clearRect(0,0, cnv.width, cnv.height);
for (var i = 0; i < circles.length; i++) {
circles[i].draw();
}
}
One note is you will want to use ctx.clearRect(0,0, cnv.width, cnv.height) to clear the screen before drawing.
Finally you can now use setInterval to change the currentRadius (*While there is nothing wrong with setInterval I'd recommend using window.requestAnimationFrame for animation as it's a bit more smooth and efficient method). Then when you call draw it will draw the circles with the new value of currentRadius. In this example I'm going to have it start at 15. Then increase by 1 until it hits maxRadius, then we can flip the sign of scaleBy to start decreasing the radius to make them smaller. Finally when it his our minRadius you can flip the sign of scaleBy again to make it start scaling up again:
var timer = setInterval( function(){
// If we hit our min or max start scaling in the other direction
if(currentRadius > maxRadius || currentRadius < minRadius){
scaleBy *= -1;
}
currentRadius += scaleBy;
draw();
}, 50);
Below is a code snippet of the complete program:
(function() {
var circles = [];
var minRadius = 1;
var maxRadius = 100;
var currentRadius = 15;
var scaleBy = 1;
var cnv = document.getElementById('canvas');
if (cnv.getContext) {
var ctx = cnv.getContext('2d');
} else {
alert('God Damn it ...');
}
function initialize() {
window.addEventListener('resize', resizeCanvas, false);
resizeCanvas();
for (var i = 0; i < 25; i++) {
width = Math.random() * cnv.width;
height = Math.random() * cnv.height;
circles.push(new Circle(width, height));
}
}
function draw() {
ctx.clearRect(0,0, cnv.width, cnv.height);
for (var i = 0; i < circles.length; i++) {
circles[i].draw();
}
}
function resizeCanvas() {
cnv.width = window.innerWidth;
cnv.height = window.innerHeight;
}
function Circle(x, y){
this.x = x;
this.y = y;
}
Circle.prototype.draw = function(){
ctx.beginPath();
ctx.arc(this.x, this.y, currentRadius, 0, Math.PI * 2);
ctx.strokeStyle = '#E1E1E1';
ctx.lineWidth = 5;
ctx.stroke();
}
initialize();
var timer = setInterval( function(){
if(currentRadius > maxRadius || currentRadius < minRadius){
scaleBy *= -1;
}
currentRadius += scaleBy;
draw();
}, 50);
})();
<canvas id="canvas"></canvas>
I am trying to get my balls, in the array, to move directly down the canvas after a short period of time, one after the other to equal exactly 100 balls dropped. I included all of my code to try and show more of what i want the program to do.
Really the balls spawn and a user controls the paddle scoring points for each ball hit. Their are radio buttons that can be checked to make the balls fall faster or slower.
Im just stuck on getting the balls to move down the canvas one at a time.
var posY = 0;
var spawnRateOfDescent = 2;
var spawnRate = 500;
var lastSpawn = -1;
var balls = [100];
var startTime = Date.now();
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
function checkRadio() {
if (document.getElementById("moderate").checked == true) {
spawnRate = 250;
} else if (document.getElementById("hard").checked == true) {
spawnRate = 100;
} else if (document.getElementById("easy").checked == true) {
spawnRate = 500;
}
}
function startGame() {
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
baton = new batonPiece(50, 10, "28E060", 210, 250)
}
function ball() {
this.x = Math.random() * (canvas.width - 30) + 15;
this.y = 0;
this.radius = 10;
this.color = randomColor();
this.draw = function () {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI, false);
ctx.fillStyle = randomColor();
ctx.fill();
ctx.closePath();
}
}
var balls = [];
for (var i = 0; i < 100; i++) {
balls[i] = new ball();
balls[i].draw();
}
function batonPiece(width, height, color, x, y) {
this.width = width;
this.height = height;
this.x = x;
this.y = y;
ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
function randomColor() {
var letter = "0123456789ABCDEF".split("");
var color = "#";
for (var i = 0; i < 6; i = i + 1) {
color += letter[Math.round(Math.random() * 15)];
}
return color;
}
function moveLeft() {
batonPiece.x -= 1;
}
function moveRight() {
baton.x += 1;
}
function stopMove() {
baton.x = 0;
}
I made this (run snippet below)
var Canvas = document.getElementById('c');
var ctx = Canvas.getContext('2d');
var resize = function() {
Canvas.width = Canvas.clientWidth;
Canvas.height = Canvas.clientHeight;
};
window.addEventListener('resize', resize);
resize();
var elements = [];
var presets = {};
presets.shard = function (x, y, s, random, color) {
return {
x: x,
y: y,
draw: function(ctx, t) {
this.x += 0;
this.y += 0;
var posX = this.x + + Math.sin((50 + x + (t / 10)) / 100) * 5;
var posy = this.y + + Math.sin((55 + x + (t / 10)) / 100) * 7;
ctx.beginPath();
ctx.fillStyle = color;
ctx.moveTo(posX, posy);
ctx.lineTo(posX+random,posy+random);
ctx.lineTo(posX+random,posy+random);
ctx.lineTo(posX+0,posy+50);
ctx.closePath();
ctx.fill();
}
}
};
for(var x = 0; x < Canvas.width; x++) {
for(var y = 0; y < Canvas.height; y++) {
if(Math.round(Math.random() * 60000) == 1) {
var s = ((Math.random() * 5) + 1) / 10;
if(Math.round(Math.random()) == 1){
var random = Math.floor(Math.random() * 100) + 10;
var colorRanges = ['#8c8886', '#9c9995'];
var color = colorRanges[Math.floor(Math.random() * colorRanges.length)];
elements.push(presets.shard(x, y, s, random, color));
}
}
}
}
setInterval(function() {
ctx.clearRect(0, 0, Canvas.width, Canvas.height);
var time = new Date().getTime();
for (var e in elements)
elements[e].draw(ctx, time);
}, 10);
<canvas id="c" width="1000" height="1000"\>
I just need to add one feature to be able to use it on the site I'm building it for. Some of the floating shards need to be blurred to give a sense of depth.
Can Canvas do this, and if so, how?
context.filter = 'blur(10px)';
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/filter
I used this few months ago, maybe it could work for you as well :
var canvas = document.getElementById("heroCanvas");
var canvasContext = canvas.getContext("2d");
var canvasBackground = new Image();
canvasBackground.src = "image.jpg";
var drawBlur = function() {
// Store the width and height of the canvas for below
var w = canvas.width;
var h = canvas.height;
// This draws the image we just loaded to our canvas
canvasContext.drawImage(canvasBackground, 0, 0, w, h);
// This blurs the contents of the entire canvas
stackBlurCanvasRGBA("heroCanvas", 0, 0, w, h, 100);
}
canvasBackground.onload = function() {
drawBlur();
}
Here the source : http://zurb.com/playground/image-blur-texture
So I am in the process of making this rhythm game with canvas, all that it does up to this point is render the receivers (the point the blocks are going to collide with so the user can press the corresponding buttons and get points) and it renders the dancer animation. For some reason though after the page is open for a while the dancer slows down significantly and continues to gradually slow.
I can't figure out why or how to fix it. Anyone have any ideas?
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
canvas.width = 500;
canvas.height = 600;
document.body.appendChild(canvas);
var spritesheet = null;
var dancer = {
time:0,
speed:0,
image:null,
x:0,
y:0,
currentFrame:0,
width:50,
height:100,
ready:false
}
function onload() {
spritesheet = new Image();
spritesheet.src = "danceSheet.png";
spritesheet.onload = initiate;
}
function initiate() {
game.startTime = new Date().getTime() / 1000;
dancer.x = (canvas.width / 2) - dancer.width;
dancer.y = 120;
game.initiateReceivers();
main();
}
var game = {
startTime:0,
currentTime:0,
receivers:[],
senders:[],
lanes:[],
drawDancer: function() {
ctx.drawImage(spritesheet, dancer.width * dancer.currentFrame, 0, dancer.width, dancer.height, dancer.x, dancer.y, dancer.width, dancer.height );
},
clearWindow: function() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
},
initiateReceivers: function() {
var distanceRate = canvas.width / 4;
var position = 30;
for(initiates = 0; initiates < 4; initiates++) {
this.receivers[initiates] = new receivers;
this.receivers[initiates].x = position;
this.receivers[initiates].y = 300;
position += distanceRate;
}
}
}
var gameUpdates = {
updateMovement: function() {
game.currentTime = new Date().getTime() / 1000;
dancer.time = game.currentTime - game.startTime;
if(dancer.time >= 0.1) {
game.startTime = new Date().getTime() / 1000;
dancer.currentFrame += 1;
if(dancer.currentFrame == 12) dancer.currentFrame = 0;
}
},
collision: function(shapeA, shapeB) {
// get the vectors to check against
var vX = (shapeA.x + (shapeA.width / 2)) - (shapeB.x + (shapeB.width / 2)),
vY = (shapeA.y + (shapeA.height / 2)) - (shapeB.y + (shapeB.height / 2)),
// add the half widths and half heights of the objects
hWidths = (shapeA.width / 2) + (shapeB.width / 2),
hHeights = (shapeA.height / 2) + (shapeB.height / 2);
// if the x and y vector are less than the half width or half height, they we must be inside the object, causing a collision
if (Math.abs(vX) < hWidths && Math.abs(vY) < hHeights) {
return true;
}
return false;
}
}
function receivers() {
this.x = 0;
this.y = 0;
this.width = 60;
this.height = 10;
}
function senders() {
this.x = 0;
this.y = 0;
this.width = 60;
this.height = 10;
this.lane = 0;
this.status = true;
}
function update() {
gameUpdates.updateMovement();
}
function render() {
game.clearWindow();
game.drawDancer();
game.receivers.forEach( function(receiver) {
ctx.rect(receiver.x,receiver.y,receiver.width,receiver.height);
ctx.fillStyle = "red";
ctx.fill();
}
)
}
function main() {
update();
render();
requestAnimationFrame(main);
}
I'm trying to get an idea of the slowness you're seeing so I adjusted your code to get a frames-per-second. Haven't found the cause yet for the drop.
Update
I found that the frames were dropping from drawing the rectangles. I've altered the code to use fillRect put the fill style outside of the loop. This seems to have fixed the frame drop.
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
canvas.width = 500;
canvas.height = 600;
document.body.appendChild(canvas);
var spritesheet = null;
var dancer = {
time: 0,
speed: 0,
image: null,
x: 0,
y: 0,
currentFrame: 0,
width: 50,
height: 100,
ready: false
}
function onload() {
spritesheet = document.createElement('canvas');
spritesheet.width = (dancer.width * 12);
spritesheet.height = dancer.height;
var ctx = spritesheet.getContext('2d');
ctx.font = "30px Arial";
ctx.fillStyle = "black";
ctx.strokeStyle = "red";
for (var i = 0; i < 12; i++) {
var x = (i * dancer.width) + 10;
ctx.fillText(i,x,60);
ctx.beginPath();
ctx.rect(i*dancer.width,0,dancer.width,dancer.height);
ctx.stroke();
}
initiate();
}
function initiate() {
game.startTime = new Date().getTime() / 1000;
dancer.x = (canvas.width / 2) - dancer.width;
dancer.y = 120;
game.initiateReceivers();
main();
}
var game = {
startTime: 0,
currentTime: 0,
receivers: [],
senders: [],
lanes: [],
drawDancer: function() {
ctx.drawImage(spritesheet, dancer.width * dancer.currentFrame, 0, dancer.width, dancer.height, dancer.x, dancer.y, dancer.width, dancer.height);
//ctx.strokeStyle="red";
//ctx.beginPath();
//ctx.lineWidth = 3;
//ctx.rect(dancer.x,dancer.y,dancer.width,dancer.height);
//ctx.stroke();
},
clearWindow: function() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
},
initiateReceivers: function() {
var distanceRate = canvas.width / 4;
var position = 30;
for (initiates = 0; initiates < 4; initiates++) {
this.receivers[initiates] = new receivers;
this.receivers[initiates].x = position;
this.receivers[initiates].y = 300;
position += distanceRate;
}
}
};
var gameUpdates = {
updateMovement: function() {
game.currentTime = new Date().getTime() / 1000;
dancer.time = game.currentTime - game.startTime;
if (dancer.time >= 0.1) {
game.startTime = new Date().getTime() / 1000;
dancer.currentFrame += 1;
if (dancer.currentFrame == 12) dancer.currentFrame = 0;
}
},
collision: function(shapeA, shapeB) {
// get the vectors to check against
var vX = (shapeA.x + (shapeA.width / 2)) - (shapeB.x + (shapeB.width / 2)),
vY = (shapeA.y + (shapeA.height / 2)) - (shapeB.y + (shapeB.height / 2)),
// add the half widths and half heights of the objects
hWidths = (shapeA.width / 2) + (shapeB.width / 2),
hHeights = (shapeA.height / 2) + (shapeB.height / 2);
// if the x and y vector are less than the half width or half height, they we must be inside the object, causing a collision
if (Math.abs(vX) < hWidths && Math.abs(vY) < hHeights) {
return true;
}
return false;
}
}
function receivers() {
this.x = 0;
this.y = 0;
this.width = 60;
this.height = 10;
}
function senders() {
this.x = 0;
this.y = 0;
this.width = 60;
this.height = 10;
this.lane = 0;
this.status = true;
}
function update() {
gameUpdates.updateMovement();
}
function render() {
game.clearWindow();
game.drawDancer();
ctx.fillStyle = "red";
game.receivers.forEach(function(receiver) {
ctx.fillRect(receiver.x, receiver.y, receiver.width, receiver.height);
});
ctx.fillText(fps,10,10);
}
var fps = 0;
var frames = 0;
function getFps() {
fps = frames;
frames = 0;
setTimeout(getFps,1000);
}
getFps();
function main() {
update();
render();
frames++;
requestAnimationFrame(main);
}
onload();
canvas {
border:1px solid blue;
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am creating a game (using HTML5 canvas) that involves catching falling apples, i know, how original! I am having trouble finding a way to make it so multiple apples fall?
Here is the code in JSFiddle: https://jsfiddle.net/pgkL09j7/12/
var apple_x = 100;
var apple_y = 0;
var basket_x = 100;
var basket_y = 100;
var points = 0;
var basket_img = new Image();
basket_img.src = "http://s18.postimg.org/h0oe1vj91/basket.png";
var Countable = function () {}
//Background colour of canvas
var c = document.getElementById("c");
var ctx = c.getContext("2d");
ctx.fillStyle = "#000";
ctx.fillRect(0, 0, 500, 500);
//Here is the event listener
c.addEventListener("mousemove", seenmotion, false);
//////////////////////
function seenmotion(e) {
//This is the code for the mouse
//moving over the canvas.
var bounding_box = c.getBoundingClientRect();
basket_x = (e.clientX - bounding_box.left) * (c.width / bounding_box.width) - basket_img.width / 2;
basket_y = (e.clientY - bounding_box.top) * (c.height / bounding_box.height) - basket_img.height / 2;
}
function start_game() {
setInterval(game_loop, 50);
}
function game_loop() {
// The code above is called every 50ms and is a
// frame-redraw-game-animation loop.
c.width = c.width;
// Below is the code that draws the objects
draw_apple(apple_x, apple_y);
draw_basket(basket_x, basket_y);
// Below is the code that updates the balloons location
apple_x++;
if (apple_y > c.height) {
apple_y = 0;
}
//Here is the collision detection code
if (collision(apple_x, apple_y, basket_x, basket_y)) {
points -= 0.5;
}
//Here is the code for the point system
points += 1;
// and let's stick it in the top right.
var integerpoints = Math.floor(points); // make it into an integer
ctx.font = "bold 24px sans-serif";
ctx.fillText(integerpoints, c.width - 50, 50);
}
context.clearRect(0, 0, 500, 500);
function collision(basket_x, basket_y, apple_x, apple_y) {
if (apple_y + 85 < basket_y) {
return false;
}
if (apple_y > basket_y + 91) {
return false;
}
if (apple_x + 80 < basket_x) {
return false;
}
if (apple_x > basket_x + 80) {
return false;
}
return true;
}
// Code to stop the game when we're finished playing
function stop_game() {
}
//Code for the ball
function draw_app
le(x, y) {
var apple_img = new Image();
apple_img.src = "http://s15.postimg.org/3nwjmzsiv/apple.png";
ctx.drawImage(apple_img, x, y);
}
//Code for the basket
function draw_basket(x, y) {
ctx.drawImage(basket_img, x, y);
}
Change the section
apple_x++;
if (apple_x > c.width) {
apple_x = 0;
}
to use vertical instead of horizontal...
apple_y++;
if (apple_y > c.height) {
apple_y = 0;
}
You've already accepted the answer, but this looked like fun. Check out this fiddle.
https://jsfiddle.net/h82gv4xn/
Improvements include:
Fixed scoreboard
Added level progression (Level increases every 10 apples)
Allowance for many many more apples on screen (play to level 9).
Apples will fall at different speeds and speed up as the levels increase.
Uses the animation frame system for much smoother animations.
Relaxed collision handling (The center of the bucket must touch the apple)
It all gets really silly as the levels wind upwards, but it should be a nice example to improve upon. The relevant javascript follows (this would go into your onLoad function):
var game = create_game();
game.init();
function create_game() {
debugger;
var level = 1;
var apples_per_level = 1;
var min_speed_per_level = 1;
var max_speed_per_level = 2;
var last_apple_time = 0;
var next_apple_time = 0;
var width = 500;
var height = 500;
var delay = 1000;
var item_width = 50;
var item_height = 50;
var total_apples = 0;
var apple_img = new Image();
var apple_w = 50;
var apple_h = 50;
var basket_img = new Image();
var c, ctx;
var apples = [];
var basket = {
x: 100,
y: 100,
score: 0
};
function init() {
apple_img.src = "http://s15.postimg.org/3nwjmzsiv/apple.png";
basket_img.src = "http://s18.postimg.org/h0oe1vj91/basket.png";
level = 1;
total_apples = 0;
apples = [];
c = document.getElementById("c");
ctx = c.getContext("2d");
ctx.fillStyle = "#000";
ctx.fillRect(0, 0, 500, 500);
c.addEventListener("mousemove", function (e) {
//moving over the canvas.
var bounding_box = c.getBoundingClientRect();
basket.x = (e.clientX - bounding_box.left) * (c.width / bounding_box.width) - basket_img.width / 2;
basket.y = (e.clientY - bounding_box.top) * (c.height / bounding_box.height) - basket_img.height / 2;
}, false);
setupApples();
requestAnimationFrame(tick);
}
function setupApples() {
var max_apples = level * apples_per_level;
while (apples.length < max_apples) {
initApple(apples.length);
}
}
function initApple(index) {
var max_speed = max_speed_per_level * level;
var min_speed = min_speed_per_level * level;
apples[index] = {
x: Math.round(Math.random() * (width - 2 * apple_w)) + apple_w,
y: -apple_h,
v: Math.round(Math.random() * (max_speed - min_speed)) + min_speed,
delay: Date.now() + Math.random() * delay
}
total_apples++;
}
function collision(apple) {
if (apple.y + apple_img.height < basket.y + 50) {
return false;
}
if (apple.y > basket.y + 50) {
return false;
}
if (apple.x + apple_img.width < basket.x + 50) {
return false;
}
if (apple.x > basket.x + 50) {
return false;
}
return true;
}
function maybeIncreaseDifficulty() {
level = Math.max(1, Math.ceil(basket.score / 10));
setupApples();
}
function tick() {
var i;
var apple;
var dateNow = Date.now();
c.width = c.width;
for (i = 0; i < apples.length; i++) {
apple = apples[i];
if (dateNow > apple.delay) {
apple.y += apple.v;
if (collision(apple)) {
initApple(i);
basket.score++;
} else if (apple.y > height) {
initApple(i);
} else {
ctx.drawImage(apple_img, apple.x, apple.y);
}
}
}
ctx.font = "bold 24px sans-serif";
ctx.fillStyle = "#2FFF2F";
ctx.fillText(basket.score, c.width - 50, 50);
ctx.fillText("Level: " + level, 20, 50);
ctx.drawImage(basket_img, basket.x, basket.y);
maybeIncreaseDifficulty();
requestAnimationFrame(tick);
}
return {
init: init
};
}