Need to find equation for moving towards something on a grid - javascript

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!

Related

JS while loop doesnt stop at true

When you run this script it shows the HP for both of the pokemon when you press 1 and click enter it subtracts your attack hit points to the enemies hit points. When you or the ememy hits 0 or less than 0 hit points it is supposed to stop and just show who won in the console log. Instead it takes an extra hit to for it to show the message.
So if you are at -10 hp it takes one more hit.
let firstFight = false;
while (!firstFight) {
let fightOptions = prompt("1. Fight, 2.Items, 3.Potions " + wildPokemon[0].name + ":" + wildPokemon[0].hp + " " + pokeBox[0].name + ":" + pokeBox[0].hp);
if (fightOptions == 1) {
if (!firstFight) {
if (wildPokemon[0].hp <= 0) {
console.log("You have won!");
firstFight = true;
} else {
let attack1 = wildPokemon[0].hp -= pokeBox[0].attack.hp;
console.log(wildPokemon[0].hp);
}
if (pokeBox[0].hp <= 0) {
console.log(wildPokemon[0] + " has killed you");
firstFight = true;
} else {
let attack2 = pokeBox[0].hp -= wildPokemon[0].attack.hp;
console.log(pokeBox[0].hp);
}
}
} else if (fightOptions == 2) {
} else if (fightOptions == 3) {
} else {
}
}
Are there any ways I can make this code more efficient?
you can simply add another if condition to check whether life of the player is still greater then '0' or less then '0' in the same turn like this.
in this way you don't have to go for next turn to check for the players life plus it rids off the extra conditional statements...
if (fightOptions == 1) {
let attack1 = wildPokemon[0].hp -= pokeBox[0].attack.hp;
console.log(wildPokemon[0].hp);
if (wildPokemon[0].hp <= 0) {
console.log("You have won!");
firstFight = true;
}
if (!firstFight){
let attack2 = pokeBox[0].hp -= wildPokemon[0].attack.hp;
console.log(pokeBox[0].hp);
if (pokeBox[0].hp <= 0) {
console.log(wildPokemon[0] + " has killed you");
firstFight = true;
}
}
}
The problem is, the points are getting subtracted after you check if they are equal to or below zero. Here is a way you can check before:
let firstFight = false;
while (!firstFight) {
let fightOptions = prompt("1. Fight, 2.Items, 3.Potions " + wildPokemon[0].name + ":" + wildPokemon[0].hp + " " + pokeBox[0].name + ":" + pokeBox[0].hp);
if (fightOptions == 1) {
wildPokemon[0].hp -= pokeBox[0].attack.hp;
if (wildPokemon[0].hp <= 0) {
console.log("You have won!");
firstFight = true;
} else {
console.log(wildPokemon[0].hp);
}
pokeBox[0].hp -= wildPokemon[0].attack.hp;
if (!firstFight && pokeBox[0].hp <= 0) {
console.log(wildPokemon[0] + " has killed you");
firstFight = true;
} else {
console.log(pokeBox[0].hp);
}
} else if (fightOptions == 2) {
} else if (fightOptions == 3) {
} else {
}
}
While loops stops when the condition is false, in you case, you set it to not false, it is not stopping because you did not explicitly determine it. There are 2 ways you can do.
1st:
while(!firstFight == false)
2nd:
var firstFight = true;
while(firstFight)
then set the firstFight to false inside your if else statements.

JS Alert when items collected?

I have created a maze game where the user must collect all the coins in the maze, however I am trying to make an alert appear once the user has collected all the coins, not in any particular order just in general. The alert is being very troublesome at the moment and not working correctly and I'm not sure where I am going wrong based off my research into the matter. I am new to JavaScript so apologies for any clear mistakes.
EDIT I GOT TOLD TO REPHRASE MY QUESTION MORE DIRECTLY - SO THIS ISN'T A DUPLICATE QUESTION. I ALSO HAVE A MAP DECLARDED BUT CANNOT UPLOAD AS IT'S TOO MUCH CODE.
Also, when I say not working correctly, it will appear at random counts as supposed to when the last reward has been collected.
var el = document.getElementById('game');
function drawWorld(){
el.innerHTML = '';
for(var y = 0; y < map.length ; y = y + 1) {
for(var x = 0; x < map[y].length ; x = x + 1) {
if (map[y][x] === 1) {
el.innerHTML += "<div class='borders'></div>";
} else if (map[y][x] === 2) {
el.innerHTML += "<div class='reward'></div>";
} else if (map[y][x] === 3) {
el.innerHTML += "<div class='ground'></div>";
} else if (map[y][x] === 5) {
el.innerHTML += "<div class='character'></div>";
} else if (map[y][x] === 4) {
el.innerHTML += "<div class='ship'></div>";
}
}
el.innerHTML += "<br>";
}
winGame();
}
function restartGame(){
window.location.reload();
}
function winGame(){
if (!map[5].includes(2) && !map[2].includes(2) &&
!map[3].includes(2) && !map[2].includes(2) && !map[4].includes(2)
&& !map[2].includes(2))
alert("Well done!");
}
drawWorld();
document.onkeydown = function(event){
if (event.keyCode === 37){
if ( map[character.y][character.x-1] !== 1){
map[character.y][character.x] = 3;
character.x = character.x - 1;
map[character.y][character.x] = 5;
drawWorld();
}
} else if (event.keyCode === 38){
if ( map[character.y-1][character.x] !== 1){
map[character.y][character.x] = 3;
character.y = character.y - 1;
map[character.y][character.x] = 5;
drawWorld();
}
} else if (event.keyCode === 39){
if ( map[character.y][character.x+1] !== 1){
map[character.y][character.x] = 3;
character.x = character.x + 1;
map[character.y][character.x] = 5;
drawWorld();
}
} else if (event.keyCode === 40){
if ( map[character.y+1][character.x] !== 1){
map[character.y][character.x] = 3;
character.y = character.y + 1;
map[character.y][character.x] = 5;
drawWorld();
}
}
console.log(map)
}

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.

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.

