Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <GLFW/glfw3.h>
- #include <stdbool.h>
- #include <stdlib.h> // exit
- #include <string.h> // strcpy, strcat: for window title
- #include <math.h> // sin, cos, M_PI, round
- #include <stdio.h> // printf, snprintf
- #define printf(...) // comment to enable console log output
- typedef struct app_s {
- int width;
- int height;
- bool windowed;
- bool benchmark;
- bool multiplayer;
- } app_s;
- app_s app = {
- .width = 800,
- .height = 600,
- .windowed = true,
- .benchmark = true,
- .multiplayer = false,
- };
- typedef struct player_s {
- double x;
- double y;
- double width;
- double height;
- double speed;
- double speed_movement;
- int score;
- } player_s;
- player_s player1 = {
- .x = 0.095,
- .y = 0.45,
- .width = 0.01,
- .height = 0.1,
- .speed = 0,
- .speed_movement = 0.015,
- .score = 0,
- };
- player_s player2 = {
- .x = 0.905,
- .y = 0.45,
- .width = 0.01,
- .height = 0.1,
- .speed = 0,
- .speed_movement = 0.015,
- .score = 0,
- };
- typedef struct ball_s {
- double x;
- double y;
- double width;
- double height;
- double rad;
- double speed;
- double speed_increase;
- } ball_s;
- ball_s ball = {
- .x = 0.4925,
- .y = 0.4925,
- .width = 0.015,
- .height = 0.015,
- .rad = 0.1,
- .speed = 0.01,
- .speed_increase = 0.00001,
- };
- void handleError(int code, const char *text)
- {
- printf("GLFW error code <%d>: %s\n", code, text);
- exit(EXIT_FAILURE);
- }
- void handleWindowClose(GLFWwindow *wind)
- {
- printf("Window close signal received\n");
- exit(EXIT_SUCCESS);
- }
- void handleKey(GLFWwindow *wind, int key, int scancode, int action, int mods)
- {
- printf("Key <%d>, scancode <%d>, action <%d>, mods <%d>\n", key, scancode,
- action, mods);
- if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS){
- printf("Esc pressed, exiting\n");
- exit(EXIT_SUCCESS);
- }
- if (app.multiplayer) {
- if (key == GLFW_KEY_A) {
- if (action == GLFW_PRESS) {
- player1.speed = -player1.speed_movement;
- } else if (action == GLFW_RELEASE) {
- if (glfwGetKey(wind, GLFW_KEY_Z) == GLFW_PRESS) {
- player1.speed = player1.speed_movement;
- } else {
- player1.speed = 0;
- }
- }
- } else if (key == GLFW_KEY_Z) {
- if (action == GLFW_PRESS) {
- player1.speed = player1.speed_movement;
- } else if (action == GLFW_RELEASE) {
- if (glfwGetKey(wind, GLFW_KEY_A) == GLFW_PRESS) {
- player1.speed = -player1.speed_movement;
- } else {
- player1.speed = 0;
- }
- }
- }
- }
- if (key == GLFW_KEY_APOSTROPHE) {
- if (action == GLFW_PRESS) {
- player2.speed = -player2.speed_movement;
- } else if (action == GLFW_RELEASE) {
- if (glfwGetKey(wind, GLFW_KEY_SLASH) == GLFW_PRESS) {
- player2.speed = player2.speed_movement;
- } else {
- player2.speed = 0;
- }
- }
- } else if (key == GLFW_KEY_SLASH) {
- if (action == GLFW_PRESS) {
- player2.speed = player2.speed_movement;
- } else if (action == GLFW_RELEASE) {
- if (glfwGetKey(wind, GLFW_KEY_APOSTROPHE) == GLFW_PRESS) {
- player2.speed = -player2.speed_movement;
- } else {
- player2.speed = 0;
- }
- }
- }
- }
- void handleFramebufferSize(GLFWwindow *wind, int x, int y)
- {
- printf("Framebuffer size changed: %d %d\n", x, y);
- app.width = x;
- app.height = y;
- glViewport (0, 0, app.width, app.height);
- glMatrixMode (GL_PROJECTION);
- glLoadIdentity ();
- glOrtho(0.0, 1.0, 1.0, 0.0, -1.0, 1.0);
- }
- double fps()
- {
- static double time = 0;
- static double time_old = 0;
- static double ret_val = 0;
- time = glfwGetTime();
- ret_val = 1 / (time - time_old);
- time_old = time;
- return ret_val;
- }
- void reset()
- {
- ball.x = 0.4925,
- ball.y = 0.4925,
- ball.speed = 0.01;
- ball.rad = 0.1;
- player1.y = 0.45;
- player2.y = 0.45;
- glfwSetTime(0);
- }
- void calcLineY(struct player_s * player)
- {
- double new_y = player->y + player->speed;
- if (new_y < 0) {
- new_y = 0;
- } else if (new_y + player->height > 1) {
- new_y = 1 - player->height;
- }
- player->y = new_y;
- }
- double flipY(double rad)
- {
- return -rad;
- }
- // unused
- double flipX(double rad)
- {
- return M_PI - rad;
- }
- void calcBall(struct ball_s * b)
- {
- double new_x = b->x + (cos(b->rad) * b->speed);
- double new_y = b->y + (sin(b->rad) * b->speed);
- // Check new X coord
- if (new_x < 0) {
- player1.score += 1;
- printf("Score: %d %d\n", player1.score, player2.score);
- reset();
- return;
- } else if (new_x > 1 - b->width) {
- player2.score += 1;
- printf("Score: %d %d\n", player1.score, player2.score);
- reset();
- return;
- } else {
- b->x = new_x;
- }
- // Check new Y coord
- if (new_y < 0) {
- b->rad = flipY(b->rad);
- } else if (new_y > 1 - b->height) {
- b->rad = flipY(b->rad);
- } else {
- b->y = new_y;
- }
- b->speed += b->speed_increase;
- }
- bool intersects(struct player_s * l, struct ball_s * b)
- {
- if (b->x < (l->x + l->width) && (b->x + b->width) > l->x &&
- b->y < (l->y + l->height) && (b->y + b->height) > l->y) {
- return true;
- } else {
- return false;
- }
- }
- double getRelDistFromCenter(struct player_s * l, struct ball_s * b)
- {
- double dist_from_center;
- dist_from_center = l->y + (l->height / 2) - (b->y + (b->height / 2));
- return dist_from_center / l->height;
- }
- void calc()
- {
- if (!app.multiplayer) {
- if (ball.y < player1.y) {
- player1.speed = -player1.speed_movement / 1.1; // up
- } else if (ball.y + ball.height > player1.y + player1.height) {
- player1.speed = player1.speed_movement / 1.1; // down
- } else {
- player1.speed = 0;
- }
- }
- calcLineY(&player1);
- calcLineY(&player2);
- if (glfwGetTime() > 1) {
- calcBall(&ball);
- }
- if (intersects(&player1, &ball)) {
- ball.rad = - 2 * getRelDistFromCenter(&player1, &ball);
- }
- if (intersects(&player2, &ball)) {
- ball.rad = M_PI + 2 * getRelDistFromCenter(&player2, &ball);
- }
- }
- void draw()
- {
- glClear (GL_COLOR_BUFFER_BIT);
- glColor3d(0.2, 0.9, 0.2);
- glBegin(GL_LINES);
- glVertex2d(0.5, 0.0);
- glVertex2d(0.5, 1.0);
- glEnd();
- glColor3d(0.9, 0.9, 0.9);
- glRectd(player1.x, player1.y,
- player1.x + player1.width,
- player1.y + player1.height);
- glRectd(player2.x, player2.y,
- player2.x + player2.width,
- player2.y + player2.height);
- glColor3d(0.0, 1.0, 0.0);
- glRectd(ball.x, ball.y,
- ball.x + ball.width,
- ball.y + ball.height);
- glFlush();
- if (glGetError() != GL_NO_ERROR) {
- printf("GL Error: %#x\n", glGetError());
- }
- }
- void setTitle(GLFWwindow *window)
- {
- char title[100];
- char fps_string[6];
- char score_string[10];
- strcpy(title, "");
- strcat(title, "Pong clone ");
- strcat(title, "FPS: ");
- snprintf(fps_string, sizeof(fps_string), "%d ", (int)round(fps()));
- strcat(title, fps_string);
- strcat(title, "Score: ");
- snprintf(score_string, sizeof(score_string), "%d:%d ", player1.score, player2.score);
- strcat(title, score_string);
- glfwSetWindowTitle(window, title);
- }
- int main(void)
- {
- GLFWwindow *window;
- glfwSetErrorCallback(handleError);
- if (glfwInit() == GL_FALSE) {
- printf("Could not init GLFW\n");
- exit(EXIT_FAILURE);
- }
- if (app.windowed) {
- window = glfwCreateWindow(app.width, app.height, "", NULL, NULL);
- } else {
- const GLFWvidmode *vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
- app.width = vidmode->width;
- app.height = vidmode->height;
- window = glfwCreateWindow(app.width, app.height, "",
- glfwGetPrimaryMonitor(), NULL);
- }
- glfwMakeContextCurrent(window);
- handleFramebufferSize(window, app.width, app.height);
- glfwSetWindowCloseCallback(window, handleWindowClose);
- glfwSetFramebufferSizeCallback(window, handleFramebufferSize);
- glfwSetKeyCallback(window, handleKey);
- glClearColor(0.1f, 0.1f, 0.1f, 0.0f);
- glEnable(GL_LINE_STIPPLE);
- glLineStipple(1, 0xFF00);
- reset();
- while(true) {
- setTitle(window);
- glfwPollEvents();
- calc();
- draw();
- glfwSwapBuffers(window);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment