Text animation with p5.js and js lagging - javascript

I have the following code which uses parts of the p5.js library to animate some text in a fade in - fade out manner (which keeps looping indefinetely), i also inserted an image to make things clearer.
The problem is that after the first loop is done (when the whole text appears and then starts to disappear) i have severe lag in the browser, although it still works fine and keeps looping. Im not sure if there is a mistake in my code that threw the calculations off or if it's simply too heavy for the browser to run.
All of my vars are self explanatory, but if you have any questions or require another part of my script by all means ask me.
Any ideas that could help my case? Thank you.
//FADE animation /w Loop
if ((animType == "FADE") && (animeLoop == true)) {
if (animDirection == true) {
for (i=0; i<userText.length; i++) {
word = userText[i].html();
posXcalc = 0;
for (j=0; j<word.length; j++) {
textColor.setAlpha(charsOpacity[i][j]);
fill(textColor);
textSize(userSize);
text(word[j], userPosX + posXcalc, userPosY + (i * (userSize + userLeading)));
posXcalc = posXcalc + textWidth(word[j]);
if (charsOpacity[charsOpacity.length-1][charsOpacity[charsOpacity.length-1].length-1] < 255) {
//console.log("going");
if ((i == 0) && (j == 0) && (charsOpacity[i][j] < 255)) {charsOpacity[i][j] = charsOpacity[i][j] + speed;}
else if ((j == 0) && (i != 0)) {
temp = charsOpacity[i-1].length;
if ((charsOpacity[i-1][temp-1] > 50) && (charsOpacity[i][j] < 255)) {charsOpacity[i][j] = charsOpacity[i][j] + speed;}
}
else if (charsOpacity[i][j-1] > 50) {charsOpacity[i][j] = charsOpacity[i][j] + speed;}
}
else {animDirection = false;}
}
}
}
else {
for (i=0; i<userText.length; i++) {
word = userText[i].html();
posXcalc = 0;
for (j=0; j<word.length; j++) {
textColor.setAlpha(charsOpacity[i][j]);
fill(textColor);
textSize(userSize);
text(word[j], userPosX + posXcalc, userPosY + (i * (userSize + userLeading)));
posXcalc = posXcalc + textWidth(word[j]);
if (charsOpacity[charsOpacity.length-1][charsOpacity[charsOpacity.length-1].length-1] > 0) {
console.log("going");
if ((i == 0) && (j == 0) && (charsOpacity[i][j] > 0)) {charsOpacity[i][j] = charsOpacity[i][j] - speed;}
else if ((j == 0) && (i != 0)) {
temp = charsOpacity[i-1].length;
if ((charsOpacity[i-1][temp-1] < 200) && (charsOpacity[i][j] > 0)) {charsOpacity[i][j] = charsOpacity[i][j] - speed;}
}
else if (charsOpacity[i][j-1] < 200) {charsOpacity[i][j] = charsOpacity[i][j] - speed;}
}
else {animDirection = true;}
}
}
}
}

Okay, after a lot of trial and error i found the problem, i was missing a check in the sencond else if statement and the array was recieving values much bigger than the range of the 255 (which is the cap for the setAlpha() function) that must have create the severe lag since it had to keep adding all those values and propably recalculate the alpha inside its own function

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.

How can I avoid heap out of memory?

