Countdown timer not working - javascript

The countdown timer I created doesn't work.
Interestingly, if I use console.log to print the value of count--which starts at 3--something like -3498 is printed, even if I am only on for around 15 seconds, so there must be something wrong with the set interval code. The value is displayed(if count is greater than 0), but set interval changes too quickly.
Here's the code.
function countdown(){
window_width=window.innerWidth-70;
window_height=window.innerHeight-150;
canvas = document.getElementById("gameCanvas");
ctx=canvas.getContext("2d");
canvas.width = window_width;
canvas.height=window_height;
if(count>0){
ctx.font = '40pt Calibri';
ctx.fillStyle = "white";
ctx.fillText(count, window_width/3, window_height/2);
}
else if(count===0){
ctx.fillText("Go!", window_width/3, window_height/2);
}
else{
return;
}
setInterval(function(){count=count-1},1000);
requestAnimationFrame(countdown);
}
Any help would be appreciated.

I'm a bit unclear as to what you're trying to accomplish, but here's a shot at it:
window.count = 3;
setTimeout(countdown,1000);
function countdown(){
window_width=window.innerWidth-70;
window_height=window.innerHeight-150;
canvas = document.getElementById("gameCanvas");
ctx=canvas.getContext("2d");
canvas.width = window_width;
canvas.height=window_height;
count--;
if(count>0){
ctx.font = '40pt Calibri';
ctx.fillStyle = "white";
ctx.fillText(count, window_width/3, window_height/2);
setTimeout(countdown,1000);
}
else if(count===0){
ctx.fillText("Go!", window_width/3, window_height/2);
}
else{
return;
}
requestAnimationFrame(countdown); // not sure if this is needed
}
As far as I can tell, you don't need the interval.

The value is displayed, but changes too quickly
You will need to distinguish between logic and presentation. When the countdown function is called, you schedule a function to decrease the count in 1s, and at the same time you schedule countdown to be called again as fast as possible. The update interval of canvases is about 16ms though… It means the count is decreased at that rate, only delayed 1 second after starting.
And it's even worse, as you did use setInterval which forever repeats decreasing the count, while that process is started every animation frame…
The solution is not to use setTimeout/setInterval at all. They are unreliable and should not be used for measuring the time. Instead, get accurate timestamps from the Date object (every time you need them, ie. every animation frame):
var canvas = document.getElementById("gameCanvas");
var ctx = canvas.getContext("2d");
canvas.width = window.innerWidth -70;
canvas.height = window.innerHeight-150;
ctx.font = '40pt Calibri';
ctx.fillStyle = "white";
var count = …;
var estimatedEnd = Date.now() + count*1000;
function countdown(){
var currentCount = (estimatedEnd - Date.now()) / 1000;
if (currentCount>0){
ctx.fillText(currentCount, window_width/3, window_height/2);
requestAnimationFrame(countdown);
} else if (currentCount===0){
ctx.fillText("Go!", window_width/3, window_height/2);
}
}
countdown();

Related

How do I put a timer that counts up in HTML5 Canvas with Javascript?

I've made the beginning of a platformer game with a sprite-character. I want to be able to be able to have a timer somewhere in the top-left corner that counts up for every second (00:00, 00:01).
I've kinda done a timer before, but that was counted down and this is different because I'm using requestAnimationframe for my game loop. Would be grateful for some tips on how to accomplish this.
I've made a death counter already using this code:
ctx.font = "20px Arial";
ctx.fillStyle = "white";
ctx.fillText("Deaths: " + deaths, 50, 50);
with deaths++ in a function that resets the position of the player. However, I can't figure out how to proceed.
Here is a jsFiddle of my game (you might have to zoom out, game is 1300x600. Arrowkeys to control character.):
https://jsfiddle.net/z3orewvb/
Strictly said you can do the timer in your loop(), so it is more coupled to the game logic and rendering. Just store the starting time outside, and whenever you redraw, calculate the difference:
let start=Date.now();
function reset() {
start=Date.now();
}
let x=0,y=0,dx=0,dy=0;
function loop() {
let seconds=Math.floor((Date.now()-start)/1000);
let minutes=Math.floor(seconds/60);
seconds%=60;
dx+=x<cnv.width/2?1:-1;
dy+=y<cnv.height/2?1:-1;
x+=dx;
y+=dy;
let ctx=cnv.getContext("2d");
ctx.fillStyle="#8080FF";
ctx.beginPath();
ctx.arc(x,y,10,0,Math.PI*2);
ctx.fill();
ctx.stroke();
ctx.clearRect(0,0,30,15);
ctx.strokeText(minutes.toString().padStart(2,"0")+":"+seconds.toString().padStart(2,"0"),0,10);
requestAnimationFrame(loop);
}
loop();
<button onclick="reset()">Reset</button><br>
<canvas id="cnv"></canvas>
Of course there is a generic repeating timer, setInterval(). But then you may have artifacts if there is anything else drawn on the same location:
let x=0,y=0,dx=0,dy=0;
function loop() {
dx+=x<cnv.width/2?1:-1;
dy+=y<cnv.height/2?1:-1;
x+=dx;
y+=dy;
let ctx=cnv.getContext("2d");
ctx.fillStyle="#8080FF";
ctx.beginPath();
ctx.arc(x,y,10,0,Math.PI*2);
ctx.fill();
ctx.stroke();
requestAnimationFrame(loop);
}
loop();
let start=Date.now();
let counter=0;
function reset() {
start=Date.now();
counter=0;
}
setInterval(()=>{
let ctx=cnv.getContext("2d");
ctx.clearRect(0,0,30,25);
let seconds=Math.floor((Date.now()-start)/1000);
let minutes=Math.floor(seconds/60);
seconds%=60;
ctx.strokeText(minutes.toString().padStart(2,"0")+":"+seconds.toString().padStart(2,"0"),0,10);
counter++;
minutes=Math.floor(counter/60);
seconds=counter%60;
ctx.strokeText(minutes.toString().padStart(2,"0")+":"+seconds.toString().padStart(2,"0"),0,20);
},1000);
function problem() {
let wait=Date.now()+1500;
while(Date.now()<wait);
}
<button onclick="reset()">Reset</button><button onclick="problem()">Problem</button><br>
<canvas id="cnv"></canvas>
Also, a "Problem" button has been added (press it a couple times): setInterval() does its best, but it is not bulletproof, it does not compensate for missed/skipped schedules, that second simply has not happened for the setInterval()-based counter (the lower one).
You should be able to do something like this.. In the callback function, I pass back the interval object, so that if needed, you can clear the interval so it doesn't continue to run in the background.. (or if you need to stop the counter at a certain point).. In this demo, I stop the counter at 11..
function counter(callback) {
var i = 0;
let interval = setInterval(function() {
callback(i, interval);
i++;
}, 1000);
}
counter((currentTime, intervalObject) => {
if (currentTime === 11) {
clearInterval(intervalObject);
} else {
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
const data = `
<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'>
<foreignObject width='100%' height='100%'>
<div xmlns='http://www.w3.org/1999/xhtml' style='font-size:40px'>
<pre>${currentTime}</pre>
</div>
</foreignObject>
</svg>
`;
const img = new Image();
const svg = new Blob([data], { type: "image/svg+xml;charset=utf-8" });
const url = URL.createObjectURL(svg);
img.onload = function() {
ctx.drawImage(img, 0, 0);
URL.revokeObjectURL(url);
};
img.src = url;
}
});
<canvas id="canvas"></canvas>

How to undo a drawing? Making a stopwatch and the text overlaps as it updates

i'm making a stopwatch that is working, but when it changes, the text overlaps itself because it is drawing the text repeatedly. If i remove the strokeText and fillText from the interval, then it does not change. It stays the same. How can i make the function undo itself, or delete the text at the beginning of the interval?
function drawTimer() {
var fontSize = 15;
graph.lineWidth = playerConfig.textBorderSize;
graph.fillStyle = playerConfig.textColor;
graph.strokeStyle = playerConfig.textBorder;
graph.miterLimit = 1;
graph.lineJoin = 'round';
graph.textAlign = 'right';
graph.textBaseline = 'middle';
graph.font = 'bold ' + fontSize + 'px sans-serif';
var gameTimeMinutes = 0;
var gameTimeSeconds = 1;
var gameTime = "";
function addTime() {
gameTimeSeconds += 1;
if (gameTimeSeconds < 10) {
gameTime = gameTimeMinutes + " : 0" + gameTimeSeconds;
} else {
gameTime = gameTimeMinutes + " : " + gameTimeSeconds;
}
if (gameTimeSeconds == 60) {
gameTimeSeconds = 0;
gameTimeMinutes++;
}
graph.strokeText(gameTime, 50, 50);
graph.fillText(gameTime, 50, 50);
}
setInterval(addTime, 1000);
}
Code explanation: gameTimeSeconds is the seconds on the right of the colon, minutes is on the left, and its saying if the seconds is not double digits, then show the zero on the left of it. It also says to add one to minutes when seconds reach 60. Then, write the time. Ex: 0:01, 0:20, 1:20, etc. . Thanks!
I assume you just need to clear your canvas on each interval: context.clearRect(0, 0, canvas.width, canvas.height);
You need to draw each 'layer' every frame for anything that might overlap.
For example, draw the back of the stopwatch, then the texton each frame.
I.E. whatever is drawing the text and background needs to happen inside of addTime

requestAnimationFrame loop not correct FPS

