I have an animation created in Edge that I need to play 3 times and then stop on a specific frame.
I'm new to javascript and I think I need to use a variable and if/else statement, but am unsure what to use and how to write it. Any help would be much appreciated. Thank you!
Reluctantly I reply, really you need to provide some code to show your attempts. However, as this is a useful starter question I'll attempt an answer.
First thing you'll need is a global scoped variable to store the loop counter. Add something like this to your Stage.compositionComplete function.
// Add a numLoops variable to global storage
sym.setVariable("numLoops", 0);
Next at the end of your animation via the Timelines actions, create an event to capture that variable, increment, and replay the animation if applicable like so:
// capture numLoops variable and increment the counter
var numLoopsHolder = sym.getVariable("numLoops");
numLoopsHolder = numLoopsHolder + 1;
// set new numLoops variable back to global storage
sym.setVariable("numLoops", numLoopsHolder);
if (numLoopsHolder <= 2) {
// replay scene until 3 iterations are complete
sym.play(0);
}
This will get it looping 3 times, but you still need to add a stop check at the desired timeline location via:
// capture numLoops variable to check for 3 loops (ie. 0, 1, 2 = 3 loops)
var numLoopsHolder = sym.getVariable("numLoops");
if (numLoopsHolder >= 2) {
// we've completed 3 loops now stop here
sym.stop();
}
Here's a screenshot of the timeline for action event references.
Related
In my game i'm trying to make a variable go up gradually, so i need to be able to sleep a certain amount of time before I increment the variable again.
1) Use a timer. This will allow you to execute one off delayed events, or execute that function call repeatedly.
An example, as the phaser website basically gives you examples of everything if you search for it,
http://phaser.io/examples/v2/time/basic-timed-event
Also, from the docs
http://phaser.io/docs/2.4.8/Phaser.Timer.html
Should you need to repeat, note the function "loop" (I would post the link, but i don't have enough reputation yet).
2) The alternative is simply to tie in to Phaser's game tick. Within your state (if this is where you are executing you variable incrementation), create an update function (this will be called every game update). You can access time since last update.
Look up the class Phaser.Timer (again, i cannot post the link).
See the properties elapsed and elapsedMS. You could use this to manually track time elapsed since your last incremental event (behind the scenes, this is basically what phaser tweens or timed events are doing).
eg:
var timeSinceLastIncrement = 0;
function update()
{
// Update the variable that tracks total time elapsed
timeSinceLastIncrement += game.time.elapsed;
if (timeSinceLastIncrement >= 10) // eg, update every 10 seconds
{
timeSinceLastIncreemnt = 0;
// Do your timed code here.
}
}
Note, that option 1 is cleaner, and likely to be the preferred solution. I present option 2 simply to suggest how this can be done manually (and in fact, how it is generally done in frameworks like phaser behind the scenes).
I have a function to do something on onClick event.
function onDocumentMouseUp( event ) {
createsprite(clickedposition);
}
createsprite(clickedposition) {
var sprite = JSONSPITE // this add correctly sprite to my scene;
//// here timer function 1 sec
setTimeout(function(){ remove(sprite); }, 1000);
}
Everything works correctly.
But when i click more than once, i have still my variable sprite as a last added one. (yes i know that is correct). And logically remove() have affected only that last one.
What is the correct solution to handle work with unknown amount of same variables.
Purpose it too remove each sprite after one second after click one by one in the order of creation.
How can i reach only one variable in the same function, even when there are more variables with the same name on each function init.
You have defined sprite as a global variable. It will exist not only in that function, but is created on the window object.
If you want to remove only the sprite you created in that function, you should make it a variable
var sprite = JSONSPITE; // typo?
This way, the scope of the sprite variable is just that function.
EDIT: OP has changed their question, making the previous explanation seem obsolete
If you want to create multiple sprites, and store them somewhere so you can access them before they are deleted, you might want to create an array of sprites.
sprites = [];
function onDocumentMouseUp( event ) {
createsprite(clickedposition);
}
function createsprite(clickedposition) {
sprites.push(JSONSPITE); // Adds the current sprite to the end of the array
setTimeout(function(){
var firstSprite = sprites.shift(); // Takes the first sprite out of the array
remove(firstSprite);
}, 1000);
}
I'm playing with animations. I'm trying to have two circles move a specified distance and then stop. The issue I'm having is with multiple intervals. I assign each interval to a unique variable, and clearInterval that variable, but the first interval continues on.
Here is the code:
function moveRight(player){
if(player==1){
currentLoc = p1Loc[0]; //global var with player's current location
intervalR1 = setInterval(function(){
p1Loc[0]+=1;
draw(); //function that redraws the canvas
if(p1Loc[0]>currentLoc+wu){ //wu is a single "width-unit"
clearInterval(intervalR1);
}
},5)
}
else{
currentLoc = p2Loc[0];
intervalR2 = setInterval(function(){
p2Loc[0]+=1;
draw();
if(p2Loc[0]>currentLoc+wu){
clearInterval(intervalR2);
}
},5)
}
}
Then, let's say I give the following instructions within a while loop:
instructions = ["moveRight(1)", "moveRight(2)"];
for(instruction in instructions){
eval(instructions[instruction]); //I know, eval(), ugh. Is just temporary
}
What ends up happening is, both players start moving right, but player 2 stops after a single wu, or width-unit while player one keeps going. If i change the instructions to only "moveRight(1);", then player one moves a single wu and stops.
What's going on here?
This is just a guess, since is a bit hard to tell what is going on with only part of the code, but could it be that you are assigning currnetLoc twice, and thus the first player's location will always be always be compared against p2Loc[0]?
So when you call moveRight(1) it sets currentLoc to p1Loc[0] then proceeds. Then immediately after you call moveRight(2) which sets currentLoc to p2Loc[0]. So now the comparison for the interval for player 1 is no longer p1Loc[0]>currentLoc+wu, but rather p2Loc[0]>currentLoc+wu. Depending on the value of p2Loc this may always be false.
This line:
currentLoc = p1Loc[0]; //global var with player's current location
is kinda scary. Don't use a global for this, especially when you re-assign its value on the second entry to the function:
currentLoc = p2Loc[0];
That's likely your problem.
If you need to keep track of a single player's position, create a player object and keep track of it in there, something like:
function Player(number) {
this.number = number
this.position = 0 //some default initial position
}
and pass this into moveRight()
I'm going to try my best to ask this question without a huge wall of code. Basically I have written a very simple math quiz game. In this game you select a difficulty, the number of questions you want, and the game starts. It asks that number of questions and then you get a score and then the game is over. However, you can restart the game. When you restart, it simply returns you to the home screen, then you can select your options again. The only problem is, we need to keep track of the number of questions remaining in the quiz, the first time around, it works well. We pass numQuestions to the game function. The second time, however, even if I pass numQuestions=10, the value remains 0 from the first time I played the game. Here is the game function:
function startGame(difficulty,numQuestions,score){
// begins game, excluded that come its just some acsii art
// asks question
var q = new question(difficulty);
$("#gameInside").html(q.string);
$("#gameInside").data('answer',q.answer);
// gives answer options
for (var ii=0;ii<=3;ii++){
$("#answers").append("<button class='answerButton'>"+q.answerArray[ii]+"</button>")
}
// starts timer
var b = document.getElementById("timer");
timer = new stopWatch(b, {delay: 100});
timer.start();
},5500)
// when answer is clicked, go here
$("#gameScreen").on("click",".answerButton",function() {
// this seems to be the problem: on the second time I play the game, numQuestions remains the value from the first game and continues to go down (-1,-2) and since my selector is (>0), the else statement fires.
numQuestions--;
var time = parseFloat($("#timer span").html());
var correct = parseFloat($("#gameInside").data('answer'));
var userAnswer = parseFloat($(this).html());
if (correct==userAnswer)
tempScore = Math.round(calculateScore(time)*100)/100;
else
tempScore = 0;
score += tempScore;
$("#score").html(Math.round(score*100)/100);
if (numQuestions > 0) {
var q = new question(difficulty);
$("#gameInside").html(q.string);
$("#gameInside").data('answer',q.answer);
$("#answers").empty();
for (var ii=0;ii<=3;ii++){
$("#answers").append("<button class='answerButton'>"+q.answerArray[ii]+"</button>")
}
timer.reset();
} else {
$("#answers").empty();
$("#gameInside").html('Game Over! Thanks for Playing!');
timer.stop();
}
});
}
any ideas? Thanks
edit:
$(".numberQButton").click(function(){
numQuestions = parseFloat($(this).html());
$("#numQuestionsScreen").hide();
$("#gameScreen").show();
$("#score").html(0);
startGame(difficulty,numQuestions,score);
});
You're problem (I think) lies in closures. When you declare a function in javascript, any accessing of a variable from outside it's own scope generates what is called a closure. In this case, numQuestions is accessed from inside your event function, creating a closure. The effect of this is that any accessing of the variable numQuestions inside your event functions references the variable as it was from the moment your javascript interpreter came across the event function itself- ie, the first time you play your game.
Have a look at these to get an idea of where it's going wrong.
It sounds like you need to instantiate a new Game object when the game is restarted.
Where do you define the on click listener? If it triggers two times, it seems like you are defining the on click listener in such way, that after you completed one game and start all over, a new listener will be registered so you got 2 in the end.
I have two instances of setInterval. Each is triggering a different function ( these two functions are title quarterNoteFunc & eighthNoteFunc ) at repeated intervals. The interval for quarterNoteFunc is 600 milliseconds. The interval for eighthNoteFunc is 300 milliseconds. Both of these functions each trigger a different audio file at repeat intervals hence creating a basic music rhythm. The rhythm between the two function calls eventually "drifts" in Google Chrome making the rhythm between the two sounds dissolve. My question is:
It seems that even though browser based timing is garbage their should be a way to create some kind of "hard" timing reference so that the sounds are locked even if the "global" timing gets offset hence keeping the sounds in sync. I thought assigning the same variable milliseconds (code below) would inhibit this - but I was wrong.
The (abbreviated) code looks like this
milliseconds = 600;
quarterNote = setInterval(quarterNoteFunc, milliseconds);
eighthNote = setInterval(eighthNoteFunc, milliseconds/2);
Probably the best way to do this is to have a single, always active 1/8 note interval, then call the quarter-note every other tick:
// wrapped in a closure to allow for a private tickCount variable
// alternatively, you could use a more advanced object with start/stop methods, etc.
(function() {
var tickCount = 0,
tick = function() {
eighthNoteFunc();
if(tickCount %2 == 0) {
quarterNoteFunc();
}
tickCount++;
};
setInterval(tick, 300);
})();
This ensures that the methods are always called on the same tick. You can also expand this to support half notes (tickCount % 4 == 0) and whole notes (tickCount % 8 == 0).
This interested me, so I decided to create a fully-working sample (except, using animated backgrounds instead of audio): http://jsfiddle.net/SycBm/
This allows you to see the eighth-, quarter-, and half- notes ticking in sync, as well as start & stop the timer, and independently enable or disable the notes.
Enjoy!