added timer and music
This commit is contained in:
parent
5f77a3a337
commit
fe353f2913
|
|
@ -1,3 +1,3 @@
|
||||||
[submodule "vendor"]
|
[submodule "vendor"]
|
||||||
path = vendor
|
path = vendor
|
||||||
url = ssh://git@git.josephaquino.net:2222/joseph-aquino/imgui-sfml-premake.git
|
url = https://gitlab.com/JosephA1997/imgui-sfml-premake.git
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -0,0 +1,93 @@
|
||||||
|
Copyright 2018 The Chakra Petch Project Authors (https://github.com/m4rc1e/Chakra-Petch.git)
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
https://openfontlicense.org
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,
|
||||||
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the Font Software.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,109 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
#include <SFML/Audio.hpp>
|
||||||
|
#include <SFML/Graphics.hpp>
|
||||||
|
|
||||||
|
using TimePoint = std::chrono::steady_clock::time_point;
|
||||||
|
using TimeDuration = std::chrono::duration<double>;
|
||||||
|
|
||||||
|
struct Player
|
||||||
|
{
|
||||||
|
sf::RectangleShape body{};
|
||||||
|
|
||||||
|
sf::Vector2f pos{};
|
||||||
|
sf::Vector2f prevPos{};
|
||||||
|
float velocity{5};
|
||||||
|
unsigned int score{};
|
||||||
|
bool up{false};
|
||||||
|
bool down{false};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Cpu
|
||||||
|
{
|
||||||
|
sf::RectangleShape body{};
|
||||||
|
|
||||||
|
sf::Vector2f pos{};
|
||||||
|
sf::Vector2f prevPos{};
|
||||||
|
float velocity{};
|
||||||
|
unsigned int score{};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Ball
|
||||||
|
{
|
||||||
|
sf::CircleShape body{};
|
||||||
|
|
||||||
|
sf::Vector2f pos{};
|
||||||
|
sf::Vector2f prevPos{};
|
||||||
|
sf::Vector2f velocity{};
|
||||||
|
float speed{};
|
||||||
|
sf::Angle angle{};
|
||||||
|
};
|
||||||
|
|
||||||
|
class Game
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void init();
|
||||||
|
|
||||||
|
void run();
|
||||||
|
|
||||||
|
void getInput();
|
||||||
|
|
||||||
|
void render();
|
||||||
|
|
||||||
|
void updateCpu();
|
||||||
|
|
||||||
|
void updatePlayer();
|
||||||
|
|
||||||
|
void updateBall();
|
||||||
|
|
||||||
|
void collision();
|
||||||
|
|
||||||
|
void updateTexts();
|
||||||
|
|
||||||
|
void soundSystem();
|
||||||
|
|
||||||
|
void resetGame();
|
||||||
|
|
||||||
|
private:
|
||||||
|
sf::RenderWindow window {sf::VideoMode({1280u, 720u}), "project-pong"};
|
||||||
|
std::chrono::steady_clock clock;
|
||||||
|
|
||||||
|
sf::RectangleShape midline{};
|
||||||
|
sf::RectangleShape gameBoundary{};
|
||||||
|
|
||||||
|
sf::Font font{};
|
||||||
|
|
||||||
|
sf::Text playerScore{font};
|
||||||
|
sf::Text cpuScore{font};
|
||||||
|
sf::Text time{font};
|
||||||
|
|
||||||
|
sf::SoundBuffer bgMusicBuffer;
|
||||||
|
sf::SoundBuffer failSoundBuffer;
|
||||||
|
sf::SoundBuffer winSoundBuffer;
|
||||||
|
sf::SoundBuffer hitSoundBuffer;
|
||||||
|
sf::SoundBuffer scoreSoundBuffer;
|
||||||
|
|
||||||
|
sf::Sound bgMusic{bgMusicBuffer};
|
||||||
|
sf::Sound failSound{failSoundBuffer};
|
||||||
|
sf::Sound winSound{winSoundBuffer};
|
||||||
|
sf::Sound hitSound{hitSoundBuffer};
|
||||||
|
sf::Sound scoreSound{scoreSoundBuffer};
|
||||||
|
|
||||||
|
size_t frameCount{};
|
||||||
|
|
||||||
|
Player player{};
|
||||||
|
Ball ball{};
|
||||||
|
Cpu cpu{};
|
||||||
|
|
||||||
|
const double physicsDeltaTime = 1.0 / 60.0;
|
||||||
|
const double targetFps = 60.0;
|
||||||
|
const double targetFrameTime = 1.0 / targetFps;
|
||||||
|
|
||||||
|
double accumulator{};
|
||||||
|
|
||||||
|
double playTime{};
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <SFML/Graphics.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
sf::Vector2f getOverlap(const sf::FloatRect first, const sf::FloatRect second);
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
@ECHO OFF
|
||||||
|
ECHO Project files will be written to ./build
|
||||||
|
..\vendor\premake5\premake5.exe vs2022
|
||||||
|
PAUSE
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
#! /bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||||
|
cd "$SCRIPT_DIR"
|
||||||
|
|
||||||
|
echo build files will be placed in /build
|
||||||
|
../vendor/premake5/premake5 premake-ninja && ninja $1 -C ../build
|
||||||
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
#! /bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||||
|
cd "$SCRIPT_DIR"
|
||||||
|
|
||||||
|
echo build files will be placed in ./build
|
||||||
|
./vendor/premake5/premake5 gmake2 && make -C ../build config=$1
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||||
|
cd "$SCRIPT_DIR"
|
||||||
|
|
||||||
|
if [ -z "$1" ] || [ $# -eq 0 ]
|
||||||
|
then
|
||||||
|
ninja -C ../build -t clean
|
||||||
|
else
|
||||||
|
ninja -C ../build -t clean $1
|
||||||
|
fi
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||||
|
cd "$SCRIPT_DIR"
|
||||||
|
|
||||||
|
if [ -z "$1" ] || [ $# -eq 0 ]
|
||||||
|
then
|
||||||
|
make -C ../build config=Debug clean && make -C ../build config=Release clean
|
||||||
|
else
|
||||||
|
make -C ../build config=$1 clean
|
||||||
|
fi
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||||
|
cd "$SCRIPT_DIR"
|
||||||
|
|
||||||
|
if [ -z "$1" ] || [ $# -eq 0 ]
|
||||||
|
then
|
||||||
|
../vendor/premake5/premake5 --config=Debug ecc
|
||||||
|
else
|
||||||
|
../vendor/premake5/premake5 --config=$1 ecc
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
mv compile_commands.json ../compile_commands.json
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
|
||||||
|
|
||||||
|
package.path = package.path .. ";../vendor/premake-scripts/?.lua"
|
||||||
|
|
||||||
|
require "ecc/ecc"
|
||||||
|
require "ninja/ninja"
|
||||||
|
|
||||||
|
local ogg = require("build-ogg")
|
||||||
|
local sfml = require("build-sfml")
|
||||||
|
local flac = require("build-flac")
|
||||||
|
local vorbis = require("build-vorbis")
|
||||||
|
local freetype = require("build-freetype")
|
||||||
|
|
||||||
|
local pong = require("project")
|
||||||
|
|
||||||
|
local rootdir = "../"
|
||||||
|
|
||||||
|
workspace "pong"
|
||||||
|
architecture "x64"
|
||||||
|
startproject"pong"
|
||||||
|
configurations{"Debug", "Release"}
|
||||||
|
location (rootdir .. "build")
|
||||||
|
|
||||||
|
filter"system:linux"
|
||||||
|
staticruntime"Off"
|
||||||
|
|
||||||
|
filter"system:windows"
|
||||||
|
staticruntime"On"
|
||||||
|
filter""
|
||||||
|
|
||||||
|
filter"system:linux"
|
||||||
|
pic"On" -- fix warning when statically linking <relocation against ... in read-only section .text>
|
||||||
|
filter""
|
||||||
|
|
||||||
|
|
||||||
|
output_dir = "%{cfg.buildcfg}-%{cfg.system}-%{cfg.architecture}"
|
||||||
|
intdir = rootdir .. "intermediate-files/"
|
||||||
|
bindir = rootdir .. "bin/" .. output_dir
|
||||||
|
liboutdir = rootdir.. "lib/" .. output_dir
|
||||||
|
|
||||||
|
externalwarnings "Off"
|
||||||
|
|
||||||
|
filter "configurations:debug"
|
||||||
|
defines {"LOG_ENABLE", "GAME_DEBUG"}
|
||||||
|
symbols "on"
|
||||||
|
runtime "Debug"
|
||||||
|
warnings "Extra"
|
||||||
|
|
||||||
|
filter "configurations:release"
|
||||||
|
defines {"GAME_RELEASE"}
|
||||||
|
optimize "Speed"
|
||||||
|
inlining "Auto"
|
||||||
|
symbols "off"
|
||||||
|
runtime "Release"
|
||||||
|
filter""
|
||||||
|
|
||||||
|
group"Dependencies"
|
||||||
|
ogg.generateproject(liboutdir, intdir)
|
||||||
|
sfml.generateproject(liboutdir, intdir)
|
||||||
|
flac.generateproject(liboutdir, intdir)
|
||||||
|
vorbis.generateproject(liboutdir, intdir)
|
||||||
|
freetype.generateproject(liboutdir, intdir)
|
||||||
|
group""
|
||||||
|
|
||||||
|
pong.generateproject(bindir, intdir)
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
local m = {}
|
||||||
|
|
||||||
|
local rootdir = path.join(path.getabsolute(path.getdirectory(_SCRIPT)), "../")
|
||||||
|
|
||||||
|
package.path = package.path .. ";../third-party/premake-scripts/?.lua"
|
||||||
|
|
||||||
|
local sfml = require("build-sfml")
|
||||||
|
|
||||||
|
function m.generateproject(bindir, intdir)
|
||||||
|
project "pong"
|
||||||
|
language "C++"
|
||||||
|
cppdialect "C++20"
|
||||||
|
systemversion "latest"
|
||||||
|
kind "WindowedApp"
|
||||||
|
targetname "pong"
|
||||||
|
targetdir (bindir)
|
||||||
|
debugdir (rootdir)
|
||||||
|
objdir (intdir)
|
||||||
|
|
||||||
|
|
||||||
|
files
|
||||||
|
{
|
||||||
|
path.join(rootdir, "src/**.cpp"),
|
||||||
|
path.join(rootdir, "include/**.h"),
|
||||||
|
path.join(rootdir, "include/**.hpp"),
|
||||||
|
}
|
||||||
|
|
||||||
|
includedirs
|
||||||
|
{
|
||||||
|
path.join(rootdir, "src"),
|
||||||
|
path.join(rootdir, "include"),
|
||||||
|
}
|
||||||
|
|
||||||
|
sfml.link()
|
||||||
|
|
||||||
|
--windows specific settings--
|
||||||
|
filter{"system:windows"}
|
||||||
|
defines {"PLATFORM_WINDOWS"}
|
||||||
|
|
||||||
|
filter {"system:windows", "configurations:debug"}
|
||||||
|
defines{"_DEBUG", "_CONSOLE"}
|
||||||
|
|
||||||
|
filter {"system:windows", "configurations:release"}
|
||||||
|
defines{"NDEBUG"}
|
||||||
|
|
||||||
|
--linux specific settings--
|
||||||
|
filter {"system:linux"}
|
||||||
|
defines {"PLATFORM_LINUX"}
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return m
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||||
|
cd "$SCRIPT_DIR/.."
|
||||||
|
|
||||||
|
./bin/$1-linux-x86_64/snake
|
||||||
|
|
@ -0,0 +1,277 @@
|
||||||
|
#include "Game.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
|
#include <chrono>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
sf::Vector2f velocityInDirection(const float speed_in, const sf::Angle angle_in)
|
||||||
|
{
|
||||||
|
return sf::Vector2f{speed_in * std::cos(angle_in.asRadians()), speed_in * std::sin(angle_in.asRadians())};
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::init()
|
||||||
|
{
|
||||||
|
//load assets
|
||||||
|
if (!font.openFromFile("assets/fonts/ChakraPetch-Regular.ttf"))
|
||||||
|
{
|
||||||
|
std::cerr << "Error: cannot open 'assets/fonts/ChakraPetch-Regular.ttf'\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bgMusicBuffer.loadFromFile("assets/sounds/bgMusic.wav"))
|
||||||
|
{
|
||||||
|
std::cerr << "Error: cannot open 'assets/sounds/bgMusic.wav'\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!winSoundBuffer.loadFromFile("assets/sounds/win.ogg"))
|
||||||
|
{
|
||||||
|
std::cerr << "Error: cannot open 'assets/sounds/win.ogg'\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!failSoundBuffer.loadFromFile("assets/sounds/lose.ogg"))
|
||||||
|
{
|
||||||
|
std::cerr << "Error: cannot open 'assets/sounds/lose.ogg'\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hitSoundBuffer.loadFromFile("assets/sounds/hit.wav"))
|
||||||
|
{
|
||||||
|
std::cerr << "Error: cannot open 'assets/sounds/hit.wav'\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!scoreSoundBuffer.loadFromFile("assets/sounds/score.wav"))
|
||||||
|
{
|
||||||
|
std::cerr << "Error: cannot open 'assets/sounds/score.wav'\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
player.pos = {100, 100};
|
||||||
|
player.body.setSize({10, 70});
|
||||||
|
player.body.setPosition(player.pos);
|
||||||
|
player.body.setFillColor(sf::Color::White);
|
||||||
|
|
||||||
|
cpu.pos = {(float)window.getSize().x - 100, 100};
|
||||||
|
cpu.body.setSize({10,70});
|
||||||
|
cpu.body.setPosition(cpu.pos);
|
||||||
|
cpu.body.setFillColor(sf::Color::White);
|
||||||
|
|
||||||
|
ball.pos = {(float)window.getSize().x / 2.f, (float)window.getSize().y / 2.f};
|
||||||
|
ball.body.setPosition(ball.pos);
|
||||||
|
ball.body.setFillColor(sf::Color::White);
|
||||||
|
ball.body.setRadius(5.f);
|
||||||
|
|
||||||
|
gameBoundary.setOutlineThickness(5);
|
||||||
|
gameBoundary.setOutlineColor(sf::Color::White);
|
||||||
|
gameBoundary.setFillColor(sf::Color::Transparent);
|
||||||
|
gameBoundary.setPosition({0,100});
|
||||||
|
gameBoundary.setSize({1280.f, 620.f});
|
||||||
|
|
||||||
|
midline.setFillColor(sf::Color::White);
|
||||||
|
midline.setSize({2, 40});
|
||||||
|
midline.setPosition({(float)window.getSize().x/2.f - 1.f, 100.f });
|
||||||
|
|
||||||
|
|
||||||
|
time.setString("Time: 00:00");
|
||||||
|
time.setPosition({560, 25});
|
||||||
|
time.setFillColor(sf::Color::White);
|
||||||
|
|
||||||
|
bgMusic.setVolume(15.f);
|
||||||
|
failSound.setVolume(15.f);
|
||||||
|
winSound.setVolume(15.f);
|
||||||
|
hitSound.setVolume(15.f);
|
||||||
|
scoreSound.setVolume(15.f);
|
||||||
|
|
||||||
|
bgMusic.play();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::run()
|
||||||
|
{
|
||||||
|
TimePoint lastFrameStartPoint = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
while (window.isOpen())
|
||||||
|
{
|
||||||
|
TimePoint currentFrameStartPoint = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
TimeDuration duration = currentFrameStartPoint - lastFrameStartPoint;
|
||||||
|
const double frameTime = duration.count();
|
||||||
|
|
||||||
|
playTime += frameTime;
|
||||||
|
|
||||||
|
lastFrameStartPoint = currentFrameStartPoint;
|
||||||
|
|
||||||
|
accumulator += frameTime;
|
||||||
|
if (accumulator > 0.25) accumulator = 0.25;
|
||||||
|
|
||||||
|
getInput();
|
||||||
|
|
||||||
|
if (bgMusic.getStatus() == sf::Sound::Status::Playing)
|
||||||
|
{
|
||||||
|
while (accumulator >= physicsDeltaTime)
|
||||||
|
{
|
||||||
|
updateBall();
|
||||||
|
|
||||||
|
updateCpu();
|
||||||
|
|
||||||
|
updatePlayer();
|
||||||
|
|
||||||
|
collision();
|
||||||
|
|
||||||
|
updateTexts();
|
||||||
|
|
||||||
|
accumulator -= physicsDeltaTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
soundSystem();
|
||||||
|
|
||||||
|
render();
|
||||||
|
|
||||||
|
TimePoint currentFrameEndPoint = std::chrono::steady_clock::now();
|
||||||
|
TimeDuration currentFrameDuration = currentFrameEndPoint - currentFrameStartPoint;
|
||||||
|
|
||||||
|
if (currentFrameDuration.count() < targetFrameTime)
|
||||||
|
|
||||||
|
{
|
||||||
|
TimeDuration sleepNeeded = TimeDuration(targetFrameTime) - currentFrameDuration;
|
||||||
|
std::this_thread::sleep_for(std::chrono::duration_cast<std::chrono::milliseconds>(sleepNeeded));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::getInput()
|
||||||
|
{
|
||||||
|
while (const std::optional event = window.pollEvent())
|
||||||
|
{
|
||||||
|
if (event->is<sf::Event::Closed>())
|
||||||
|
{
|
||||||
|
window.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const auto* keyPressed = event->getIf<sf::Event::KeyPressed>())
|
||||||
|
{
|
||||||
|
switch (keyPressed->scancode)
|
||||||
|
{
|
||||||
|
case sf::Keyboard::Scan::Escape:
|
||||||
|
window.close();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case sf::Keyboard::Scan::Up:
|
||||||
|
case sf::Keyboard::Scan::W:
|
||||||
|
player.up = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case sf::Keyboard::Scan::Down:
|
||||||
|
case sf::Keyboard::Scan::S:
|
||||||
|
player.down = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case sf::Keyboard::Scan::R:
|
||||||
|
resetGame();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const auto* keyReleased = event->getIf<sf::Event::KeyReleased>())
|
||||||
|
{
|
||||||
|
switch (keyReleased->scancode)
|
||||||
|
{
|
||||||
|
case sf::Keyboard::Scan::Up:
|
||||||
|
case sf::Keyboard::Scan::W:
|
||||||
|
player.up = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case sf::Keyboard::Scan::Down:
|
||||||
|
case sf::Keyboard::Scan::S:
|
||||||
|
player.down = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::render()
|
||||||
|
{
|
||||||
|
window.clear();
|
||||||
|
window.draw(gameBoundary);
|
||||||
|
|
||||||
|
window.draw(midline);
|
||||||
|
|
||||||
|
while (midline.getPosition().y <= window.getSize().y)
|
||||||
|
{
|
||||||
|
midline.move({0, 60});
|
||||||
|
window.draw(midline);
|
||||||
|
}
|
||||||
|
|
||||||
|
midline.setPosition({midline.getPosition().x, 100.f});
|
||||||
|
|
||||||
|
player.body.setPosition(player.pos);
|
||||||
|
window.draw(player.body);
|
||||||
|
|
||||||
|
cpu.body.setPosition(cpu.pos);
|
||||||
|
window.draw(cpu.body);
|
||||||
|
|
||||||
|
window.draw(playerScore);
|
||||||
|
window.draw(cpuScore);
|
||||||
|
window.draw(time);
|
||||||
|
|
||||||
|
ball.body.setPosition(ball.pos);
|
||||||
|
window.draw(ball.body);
|
||||||
|
|
||||||
|
window.display();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::updateCpu()
|
||||||
|
{
|
||||||
|
if (ball.pos.y > cpu.pos.y)
|
||||||
|
{
|
||||||
|
cpu.velocity = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ball.pos.y < cpu.pos.y)
|
||||||
|
{
|
||||||
|
cpu.velocity = -5;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ball.pos.y == cpu.pos.y)
|
||||||
|
{
|
||||||
|
cpu.velocity = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cpu.prevPos = cpu.pos;
|
||||||
|
cpu.pos.y += cpu.velocity;
|
||||||
|
}
|
||||||
|
void Game::updatePlayer()
|
||||||
|
{
|
||||||
|
const int direction = player.down - player.up;
|
||||||
|
|
||||||
|
player.prevPos = player.pos;
|
||||||
|
player.pos.y += player.velocity * (float)direction;
|
||||||
|
}
|
||||||
|
void Game::updateBall()
|
||||||
|
{
|
||||||
|
ball.prevPos = ball.pos;
|
||||||
|
ball.pos += ball.velocity;
|
||||||
|
}
|
||||||
|
void Game::collision() {}
|
||||||
|
|
||||||
|
void Game::updateTexts()
|
||||||
|
{
|
||||||
|
const int totalSeconds = static_cast<int>(playTime);
|
||||||
|
const int minutes = totalSeconds / 60;
|
||||||
|
const int seconds = totalSeconds % 60;
|
||||||
|
|
||||||
|
const std::string secondsStr = (seconds < 10) ? "0" + std::to_string(seconds) : std::to_string(seconds);
|
||||||
|
const std::string minutesStr = (minutes < 10) ? "0" + std::to_string(minutes) : std::to_string(minutes);
|
||||||
|
|
||||||
|
time.setString("Time: " + minutesStr + ":" + secondsStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::soundSystem() {}
|
||||||
|
void Game::resetGame() {}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
#include "Game.h"
|
||||||
|
|
||||||
|
int main (int argc, const char** argv)
|
||||||
|
{
|
||||||
|
Game game;
|
||||||
|
game.init();
|
||||||
|
game.run();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
|
||||||
|
sf::Vector2f getOverlap(const sf::FloatRect first, const sf::FloatRect second)
|
||||||
|
{
|
||||||
|
const float deltaX = std::abs(second.position.x - first.position.x);
|
||||||
|
const float deltaY = std::abs(second.position.y - first.position.y);
|
||||||
|
|
||||||
|
const float resultX = (first.size.x + second.size.x) - deltaX;
|
||||||
|
const float resultY = (first.size.y + second.size.y) - deltaY;
|
||||||
|
return {resultX, resultY};
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue