Reputation: 132
Ok so the red blocks dangers[]
should fall down smoothly down the canvas, but they skip and act weirdly. Does it have anything to do with the for loop that show();
them?
Here's the code:
var dangers = [];
function setup() {
createCanvas(1060, 480);
createDanger();
}
var x = 0;
function createDanger() {
var randomWidth = (floor(random(980)) * 80) % 980;
dangers[x] = new Danger(randomWidth, -80);
dangers.forEach(function(obj) {
setInterval(function() {
obj.fall();
}, 1000);
});
x++;
console.log(dangers);
}
function draw() {
background(0);
for (danger of dangers) {
danger.show();
}
}
setInterval(createDanger, 3000)
//Danger
function Danger (x, y) {
this.x = x;
this.y = y;
var size = 80;
this.fall = function () {
this.y += size;
}
this.update = function () {
}
this.show = function () {
fill(255,0,0);
noStroke();
rect(this.x, this.y, size, size);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/addons/p5.dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/p5.min.js"></script>
<meta charset="utf-8" />
And if you have any other suggestions to my code, feel free to help. Thanks.
Upvotes: 0
Views: 103
Reputation: 11730
Here's an example of smoother performance.
var dangers = [];
function setup() {
background(0);
createCanvas(1060, 480);
createDanger();
}
function createDanger() {
var randomWidth = (floor(random(980)) * 80) % 980;
dangers.push(new Danger(randomWidth, -80));
}
var lastRenderTime;
function update() {
var now = Date.now();
if (lastRenderTime) {
var elapsed = (now - lastRenderTime) / 1000;
dangers.forEach(function(obj) {
obj.fall(elapsed);
});
}
dangers = dangers.filter(d => d.y < 400);
lastRenderTime = now;
}
function draw() {
update();
background(0);
for (danger of dangers) {
danger.show();
}
}
setInterval(function () {
createDanger();
}, 500)
//Danger
function Danger (x, y) {
this.x = x;
this.y = y;
this.speed = 40 + random(50); // pixels per second
var size = 80;
this.fall = function (time) {
this.y += this.speed * time;
}
this.update = function () {
}
this.show = function () {
fill(255,0,0);
noStroke();
rect(this.x, this.y, size, size);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/addons/p5.dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/p5.min.js"></script>
<meta charset="utf-8" />
This is close to the original, except that I did a couple of things differently:
update
function that is called from the draw
function. That guarantees that the animation is up to date before each frame is rendered.lastRenderTime
variable and subtract now
minus lastRenderTime
to compute the elapsed time. The elapsed time is passed through to the update function as a parameter.this.y += size
becomes this.y += this.speed * time
.push
which is a more language-agnostic description of the operation you are trying to perform rather than relying on JavaScript's quirky "extend the length of the array when you write off the end of it" behaviour.filter
function to remove expired objects after they hit the bottom of the window to ensure the array doesn't grow without bound and consume resources over time.Upvotes: 1