mirror of
https://codeberg.org/kbruen/y3s2-gui-project.git
synced 2025-02-22 17:19:37 +02:00
Initial commit
This commit is contained in:
commit
e2a0f56261
10 changed files with 462 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
program
|
||||||
|
obj/**
|
33
.vscode/launch.json
vendored
Normal file
33
.vscode/launch.json
vendored
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "(gdb) Launch",
|
||||||
|
"type": "cppdbg",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${workspaceFolder}/program",
|
||||||
|
"args": [],
|
||||||
|
"stopAtEntry": false,
|
||||||
|
"cwd": "${fileDirname}",
|
||||||
|
"environment": [],
|
||||||
|
"externalConsole": false,
|
||||||
|
"MIMode": "gdb",
|
||||||
|
"setupCommands": [
|
||||||
|
{
|
||||||
|
"description": "Enable pretty-printing for gdb",
|
||||||
|
"text": "-enable-pretty-printing",
|
||||||
|
"ignoreFailures": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Set Disassembly Flavor to Intel",
|
||||||
|
"text": "-gdb-set disassembly-flavor intel",
|
||||||
|
"ignoreFailures": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"preLaunchTask": "build debug"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"array": "cpp"
|
||||||
|
}
|
||||||
|
}
|
27
.vscode/tasks.json
vendored
Normal file
27
.vscode/tasks.json
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||||
|
// for the documentation about the tasks.json format
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "build",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "make -B",
|
||||||
|
"problemMatcher": [],
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "build debug",
|
||||||
|
"type": "shell",
|
||||||
|
"options": {
|
||||||
|
"env": {
|
||||||
|
"CXX_PARAMS": "-g"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"command": "make -B"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
20
Makefile
Normal file
20
Makefile
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
LD_PARAMS := -lglut -lGL -lGLU
|
||||||
|
SRC := src
|
||||||
|
OBJ := obj
|
||||||
|
CXX := g++
|
||||||
|
LD := g++
|
||||||
|
|
||||||
|
SOURCES := $(wildcard $(SRC)/*.cpp)
|
||||||
|
OBJECTS := $(patsubst $(SRC)/%.cpp, $(OBJ)/%.o, $(SOURCES))
|
||||||
|
|
||||||
|
all: program
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f program
|
||||||
|
rm -rf obj
|
||||||
|
|
||||||
|
program: ${OBJECTS}
|
||||||
|
$(LD) ${LD_PARAMS} $^ -o $@
|
||||||
|
|
||||||
|
$(OBJECTS): $(OBJ)/%.o: $(SRC)/%.cpp
|
||||||
|
$(CXX) ${CXX_PARAMS} $< -c -o $@
|
6
src/drawable.h
Normal file
6
src/drawable.h
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class Drawable {
|
||||||
|
public:
|
||||||
|
virtual void draw() = 0;
|
||||||
|
};
|
201
src/main.cpp
Normal file
201
src/main.cpp
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
#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:
|
||||||
|
GLfloat radius;
|
||||||
|
GLfloat x, y;
|
||||||
|
GLfloat veloX, veloY;
|
||||||
|
|
||||||
|
Ball(GLfloat x, GLfloat y) : x(x), y(y), radius(0.025), veloX(0.4) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
const GLfloat paddleMoveSpeed = 0.75;
|
||||||
|
|
||||||
|
void idle() {
|
||||||
|
int newTime = glutGet(GLUT_ELAPSED_TIME);
|
||||||
|
deltaTime = (newTime - gameTime) / 1000.0;
|
||||||
|
gameTime = newTime;
|
||||||
|
|
||||||
|
if (gameRunning) {
|
||||||
|
ball.update();
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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");
|
||||||
|
glutSetKeyRepeat(GLUT_KEY_REPEAT_OFF);
|
||||||
|
glutKeyboardFunc(keyDown);
|
||||||
|
glutKeyboardUpFunc(keyUp);
|
||||||
|
glutDisplayFunc(display);
|
||||||
|
glutMouseFunc(mouse);
|
||||||
|
glutIdleFunc(idle);
|
||||||
|
glutMainLoop();
|
||||||
|
return 0;
|
||||||
|
}
|
63
src/pixel_wise.cpp
Normal file
63
src/pixel_wise.cpp
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
#include "pixel_wise.h"
|
||||||
|
|
||||||
|
#include <GL/glut.h>
|
||||||
|
#include "utils.hpp"
|
||||||
|
|
||||||
|
// For personal reference:
|
||||||
|
// x - left->right
|
||||||
|
// y - bottom->top
|
||||||
|
|
||||||
|
std::array<GLfloat, 2> PW::toRelative(GLfloat x, GLfloat y, PW::Anchor anchor) {
|
||||||
|
auto winWidth = glutGet(GLUT_WINDOW_WIDTH);
|
||||||
|
auto winHeight = glutGet(GLUT_WINDOW_HEIGHT);
|
||||||
|
|
||||||
|
std::array<GLfloat, 2> result;
|
||||||
|
|
||||||
|
switch (anchor) {
|
||||||
|
case PW::BOTTOM_LEFT:
|
||||||
|
case PW::MID_LEFT:
|
||||||
|
case PW::TOP_LEFT:
|
||||||
|
case PW::NONE_LEFT:
|
||||||
|
result[0] = Utils::nummap(x, (GLfloat)0, (GLfloat)winWidth, (GLfloat)-1, (GLfloat)1);
|
||||||
|
break;
|
||||||
|
case PW::BOTTOM_MID:
|
||||||
|
case PW::CENTER:
|
||||||
|
case PW::TOP_MID:
|
||||||
|
case PW::NONE_MID:
|
||||||
|
result[0] = Utils::nummap(x, -((GLfloat)winWidth) / 2, ((GLfloat)winWidth) / 2, (GLfloat)-1, (GLfloat)1);
|
||||||
|
break;
|
||||||
|
case PW::BOTTOM_RIGHT:
|
||||||
|
case PW::MID_RIGHT:
|
||||||
|
case PW::TOP_RIGHT:
|
||||||
|
case PW::NONE_RIGHT:
|
||||||
|
result[0] = Utils::nummap(x, -(GLfloat)winWidth, (GLfloat)0, (GLfloat)-1, (GLfloat)1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result[0] = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (anchor) {
|
||||||
|
case PW::TOP_LEFT:
|
||||||
|
case PW::TOP_MID:
|
||||||
|
case PW::TOP_RIGHT:
|
||||||
|
case PW::TOP_NONE:
|
||||||
|
result[1] = Utils::nummap(y, (GLfloat)0, (GLfloat)winHeight, (GLfloat)1, (GLfloat)-1);
|
||||||
|
break;
|
||||||
|
case PW::MID_LEFT:
|
||||||
|
case PW::CENTER:
|
||||||
|
case PW::MID_RIGHT:
|
||||||
|
case PW::MID_NONE:
|
||||||
|
result[1] = Utils::nummap(y, -((GLfloat)winHeight) / 2, ((GLfloat)winHeight) / 2, (GLfloat)1, (GLfloat)-1);
|
||||||
|
break;
|
||||||
|
case PW::BOTTOM_LEFT:
|
||||||
|
case PW::BOTTOM_MID:
|
||||||
|
case PW::BOTTOM_RIGHT:
|
||||||
|
case PW::BOTTOM_NONE:
|
||||||
|
result[1] = Utils::nummap(y, (GLfloat)0, -(GLfloat)winHeight, (GLfloat)1, (GLfloat)-1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result[1] = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::move(result);
|
||||||
|
}
|
89
src/pixel_wise.h
Normal file
89
src/pixel_wise.h
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
#include <GL/gl.h>
|
||||||
|
|
||||||
|
namespace PW {
|
||||||
|
enum Anchor
|
||||||
|
{
|
||||||
|
MID_LEFT,
|
||||||
|
TOP_LEFT,
|
||||||
|
TOP_MID,
|
||||||
|
TOP_RIGHT,
|
||||||
|
MID_RIGHT,
|
||||||
|
BOTTOM_RIGHT,
|
||||||
|
BOTTOM_MID,
|
||||||
|
BOTTOM_LEFT,
|
||||||
|
CENTER,
|
||||||
|
TOP_NONE,
|
||||||
|
MID_NONE,
|
||||||
|
BOTTOM_NONE,
|
||||||
|
NONE_LEFT,
|
||||||
|
NONE_MID,
|
||||||
|
NONE_RIGHT,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Convert pixel-space x and y to relative-space (-1 -> 0 -> 1) coords
|
||||||
|
std::array<GLfloat, 2> toRelative(GLfloat x, GLfloat y, Anchor anchor);
|
||||||
|
/// Mid-Left `toRelative`
|
||||||
|
inline std::array<GLfloat, 2> ml(GLfloat x, GLfloat y) {
|
||||||
|
return PW::toRelative(x, y, PW::MID_LEFT);
|
||||||
|
}
|
||||||
|
/// Top-Left `toRelative`
|
||||||
|
inline std::array<GLfloat, 2> tl(GLfloat x, GLfloat y) {
|
||||||
|
return PW::toRelative(x, y, PW::TOP_LEFT);
|
||||||
|
}
|
||||||
|
/// Top-Mid `toRelative`
|
||||||
|
inline std::array<GLfloat, 2> tm(GLfloat x, GLfloat y) {
|
||||||
|
return PW::toRelative(x, y, PW::TOP_MID);
|
||||||
|
}
|
||||||
|
/// Top-Right `toRelative`
|
||||||
|
inline std::array<GLfloat, 2> tr(GLfloat x, GLfloat y) {
|
||||||
|
return PW::toRelative(x, y, PW::TOP_RIGHT);
|
||||||
|
}
|
||||||
|
/// Mid-Right `toRelative`
|
||||||
|
inline std::array<GLfloat, 2> mr(GLfloat x, GLfloat y) {
|
||||||
|
return PW::toRelative(x, y, PW::MID_RIGHT);
|
||||||
|
}
|
||||||
|
/// Bottom-Right `toRelative`
|
||||||
|
inline std::array<GLfloat, 2> br(GLfloat x, GLfloat y) {
|
||||||
|
return PW::toRelative(x, y, PW::BOTTOM_RIGHT);
|
||||||
|
}
|
||||||
|
/// Bottom-Mid `toRelative`
|
||||||
|
inline std::array<GLfloat, 2> bm(GLfloat x, GLfloat y) {
|
||||||
|
return PW::toRelative(x, y, PW::BOTTOM_MID);
|
||||||
|
}
|
||||||
|
/// Bottom-Left `toRelative`
|
||||||
|
inline std::array<GLfloat, 2> bl(GLfloat x, GLfloat y) {
|
||||||
|
return PW::toRelative(x, y, PW::BOTTOM_LEFT);
|
||||||
|
}
|
||||||
|
/// Center `toRelative`
|
||||||
|
inline std::array<GLfloat, 2> c(GLfloat x, GLfloat y) {
|
||||||
|
return PW::toRelative(x, y, PW::CENTER);
|
||||||
|
}
|
||||||
|
/// Top-None `toRelative`
|
||||||
|
inline std::array<GLfloat, 2> tn(GLfloat x, GLfloat y) {
|
||||||
|
return PW::toRelative(x, y, PW::TOP_NONE);
|
||||||
|
}
|
||||||
|
/// Mid-None `toRelative`
|
||||||
|
inline std::array<GLfloat, 2> mn(GLfloat x, GLfloat y) {
|
||||||
|
return PW::toRelative(x, y, PW::MID_NONE);
|
||||||
|
}
|
||||||
|
/// Bottom-None `toRelative`
|
||||||
|
inline std::array<GLfloat, 2> bn(GLfloat x, GLfloat y) {
|
||||||
|
return PW::toRelative(x, y, PW::BOTTOM_NONE);
|
||||||
|
}
|
||||||
|
/// None-Left `toRelative`
|
||||||
|
inline std::array<GLfloat, 2> nl(GLfloat x, GLfloat y) {
|
||||||
|
return PW::toRelative(x, y, PW::NONE_LEFT);
|
||||||
|
}
|
||||||
|
/// None-Mid `toRelative`
|
||||||
|
inline std::array<GLfloat, 2> nm(GLfloat x, GLfloat y) {
|
||||||
|
return PW::toRelative(x, y, PW::NONE_MID);
|
||||||
|
}
|
||||||
|
/// None-Right `toRelative`
|
||||||
|
inline std::array<GLfloat, 2> nr(GLfloat x, GLfloat y) {
|
||||||
|
return PW::toRelative(x, y, PW::NONE_RIGHT);
|
||||||
|
}
|
||||||
|
}
|
16
src/utils.hpp
Normal file
16
src/utils.hpp
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Utils {
|
||||||
|
const double PI = 3.14159265358979323846;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T nummap(T input, T inMin, T inMax, T outMin, T outMax) {
|
||||||
|
// From: https://www.arduino.cc/reference/en/language/functions/math/map/
|
||||||
|
return (input - inMin) * (outMax - outMin) / (inMax - inMin) + outMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
constexpr T toRad(T deg) {
|
||||||
|
return deg * PI / 180;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue