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.
Related
I am building a platforming game in JavaScript.
For some reason, when my character lands on a platform, the character will then begin alternating between doing a very small jump, and then do a full-sized jump. I want it to do a full-sized jump every time. Why isn't this working?
Here's my code:
if (isCollideY(platforms[i].getBoundingClientRect(), document.getElementById('spriteNotReal').getBoundingClientRect()) == true) {
if (falling == true && (jumping == false)) {
moveY = platforms[i].getBoundingClientRect().y + 3;
momentumY = 0;
onSolidGround = true;
}
}
if (event.code == 'KeyW' && (onSolidGround == true)) {
momentumY = momentumY + 20;
onSolidGround = false;
falling = false;
jumping = true;
}
else if (onSolidGround == false) {
if (momentumY < 0) {
falling = true;
}
else if (momentumY > 0) {
jumping = true;
}
else {
jumping = false;
}
moveX += momentumX / 3 + 1;
document.getElementById("spriteNotReal").src = "jumpmain.gif";
}
This is most likely an issue with your booleans for jumping / falling / onSolidGround. Most likely the character is somehow being flagged as something other than
onSolidGround = true;
jumping = false;
falling = false;
When the first jump is taking place.
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
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.
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();
}
}
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!