223 lines
5.1 KiB
C++

#include <array>
#include <cmath>
#include "App.hpp"
#include <raylib.h>
#include <raymath.h>
#define TOP (1 - pos)
#define BOTTOM pos
Rectangle TextInSpace(Rectangle box, float textH, float textW, float margin, bool topOrBottom)
{
float br = box.width / box.height;
float tr = textW / textH;
Rectangle ret = {0, 0, 0, 0};
float hm = box.height * margin;
float wm = box.width * margin;
ret.height = box.height - hm;
ret.width = box.width - wm;
if (br < tr)
{
// bolj kvadrat izracunaj visino iz sirine
ret.height = ret.width / tr;
}
else
{
// bolj podolgovat izracunaj sirino iz visine
ret.width = ret.height * tr;
}
if (topOrBottom)
{
ret.y = box.y + hm;
}
else
{
ret.y = box.y + box.height - hm - ret.height;
}
ret.x = box.x + wm;
return ret;
}
// Dimentions for font size 20
// DISLIKE 83
// LIKE 46
// GEN 9999: 999/999 -> 200
constexpr float textMargin = 0.02f;
void App::init(int screenWidth, int screenHeight)
{
this->screenWidth = screenWidth;
this->screenHeight = screenHeight;
this->canvas.init(screenWidth);
// int s = MeasureText("GEN 9999: 999/999", 20);
// TraceLog(LOG_INFO, "%d", s);
for (size_t i = 0; i < canvasTexure.size(); i++)
{
canvasTexure[i] = LoadRenderTexture(screenWidth, screenWidth);
}
DnaStore::load(&manager);
upTex(Liked::tbd);
while (!canvas.tick(canvasTexure[TOP]))
{
// wait to finish drawing
}
pos = 1 - pos;
upTex(Liked::tbd);
while (!canvas.tick(canvasTexure[TOP]))
{
// wait to finish drawing
}
pos = 1 - pos;
float posY = (screenHeight - screenWidth) / 2.0f;
likedTextBox = TextInSpace({0,
0,
(float)screenWidth / 2.0f,
posY},
20.0f, 83.0f, textMargin, false);
genTextBox = TextInSpace({0,
posY + screenWidth,
(float)screenWidth,
posY},
20.0f, 200.0f, textMargin, true);
destB = {0, posY, (float)screenWidth, (float)screenWidth};
destA = destB;
float recPosX = screenWidth * 0.3f;
disLikeBox = {0, posY, (float)recPosX, (float)screenWidth};
likeBox = {screenWidth - recPosX, posY, (float)recPosX, (float)screenWidth};
}
void App::upTex(Liked liked)
{
if (liked != Liked::tbd)
{
unit[TOP].liked = liked;
bool ng = DnaManager::like(unit[TOP], &manager);
if (ng)
{
DnaStore::saveGen(&manager);
DnaManager::newGen(&manager);
DnaStore::saveVec(&manager);
}
DnaStore::saveData(&manager);
}
unit[TOP] = DnaManager::next(&manager);
if (unit[TOP].dna != nullptr)
{
canvas.newGen(canvasTexure[TOP], unit[TOP].dna);
return;
}
BeginTextureMode(canvasTexure[TOP]);
ClearBackground(BLACK);
DrawText("NEXT GEN", 10, 10, 20, WHITE);
EndTextureMode();
}
void App::update()
{
bool isDone = canvas.tick(canvasTexure[BOTTOM]);
Vector2 mousePosition = GetMousePosition();
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
{
mouseStart = mousePosition;
validHit = CheckCollisionPointRec(mouseStart, destA);
len = Vector2Distance(mouseStart, {destB.x, destB.y});
ofset = std::atan2(destB.x - mouseStart.x, destB.y - mouseStart.y);
}
if (IsMouseButtonDown(MOUSE_BUTTON_LEFT) && validHit)
{
float dist = mousePosition.x - mouseStart.x;
float l = dist / screenWidth;
rotation = Lerp(45.0f, -45.0f, (l + 1) / 2);
float angle = ((rotation)*PI) / 180.0f;
angle += ofset;
Vector2 newCenter = {.x = len * std::sin(angle), .y = len * std::cos(angle)};
destA.x = newCenter.x + mousePosition.x;
destA.y = newCenter.y + mousePosition.y;
if (CheckCollisionPointRec(mousePosition, disLikeBox))
{
topLiked = Liked::no;
}
else if (CheckCollisionPointRec(mousePosition, likeBox))
{
topLiked = Liked::yes;
}
else
{
topLiked = Liked::tbd;
}
}
if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT) && validHit)
{
if (isDone)
{
if (topLiked != Liked::tbd)
{
upTex(topLiked);
pos = 1 - pos; // switch bottom and top
}
}
rotation = 0.0f;
destA = destB;
topLiked = Liked::tbd;
}
}
void App::draw()
{
ClearBackground(BLUE);
Rectangle source = {0, 0, (float)screenWidth, (float)-screenWidth};
Vector2 origin = {0.0f, 0.0f};
DrawTexturePro(canvasTexure[BOTTOM].texture, source, destB, origin, 0.0f, WHITE);
DrawTexturePro(canvasTexure[TOP].texture, source, destA, origin, 360 - rotation, WHITE);
const char *text = TextFormat("GEN %d: %d / %d", manager.generation, unit[TOP].index + 1, NUM_PER_GEN);
DrawText(text, genTextBox.x, genTextBox.y, genTextBox.height, BLACK);
switch (topLiked)
{
case Liked::yes:
DrawText("LIKED", likedTextBox.x, likedTextBox.y, likedTextBox.height, BLACK);
break;
case Liked::no:
DrawText("DISLIKE", likedTextBox.x, likedTextBox.y, likedTextBox.height, BLACK);
break;
default:
break;
}
}
void App::deinit()
{
for (size_t i = 0; i < canvasTexure.size(); i++)
{
UnloadRenderTexture(canvasTexure[i]);
}
canvas.deinit();
}