1
0
Fork 0
mirror of https://codeberg.org/kbruen/y3s2-gui-project.git synced 2025-04-20 23:03:56 +03:00
y3s2-gui-project/src/main.cpp

245 lines
6.1 KiB
C++
Raw Normal View History

2022-03-21 01:59:09 +02:00
#include <iostream>
2022-03-21 01:39:06 +02:00
#include <functional>
#include <string>
#include <cmath>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include "pixel_wise.h"
#include "drawable.h"
#include "utils.hpp"
GLfloat deltaTime;
bool gameRunning = false;
bool mouseDown = false;
int leftScore = 0;
int rightScore = 0;
int leftMove = 0;
int rightMove = 0;
void mouse(int button, int state, int x, int y) {
if (state == GLUT_DOWN) {
gameRunning = true;
}
}
class BoardMiddle : public Drawable {
public:
virtual void draw() {
glBegin(GL_POLYGON);
glColor3ub(0xBD, 0xBD, 0xBD);
glVertex2fv(PW::nm(-2, -1).data());
glVertex2fv(PW::nm(2, -1).data());
glVertex2fv(PW::nm(2, 1).data());
glVertex2fv(PW::nm(-2, 1).data());
glEnd();
}
} bm;
class Ball : public Drawable {
public:
2022-03-21 01:59:09 +02:00
static constexpr GLfloat defaultVeloX = 0.5;
2022-03-21 01:39:06 +02:00
GLfloat radius;
GLfloat x, y;
GLfloat veloX, veloY;
2022-03-21 01:59:09 +02:00
Ball(GLfloat x, GLfloat y) : x(x), y(y), radius(0.025), veloX(defaultVeloX) {
2022-03-21 01:39:06 +02:00
}
virtual void draw() {
glBegin(GL_POLYGON);
glColor3ub(0xFF, 0xEE, 0x58);
for (float i = 0; i < 360; i += 0.5) {
const auto rad = Utils::toRad(i);
glVertex2f(x + radius * cos(rad), y + radius * sin(rad));
}
glEnd();
}
void update() {
x += veloX * deltaTime;
y += veloY * deltaTime;
}
} ball {0, 0};
class Text : public Drawable {
std::function<std::string()> strObtainer;
public:
std::function<GLfloat()> x, y;
void *font;
Text(std::function<std::string()> strObtainer, GLfloat x, GLfloat y) : strObtainer(strObtainer), x([=](){return x;}), y([=](){return y;}), font(GLUT_BITMAP_HELVETICA_18) {}
Text(std::function<std::string()> strObtainer, std::function<GLfloat()> x, std::function<GLfloat()> y) : strObtainer(strObtainer), x(x), y(y), font(GLUT_BITMAP_HELVETICA_18) {}
Text(std::function<std::string()> strObtainer, std::array<GLfloat, 2> pos) : strObtainer(strObtainer), x([=](){return pos[0];}), y([=](){return pos[1];}), font(GLUT_BITMAP_HELVETICA_18) {}
Text(std::function<std::string()> strObtainer, std::function<std::array<GLfloat, 2>()> pos) : strObtainer(strObtainer), x([=](){return pos()[0];}), y([=](){return pos()[1];}), font(GLUT_BITMAP_HELVETICA_18) {}
virtual void draw() {
glRasterPos2f(x(), y());
for (const auto& c: strObtainer()) {
glutBitmapCharacter(font, c);
}
}
} leftScoreText{[](){ return std::to_string(leftScore); }, [](){return PW::tm(-100, 20);}},
rightScoreText{[](){ return std::to_string(rightScore); }, [](){return PW::tm(100, 20);}};
class Paddle : public Drawable {
public:
GLfloat height, width;
GLfloat x, y;
Paddle(GLfloat x, GLfloat y) : x(x), y(y), height(0.4), width(0.02) {}
virtual void draw() {
glBegin(GL_POLYGON);
glVertex2f(x, y);
glVertex2f(x + width, y);
glVertex2f(x + width, y + height);
glVertex2f(x, y + height);
glEnd();
}
} leftPaddle{-0.9, -0.2}, rightPaddle{0.9 - 0.02, -0.2};
void display(void) {
glClear(GL_COLOR_BUFFER_BIT);
bm.draw();
ball.draw();
glColor3ub(0x66, 0xBB, 0x6A);
leftScoreText.draw();
leftPaddle.draw();
glColor3ub(0x42, 0xA5, 0xF5);
rightScoreText.draw();
rightPaddle.draw();
glFlush();
}
int gameTime;
2022-03-21 01:59:09 +02:00
const GLfloat paddleMoveSpeed = 0.8;
2022-03-21 01:39:06 +02:00
void idle() {
int newTime = glutGet(GLUT_ELAPSED_TIME);
deltaTime = (newTime - gameTime) / 1000.0;
gameTime = newTime;
if (gameRunning) {
ball.update();
2022-03-21 01:59:09 +02:00
// Detect ball collission
if (leftPaddle.x <= (ball.x + ball.radius) && (ball.x - ball.radius) <= (leftPaddle.x + leftPaddle.width)) {
// Ball inside left-right area of left paddle
if (leftPaddle.y <= ball.y && ball.y <= leftPaddle.y + leftPaddle.height) {
// Ball inside up-down area of left paddle
ball.veloX = ball.defaultVeloX;
ball.veloY = Utils::nummap(ball.y, leftPaddle.y, leftPaddle.y + leftPaddle.height, (GLfloat)-1, (GLfloat)1);
}
}
else if (rightPaddle.x <= (ball.x + ball.radius) && (ball.x - ball.radius) <= (rightPaddle.x + rightPaddle.width)) {
// Ball inside left-right area of right paddle
if (rightPaddle.y <= ball.y && ball.y <= rightPaddle.y + rightPaddle.height) {
// Ball inside up-down area of right paddle
ball.veloX = -ball.defaultVeloX;
ball.veloY = Utils::nummap(ball.y, rightPaddle.y, rightPaddle.y + rightPaddle.height, (GLfloat)-1, (GLfloat)1);
}
}
else if (ball.x + ball.radius < -1) {
// Ball exited board on the left side
rightScore += 1;
ball.x = ball.y = 0;
ball.veloY = 0;
2022-03-21 01:59:09 +02:00
gameRunning = false;
}
else if (ball.x - ball.radius > 1) {
// Ball exited board on the right side
leftScore += 1;
ball.x = ball.y = 0;
ball.veloY = 0;
2022-03-21 01:59:09 +02:00
gameRunning = false;
}
else if (ball.y - ball.radius < -1) {
// Ball touched bottom side
ball.veloY *= -1;
}
else if (ball.y + ball.radius > 1) {
// Ball touched top side
ball.veloY *= -1;
}
2022-03-21 01:39:06 +02:00
}
2022-03-21 01:59:09 +02:00
// Move paddle
leftPaddle.y += leftMove * paddleMoveSpeed * deltaTime;
rightPaddle.y += rightMove * paddleMoveSpeed * deltaTime;
// Clamp paddle to stay on screen
if (leftPaddle.y < -1) leftPaddle.y = -1;
if (rightPaddle.y < -1) rightPaddle.y = -1;
if (leftPaddle.y > 1 - leftPaddle.height) leftPaddle.y = 1 - leftPaddle.height;
if (rightPaddle.y > 1 - rightPaddle.height) rightPaddle.y = 1 - rightPaddle.height;
2022-03-21 01:39:06 +02:00
glutPostRedisplay();
}
void keyDown(unsigned char key, int x, int y) {
switch(key) {
case 'w':
case 'W':
leftMove = 1;
break;
case 's':
case 'S':
leftMove = -1;
break;
case 'p':
case 'P':
rightMove = 1;
break;
case ';':
case ':':
rightMove = -1;
break;
}
}
void keyUp(unsigned char key, int x, int y) {
switch(key) {
case 'w':
case 'W':
case 's':
case 'S':
leftMove = 0;
break;
case 'p':
case 'P':
case ';':
case ':':
rightMove = 0;
break;
}
}
int main(int argc, char** argv)
{
2022-03-21 09:10:18 +02:00
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(600, 600);
glutInitWindowPosition(glutGet(GLUT_SCREEN_WIDTH) * 0.6, (glutGet(GLUT_SCREEN_HEIGHT) - 600) * 0.5);
glutCreateWindow("Pong");
2022-03-21 01:39:06 +02:00
glutSetKeyRepeat(GLUT_KEY_REPEAT_OFF);
glutKeyboardFunc(keyDown);
glutKeyboardUpFunc(keyUp);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutIdleFunc(idle);
glutMainLoop();
return 0;
}