I wrote this code to get ended my homework as a practice.
This code controls browser with nightmare.js.It just iterates clicking button and waiting for a sec.
But this code issued an error of heap out of memory. I just tried out "--max-old-space-size=4096". but it didn't work...
ANYONE HELP ME??
I checked other than iterations can work. Then putting iterations..., it cannot work due to heap out of memory.
To be honest, I am not good at coding and English. If there are any miswriting, ask me please!
const Nightmare = require('nightmare');
const nightmare = Nightmare({show: true});
const LinguaURL = "";
const NumberOfMine = "";
const PwdOfMine = "";
var i,j = -1;
var selection, progress;
var radioSelect = -1;
function main() {
nightmare
.goto(LinguaURL)
.wait(1000)
.type("input[type='text']", NumberOfMine)
.type("input[type='password']", PwdOfMine)
.click("input[type='submit']")
.wait(5000)
.click('a[href="javascript:document.Study.submit()"]')
.wait(3000)
.click("input[type='button']")
.wait(3000);
for(i = 3;i<43;i++){
nightmare
.click('a[onclick="unit_view_page(\''+i.toString()+'\');"]');
while(true){
j++;
if(j % 4 == 0){
nightmare
.click('input[onclick="select_unit(\'drill\', \''+(1833+j).toString()+'\', \'\');"]')
.wait(1000);
while(true){
radioSelect++;
nightmare
.click('input[id="answer_0_' + radioSelect.toString() +'"]')
.wait(1000)
.click('input[id="ans_submit"]')
.wait(1000)
.evaluate(function (){
return selection = document.querySelector('.btn btn-answer-view form-font-size');
})
.evaluate(function (){
return progress = document.querySelector('btn btn-next-problem form-font-size');
});
if(selection == null && progress == null)break;
if(selection != null){
continue;
}else{
nightmare
.click('input[class="btn btn-next-problem form-font-size"]');
continue;
}
}
if((j + 1) % 10 == 0)break;
}
}
}
nightmare
.wait(100)
.end()
.then(console.log);
}
main();
If I'm not mistaken, I think this is the reason.
function main() {
for(i = 3;i<43;i++){
while(true){
j++;
if(j % 4 == 0){
while(true){
/**** break for the second while. ****/
if(selection == null && progress == null) break;
if(selection != null){
continue;
}else{
continue;
}
}
/**** break for the first while. ****/
// But this code will be run if 'j % 4 == 0',
// and I can't see any assigned the value to 'j' variable inside of 'if'.
// There's no way the result will be true.
if((j + 1) % 10 == 0) { break; }
}
}
}
}
var j = -1;
var limit = 2000 * 4;
while(true){
j++;
if(j != 0 && j % 1000 == 0) console.log("loop: " + j);
// here we go.
if(j % 4 == 0){
while(true){
break;
}
// But this code will be run if 'j % 4 == 0',
// and I can't see any assigned the value to 'j' variable inside of 'if'.
// There's no way the result will be true.
if((j + 1) % 10 == 0) { console.log("your if statement"); break; }
// limit
if (j == limit) { console.log("break using limit"); break; }
}
// Maybe (do you just want to run ten times?)
// if((j + 1) % 10 == 0) { console.log("[maybe] your if statement"); break; }
}
console.log("process end");

More JS AI causes slower AI movement in HTML Canvas

