Trying to update timer within canvas (JS) - javascript

I'm trying to re-create a game inspired by the minigame in New Super Mario Bros. called "Wanted!". Here's the situation:
I'm trying to have a countdown timer of 10 seconds, using JavaScript. When the timer counts down, I want the timer to refresh every second that passes. But as you'll see in the picture below, the timer writes over itself. I'm trying to do this with pure JavaScript, but HTML will also work if it is a preferred method. Keep in mind that this is a still frame. Here's what I have:
function drawTimer() {
var timeLeft = 10; // Set seconds
let countDown = setInterval(function() {
// Check if we reached 0.
if (timeLeft <= 0) {
alert("Time's up!");
isWinner = false;
document.location.reload(); // reload the page
clearInterval(countDown);
}
else { // Less than 10,
requestAnimationFrame(drawTimer);
ctx.beginPath();
ctx.font = "16px Arial";
ctx.fillStyle = "#FFFFFF";
ctx.strokeStyle = "#000000";
ctx.fillText("Time left: " + timeLeft, 200, 20);
ctx.closePath();
}
timeLeft -= 1;
}, 1000);
}
Here's what it looks like:

Not sure if you understand what canvas do. Its just a "canvas", as it says, and you draw pixels.
For example, if you draw something and you want to move it somewhere, you should draw new pixels on the place where that should be moved and erase previous pixels. Its like you are drawing a circle on a paper, and wanna draw it (move it) to another place (that would be another frame), you should erase current circle and draw a new one on another place.
In your case, for showing timer text you draw pixels, each drawn pixel will stay on canvas unless you erase it at some point. You should find a way to erase it, but easier would be to have an element in html that is above canvas (absolute position) and you will not have a problems with repainting.

Related

How to make a character jump up with javascript

I am trying to work on the mechanics for a game I want to work on, however I don't have much experience with this area of programming. I have gotten a circle to move smoothly left and right with the A and D keys using requestAnimationFrame(), however I have absolutely no clue what the best approach would be to make the circle "jump" so to speak.
I want the ball to be able to move upwards when W is pressed until a certain height is reached, and then begin to fall down to the ground at a certain rate. I also want to retain the ability for the ball to move left and right while jumping. I'm not exactly sure how to go about this as I have little experience with request animation frame(), I've tried cancelling the current animation frame and calling a new one within a jump function but that doesn't seem to work at all.
Here is my code so far:
var canvas,
ctx,
westX = 300,
westY = 400,
velX = 0,
velY = 0,
speed = 3,
jumpSpeed = 2,
friction = 0.98,
keys = [],
jumping = false;
window.onload = function(){
canvas = document.getElementById("gameCanvas");
ctx = canvas.getContext("2d");
drawLevel(); //intial level draw
}
function drawLevel() {
move();
ctx.clearRect(0,0,canvas.width, canvas.height);
ctx.fillStyle = "#c3c3d5";
ctx.fillRect(0,0,canvas.width,canvas.height);
ctx.fillStyle = "black";
ctx.beginPath();
ctx.arc(westX,westY,8,0,Math.PI*2,true);
ctx.fill();
if (!keys[87] && !keys[32])
requestAnimationFrame(drawLevel);
if (keys[87] || keys[32])
{
jump();
}
}
Character Movement:
//moves character
function move()
{
//requestAnimationFrame(move);
if (keys[65]) { //if a is pressed
if (velX > -speed) {
velX--;
}
}
if (keys[68]) { //if d is pressed
if (velX < speed) {
velX++;
}
}
velX*= friction;
westX += velX;
//checks if character is at the edge
if (westX >= canvas.width-8)
{
westX = canvas.width-8;
} else if (westX <= 8)
{
westX = 8;
}
}
Attempt at jump function:
function jump()
{
requestAnimationFrame(jump)
if (velY > -jumpSpeed) {
velY--;
}
velY*= friction;
westY += velY;
}
document.addEventListener("keydown", function(e) {
keys[e.keyCode] = true;
});
document.addEventListener("keyup", function(e) {
keys[e.keyCode] = false;
});
Also, here is a codepen link to show what I have working so far:
https://codepen.io/shanetorres/pen/OvRdjq?editors=1010
Any help or suggestions would be greatly appreciated!
You're on the right track, but the pieces are not arranged correctly.
Divide the character control in two phases: movement calculation, and animation. Think in kinematics: The character's next position is driven by its actual position vector and its current velocity vector.
In the first phase, movement calculation, you alter only the velocity. Left/right modify the horizontal component of the speed, and the jump and gravity modify the vertical component. You want full air control, so both are independent (otherwise, altering the horizontal velocity manipulation would be conditioned by the vertical position, i.e., not jumping/falling). Ignore inertia for the moment (I think that's a better name than friction IMHO). The horizontal velocity velX is either maxVelX, -maxVelX, or 0, depending on whether right, left, or none/both are pressed. The vertical velocity velY is 0 if y is below or exactly a given value (i.e., the floor); when on the floor, pressing jump will set velY to velJump, and you decrease this value a certain amount every frame (i.e., gravity. Remember that it's an acceleration, i.e., velocity over time). When the character's y is below the floor level, you set velY to 0 and y to the floor level.
Once you have the movement calculated, you apply it to the position (i.e., animate it): x += velX; y += velY; This is the second phase of the character control.
Once you have this running, you can add inertia. Horizontal velocity is increased/decreased every frame until its "target" velocity is reached. I'd remove the vertical inertia/movement dampening unless you want your player to get stuck on the air or fall like a feather. However, it's usually a good idea to limit the falling speed to a hard limit if there's a lot of verticality in your game.
This is, of course, an over-simplistic approach to physics (common in most platforming/arcade games). For realistic or more elaborate approaches, I'd consider a 2D physics engine and using forces instead of just velocities.
Do you specifically want to program the physics yourself or is building the game itself your primary goal? If you're not too interested in programming the physics, I'd recommend that you look into Phaser.io framework for writing the game. It has physics libraries included, there are tons of tutorials and it's just a good tool to for building HTML games.

