First iteration of pong finished

This commit is contained in:
Toasterbirb 2021-12-31 20:10:05 +02:00
parent 868bc065b7
commit 960ff4edcf
3 changed files with 317 additions and 74 deletions

View File

@ -21,7 +21,7 @@ pong: pong_main.o logger.o renderwindow.o timestep.o entity.o utils.o
rsync -av ./games/Ping-Pong/res ./build/
$(CC) $^ $(SDL_FLAGS) $(WarningFlags) -o $(outputDir)/pong
pong_main.o: $(PONG_SRC)/main.cpp
pong_main.o: $(PONG_SRC)/pong_entry.cpp
$(CC) -c $(INCLUDES) $(SDL_FLAGS) $(WarningFlags) $^ -o pong_main.o
entity.o: $(SRCDIR)/entity.cpp

View File

@ -1,73 +0,0 @@
#include <iostream>
#include <SDL2/SDL.h>
#include "Entity.hpp"
#include "Logger.hpp"
#include "Values.hpp"
#include "Timestep.hpp"
#include "Renderwindow.hpp"
/* Variables */
bool GameRunning = true;
int main(int argc, char **argv)
{
Debug::Log("Starting Pong!");
Debug::Log("Working directory: " + (std::string)argv[0]);
std::string workdir = (std::string)argv[0];
size_t pos = std::string::npos;
// Search for the substring in string in a loop untill nothing is found
while ((pos = workdir.find("/pong") )!= std::string::npos)
{
// If found then erase it from string
workdir.erase(pos, std::string("/pong").length());
}
Birb2D::Window window("Pong", Vector2int(1280, 720), 240);
Birb2D::TimeStep timeStep;
/* Initialize timestep */
timeStep.Init();
/* Gameloop variables */
SDL_Event event;
TTF_Font* titleFont = Birb2D::Resources::LoadFont(workdir + "/res/fonts/manaspace/manaspc.ttf", 16);
Birb2D::Entity title("Title", Vector2int(0, 0), Birb2D::TextComponent("Ping Pong", titleFont, &Colors::White));
title.localScale = { 2.2, 2.2 };
Birb2D::Entity testPicture("Gigachad", Vector2int(150, 150), Birb2D::Resources::LoadTexture(workdir + "/res/textures/giga_stretch.png"));
testPicture.localScale = { 0.5, 0.5 };
while (GameRunning)
{
timeStep.Start();
while (timeStep.Running())
{
while (SDL_PollEvent(&event) != 0)
{
window.EventTick(event, &GameRunning);
}
timeStep.Step();
}
timeStep.End();
/* Render stuff */
window.Clear();
Birb2D::Render::DrawEntity(title);
Birb2D::Render::DrawRect(Colors::White, Rect(25, 40, 300, 300));
Birb2D::Render::DrawCircle(Colors::Red, Vector2int(250, 260), 150);
Birb2D::Render::DrawCircle(Colors::Green, Vector2int(290, 260), 150);
Birb2D::Render::DrawEntity(testPicture);
Birb2D::Render::DrawCircle(Colors::Blue, Vector2int(190, 360), 150);
window.Display();
/* End of rendering */
}
Debug::Log("Starting cleanup...");
window.Cleanup();
SDL_Quit();
Debug::Log("Game should be closed now!");
return 0;
}

View File