I have a simple little game with one character as the player and four enemy characters. I created a very basic AI, that moves towards the player when the player is nearby. That all worked fine, but when I added AI-AI collision (using a bounding box model), it slowed it down tremendously, and exponentially the more AI there are. With four AI, they move quite slowly. 3 AI is a bit better. 2 is just perfect, and 1 is too fast.
I have the following function to calculate the AI movement when near a player.
function updateAI() {
for (i = 0; i < aiCount; i++) {
if (aiCounterAI >= aiCount) {
aiCounterAI = 0;
}
checkArmyAIcol = armyAI[aiCounterAI][1];
checkArmyAIrow = armyAI[aiCounterAI][2];
enemySpeed = enemies[armyAI[aiCounterAI][0][0]][3];
enemyPlayerCollision = false;
if (playerBattle.xCoord - 6 <= checkArmyAIcol && playerBattle.xCoord + 6 >= checkArmyAIcol) {
if (playerBattle.yCoord - 6 <= checkArmyAIrow && playerBattle.yCoord + 6 >= checkArmyAIrow) {
if (playerBattle.x < armyAI[aiCounterAI][3] - 48) {
armyAI[aiCounterAI][3] = armyAI[aiCounterAI][3] - enemySpeed;
aiDirection = 'left';
}
if (playerBattle.x > armyAI[aiCounterAI][3] + 48) {
armyAI[aiCounterAI][3] = armyAI[aiCounterAI][3] + enemySpeed;
aiDirection = 'right';
}
if (playerBattle.y < armyAI[aiCounterAI][4] - 48) {
armyAI[aiCounterAI][4] = armyAI[aiCounterAI][4] - enemySpeed;
aiDirection = 'up';
}
if (playerBattle.y > armyAI[aiCounterAI][4] + 48) {
armyAI[aiCounterAI][4] = armyAI[aiCounterAI][4] + enemySpeed;
aiDirection = 'down';
}
checkBattleCollision('ai',aiCounterAI);
armyAI[aiCounterAI][1] = Math.ceil(armyAI[aiCounterAI][3] / 48);
armyAI[aiCounterAI][2] = Math.ceil(armyAI[aiCounterAI][4] / 48);
}
}
aiCounterAI++;
}
}
And finally I have this function to calculate the AI collision.
if (type == 'ai') {
enemyEnemyCollision = false;
if (aiCount > 1) {
checkArmyAIcol1 = armyAI[ai][1];
checkArmyAIrow1 = armyAI[ai][2];
checkArmyAIx1 = armyAI[ai][3];
checkArmyAIy1 = armyAI[ai][4];
var aiCounter2 = 0;
for (i = 0; i < aiCount; i++) {
if (aiCounter2 != ai) {
checkArmyAIcol2 = armyAI[aiCounter2][1];
checkArmyAIrow2 = armyAI[aiCounter2][2];
checkArmyAIx2 = armyAI[aiCounter2][3];
checkArmyAIy2 = armyAI[aiCounter2][4];
// Check if the AI is near the other AI before checking if collision is true
if (checkArmyAIcol1 - 1 <= checkArmyAIcol2 && checkArmyAIcol1 + 1 >= checkArmyAIcol2) {
if (checkArmyAIrow1 - 1 <= checkArmyAIrow2 && checkArmyAIrow1 + 1 >= checkArmyAIrow2) {
if (checkArmyAIx1 < checkArmyAIx2 + 48 &&
checkArmyAIx1 + 48 > checkArmyAIx2 &&
checkArmyAIy1 < checkArmyAIy2 + 48 &&
checkArmyAIy1 + 48 > checkArmyAIy2) {
enemyEnemyCollision = true;
checkEnemyEnemyCollision(ai,aiCounter2);
}
}
}
}
aiCounter2++;
}
}
}
function checkEnemyEnemyCollision(enemy1,enemy2) {
enemySpeed = enemies[armyAI[enemy1][0][0]][3];
if (enemyEnemyCollision == true) {
if (aiDirection == 'left') {
armyAI[enemy1][3] = armyAI[enemy1][3] + enemySpeed;}
if (aiDirection == 'right') {
armyAI[enemy1][3] = armyAI[enemy1][3] - enemySpeed;}
if (aiDirection == 'up') {
armyAI[enemy1][4] = armyAI[enemy1][4] + enemySpeed;}
if (aiDirection == 'down') {
armyAI[enemy1][4]= armyAI[enemy1][4] - enemySpeed;}
console.log("ya'll collided ya clumsy potatoes");
}
}
The updateAI function is fast and runs great. Adding the collision (using a bounding box model) as said before slows it down a lot. These functions are called sixty times a second, through requestAnimationFrame in my gameloop. My guess is that it can't keep up fast enough in the collision with the frame rate so they just can't move much as they could otherwise. Yet, I don't know how to fix this. Does anyone have any suggestions? Bounding box collision and multiple moving items is new territory for me so I wouldn't mind suggestions on improving my code.

Printing previous answers

