Bridges-C++  3.4.4
Bridges(C++ API)
NonBlockingGame.h
Go to the documentation of this file.
1 #ifndef NONBLOCKING_GAME_H
2 #define NONBLOCKING_GAME_H
3 
4 #include <GameBase.h>
5 #include <InputHelper.h>
6 #include <InputStateMachine.h>
7 
8 namespace bridges {
9  namespace game {
10 
179  class NonBlockingGame : public GameBase {
180  private:
181  using GameBase::render;
183 
184  typedef std::chrono::steady_clock localclock;
185 
186  InputHelper ih;
187  InputStateMachine upSM;
188  InputStateMachine downSM;
189  InputStateMachine leftSM;
190  InputStateMachine rightSM;
191 
192  InputStateMachine qSM;
193  InputStateMachine spaceSM;
194 
195  InputStateMachine wSM;
196  InputStateMachine aSM;
197  InputStateMachine sSM;
198  InputStateMachine dSM;
199 
200  double fps = 30.;
201 
202  localclock::time_point timeOfLastFrame;
203 
204  void handleFrameRate() {
205  using std::chrono::seconds;
206  using std::chrono::microseconds;
207  using std::chrono::duration_cast;
208 
209  microseconds frametime = duration_cast<microseconds>(seconds(1l)) / (int)fps;
210 
211  localclock::time_point theoretical_next_frame = timeOfLastFrame + frametime;
212 
213  auto wait_time = theoretical_next_frame - localclock::now();
214 
215  if (wait_time.count() > 0) {
216  microseconds wait_time_in_us = duration_cast<microseconds>(wait_time);
217  usleep(wait_time_in_us.count());
218  }
219 
220  timeOfLastFrame = localclock::now();
221  }
222 
223  void updateInputState() {
224  upSM.update();
225  downSM.update();
226  leftSM.update();
227  rightSM.update();
228 
229  qSM.update();
230  spaceSM.update();
231 
232  wSM.update();
233  aSM.update();
234  sSM.update();
235  dSM.update();
236  }
237 
238  public:
245  NonBlockingGame(int assignmentID, std::string username,
246  std::string apikey, int nbRow = 10, int nbCol = 10)
247  : GameBase(assignmentID, username, apikey, nbRow, nbCol),
248  ih(),
249  upSM([this]() ->bool {return this->ih.keyUp();}),
250  downSM([this]() ->bool {return this->ih.keyDown();}),
251  leftSM([this]() ->bool {return this->ih.keyLeft();}),
252  rightSM([this]() ->bool {return this->ih.keyRight();}),
253 
254  qSM([this]() ->bool {return this->ih.keyQ();}),
255  spaceSM([this]() ->bool {return this->ih.keySpace();}),
256 
257  wSM([this]() ->bool {return this->ih.keyW();}),
258  aSM([this]() ->bool {return this->ih.keyA();}),
259  sSM([this]() ->bool {return this->ih.keyS();}),
260  dSM([this]() ->bool {return this->ih.keyD();}) {
261  if (debug)
262  std::cerr << "nbRow: " << nbRow << " nbCol: " <<
263  nbCol << std::endl;
264 
265  if (nbRow * nbCol > 32 * 32) {
266  throw "NonBlockingGame can not have a grid of more than 32x32 (or a combination(so 16x64 is ok; 16x128 is not)";
267  }
268 
269  registerKeyListener(&ih);
270 
271  }
272 
273  virtual ~NonBlockingGame() = default;
274 
277  void start() {
278  timeOfLastFrame = localclock::now();
279  initialize();
280 
281  long framelimit = -1; //negative means no limit
282  {
283  char* str_limit = getenv("FORCE_BRIDGES_FRAMELIMIT");
284  if (str_limit != nullptr) {
285  std::stringstream ss;
286  ss << str_limit;
287  ss >> framelimit;
288  std::cerr << "Setting framelimit to " << framelimit << std::endl;
289  }
290  }
291  long frame = 0;
292  while (!gameover()) {
293  updateInputState();
294  gameLoop();
295  render();
296  handleFrameRate();
297  frame++;
298  if (framelimit > 0 && frame > framelimit)
299  quit();
300  }
301  }
302 
303  protected:
309  double getFrameRate() const {
310  return fps;
311  }
312 
316  bool keyLeft() {
317  return ih.keyLeft();
318  }
319 
322  return leftSM.justPressed();
323  }
324 
327  return leftSM.stillPressed();
328  }
331  return leftSM.justNotPressed();
332  }
335  return leftSM.stillNotPressed();
336  }
337 
339  bool keyLeftFire() {
340  return leftSM.fire();
341  }
342 
346  void keyLeftSetupFire(int f) {
347  leftSM.setFireCooldown(f);
348  }
352  bool keyRight() {
353  return ih.keyRight();
354  }
357  return rightSM.justPressed();
358  }
361  return rightSM.stillPressed();
362  }
365  return rightSM.justNotPressed();
366  }
369  return rightSM.stillNotPressed();
370  }
372  bool keyRightFire() {
373  return rightSM.fire();
374  }
378  void keyRightSetupFire(int f) {
379  rightSM.setFireCooldown(f);
380  }
384  bool keyUp() {
385  return ih.keyUp();
386  }
387 
390  return upSM.justPressed();
391  }
393 
395  return upSM.stillPressed();
396  }
398 
400  return upSM.justNotPressed();
401  }
403 
405  return upSM.stillNotPressed();
406  }
408 
409  bool keyUpFire() {
410  return upSM.fire();
411  }
415 
416  void keyUpSetupFire(int f) {
417  upSM.setFireCooldown(f);
418  }
419 
423  bool keyDown() {
424  return ih.keyDown();
425  }
426 
429  return downSM.justPressed();
430  }
432 
434  return downSM.stillPressed();
435  }
437 
439  return downSM.justNotPressed();
440  }
443  return downSM.stillNotPressed();
444  }
446  bool keyDownFire() {
447  return downSM.fire();
448  }
452 
453  void keyDownSetupFire(int f) {
454  downSM.setFireCooldown(f);
455  }
456 
460  bool keyW() {
461  return ih.keyW();
462  }
463 
466  return wSM.justPressed();
467  }
469 
471  return wSM.stillPressed();
472  }
474 
476  return wSM.justNotPressed();
477  }
479 
481  return wSM.stillNotPressed();
482  }
484  bool keyWFire() {
485  return wSM.fire();
486  }
490 
491  void keyWSetupFire(int f) {
492  wSM.setFireCooldown(f);
493  }
494 
498  bool keyA() {
499  return ih.keyA();
500  }
501 
504  return aSM.justPressed();
505  }
507 
509  return aSM.stillPressed();
510  }
512 
514  return aSM.justNotPressed();
515  }
517 
519  return aSM.stillNotPressed();
520  }
522  bool keyAFire() {
523  return aSM.fire();
524  }
528 
529  void keyASetupFire(int f) {
530  aSM.setFireCooldown(f);
531  }
532 
536  bool keyS() {
537  return ih.keyS();
538  }
539 
542  return sSM.justPressed();
543  }
544 
546 
548  return sSM.stillPressed();
549  }
551 
553  return sSM.justNotPressed();
554  }
556 
558  return sSM.stillNotPressed();
559  }
561  bool keySFire() {
562  return sSM.fire();
563  }
567 
568  void keySSetupFire(int f) {
569  sSM.setFireCooldown(f);
570  }
571 
575  bool keyD() {
576  return ih.keyD();
577  }
580  return dSM.justPressed();
581  }
583 
585  return dSM.stillPressed();
586  }
588 
590  return dSM.justNotPressed();
591  }
593 
595  return dSM.stillNotPressed();
596  }
598  bool keyDFire() {
599  return dSM.fire();
600  }
604 
605  void keyDSetupFire(int f) {
606  dSM.setFireCooldown(f);
607  }
611  bool keyQ() {
612  return ih.keyQ();
613  }
616  return qSM.justPressed();
617  }
619 
621  return qSM.stillPressed();
622  }
624 
626  return qSM.justNotPressed();
627  }
629 
631  return qSM.stillNotPressed();
632  }
634  bool keyQFire() {
635  return qSM.fire();
636  }
640 
641  void keyQSetupFire(int f) {
642  qSM.setFireCooldown(f);
643  }
647  bool keySpace() {
648  return ih.keySpace();
649  }
652  return spaceSM.justPressed();
653  }
655 
657  return spaceSM.stillPressed();
658  }
660 
662  return spaceSM.justNotPressed();
663  }
665 
667  return spaceSM.stillNotPressed();
668  }
670  bool keySpaceFire() {
671  return spaceSM.fire();
672  }
676 
677  void keySpaceSetupFire(int f) {
678  spaceSM.setFireCooldown(f);
679  }
680  };
681  }
682 }
683 
684 #endif
The base class building and using the BRIDGES based games.
Definition: GameBase.h:23
void registerKeyListener(KeypressListener *p)
register a new KeypressListener
Definition: GameBase.h:79
void render()
Renders the game.
Definition: GameBase.h:87
This is meant to be an internal class, not something that the library user will use.
Definition: InputHelper.h:21
bool keyA() const
Definition: InputHelper.h:105
bool keySpace() const
Definition: InputHelper.h:117
bool keyRight() const
Definition: InputHelper.h:98
bool keyDown() const
Definition: InputHelper.h:90
bool keyW() const
Definition: InputHelper.h:102
bool keyLeft() const
Definition: InputHelper.h:94
bool keyS() const
Definition: InputHelper.h:108
bool keyUp() const
Definition: InputHelper.h:86
bool keyQ() const
Definition: InputHelper.h:114
bool keyD() const
Definition: InputHelper.h:111
Definition: InputStateMachine.h:9
void update()
Definition: InputStateMachine.h:38
void setFireCooldown(int c)
Definition: InputStateMachine.h:123
bool justPressed() const
Definition: InputStateMachine.h:110
bool fire() const
Definition: InputStateMachine.h:130
bool justNotPressed() const
Definition: InputStateMachine.h:116
bool stillNotPressed() const
Definition: InputStateMachine.h:119
bool stillPressed() const
Definition: InputStateMachine.h:113
This class provides the features necessary to implement simple non blocking games.
Definition: NonBlockingGame.h:179
bool keyRightStillNotPressed()
indicates whether the Right key is not pressed and has not been pressed for more than a frame.
Definition: NonBlockingGame.h:368
void keyDownSetupFire(int f)
configures how many frames between two fire events for the Down key.
Definition: NonBlockingGame.h:453
bool keyUp()
Is Up currently pressed?
Definition: NonBlockingGame.h:384
bool keyRightJustPressed()
indicates whether the right key has just been pressed this current frame.
Definition: NonBlockingGame.h:356
void keyASetupFire(int f)
configures how many frames between two fire events for the A key.
Definition: NonBlockingGame.h:529
bool keySpaceJustPressed()
indicates whether the Space key has just been pressed this current frame.
Definition: NonBlockingGame.h:651
bool keyDownJustPressed()
indicates whether the Down key has just been pressed this current frame.
Definition: NonBlockingGame.h:428
bool keyDownFire()
indicates whether the current frame is a fire frame for the Down key.
Definition: NonBlockingGame.h:446
bool keyUpStillPressed()
indicates whether the Up key is still being pressed this current frame.
Definition: NonBlockingGame.h:394
virtual ~NonBlockingGame()=default
bool keyDStillNotPressed()
indicates whether the D key is not pressed and has not been pressed for more than a frame.
Definition: NonBlockingGame.h:594
bool keyAFire()
indicates whether the current frame is a fire frame for the A key.
Definition: NonBlockingGame.h:522
bool keyLeftStillNotPressed()
indicates whether the Left key is not pressed and has not been pressed for more than a frame.
Definition: NonBlockingGame.h:334
void keyQSetupFire(int f)
configures how many frames between two fire events for the Q key.
Definition: NonBlockingGame.h:641
bool keySJustNotPressed()
indicates whether the S key has just been released this current frame.
Definition: NonBlockingGame.h:552
bool keyLeftFire()
indicates whether the current frame is a fire frame for the Left key.
Definition: NonBlockingGame.h:339
NonBlockingGame(int assignmentID, std::string username, std::string apikey, int nbRow=10, int nbCol=10)
Definition: NonBlockingGame.h:245
bool keySpaceJustNotPressed()
indicates whether the Space key has just been released this current frame.
Definition: NonBlockingGame.h:661
void keySpaceSetupFire(int f)
configures how many frames between two fire events for the Space key.
Definition: NonBlockingGame.h:677
void keyDSetupFire(int f)
configures how many frames between two fire events for the D key.
Definition: NonBlockingGame.h:605
bool keySpaceStillPressed()
indicates whether the Space key is still being pressed this current frame.
Definition: NonBlockingGame.h:656
bool keyLeftStillPressed()
indicates whether the Left key is still being pressed this current frame.
Definition: NonBlockingGame.h:326
bool keyDown()
Is Down currently pressed?
Definition: NonBlockingGame.h:423
bool keySpace()
Is Space currently pressed?
Definition: NonBlockingGame.h:647
bool keyAJustNotPressed()
indicates whether the A key has just been released this current frame.
Definition: NonBlockingGame.h:513
bool keyLeftJustNotPressed()
indicates whether the Left key has just been released this current frame.
Definition: NonBlockingGame.h:330
bool keyQStillNotPressed()
indicates whether the Q key is not pressed and has not been pressed for more than a frame.
Definition: NonBlockingGame.h:630
bool keySJustPressed()
indicates whether the S key has just been pressed this current frame.
Definition: NonBlockingGame.h:541
bool keyQStillPressed()
indicates whether the Q key is still being pressed this current frame.
Definition: NonBlockingGame.h:620
bool keySStillNotPressed()
indicates whether the S key is not pressed and has not been pressed for more than a frame.
Definition: NonBlockingGame.h:557
void keyRightSetupFire(int f)
configures how many frames between two fire events for the Right key.
Definition: NonBlockingGame.h:378
bool keyS()
Is S currently pressed?
Definition: NonBlockingGame.h:536
bool keySpaceFire()
indicates whether the current frame is a fire frame for the Space key.
Definition: NonBlockingGame.h:670
bool keyQJustPressed()
indicates whether the Q key has just been pressed this current frame.
Definition: NonBlockingGame.h:615
bool keyW()
Is W currently pressed?
Definition: NonBlockingGame.h:460
bool keyUpFire()
indicates whether the current frame is a fire frame for the Up key.
Definition: NonBlockingGame.h:409
void keyUpSetupFire(int f)
configures how many frames between two fire events for the Up key.
Definition: NonBlockingGame.h:416
void keyWSetupFire(int f)
configures how many frames between two fire events for the W key.
Definition: NonBlockingGame.h:491
bool keyWFire()
indicates whether the current frame is a fire frame for the W key.
Definition: NonBlockingGame.h:484
void keyLeftSetupFire(int f)
configures how many frames between two fire events for the Left key.
Definition: NonBlockingGame.h:346
bool keyWJustNotPressed()
indicates whether the W key has just been released this current frame.
Definition: NonBlockingGame.h:475
bool keyD()
Is D currently pressed?
Definition: NonBlockingGame.h:575
bool keyLeft()
Is Left currently pressed?
Definition: NonBlockingGame.h:316
bool keyRightFire()
indicates whether the current frame is a fire frame for the Right key.
Definition: NonBlockingGame.h:372
void keySSetupFire(int f)
configures how many frames between two fire events for the S key.
Definition: NonBlockingGame.h:568
bool keyDownStillNotPressed()
indicates whether the Down key is not pressed and has not been pressed for more than a frame.
Definition: NonBlockingGame.h:442
bool keyDJustPressed()
indicates whether the D key has just been pressed this current frame.
Definition: NonBlockingGame.h:579
double getFrameRate() const
What frame rate is the game running at?
Definition: NonBlockingGame.h:309
void start()
Call this function from main to start the game. Runs exactly once.
Definition: NonBlockingGame.h:277
bool keyDJustNotPressed()
indicates whether the D key has just been released this current frame.
Definition: NonBlockingGame.h:589
bool keyUpJustNotPressed()
indicates whether the Up key has just been released this current frame.
Definition: NonBlockingGame.h:399
bool keyUpJustPressed()
indicates whether the Up key has just been pressed this current frame.
Definition: NonBlockingGame.h:389
bool keySStillPressed()
indicates whether the S key is still being pressed this current frame.
Definition: NonBlockingGame.h:547
bool keyQJustNotPressed()
indicates whether the Q key has just been released this current frame.
Definition: NonBlockingGame.h:625
bool keyDFire()
indicates whether the current frame is a fire frame for the D key.
Definition: NonBlockingGame.h:598
bool keyUpStillNotPressed()
indicates whether the Up key is not pressed and has not been pressed for more than a frame.
Definition: NonBlockingGame.h:404
bool keyAStillNotPressed()
indicates whether the A key is not pressed and has not been pressed for more than a frame.
Definition: NonBlockingGame.h:518
bool keyLeftJustPressed()
indicates whether the Left key has just been pressed this current frame.
Definition: NonBlockingGame.h:321
bool keyDStillPressed()
indicates whether the D key is still being pressed this current frame.
Definition: NonBlockingGame.h:584
bool keyQFire()
indicates whether the current frame is a fire frame for the Q key.
Definition: NonBlockingGame.h:634
bool keyAStillPressed()
indicates whether the A key is still being pressed this current frame.
Definition: NonBlockingGame.h:508
bool keyWJustPressed()
indicates whether the W key has just been pressed this current frame.
Definition: NonBlockingGame.h:465
bool keyRightJustNotPressed()
indicates whether the Right key has just been released this current frame.
Definition: NonBlockingGame.h:364
bool keyDownStillPressed()
indicates whether the Down key is still being pressed this current frame.
Definition: NonBlockingGame.h:433
bool keyWStillPressed()
indicates whether the W key is still being pressed this current frame.
Definition: NonBlockingGame.h:470
bool keyQ()
Is Q currently pressed?
Definition: NonBlockingGame.h:611
bool keyDownJustNotPressed()
indicates whether the Down key has just been released this current frame.
Definition: NonBlockingGame.h:438
bool keySFire()
indicates whether the current frame is a fire frame for the S key.
Definition: NonBlockingGame.h:561
bool keyAJustPressed()
indicates whether the A key has just been pressed this current frame.
Definition: NonBlockingGame.h:503
bool keyRightStillPressed()
indicates whether the Right key is still being pressed this current frame.
Definition: NonBlockingGame.h:360
bool keySpaceStillNotPressed()
indicates whether the Space key is not pressed and has not been pressed for more than a frame.
Definition: NonBlockingGame.h:666
bool keyA()
Is A currently pressed?
Definition: NonBlockingGame.h:498
bool keyWStillNotPressed()
indicates whether the W key is not pressed and has not been pressed for more than a frame.
Definition: NonBlockingGame.h:480
bool keyRight()
Is Right currently pressed?
Definition: NonBlockingGame.h:352
these methods convert byte arrays in to base64 codes and are used in BRIDGES to represent the color a...
Definition: alltypes.h:4