Code mess

Started by
15 comments, last by Zahlman 15 years, 3 months ago
A few suggestions. By no means did I find everything. :)

struct failed_flip : std::runtime_error {};void attempt_flip(SDL_Surface* screen) {	if (SDL_Flip(screen) == -1) { throw failed_flip(); }}bool handle_arrows(const Keystate* keystates, Rect& player) {	if (keystates[SDLK_LEFT]) {		// Logic for handling screen collision belongs inside the object.		// As does some encapsulation of the position data :)		player.move(-STEP, 0);	}	if (keystates[SDLK_RIGHT]) {		player.move(STEP, 0);	}	if (keystates[SDLK_UP]) {		player.move(0, -STEP);	}	if (keystates[SDLK_DOWN]) {		player.move(0, STEP);	}}enum game_result { PLAYER_WINS, COMPUTER_WINS, STILL_GOING };game_result check_result() {	// Instead of doing raw math for the ball/line ("end zone") collision, use the ball/rect collision code you already have.	SDL_Rect computerTarget = {0, SCREEN_HEIGHT, SCREEN_WIDTH, 0};	SDL_Rect playerTarget = {0, 0, SCREEN_WIDTH, 0};	if (collision(ball.getOffset(), computerTarget)) { return COMPUTER_WINS; }	if (collision(ball.getOffset(), humanTarget)) { return HUMAN_WINS; }	return STILL_GOING;}void physics(Rect& player, Rect& computer, Sprite& ball) {	AI(computer, ball);	ball.move();				result = check_result(ball);	// Again, the logic belongs inside the object. Accessor/mutator pairs are a bad code smell.	if (ball.collideWith(player) || ball.collideWith(computer)) {		// collideWith() calls the collision() code and does a changeDirectionOnCollision() if necessary.		// There should be no need to .setDirectionY() explicitly; what is changeDirectionOnCollision() for, after all?		ball.speedUp();	}}void applyRelativeToCenter(SDL_Surface* toApply, SDL_Surface* screen, int dx, int dy) {	applySurface(dx + ((screen->w - toApply->w) / 2), dy + ((screen->h - toApply->h) / 2), toApply, screen);}void draw(Rect& player, Rect& computer, Sprite& ball) {	applySurface(0, 0, background, screen);	player.draw();	computer.draw();	// If the paddles know how to draw themselves, why shouldn't the ball? 	ball.draw();	if (result != STILL_GOING) {		applyRelativeToCenter(message, screen, 0, 20);		applyRelativeToCenter(result == COMPUTER_WINS ? youLoseMessage : youWinMessage, screen, 0, -20);	}	attempt_flip(screen);}bool gameloop(Rect& player, Rect& computer, Sprite& ball) {		game_result result = STILL_GOING;	attempt_flip(screen);	Timer timer; // .start() in the constructor	while (true) {		if (!timer.ready()) { continue; } // again, the math belongs inside		SDL_Event event;		Keystate keystates[NUM_KEYS];		game_result result;		while (SDL_PollEvent(&event)) {			switch (event.type) {				case SDL_QUIT: return false;				case SDL_KEYDOWN: keystates[event.keysym] = true; break;				case SDL_KEYUP: keystates[event.keysym] = false; break;			}		}		if (keystates[SDLK_ESCAPE]) { return false; }		handle_arrows(keystates, player);		if ((result != STILL_GOING) && keystates[SDLK_RETURN]) { return true; }		if (timer.running()) { // probably a better name			physics(player, computer, ball);			result = check_result();		}		draw(player, computer, ball);	}}int main(int argc, char *args[]) {	// init() should set the random number seed, too... isn't that part of initialization?	if (!init()) { return 1; }	background = loadImage("background.jpg");	message = loadImage("play_again.jpg");	youWinMessage = loadImage("you_win.jpg");	youLoseMessage = loadImage("you_lose.jpg");	SDL_Rect bounds = {0, 0, SCREEN_WIDTH, SCREEN_HEIGHT};	Sprite ball(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, loadImage("ball.gif"), bounds);	ball.setStep(BALL_SPEED);	randomizeDirections(ball);	Rect player(SCREEN_WIDTH / 2 - RECT_WIDTH / 2, SCREEN_HEIGHT - int(RECT_HEIGHT * 1.5), RECT_WIDTH, RECT_HEIGHT),	     computer(SCREEN_WIDTH / 2 - RECT_WIDTH / 2, int(RECT_HEIGHT * 1.5) - RECT_HEIGHT, RECT_WIDTH, RECT_HEIGHT);	player.setColor(rand() % 256, rand() % 256, rand() % 256);	computer.setColor(rand() % 256, rand() % 256, rand() % 256);		// Use an outer loop to control requests to play repeatedly.	int result = 0;	try {		while (play(player, computer, ball)) {}		SDL_Quit();	} catch (failed_flip&) {		result = 1;	}	cleanup();	return result;}
Advertisement
Thanks a lot everyone, especially zahlman! Your post was very helpful!
if(SDL_Init(SDL_INIT_EVERYTHING) == -1)	{		throw std::runtime_error;	}


'std::runtime_error' : illegal use of this type as an expression

(I included its header file) (stdexcept)

What's wrong here?
Maybe like so:
throw std::runtime_error();

Quote:Original post by phresnel
Maybe like so:
throw std::runtime_error();


Thanks :)
Welcome ;)
The error is telling you that the type name 'std::runtime_error' does not qualify as an expression (portion of a statement that would evaluate to a value). It's analogous to:

// throw int; <-- not valid; what value of int would you like to throw exactly?throw 42; // valid, although poor style (please only throw instances of classes derived from std::exception)


Anyway, please study the example carefully. There are more changes illustrated than I could easily explain in words :)

This topic is closed to new replies.

Advertisement