2

I'm making a game, and I want to have a pause between one condition being true and an expression being run. The commented line below shows you where I want the pause, and the kind of pause I want is like this (which doesn't work):

while (bullet.yPos >= 0) {}; //Tried, failed 

So I want my code to stop while bullet.yPos is greater than or equal to 0, and then continue when bullet.yPos is less than 0.

bullet.hidden = true; //I want the pause here, and the line below to be executed when bullet.yPos is less than 0 bullet.hidden = false; 

How should I do this?

EDIT: Here is the relevant method:

check: function() { for (var i = 0; i < this.aliens.length; i++) { var item = this.aliens[i]; if ((bullet.lockedXPos >= item.xPos) && (bullet.lockedXPos <= item.xPos + this.size) && (bullet.yPos >= item.yPos) && (bullet.yPos <= item.yPos + this.size)) { item.hit = true; bullet.hidden = true; while (bullet.yPos >= 0) {}; bullet.hidden = false; } } }, 
7
  • Games run in forever loops (think while(true)). Decisions are based on logic. Within your main game loop check if bullet.yPos < 0 ... if so apply whatever it is you're trying to do. If not, do nothing. Commented Oct 9, 2018 at 0:04
  • You could use a Promise that resolves when the value is appropriate. Commented Oct 9, 2018 at 0:05
  • @jhpratt Could you show me how to do that? Commented Oct 9, 2018 at 0:05
  • I'd need a bit more context to be able to do so properly. Commented Oct 9, 2018 at 0:05
  • @jhpratt Better now? Commented Oct 9, 2018 at 0:06

2 Answers 2

1

You can create a Promise along with the instance. I'm simplifying here, but the general idea is there.

const yGreaterThanZero, { resolve } = new Promise();

Now, in the method you've provided, you can use await yGreaterThanZero, which does exactly what you'd expect

check: async function() { for (var i = 0; i < this.aliens.length; i++) { var item = this.aliens[i]; if ((bullet.lockedXPos >= item.xPos) && (bullet.lockedXPos <= item.xPos + this.size) && (bullet.yPos >= item.yPos) && (bullet.yPos <= item.yPos + this.size)) { item.hit = true; bullet.hidden = true; // while (bullet.yPos >= 0) {}; await yGreaterThanZero; // this bit here is key bullet.hidden = false; } } }, 

Additionally, where you update bullet.yPos, you'll want to add the following:

if (bullet.yPos >= 0) resolve();

Of course, the variable names should be semantic, so you shouldn't just call it resolve. However, that should suffice to wait for a certain condition, provided that you're also telling JS when that condition occurs.

Important note: The function was made async, so you'll need to adjust other bits of code where you're using it, so you're awaiting (and awaiting those functions as necessary).

Sign up to request clarification or add additional context in comments.

15 Comments

How can I make the function named and async? Is it possible? How would I call this function if it doesn't have a name?
Sorry, I pulled that bit out. Just use async function where you would use function.
Where would I put the constant?
I presume you're defining this inside of a class, so making it a class field would be appropriate. Just somewhere local enough that it's visible to the necessary functions, but no more.
So I could put it inside the check function?
|
0

When you have a spin loop in javascript (which is the type of loop you've written), no other code will end up executing. Ever. Just the code in the loop. That is because javascript is (generally) single threaded, so until a function returns, no other functions can run.

So in this case, you need restructure your code. One common way is to have a main loop that calls other functions every second or so (usually faster than that, usually once per frame). Then, you would rewrite your code to like this:

//in main loop … let bullet = createBullet() // makes a hidden bullet handleBullet(bullet) … function handleBullet(bullet) { if (bullet.yPos >= 0) return bullet.hidden = false } 

This is just one possible and simplified answer, and there are many techniques and patterns you can use to structure your code more effective.

However, the key is to remember that if you need to "wait" and you are using a main loop, what you really want to do is skip the part of the code until that needs to wait, until the condition is true, but make sure everything else keeps working.

3 Comments

The easiest way to wait is by using await. Just saying :)
Normally I would be all for that (I love async / await), but the problem is triggering the promise resolution. you still need to check the main loop for the bullet position, and then trigger the resolve. So here, it actually seems more appropriate to not use an async function, because you gain very little from it. What is really needed is to split things up, so that the bullet portion check is separate from the collision check. One option is to register events on changes of the data model, and run functions there. but that is a whole book of explanation, probably.
Ooh! this would actually be really fun to implement in mobx! You could use that to easily get the event driven changes you'd need. But it takes a couple days to understand what mobx is doing, although what it does is really neat and powerful.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.