Laboratorium 5 done
This commit is contained in:
parent
9af453e459
commit
aec76c7378
@ -154,11 +154,12 @@
|
|||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="KCircle.cpp" />
|
||||||
<ClCompile Include="KGame.cpp" />
|
<ClCompile Include="KGame.cpp" />
|
||||||
<ClCompile Include="KInput.cpp" />
|
<ClCompile Include="KInput.cpp" />
|
||||||
<ClCompile Include="KTexture.cpp" />
|
<ClCompile Include="KTexture.cpp" />
|
||||||
<ClCompile Include="KTile.cpp" />
|
|
||||||
<ClCompile Include="Main.cpp" />
|
<ClCompile Include="Main.cpp" />
|
||||||
|
<ClCompile Include="Utils.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="vcpkg.json" />
|
<None Include="vcpkg.json" />
|
||||||
@ -166,10 +167,10 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Constants.h" />
|
<ClInclude Include="Constants.h" />
|
||||||
<ClInclude Include="GamePad.h" />
|
<ClInclude Include="GamePad.h" />
|
||||||
|
<ClInclude Include="KCircle.h" />
|
||||||
<ClInclude Include="KGame.h" />
|
<ClInclude Include="KGame.h" />
|
||||||
<ClInclude Include="KInput.h" />
|
<ClInclude Include="KInput.h" />
|
||||||
<ClInclude Include="KTexture.h" />
|
<ClInclude Include="KTexture.h" />
|
||||||
<ClInclude Include="KTile.h" />
|
|
||||||
<ClInclude Include="Utils.h" />
|
<ClInclude Include="Utils.h" />
|
||||||
<ClInclude Include="KVector2d.h" />
|
<ClInclude Include="KVector2d.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -18,9 +18,6 @@
|
|||||||
<ClCompile Include="Main.cpp">
|
<ClCompile Include="Main.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="KTile.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="KTexture.cpp">
|
<ClCompile Include="KTexture.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -30,6 +27,12 @@
|
|||||||
<ClCompile Include="KInput.cpp">
|
<ClCompile Include="KInput.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="KCircle.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Utils.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="vcpkg.json" />
|
<None Include="vcpkg.json" />
|
||||||
@ -44,9 +47,6 @@
|
|||||||
<ClInclude Include="KVector2d.h">
|
<ClInclude Include="KVector2d.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="KTile.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="KTexture.h">
|
<ClInclude Include="KTexture.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@ -59,5 +59,8 @@
|
|||||||
<ClInclude Include="KInput.h">
|
<ClInclude Include="KInput.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="KCircle.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
namespace KapitanGame {
|
namespace KapitanGame {
|
||||||
namespace Constants {
|
namespace Constants {
|
||||||
constexpr const char* WINDOW_TITLE = "2DGK - Zadanie 5";
|
constexpr const char* WINDOW_TITLE = "2DGK - Zadanie 7-8";
|
||||||
//Analog joystick dead zone
|
//Analog joystick dead zone
|
||||||
constexpr int JOYSTICK_DEAD_ZONE = 8000;
|
constexpr int JOYSTICK_DEAD_ZONE = 8000;
|
||||||
//Screen dimension constants
|
//Screen dimension constants
|
||||||
@ -13,5 +13,6 @@ namespace KapitanGame {
|
|||||||
constexpr int TILE_HEIGHT = 32;
|
constexpr int TILE_HEIGHT = 32;
|
||||||
constexpr float SPEED = 0.16f;
|
constexpr float SPEED = 0.16f;
|
||||||
constexpr float SMOOTH = 0.4f;
|
constexpr float SMOOTH = 0.4f;
|
||||||
|
constexpr int CIRCLES_COUNT = 100;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
78
2dgk_6/2dgk_6/KCircle.cpp
Normal file
78
2dgk_6/2dgk_6/KCircle.cpp
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
#include "KCircle.h"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Constants.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
|
namespace KapitanGame {
|
||||||
|
std::atomic<int> KCircle::IdCounter{ 0 };
|
||||||
|
|
||||||
|
KCircle::KCircle(const KVector2D& position, const KVector2D& velocity, const float& radius, const KTexture& texture) : Id(++IdCounter),
|
||||||
|
Position(position),
|
||||||
|
Velocity(velocity),
|
||||||
|
Radius(radius),
|
||||||
|
Texture(texture) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void KCircle::CollisionDetectionStep(const std::vector<KCircle>& circles, const bool& shouldSeparate, const bool& shouldReflect) {
|
||||||
|
for (auto& other : circles) {
|
||||||
|
if (other.Id == Id) continue;
|
||||||
|
if (IsCollision(other)) {
|
||||||
|
auto separationVector = GetSeparationVector(other);
|
||||||
|
if (shouldSeparate)
|
||||||
|
Position += separationVector;
|
||||||
|
if (shouldReflect)
|
||||||
|
{
|
||||||
|
separationVector.Normalize();
|
||||||
|
Velocity = Velocity.Reflect(separationVector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KCircle::MovementStep(const float& timeStep) {
|
||||||
|
//Velocity.Normalize();
|
||||||
|
//Velocity *= 100;
|
||||||
|
Position += Velocity * timeStep;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KCircle::IsCollision(const KCircle& other) const {
|
||||||
|
return (Position - other.Position).Length() < Radius + other.Radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
KVector2D KCircle::GetSeparationVector(const KCircle& other) const {
|
||||||
|
const KVector2D centerDiff = Position - other.Position;
|
||||||
|
const float centerDiffLength = centerDiff.Length();
|
||||||
|
return centerDiff / centerDiffLength * (Radius + other.Radius - centerDiffLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KCircle::Render(SDL_Renderer* renderer) const {
|
||||||
|
Texture.Render(renderer, static_cast<int>(Position.X) - Texture.GetWidth() / 2, static_cast<int>(Position.Y) - Texture.GetHeight() / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KCircle::CollisionDetectionWithMapStep(const SDL_Rect& map) {
|
||||||
|
|
||||||
|
if (Position.X - map.x - Radius < 0)
|
||||||
|
{
|
||||||
|
Position.X += -(Position.X - map.x - Radius);
|
||||||
|
Velocity = Velocity.Reflect({ -1.f, 0.f });
|
||||||
|
}
|
||||||
|
if (Position.X + Radius - map.w > 0)
|
||||||
|
{
|
||||||
|
Velocity = Velocity.Reflect({ 1.f, 0.f });
|
||||||
|
Position.X += -(Position.X - map.w + Radius);
|
||||||
|
}
|
||||||
|
if (Position.Y - Radius - map.y < 0) {
|
||||||
|
Position.Y += -(Position.Y - map.y - Radius);
|
||||||
|
Velocity = Velocity.Reflect({ 0.f, 1.f });
|
||||||
|
}
|
||||||
|
if (Position.Y + Radius - map.h > 0) {
|
||||||
|
Position.Y += -(Position.Y - map.h + Radius);
|
||||||
|
Velocity = Velocity.Reflect({ 0.f, -1.f });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
31
2dgk_6/2dgk_6/KCircle.h
Normal file
31
2dgk_6/2dgk_6/KCircle.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <atomic>
|
||||||
|
#include <SDL_render.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "KTexture.h"
|
||||||
|
#include "KVector2d.h"
|
||||||
|
|
||||||
|
namespace KapitanGame {
|
||||||
|
class KCircle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
KCircle(const KVector2D& position, const KVector2D& velocity, const float& radius, const KTexture& texture);
|
||||||
|
|
||||||
|
void CollisionDetectionStep(const std::vector<KCircle>& circles, const bool& shouldSeparate, const bool& shouldReflect);
|
||||||
|
void MovementStep(const float& timeStep);
|
||||||
|
bool IsCollision(const KCircle& other) const;
|
||||||
|
KVector2D GetSeparationVector(const KCircle& other) const;
|
||||||
|
void Render(SDL_Renderer* renderer) const;
|
||||||
|
void CollisionDetectionWithMapStep(const SDL_Rect& map);
|
||||||
|
const int Id;
|
||||||
|
static std::atomic<int> IdCounter;
|
||||||
|
private:
|
||||||
|
KVector2D Position{ 0.f, 0.f };
|
||||||
|
KVector2D Velocity{ 0.f, 0.f };
|
||||||
|
float Radius{ 1.f };
|
||||||
|
const KTexture& Texture;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
|||||||
#include "KVector2d.h"
|
#include "KVector2d.h"
|
||||||
|
|
||||||
namespace KapitanGame {
|
namespace KapitanGame {
|
||||||
KGame::KGame() {
|
KGame::KGame() : HasSeparation(true), HasCollision(true) {
|
||||||
//Initialize SDL
|
//Initialize SDL
|
||||||
if (SDL_Init(SDL_INIT_VIDEO) < 0)
|
if (SDL_Init(SDL_INIT_VIDEO) < 0)
|
||||||
{
|
{
|
||||||
@ -45,11 +45,8 @@ namespace KapitanGame {
|
|||||||
|
|
||||||
KGame::~KGame() {
|
KGame::~KGame() {
|
||||||
//Free loaded images
|
//Free loaded images
|
||||||
for (int i = 0; i <= static_cast<int>(TileType::Dot); ++i)
|
|
||||||
TileTextures[i].Free();
|
|
||||||
|
|
||||||
PlayerTexture.Free();
|
CircleTexture.Free();
|
||||||
PlayerTexture2.Free();
|
|
||||||
|
|
||||||
Input.Free();
|
Input.Free();
|
||||||
|
|
||||||
@ -68,64 +65,11 @@ namespace KapitanGame {
|
|||||||
//Loading success flag
|
//Loading success flag
|
||||||
bool success = true;
|
bool success = true;
|
||||||
|
|
||||||
if (!PlayerTexture.LoadFromFile("textures/player.bmp", Renderer))
|
if (!CircleTexture.LoadFromFile("textures/00.bmp", Renderer))
|
||||||
{
|
{
|
||||||
printf("Failed to load player texture image!\n");
|
printf("Failed to load player texture image!\n");
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
if (!PlayerTexture2.LoadFromFile("textures/player2.bmp", Renderer))
|
|
||||||
{
|
|
||||||
printf("Failed to load player texture image!\n");
|
|
||||||
success = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = static_cast<int>(TileType::Default); i <= static_cast<int>(TileType::Dot); ++i)
|
|
||||||
{
|
|
||||||
if (!TileTextures[i].LoadFromFile("textures/0" + std::to_string(i) + ".bmp", Renderer))
|
|
||||||
{
|
|
||||||
printf("Failed to load 0%d texture image!\n", i);
|
|
||||||
success = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Tiles.clear();
|
|
||||||
std::ifstream levelFile;
|
|
||||||
levelFile.open("level.txt");
|
|
||||||
if (levelFile.fail())
|
|
||||||
{
|
|
||||||
printf("Failed to load level.txt!\n");
|
|
||||||
success = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int y = 0;
|
|
||||||
std::string line;
|
|
||||||
while (std::getline(levelFile, line)) {
|
|
||||||
if (MapWidth < static_cast<int>(line.length() * Constants::TILE_WIDTH))
|
|
||||||
MapWidth = static_cast<int>(line.length()) * Constants::TILE_WIDTH;
|
|
||||||
for (auto i = 0ull; i < line.length(); ++i) {
|
|
||||||
auto type = TileType::Default;
|
|
||||||
switch (line[i])
|
|
||||||
{
|
|
||||||
case '|':
|
|
||||||
type = TileType::VerticalWall;
|
|
||||||
break;
|
|
||||||
case '-':
|
|
||||||
type = TileType::HorizontalWall;
|
|
||||||
break;
|
|
||||||
case '.':
|
|
||||||
type = TileType::Dot;
|
|
||||||
break;
|
|
||||||
default:;
|
|
||||||
}
|
|
||||||
Tiles.emplace_back(i * Constants::TILE_WIDTH, y * Constants::TILE_HEIGHT, type);
|
|
||||||
}
|
|
||||||
++y;
|
|
||||||
}
|
|
||||||
MapHeight = y * Constants::TILE_HEIGHT;
|
|
||||||
levelFile.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,51 +114,21 @@ namespace KapitanGame {
|
|||||||
//Event handler
|
//Event handler
|
||||||
SDL_Event e;
|
SDL_Event e;
|
||||||
|
|
||||||
SDL_Rect viewport;
|
SDL_Rect map{ 0,0,Constants::SCREEN_WIDTH, Constants::SCREEN_HEIGHT };
|
||||||
viewport.x = Constants::SCREEN_WIDTH / 2;
|
|
||||||
viewport.y = Constants::SCREEN_HEIGHT / 2;
|
|
||||||
viewport.w = Constants::SCREEN_WIDTH;
|
|
||||||
viewport.h = Constants::SCREEN_HEIGHT;
|
|
||||||
|
|
||||||
KVector2D playerOnePosition(0, 0);
|
for (int i = 0; i < Constants::CIRCLES_COUNT; ++i) {
|
||||||
KVector2D playerOneInput(0, 0);
|
KVector2D position(Utils::RandomNumber() * (Constants::SCREEN_WIDTH - 2 * CircleTexture.GetWidth()) + CircleTexture.GetWidth(), Utils::RandomNumber() * (Constants::SCREEN_HEIGHT - 2 * CircleTexture.GetHeight()) + CircleTexture.GetHeight());
|
||||||
KVector2D playerOneVelocity(0, 0);
|
Circles.emplace_back(position, KVector2D(100.f, 100.f), CircleTexture.GetWidth() / 2, CircleTexture);
|
||||||
|
}
|
||||||
KVector2D playerTwoPosition(0, 0);
|
uint32_t previousTime;
|
||||||
KVector2D playerTwoInput(0, 0);
|
uint32_t time = previousTime = SDL_GetTicks();
|
||||||
KVector2D playerTwoVelocity(0, 0);
|
|
||||||
|
|
||||||
SDL_Rect playerAreaModeGauntlet;
|
|
||||||
playerAreaModeGauntlet.x = 0;
|
|
||||||
playerAreaModeGauntlet.y = 0;
|
|
||||||
playerAreaModeGauntlet.w = Constants::SCREEN_WIDTH - Constants::WINDOW_DEAD_ZONE;
|
|
||||||
playerAreaModeGauntlet.h = Constants::SCREEN_HEIGHT - Constants::WINDOW_DEAD_ZONE;
|
|
||||||
|
|
||||||
|
|
||||||
SDL_Rect playerAreaModeZoom;
|
|
||||||
playerAreaModeZoom.x = 0;
|
|
||||||
playerAreaModeZoom.y = 0;
|
|
||||||
playerAreaModeZoom.w = (MapWidth <= MapHeight ? MapWidth : static_cast<int>(static_cast<float>(MapHeight) * Constants::SCREEN_RATIO)) - Constants::WINDOW_DEAD_ZONE;
|
|
||||||
playerAreaModeZoom.h = (MapHeight <= MapWidth ? MapHeight : static_cast<int>(static_cast<float>(MapWidth) / Constants::SCREEN_RATIO)) - Constants::WINDOW_DEAD_ZONE;
|
|
||||||
|
|
||||||
float scale = 1.f;
|
|
||||||
|
|
||||||
//Normalized direction
|
|
||||||
int xDir = 0;
|
|
||||||
int yDir = 0;
|
|
||||||
|
|
||||||
uint32_t time, previousTime;
|
|
||||||
time = previousTime = SDL_GetTicks();
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
bool zoom = false;
|
|
||||||
|
|
||||||
//While application is running
|
//While application is running
|
||||||
while (!quit)
|
while (!quit)
|
||||||
{
|
{
|
||||||
previousTime = time;
|
previousTime = time;
|
||||||
time = SDL_GetTicks();
|
time = SDL_GetTicks();
|
||||||
playerOneInput.X = 0;
|
|
||||||
playerOneInput.Y = 0;
|
|
||||||
|
|
||||||
Input.HandleInputPreEvents();
|
Input.HandleInputPreEvents();
|
||||||
|
|
||||||
@ -231,123 +145,31 @@ namespace KapitanGame {
|
|||||||
}
|
}
|
||||||
Input.HandleInputPostEvents();
|
Input.HandleInputPostEvents();
|
||||||
|
|
||||||
playerTwoInput.X = Input.GetControllerAxis(Controllers::Controller1, SDL_CONTROLLER_AXIS_LEFTX);
|
if (Input.IsKeyboardButtonPressed(SDL_SCANCODE_S) || Input.IsControllerButtonPressed(Controllers::Controller1, SDL_CONTROLLER_BUTTON_START))
|
||||||
playerTwoInput.Y = Input.GetControllerAxis(Controllers::Controller1, SDL_CONTROLLER_AXIS_LEFTY);
|
|
||||||
|
|
||||||
if (Input.IsKeyboardButtonHeld(SDL_SCANCODE_W))
|
|
||||||
{
|
{
|
||||||
playerOneInput.Y = -1;
|
HasSeparation = !HasSeparation;
|
||||||
}
|
}
|
||||||
if (Input.IsKeyboardButtonHeld(SDL_SCANCODE_S))
|
if (Input.IsKeyboardButtonPressed(SDL_SCANCODE_C) || Input.IsControllerButtonPressed(Controllers::Controller1, SDL_CONTROLLER_BUTTON_BACK))
|
||||||
{
|
{
|
||||||
playerOneInput.Y = 1;
|
HasCollision = !HasCollision;
|
||||||
}
|
|
||||||
if (Input.IsKeyboardButtonHeld(SDL_SCANCODE_A))
|
|
||||||
{
|
|
||||||
playerOneInput.X = -1;
|
|
||||||
}
|
|
||||||
if (Input.IsKeyboardButtonHeld(SDL_SCANCODE_D))
|
|
||||||
{
|
|
||||||
playerOneInput.X = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
playerOneInput.Normalize();
|
|
||||||
playerOneVelocity = playerOneInput * Constants::SPEED * (1 - Constants::SMOOTH) + playerOneVelocity * Constants::SMOOTH;
|
|
||||||
|
|
||||||
playerOnePosition += playerOneVelocity;
|
for (auto& circle : Circles)
|
||||||
|
circle.CollisionDetectionStep(Circles, HasSeparation, HasCollision);
|
||||||
|
|
||||||
if (Input.IsKeyboardButtonPressed(SDL_SCANCODE_F))
|
for (auto& circle : Circles)
|
||||||
{
|
circle.CollisionDetectionWithMapStep(map);
|
||||||
zoom = !zoom;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto& playerArea = zoom ? playerAreaModeZoom : playerAreaModeGauntlet;
|
|
||||||
|
|
||||||
|
|
||||||
// keep player one near player two
|
|
||||||
if (playerOnePosition.X < playerTwoPosition.X - playerArea.w) playerOnePosition.X = playerTwoPosition.X - playerArea.w;
|
|
||||||
if (playerOnePosition.X > playerTwoPosition.X + playerArea.w) playerOnePosition.X = playerTwoPosition.X + playerArea.w;
|
|
||||||
if (playerOnePosition.Y < playerTwoPosition.Y - playerArea.h) playerOnePosition.Y = playerTwoPosition.Y - playerArea.h;
|
|
||||||
if (playerOnePosition.Y > playerTwoPosition.Y + playerArea.h) playerOnePosition.Y = playerTwoPosition.Y + playerArea.h;
|
|
||||||
|
|
||||||
// keep player one in map
|
|
||||||
if (playerOnePosition.X < 0) playerOnePosition.X = 0;
|
|
||||||
if (playerOnePosition.X > MapWidth - PlayerTexture.GetWidth()) playerOnePosition.X = (MapWidth - PlayerTexture.GetWidth());
|
|
||||||
if (playerOnePosition.Y < 0) playerOnePosition.Y = (0);
|
|
||||||
if (playerOnePosition.Y > MapHeight - PlayerTexture.GetHeight()) playerOnePosition.Y = (MapHeight - PlayerTexture.GetHeight());
|
|
||||||
|
|
||||||
//playerTwoInput.Normalize();
|
|
||||||
//printf("\r \rX:%f, Y:%f", playerTwoInput.x, playerTwoInput.y);
|
|
||||||
playerTwoVelocity = playerTwoInput * Constants::SPEED * (1 - Constants::SMOOTH) + playerTwoVelocity * Constants::SMOOTH;
|
|
||||||
|
|
||||||
playerTwoPosition += playerTwoVelocity;
|
|
||||||
|
|
||||||
|
|
||||||
if (playerTwoPosition.X < playerOnePosition.X - static_cast<float>(playerArea.w)) playerTwoPosition.X = playerOnePosition.X - playerArea.w;
|
|
||||||
if (playerTwoPosition.X > playerOnePosition.X + playerArea.w) playerTwoPosition.X = playerOnePosition.X + playerArea.w;
|
|
||||||
if (playerTwoPosition.Y < playerOnePosition.Y - playerArea.h) playerTwoPosition.Y = playerOnePosition.Y - playerArea.h;
|
|
||||||
if (playerTwoPosition.Y > playerOnePosition.Y + playerArea.h) playerTwoPosition.Y = playerOnePosition.Y + playerArea.h;
|
|
||||||
|
|
||||||
if (playerTwoPosition.X < 0) playerTwoPosition.X = 0;
|
|
||||||
if (playerTwoPosition.X > MapWidth - PlayerTexture.GetWidth()) playerTwoPosition.X = MapWidth - PlayerTexture.GetWidth();
|
|
||||||
if (playerTwoPosition.Y < 0) playerTwoPosition.Y = 0;
|
|
||||||
if (playerTwoPosition.Y > MapHeight - PlayerTexture.GetHeight()) playerTwoPosition.Y = MapHeight - PlayerTexture.GetHeight();
|
|
||||||
|
|
||||||
|
|
||||||
scale = 1.f;
|
|
||||||
if (zoom)
|
|
||||||
{
|
|
||||||
float xDist = std::abs(playerTwoPosition.X - playerOnePosition.X) - playerAreaModeGauntlet.w;
|
|
||||||
float yDist = std::abs(playerTwoPosition.Y - playerOnePosition.Y) - playerAreaModeGauntlet.h;
|
|
||||||
float xMaxDist = playerAreaModeZoom.w - playerAreaModeGauntlet.w;
|
|
||||||
float yMaxDist = playerAreaModeZoom.h - playerAreaModeGauntlet.h;
|
|
||||||
float t1 = Utils::Clamp(xDist / xMaxDist);
|
|
||||||
float t2 = Utils::Clamp(yDist / yMaxDist);
|
|
||||||
float t = std::max(std::max(t1, 0.f), std::max(t2, 0.f));
|
|
||||||
scale = Utils::Lerp(scale, std::max(Constants::SCREEN_WIDTH * 1.0f / MapWidth, Constants::SCREEN_HEIGHT * 1.0f / MapHeight), t);
|
|
||||||
//printf("\rscale: %f, t1: %f, t2: %f, t: %f", scale, t1, t2, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
KVector2D focusPoint = (playerOnePosition + playerTwoPosition + KVector2D(PlayerTexture.GetWidth(), PlayerTexture.GetHeight())+KVector2D(Constants::WINDOW_DEAD_ZONE, Constants::WINDOW_DEAD_ZONE)/2)*scale/2;
|
|
||||||
if (Input.IsKeyboardButtonHeld(SDL_SCANCODE_Q))
|
|
||||||
{
|
|
||||||
focusPoint = KVector2D(MapWidth / 2.f, MapHeight / 2.f);
|
|
||||||
}
|
|
||||||
|
|
||||||
//viewport.x += clamp((time - previous_time) * .05f) * (focusPoint.x - SCREEN_WIDTH / 2 - viewport.x);
|
|
||||||
viewport.x = Utils::Lerp(viewport.x, static_cast<int>(focusPoint.X - Constants::SCREEN_WIDTH / 2.f), static_cast<float>(time - previousTime) * .05f);
|
|
||||||
if ((focusPoint.X - Constants::SCREEN_WIDTH / 2.f) - static_cast<float>(viewport.x) <= 0.005f)
|
|
||||||
{
|
|
||||||
viewport.x = static_cast<int>(focusPoint.X - Constants::SCREEN_WIDTH / 2.f)/scale;
|
|
||||||
}
|
|
||||||
viewport.y = Utils::Lerp(viewport.y, static_cast<int>(focusPoint.Y - Constants::SCREEN_HEIGHT / 2.f), static_cast<float>(time - previousTime) * .05f);
|
|
||||||
if (focusPoint.Y - static_cast<float>(Constants::SCREEN_HEIGHT) / 2.0f - static_cast<float>(viewport.y) <= 0.005f)
|
|
||||||
{
|
|
||||||
viewport.y = static_cast<int>(focusPoint.Y - Constants::SCREEN_HEIGHT / 2.f) / scale;
|
|
||||||
}
|
|
||||||
if (viewport.x < 0)
|
|
||||||
viewport.x = 0;
|
|
||||||
if (viewport.y < 0)
|
|
||||||
viewport.y = 0;
|
|
||||||
if (viewport.x > MapWidth - static_cast<int>(static_cast<float>(viewport.w) / scale))
|
|
||||||
viewport.x = MapWidth - static_cast<int>(static_cast<float>(viewport.w) / scale);
|
|
||||||
if (viewport.y > MapHeight - static_cast<int>(static_cast<float>(viewport.h) / scale))
|
|
||||||
viewport.y = MapHeight - static_cast<int>(static_cast<float>(viewport.h) / scale);
|
|
||||||
|
|
||||||
//printf("\rp1(%f, %f), p2(%f, %f), viewport:(%d, %d, %d, %d), map(%d, %d), focus(%f, %f)", playerOnePosition.X * scale, playerOnePosition.Y * scale, playerTwoPosition.X * scale, playerTwoPosition.Y * scale, static_cast<int>(viewport.x * scale), static_cast<int>(viewport.y * scale), static_cast<int>(static_cast<float>(viewport.w) / scale), static_cast<int>(static_cast<float>(viewport.h) / scale), MapWidth, MapHeight, focusPoint.X, focusPoint.Y);
|
|
||||||
|
|
||||||
|
for (auto& circle : Circles)
|
||||||
|
circle.MovementStep(static_cast<float>(time - previousTime) / 1000.f);
|
||||||
|
|
||||||
//Clear screen
|
//Clear screen
|
||||||
SDL_SetRenderDrawColor(Renderer, 0, 0xFF, 0, 0xFF);
|
SDL_SetRenderDrawColor(Renderer, 0, 0xFF, 0, 0xFF);
|
||||||
SDL_RenderClear(Renderer);
|
SDL_RenderClear(Renderer);
|
||||||
|
|
||||||
|
for (auto& circle : Circles)
|
||||||
|
circle.Render(Renderer);
|
||||||
for (auto& tile : Tiles)
|
|
||||||
tile.Render(Renderer, TileTextures, viewport, scale);
|
|
||||||
|
|
||||||
PlayerTexture.Render(Renderer, playerOnePosition.X - viewport.x, playerOnePosition.Y - viewport.y, nullptr, scale);
|
|
||||||
PlayerTexture2.Render(Renderer, playerTwoPosition.X - viewport.x, playerTwoPosition.Y - viewport.y, nullptr, scale);
|
|
||||||
|
|
||||||
//Update screen
|
//Update screen
|
||||||
SDL_RenderPresent(Renderer);
|
SDL_RenderPresent(Renderer);
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "KTexture.h"
|
#include "KTexture.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <SDL_joystick.h>
|
#include <SDL_render.h>
|
||||||
|
|
||||||
|
#include "KCircle.h"
|
||||||
#include "KInput.h"
|
#include "KInput.h"
|
||||||
|
|
||||||
|
|
||||||
namespace KapitanGame {
|
namespace KapitanGame {
|
||||||
class KTile;
|
|
||||||
|
|
||||||
class KGame
|
class KGame
|
||||||
{
|
{
|
||||||
@ -24,15 +24,13 @@ namespace KapitanGame {
|
|||||||
|
|
||||||
SDL_Renderer* Renderer = nullptr;
|
SDL_Renderer* Renderer = nullptr;
|
||||||
|
|
||||||
KTexture TileTextures[4];
|
KTexture CircleTexture;
|
||||||
KTexture PlayerTexture;
|
|
||||||
KTexture PlayerTexture2;
|
|
||||||
std::vector<KTile> Tiles;
|
|
||||||
|
|
||||||
int MapHeight = -1;
|
std::vector<KCircle> Circles;
|
||||||
int MapWidth = -1;
|
|
||||||
KInput Input;
|
KInput Input;
|
||||||
|
bool HasSeparation;
|
||||||
|
bool HasCollision;
|
||||||
|
private:
|
||||||
bool LoadMedia();
|
bool LoadMedia();
|
||||||
|
|
||||||
SDL_Texture* LoadTexture(const std::string& path) const;
|
SDL_Texture* LoadTexture(const std::string& path) const;
|
||||||
|
@ -9,6 +9,11 @@ namespace KapitanGame {
|
|||||||
KVector2D(const float x, const float y) : X(x), Y(y) {}
|
KVector2D(const float x, const float y) : X(x), Y(y) {}
|
||||||
|
|
||||||
float Length() const { return sqrt(X * X + Y * Y); }
|
float Length() const { return sqrt(X * X + Y * Y); }
|
||||||
|
float Length2() const { return X * X + Y * Y; }
|
||||||
|
|
||||||
|
bool operator==(const KVector2D& v2) const {
|
||||||
|
return (*this - v2).Length2() < FLT_EPSILON * FLT_EPSILON;
|
||||||
|
}
|
||||||
|
|
||||||
KVector2D operator+(const KVector2D& v2) const {
|
KVector2D operator+(const KVector2D& v2) const {
|
||||||
return { X + v2.X, Y + v2.Y };
|
return { X + v2.X, Y + v2.Y };
|
||||||
@ -49,6 +54,12 @@ namespace KapitanGame {
|
|||||||
Y /= scalar;
|
Y /= scalar;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
float DotProduct(const KVector2D& v2) const {
|
||||||
|
return DotProduct(*this, v2);
|
||||||
|
}
|
||||||
|
KVector2D Reflect(const KVector2D& normal) const {
|
||||||
|
return Reflect(normal, *this);
|
||||||
|
}
|
||||||
|
|
||||||
void Normalize() {
|
void Normalize() {
|
||||||
const float l = Length();
|
const float l = Length();
|
||||||
@ -56,6 +67,14 @@ namespace KapitanGame {
|
|||||||
(*this) *= 1 / l;
|
(*this) *= 1 / l;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static KVector2D Reflect(const KVector2D& normal, const KVector2D& vector) {
|
||||||
|
const float dn = 2 * vector.DotProduct(normal);
|
||||||
|
return vector - normal * dn;
|
||||||
|
}
|
||||||
|
static float DotProduct(const KVector2D& v1, const KVector2D& v2) {
|
||||||
|
return v1.X * v2.X + v1.Y * v2.Y ;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
16
2dgk_6/2dgk_6/Utils.cpp
Normal file
16
2dgk_6/2dgk_6/Utils.cpp
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
|
#include <random>
|
||||||
|
|
||||||
|
namespace KapitanGame {
|
||||||
|
namespace Utils {
|
||||||
|
double RandomNumber() {
|
||||||
|
// Making rng static ensures that it stays the same
|
||||||
|
// Between different invocations of the function
|
||||||
|
static std::default_random_engine rng(make_default_random_engine());
|
||||||
|
|
||||||
|
std::uniform_real_distribution<double> dist(0.0, 1.0);
|
||||||
|
return dist(rng);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <random>
|
||||||
namespace KapitanGame {
|
namespace KapitanGame {
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
|
|
||||||
@ -16,15 +17,37 @@ namespace KapitanGame {
|
|||||||
return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside
|
return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside
|
||||||
}
|
}
|
||||||
template <class T>
|
template <class T>
|
||||||
constexpr const T& Clamp(const T& x)
|
constexpr const T& Clamp01(const T& x)
|
||||||
{
|
{
|
||||||
return std::max(std::min(1.f, x), 0.f);
|
return Clamp(x, 0.f, 1.f);
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
constexpr const T& Clamp(const T& x, const T& min, const T& max)
|
||||||
|
{
|
||||||
|
return std::max(std::min(max, x), min);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
constexpr const T& Lerp(const T& a, const T& b, const float& t)
|
constexpr const T& Lerp(const T& a, const T& b, const float& t)
|
||||||
{
|
{
|
||||||
return a + (b - a) * t;
|
return a + (b - a) * t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::default_random_engine make_default_random_engine()
|
||||||
|
{
|
||||||
|
// This gets a source of actual, honest-to-god randomness
|
||||||
|
std::random_device source;
|
||||||
|
|
||||||
|
// Here, we fill an array of random data from the source
|
||||||
|
unsigned int random_data[10];
|
||||||
|
for (auto& elem : random_data) {
|
||||||
|
elem = source();
|
||||||
|
}
|
||||||
|
|
||||||
|
// this creates the random seed sequence out of the random data
|
||||||
|
std::seed_seq seq(random_data + 0, random_data + 10);
|
||||||
|
return std::default_random_engine{ seq };
|
||||||
|
}
|
||||||
|
|
||||||
|
double RandomNumber();
|
||||||
}
|
}
|
||||||
}
|
}
|
BIN
2dgk_6/2dgk_6/textures/00.bmp
(Stored with Git LFS)
BIN
2dgk_6/2dgk_6/textures/00.bmp
(Stored with Git LFS)
Binary file not shown.
BIN
2dgk_6/2dgk_6/textures/01.bmp
(Stored with Git LFS)
BIN
2dgk_6/2dgk_6/textures/01.bmp
(Stored with Git LFS)
Binary file not shown.
BIN
2dgk_6/2dgk_6/textures/02.bmp
(Stored with Git LFS)
BIN
2dgk_6/2dgk_6/textures/02.bmp
(Stored with Git LFS)
Binary file not shown.
BIN
2dgk_6/2dgk_6/textures/03.bmp
(Stored with Git LFS)
BIN
2dgk_6/2dgk_6/textures/03.bmp
(Stored with Git LFS)
Binary file not shown.
BIN
2dgk_6/2dgk_6/textures/player.bmp
(Stored with Git LFS)
BIN
2dgk_6/2dgk_6/textures/player.bmp
(Stored with Git LFS)
Binary file not shown.
BIN
2dgk_6/2dgk_6/textures/player2.bmp
(Stored with Git LFS)
BIN
2dgk_6/2dgk_6/textures/player2.bmp
(Stored with Git LFS)
Binary file not shown.
Loading…
Reference in New Issue
Block a user