Why is game time shortened by half instead of 2 seconds? - javascript

I am trying to build a game in pure JavaScript as an exercise.
The game purpose is to answer a random math exercise before a timer runs out. The time is represented by an egg that falls on someones head; if you answered all of the math exercises correctly, you will start over, but the time will be shortened by 2 seconds.
My problem: During level 1 of the game, the time works as expected, but by level 2 time is getting shorter by half. What is causing this to happen?
Related code:
var gameTime;
//function responsible for starting The game
function StartGame() {
...
...
...
checkLevel();
getNewTime();
speed=getNewSpeed();
dh=setInterval("move(egg)",gameTime);
...
}//End start game
function checkLevel() {
if(document.getElementById("begginer").checked==true) {
fillNumbervalue(true);
gameTime=30;
}
else {
fillNumbervalue(false);
gameTime=60;
} //End else
}//End of checkLevel
function getNewSpeed () {
return (distanceBetweenEggToYudale/gameTime); //distanceBetweenEggToYudale=310
}//End function
//if player pass level this function will get down by 2 seconds the time
function getNewTime() {
for(var i=0;i<levelCount;i++)
gameTime-=2;
}//end getNewTime
//function responsible for moving The Egg
function move(eggBall) {
eggBall.imagePositionY=eggBall.imagePositionY+(gameTime/1000)*speed;
//image postion=0 at the beginning
eggBall.element.style.top=eggBall.imagePositionY+"px";
...
...
}//End move
//when the player push the answer button
function answerValidation() {
var answers=new Array();
for(var i=0;i<result.length;i++)
answers[i]=document.getElementById("txtAnswer"+(i+1)).value;
if(result[0]!=answers[0] || result[1]!=answers[1] || result[2]!=answers[2])
gameOverScreen();
else
{
score++;
levelCount++;
init(); //Initial the egg position onload of the body element
clearTxtRows();
gameTime-=2;
StartGame();
}//End else
}//End anwser validation
I know this question is loaded with code, so I would really appreciate if someone can help.

