While loop inside if/else - javascript

while(playerTwoHealth > 0 && playerOneHealth > 0){
changeScreen("Player1's Turn", "<button id='player1Attack'>Attack</button><button id='player1Defend'>Defend</button>");
$("#player1Attack").click(function(){
var successfulAttack = alert("Did you get this question right?");
if(successfulAttack === true){
playerTwoHealth = playerTwoHealth - 1;
if(playerTwoHealth === 0){
break;
};
}else{
};
});
};
I'm making a educational mathematics game, and In this section of code, I am trying to test the reaction to questions being asked. The function changeScreen changes the title and paragraph sections of the screen to be the specified HTML. On line no. 7-9, the if/else statement is designed to test if a player's health has reached 0, and if it has, break the while loop declared on line 1. However, the break statement throws an illegal break statement error. Please post any suggestions on how to solve.

Move the click event outside of the loop. In fact you don't really need a break since the while loop condition will not be valid when health is 0
while(playerTwoHealth > 0 && playerOneHealth > 0){
changeScreen("Player1's Turn", "<button id='player1Attack'>Attack</button><button id='player1Defend'>Defend</button>");
};
$("#player1Attack").click(function(){
var successfulAttack = alert("Did you get this question right?");
if(successfulAttack === true){
playerTwoHealth = playerTwoHealth - 1;
if(playerTwoHealth === 0){
// Do stuff
};
} else {
};
});

Your break statement is inside a function which you are binding to the click event, so it's not inside the while loop. You should never bind events within a while loop, as this will try to bind the event every time it loops around.
Also, you might want to replace alertwith prompt

Related

Phaser 2 buttons are needed to work text? What's happening?

