Advertisement

I write game Snake

Started by December 29, 2018 06:12 PM
10 comments, last by Lactose 6 years, 1 month ago

I learn C++ on example game "Snake".
Do not scold from code, i begin programmers. Better help, and specify on errors.


#include <GL/freeglut.h>
#include <iostream>
#include <string>
#include <list>
#include <ctime>

using namespace std;

bool dirSnake = true;
int lives = 3;
int score = 0;

const int gameFieldSize = 20;

int fieldWidth = 260;
int fieldHeight = 260;

struct Color3f
{
	float r = 0.5f;
	float g = 0.5f;
float b = 0.5f;
};

struct Vector2i
{
	int x, y;
};

Vector2i snakeDir{ 1, 0 };

list<Vector2i> snake;

Vector2i food;

void drawText(float x, float y, string text)
{
	glColor3f(1.0f, 1.0f, 1.0f);

	glRasterPos2f(x, y);
	glutBitmapString(GLUT_BITMAP_8_BY_13, (const unsigned char*)text.c_str());
}

void drawSquare(int x, int y, int size, Color3f color)
{
	const float padding = 0.1f;

	glColor3f(color.r, color.g, color.b);

	glBegin(GL_QUADS);
	glVertex2f(x + padding, y + padding);
	glVertex2f(x + size - padding, y + padding);
	glVertex2f(x + size - padding, y + size - padding);
	glVertex2f(x + padding, y + size - padding);
	glEnd();
}

void drawFood()
{
	Color3f foodColor;
	foodColor.r = 0.0f;
	foodColor.g = 0.5f;
	foodColor.b = 0.5f;
	drawSquare(food.x, food.y, 1, foodColor);
}

void drawSnake()
{
	Color3f snakeColor;
	snakeColor.r = 0.0f;
	snakeColor.g = 1.0f;
	snakeColor.b = 0.0f;
	for (auto const& cell : snake)
	{
		drawSquare(cell.x, cell.y, 1, snakeColor);
	}
}

void drawRectangle(float x, float y, float width, float height)
{
	glBegin(GL_QUADS);
	glVertex2f(x, y);
	glVertex2f(x + width, y);
	glVertex2f(x + width, y + height);
	glVertex2f(x, y + height);
	glEnd();
}

void draw()
{
	glClear(GL_COLOR_BUFFER_BIT);
	drawText(0, 19, "Score: " + to_string(score));
	drawText(15, 19, "Lives: " + to_string(lives));
	if (score >= 10)
	{
		drawText(gameFieldSize / 3, gameFieldSize / 2, "You win the game");
	}
	if (dirSnake == false)
	{
		drawText(gameFieldSize / 3, gameFieldSize / 2, "You lose the game");
	}
	drawFood();
	drawSnake();

	glutSwapBuffers();
}

int getRandomInt(int max)
{
	srand(time(0));
	return rand() % max;
	return 0;
}

void update(int value)
{
	if (score >= 10)
	{
		dirSnake = false;
	}
	if (dirSnake)
	{
		Vector2i newPos;
		int xHead = snake.front().x;
		int yHead = snake.front().y;
		if (xHead >= gameFieldSize)
		{
		snake.front().x = -1;
		}
		else if (xHead == -1)
		{
		snake.front().x = gameFieldSize;
		}
		else if (yHead >= gameFieldSize)
		{
			snake.front().y = -1;
		}
		else if (yHead == -1)
		{
		snake.front().y = gameFieldSize;
		}

		newPos.x = snake.front().x + snakeDir.x;
		newPos.y = snake.front().y + snakeDir.y;
		snake.push_front(newPos);
		snake.pop_back();

		for (auto it = ++snake.begin(); it != snake.end(); ++it)
		{
			int snakeX = (*it).x;
			int snakeY = (*it).y;
			if (newPos.x == snakeX && newPos.y == snakeY)
			{
				dirSnake = false;
				cout << "Warning" << endl;
			}
		}

		if (xHead == food.x && yHead == food.y)
		{
			score++;
			Vector2i cell = { food.x, food.y };
			snake.push_back(cell);

			// Generate a new food
			food.x = getRandomInt(gameFieldSize);
			food.y = getRandomInt(gameFieldSize);
		}

		glutTimerFunc(150, update, 0);
		glutPostRedisplay();
	}
	
}

void specialKeyHandler(int key, int x, int y)
{
	switch (key)
	{
	case GLUT_KEY_UP:
		if (snakeDir.y == 0) {
			snakeDir.x = 0;
			snakeDir.y = 1;
		}
		break;
	case GLUT_KEY_LEFT:
		if (snakeDir.x == 0) {
			snakeDir.x = -1;
			snakeDir.y = 0;
		}
		break;
	case GLUT_KEY_DOWN:
		if (snakeDir.y == 0) {
			snakeDir.x = 0;
			snakeDir.y = -1;
		}
		break;
	case GLUT_KEY_RIGHT:
		if (snakeDir.x == 0) {
			snakeDir.x = 1;
			snakeDir.y = 0;
		}
		break;
	}
}

void normalKeyHandler(unsigned char key, int x, int y)
{
	switch (key)
	{
	case 'w':
		if (snakeDir.y == 0) {
			snakeDir.x = 0;
			snakeDir.y = 1;
		}
		break;
	case 'a':
		if (snakeDir.x == 0) {
			snakeDir.x = -1;
			snakeDir.y = 0;
		}
		break;
	case 's':
		if (snakeDir.y == 0) {
			snakeDir.x = 0;
			snakeDir.y = -1;
		}
		break;
	case 'd':
		if (snakeDir.x == 0) {
			snakeDir.x = 1;
			snakeDir.y = 0;
		}
		break;
	default:
		cout << "This key is not used: " << key << endl;
		break;
	}
}

void setNewCoordSystem(int width, int height)
{
	glViewport(0, 0, width, height);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0.0f, gameFieldSize, 0.0f, gameFieldSize, 0.0f, 1.0f);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

int main(int argc, char** argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
	glutInitWindowSize(fieldWidth, fieldHeight);
	glutCreateWindow("Snake");
	glutDisplayFunc(draw);
	glutTimerFunc(250, update, 0);

	glutKeyboardFunc(normalKeyHandler);
	glutSpecialFunc(specialKeyHandler);

	setNewCoordSystem(fieldWidth, fieldHeight);

	Vector2i head = { 4, 1 };
	snake.push_back(head);
	
	glutMainLoop();
	return 0;
}

I don't think this is how this forum works. IMO it's supposed to be a Q/A forum and your question is a little bit vague. But I think you'd better start to look into programmable pipeline instead of fixed pipeline.

Advertisement

Welcome to GameDev.net!

It helps immensely if you give a good description of the feedback you are seeking.  Are you asking for suggestions for improvement, or is there a problem with the code you would like help with?  Are you getting any errors?  Things like that. ;)

Okey, if my question will, what do next?

2 minutes ago, acerskyline said:

IMO it's supposed to be a Q/A forum

More of a discussion forum than strictly Question -> Answer.. ;)

1 minute ago, Alteration said:

Okey, if my question will, what do next?

You looking for ideas for a next step?  Pong ;)

1 hour ago, Alteration said:

Okey, if my question will, what do next?

Juice it.

 

🙂🙂🙂🙂🙂<←The tone posse, ready for action.

Advertisement

I'm not sure, but I think sometimes indentation (or whitespace in general) can get altered when pasting code in the forums. In any case, if you could reformat your code so that indentation and spacing is consistent, that would make it easier to read.

I'll leave it to others to determine whether asking for general feedback on code is ok in the forums, but I will say that I've seen others do so. In any case, assuming it is ok, if you could post the code with better formatting, you might get more feedback on it.

Quote

More of a discussion forum than strictly Question -> Answer.. ;)

I new user in you forum. Sorry was fit.
 

Quote

You looking for ideas for a next step?  Pong ;)

 

Yes, i find.
 

Quote

I'm not sure, but I think sometimes indentation (or whitespace in general) can get altered when pasting code in the forums. In any case, if you could reformat your code so that indentation and spacing is consistent, that would make it easier to read.

I'll leave it to others to determine whether asking for general feedback on code is ok in the forums, but I will say that I've seen others do so. In any case, assuming it is ok, if you could post the code with better formatting, you might get more feedback on it.

mmm... I copy and put in code. Maybe forum warped indents.

Quote

I'm not sure, but I think sometimes indentation (or whitespace in general) can get altered when pasting code in the forums. In any case, if you could reformat your code so that indentation and spacing is consistent, that would make it easier to read.

I'll leave it to others to determine whether asking for general feedback on code is ok in the forums, but I will say that I've seen others do so. In any case, assuming it is ok, if you could post the code with better formatting, you might get more feedback on it.

I find my warning. I correct code, you can check.

For your next project, you could look into modern OpenGL and the programmable pipeline, as previously suggested.

You could also look into adding sound. Using a more modern and/or fully-featured alternative to FreeGLUT could help with that as well.

srand() seeds the PRNG, and only needs to be called once. You don't need to call it for every random number. Also, you have an extra return statement in your getRandomInt() function. (Compilers will often give you warnings for things like that, so watch out for those.)

I see a few other things, but I don't want to write too much here, so I'll leave it at that :)

This topic is closed to new replies.

Advertisement