I have a javascript function that my game loops through (hopefully) 60 times a second that controls input, drawing, etc.
The way it is currently coded it seems to be always be around 52, noticeably lower than 60 fps, and it even dips to 25-30 fps even when nothing else is happening
function loop() {
setTimeout(function () {
requestAnimationFrame(loop);
time += (1000 / 60);
if (time % 600 == 0) {
oldtick = tick;
tick += 1;
time = 0;
aiMovement();
combat();
}
context.clearRect(0, 0, c.width, c.height);
drawMap();
playerInput();
movePlayer();
drawEntities();
drawPopups();
var thisLoop = new Date;
var fps = 1000 / (thisLoop - lastLoop);
lastLoop = thisLoop;
context.drawImage(cursor, mouse.x, mouse.y, 16, 16);
context.fillStyle = "#ffff00";
context.fillText("FPS: " + Math.floor(fps) + " Time: " + Math.floor(time) + " tick: " + tick, 10, 450);
context.fillText("Gold: " + gold, 10, 460);
//requestAnimationFrame(loop);
}, 1000 / 60);
}
if I remove the setTimeout and the first requestAnimationFrame from the top and uncomment the reuqestAnimationFrame at the bottom and remove the other setTimeout things, the FPS improves to 58 but rapidly changes between 58 and 62, again, not statically 60. Does it have something to do with 1000/60 is not a whole number? How would people using requestAnimationFrame achieve 60 fps if this was true?
Don`t use setTimeout or setInterval for animation.
The problem is that you are calling a timer event from within the request animation event. Remove the timeout and just use requestAnimationFrame.
function loop(time){ // microsecond timer 1/1,000,000 accuracy in ms 1/1000th
// render code here
requestAnimationFrame(loop);
// or render code here makes no diff
}
requestAnimationFrame(loop); // to start
RequestAnimationFrame (rAF) is always in sync (unless the browser has vertical sync turned off). The next frame will be presented in 1/60th, 2/60th, 3/60th etc... of a second. You will not get 52frame per second using rAF, rather 60fps, 30fps, 15fps, etc...
The Demo below show the difference in use.
Because requestAnimationFrame uses some smarts to time the animation they can not both run at the same time so click on the canvas to start it.
You can also add a load to simulate rendering. There is a 14ms load and a 28 ms load. The 28ms load is design to mess up rAF as it will on many machines flick between 30 and 60 frames per second. The point is to show that rAF can only have 60, 30, 20,.. etc frames per second.
var ctx1 = can1.getContext("2d");
var ctx2 = can2.getContext("2d");
var ctx3 = can3.getContext("2d");
var lastTime1 = 0;
var lastTime2 = 0;
var lastTime3 = 0;
var frameFunction = frame1;
var frameText = "";
var drag = false;
var loadAmount = 14;
var stats = [{
data : [],
pos : 0,
add(val){
this.data[(this.pos ++) % 150] = val;
}
},{
data : [],
pos : 0,
add(val){
this.data[(this.pos ++) % 150] = val;
}
},{
data : [],
pos : 0,
add(val){
this.data[(this.pos ++) % 150] = val;
}
}
];
for(let i = 0; i < 150; i += 1){
stats[0].add(0);
stats[1].add(0);
stats[2].add(0);
}
setupContext(ctx1);
setupContext(ctx2);
setupContext(ctx3);
drawFrameTime(ctx1,0);
drawFrameTime(ctx2,0);
drawFrameTime(ctx3,0);
can1.addEventListener("click",()=>frameFunction = frame1);
can2.addEventListener("click",()=>frameFunction = frame2);
can3.addEventListener("click",()=>frameFunction = frame3);
load.addEventListener("click",()=>{
if(drag){
drag = false;
load.value = "Add load.";
}else{
drag = true;
load.value = "Remove load.";
}
});
loadPlus.addEventListener("click",()=>{
if(loadAmount === 14){
loadAmount = 28;
loadPlus.value = "28ms";
}else{
loadAmount = 14;
loadPlus.value = "14ms";
}
});
function CPULoad(){
if(drag){
var stopAt = performance.now() + loadAmount;
while(performance.now() < stopAt);
}
}
function setupContext(ctx){
ctx.font = "64px arial";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
}
function drawStats(ctx,stat){
ctx.setTransform(1,0,0,1,0,64);
ctx.strokeStyle = "red";
ctx.strokeRect(-1,16.666,152,0);
ctx.strokeStyle = "black";
ctx.beginPath();
var i = stat.pos + 149;
var x = 0;
ctx.moveTo(x,stat.data[(i++) % 150]);
while(x ++ < 150 && stat.data[i % 150] !== undefined) {
ctx.lineTo(x,stat.data[(i++) % 150]);
}
ctx.stroke();
}
function drawFrameTime(ctx,time){
ctx.fillStyle = "black";
ctx.setTransform(1,0,0,1,0,0);
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
if(time > 0){
ctx.fillStyle = drag ? "red" : "black";
ctx.setTransform(1,0,0,1,ctx.canvas.width / 2,ctx.canvas.height *0.25);
ctx.fillText(time,0,0);
ctx.setTransform(0.4,0,0,0.4,ctx.canvas.width / 2,ctx.canvas.height * 0.75);
ctx.fillText(Math.round(1000 / Number(time)) + "fps",0,0);
}else{
ctx.setTransform(0.4,0,0,0.4,ctx.canvas.width / 2,ctx.canvas.height * 0.75);
ctx.fillText("Click to Start.",0,0);
}
ctx.fillStyle = "black";
ctx.setTransform(0.2,0,0,0.2,ctx.canvas.width / 2,ctx.canvas.height * 0.9);
ctx.fillText(frameText,0,0);
if(drag){
ctx.fillStyle = "red";
ctx.setTransform(0.2,0,0,0.2,ctx.canvas.width / 2,ctx.canvas.height * 0.5);
ctx.fillText("Load " + loadAmount + "ms",0,0);
}
}
function frame1(time){
requestAnimationFrame(frameFunction);
frameText = "Using rAF.";
var frameTime = time - lastTime1;
lastTime1 = time;
stats[0].add(frameTime);
drawFrameTime(ctx1,frameTime.toFixed(2));
drawStats(ctx1,stats[0]);
CPULoad()
}
function frame2() {
setTimeout(function () {
frameText = "Using rAF & setTimeout.";
var time = performance.now();
var frameTime = time - lastTime2;
stats[1].add(frameTime);
lastTime2 = time;
drawFrameTime(ctx2, frameTime.toFixed(2));
drawStats(ctx2,stats[1]);
CPULoad();
requestAnimationFrame(frameFunction);
}, 1000 / 60);
}
function frame3() {
setTimeout(frameFunction,1000/60);
frameText = "SetTimeout by itself.";
var time = performance.now();
var frameTime = time - lastTime3;
stats[2].add(frameTime);
lastTime3 = time;
drawFrameTime(ctx3, frameTime.toFixed(2));
drawStats(ctx3,stats[2]);
CPULoad();
}
requestAnimationFrame(frameFunction);
body {
font-family : arial ;
}
canvas {
border : 1px solid black;
}
div {
text-align : center;
}
<div><h2>RequestAnimationFrame (rAF)</h2>
rAF V rAF & setTimeout V setTimeout<br>
<canvas id = can1 width = 150></canvas>
<canvas id = can2 width = 150></canvas>
<canvas id = can3 width = 150></canvas><br>
Click the frame to set the current test.<br>
The left frame is using rAF alone, the middle using setTimeout and rAf, and the rigth frame uses setTimeout alone.<br>
Click <input type="button" id=load value="add Load"></input> to simulate a rendering load of around <input type="button" id=loadPlus value="14ms" title="click to change CPU load between 14 and 28ms"></input> <br>
Try draging and selecting this text and see how it effects the different methods.<br>
rAF is by far the most stable of the 3.<br>
</div>
The functions purpose isnt to have 60 FPS, but to draw while a frame is beeing drawn and make the performance better. No computer will stay perfectly at 60 FPS.
Also, why is your requestAnimationFrame IN the timeout?

Registering event handlers with JS and Canvas

In my transition from the basics of Python (learned on the Coursera RICE course) to the Javascript ones, I'm trying to register even handlers using the same paradigm people here have been helping me successfully converting.
In this example, both the timer and update handlers aren't running :
//Globals
var message = "test message";
var positionX = 50;
var positionY = 50;
width = 500;
height = 500;
var interval = 2000;
//handler for text box
function update(text) {
message = text;
}
//handler for timer
function tick() {
var x = Math.floor(Math.random() * (width - 0) + 0);
var y = Math.floor(Math.random() * (height - 0) + 0);
positionX = x;
positionY = y;
}
//handler to draw on canvas
function draw(canvas) {
ctx.font="20px Georgia";
ctx.fillText(message,positionX,positionY);
}
//create a frame
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
canvas.width = width;
canvas.height = height;
//register event handlers
setInterval(tick, interval);
draw();
//start the frame and animation
<html>
<head>
</head>
<body>
Enter text here :
<input type="text" onblur="update(this.value)">
<canvas id="myCanvas" style="border:1px solid #000000;"></canvas>
<script>
</script>
</body>
</html>
Adding canvas.addEventListener("draw", draw(), false); and canvas.addEventListener("update", update(), false); didn't change anything.
Though, the only time it "worked" was when I added the draw(); call inside the tick(); function but it was keeping the text and duplicating it on screen randomly as the functions should work.
On a general note, do you guys think the current paradigm :
//Global state
//Handler for text box
//Handler for timer
//Handler to draw on canvas
//Create a frame
//Register event handlers
//Start the frame animation
is worth pursuing with JS and Canvas ?
Again, thanks for your time and help.
K.
The draw function should be inside the tick function. If you want to stop the old text you need to clear the canvas before you draw the text again. SetInterval is ok for time over 100ms or so but if you plan to do full frame animation 60fps use requestAnimationFrame
I am personally not a fan of setInterval and use setTimeout instead. Also note that the times given for set interval and timeout are approximations only. Javascript is single threaded and if the timeout or interval occurs while code is running then the events will wait until the current execution is complete.
"use strict";
//Globals
var message = "test message";
var positionX = 50;
var positionY = 50;
// constants
const width = 500;
const height = 500;
const interval = 2000;
if(typeof inputText !== "undefined"){
inputText.value = message;
}
//handler for text box
function update(text) {
message = text;
}
//handler for timer
function tick() {
setTimeout(tick, interval); // create the next timer event
positionX = Math.floor(Math.random() * width);
positionY = Math.floor(Math.random() * (height-20)); // 20 pixels of height to stop it disappearing
draw();
}
//handler to draw on canvas
function draw() {
ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
var textWidth = ctx.measureText(message).width;
ctx.fillText(message,Math.min(width - textWidth, positionX), positionY);
}
//create a context
const canvas = document.getElementById('myCanvas');
// set size befor get context as it is a little more efficient
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext('2d');
// if the same font only need to set it once or after the canvas is resized
ctx.font="20px Georgia";
//start the animation
tick();
<html>
<head>
</head>
<body>
Enter text here :
<input id="inputText" type="text" onblur="update(this.value)">
<canvas id="myCanvas" style="border:1px solid #000000;"></canvas>
<script>
</script>
</body>
</html>

Fill canvas before alert

For a canvas game, how can I load a canvas fill and text before the window alert? Even by just a few milliseconds.
There is a collision that occurs between two players.
Immediately after, the canvas should fill as colour and text should be displayed.
The problem is the alert appears before this happens.
The alert, when OK pressed, should reload the page - I have found that setTimeout does not work because of the location.reload inside of it.
Quick (nasty) example of how it works currently: JSFiddle
//collision
if (x < object.x - 50 + 60 &&
x + width > object.x - 50 &&
y < object.y - 60 + 60 &&
height + y > object.y - 60) {
//fill before alert
ctx.fillRect(0,0,2000,2000);
ctx.strokeText("You only reached a score of " + score + ", you lose!\nPress 'OK' to try again?", 250, 290);
ctx.fillText("You only reached a score of " + score + ", you lose!\nPress 'OK' to try again?",250,290);
//end game alert
if(!alert("You reached a score of ...")){
location.reload();
}}
setTimeout perfectly works, check this code out
HTML
<canvas id="canvas"></canvas>
<button id="buttonID">click here</button>
Javascript
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d");
ctx.fillStyle=gradient;
var my_gradient=ctx.createLinearGradient(0,0,0,170);
my_gradient.addColorStop(0,"#7E6189");
my_gradient.addColorStop(1,"#FFFFFF");
ctx.fillStyle=my_gradient;
ctx.lineWidth = 5;
ctx.font="30px Verdana";
var gradient=ctx.createLinearGradient(0,0,canvas.width,0);
gradient.addColorStop("0","magenta");
gradient.addColorStop("0.5","blue");
gradient.addColorStop("1.0","red");
ctx.strokeStyle = 'black';
//irrelevant above
var x = 1 //collision or any true statement
// when the event occures
// create the gredient
document.querySelector('#buttonID').onclick = function() {
ctx.fillRect(0,0,2000,2000);
ctx.strokeText("You only reached a score of ...", 250, 290);
ctx.fillText("You only reached a score of ...",250,290);
setTimeout(function() {
if(!alert("You only reached a score of ...")){
location.reload();
}
}, 300); // chenge the millis to whatever you want
}
i am using an event to execute the code because the permanent alets are annoying
This should work.
var x = 1 //collision or any true statement
if (x == 1) {
ctx.fillRect(0, 0, 2000, 2000);
ctx.strokeText("You only reached a score of ...", 250, 290);
ctx.fillText("You only reached a score of ...", 250, 290);
setTimeout(function(){
alert("You only reached a score of ...");
location.reload();
}, 10);
}
https://jsfiddle.net/ajrwpmb3/10/
Alerts does not return any value. they block the complete code execution. The problem here was that browsers tend to do bulk updates to DOM for changes done inside a function. Since in your code changes to canvas as done and immediately browser thread is blocked by alert, therefore the changes are not applied. in my example i have added 10 ms to break the event of canvas update and alert into 2 blocks in browser's event queue, this allows browser to complete event 1 i.e. canvas update first and then execute 2nd event i.e. show alert which blocks the code.
You can validate this concept by using the timeout value as 0ms.
window.alert, confirm, and prompt should die..
So many answers but I will add one more.
DON'T USE ALERTS... ever... please!!!, for the sake of all the users of your site and because if they are like me the very first time I see an alert on a site I turn them off. The fact that users can block/stop these alerts should be more than reason enough to not use them, because relying on alerts will break your game for pedantic people like me.
A much better Alert
Your best option is to create your own non blocking, customized alert. Create a div set its style to position: absolute, center it to the page, then add an ok button and hide the whole thing.
Give the alert div the id="myAlert" and when you need it just unhide it and wait for the button to be clicked, when the button is clicked hide the alert.
For your game you should add some pause logic, and when the alert needs to be shown just pause the game and show the alert. When the alert has been clicked unpause the games and do what is needed.
The demo just shows how you can implement a simple custom alert and pause a game.
// alert function handles the display of a custom alert
var alert = (function(){
var firstRun = true;
var callback;
function alertCallback(){ // handle the click event
if(typeof callback === "function"){
callback();
}
myAlert.className = "alert hideAlert";
}
function alert(message,callbackO){
myAletMessage.textContent = message;
myAlert.className = "alert showAlert";
if(firstRun){
firstRun = false;
myAlertButton.addEventListener("click",alertCallback)
}
callback = callbackO; // set the callback
}
return alert;
})()
var canvas,ctx;
function addCanvas(){
canvas = document.createElement("canvas");
canvas.style.top = "0px";
canvas.style.left = "0px";
canvas.style.position = "absolute";
document.body.appendChild(canvas);
ctx = canvas.getContext("2d");
}
function resizeCanvas(){
if(canvas === undefined){
addCanvas();
}
canvas.width = innerWidth;
canvas.height = innerHeight;
ctx.font = "32px arial black";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillStyle = "red";
}
resizeCanvas();
window.addEventListener("resize",resizeCanvas);
// The following code just shows a pretend game with a paused function
// The paused is used when the alert is called.
var paused = false;
var x,y,t;
function update2(timer){
globalTime = timer;
ctx.setTransform(1,0,0,1,0,0); // reset transform
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.globalAlpha = 1; // reset alpha
if(paused){
if(t > 0){
var sc = t / 10 + 0.1;
ctx.setTransform(sc,0,0,sc,x,y);
ctx.fillText("BANG!",0,0);
}
var sc = Math.sin(timer /100) * 0.1 + 1.0;
ctx.fillStyle = "Green";
ctx.setTransform(sc,0,0,sc,canvas.width/2,canvas.height/2);
ctx.fillText("Paused!",0,0);
ctx.fillStyle = "Red";
}else{
if(t > 0){
var sc = t / 10 + 0.1;
ctx.setTransform(sc,0,0,sc,x,y);
ctx.fillText("BANG!",0,0);
t -= 1;
}else{
if(Math.random() < 0.1){
x = (Math.random() * (canvas.width -200))+100;
y = (Math.random() * (canvas.height -200))+100;
t= 10;
}
}
if(Math.random() < 0.01){
alert("A 1 in 100 random event paused the game!",function(){paused = false;});
paused = true;
}
}
requestAnimationFrame(update2);
}
requestAnimationFrame(update2);
.alert {
position : absolute;
z-index : 100;
left : 35%;
width : 30%;
top : 10%;
background: #fff;
border: 1px #000 solid;
text-align: center;
padding: 6px;
}
.hideAlert {
display : none;
}
.showAlert {
display : block;
}
<div class="alert hideAlert" id="myAlert">
<div id="myAletMessage"></div><br>
<input id="myAlertButton" type="button" value="OK got it."></input>
</div>

Categories

Resources