Animation on canvas two loops at once - javascript

Global for the main game loop
var requestAnimFrame = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000/60);
};
Below you can see that this function should start an animation. What it does however it speeds through the animation without enough time to see it. This I think is because the main game loop overrides it. I Do not know how to solve this?
function DrawSpawnAnimation() {
anim();
}
function anim() {
//alert(explodeY);
ctxAnimation.drawImage(spriteSheet, ExplodeFrame * 100, 2740,100,100,explodeX,explodeY,100,100);
if(ExplodeFrame == 5)
{
ctxAnimation.drawImage(spriteSheet, 6, 2851,100,106,(Player.x - 50) + 10,(Player.y - 50) + 10,100,100);
}
else if(ExplodeFrame == 6)
{
ctxAnimation.drawImage(spriteSheet, 106, 2851,100,106,(Player.x - 50) + 10,(Player.y - 50) + 10,100,100);
}
else if(ExplodeFrame == 7)
{
ctxAnimation.drawImage(spriteSheet, 206, 2851,100,106,(Player.x - 50) + 10,(Player.y - 50) + 10,100,100);
}
else if(ExplodeFrame == 8)
{
ctxAnimation.drawImage(spriteSheet, 306, 2851,100,106,(Player.x - 50) + 10,(Player.y - 50) + 10,100,100);
}
else if(ExplodeFrame == 9)
{
ctxAnimation.drawImage(spriteSheet, 406, 2851,100,106,(Player.x - 50) + 10,(Player.y - 50) + 10,100,100);
}
if (ExplodeFrame < 9) {
ExplodeFrame++;
setTimeout(anim, 1000 / 15);
}
else
{
Death = false;
ctxAnimation.drawImage(spriteSheet, 506, 2851,100,106,(Player.x - 50) + 10,(Player.y - 50) + 10,100,100);
ExplodeFrame = 0;
}
//alert("hi");
}
In this function if the player is dead it calls the explode animation.
function Loop(){
if (isPlaying == true)
{
//document.addEventListener('click', pauseClicked ,false); //WARNING REMOVE THIS WHEN YOU CLICK MENU OR EXIT LEVEL IN ANYWAY
Platforms = [];
Lavas = [];
Flags = [];
Teleporters = [];
Prepare();
if(level == 1)
{
Level1();
}
else if(level == 2)
{
Level2();
}
else if (level ==3)
{
Level3();
}
else if (level == 4)
{
Level4();
}
else if (level ==5)
{
Level5();
}
else if (level ==6)
{
Level6();
}
else if (level ==7)
{
Level7();
}
else if (level ==8)
{
Level8();
}
else if (level ==9)
{
Level9();
}
else if (level ==10)
{
Level10();
}
else if (level ==11)
{
Level11();
}
else
{
stopLoop();
}
if(ElevatorOn == true)
{
drawElevators();
}
if(LavaElevatorOn == true)
{
drawLavaElevators();
}
if(TeleportersOn == true)
{
drawTeleporters();
}
movePlayer();
checkCol();
if(Death == false)
{
drawPlayer();
}
drawGUI();
if(Death ==true)
{
DrawSpawnAnimation();
requestAnimFrame(Loop);
}
else
{
requestAnimFrame(Loop); //this calls it again
}
}
}

I don't have time to look at the animation frame problem right now, but there are two other things you should definitely do:
Format and indent your code. It's not very consistent. There are many JavaScript beautifiers you can find with a search for "javascript beautifier". Pick one and run your code through it, and then as you make future changes keep the formatting consistent—or run it through the beautifier again.
Simplify, simplify, simplify! For example, consider this code (reformatted here):
if( level == 1 ) {
Level1();
} else if( level == 2 ) {
Level2();
} else if( level == 3 ) {
Level3();
} else if( level == 4 ) {
Level4();
} else if( level == 5 ) {
Level5();
} else if( level == 6 ) {
Level6();
} else if( level == 7 ) {
Level7();
} else if( level == 8 ) {
Level8();
} else if( level == 9 ) {
Level9();
} else if( level == 10 ) {
Level10();
} else if( level == 11 ) {
Level11();
} else {
alert( "Game over - Still in development - Wayne Daly 2013" );
stopLoop();
}
You can replace all that code with:
var levelFun = levelFunctions[level];
if( levelFun ) {
levelFun();
} else {
alert( "Game over - Still in development - Wayne Daly 2013" );
stopLoop();
}
and then where you have all the Level(), Level2(), etc. functions defined, replace them all with:
var levelFunctions = [
null, // there is no level 0
function() {
// level 1 function
},
function() {
// level 2 function
},
...
];
You can also simplify that long list of if(ExplodeFrame == N) tests to all use a common bit of code. Just calculate the second parameter to ctxAnimation.drawImage() with ( ExplodeFrame - 5 ) * 100 + 6 instead of all the if tests and hard coded values.

