Javascript timer used in points system - javascript

I am trying to make a game. There are blocks falling and a main block which the user commands that is trying to avoid them. There is a point system that is supposed to add 10points each time the red cube touches one of the extremities. The problem is that it adds 10 points per each 10 milliseconds that the cube stays in the extremity. How can I solve this??

You just need a flag that you set and then clear whenever you touch the side.
Since the box starts touching the side, i initialized already_touched to true.
var already_touched = true;
Then your logic below becomes:
if (mySprite.x == 450 || mySprite.x == 0) {
if (!already_touched) {
already_touched = true;
count += 10;
}
var alert1 = document.getElementById("score");
alert1.innerHTML = "Score: " + count;
} else {
already_touched = false;
}
Working demo here: http://jsfiddle.net/KrZq9/

Related

How to limit the amount of bullets in a JavaScript Game?

So the question is really bad because I don't know what to ask or call what I'm trying to do, but...
I have a game I'm creating and I've added in an array for the lasers. It works fine but I want to limit the number of lasers that can be on the screen at once so the player doesn't just spam the space bar to win.
I tried limiting it by making a set number of bullets which only allows the user to shoot twice but where I tried to add back bullets once it reached the top of the canvas so they could start shooting again but it didn't work.
I assume this is because it is within the spacePressed if and so it considers spacePressed to be false so it won't run where it adds one bullet but when I put the adding bullets if outside the spacePressed it still didn't work.
I'm not sure how to go about doing what I'm trying to do and would appreciate any ideas towards fixing this. I will also have to add in later where the laser disappears upon hitting the meteor and adds back one bullet so I would also like help with figuring that out.
https://jsfiddle.net/200uaqrn/18/ <-before adding any bullets
https://jsfiddle.net/200uaqrn/19/ <-adding in my attempt to create limited bullets
if(spacePressed) {
if(lasers.y<=laserSize) {
bullets+=1;
}
else{
drawLaser();
lasers.forEach(function(laser,index){
laser.y-=laserdY;
})
}
}
Also separate question for the same project I'm going to later make multiple meteors falling at once and I assume I would use an array for that. But I don't know how to use that array to make them fall from random y cords at different times, etc.
For the laser, you can try to just set a function with timeout:
var canFire = true;
function allowFire() {
canFire = true;
}
function newLaser() {
this.x = turretX
this.y = canvas.height - 75
canFire = false;
setTimeout(allowFire, 3000);
}
document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
function keyDownHandler(e) {
if (e.keyCode === 39) {
rightPressed = true;
} else if (e.keyCode === 37) {
leftPressed = true;
}
if (e.keyCode === 32 && canFire == true) {
spacePressed = true;
lasers.push(new newLaser())
}
}
Note that 3000 is the cooldown there.
This will limit the amount of bullets at the same time in the screen, as the player will only shoot every x milliseconds, if you wanna a exact amount of bullets, you can do a var for them with the desired amount, then remove one every time that the player press space, and do a check for > 0 here: (e.keyCode === 32 && canFire == true)
For the meteors if you're going to use the array, to make them fall random you can use this function(found in Mozilla Developers):
function getRandomInt(max) {
return Math.floor(Math.random() * Math.floor(max));
}
So you can use it for the coordinates and for the time you can use a timeout(like above) with a random time too, using this(from the same source):
function getRandomArbitrary(min, max) {
return Math.random() * (max - min) + min;
}
If it's a array you can use it like getRandomArbitrary(i * 1000, i * 3000) as i being the index in a for loop. It depends on how specifically you wanna them to work, there's many ways to do that, a function that call itself, while loop, etc.
"It works fine but I want to limit the number of lasers that can be on the screen at once so the player doesn't just spam the space bar to win."
So it sounds like what you want to do is not limit the amount of bullets, but limit the ability of the player to shoot. You could ensure that some time (a tenth of a second?) must pass before the player can shoot again.
As for random numbers, see the later examples here on how to get random numbers in some range.

How to make the alert pop up after the spin results?