I am creating a game where the user has to try and guess the combination of a code. I want the user to be able to see his previous attempts that he has had. However at the moment I can only get the div box's that they are in to display their most recent code.
Here is my code where the function is.
Game.countAnimals = function(playerGo){
var count = {bulls:0, cows:0};
Game.counter = 1;
for (var i = 0; i < playerGo.length; i++) {
var digPresent = playerGo.indexOf(Game.score[i]);
if (playerGo[i] == Game.score[i]) {count.bulls++;}
else if (digPresent>=0) {count.cows++;}
Game.counter++
if (count.bulls == playerGo.length && Game.counter < 7){
console.log("you have won")}
else if (count.bulls !== playerGo.length && Game.counter < 7) {
console.log("Sorry Homes")}
else if (count.bulls !== playerGo.length && Game.counter > 7 ){console.log ("you lose");}
}
$(".scoreboard1").html(count.cows);
$(".scoreboard2").html(count.bulls);

Need to find equation for moving towards something on a grid

Ok, I wrote a script that let's you move around and what not on a grid made up of a bunch of put together 'x' letters. So you know what it looks like, here is the JS that makes it:
function generate_page() {
var x = 0;
var y = 0;
var lines = 20;
var output;
while (x <= lines) {
while( y <= lines*2){
if (x == 0 && y == 1) {
output = "<span id='x" + x + "_" + y + "' style='background-color: red'>o</span>";
} else if (x == 3 && y == 5) {
output = "<span id='x" + x + "_" + y + "' style='background-color: green'>z</span>";
} else {
output = ("<span id='x" + x + "_" + y + "'>x</span>");
}
$('#board').append(output);
y++;
}
y = 0;
x++;
$('#board').append('<br />');
}
}
Now, I have a green character on the board that I'm trying to program to go towards the red one that you control. I have the North, South, East, and West functions worked out. However, for the life of me, I can not figure out the little algorithm to make one go towards the other.I have tried with the following, but it doesn't work what-so-ever. Could anyone help me come up with a way for one character to track another? Here is my failed attempt:
function moveGreen() {
var x_distance = currentX_green - currentX_red;
var y_distance = currentY_green - currentY_red;
var larger;
if (x_distance > y_distance) {
larger = 'x';
} else if (y_distance > x_distance) {
larger = 'y';
} else {
larger = 'o';
}
if (larger == 'x') {
if (x_distance > 0){
north('green');
} else {
south('green');
}
} else if (larger == 'y'){
if (y_distance > 0) {
west('green');
} else {
east('green');
}
} else if (larger == 'o'){
if (y_distance > 0){
east();
} else if (y_distance == 0) {
if (x_distance > 0) {
north();
} else {
south();
}
} else {
west();
}
}
}
Edit: Here is the current program. Ignore the green moves on red stuff.
Edit 2: Ok, I updated the problems with the west and stuff without green. Here is the new code:
function moveGreen() {
var x_distance = currentX_green - currentX_red;
var y_distance = currentY_green - currentY_red;
var larger;
if (Math.abs(x_distance) > Math.abs(y_distance)) {
larger = 'x';
} else if (Math.abs(y_distance) > Math.abs(x_distance)) {
larger = 'y';
} else {
larger = 'o';
}
if (larger == 'x') {
if (x_distance > 0){
north('green');
} else {
south('green');
}
} else if (larger == 'y'){
if (y_distance > 0) {
west('green');
} else {
east('green');
}
} else if (larger == 'o'){
if (y_distance > 0){
east('green');
} else if (y_distance == 0) {
if (x_distance > 0) {
north('green');
} else if (x_distance < 0){
south('green');
}
} else {
west('green');
}
}
}
one obvious issue is that you need to check the absolute values near the top.
instead of
if (x_distance > y_distance) {
larger = 'x';
} else if (y_distance > x_distance) {
you need
if (Math.abs(x_distance) > Math.abs(y_distance)) {
larger = 'x';
} else if (Math.abs(y_distance) > Math.abs(x_distance)) {
since you still want the "biggest" even if it's negative.
update now it stops where x=y. looking at the code there's no "green" in the argument to east etc for that case.
update well, now it goes wrong when it's on a diagonal so i would guess east/west are the wrong way round for the "o" case (and indeed, they are not consistent with the "y" case). looks a lot nicer now!

Categories

Resources