Related

My HTML5 canvas game keeps blinking in between frames

I've started working on an HTML5 RPG canvas game recently, and decided to make a "text-box" sort of thing, but when once I programmed it, it started blinking between the blue and text box every other frame. What could have caused this?
Code: https://github.com/Codezters/RPG-Game-1
Important Code (I think most of the player movement stuff is irrelevant though):
function update() {
if (realm == 'overworld') {
cc.fillStyle='blue';
cc.fillRect(0,0,c.width,c.height);
cc.drawImage(bob, x, y);
// Player Walk Animations
if (direction == 'up' && idleness == false) {
if (walkstage > 0 && walkstage <4) {
document.getElementById("source").src = "IdleMoveUP1.png"
}
else if (walkstage > 3 && walkstage < 7) {
document.getElementById("source").src = "IdleUP.png"
}
else if (walkstage > 6 && walkstage < 10) {
document.getElementById("source").src = "IdleMoveUP2.png"
}
}
else if (direction == 'right' && idleness == false) {
if (walkstage > 0 && walkstage <4) {
document.getElementById("source").src = "IdleMoveRIGHT1.png"
}
else if (walkstage > 3 && walkstage < 7) {
document.getElementById("source").src = "IdleRIGHT.png"
}
else if (walkstage > 6 && walkstage < 10) {
document.getElementById("source").src = "IdleMoveRIGHT2.png"
}
}
else if (direction == 'left' && idleness == false) {
if (walkstage > 0 && walkstage <4) {
document.getElementById("source").src = "IdleMoveLEFT1.png"
}
else if (walkstage > 3 && walkstage < 7) {
document.getElementById("source").src = "IdleLEFT.png"
}
else if (walkstage > 6 && walkstage < 10) {
document.getElementById("source").src = "IdleMoveLEFT2.png"
}
}
else if (direction == 'down' && idleness == false) {
if (walkstage > 0 && walkstage <4) {
document.getElementById("source").src = "IdleMoveDOWN1.png"
}
else if (walkstage > 3 && walkstage < 7) {
document.getElementById("source").src = "IdleDOWN.png"
}
else if (walkstage > 6 && walkstage < 10) {
document.getElementById("source").src = "IdleMoveDOWN2.png"
}
}
if (idleframe == 8) {
if (direction == 'down') {
document.getElementById("source").src = "IdleDOWN.png"
idleframe = 0;
idleness = true;
}
else if (direction == 'up') {
document.getElementById("source").src = "IdleUP.png"
idleframe = 0;
idleness = true;
}
else if (direction == 'right') {
document.getElementById("source").src = "IdleRIGHT.png"
idleframe = 0;
idleness = true;
}
else if (direction == 'left') {
document.getElementById("source").src = "IdleLEFT.png"
idleframe = 0;
idleness = true;
}
if (talking == true) {
if (wordcount != textBoxTest.length) {
cc.drawImage(textBox, 0, 400);
cc.fillStyle = "white";
console.log("this is working")
cc.fillText(counted, 0, 100);
counted += textBoxTest[wordcount]
wordcount++;
}
else if (EnterToggle == true) {
EnterToggle = false;
talking = false;
}
Game so far: https://codezters.github.io/RPG-Game-1/
Solution:
I didn't need to clear the canvas when nothing was happening, so I made it clear less frequently and the problem was fixed.
The HTML is completely wrong for a start, with tags in the wrong places and obsolete elements. I mean no offense, we all have to start somewhere, but you should complete a basic course in HTML and JavaScript before attempting this. MDN is a great place to start.
You're changing the src attribute of img tags, you shouldn't be doing that at all. Use a different Image object for each file and make your code choose which image to draw instead. This ensures all images are loaded once before the game starts and not every time you change it. Loading can take place asynchronously and cause errors where the image is not ready to be drawn yet when you try to.
You also have this code:
window.onload= function() {
c=document.getElementById('gc');
document.addEventListener("keydown",keyPush)
cc=c.getContext('2d');
setInterval(update,1000/30);
};
Since you run update through setInterval, you both update and draw the game 33 times per second. You should have an independent function which takes care of drawing which is called with requestAnimationFrame(draw). This will make sure the browser only draws frames when it can, and skips drawing when the computer is having trouble keeping up. Go read the documentation on requestAnimationFrame for more info.

Why this jquery else if statements are not working?

Could you please take a look at this? It does not work. I can not figure out why.
$(document).ready(function() {
var result = parseInt($('#kmi').text());
if (result < 18, 5) {
$("#line1").css("background-color", "#eee");
} else if (result >= 18, 5 && result < 24, 9) {
$("#line2").css("background-color", "#eee");
} else if (result >= 25 && result = < 29, 9) {
$("#line3").css("background-color", "#eee");
} else if (result >= 30 && result = < 34.9) {
$("#line4").css("background-color", "#eee");
} else if (result >= 35 && result = < 39.9) {
$("#line5").css("background-color", "#eee");
} else if (result >= 40) {
$("#line6").css("background-color", "#eee");
} else {
$("#line1").css("background-color", "#fff");
}
}
});
first of all you should change comma to dot and you have used => instead of <= and don't use much else if statement you can use one class property for all lines because all CSS having same property background-color, "#eee" something like this , please check the condition for if statement
$(document).ready(function(){
var result = parseInt($('#kmi').text());
if(result<18.5 || result>=40){
$(".lines").css("background-color", "#eee");
}else{
$("#line1").css("background-color", "#fff");
}
}
});
You wrote => instead of <= where the former one will be considered as an assignment operator and there was an extra } closing braces.
$(document).ready(function() {
var result = parseInt($('#kmi').text());
if (result < 18, 5) {
$("#line1").css("background-color", "#eee");
} else if (result >= 18.5 && result < 24.9) {
$("#line2").css("background-color", "#eee");
} else if (result >= 25 && result <= 29.9) {
$("#line3").css("background-color", "#eee");
} else if (result >= 30 && result <= 34.9) {
$("#line4").css("background-color", "#eee");
} else if (result >= 35 && result <= 39.9) {
$("#line5").css("background-color", "#eee");
} else if (result >= 40) {
$("#line6").css("background-color", "#eee");
} else {
$("#line1").css("background-color", "#fff");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

js game freezes with no error

I am working on a javascript game that involves building, destroying, and survival.
It has been working fine but after adding trees the game would randomly freeze after breaking blocks.
The code is here:
for (var bl in blocks) {
if (mouse.x >= blocks[bl].x-camera.x && mouse.y >= camera.y+blocks[bl].y && mouse.x <= blocks[bl].x-camera.x+64 && mouse.y <= camera.y+blocks[bl].y+64) {
document.body.style.cursor = "pointer";
if (mouse.down) {
if (!blocks[bl].d && blocks[bl].d !== 0) {
blocks[bl].d = 32;
} else if (blocks[bl].d > 0) {
blocks[bl].d -= 0.5;
if (tools[player.tool].n === 'axe') {
blocks[bl].d -= 1;
}
} else {
var fb = false;
for (var i in inventory) {
if (inventory[i].n === blocks[bl].n) {
inventory[i].a ++;
fb = true;
}
}
if (!fb) {
inventory.push({n: blocks[bl].n, a: 1});
}
blocks.splice(bl, 1);
}
}
}
}
I don't see any way there could be an infinite loop and no errors show up when it happens.
EDIT
I changed the code to
var spliceblock = {bl: 0, s: false};
for (var bl in blocks) {
if (mouse.x >= blocks[bl].x-camera.x && mouse.y >= camera.y+blocks[bl].y && mouse.x <= blocks[bl].x-camera.x+64 && mouse.y <= camera.y+blocks[bl].y+64) {
document.body.style.cursor = "pointer";
if (mouse.down) {
if (!blocks[bl].d && blocks[bl].d !== 0) {
blocks[bl].d = 32;
} else if (blocks[bl].d > 0) {
blocks[bl].d -= 0.5;
if (tools[player.tool].n === 'axe') {
blocks[bl].d -= 1;
}
} else {
var fb = false;
for (var i in inventory) {
if (inventory[i].n === blocks[bl].n) {
inventory[i].a ++;
fb = true;
}
}
if (!fb) {
inventory.push({n: blocks[bl].n, a: 1});
}
spliceblock.s = true;
spliceblock.bl = bl;
//blocks.splice(bl, 1);
}
}
}
}
if (spliceblock.s) {
blocks.splice(spliceblock.bl, 1);
}
but it still freezes randomly when trying to break blocks.
Modifying an array (using splice) while you're iterating through it is bound to cause problems. If you remove the block bl from the array and then continue to run through it, the counter will probably be off.
Instead, store the index of the block you're removing, then remove it after you're done looping through the blocks.

How to show a div depending on the numbers of games

I have a question and I can't resolve it. Can you help me please?
So my php code :
$aTicketsGames = array(134, 137, 165, 136, 177, 181, 190);
$b_isRapidGame = false;
if(in_array($i_jeu, $aTicketsGames)){
$b_isRapidGame = true;
}
In .js after click on the button I do :
if(obj.google_analytics.is_rapid_game == true){
var i++;
if(i == 10){
document.getElementById('div1').setAttribute('class','display-block');
}
if(i==20){
document.getElementById('div2').setAttribute('class','display-block');
}
}
The idea is : suppose I have a variable i signifying the number of games played.
if i = 10,30,50,70,90.... show div1.
if i = 20,40,60,80,100.... show div2.
I'm newbie in .js and I have no idea how to impliment this. Help me please!!!!
Thx in advance.
Use style instead of class and use % for the if condition. Also, i should be set globally not locally.
var i = 0;
if(obj.google_analytics.is_rapid_game == true){
i++;
if(i % 20 == 10){
document.getElementById('div1').setAttribute('style','display-block');
}
else if(i % 20 == 0 && i > 0){
document.getElementById('div2').setAttribute('style','display-block');
}
}
See comments inline:
var i = 0; // Define it out of `if`.
if (obj.google_analytics.is_rapid_game === true) {
i++; // Increment by 1
if (i && (i % 20) === 0) { // If divisible by 20
$('#div2').show(); // Show `div2`
// OR
$('#div2').addClass('display-block'); // Add Class
} else if (i && (i % 10) === 0) { // If divisible by 10
$('#div1').hide(); // Hide `div1`
// OR
$('#div1').removeClass('display-block'); // Remove Class
}
}
var i = 0;
if (obj.google_analytics.is_rapid_game === true) {
i++;
if ((i % 20) === 0) {
$('#div2').show();**//or** $('#div2;).css('display','block');
$('#div1').hide();**//or** $('#div1;).css('display','none');
} else if ((i % 10) === 0) {
$('#div1').show();
$('#div2').hide();
}
}

How to move an element in javascript automatically with while loop?

I am making a Snake game so I'm trying to move my snake. It is moving with keys but it should move automatically on the screen. I tried doing that with while loops like in the code below but because of break; I have to press a key every time I want it to move. How can I make it move automatically? I tried removing break; an using an if statement but I didn't succeed.
Any other solutions or something else?
I'm new to programming so any advices would be helpful.
var main = function() {
var i = 0;
var j = 0;
$(document).keyup(function(event) {
var e = event.which;
while(i == 1) {
$('.snake').animate({left: '+=10px'}, 10);
break;
}
while(i == 2) {
$('.snake').animate({left: '-=10px'}, 10);
break;
}
while(i == 3) {
$('.snake').animate({top: '-=10px'}, 10);
break;
}
while(i == 4) {
$('.snake').animate({top: '+=10px'}, 10);
break;
}
//Which key is preesed
//D
if(e == 68) {
i = 1;
}
//A
else if(e == 65) {
i = 2;
}
//W
else if(e == 87) {
i = 3;
}
//S
else if(e == 83) {
i = 4;
}
//Any other key
else {
i = 0;
}
});
};
$(document).ready(main);
I think you just have to organize a little bit your code.
First. You must put your code inside a function. You really don't need a while. You can use a simple if.
function move(i) {
if(i == 1) {
$('.snake').animate({left: '+=10px'}, 10);
break;
}
if(i == 2) {
$('.snake').animate({left: '-=10px'}, 10);
break;
}
if(i == 3) {
$('.snake').animate({top: '-=10px'}, 10);
break;
}
if(i == 4) {
$('.snake').animate({top: '+=10px'}, 10);
break;
}
}
Now you have to change the event, using keydown instead of keyup
function main() {
var interval;
$(document).keydown(function(event) {
if(interval) clearInterval(interval); // Clear the previous interval
var e = event.which;
var i;
//Which key is pressed
//D
if(e == 68) {
i = 1;
}
//A
else if(e == 65) {
i = 2;
}
//W
else if(e == 87) {
i = 3;
}
//S
else if(e == 83) {
i = 4;
}
//Any other key
else {
i = 0;
}
interval = setInterval(function() {
move(i)
},1000); // repeat every 1 second
});
}
$(document).ready(main);

Categories

Resources