I'm making a very each game for school project, it should works like this:
User click spin, 3 cards will display elements
If all 3 cards matches, the balance will add $50, and pop up alert "you won!"
Otherwise, it will subtract $10 for each spin doesn't match.
If the balance fall below $10, pop up alert "you have less than $10.
I'm trying to make the alert pop up after the slots rendered and balance updated, however the alert always pop up ahead. Any idea how to fix it?
let slotsContainer = document.getElementById('slots');
let balanceContainer = document.getElementById("balance-container");
let tries = document.getElementById("tries");
const INITIAL_AMOUNT = 1000;
let values = ['❤', '🌞', '👻'];
let number_of_spinners = 3;
let spinCount = 0;
let slot_els = [];
let balance = INITIAL_AMOUNT;
balanceContainer.innerHTML = balance;
function render(result) {
slotsContainer.innerHTML = '';
for (var i = 0; i < number_of_spinners; i++) {
let spinner = document.createElement('div');
spinner.innerHTML = result[i];
slotsContainer.appendChild(spinner);
slot_els.push(spinner);
}
}
render(['?', '?', '?'])
function getOneRandomNumber() {
return Math.floor(Math.random() * values.length);
}
function spin_func() {
let firstRandomValue = getOneRandomNumber();
let secondRandomValue = getOneRandomNumber();
let thirdRandomValue = getOneRandomNumber();
render([values[firstRandomValue], values[secondRandomValue], values[thirdRandomValue]]);
if ((firstRandomValue === secondRandomValue) && (secondRandomValue === thirdRandomValue)) {
balance += 50;
balanceContainer.innerHTML = balance;
alert("you won!");
} else {
if (balance >= 10) {
balance -= 10;
balanceContainer.innerHTML = balance;
} else {
alert("You have less than $10");
}
}
console.log('spin!!!');
}
let spin_button = document.getElementById('spin');
spin_button.onclick = spin_func
The DOM is rendered asynchronously so you need to trigger the alert asynchronously.
Try replacing alert("xyz"); with setTimeout(alert, 0, "xyz"); where you are using it.
If you want the player to have time to read the result before triggering the alert, just increase the delay expressed in milliseconds from 0 to 2000 (2 seconds).
Ok. This is because the JS code runs so fast it spins but you don't see it.
This code
for (var i = 0; i < number_of_spinners; i++) {
let spinner = document.createElement('div');
spinner.innerHTML = result[i];
slotsContainer.appendChild(spinner);
slot_els.push(spinner);
}
Would need to be slowed down using a delay. The delay would need to be say 1/4 of a second per animation. Then the code would allow you to see it. Afterwhich the alert would fire and it would work as expected.
The problem here now is that you would need to make the code asynchronous.
Otherwise it still will not work.
Here is a Question of SO re a loop with a delay
How do I add a delay in a JavaScript loop?
You need to make this call your alert (finish) code when the loop completes otherwise, it still won't work.
The principle is:
run a loop that fires the animation
delay the next iteration by the animation speed say 600ms
call the alert/end code when the loop completes

JavaScript and Array's

