feat: ping pong beta
This commit is contained in:
229
main.cpp
229
main.cpp
@@ -1,5 +1,8 @@
|
|||||||
// #define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
|
// #define SDL_MAIN_USE_CALLBACKS 1 /* use the callbacks instead of main() */
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
#include <SDL3/SDL_events.h>
|
||||||
|
#include <SDL3/SDL_keyboard.h>
|
||||||
|
#include <SDL3/SDL_thread.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <GLES3/gl3.h>
|
#include <GLES3/gl3.h>
|
||||||
@@ -12,11 +15,17 @@
|
|||||||
#define SDL_WINDOW_FLAG 0
|
#define SDL_WINDOW_FLAG 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SCREEN_WIDTH 1600
|
#define SCREEN_WIDTH 1600.f
|
||||||
#define SCREEN_HEIGHT 720
|
#define SCREEN_HEIGHT 720.f
|
||||||
|
|
||||||
#define BOX_WIDTH 100
|
#define BALL_SIZE 50.f
|
||||||
#define BOX_HEIGHT 100
|
|
||||||
|
#define PLATE_WIDTH 50.f
|
||||||
|
#define PLATE_HEIGHT 150.f
|
||||||
|
|
||||||
|
#define max(a, b) ((a) > (b) ? (a) : (b))
|
||||||
|
#define min(a, b) ((a) < (b) ? (a) : (b))
|
||||||
|
#define clamp(x, minV, maxV) max((minV), min((maxV), (x)))
|
||||||
|
|
||||||
static SDL_Window *window = NULL;
|
static SDL_Window *window = NULL;
|
||||||
|
|
||||||
@@ -25,24 +34,32 @@ static bool running = true;
|
|||||||
static Uint8 color = 0x18;
|
static Uint8 color = 0x18;
|
||||||
|
|
||||||
static Uint64 elapsed = 0;
|
static Uint64 elapsed = 0;
|
||||||
static float boxVelX = 0.5f;
|
|
||||||
static float boxVelY = 0.5f;
|
|
||||||
|
|
||||||
static float boxSpeed = 300.f;
|
static float ballVelX = -0.5f;
|
||||||
|
static float ballVelY = 0.5f;
|
||||||
|
static float ballSpeed = 600.f;
|
||||||
|
static float ballAccel = 25.f;
|
||||||
|
|
||||||
|
static float opponentSpeed = 450.f;
|
||||||
|
static float opponentVelY = 0.f;
|
||||||
|
|
||||||
const char* vShader = "#version 300 es\n"
|
const char* vShader = "#version 300 es\n"
|
||||||
"layout (location = 0) in vec2 aPos;\n"
|
"layout (location = 0) in vec2 aPos;\n"
|
||||||
|
"uniform vec4 uColor;\n"
|
||||||
|
"out vec4 color;\n"
|
||||||
"void main()\n"
|
"void main()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" gl_Position = vec4(aPos, 0.0, 1.0);\n"
|
" gl_Position = vec4(aPos, 0.0, 1.0);\n"
|
||||||
|
" color = uColor;\n"
|
||||||
"}";
|
"}";
|
||||||
|
|
||||||
const char* fShader = "#version 300 es\n"
|
const char* fShader = "#version 300 es\n"
|
||||||
"precision mediump float;\n"
|
"precision mediump float;\n"
|
||||||
"out vec4 fragColor;\n"
|
"out vec4 fragColor;\n"
|
||||||
|
"in vec4 color;\n"
|
||||||
"void main()\n"
|
"void main()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" fragColor = vec4(0.8, 0.8, 0.8, 1.0);\n"
|
" fragColor = color;\n"
|
||||||
"}";
|
"}";
|
||||||
|
|
||||||
void computeLetterbox(int windowW, int windowH,
|
void computeLetterbox(int windowW, int windowH,
|
||||||
@@ -62,12 +79,101 @@ void computeLetterbox(int windowW, int windowH,
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct Rect {
|
struct Rect {
|
||||||
|
public:
|
||||||
float x;
|
float x;
|
||||||
float y;
|
float y;
|
||||||
float w;
|
float w;
|
||||||
float h;
|
float h;
|
||||||
|
private:
|
||||||
|
float vertices[12];
|
||||||
|
GLuint vao, vbo;
|
||||||
|
public:
|
||||||
|
Rect(float x, float y, float w, float h) {
|
||||||
|
this->x = x;
|
||||||
|
this->y = y;
|
||||||
|
this->w = w;
|
||||||
|
this->h = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Init() {
|
||||||
|
glGenVertexArrays(1, &vao);
|
||||||
|
glGenBuffers(1, &vbo);
|
||||||
|
|
||||||
|
glBindVertexArray(vao);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
|
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void *)0);
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Draw() {
|
||||||
|
float xProj = (x / SCREEN_WIDTH) * 2.0f - 1.0f;
|
||||||
|
float yProj = 1.0f - (y / SCREEN_HEIGHT) * 2.0f;
|
||||||
|
|
||||||
|
float wProj = (w / SCREEN_WIDTH) * 2.0f;
|
||||||
|
float hProj = (h / SCREEN_HEIGHT) * 2.0f;
|
||||||
|
|
||||||
|
vertices[0] = xProj;
|
||||||
|
vertices[1] = yProj;
|
||||||
|
vertices[2] = xProj + wProj;
|
||||||
|
vertices[3] = yProj;
|
||||||
|
vertices[4] = xProj + wProj;
|
||||||
|
vertices[5] = yProj - hProj;
|
||||||
|
|
||||||
|
vertices[6] = xProj;
|
||||||
|
vertices[7] = yProj;
|
||||||
|
vertices[8] = xProj;
|
||||||
|
vertices[9] = yProj - hProj;
|
||||||
|
vertices[10] = xProj + wProj;
|
||||||
|
vertices[11] = yProj - hProj;
|
||||||
|
|
||||||
|
glBindVertexArray(vao);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
|
glBindVertexArray(vao);
|
||||||
|
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||||
|
|
||||||
|
glBindVertexArray(0);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CollidesWith(const Rect& b) {
|
||||||
|
return (x < b.x + b.w &&
|
||||||
|
x + w > b.x &&
|
||||||
|
y < b.y + b.h &&
|
||||||
|
y + h > b.y);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static Rect ball(
|
||||||
|
SCREEN_WIDTH / 2 - BALL_SIZE / 2,
|
||||||
|
SCREEN_HEIGHT / 2 - BALL_SIZE / 2,
|
||||||
|
BALL_SIZE,
|
||||||
|
BALL_SIZE
|
||||||
|
);
|
||||||
|
|
||||||
|
static Rect player(
|
||||||
|
50.f,
|
||||||
|
SCREEN_HEIGHT / 2 - PLATE_HEIGHT / 2,
|
||||||
|
PLATE_WIDTH,
|
||||||
|
PLATE_HEIGHT
|
||||||
|
);
|
||||||
|
|
||||||
|
static Rect opponent(
|
||||||
|
SCREEN_WIDTH - PLATE_WIDTH - 50.f,
|
||||||
|
SCREEN_HEIGHT / 2 - PLATE_HEIGHT / 2,
|
||||||
|
PLATE_WIDTH,
|
||||||
|
PLATE_HEIGHT
|
||||||
|
);
|
||||||
|
|
||||||
|
bool paused = true;
|
||||||
|
|
||||||
extern "C" int APP_MAIN(int argc, char **argv) {
|
extern "C" int APP_MAIN(int argc, char **argv) {
|
||||||
SDL_SetAppMetadata("Example Renderer Primitives", "1.0", "com.example.renderer-primitives");
|
SDL_SetAppMetadata("Example Renderer Primitives", "1.0", "com.example.renderer-primitives");
|
||||||
SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeLeft LandscapeRight");
|
SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeLeft LandscapeRight");
|
||||||
@@ -129,28 +235,9 @@ extern "C" int APP_MAIN(int argc, char **argv) {
|
|||||||
glDeleteShader(vertexShader);
|
glDeleteShader(vertexShader);
|
||||||
glDeleteShader(fragmentShader);
|
glDeleteShader(fragmentShader);
|
||||||
|
|
||||||
float vertices[12] = {0};
|
ball.Init();
|
||||||
|
player.Init();
|
||||||
Rect rect = {
|
opponent.Init();
|
||||||
.x = 50.f,
|
|
||||||
.y = 50.f,
|
|
||||||
.w = BOX_WIDTH,
|
|
||||||
.h = BOX_HEIGHT,
|
|
||||||
};
|
|
||||||
|
|
||||||
GLuint vao, vbo;
|
|
||||||
glGenVertexArrays(1, &vao);
|
|
||||||
glGenBuffers(1, &vbo);
|
|
||||||
|
|
||||||
glBindVertexArray(vao);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW);
|
|
||||||
|
|
||||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void *)0);
|
|
||||||
glEnableVertexAttribArray(0);
|
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
glBindVertexArray(0);
|
|
||||||
|
|
||||||
int drawableW, drawableH;
|
int drawableW, drawableH;
|
||||||
SDL_GetWindowSizeInPixels(window, &drawableW, &drawableH);
|
SDL_GetWindowSizeInPixels(window, &drawableW, &drawableH);
|
||||||
@@ -173,57 +260,77 @@ extern "C" int APP_MAIN(int argc, char **argv) {
|
|||||||
if (event.type == SDL_EVENT_QUIT) {
|
if (event.type == SDL_EVENT_QUIT) {
|
||||||
running = false;
|
running = false;
|
||||||
}
|
}
|
||||||
|
if (!paused) {
|
||||||
|
if (event.type == SDL_EVENT_MOUSE_MOTION) {
|
||||||
|
player.y = clamp(event.motion.y - PLATE_HEIGHT / 2, 0, SCREEN_HEIGHT - PLATE_HEIGHT);
|
||||||
|
} else if (event.type == SDL_EVENT_FINGER_MOTION) {
|
||||||
|
player.y = clamp(event.motion.y - PLATE_HEIGHT / 2, 0, SCREEN_HEIGHT - PLATE_HEIGHT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (paused && event.type == SDL_EVENT_KEY_DOWN && event.key.key == SDLK_SPACE) {
|
||||||
|
paused = false;
|
||||||
|
} else if (paused && event.type == SDL_EVENT_FINGER_UP) {
|
||||||
|
paused = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto now = SDL_GetTicks();
|
auto now = SDL_GetTicks();
|
||||||
float dt = now - elapsed;
|
float dt = now - elapsed;
|
||||||
elapsed = now;
|
elapsed = now;
|
||||||
// SDL_Log("dt: %f\n", dt);
|
|
||||||
dt /= 1000.f;
|
dt /= 1000.f;
|
||||||
|
|
||||||
rect.x += boxSpeed * boxVelX * dt;
|
if (!paused) {
|
||||||
rect.y += boxSpeed * boxVelY * dt;
|
ball.x += ballSpeed * ballVelX * dt;
|
||||||
// boxSpeed += 50.f * dt;
|
ball.y += ballSpeed * ballVelY * dt;
|
||||||
|
ballSpeed += ballAccel * dt;
|
||||||
|
|
||||||
if (rect.x + BOX_WIDTH >= SCREEN_WIDTH || rect.x <= 0) boxVelX *= -1.f;
|
if (ball.x + BALL_SIZE >= SCREEN_WIDTH || ball.x <= 0) ballVelX *= -1.f;
|
||||||
if (rect.y + BOX_HEIGHT >= SCREEN_HEIGHT || rect.y <= 0) boxVelY *= -1.f;
|
|
||||||
|
|
||||||
// float xProj = -1 + rect.x / ((float)SCREEN_WIDTH / 2);
|
if (ball.x <= 0) {
|
||||||
// float yProj = rect.y / ((float)SCREEN_HEIGHT / 2);
|
ball.x = 1.f;
|
||||||
|
paused = true;
|
||||||
|
}
|
||||||
|
if (ball.x + BALL_SIZE >= SCREEN_WIDTH) {
|
||||||
|
ball.x = SCREEN_WIDTH - BALL_SIZE - 1.f;
|
||||||
|
paused = true;
|
||||||
|
}
|
||||||
|
|
||||||
float xProj = (rect.x / SCREEN_WIDTH) * 2.0f - 1.0f;
|
if (ball.y + BALL_SIZE >= SCREEN_HEIGHT || ball.y <= 0) ballVelY *= -1.f;
|
||||||
float yProj = 1.0f - (rect.y / SCREEN_HEIGHT) * 2.0f;
|
if (ball.y + BALL_SIZE >= SCREEN_HEIGHT) ball.y = SCREEN_HEIGHT - BALL_SIZE - 1.f;
|
||||||
|
if (ball.y <= 0) ball.y = 1.f;
|
||||||
|
|
||||||
float wProj = (rect.w / SCREEN_WIDTH) * 2.0f;
|
if (ball.CollidesWith(player)) {
|
||||||
float hProj = (rect.h / SCREEN_HEIGHT) * 2.0f;
|
ball.x = player.x + PLATE_WIDTH + 1.f;
|
||||||
SDL_Log("%f::%f (%f:%f)\n", xProj, yProj, wProj, hProj);
|
ballVelX *= -1;
|
||||||
|
}
|
||||||
|
if (ball.CollidesWith(opponent)) {
|
||||||
|
ball.x = opponent.x - BALL_SIZE - 1.f;
|
||||||
|
ballVelX *= -1;
|
||||||
|
}
|
||||||
|
|
||||||
vertices[0] = xProj;
|
opponentVelY = clamp(ball.y - (opponent.y + PLATE_HEIGHT / 2 - BALL_SIZE / 2), -1.f, 1.f);
|
||||||
vertices[1] = yProj;
|
opponent.y = clamp(opponent.y + opponentSpeed * opponentVelY * dt, 0, SCREEN_HEIGHT - PLATE_HEIGHT);
|
||||||
vertices[2] = xProj + wProj;
|
}
|
||||||
vertices[3] = yProj;
|
|
||||||
vertices[4] = xProj + wProj;
|
|
||||||
vertices[5] = yProj - hProj;
|
|
||||||
|
|
||||||
vertices[6] = xProj;
|
|
||||||
vertices[7] = yProj;
|
|
||||||
vertices[8] = xProj;
|
|
||||||
vertices[9] = yProj - hProj;
|
|
||||||
vertices[10] = xProj + wProj;
|
|
||||||
vertices[11] = yProj - hProj;
|
|
||||||
|
|
||||||
glClearColor(0x18/255.f, 0x18/255.f, 0x18/255.f, 1.0f);
|
glClearColor(0x18/255.f, 0x18/255.f, 0x18/255.f, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
// Draw your 3D stuff here
|
// Draw your 3D stuff here
|
||||||
glBindVertexArray(vao);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW);
|
|
||||||
|
|
||||||
glUseProgram(program);
|
glUseProgram(program);
|
||||||
glBindVertexArray(vao);
|
auto colorLoc = glGetUniformLocation(program, "uColor");
|
||||||
|
float color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
glUniform4fv(colorLoc, 1, color);
|
||||||
|
ball.Draw();
|
||||||
|
player.Draw();
|
||||||
|
|
||||||
|
color[0] = 0.8f;
|
||||||
|
color[1] = 0.2f;
|
||||||
|
color[2] = 0.25f;
|
||||||
|
color[3] = 1.0f;
|
||||||
|
glUniform4fv(colorLoc, 1, color);
|
||||||
|
opponent.Draw();
|
||||||
|
|
||||||
SDL_GL_SwapWindow(window);
|
SDL_GL_SwapWindow(window);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user