#include "Game.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include const float Game::paddleSpeed = 400.0f; const float Game::ballSpeed = 5000.0f; Game::~Game() { } Game::Game() : Level("Game"), plyScore(0), aiScore(0), started(false) { } Game::Game(const Game& lvl) : Level(lvl), plyScore(lvl.plyScore), aiScore(lvl.aiScore), started(lvl.started) { } Game& Game::operator=(const Game& lvl) { if (this == &lvl) return *this; Level::operator=(lvl); plyScore = lvl.plyScore; aiScore = lvl.aiScore; started = lvl.started; return *this; } void Game::SetupResources(lwe::GpuInterface *inf) { Level::SetupResources(inf); // Setup Resource Code Here AddResource(new lwe::GpuMesh(inf, ehs::portraitGui)); AddResource(new ehs::Audio("resources/audio/Wall.wav", ehs::DataType::FLOAT)); AddResource(new ehs::Audio("resources/audio/Paddle.wav", ehs::DataType::FLOAT)); AddResource(new ehs::Audio("resources/audio/Score.wav", ehs::DataType::FLOAT)); constexpr ehs::UInt_8 circleData[] = {255, 255, 255, 255}; lwe::GpuImg* circle = new lwe::GpuImg("Circle", inf, 1, 4, {1, 1}, (ehs::Byte*)circleData, lwe::GpuImgAspect::IMG_ASPECT_COLOR); AddResource(circle); } void Game::Setup(lwe::GpuInterface *inf) { Level::Setup(inf); // Setup Code Here lwe::GameLoop* gl = GetParent(); lwe::RenderWindow* win = gl->GetWindow(); // Adding Systems Here //AddSystem(new lwe::AudioSystem()); AddSystem(new lwe::Portrait2DSystem()); AddSystem(new lwe::RigidBodySystem()); lwe::GuiSystem* gui = new lwe::GuiSystem(); gui->AddResource(new lwe::GpuFontAtlas("resources/fonts/Arial_48.ehf", win->GetInterface())); AddSystem(gui); ehs::Vec2_f scale = win->GetSwapChain()->GetScale(); ehs::Vec2_f center = win->GetSwapChain()->GetScale() / 2; // Score Gui lwe::LabelGui* plyScore = new lwe::LabelGui("PlyScore", "Arial_48", "0"); plyScore->SetPosition({20.0f, 20.0f, 0.0f}); gui->AddGui(plyScore); lwe::LabelGui* aiScore = new lwe::LabelGui("AiScore", "Arial_48", "0"); aiScore->SetPosition({scale.x - 68.0f, 20.0f, 0.0f}); gui->AddGui(aiScore); // Bounds Entity lwe::Entity bounds("Bounds"); bounds.SetScale({win->GetSwapChain()->GetScale(), 1.0f}); lwe::AABB2D* collider = new lwe::AABB2D("BoundsCollider", 0.0f, 0.0f); collider->SetInverted(true); collider->SetStatic(true); bounds.AddComponent(collider); AddEntity(bounds); // Field Separator Entity lwe::Entity fieldSep("FieldSeparator"); fieldSep.SetScale({10.0f, scale.y, 1.0f}); fieldSep.SetPos({center.x - 5.0f, 0.0f, 0.0f}); lwe::Portrait2D* fieldSepImg = new lwe::Portrait2D("PaddleImg", "Circle"); fieldSepImg->SetColor({0.75f}); fieldSep.AddComponent(fieldSepImg); AddEntity(fieldSep); // Paddle Entity Template lwe::Entity paddle("Paddle"); paddle.SetScale({20.0f, 200.0f, 1.0f}); lwe::AABB2D* paddleCollider = new lwe::AABB2D("PaddleCollider", 0.0f, 0.0f); paddleCollider->SetStatic(true); paddle.AddComponent(paddleCollider); lwe::Portrait2D* paddleImg = new lwe::Portrait2D("PaddleImg", "Circle"); paddleImg->SetColor({0.75f}); paddle.AddComponent(paddleImg); AddTemplate(paddle); // Player's Paddle lwe::Entity* plyPaddle = CreateEntity("Paddle", "PlyPaddle"); plyPaddle->SetPos({50.0f, center.y - 100.0f, 0.0f}); // Player's Paddle lwe::Entity* aiPaddle = CreateEntity("Paddle", "AiPaddle"); aiPaddle->SetPos({scale.x - 50.0f, center.y - 100.0f, 0.0f}); // Ball Entity lwe::Entity ball("Ball"); ball.SetScale({20.0f, 20.0f, 1.0f}); ball.SetPos({center.x - 10.0f, center.y - 10.0f, 0.0f}); lwe::AABB2D* ballCollider = new lwe::AABB2D("BallCollider", 0.5f, 1.1f); ballCollider->SetCollidedCb([](lwe::RigidBody* a, lwe::RigidBody* b) { lwe::Entity* aOwner = (lwe::Entity*)a->GetEntity(); lwe::Entity* bOwner = (lwe::Entity*)b->GetEntity(); static ehs::UInt_64 id = 0; if (bOwner->GetId() == "Bounds") { lwe::AudioSource* audio = new lwe::AudioSource("Audio_" + ehs::Str_8::FromNum(id++),"Wall"); audio->EnableAutoDelete(true); audio->EnableLoop(false); audio->Play(); aOwner->AddComponent(audio); } else { lwe::AudioSource* audio = new lwe::AudioSource("Audio_" + ehs::Str_8::FromNum(id++),"Paddle"); audio->EnableAutoDelete(true); audio->EnableLoop(false); audio->Play(); aOwner->AddComponent(audio); } }); ball.AddComponent(ballCollider); lwe::Portrait2D* ballImg = new lwe::Portrait2D("BallImg", "Circle"); ballImg->SetColor({1.0f, 0.0f, 0.0f}); ball.AddComponent(ballImg); AddEntity(ball); } void Game::PostInitialize(lwe::GpuCmdBuffer* cmdBuffer) { Level::PostInitialize(cmdBuffer); // Post Initialization Code Here } void Game::OnUpdate(lwe::RenderWindow* win, ehs::Input* input, const float delta) { Level::OnUpdate(win, input, delta); // Update Code Here const ehs::InputHandler* ih = win->GetInputHandler(); const ehs::Keyboard* keyboard = (ehs::Keyboard*)ih->GetDeviceByType(EHS_HID_KEYBOARD); if (!keyboard) return; lwe::Entity* bounds = GetEntity("Bounds"); lwe::Entity* ball = GetEntity("Ball"); ehs::Vec3_f ballPos = ball->GetPos(); ehs::Vec3_f ballScale = ball->GetScale(); if (ballPos.x <= bounds->GetPos().x + 10.0f) { aiScore++; lwe::GuiSystem* gui = (lwe::GuiSystem*)GetSystem("GuiSystem"); lwe::LabelGui* aiScoreLabel = (lwe::LabelGui*)gui->GetGui("AiScore"); aiScoreLabel->SetText(ehs::Str_8::FromNum(aiScore)); ResetGame(bounds, ball); } else if (ballPos.x + ballScale.x >= bounds->GetScale().x - 10.0f) { plyScore++; lwe::GuiSystem* gui = (lwe::GuiSystem*)GetSystem("GuiSystem"); lwe::LabelGui* plyScoreLabel = (lwe::LabelGui*)gui->GetGui("PlyScore"); plyScoreLabel->SetText(ehs::Str_8::FromNum(plyScore)); ResetGame(bounds, ball); } lwe::Entity* plyPaddle = GetEntity("PlyPaddle"); if (!started && keyboard->IsTouched(ehs::Keyboard::Space)) { if (!ehs::CPU::HasRDRND()) return; lwe::AABB2D* ballCollider = (lwe::AABB2D*)ball->GetComponent("AABB2D"); if (const ehs::UInt_8 result = ehs::HRNG::Generate_s8(0, 4); result == 0) ballCollider->ApplyForce({ballSpeed, ballSpeed, 0.0f}); else if (result == 1) ballCollider->ApplyForce({-ballSpeed, ballSpeed, 0.0f}); else if (result == 2) ballCollider->ApplyForce({ballSpeed, -ballSpeed, 0.0f}); else if (result == 3) ballCollider->ApplyForce({-ballSpeed, -ballSpeed, 0.0f}); started = true; } if (keyboard->IsDown(ehs::Keyboard::W)) { ehs::Vec3_f newPos = plyPaddle->GetPos() - ehs::Vec3_f(0.0f, paddleSpeed, 0.0f) * delta; if (newPos.y <= bounds->GetPos().y) newPos.y = bounds->GetPos().y; plyPaddle->SetPos(newPos); } if (keyboard->IsDown(ehs::Keyboard::S)) { ehs::Vec3_f newPos = plyPaddle->GetPos() + ehs::Vec3_f(0.0f, paddleSpeed, 0.0f) * delta; if (newPos.y + plyPaddle->GetScale().y >= bounds->GetScale().y) newPos.y = bounds->GetScale().y - plyPaddle->GetScale().y; plyPaddle->SetPos(newPos); } lwe::Entity* aiPaddle = GetEntity("AiPaddle"); ehs::Vec3_f aiPaddlePos = aiPaddle->GetPos(); ehs::Vec3_f aiPaddleScale = aiPaddle->GetScale(); if (aiPaddlePos.y + aiPaddleScale.y / 2.0f < ballPos.y + ballScale.y / 2.0f) { aiPaddlePos = aiPaddlePos + ehs::Vec3_f(0.0f, paddleSpeed * 2.0f, 0.0f) * delta; if (aiPaddlePos.y + aiPaddleScale.y / 2.0f > ballPos.y + ballScale.y / 2.0f) aiPaddlePos.y = ballPos.y + ballScale.y / 2.0f - aiPaddleScale.y / 2.0f; if (aiPaddlePos.y + aiPaddleScale.y >= bounds->GetScale().y) aiPaddlePos.y = bounds->GetScale().y - aiPaddleScale.y; aiPaddle->SetPos(aiPaddlePos); } else { aiPaddlePos = aiPaddlePos - ehs::Vec3_f(0.0f, paddleSpeed * 2.0f, 0.0f) * delta; if (aiPaddlePos.y + aiPaddleScale.y / 2.0f < ballPos.y + ballScale.y / 2.0f) aiPaddlePos.y = ballPos.y + ballScale.y / 2.0f - aiPaddleScale.y / 2.0f; if (aiPaddlePos.y <= bounds->GetPos().y) aiPaddlePos.y = bounds->GetPos().y; aiPaddle->SetPos(aiPaddlePos); } } void Game::PreRender(lwe::GpuCmdBuffer* cmdBuffer) { Level::PreRender(cmdBuffer); // Pre-Render Code Here } void Game::ResetGame(const lwe::Entity* bounds, lwe::Entity* ball) { lwe::AudioSource* audio = new lwe::AudioSource("Score", "Score"); audio->EnableAutoDelete(true); audio->EnableLoop(false); audio->Play(); ball->AddComponent(audio); ball->SetPos(bounds->GetScale() / 2.0f - ball->GetScale() / 2.0f); lwe::AABB2D* ballCollider = (lwe::AABB2D*)ball->GetComponent("AABB2D"); ballCollider->ResetVelocity(); started = false; }