Passing gameState from update to draw


#1

In class today we had to make a simple frogger game as a quiz in under 30 mins. I took my written code and typed it up, and wanted to add a “game over” screen to the end of the game. To do this I created a simple int variable in ofApp.h and set it to 0 in the setup(). In the update() when one block collides with another, all velocities are set to zero effectively ending the game. When this condition is true, gameState changes to 1. When gameState == 1 in an if statement, a game over screen is drawn.

Simple enough… however draw() never sees that the gameState is 1. A simple cout << gameState within update() accurately outputs 1. When calling cout << gameState in draw, it does not report the change from 0 to 1. In fact it will out 00000000 until the game ends. At first I thought this must be a problem passing data between update and draw, and I did some research and found that I could move the whole code block there. Upon doing so the game plays and ends nominally, but gameState STILL doesn’t update accurately in draw.

What gives?

Code:
ofApp.h //
#pragma once

#include “ofMain.h”

class ofApp : public ofBaseApp{

public:
	void setup();
	void update();
	void draw();

	ofPoint Point[8];
	ofColor Color[8];
	ofRectangle Box[9];
	ofRectangle Player;

	float vel[8];

	int width = 50;
	int height = 50;

	int turnAround[8];
	int gameState;

	void keyPressed(int key);
	void keyReleased(int key);
	void mouseMoved(int x, int y );
	void mouseDragged(int x, int y, int button);
	void mousePressed(int x, int y, int button);
	void mouseReleased(int x, int y, int button);
	void mouseEntered(int x, int y);
	void mouseExited(int x, int y);
	void windowResized(int w, int h);
	void dragEvent(ofDragInfo dragInfo);
	void gotMessage(ofMessage msg);

};

ofApp.cpp //
#include “ofApp.h”

//--------------------------------------------------------------
void ofApp::setup(){
gameState = 0;

for (int i = 0; i < 8; i++) {
	Point[i].set(500, 100 * i);
	Color[i].set(0, rand() % 256, rand() % 256);
	Box[i].set(Point[i], width, height);
	vel[i] = ((rand() % 40) - 20)+.1;
	turnAround[i] = 1;
}

Player.set(500, 900, width, height);

}

//--------------------------------------------------------------
void ofApp::update(){

}

//--------------------------------------------------------------
void ofApp::draw(){

for (int i = 0; i < 8; i++) {
	if (Player.intersects(Box[i]) == true) {
		gameState = 1;
		cout << gameState;

		for (int j = 0; j < 8; i++) {
			vel[j] = 0;
		}
	}
	else if (Player.intersects(Box[i]) == false) {

		if (Point[i].x < 1000) {
			Point[i].x += vel[i] * turnAround[i];
		}

		if (Point[i].x > 1000) {
			turnAround[i] *= -1;
			Point[i].x += vel[i] * turnAround[i];
		}

		if (Point[i].x < 0) {
			turnAround[i] *= -1;
			Point[i].x += vel[i] * turnAround[i];
		}
	}

}

if (gameState == 0) {
	for (int i = 0; i < 8; i++) {
		Box[i].x = Point[i].x;
	}
	for (int i = 0; i < 8; i++) {
		ofSetColor(Color[i]);
		ofDrawRectangle(Box[i]);
	}

	ofSetColor(255, 0, 0);
	ofDrawRectangle(Player);
}

// cout << gameState;

if (gameState == 1) {
	for (int i = 0; i < 8; i++) {
		Box[i].x = Point[i].x;
	}
	ofSetColor(255, 255, 255);
	ofDrawRectangle(0, 0, 1000, 1000);
	ofSetColor(0, 0, 0);
	ofDrawBitmapString("Game Over!", 500, 500);
}

}

//--------------------------------------------------------------
void ofApp::keyPressed(int key){
if (key == OF_KEY_UP) {
Player.y -= 50;
}
else if (key == OF_KEY_DOWN) {
Player.y += 50;
}
}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseEntered(int x, int y){

}

//--------------------------------------------------------------
void ofApp::mouseExited(int x, int y){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){

}


#2

Dear bamu,

update and draw work as you would expect. I advise to extensively write speaking couts to debug such problems. See below.
With additional cout in if (Player.intersects(Box[i]) == true) loop I found out quickly that (as you expect) gameState changes as it should. Output is:

HIT! Before change game state: 0  and after change: 1

So I added another speaking cout at the end of draw loop. giving me

end of function game state: 0 end of function game state: 0 end of function game state: 0 end of function game state: 0 HIT! Before change game state: 0  and after change: 1

and then nothing. This means program seem to stop or hang in between changing the state and the end of loop. I added yet another cout in the loop stopping the vel showing me that the program hangs in this loop infinitely after gameState is set to 1. So your problem is in this loop.

			for (int j = 0; j < 8; i++) {

oh well, now it’s obvious. it should be

			for (int j = 0; j < 8; j++) {

so j++ instead of i++. Otherwise loop runs infinitely.
Here the code with still the error but with speaking debug couts:

//--------------------------------------------------------------
void ofApp::setup() {
	gameState = 0;

	for (int i = 0; i < 8; i++) {
		Point[i].set(500, 100 * i);
		Color[i].set(0, rand() % 256, rand() % 256);
		Box[i].set(Point[i], width, height);
		vel[i] = ((rand() % 40) - 20) + .1;
		turnAround[i] = 1;
	}
	Player.set(500, 900, width, height);
  }
  //--------------------------------------------------------------
  void ofApp::update() {

  }

//--------------------------------------------------------------
void ofApp::draw() {
	cout << gameState;

	for (int i = 0; i < 8; i++) {
		if (Player.intersects(Box[i]) == true) {

			cout << "HIT! Before change game state: " << gameState;
			gameState = 1;
			cout << " and after change: " << gameState;

			for (int j = 0; j < 8; i++) {
				cout << " - stopping - ";
				vel[j] = 0;
			}
		}
		else if (Player.intersects(Box[i]) == false) {

			if (Point[i].x < 1000) {
				Point[i].x += vel[i] * turnAround[i];
			}

			if (Point[i].x > 1000) {
				turnAround[i] *= -1;
				Point[i].x += vel[i] * turnAround[i];
			}

			if (Point[i].x < 0) {
				turnAround[i] *= -1;
				Point[i].x += vel[i] * turnAround[i];
			}
		}

	}

	if (gameState == 0) {
		for (int i = 0; i < 8; i++) {
			Box[i].x = Point[i].x;
		}
		for (int i = 0; i < 8; i++) {
			ofSetColor(Color[i]);
			ofDrawRectangle(Box[i]);
		}

		ofSetColor(255, 0, 0);
		ofDrawRectangle(Player);
	}

	cout << " end of function game state: "  << gameState;

	if (gameState == 1) {
		for (int i = 0; i < 8; i++) {
			Box[i].x = Point[i].x;
		}
		ofSetColor(255, 255, 255);
		ofDrawRectangle(0, 0, 1000, 1000);
		ofSetColor(0, 0, 0);
		ofDrawBitmapString("Game Over!", 500, 500);
	}

}

//--------------------------------------------------------------
void ofApp::keyPressed(int key) {
	if (key == OF_KEY_UP) {
		Player.y -= 50;
	}
	else if (key == OF_KEY_DOWN) {
		Player.y += 50;
	}
}

have a good day!
oe


#3

Gah, thank you for pointing out such a simple mistake!

Really appreciate it.

Best,
Bamu.