NaN error equation

In this javascript code I try to solve a quadratic equation, I've been working on it for an hour and this should tell me the value of a, b and c where y is a(x^2). I'm a relative javascript beginner and would love some help. Why are the values of a, b and c not numbers? The variable names are in italian, in english and in something else(Not even I know what), but I commented what they are. That's one of my bad traits as a student that usually works alone, sorry if it's not easy to understand.
<script type="text/javascript">
var equa=prompt("Scrivi l'equazione senza spazi usando x come incognita e y come x^2");
var a = 0.0; b = 0.0; c = 0.0;//ax2+bx+c
var prima = true; //before or after equal?
var ope = 1;//1add 2sub 3mul 4div
var lasto = 0.0;//last number, used for div and mul
var lastos = 3; //1a2b3c
var errore=0;//is something messed up?
for(var i = 0; i < equa.length;i=i){
if(equa.charAt(i)=='='){
prima = false;
i++;
}else if(equa.charAt(i)=='+'){
ope=1;
i++;
}else if(equa.charAt(i)=='-'){
ope=2;
i++;
}else if(equa.charAt(i)=='*'){
ope=3;
i++;
}else if(equa.charAt(i)=='/'){
ope=4;
i++;
}else{
var nume = "";//Current number in string form
while(i<equa.length && equa.charAt(i)>'0' && equa.charAt(i)<'9'){
nume+=equa.charAt(i);
i++;
}
var lasnum = 0.0;//current number in float form
var lasval = 3; //1a2b3c
if(equa.charAt(i) == 'x'){
lasnum=parseFloat(nume);
lasval = 2;
}else if(equa.charAt(i) == 'y'){
lasnum=parseFloat(nume);
lasval = 1;
}else{
lasnum = parseFloat(nume);
lasval=3;
}
i++;
if( (ope == 1 || ope == 2) && !(equa.charAt(i) =='*' || equa.charAt(i) == '/')){
if(lasval == 1){
if(prima) a+=lasnum;
else a-=lasnum;
}
else if(lasval == 2){
if(prima) b+=lasnum;
else b-=lasnum;
}
else {
if(prima) c+=lasnum;
else c-=lasnum;
}
}else if( (ope==1 || ope == 2) && (equa.charAt(i) =='*' || equa.charAt(i) == '/')){
//zitto e fermo
lasto=lasnum;
lastos=lasval;
}else if( (ope==3||ope == 4)){
if(ope==3){
if(lastos==3){
lasnum*=lasto;
}
if(lastos == 2){
if(lastval==3){
lasnum*=lasto;
lastval=2;
}
if(lastval==2){
lasnum*=lasto;
lastval=1;
}
if(lastval==1){
errore=1;
}
}
if(lastos == 1){
if(lastval == 3){
lasnum*=lasto;
lastval=1;
}else{
errore=1;
}
}
}
if(ope == 4){
if(lastos == 1){
if(lastval==3){
lasnum/=lasto;
lastval=1;
}
if(lastval==2){
lasnum/=lasto;
lastval=2;
}
if(lastval==1){
lasnum/=lasto;
lastval=3;
}
}
if(lastos == 2){
if(lastval==1){
errore=1;
}
if(lastval==2){
lasnum/=lasto;
lastval=3;
}
if(lastval==3){
lasnum/=lasto;
lastval=2;
}
}
if(lastos == 3){
if(lastval==3){
lasnum/=lasto;
}else{
errore=1;
}
}
}
if(equa.charAt(i) =='*' || equa.charAt(i) == '/'){
lasto=lasnum;
lasto=lasval;
}else{
if(lasval == 1){
if(prima) a+=lasnum;
else a-=lasnum;
}
else if(lasval == 2){
if(prima) b+=lasnum;
else b-=lasnum;
}
else {
if(prima) c+=lasnum;
else c-=lasnum;
}
lasto=0;
lastos=3;
}
}
}
}
if(errore==0){
alert("a ="+a+" b="+b+" c="+c);
}else{
alert("AOOOOOOo");
}
</script>
Since the expected input should be in the format "15y+3x+5=20" for example, then this is a simple regular expression:
var equa = prompt("Scrivi l'equazione senza spazi usando x come incognita e y come x^2");
var regex = /^([0-9.]+)y\+([0-9.]+)x\+([0-9.]+)=([0-9.]+)$/;
var matches = regex.exec(equa);
if (matches) {
var a = parseFloat(matches[1]);
var b = parseFloat(matches[2]);
var c = parseFloat(matches[3]) - parseFloat(matches[4]);
var discriminant = b*b - 4*a*c;
if (discriminant < 0) {
alert('No real solutions');
}
else {
var root = Math.sqrt(discriminant);
alert('Root: ' + ((-b + root)/(2*a)) + ', ' + ((-b - root)/(2*a)));
}
}
else {
alert("AOOOOOOo");
}

Categories

Resources