The problem is that you're reusing your gameTime variable, when what you want to do is start at the same time and decrement from that. So you want a startGameTime variable.
With only a gameTime variable:
http://jsfiddle.net/DPTJ3/1/
With a startGameTime variable to restart the gameTime value before decrement:
http://jsfiddle.net/DPTJ3/
function getNewTime() {
gameTime = startGameTime;
for (var i = 0; i < levelCount; i++) {
gameTime -= 2;
}
}
function logData() {
log = document.getElementById('log');
log.innerHTML += "LEVEL: " + levelCount + "\nGTIME: " + gameTime + "\n\n";
}
var levelCount = 1;
var startGameTime = 60;
var gameTime = 60;
logData();
for (var i = 0; i < 10; i++) {
levelCount++;
getNewTime();
logData();
}
OUTPUT
LEVEL: 1
GTIME: 60
LEVEL: 2
GTIME: 56
LEVEL: 3
GTIME: 54
LEVEL: 4
GTIME: 52
LEVEL: 5
GTIME: 50
LEVEL: 6
GTIME: 48
LEVEL: 7
GTIME: 46
LEVEL: 8
GTIME: 44
LEVEL: 9
GTIME: 42
LEVEL: 10
GTIME: 40
LEVEL: 11
GTIME: 38
EDIT
Also, if you want to accurately decrement, you should probably account for the fact that the first level is really 0 instead of one to the getNewTime() function. If you notice, it seems to decrement the first by two level degrees. To resolve this, you can:
for (var i = 0; i < levelCount - 1; i++) { // Notice the - 1

Related

How to do a countdown with randomized time intervals, stopping at zero?

i would like to add another counter in this code:
function animateValue(id) {
var obj = document.getElementById(id);
var counter = getLocalStoregaValue();
var current = counter ? +counter : obj.innerHTML;
obj.innerHTML = counter;
setInterval(function() {
var counter = current--;
obj.innerHTML = counter;
localStorage.setItem('counter', counter);
}, 1000);
}
function getLocalStoregaValue() {
return localStorage.getItem('counter');
}
animateValue('value');
I would like it to scale once every second (as in this case) and once every 5 seconds. How can I? And then, how can I make it stop at 0? So without negative numbers. Thank you very much.
EDIT: I explained myself wrong.
I would like a single counter that drops in number from a minimum of 10 to a maximum of 20.
Example: the counter marks 50. After 15 seconds it marks 49. After 18 seconds it marks 48. After 11 seconds it marks 47. And so up to 0.
I hope I explained myself well this time :)
Ok, I was interrupted while posting my answer. Here now the explanation:
I left out the localStorage part of your question and concentrated on the generation of "independent countdowns" first:
function cntdwn(sel,stp,intv){
let el=document.querySelector(sel),
n=el.textContent-stp,
cd=setInterval(()=>{
el.textContent=n;
if((n-=stp)<0) clearInterval(cd);
}, intv);
}
cntdwn('#one',1,1000) ;
setTimeout(()=>cntdwn('#two',1,3000), 12000);
<p>first countdown:<br>step: 1, interval: 1s</p>
<p id="one">15</p>
<p>second countdown:<br>step: 1, action after: 15, 18, 21, 24 ... s (as mentioned in comment)</p>
<p id="two">50</p>
The cntdwn() function provides a scope in which individual countdowns can be set up for arbitrary DOM elements, each with their own counter (it starts with the value found in the DOM element), step-width and interval (in milliseconds).
Each countdown is generated with let cd=setInterval(...). The reference cd can then be used to stop the countdown (in clearInterval(cd)), once the value of n is found to be below zero.
Edit:
Assuming you made a typo in your sequence of intervals and you really meant: 15, 18, 21 seconds, then the edited second countdown should be the correct solution.
I used a setTimeout() function to delay the action by 12 seconds, then, after the first of the regular 3 second intervals (i. e. after a total of 15 seconds) the first change occurs. The countdown then continues in 3 second intervals until it reaches zero.
Yet another edit:
Ok, so you want: "A countdown with random time intervals (range 10 to 20s each) that will stop at zero"
This should do it:
function cntdwn(sel,int1,int2){
let el=document.querySelector(sel),
n=el.textContent-1,
cd=()=>setTimeout(()=>{
el.textContent=n;
if(n--) cd();
}, 1000*(int1+Math.random()*(int2-int1)));
cd();
}
cntdwn('#one',10,20);
<p>countdown:<br>step: 1, intervals: between 10 and 20 s</p>
<p id="one">5</p>
If you can use ES2017, you can use an asynchronous function to do it, like this:
async function animateValue(id) {
function timeout(t){
return new Promise(r => setTimeout(r, t))
}
var obj = document.getElementById(id);
var counter = getLocalStoregaValue();
for(let i = +counter || +obj.innerHTML || 0; i >= 0; i--){
obj.innerHTML = i;
localStorage.setItem('counter', i);
await timeout((Math.random() * 10 + 10) * 1000); //Pause for 10 to 20 seconds. For an integer second value, wrap `Math.random() * 10` into a `Math.floor` call
};
}
function getLocalStoregaValue() {
return localStorage.getItem('counter');
}
animateValue('value').catch(console.error);
<div id="value">50</div>
Try it (I commented out the localStorage part, as it isn't allowed in Stack Snippets):
async function animateValue(id) {
function timeout(t){
return new Promise(r => setTimeout(r, t))
}
var obj = document.getElementById(id);
var counter = getLocalStoregaValue();
for(let i = +counter || +obj.innerHTML || 0; i >= 0; i--){
obj.innerHTML = i;
//localStorage.setItem('counter', i);
await timeout((Math.random() * 10 + 10) * 1000); //Pause for 10 to 20 seconds. For an integer second value, wrap `Math.random() * 10` into a `Math.floor` call
};
}
function getLocalStoregaValue() {
//return localStorage.getItem('counter');
}
animateValue('value').catch(console.error);
<div id="value">50</div>

Select random winner with percentages

I would want to select a random winner from about 2 - 10 players.
Every player have precent chance to win. Someone have 50% and someone 10%.
Let's say we have 2 players. One player have 20% and other have 80%. How do I select winner between these two?.
Players are in array
var players = {
player1: {
chance: 20 //%
}
player2: {
chance: 80 //%
}
}
//Select winner from json
(Assuming the percentages all add up to 100)
You would first have to order the players. Then take a random number from 1 to 100, and find out which player that random number falls under.
For example:
// Modified json to array so we can easily loop through them
// If you would like help turning the json to an array, I can provide code for that upon request
var players = [
{
chance: 20
},
{
chance: 40
},
{
chance: 40
}
];
// Generate random number
var perc = Math.random() * 100; // between 0 and 99.999~
// Save where we are in the percentage
var currentPerc = 0;
// Loop through the players and check who the random number chose
for ( var pID = 0; pID < players.length; pID++ ) {
// Check if the current player we are looking at has won
if (perc < (players[pID].chance + currentPerc)) {
alert("PLAYER " + (pID + 1) + " HAS WON.");
// Do player winning code here
break; // break out of the loop, we're done
} else {
currentPerc += players[pID].chance;
}
}
In the above example, imagine that the random number chose 45 (0.45 * 100 since math.random gives us 0.0 to 0.99~).
This would mean that player 2 won
0 to 20 = Player 1 wins
21 to 60 = Player 2 wins
61 to 100 = Player 3 wins
Using 45 as the random number chosen The first iteration, we check if player 1 has won. He has not, so we add player 1's percentage to the "current percentage".
Then in the second iteration we check player 2. Since 45 < (20 + 40), player 2 has won chosen. We alert that he has won and will do some code for that.
var players = [20,5,15,40,20];
var getWinner = function(players){
var random = Math.random();
var sum = 0;
for(var i = 0; i < players.length; i++){
sum+= players[i]/100;
if(random<= sum) return i;
}
}
Returns the number of the player(index 0) who wins

Javascript for loop displaying more results than expected

When running the code below, the text inside the document.write runs 8 times and not 7 times as I was expected.
If I understand correctly, increment by 2 should display the positions:
20+2, 22+2, 24+2, 26+2, 28+2, 30+2 and 32+2.
Based on the results I get I assume it also displays the 34+2, which is 36. What I am missing? Thank you.
x = 20;
for (x = 20; x < 35; x += 2) {
document.write("How many times will this loop execute?" + "<br/>");
};
As noted in the comments above, The loop is correct in running 8 times. Since no one stated the reason, it is this: the x+=2 happens at the end of the loop, not at the beginning. So the loop will run for 20, 22, 24, 26, 28, 30, 32, and 34.
You are misunderstanding how the for loop works.
for ([initialization]; [condition]; [final-expression])
final-expression: An expression to be evaluated at the end of each loop iteration. This occurs before the next evaluation of condition. Generally used to update or increment the counter variable.
So your counter gets incremented at the end of the loop and the observed behaviour is correct. The loop gets executed for 20, 22, 24, 26, 28, 30, 32, and 34.
When start loop add +2 to x like below:
x = 20;
for (x = 20+2; x<35; x+=2) {
document.write("How many times will this loop execute?" + "<br/>");
};
fiddle
Script:
x = 20;
count = 1;
for (x = 20; x < 35; x += 2){
document.write("Execution: "+ (count++)+ "<br/>");
};
Output
The loop executes total 8 times.
Execution: 1
Execution: 2
Execution: 3
Execution: 4
Execution: 5
Execution: 6
Execution: 7
Execution: 8
jsfiddle link to checkout.
Yes, is executing 8 times, because is from 20 to 35 in 2 x 2
x = 20;
for (x = 20; x < 35; x += 2) {
document.write("Execute for " + x + " " + "<br/>");
};
/*
OUTPUT:
Execute for 20
Execute for 22
Execute for 24
Execute for 26
Execute for 28
Execute for 30
Execute for 32
Execute for 34
*/
If you want 7 times, you can change to 34
x = 20;
for (x = 20; x < 34; x += 2) {
document.write("Execute for " + x + " " + "<br/>");
};
It will run eight times, x iterating through every even number between 20 and 34 inclusive. You can write it like this if it helps:
var x = 20;
while (x <= 34) {
// do something
x += 2;
}
However, it is important to note that after the loop has run (whether you're using the for or while version), x will equal 36, since it is incremented to that before it finally fails the test; inside the loop, x will never equal 36. In terms of best practice, you should only really use a counter variable like x within the loop; this can be enforced by using the ES6 let keyword (which is block-scoped) like so (the example just prints out a list of the x values as DOM elements):
function appendSpanCounter(i, end) {
let el = document.createElement("span"),
content = i.toString(10);
if (i < end) content += ", ";
(typeof el.textContent === "string") // ternary operator
? el.textContent = content
: el.innerText = content;
(document.body || document.querySelector("body")).appendChild(el);
}
for (let x = 20; x <= 34; x += 2) {
appendSpanCounter(x, 34);
}
// x is now undefined here

how to make number repeatedly add in javascript

okay i guys i just got into java script and i made a simple game it works and does everything i wanted but now i want to make it difficult so that every time the enemy health is 0 it refill but comes back stronger as in it has more health this is what i came up with this is the part that makes it refill it adds 100 but only stays 200 when it refills i want it to increase by 100 every time it becomes 0
if (enemyHealth<=0) {
enemyHealth=0;
alert("you win");
gold=gold+500;
document.FGame.Output.value=gold;
enemyHealth=100+100;
}
It's because you always set the enemyHealth to 100 + 100, which will always equal 200. What you could do is to have a totalEnemyHealth variable which increase by 100 every time the enemy dies. When you revive that enemy, you would set it's health to the new totalEnemyHealth value.
//make sure not to re-initialize this variable every time
var totalEnemyHealth = 100;
//then in your function
if (enemyHealth<=0){
enemyHealth = totalEnemyHealth += 100;
alert("you win")
gold=gold+500;
document.FGame.Output.value=gold;
}
However if you have multiple ennemies, that approach will not give the desired results. To solve your problem you will need something more object-oriented, such as all ennemies represented by an Enemy instance, where the instance would have the capability of tracking how many times it died and use this as a health multiplier.
Simple example:
var Enemy = {
baseHealth: 100,
health: 100,
deathCount: 0,
takeDamage: function (amount) {
if ((this.health -= amount) <= 0) {
this.die();
this.respawn();
}
},
die: function () {
this.deathCount++;
},
respawn: function () {
this.health = (this.deathCount + 1) * this.baseHealth;
}
};
var someEnemy = Object.create(Enemy);
console.log(someEnemy.health); //100
someEnemy.takeDamage(150); //violent attack
console.log(someEnemy.health); //200
Here is an example:
http://jsfiddle.net/9zhqg/1/
var gold = 0;
for(i = 0; i < 20; i++){
var num = Math.floor(Math.random()*10);
var enemyHealth = num *i;
if (enemyHealth<=0){
//enemyHealth=0
alert(i + "you win")
gold+= 500;
//document.FGame.Output.value=gold;
enemyHealth += 100
alert(enemyHealth);
}
}
You can see when it runs, the number of times it hit 0 out of a for loop of 20 times. Then it bounces the health back to 100. I think this is what you need. - not 100% sure if I understand your use case.
You could just add a counter. Something simple like:
var counter=1; //at start of game
if (enemyHealth<=0)
{
enemyHealth=0
alert("you win")
gold=gold+500;
document.FGame.Output.value=gold;
enemyHealth=100+(100*counter);
counter++;
}

change javascript counter var to zero of a third-person website

There's a website that has a counter in it, just like file sharing sites that makes you wait till the count down finishes...well I just want to immediately set it to zero by a script or by using the Browser's Web Console or something...I just got the counter script from the source, and here is it:
var ms = 0;
var se = 17;
document.counter.d2.value = "17";
function d() {
if (ms <= 0) {
ms = 9;
se -= 1
}
if (se <= -1) {
ms = 0;
se += 1
}
else {
ms -= 1
}
document.counter.d2.value = se + "." + ms;
setTimeout("d()", 100)
}
d();
The count down time is about 17 secs (as you may have noticed in the code above). Well I tried to set the "se" (which means seconds in here) to zero with web console but nothing happens...Even I tried to set "document.counter.d2.value" to zero, nothing happens either....
Is there a way that can make this happen? Thanks in advance...

Categories

Resources