EDIT I originally posted this with my version of the J.S but it's so far off no one can even help so i'm starting over. Here is the pseudocode i have done that needs to be translated into a Javascript program. Any help is appreciated!
I am a beginning programmer i understand this code will have multiple errors, that's why i am here. Array's and loops have given me much trouble while trying to learn them and especially with formatting them in JavaScript. The things i know are incorrect or still need i commented out i still need them, i also know i'm not passing anything i just can't seem to wrap my head around how to get them there. I'm also not sure if while gather input i'm using alter and prompt correctly. In the display function the spacing is necessary for when it will be displayed. Corrections and explanations are greatly appreciated.
Module main()
//Declare local variables
Declare endProgram = “no”
While endProgram == “no”
Declare Real notGreenCost[12]
Declare Real goneGreenCost[12]
Declare Real savings[12]
Declare String months[12] = “January”, “February”, “March”, “April”, “May”, “June”, “July”, “August”, “September”, “October”, “November”, “December”
//function calls
getNotGreen(notGreenCost, months)
getGoneGreen(goneGreenCost, months)
energySaved(notGreenCost, goneGreenCosts, savings)
displayInfo(notGreenCost, goneGreenCosts, savings, months)
Display “Do you want to end the program? Yes or no”
Input endProgram
End While
End Module
Module getNotGreen(Real notGreenCost[], String months[])
Set counter = 0
While counter < 12
Display “Enter NOT GREEN energy costs for”, months[counter]
Input notGreenCosts[counter]
Set counter = counter + 1
End While
End Module
Module getGoneGreen(Real goneGreenCost[], String months[])
Set counter = 0
While counter < 12
Display “Enter GONE GREEN energy costs for”, months[counter]
Input goneGreenCosts[counter]
Set counter = counter + 1
End While
End Module
Module energySaved(Real notGreenCost[], Real goneGreenCost[], Real savings[])
Set counter = 0
While counter < 12
Set savings[counter] = notGreenCost[counter] – goneGreenCost[counter]
Set counter = counter + 1
End While
End Module
Module displayInfo(Real notGreenCost[], Real goneGreenCost[], Real savings[], String months[])
Set counter = 0
While counter < 12
Display “Information for”, months[counter]
Display “Savings $”, savings[counter]
Display “Not Green Costs $”, notGreenCost[counter]
Display “Gone Green Costs $”, goneGreenCost[counter]
End While
End Module
A few notes:
Currently the program creates a few variables and functions that
don't seem to interact
Most of the edits below are not optimal - there are parts that
could be done by much simpler means (i.e. counter++) - But thats
for you to learn =P
I made quite a few assumptions of what you wanted the program to
do, they might be wrong, they might be right
var notGreenCost = []; //Array lengths don't need to be specified
var goneGreenCost = [];
var savings = [];
var months = ["January", "Feburary", "March", "April", "May", "June"];
//A boolean value (true | false) would suit this better as opposed to "yes"/ "no"
var endProgram = false;
var option = 0;
/* You dont need main functions in javascript
* migrated everything to be global :/
* Delete:
function main(){
// Move this (made it global): var endProgram = "no";
}
*/
// I don't think this is meant to be initMonths..
// Maybe something like getOptions?
function /*initMonths*/getOptions(){
while (endProgram == false){ //lowercase while
//Because prompt would block everything else until it gets input
//we probably want to move the prompt to be after the alerts
alert("options:"); //Clarity
alert("1 to enter data");
alert("2 to display data");
alert("3 to write data to a file");
alert("4 to read data from a file");
//Alter global "option" to take the value of the prompt
option = prompt("What would you like to do? Type:");
//} //I assume you want the rest of the code in this while loop - otherwise it will loop forever
// Delete this bracket (its unmatched): {
// Delete return statement as it will stop the function return option;
// Delete this bracket (its unmatched): }
//Create a variable to take the value of prompt (this should be outside the while loop) but it seem clearer for explanation purposes to be here
var toEnd;
toEnd = prompt("Do you want to end the program (enter yes or no)");
// Javascript uses != for "not equal to" and && for "AND"
while (toEnd != "no" && toEnd != "yes") {
toEnd = prompt("Please enter a value of yes or no");
}
//I think you want to assign the value of toEnd to endProgram
// Note the the below is not the only/best way to do it
if(toEnd == "no") {
endProgram = false;
} else if(toEnd == "yes") {
endProgram = true;
}
// While use brackets not End s
// End While
// End While
}//End while loop here
}
Javascript in a browser cannot alter files - writeToFile, readFromFile have all been removed
I believe you want months to be global, if it is then initMonths is unnecessary
getNotGreen:
function getNotGreen(){
//You don't need to specify types in Javascript
/*Integer*/ var counter = 0
while (counter < 6){ //lowercase while
//I'm assuming you want to combine the values of "Enter NOT GREEN energy costs for" and months[counter] - This is done by using the + sign
//Im also assuming you want to read the value into notGreenCost
//.push adds a value to a array
notGreenCost.push(prompt("Enter NOT GREEN energy costs for" + months[counter]))
//Returning here makes the rest of the function redundant
//}
//return notGreenCost[counter];
//}
//Javascript does not use Set
// Note that below is not the only/best way to do it
/*Set*/ counter = counter + 1
} //End the while loop here
}
getGoneGreen:
function getGoneGreen(){
//Counter should probably be local (not global) - use var
var counter = 0;
while (counter < 6){//lowercase while
//I'm assuming you want to combine the values of "Enter NOT GREEN energy costs for" and months[counter] - This is done by using the + sign
//Im also assuming you want to read the value into notGreenCost
//.push adds a value to a array
goneGreenCost.push(prompt("Enter GONE GREEN energy costs for" + months[counter]));
//See above (getNotGreen)
//}
//return goneGreenCost[counter];
/*Set*/ counter = counter + 1;
}//End while loop here
}
energySaved:
function energySaved(){
//Counter should probably be local (not global) - use var
var counter = 0;
while (counter < 6){//lowercase while
savings[counter] = notGreenCost[counter] - goneGreenCost[counter]
counter = counter + 1;
}
} //I assume you want to end energySaved here?
displayInfo:
function displayInfo(){
//Alert produced individual boxes, i assume you want the following in a single window?
// "\n" is a line break
alert("SAVINGS NOT GREEN GONE GREEN MONTH\n"+
"_________________________________________________\n");
//Counter should probably be local (not global) - use var
var counter = 0;
while (counter < 6){//lowercase while
alert( "$" + savings[counter] + "$" + notGreenCost[counter] + "$" + goneGreenCost[counter] + "" + months[counter]);
counter = counter + 1;
}
} //I assume you want to end displayInfo here?

Javascript alert box shows up before executing previous statement

I am having a strange issue, but it is not surprising as I am a bit of a JavaScript newbie. Basically I am creating a simple high-low card game. (Draw two cards, highest card wins). Anyways, the code is below.
The basic flow of the program is pretty simple. I choose 2 random numbers (1-52). These numbers are mapped to a corresponding card. (i.e. number 1 is the ace of spades, number 37 is the jack of clubs, etc.). Anyways, after drawing the cards, the program is to display the corresponding card and determine the winner. At the end of all of this, i have an alert that comes up and and tells the winner of the draw and asks if the user wants to play again.
The problem I am having is this: Even though the program should have already displayed the image of the card and output the results to a text area, the alert box shows up before any of that actually occurs and never displays the cards or the results. Any ideas? I am posting all of the code so far and any help would be appreciated. Thanks in advance.
function drawCards() {
var oppCard = randNumber();
var customerCard = randNumber();
while (oppCard == customerCard) {
customerCard = randNumber();
}
var oppCardName = displayCard(oppCard, "oppImage");
var customerCardName = displayCard(customerCard, "custImage");
var result2 = "Your card was: " + customerCardName;
var result1 = "The opponent's card was: " + oppCardName;
var result3 = determineWinner(oppCard, customerCard);
var result4 = result3 + '\n' + result1 + '\n' + result2;
$("#textareaRes").text(result4);
playAgain(result3);
}
function determineWinner(oppsCard, customersCard) {
var oppValue = oppsCard % 13;
var customerValue = oppsCard % 13;
var winnerString = "";
if (oppValue == 0) {
oppValue = 13;
}
if (customerValue == 0) {
customerValue = 13;
}
if (oppValue == customerValue) {
winnerString = "You Tied.";
}
else if (oppValue > customerValue) {
winnerString = "You Lose.";
}
else if (oppValue < customerValue) {
winnerString = "You Win!!";
}
return winnerString;
}
function randNumber() {
var min = 1;
var max = 52;
var random = Math.floor(Math.random() * (max - min + 1)) + min;
return random;
}
function playAgain(resultString) {
if (resultString == "You Lose." || resultString == "You Win!!") {
alert(resultString);
var conf = confirm("Play Again?");
if (conf == true) {
$("#textareaRes").text("");
document.getElementById("custImage").src="./cardImages/default.png";
document.getElementById("oppImage").src="./cardImages/default.png";
}
else {
window.location = "#mainMenuPage";
}
}
else {
alert(resultString);
alert("Try Again.");
$("#textareaRes").text("");
document.getElementById("custImage").src="./cardImages/default.png";
document.getElementById("oppImage").src="./cardImages/default.png";
}
}
So I did not place the code in here for the display card function, just because for testing it is exceptionally long. It is just a giant switch case for all 52 random numbers. The finished product will actually be pulling from an XML file, but I used this just for testing purposes. (If, for some reason, you need to see the display cards function, let me know and I can post it.) Anyway, to recap, the last call made in the drawCards() function is the playAgain function. Upon running this code the results nor the card images are displayed. It just jumps straight to the alert that is called for by the playAgain function. This is probably a pretty noobish question, but I am a little perplexed by it. So any help you guys can offer would be GREATLY appreciated. Thanks.
EDIT: It actually performs correctly in a computer's browser. However, the problem happens on a mobile device like a phone or tablet. So this is probably something that I am doing incorrectly here. Any help is greatly appreciated.
Changes in the browser doesn't show up as long as your Javascript code is running.
The browser is event driven, so changing an element in the DOM doesn't show the change immediately, instead an event is triggered to redraw the element. When your function has finished running, the browser will handle any pending events and show the changes.
So, when building an application, you have to use the same approach so that the browser has a chance to show the changes.
For anyone who finds this looking for the solution to the problem, the solution can be found in this answer: https://stackoverflow.com/a/13338585/870729
Here is a working fiddle of a simple example:
jQuery(function($) {
$.when($('#empty-me').html('')).done(function() {
alert('I did it!');
});
});
"./cardImages/default.png"
im not sure ... but try "../cardImages/default.png" ... i always use 2 dots for come to a higher level