smoother canvas noise transition - fade in of particles

Here is my canvas on jsfiddle:
https://jsfiddle.net/vzrandom/fkho6grf/8/
I'm using simplex-noise.js and dat.GUI to create movement of particles. There is simulated click on canvas every 5 seconds. On click first animation is coming in background and new animation starts.
My problem is that animation on click starts too abruptly. I would like to have some kind of fade in of particles.
It seems like a simple problem but somehow I can't get it how to make fade in of elements that are inside the canvas - not entire canvas himself.
Entire code is on jsfiddle, here is part that handles the click:
function onCanvasClick(e) {
context.save();
context.globalAlpha = 1;
context.fillStyle = Configs.backgroundColor;
context.fillRect(0, 0, screenWidth, screenHeight);
context.restore();
simplexNoise = new SimplexNoise();
}
You need to render to an offscreen canvas.
Just create a second canvas
var canvas2 = document.createElement("canvas");
canvas2.width = canvas.width;
canvas2.height = canvas.height;
var ctx2 = canvas.getContext("2d");
Then for all your drawing calls use the background canvas 2dContext
To do the fade just render that canvas onto the display canvas setting alpha to make it fade.
The function called by requestAnimationFrame is passed a hi resolution time as the first argument. The code below is for the update function. Note that if you are using a polyfill for requestAnimationFrame you should use one that matches the standard.
var fadeTime = 1; // one second
var fadeTimeStart = undefined; // when undefined then this indicates start of fade
function update(time){
// render your particles to offscreen canvas
if(fadeTimeStart === undefined){ // get the current time as start
fadeTimeStart = time;
}
// get amount of fade
var fTime = (time - fadeTimeStart) / fadeTime;
// is it fading
if(fTime < 1){ // yes
ctx.globalAlpha = fTime;
clearRect(0,0,canvas.width,canvas.height); // clear last rendered scene
ctx.drawImage(canvas2,0,0); // draw the offscreen canvas
}else{
// you may or may not have to clear the canvas
ctx.drawImage(canvas2,0,0); // if no fade and assuming canvas is opaque then just draw the canvas onto the display.
}
requestAnimationFrame(update);
}
Then in the click event to start a new fade in just set the fadeTimeStart = undefined and it will start a new fade in.
I don't know if this is the effect you want to achieve, but you might get away with clearing the canvas a little on each iteration by filling it with a semi-transparent color in update function, instead of clearing it completely on each click.
See my fork here: https://jsfiddle.net/640e32ua/
Main change is changing Configs.backgroundColor to something semi-transparent and adding these two lines to update:
context.fillStyle = Configs.backgroundColor;
context.fillRect(0, 0, screenWidth, screenHeight);

placing text on top of a sketch in p5.js

