I have a problem with a countdown function I've created for an idiotic fight game I'm developing as an assignment.
I have the following method:
/* Countdown timer before fight */
startTimer() {
this.countDownPanel = true;
if (this.countDownNumbers > 0) {
this.countDown = setInterval(() => {
this.countDownNumbers--;
}, 1000);
this.textDownsizer = setInterval(() => {
this.countDownTextSize--;
}, 10);
}
},
And the following watcher that stops the countdown:
/* Countdown Watcher */
countDownNumbers() {
this.countDownTextSize = 100;
if (this.countDownNumbers < 0) {
clearInterval(this.textDownsizer);
this.textDownsizer = null;
clearInterval(this.countDown);
this.countDown = null;
this.countDownPanel = false;
}
}
},
The problem is that even after I use the clearInterval() through the Vue DevTools I can see the timer still running until countDownNumbers reaches 0. But the case is that it happens a while after the actual numbers on the screen are down to 0. And when I reset the game, running the same instance, the countdown goes nuts and causes a memory leak. Is there a better way of doing it?
Here's the complete Js code:
new Vue({
el: '#app',
data: {
gameStatus: 'disclaimer', //Status of the app, it can be (so far) 'disclaimer', 'startScreen', 'playStage', 'looseScreen', 'wonScreen', 'menuScreen'
backgroundAudio: new Array(), //Array of current playing background sounds
blurFilter: true, //Blur shown at the start of the app
audioTracks: ["sound/battle.mp3", "sound/dungeon.wav", "sound/echo.ogg"], //List of file in the folder 'sound'
playList: new Array(), //Array with a collection of Audio objects that are playable
/*
The health points function in an inverse way. The subject dies when it reaches 100
The health bar div width % is calculated subtracting the current health of the avatar of 100.
*/
healthHuman: 0,
healthComputer: 0,
muted: false, //Obviously determines if the audio is activated or not
humanStatus: true, //Defines if the human player is dead or alive
computerStatus: true, //Defines if the computer player is dead or alive
/* Collection of string that are outputed when a avatar dies */
humanDiesPhrases: [
"You've just been killed and that's why you're seeing your own life flash in front of you.",
"It's almost as if your soul has taken over your body in a frantic attempt to preserve the memory of what you love.",
"The problem is that when your soul leaves your body, it's physically incapable of going back in and if it doesn't try to go back in and make the same decision, it could start experiencing the same things all over again.",
"That was sad and gruesome and an almost poetic way. Anyway, you're dead. The rats are anxious to eat your remains.",
"Looks like the monster will be eating something besides rats today",
"Woow! That must have hurted! Dude! Are you okay? Dude? Dude... Ohh, you're dead. Sorry about that",
"Your death looks like an abstract painting. To me, not for you. For you that must have hurted like hell.",
"Yep! Looks like you're dead. Can I have your sowrd?",
"You died! Was killed to be more exact. Now your opponent drags you to one of many dark pits inside the dungeon.",
"Oh my god, how can you suck in such idiotic game? I know that the game is lame, but you just raised the bar fella.",
"You're not very good at this are you? Have you ever considered trying gardening?"
],
computerDiesPhrases: [
"You've just killed it! Or should I say him? Or her? You didn't ask, did you? How considerate of you.",
"GG mah boy, keep it like this and I'm sure you're going places. Maybe...",
"Wow that was 2 minutes less of your life, how does it feel? You're not having those back... Are you still reading?",
"Oh my, my... Why such violence? Have you considered petting it? Maybe it was just saying hello. Weirdo.",
"Well, it's dead. Now what? Are you going to eat it? Of course not silly, this is just a game. Back to being productive",
"AM I being nosy or you should be doind something else instead? I mean, killing virtual monsters?",
"Good kill dude! But, have you considered that it maybe was the last of its kind? That's disturbing.",
"You've just killed the creature! Good for you girl!",
"Wait! Have you considered trying to... Forget it, it's dead already",
"Oh man! (or woman!). That was gruesome. Wait a minute, have you just farted? Ewww! Ohh sorry, that one was mine.",
"Why did you do that? Such violence. Well you killed it, just like that. That's aliens haven't made contact with us yet...Savage!"
],
humanParts: [
"groin", "left eye", "upper lip", "right ear", "left leg", "tiny finger", "balls", "right knee", "face", "head", "lung", "chest", "chin", "middle finger", "you know where", "neck", "nose", "foot", "ribs", "teeth",
],
monsterParts: [
"center most tentacle", "foremost tooth", "tiny tentacle", "lady parts", "boy parts", "gum", "ass", "iris", "eyeball", "feelings", "wise tooth"
],
fightingMovements: [
"bite", "slapped", "punched", "kicked", "headbutted", "scratched", "hit", "punctured", "fingered", "poundded", "bashed"
],
countDownNumbers: 5, //Countdown counter =)
countDown: '', //Stores the main countdown
countDownTextSize: 100, //Obvious
textDownsizer: '', //Stores the timer responsible to downsize the font of the countdown
logger: new Array(), //Array responsible for storing all messages that will be shown to the player
countDownPanel: false, //Determines if the countdown is to be shown or not
},
computed: {
/* Unset the blur when the disclaimer modal goes away */
flipBlur() {
if (this.gameStatus != 'disclaimer') {
return this.blurFilter = false;
} else {
return true;
}
},
},
watch: {
//Wacth the gameStatus and make changes accordingly
gameStatus() {
//Background Audio Controler
//Tracks
echoSound = this.playList['echo'];
battleSound = this.playList['battle'];
dungeonSound = this.playList['dungeon'];
//Game status DJ
if (this.gameStatus == 'startScreen') {
this.loopPlay(echoSound);
this.loopPlay(dungeonSound);
} else if (this.gameStatus == 'playStage') {
//Add battle song to the background
this.loopPlay(battleSound);
battleSound.volume = 0.25;
//Trigger the coundown
this.startTimer();
}
},
muted() {
if (this.muted == true) {
this.backgroundAudio.forEach(element => {
element.pause();
});
} else {
this.backgroundAudio.forEach(element => {
element.play();
});
}
},
/* Health checkers // Killer */
healthHuman() {
if (this.healthHuman >= 100) {
this.healthHuman = 100;
this.humanStatus = false;
this.humanDied();
}
},
healthComputer() {
if (this.healthComputer >= 100) {
this.healthComputer = 100;
this.computerStatus = false;
this.computerDied();
}
},
/* Logger Wachter - Maintain only the last 3 elements of the logger */
logger() {
if (this.logger.length > 3) {
this.logger.pop();
}
},
/* Countdown Watcher */
countDownNumbers() {
this.countDownTextSize = 100;
if (this.countDownNumbers < 0) {
clearInterval(this.textDownsizer);
this.textDownsizer = null;
clearInterval(this.countDown);
this.countDown = null;
this.countDownPanel = false;
}
}
},
beforeDestroy() {
clearInterval(this.textDownsizer);
},
created: function () {
this.buildPlayList();
},
methods: {
/* Background soundtracks and sound effects */
loopPlay(audioTrack) {
if (audioTrack) {
audioTrack.play();
audioTrack.loop = true;
this.backgroundAudio.push(audioTrack);
}
},
buildPlayList() {
this.audioTracks.forEach(element => {
trackName = element.substring(element.indexOf('/') + 1);
trackName = trackName.substring(0, trackName.indexOf('.'));
this.playList[trackName] = new Audio(element);
});
},
/*
HP monitoring and controller
These two functions return the css property 'width' of the health bars.
*/
heartMonitorHuman() {
return {
width: this.healthHuman + '%'
}
},
heartMonitorComputer() {
return {
width: this.healthComputer + '%'
}
},
/* Generates random hit points */
hitGenerator() {
var hit = Math.round(Math.random() * 20);
return hit;
},
/* Controlls the timer before the fight */
counterFontSize() {
return {
'fontSize': this.countDownTextSize + 'vw'
}
},
/* Hits the human */
hitHuman() {
if (this.healthHuman < 100) {
var willHitPoints = Math.floor(this.hitGenerator() * 1.1); //Gives the monster 10% more attack power on average
this.healthHuman += willHitPoints;
this.logHandler('You got ' + this.randomFightingMoves() + ' on the ' + this.humanHitDesc() + ' and lost ' + willHitPoints + ' HP');
} else {
this.humanDied();
}
},
/* Hits the computer */
hitComputer() {
if (this.healthComputer < 100 && this.countDownNumbers <= 0) {
var willHitPoints = this.hitGenerator();
this.healthComputer += willHitPoints;
this.logHandler('You ' + this.randomFightingMoves() + ' the monster\'s ' + this.monsterHitDesc() + ' and it lost ' + willHitPoints + ' HP');
//Hits the human player back
this.hitHuman();
} else {
this.computerDied();
}
},
/* Shows phrases regarding the avatar's deaths */
humanDied() {
if (this.humanStatus == false) {
var deathMessage = Math.round(Math.random() * 10);
this.logHandler(this.humanDiesPhrases[deathMessage]);
this.logHandler("You died!");
setTimeout(() => {
this.resetGame();
}, 3000);
}
},
computerDied() {
if (this.computerStatus == false) {
var deathMessage = Math.round(Math.random() * 10);
this.logHandler(this.computerDiesPhrases[deathMessage]);
this.logHandler("You win?");
setTimeout(() => {
this.resetGame();
}, 3000);
}
},
/* Generates a random key to be used with a dictionary of log messages */
keyGen() {
return '_' + Math.random().toString(36).substr(2, 9);
},
/* Creates a dictionary with all log messages generated by the app */
logHandler(msg) {
var newLog = {
id: this.keyGen(),
message: msg,
};
this.logger.unshift(newLog);
},
/* Random hits generators */
humanHitDesc() {
randomNumber = Math.floor(Math.random() * 20);
return this.humanParts[randomNumber];
},
monsterHitDesc() {
randomNumber = Math.floor(Math.random() * 10);
return this.monsterParts[randomNumber];
},
randomFightingMoves() {
randomNumber = Math.floor(Math.random() * 10);
return this.fightingMovements[randomNumber];
},
resetGame() {
this.logger = [];
this.healthHuman = 0;
this.humanStatus = true;
this.healthComputer = 0;
this.computerStatus = true;
this.countDownNumbers = 5;
this.startTimer();
},
/* Countdown timer before fight */
startTimer() {
this.countDownPanel = true;
if (this.countDownNumbers > 0) {
this.countDown = setInterval(() => {
this.countDownNumbers--;
}, 1000);
this.textDownsizer = setInterval(() => {
this.countDownTextSize--;
}, 10);
}
},
}
});
The GitHub repo is: https://github.com/Saiuke/MonsterSlayer
Here's a screen capture of the game:
edited: sorry for the mistake. its fixed now.
Have you tried changing if (this.countDownNumbers < 0) to if (this.countDownNumbers === 0)? That might work. If that does not work then why not just make a simple countdown like this:
let num = 10;
let timer = setInterval(function(){
num = num - 1;
console.log(num);
if(num <= 0){
clearInterval(timer);
}
},1000);
The main issue is that startTimer() does not stop any existing timers before starting new ones. And since startTimer() is indirectly invoked by the user (i.e., humanDied() -> resetGame() -> startTimer(), computerDied() -> resetGame() -> startTimer(), or gameStatus change -> startTimer()), multiple timers can be started unpredictably.
The solution is to stop any existing timers before starting new ones, and to move the expiration logic from the countdownTimer watcher into startTimer():
export default {
watch: {
countDownNumbers() {
this.countDownTextSize = 100;
// XXX: DON'T DO THIS HERE
// if (this.countDownNumbers < 0) {
// clearInterval(this.textDownsizer);
// this.textDownsizer = null;
// clearInterval(this.countDown);
// this.countDown = null;
// this.countDownPanel = false;
// }
}
},
methods: {
startTimer() {
clearInterval(this.countDown);
this.countDown = null;
clearInterval(this.textDownsizer);
this.textDownsizer = null;
if (this.countDownNumbers > 0) {
this.countDown = setInterval(() => {
this.countDownNumbers--;
if (countDownNumbers <= 0) {
this.countDownPanel = false;
}
}, 1000);
this.textDownsizer = setInterval(() => {
this.countDownTextSize--;
}, 10);
}
}
}
}
you can do by this way it is so easy. this code is compatible with Vue-Js 3.
...... youe code......
,mounted() {
this.intervalId = setInterval(this.callStatusFn, 200)
console.log("intervalId "+ this.intervalId)
},
unmounted() {
clearInterval(this.intervalId)
}
The 'Win' and 'Draw' parts are showing up on time, but the 'Lost' part doesn't show the message 'you lost'until I click on an empty cell once again. Please check out my code and help me find any errors.
Below is my code:
Marked is a class that changes the opacity of the clicked cell.
1,2,3...are the id's of respective cells in the table(html).
I tried delay() too instead of setTimeout(), but it didn't work as well.
$(document).ready(function() {
var timer;
var x = 0;
$("td").click(function() {
if($(this).text()=='') {
$(this).text("0").addClass("marked");
x = 1;
}
}).click(function() {
if(x==1) {
timer = setTimeout(function() {
var choose = $("td").not(".marked");
var random = choose[Math.floor(Math.random()*choose.length)];
$(random).text("X").addClass("marked");
},1000);
x=0;
showResult();
}
});
function showResult() {
var one = $("#1").text();
var two = $("#2").text();
var three = $("#3").text();
var four = $("#4").text();
var five = $("#5").text();
var six = $("#6").text();
var seven = $("#7").text();
var eight = $("#8").text();
var nine = $("#9").text();
if(one==two && two==three)
result(one)
else if (four==five && five==six)
result(four)
else if(seven==eight && eight==nine)
result(seven)
else if (one==four && four==seven)
result(one)
else if (two==five && five==eight)
result(two)
else if (three==six && six==nine)
result(three)
else if (one==five && five==nine)
result(one)
else if(three==five && five==seven)
result(three);
else {
var z = $("td").not(".marked");
if(z.length == 0) {
$("p").text("Draw!");
$("td").removeClass("marked");
$("td").text("");
$("#demo1").append('<img src="https://media.tenor.com/images/54c63f726505bfdb455eb4c29e626ad8/tenor.gif">');
clearTimeout(timer);
}
}
}
function result(y) {
var result = y;
if(result=="X"){
clearTimeout(timer);
$("p").text("You Lost!");
$("td").removeClass("marked");
$("td").text("");
$("#demo1").append('<img src="https://media.tenor.com/images/08902a85a6107684f8614846f4a54218/tenor.gif">');
}
if(result=="0") {
$("td").text("");
$("p").text("You Won!");
$("#demo1").append('<img src="https://i.gifer.com/4OuC.gif">');
$("td").removeClass("marked");
clearTimeout(timer);
}
}
});
You are calling showResult immeadiately when the user clicked, so it cant't recognize the X put into the table one second later.
Just do:
$("td").click(function() {
[...]
}).click(function() {
if (x == 1) {
timer = setTimeout(function() {
var choose = $("td").not(".marked");
var random = choose[Math.floor(Math.random() * choose.length)];
$(random).text("X").addClass("marked");
/******** ADD ANOTHER CHECK HERE ********/
showResult();
}, 1000);
x = 0;
showResult();
}
});
It might also be a good idea to add a return to showResult that returns false when a result was achieved. This way you could do something like
x = 0;
if (showResult()) {
timer = setTimeout(function() {
[...]
}
}
And the user can't get a loose message right after a win message.
Also: Why do you need the 2 click listeners? You can just use the if statement in the top one and then you don't need the (x == 1)
I am making an artificial intelligent agent to play google chromes t-rex game and need help creating a loop for the game to continuously play at the moment to begin the game I have to actually press space.
document.getElementById("botStatus").addEventListener("change", function() {
if (this.checked === true) {
// Activate bot
var INTERVAL = 2;
window.tRexBot = setInterval(function() {
var tRex = Runner.instance_.tRex;
var obstacles = Runner.instance_.horizon.obstacles;
var lengthsize = 0;
var a = 0.1;
var b = 5;
var c = 35;
var d = 160;
var posWidth = 20;
// if (!tRex.jumping && (obstacles.length > 0) && (obstacles[0].xPos + obstacles[0].width) <= ((parseInt(Runner.instance_.currentSpeed - 0.1) - 5) * 34 + 160) && (obstacles[0].xPos + obstacles[0].width) > 20) {
if (!tRex.jumping && (obstacles.length > lengthsize) && (obstacles[0].xPos + obstacles[0].width) <= ((parseInt(Runner.instance_.currentSpeed - a) - b) * c + d) && (obstacles[0].xPos + obstacles[0].width) > posWidth) {
// console.log(obstacles[0].xPos + obstacles[0].width + " | " + ((parseInt(Runner.instance_.currentSpeed - 0.1) - 5) * 34 + 160));
tRex.startJump();
}
}, INTERVAL);
} else {
// Disable bot
clearInterval(tRexBot);
}
});
what I require is for once the Interval ends, I would like it to take the games current speed and distance of obstacles then either increase or decrease the variables I have set into a new interval, so that it will hopefully learn how to get further and further into the game as it picks up speed...
If this sort of makes sense?
A number of changes you could make to improve the code.
1) Extract the code for starting/stopping the bot to their own functions
var INTERVAL = 2;
function startBot(){
var bot = {}; //empty bot info
bot.tRex = Runner.instance_.tRex;
....
bot.posWidth = 20;
bot.interval = setInterval(function() {
if (!bot.tRex.jumping && (bot.obstacles.length > bot.lengthsize) /*...*/) {
tRex.startJump();
}
},INTERVAL);
return bot;
}
function stopBot(bot) {
clearInterval(bot.interval);
}
document.getElementById("botStatus").addEventListener("change", function() {
if (this.checked === true) {
window.bot = startBot();
}
else {
stopBot(window.bot);
}
}
2) pass the config parameters into the "startBot" function so you can more easily change it on the outside.
var config = { posWidth:20,a: 01,...};
startBot(config);
function startBot(config) {
var bot = config;
//....
}
I'm trying to figure out how to switch between cases in Javascript/jQuery. I'm creating a dice game where the player needs to roll the dice until they finish the "Phase". Once they finish the "Phase" they will move onto the next "Phase" and any previous "Phases" won't interfere with the current "Phase". There will be several different "Phases" where they start at "Phase 1" and work down to "Phase 2" and so on until the last phase. Is there any way I can work down the "Phases"? I'm trying a switch statement here with no success. If a switch statement won't do the job, what will?
//Start of Dice Code
var die1Array = [];
var die2Array = [];
var die3Array = [];
var die1 = function() {
var roll1 = Math.floor(Math.random() * 6) + 1;
if(roll1 === 1) {
die1Array.push(1);
}
else if(roll1 === 2) {
die1Array.push(2);
}
else if(roll1 === 3) {
die1Array.push(3);
}
else if(roll1 === 4) {
die1Array.push(4);
}
else if(roll1 === 5) {
die1Array.push(5);
}
else if(roll1 === 6) {
die1Array.push(6);
}
};
var die2 = function() {
var roll2 = Math.floor(Math.random() * 6) + 1;
if(roll2 === 1) {
die2Array.push(1);
}
else if(roll2 === 2) {
die2Array.push(2);
}
else if(roll2 === 3) {
die2Array.push(3);
}
else if(roll2 === 4) {
die2Array.push(4);
}
else if(roll2 === 5) {
die2Array.push(5);
}
else if(roll2 === 6) {
die2Array.push(6);
}
};
var die3 = function() {
var roll3 = Math.floor(Math.random() * 6) + 1;
if(roll3 === 1) {
die3Array.push(1);
}
else if(roll3 === 2) {
die3Array.push(2);
}
else if(roll3 === 3) {
die3Array.push(3);
}
else if(roll3 === 4) {
die3Array.push(4);
}
else if(roll3 === 5) {
die3Array.push(5);
}
else if(roll3 === 6) {
die3Array.push(6);
}
};
//End of Dice Code
var main = function() {
$("#roll").on("click", die1);
$("#roll").on("click", die2);
$("#roll").on("click", die3);
$("#roll").on("click", die4);
$("#roll").on("click", die5);
$("#roll").on("click", die6);
//Where I want to switch between cases.
//Once Phase 1's condition (the if statement) is met, I want to switch to Phase 2.
var lvls = 1;
switch(lvls) {
case 1:
alert("Phase 1");
$("#submit").click(function() {
if((die1Array.slice(-1)=="1"||die2Array.slice(-1)=="1"||die3Array.slice(-1)=="1")&&(die1Array.slice(-1)=="2"||die2Array.slice(-1)=="2"||die3Array.slice(-1)=="2")&&(die1Array.slice(-1)=="3"||die2Array.slice(-1)=="3"||die3Array.slice(-1)=="3")) {
alert("Completed Phase 1: Straight of 3");
lvls = 2;
return lvls;
}
else {
alert("Phase 1: Straight of 3. Not Complete. Try again.");
};
});
break;
case 2:
alert("Phase 2");
//Phase 2's code
break;
//Additional cases/Phases would go here.
default:
};
};
$(document).ready(main);
In your die# function you could just push the values without the if else part.
var die1 = function () {
var roll1 = Math.floor(Math.random() * 6) + 1;
die1Array.push(roll1);
}
Or more general:
var die = function (dieArray) {
dieArray.push(Math.floor(Math.random() * 6) + 1);
}
Using:
die(die1Array);
die(die2Array);
die(die3Array);
...
The issue of your current swithc is that you bind an event handler function inside a case.
If you want that event handler work only in a particular state, you should set a state variable to save the current state and check this variable in the handler function.
var main = function () {
var diceState = 1;
$("#submit").click(function() {
if (diceState === 1) {
// do something
}
});
switch(lvls) {
case 1:
diceState = 1;
break;
case 2:
diceState = 2;
break;
}
The other problem you have is that you set the value of lvls to 1 in the main function and so you will have only 1 case, the other changes of lvls will have no effect at all, even you call main again.
If you call main more than one time, then you have the problem you're continuosly binding event onsubmit, so each time you submit the form, the function handler is called many times.
You should move the switch statement in a different function, passing the state variable as parameter, and call each time you want to change the state.
So here an example:
// Should be in same scope of the function
// or an attribute of an object to be passed by reference.
var diceState;
var changeState = function (state) {
switch(state) {
case 1:
diceState = 1;
break;
....
default:
throw new Error("State " + state + " not supported");
}
}
And is a good practice to use the default case to handle unexpected values.
Here a suggestion on how to change your main function:
var main = function() {
var lvls;
$("#roll").on("click", die1);
$("#roll").on("click", die2);
$("#roll").on("click", die3);
$("#roll").on("click", die4);
$("#roll").on("click", die5);
$("#roll").on("click", die6);
var changeState = function (state) {
switch(state) {
case 1:
alert("Phase 1");
lvls = state;
break;
case 2:
alert("Phase 2");
//Phase 2's code
lvls = state;
break;
//Additional cases/Phases would go here.
default:
};
}
// bind the event handler
$("#submit").click(function() {
if((die1Array.slice(-1)=="1"||die2Array.slice(-1)=="1"||die3Array.slice(-1)=="1")&&(die1Array.slice(-1)=="2"||die2Array.slice(-1)=="2"||die3Array.slice(-1)=="2")&&(die1Array.slice(-1)=="3"||die2Array.slice(-1)=="3"||die3Array.slice(-1)=="3")) {
alert("Completed Phase 1: Straight of 3");
changeState(2);
// you could not return the vaue here!
// return lvls;
}
else {
alert("Phase 1: Straight of 3. Not Complete. Try again.");
};
});
changeState(1);
};
Before addressing your question I want to mention your if/else statements:
if(roll1 === 1) {
die1Array.push(1);
}
else if(roll1 === 2) {
die1Array.push(2);
}
If you're going to put the value of roll1 into die1Array regardless of what the value is, why are you checking it first every time? Just do a die1Array.push(roll1); and call it a day.
I don't think you even want a switch statement here at all. What are you hoping to achieve with a switch statement?
The logic of your code is essentially this:
var main = function() {
// onclick stuff
lvls = 1
switch(lvls){}
}
This is going to immediately go into this switch statement with the hard value of 1 you force immediately before it, thus always hitting the first case.
The logic of this seems like it would be better suited to calling various functions. Maybe a function for phaseTwo(){...} but a switch statement is primarily used to check the state of an item at a specific point, not for tracking the state over time.
Here is some working ES6 code you may find useful.
It defines the names and the verification functions for each of the phases in an array. The roll function performs the random generation of the 5 dices (could be any number) a few times, so to give some animation, and then calls back, providing the value of each of the dice.
A global lvl variable is then used to find and execute the correct verification function. If this passes, the lvl is incremented:
const dieFaces = [null,'⚀','⚁','⚂','⚃','⚄','⚅'];
const DICE_COUNT = 5;
var lvl = 0;
var phases = [
{
descr: 'Phase 1: Pair',
test: function (counts) {
return counts.some( count => count > 1 );
}
},
{
descr: 'Phase 2: Three of a Kind',
test: function (counts) {
return counts.some( count => count > 2 );
}
},
{
descr: 'Phase 3: Full House',
test: function (counts) {
return counts.some( count => count > 2 ) &&
counts.filter( count => count > 1 ).length > 1;
}
},
{
descr: 'Phase 4: Small Straight',
test: function (counts) {
return counts.map( count => count>0 ).join('').indexOf('1111') > -1;
}
},
{
descr: 'Phase 5: Large Straight',
test: function (counts) {
return counts.map( count => count>0 ).join('').indexOf('11111') > -1;
}
},
{
descr: 'Phase 6: Four of a Kind',
test: function (counts) {
return counts.some( count => count > 3 );
}
}
];
function roll(callback, rolling = 20) {
let faces = [];
let dice = [];
for (let i = 0; i < DICE_COUNT; i++) {
let die = Math.floor(Math.random() * 6) + 1;
dice.push(die);
faces.push(dieFaces[die]);
}
$('#dice').html(faces.join(' '));
if (!rolling) return callback(dice);
setTimeout(roll.bind(null, callback, rolling-1), 50);
}
$("#roll").on("click", function () {
$('#result').text("");
roll(function (dice) {
var acc = dice.map( die => 0 );
dice.forEach( die => ++acc[die] );
if (phases[lvl].test(acc)) {
$('#result').text("Completed " + phases[lvl].descr);
lvl++;
$('#phase').text(phases[lvl].descr);
} else {
$('#result').text("Try again");
}
});
});
$('#phase').text(phases[0].descr);
#dice { font-size: 40px }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="phase"></div>
<button id="roll">Roll</button>
<div id="dice"></div>
<div id="result"></div>
I am creating an inventory for object, When I pick object it stores in inventory but my display line (Press E to pick up) still showing.
method ONGUI, I think making some problem,
Here is code of FPS pickup.
#pragma strict
var InstructionBoxSkin : GUISkin;
var ButtonToPress : KeyCode = KeyCode.E;
var PickUpDistance = 1.7f;
private var canPickUp = false;
private var theItem : Item;
private var thePlayer : Transform;
private var dist = 9999f;
#script AddComponentMenu ("Inventory/Items/First Person Pick Up")
#script RequireComponent(Item)
function Awake ()
{
theItem = (GetComponent(Item));
if (InstructionBoxSkin == null)
{
InstructionBoxSkin = Resources.Load("OtherSkin", GUISkin);
}
}
function RetrievePlayer (theInv : Inventory)
{
thePlayer = theInv.transform.parent;
}
function OnGUI ()
{
//This is where we draw a box telling the Player how to pick up the item.
//
GUI.skin = InstructionBoxSkin;
GUI.color = Color(1, 1, 1, 0.7);
if (canPickUp == true)
{
if (transform.name.Length <= 1)
{
GUI.Box (Rect (Screen.width*0.5-(165*0.5), 200, 165, 22), "Press E to pick up " + transform.name + ".");
}
else
{
GUI.Box (Rect (Screen.width*0.5-(185*0.5), 200, 185, 22), "Press E to pick up " + transform.name + ".");
}
}
}
function Update ()
{
if (thePlayer != null)
{
dist = Vector3.Distance(thePlayer.position, transform.position);
if (dist <= PickUpDistance)
{
canPickUp = true;
}
else
{
canPickUp = false;
}
//This is where we allow the player to press the ButtonToPress to pick up the item.
if (Input.GetKeyDown(ButtonToPress) && canPickUp == true)
{
theItem.PickUpItem();
}
}
}
function OnDrawGizmosSelected ()
{
Gizmos.color = Color.yellow;
Gizmos.DrawWireSphere (transform.position, PickUpDistance);
}
What could be the reason?
It looks like canPickUp is never set to false.
Does changing:
if (Input.GetKeyDown(ButtonToPress) && canPickUp == true)
{
theItem.PickUpItem();
canPickUp = false;
}
resolve the issue?