I'm working on a dialogue system for my game. I have it almost finished, but I'm stuck on one weird bug. Here is the code for it in the update method. Assume everything with this in front of it was declared in the create method.
if ((this.checkCollision(this.p1, this.goodLamb) || this.checkCollision(this.p1, this.stiches)) && Phaser.Input.Keyboard.JustDown(this.keyT)) {
this.talking = true;
}
if (this.talking == true){
if (this.checkCollision(this.p1, this.goodLamb) || this.checkCollision(this.p1, this.stiches)) {
if (this.has("spool") && this.has("needleOne") && this.has("needleTwo")){
this.line1.setText('Good Lamb: Oh, thanks Peef! Now we can fix Stiches!');
this.line2.setText('Peef: Glad to help. I know how painful rips are.');
}
else if (!(this.has("spool")) || !(this.has("needleOne")) || !(this.has("needleTwo"))) {
this.line1.setText('Good Lamb: Help! Stiches ripped herself again! Can you get the sewing supplies?');
this.line2.setText('Peef: Oh gosh! Sit tight Stiches. Ill be back soon!');
}
}
if(this.keyA.isDown) {
this.p1.setVelocityX(0);
}
else if(this.keyD.isDown) {
this.p1.setVelocityX(0);
}
if(this.p1.body.touching.down && Phaser.Input.Keyboard.JustDown(this.keyW)) {
this.p1.body.setVelocityY(0);
}
if ((this.checkCollision(this.p1, this.goodLamb) || this.checkCollision(this.p1, this.stiches)) && Phaser.Input.Keyboard.JustDown(this.keyT)){
this.talking = false;
this.line1.setText('');
this.line2.setText('');
}
}
I admit this may be an outrageously overly complicated text system, but it's the only one I've gotten to work. When the player presses the talk button when touching an npc, the game checks for collision and sets the talking Boolean to true. If that Boolean is true, the game disables the player's movement and displays dialogue based on who the npc is and if they met the criteria for completing the associated quest, in this case gathering 2 needles and a spool of thread. For the player to continue, they have to press the talk button again, which turns the talking Boolean back to false, restores movement and makes the text disappear.
It's the last step that's not working. For some reason, when the player presses the talking button again, the talking Boolean doesn't change back and none of the associated actions happen.
The only solution I currently have is to change the button that makes the text disappear to a different button from the talking button. This lets things work as intended, but it's also an awkward button set up for the player.
Is there a solution, or am I just going to have to live with this issue?
If it helps, I'm using Phaser 3 in VSCode employing arcade physics.
No 1 Button is enough. What is happening, is hard to say, because your code is pretty complicated. In any case the main problem is that your if/else blocks are setup incorrect.
I cleaned it up and tried teh if/elseblocks in the correct order, so that they reflect, what you want to happen.
Although it is hard to say since, your code snippet covers only a small part of your update function.
if ((this.checkCollision(this.p1, this.goodLamb) || this.checkCollision(this.p1, this.stiches)) && Phaser.Input.Keyboard.JustDown(this.keyT)) {
if(this.talking == false){
this.talking = true;
if (this.has("spool") && this.has("needleOne") && this.has("needleTwo")) {
this.line1.setText('Good Lamb: Oh, thanks Peef! Now we can fix Stiches!');
this.line2.setText('Peef: Glad to help. I know how painful rips are.');
}
else if (!(this.has("spool")) || !(this.has("needleOne")) || !(this.has("needleTwo"))) {
this.line1.setText('Good Lamb: Help! Stiches ripped herself again! Can you get the sewing supplies?');
this.line2.setText('Peef: Oh gosh! Sit tight Stiches. Ill be back soon!');
}
/* this velocity blocks seem strange, but if it works for you why not */
if (this.keyA.isDown || this.keyD.isDown) {
this.p1.setVelocityX(0);
}
if (this.p1.body.touching.down && Phaser.Input.Keyboard.JustDown(this.keyW)) {
this.p1.body.setVelocityY(0);
}
} else {
this.talking = false;
this.line1.setText('');
this.line2.setText('');
}
}
Try to keep if/else nesting low, and try to group condition to avoid mistakes and performance issues (for example: multiple calculations / collision checks)
Update / Improvement:
Here the same code from above just more concise, and easier to understand / read
/* default text values is empty string */
let textLine1 = '';
let textLine2 = '';
/* I put "Phaser.Input.Keyboard..." first, for performance reasons */
if (Phaser.Input.Keyboard.JustDown(this.keyT) && (this.checkCollision(this.p1, this.goodLamb) || this.checkCollision(this.p1, this.stiches))) {
if(this.talking == false){
let hasAllItems = this.has("spool") && this.has("needleOne") && this.has("needleTwo");
if (hasAllItems) {
textLine1 = 'Good Lamb: Oh, ...';
textLine2 = 'Peef: Glad to help. ...';
} else {
textLine1 ='Good Lamb: Help! ...';
textLine2 = 'Peef: Oh gosh! ...';
}
/* just set the velocity always to 0, no if/else is needed */
this.p1.setVelocity(0);
}
// toggles: true <=> false
this.talking = !this.talking;
/* set the text's object in one place, no matter the text */
this.line1.setText(textLine1);
this.line2.setText(textLine2);
}

Protractor break while in promise then()

I'm automating e2e tests on an angular app. We have virtual scrolls on few input elements (only 10-20 items are loaded at a time, scrolling down loads more items and delete the previous ones to improve performance).
I made a method to scroll until I find the DOM element and click on it. However, I don't know how I can stop looping after I clicked the element.
Here is what I've done so far :
findQuery(queryName){
this.getSavedQueryCount().then((queryCount)=>{ // Total nb of items
this.count().then((displayCount)=>{ //nb of items this screen can display
let count = 0;
let flag = 0;
let actualCount = displayCount + 1;
do
{
if(count % (actualCount) === 0 && count !== 0) count++; //handling weird behavior, index 0 never gets deleted so we increment by 1 to get the next item.
browser.executeScript('arguments[0].scrollIntoView({behavior: "smooth", block: "end"});', this.getSavedQuery(count % actualCount)); // scroll to elem at index
this.getSavedQueryByName(queryName).isPresent().then((bool)=>{ // clicking on elem if it's in the DOM
if(bool)
{
this.getSavedQueryByName(queryName).getAttribute('class').then((cl)=>{
if(!(cl === "selected"))//making sure to click only once so we don't deselect the item
{
this.getSavedQueryByName(queryName).click();
flag = 1;
}
});
}
});
count += 1;
} while(queryCount > count || flag);
});
});
}
Please don't judge the code I will refactor it after I get the answer to this question (don't take the weird index handling into account).
So far this method works but it never stops looping until queryCount > count. I want it to stop looping after I clicked the element too (with the flag var).
Thanks in advance.

JavaScript Conditionals not working

I'm sorry I didn't search for another topic I thought this was a bit too specific, ok now that's out of the way!
When this is run missionButton.click(); is always ran, even though CheckHealth() is = to 0 it's like it's just skipping over the original if statement, is this normal for JavaScript (I'm used to other languages)
//__Action_Functions__
// When you're at zero health.
function Hospital(){
location.assign("http://www.gangwarsmobile.com/index.php?p=hospital");
var HospitalUse = HospitalID;
HospitalUse.click();
setTimeout(location.assign("http://www.gangwarsmobile.com/index.php?p=crimes"),5000);
}
//__Does Mission__
function start(){
var missionButton = CrimeID; //CrimeID is the ButtonID from the /crimes page/ variables at the top of this script.
if(CheckHealth() === 0){Hospital();}
else if (CheckStamina() > 0);{missionButton.click();}
}
I can't see a reason why this will not work.
EXTRA
I'm using TamperMonkey, if that makes any difference.
Did you forget to take out ; after the () > 0 ?
Original:
if(CheckHealth() === 0){Hospital();}
else if (CheckStamina() > 0);{missionButton.click();}
Fixed:
if(CheckHealth() === 0){
Hospital();
} else if (CheckStamina() > 0) {
missionButton.click();
}

syntax issues with js/jquery assignment - Quiz questions in an object

I'm trying to work through an assignment to further my understanding of js but I'm running into some issues that are keeping me from final code. The code executes a short quiz- inputs from radio buttons are taken in and matched to an object containing answers, then outputting a final score.
code at http://jsfiddle.net/8ax9A/3/
issues I'm aware of now :
my $response variable doesn't seem to work.
var $response = $('[name=rad]:checked').val();
counter is listening for clicks through questions. After the last question, I want to report final score. I can't get counter to reach the end of questions + 1, and I cant get an accurate final score listener reported (var finalScore).
if ($response == parseInt(questions[counter].answer, 10)) {
finalScore++;
}
Those are just snippets so check out the fiddle for full code. I'd love some suggestions on how to understand where I'm going wrong.
Here is one way you could do it:
//Initialization
var counter=0;
var score=0;
loadQuestion();
$('#next').on('click',answer);
//functions
function answer(){
// if the user did not answer
if ($('input:radio:checked').length == 0){
alert('You have to answer!');
return;
}
var currentQ=questions[counter];
// if answer is correct
if($('[name=rad]:checked').val()==currentQ.answer){score++;}
counter++;
// if there are no questions left
if(counter >= questions.length) {displayResults(); return;}
loadQuestion();
}
function loadQuestion(){
// clear the radio buttons
$("input:checked").removeAttr("checked");
var currentQ=questions[counter];
// display the question
$('h1').text(currentQ.question);
$('#a1').text(currentQ.choices[0]);
$('#a2').text(currentQ.choices[1]);
$('#a3').text(currentQ.choices[2]);
}
function displayResults(){
$("h1").text("You've finished with a score of " + score + "!");
$('[name=rad], #a1, #a2, #a3, #next').remove();
}
JS Fiddle

how to do parallel animation on same element

Here is code in jsfiddle !
Here is the actual site !
Problem 1: It seem's that when I call functions when clicking enter they don't execute on after each other , it sometimes works if it goe's in parallel and does everything at once! But this isn't the actual problem, it's something I would love some advice!
Problem Actual: When I call enter I switch all the clases and then do a parallel animation on div.third(making background green or red and then fading out), problem is, when I do fast enough it doesn't resize div.fourth untill background animation finished. So I thought solution for this would be a parallel animation witch doesn't interact with main animation thus switchClases().
Code where all the magic happens:
// Do everytime we press a key
$(document).keydown(function(){
// By presing 'Enter' we call exec.
$("#wraper input.third").bind('keydown',function(e){
// Make key variable by phrasing the event
var keyPresed = (e.keyCode ? e.keyCode : e.which);
// Allow only backspace, delete and enter
if (keyPresed == 46 || keyPresed == 8 || keyPresed == 13){
// If this is true animation is still in progress
if (transAct) {
// OBLIVION
}
// Or else start another animation and execution
else{
// If 'enter' is pressed then and new row and execute everything
if((keyPresed == 13) && $("input.third").val()){
//Set the new uniqueId
uniqueId++;
$("div.second").addClass("class"+uniqueId);
//Get result number because it will not be his name anymore
result = $("input.third").val();
//Switch clases
SwitchClases(_this);
transAct = true;
// Her we actualy insert the new line
$("<div class='first'>9 x 8 = <input class='first' type='text' disabled='true' maxlength='2'/></div>").css("opacity", "0").hide().prependTo(_this).slideDown().animate({opacity: 0.1},function(){
transAct = false;
})
$("div.third").append(" "+result) // Write down inputed result
$("input.third").fadeOut().remove() // Drop input box into black hole
$("div.fifth").fadeOut().remove(); // Do same thing to last division
// Check if answer was correct!
// Here are two examples with whom you can play as much as you like
//$(".leftSide div.class"+(uniqueId-1)).stop().animate({backgroundColor: '#00DD00'},100).animate({backgroundColor: 'white'},900);
// $(".leftSide").stop().animate({backgroundColor: '#DD0000'},100).animate({backgroundColor: 'white'},900);
//Now set focus to next input area , so we can continue and be lazy by not clicking on new input box!
$('.newEleCont input.second').focus();
}
}
}
// Restrict inputing any other character besides a number
else {
// Ensure that it is a number and stop the keypress
if ((keyPresed < 48 || keyPresed > 57) && (keyPresed < 96 || keyPresed > 105 )) {
e.preventDefault();
}
}
});
});
1) How could I find solution for double animation?
2) How could I improve this code?(that is , using less jquery)
EDIT: As you can see I added additional uniqueID class to every new div.third. And what I want to do is to cast backgroundColor animation only on given uniqueID BUT not interacing with basic third>fourth>fifth class animations, like if they did there own separate things!
Parallel Animation in jQuery : You can do parallel animation by passing the properties object to animate function. For example:
var animateProperties = {
top:50px,
left:100px,
width:300px,
}
object.animate(animateProperties);
and you can use stop function to stop the animation in progress. I have modified your code, the code that calls animate function is given below.
var style = {
"opacity": opacity,
"font-size": fontSize + "px"
}
if(animate){
if(index == config.activeIndex + 1){
style.backgroundColor = '#00EE00';
$(row).stop(true, true).animate(style, 100)
.animate({backgroundColor: 'white'}, 1200);
}else{
$(row).stop(true, true).animate(style, 100);
}
}else{
$(row).css(style);
}
You can find the final version of code here http://jsfiddle.net/diode/rBqVE/6/
I have made this configurable using a config object. You can find it in the code, but to get the best result you will have to modify css also.
See the function dequeue
http://api.jquery.com/jQuery.dequeue/
jQuery adds each animate call to a queue. Using dequeue you can invoke next animate call in the queue.
Here dequeue demo you can see a simple demonstration.
Also see jQuery effect http://jqueryui.com/demos/effect/. Its not for this purpose, but might be useful.

Categories