I am trying to create my first website using the p5.js library, with the end goal being an online digital portfolio. I am currently working on a splash screen, in which I have some large title text filling the center of the screen on a simple black background, which actively resizes to fill the window.
I would like to place a simple doodle in the background to add some interest. My challenge is that I would not like this doodle to draw on top of my text, but instead place it underneath my text. Initially I was thinking of infinitely redrawing the text so it stays at the top, however I have deduced there is no way to do this while still animating something beneath it.
My knowledge of HTML / CSS is minimal, however I was thinking of making the background of the title sketch transparent, a separate sketch with the doodle, and use the z index property in CSS to place the doodle beneath the title, is this even possible?
Thanks!
Further edits based on recommendations:
function preload() {
myFont = loadFont('assets/HighTide.otf');
}
function setup() {
canvas = createCanvas(window.innerWidth, window.innerHeight);
title = text("Welcome", width/2, height/2);
background(30);
fsize = window.innerHeight/4;
pg = createGraphics(window.innerWidth, window.innerHeight);
}
function draw() {
background(30);
pg.fill(random(0,255), random(0,255), random(0,255));
//pg.translate(width/2, height/2);
pg.ellipse(random(window.innerWidth), random(window.innerHeight), 60, 60)
image(pg, 0, 0);
textFont(myFont);
textSize(fsize);
textAlign(CENTER);
fill(255);
text("Welcome", width/2, height/2);
}
window.onresize = function() {
var w = window.innerWidth;
var h = window.innerHeight;
canvas.size(w,h);
fsize = window.innerHeight/4;
title.textSize(fsize);
width = w;
height = h;
}
It depends on exactly how you're drawing everything, but if you're doing this all in P5.js then you've already described exactly what you need to do.
Step 1: Each frame, clear out old frames by calling the background() function.
Step 2: Then draw your doodle.
Step 3: Finally, draw your text. Since you're drawing the text after the doodle, it shows up "on top" of the doodle.
This is how most P5.js sketches work: every frame, you clear out the old frames and then draw the next frame.
Edit: If you need a sketch that doesn't clear out old frames but still shows two different layers (your doodle and your text), then what you could do is draw your doodle to a buffer, then draw that buffer each frame, then draw the text on top of the buffer. Check out the createGraphics() function in the reference.

HTML Canvas Animate folding triangle

I have drawn a triangle with canvas,
http://jsfiddle.net/nicekiwi/GfM6M/
I want to animate the triangle "unfolding" by moving one corner of it away form the other 2.
o---o---o
animate to below over 0.8 seconds or something.
o
/ \
/ \
/ \
o-------o
How can I do this? All the tutorials I could find move the entire object not a single point of it.
I really want to animate a number of these opening form each other in sequence, but hopefully I can figure that out myself. :)
When you want to animate a canvas, you need to create the animation in frames. Draw one frame, erase the canvas, and draw the next.
To get the timing right, you can use setInterval to execute a function at regular intervals. In the function you pass to setInterval:
erase the canvas with context.clearRect
adjust the coordinates
draw a triangle with the new coordinates
Adding this code below yours does the trick:
var x = 300;
// execute a function every 50ms
window.setInterval( function() {
// erase the canvas
var context = document.getElementById('canvas').getContext('2d');
context.clearRect(0, 0, 900, 500);
// update the coordinates
x++;
if (x > 500) x = 300;
// redraw with new coordinates
draw_triangle('410','48',x,'86','420','135');
}, 50);
A more professional way would be to use requestAnimationFrame instead of setInterval which has many advantages. But it makes your programming more complicated, because the animation speed will depend on the framerate and you either will need to compensate for that or decouple logic from rendering.

Redrawing Canvas in HTML5 using Javascript

I am creating a click and clear game. Once the user clicks some brick its adjacent bricks are checked for same color and all these bricks are bricks are cleared at once.
These are Cleared using clearRect() function.
Now this leaves a white patch right between the bricks above and bricks below leaving the above bricks hanging.
Now i want to bring these bricks above downward. How do i do this..?
Plz help
The question is quite vague, but based on the title, you'll need to clear your canvas before you can redraw. Otherwise, the drawn elements would simply stack on top of each other.
To do this, call the function clearRect on the canvas itself:
function clear() {
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, 500, 500);
}
Where canvas is the ID of your canvas, and 500, 500 the dimensions. Now you'll have an empty canvas where you can redraw everything again.
I once created a simple HTML5 canvas game as well, you might learn from the source code.
I think I understand what you're asking. If so then you're wanting to know how to move the blocks down when the blocks below have been removed.
This is just a matter of increasing the x position (remember the canvas starts at 0,0) with each iteration of your game loop.
How far to increase? Well that would be to where the highest "solid tower" is. I.E., say you have a column of 10 tokens and you remove the 7. The 3 below need all fall to the height of the remaining 6 - so that would be board height - (6*token height)
*
*
*
+ <- remove
* <- 6x token height (and less the board height)
*
*
*
*
*
I had success at redrawing the HTML Canvas by DOM.
var c = document.getElementsByName("myCanvas")[0];
if (c != null)
{
c.remove();
}
var c = document.createElement("canvas");
c.setAttribute("name", "myCanvas");
c.setAttribute("width", 900);
c.setAttribute("height", 600);
c.setAttribute("style", "border:1px solid #d3d3d3");

Categories