@ -0,0 +1,316 @@
#include <iostream>
#include <SDL2/SDL.h>
#include "Entity.hpp"
#include "Logger.hpp"
#include "Values.hpp"
#include "Timestep.hpp"
#include "Renderwindow.hpp"
enum PlayerType
{
Player, Bot, NoOne
};
enum Side
{
Left, Right, Top, Bottom, Up, Down, None
};
/* Variables */
bool GameRunning = true;
const Vector2f baseBallVector = { 6, 6 };
PlayerType lastCollider = PlayerType::NoOne;
Side lastSide = Side::None;
void MirrorBallVector(Vector2f* ballVector, Side side, Side playerMovementDirection)
{
float movementMultiplier = 1.00f;
if (playerMovementDirection != Side::None && side == Left && side != Top && side != Bottom)
{
std::cout << "Changing ball direction" << std::endl;
movementMultiplier = 1.10f;
/* Change the ball movement direction depending on the player movement */
ballVector->x *= -1;
switch (playerMovementDirection)
{
case (Side::Up):
if (ballVector->y > 0)
ballVector->y *= -1 * movementMultiplier;
break;
case (Side::Down):
if (ballVector->y < 0)
ballVector->y *= -1 * movementMultiplier;
break;
default:
break;
}
lastSide = Side::Left;
return;
}
else
movementMultiplier = 0.90f;
/* Prevent the ball from glitching into the walls */
if (side == lastSide)
{
Debug::Log("Cancelling repeating collision");
return;
}
switch (side)
{
case (Top):
ballVector->y *= -1 * movementMultiplier;
break;
case (Bottom):
ballVector->y *= -1 * movementMultiplier;
break;
case (Left):
ballVector->x *= -1;
break;
case (Right):
ballVector->x *= -1;
break;
default:
break;
}
lastSide = side;
std::cout << side << std::endl;
}
Side BallScreenBoundHit(Vector2f pos, int radius, Birb2D::Window window)
{
/* Top hit */
if (pos.y - radius < 0)
return Side::Top;
/* Bottom hit */
if (pos.y + radius > window.window_dimensions.y)
return Side::Bottom;
/* Left hit */
if (pos.x - radius < 0)
return Side::Left;
/* Right hit */
if (pos.x + radius > window.window_dimensions.x)
return Side::Right;
return Side::None;
}
void ResetBall(Vector2f* ballPosition, Vector2f* ballVector, Birb2D::Window window)
{
ballPosition->x = window.window_dimensions.x / 2.00f;
ballPosition->y = window.window_dimensions.y / 2.00f;
ballVector->x = baseBallVector.x;
ballVector->y = baseBallVector.y;
lastCollider = PlayerType::NoOne;
lastSide = Side::None;
}
void UpdateBallCollider(Rect* collider, Vector2f ballPosition, int ballSize)
{
collider->x = ballPosition.x - (ballSize / 2.00f);
collider->y = ballPosition.y - (ballSize / 2.00f);
collider->w = (float)ballSize;
collider->h = (float)ballSize;
}
Side BallPlayerCollision(Rect playerDimensions, Rect botDimensions, Rect ballCollider)
{
SDL_Rect player = playerDimensions.getSDLRect();
SDL_Rect bot = botDimensions.getSDLRect();
SDL_Rect ball = ballCollider.getSDLRect();
/* Collision with either bot or player and the ball */
if (SDL_HasIntersection(&player, &ball) && lastCollider != PlayerType::Player)
{
lastCollider = PlayerType::Player;
return Side::Left;
}
else if (SDL_HasIntersection(&bot, &ball) && lastCollider != PlayerType::Bot)
{
lastCollider = PlayerType::Bot;
return Side::Right;
}
else
return Side::None;
}
int main(int argc, char **argv)
{
Debug::Log("Starting Pong!");
Debug::Log("Working directory: " + (std::string)argv[0]);
std::string workdir = (std::string)argv[0];
size_t pos = std::string::npos;
// Search for the substring in string in a loop untill nothing is found
while ((pos = workdir.find("/pong") )!= std::string::npos)
{
// If found then erase it from string
workdir.erase(pos, std::string("/pong").length());
}
Birb2D::Window window("Pong", Vector2int(1280, 720), 240);
Birb2D::TimeStep timeStep;
/* Initialize timestep */
timeStep.Init();
/* Gameloop variables */
SDL_Event event;
bool holdingKey = false;
TTF_Font* manaspaceFont = Birb2D::Resources::LoadFont(workdir + "/res/fonts/manaspace/manaspc.ttf", 16);
/* Ball variables */
Vector2f ballVector = { 6, 6 };
Vector2f ballPosition = { window.window_dimensions.x / 2.00f, window.window_dimensions.y / 2.00f };
int ballSize = 8;
Rect ballCollider;
/* Player variables */
int playerSpeed = 8;
int playerSideOffset = 32;
Rect playerDimensions = { (float)playerSideOffset, window.window_dimensions.y / 2.00f - 50, 10, 100 };
Side playerMovementDirection = Side::None;
int botMovementSpeed = 4;
Rect botDimensions = playerDimensions;
botDimensions.x = window.window_dimensions.x - playerDimensions.x - playerDimensions.w;
while (GameRunning)
{
timeStep.Start();
while (timeStep.Running())
{
bool playerMoved = false;
while (SDL_PollEvent(&event) != 0)
{
window.EventTick(event, &GameRunning);
/* Player movement */
if (event.type == SDL_KEYDOWN)
{
switch (event.key.keysym.scancode)
{
/* Up arrow */
case (82):
playerMovementDirection = Side::Up;
break;
case (81):
playerMovementDirection = Side::Down;
break;
default:
playerMovementDirection = Side::None;
break;
}
}
else if (event.type == SDL_KEYUP)
{
playerMovementDirection = Side::None;
}
}
timeStep.Step();
}
timeStep.End();
/* Handle player movement */
{
if (playerMovementDirection == Side::Up)
playerDimensions.y -= playerSpeed;
else if (playerMovementDirection == Side::Down)
playerDimensions.y += playerSpeed;
}
/* Ball movemement and colliders */
{
ballPosition.x += ballVector.x;
ballPosition.y += ballVector.y;
UpdateBallCollider(&ballCollider, ballPosition, ballSize);
/* Ball hit the top or bottom. Just bounce */
Side hitSide = BallScreenBoundHit(ballPosition, ballSize, window);
if (hitSide == Side::Top || hitSide == Side::Bottom)
MirrorBallVector(&ballVector, hitSide, playerMovementDirection);
/* Ball hit the side walls. Reset the game */
if (hitSide == Side::Left || hitSide == Side::Right)
{
MirrorBallVector(&ballVector, hitSide, playerMovementDirection);
ResetBall(&ballPosition, &ballVector, window);
}
/* Check for paddle hits */
hitSide = BallPlayerCollision(playerDimensions, botDimensions, ballCollider);
if (hitSide != Side::None)
MirrorBallVector(&ballVector, hitSide, playerMovementDirection);
}
/* Render stuff */
window.Clear();
{
/* Draw playfield divider */
Birb2D::Render::DrawRect(Colors::White, Rect((window.window_dimensions.x / 2.00f) - 4, 0, 8, window.window_dimensions.y));
/* Draw players */
{
/* Player */
Birb2D::Render::DrawRect(Colors::White,
Rect(playerDimensions.x, playerDimensions.y,
playerDimensions.w, playerDimensions.h));
/* Bot */
if (ballPosition.x > window.window_dimensions.x / 2.00f) // Only move the bot paddle if the ball is on its side
{
if (ballPosition.y - (playerDimensions.h / 2.00f) > 0 && ballPosition.y + (playerDimensions.h / 2.00f) < window.window_dimensions.y)
{
if (ballPosition.y > botDimensions.y + (botDimensions.h / 2.00f))
botDimensions.y += botMovementSpeed;
else
botDimensions.y -= botMovementSpeed;
}
}
Birb2D::Render::DrawRect(Colors::White,
Rect(botDimensions.x, botDimensions.y,
botDimensions.w, botDimensions.h));
}
/* Draw the ball */
Birb2D::Render::DrawCircle(Colors::White,
Vector2int(ballPosition.x, ballPosition.y),
ballSize);
}
window.Display();
/* End of rendering */
}
Debug::Log("Starting cleanup...");
window.Cleanup();
SDL_Quit();
Debug::Log("Game should be closed now!");
return 0;
}