Implementing voting logic based on previous score

Wondering how to handle this. I've done it previously, but it involves a lot of if/else statements and I can't seem to figure it out without resorting to that. I posted it on codereview and got someone to help me re-facor it, but now I'm trying to get this functionality working properly.
How this works now is, if you click "up", it'll increase the score 1 point. If you click "up" again, it'll decrease the score. That's fine. If you click "down" it'll have the same behavior. It will not however go below 0 ever, since I don't want to display a negative score.
Right now I'm just checking to see if the previous or next buttons have .upColor and .downColor css classes on them, which check if they've already voted. I'm having trouble trying to update the proper score based off of this especially if the original score is 0, or if the score is 10.
Logic I'm trying to implement:
E.g. Original score is 0:
User votes up. Score goes to 1. User votes down. Score goes to 0 (not -1)
User votes down. Score stays at 0. User votes up. Score goes to 1.
E.g. Original score is 10:
User votes up. Score goes to 11. User votes down. Score goes to 9.
User votes down. Score goes to 9. User votes up. Score goes to 11.
Code:
$(function() {
var handleClick = function($btn) {
var $voteContainer = $btn.parent();
var scoreNode = $('.count');
var originalScore = Number($voteContainer.data('original-score'));
if ($btn.hasClass('down')) {
if ($btn.prevAll('.up').hasClass('upColor')) {
$btn.prevAll('.up').toggleClass('upColor');
alert('voted up now voting down, decrease 2 points, but don\'t go below 0.');
}
}
if ($btn.hasClass('up')) {
if ($btn.nextAll('.down').hasClass('downColor')) {
$btn.nextAll('.down').toggleClass('downColor');
alert('voted down now voting up, increase by 2 points');
}
}
var increment = $btn.hasClass('up') ? 1 : $btn.hasClass('down') && originalScore > 0 ? -1 : 0; // default
// Only do something if there is an increment
if (increment) {
var currentScore = Number(scoreNode.text()) || 0;
var newScore = currentScore + increment;
var diff = Math.abs(originalScore - newScore);
// Can't go more than + or - 1
if (diff > 1) {
newScore = originalScore;
}
// Set new displayed value
scoreNode.text(newScore);
}
$btn.hasClass('up') ? $btn.toggleClass('upColor') : $btn.toggleClass('downColor');
};
var upBtn = $('.up');
var downBtn = $('.down');
upBtn.add(downBtn).click(function() {
var $btn = $(this);
handleClick($btn);
});
});
Demo: http://jsfiddle.net/3kCPw/
I won't rewrite your code because it will take me too long, but I will give you some code that I would have used from the start.
Start with the original number:
var original_vote = 2;
var current_vote = original_vote;
Keep this as a constant to refer to for the future. Then when you click the up vote, you can add 1 to that simply with:
current_vote = original_vote + 1;
Then un-checking the up vote would make it:
current_vote = original_vote;
Then just do the opposite for down voting.
Keeping the original number ensures that you will not accidentally make the votes go out of the scope that it should.
Hope this helps!

Categories

Resources