Files
SDLpriklady/main.cpp
Simon Zaris a0710fded3 init
2025-03-20 10:10:14 +01:00

294 lines
9.2 KiB
C++

#include "SDL2/SDL.h"
#include <iostream>
#include <vector>
#include <stdlib.h>
#include <time.h>
typedef struct {
uint8_t a;
uint8_t b;
bool isMinus;
int8_t result;
} Priklad;
Priklad priklad;
typedef struct {
SDL_Rect rekt;
int8_t value;
}Vysledok;
// Constants
const int SCREEN_WIDTH = 1280;
const int SCREEN_HEIGHT = 720;
const int PLAYER_HEIGHT = 20;
const int OBJECT_SIZE = 30;
const int PLAYER_SPEED = 10;
const int SEGMENT_WIDTH = 10;
const int DIGIT_WIDTH = 40;
const int DIGIT_HEIGHT = 60;
const int PLAYER_WIDTH = (DIGIT_WIDTH * 3) / 2;
const int MAX_FALL_SPEED = 8;
const int ORIG_FALL_SPEED = 2;
int FALL_SPEED = ORIG_FALL_SPEED;
const int vyslWidth = DIGIT_WIDTH * 4;
Vysledok vysledky[(SCREEN_WIDTH / vyslWidth)];
int score = 0;
// SDL Variables
SDL_Window* window = nullptr;
SDL_Renderer* renderer = nullptr;
SDL_Rect player, object;
const int numResults = sizeof(vysledky) / sizeof(Vysledok);
void generatePriklad() {
priklad.a = rand() % 10;
priklad.b = rand() % 10;
priklad.isMinus = rand() > (RAND_MAX / 2);
priklad.result = priklad.isMinus ? (priklad.a - priklad.b) : (priklad.a + priklad.b);
}
void generateVysledky() {
generatePriklad();
for (size_t i = 0; i < numResults; i++) {
vysledky[i].rekt.x = i * vyslWidth;
vysledky[i].rekt.y = DIGIT_HEIGHT * 2;
vysledky[i].rekt.w = (DIGIT_WIDTH + 10) * 3;
vysledky[i].rekt.h = DIGIT_HEIGHT;
vysledky[i].value = rand() % 19;
}
// Choose a random index to set to a specific value
size_t randomIndex = rand() % numResults; // Pick a random index
vysledky[randomIndex].value = priklad.result; // Set this specific element to a value (e.g., 42)
}
void stepVysledky() {
for (size_t i = 0; i < sizeof(vysledky) / sizeof(Vysledok); i++) {
vysledky[i].rekt.y += FALL_SPEED;
if (SDL_HasIntersection(&player, &vysledky[i].rekt)) {
if (vysledky[i].value == priklad.result) {
score++;
FALL_SPEED = score / 4 + 2;
} else {
score = 0;
FALL_SPEED = ORIG_FALL_SPEED;
}
if (FALL_SPEED > MAX_FALL_SPEED) {
FALL_SPEED = MAX_FALL_SPEED;
}
if (FALL_SPEED < ORIG_FALL_SPEED) {
FALL_SPEED = ORIG_FALL_SPEED;
}
generateVysledky();
}
if (vysledky[i].rekt.y >= SCREEN_HEIGHT) {
generateVysledky();
break;
}
}
}
// Function to initialize SDL
bool init() {
srand(time(NULL));
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
std::cout << "SDL Initialization Failed: " << SDL_GetError() << std::endl;
return false;
}
window = SDL_CreateWindow("Catch the Falling Object", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if (!window) {
std::cout << "Window Creation Failed: " << SDL_GetError() << std::endl;
return false;
}
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (!renderer) {
std::cout << "Renderer Creation Failed: " << SDL_GetError() << std::endl;
return false;
}
generateVysledky();
return true;
}
// Function to close SDL
void close() {
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
}
// Function to draw a single 7-segment style digit
void drawSegmentedDigit(int digit, int x, int y) {
static const std::vector<std::vector<bool>> segments = {
{1, 1, 1, 0, 1, 1, 1, 0}, // 0
{0, 0, 1, 0, 0, 1, 0, 0}, // 1
{1, 0, 1, 1, 1, 0, 1, 0}, // 2
{1, 0, 1, 1, 0, 1, 1, 0}, // 3
{0, 1, 1, 1, 0, 1, 0, 0}, // 4
{1, 1, 0, 1, 0, 1, 1, 0}, // 5
{1, 1, 0, 1, 1, 1, 1, 0}, // 6
{1, 0, 1, 0, 0, 1, 0, 0}, // 7
{1, 1, 1, 1, 1, 1, 1, 0}, // 8
{1, 1, 1, 1, 0, 1, 1, 0}, // 9
{0, 0, 0, 1, 0, 0, 0, 0}, //plus
{0, 0, 0, 1, 0, 0, 1, 0}, //equals
{0, 0, 0, 1, 0, 0, 0, 1}, //minus
};
SDL_SetRenderDrawColor(renderer, 255, 255, 0, 255);
SDL_Rect seg[8] = {
{x + SEGMENT_WIDTH, y, DIGIT_WIDTH - 2 * SEGMENT_WIDTH, SEGMENT_WIDTH}, // Top
{x, y + SEGMENT_WIDTH, SEGMENT_WIDTH, DIGIT_HEIGHT / 2 - SEGMENT_WIDTH}, // Top-left
{x + DIGIT_WIDTH - SEGMENT_WIDTH, y + SEGMENT_WIDTH, SEGMENT_WIDTH, DIGIT_HEIGHT / 2 - SEGMENT_WIDTH}, // Top-right
{x + SEGMENT_WIDTH, y + DIGIT_HEIGHT / 2 - SEGMENT_WIDTH / 2, DIGIT_WIDTH - 2 * SEGMENT_WIDTH, SEGMENT_WIDTH}, // Middle
{x, y + DIGIT_HEIGHT / 2, SEGMENT_WIDTH, DIGIT_HEIGHT / 2 - SEGMENT_WIDTH}, // Bottom-left
{x + DIGIT_WIDTH - SEGMENT_WIDTH, y + DIGIT_HEIGHT / 2, SEGMENT_WIDTH, DIGIT_HEIGHT / 2 - SEGMENT_WIDTH}, // Bottom-right
{x + SEGMENT_WIDTH, y + DIGIT_HEIGHT - SEGMENT_WIDTH, DIGIT_WIDTH - 2 * SEGMENT_WIDTH, SEGMENT_WIDTH}, // Bottom
{x + DIGIT_WIDTH / 2 - SEGMENT_WIDTH / 2, y + DIGIT_HEIGHT / 2 - DIGIT_HEIGHT / 4 + (SEGMENT_WIDTH / 2), SEGMENT_WIDTH, SEGMENT_WIDTH * 2}, // Bottom-right
};
for (int i = 0; i < 8; i++) {
if (segments[digit][i]) {
SDL_RenderFillRect(renderer, &seg[i]);
}
}
}
void drawVysledok(Vysledok vysledok) {
char scoreStr[4]; // Array to store the digits and sign (+ or -)
size_t index = 0;
// Handle the sign (+ or -)
if (vysledok.value >= 0) {
scoreStr[index++] = '+'; // Add '+' for positive numbers or zero
} else {
scoreStr[index++] = '-'; // Add '-' for negative numbers
vysledok.value = -vysledok.value; // Make the value positive for easier processing
}
// Handle the digits (1 or 2 digit numbers)
if (vysledok.value < 10) {
scoreStr[index++] = '0' + vysledok.value; // Single digit number
} else {
scoreStr[index++] = '0' + (vysledok.value / 10); // Tens digit
scoreStr[index++] = '0' + (vysledok.value % 10); // Ones digit
}
// Add null terminator to the string
scoreStr[index] = '\0';
// Draw the segments
for (size_t i = 0; i < index; i++) {
// Handle '-' and '+' signs as special cases
if (scoreStr[i] == '-') {
scoreStr[i] = 10; // ASCII value for '-' is converted to 10 for rendering
} else if (scoreStr[i] == '+') {
scoreStr[i] = 12; // ASCII value for '+' is converted to 11 for rendering
} else {
scoreStr[i] -= '0'; // Convert from ASCII char to integer
}
// Draw the digit
drawSegmentedDigit(scoreStr[i], vysledok.rekt.x + i * (DIGIT_WIDTH + 10), vysledok.rekt.y);
}
}
// Function to draw score
void drawScore(int score, int x, int y) {
std::string scoreStr = std::to_string(score);
for (size_t i = 0; i < scoreStr.size(); i++) {
drawSegmentedDigit(scoreStr[i] - '0', x + i * (DIGIT_WIDTH + 10), y);
}
}
// Render priklad
void drawPriklad(int x, int y) {
uint8_t i = 0;
drawSegmentedDigit(priklad.a, x + i++ * (DIGIT_WIDTH), y);
drawSegmentedDigit(priklad.isMinus ? 10 : 12, x + i++ * (DIGIT_WIDTH), y);
drawSegmentedDigit(priklad.b, x + i++ * (DIGIT_WIDTH), y);
drawSegmentedDigit(11, x + i++ * (DIGIT_WIDTH), y);
}
int main(int argv, char** args) {
if (!init()) return -1;
// Initialize player & object
player = {SCREEN_WIDTH / 2 - PLAYER_WIDTH / 2, SCREEN_HEIGHT - 50, PLAYER_WIDTH, PLAYER_HEIGHT};
bool running = true;
SDL_Event e;
while (running) {
// Event Handling
while (SDL_PollEvent(&e) != 0) {
if (e.type == SDL_QUIT) running = false;
}
// Player Movement
//const Uint8* keystate = SDL_GetKeyboardState(NULL);
//if (keystate[SDL_SCANCODE_LEFT] && player.x > 0) player.x -= PLAYER_SPEED;
//if (keystate[SDL_SCANCODE_RIGHT] && player.x < SCREEN_WIDTH - PLAYER_WIDTH) player.x += PLAYER_SPEED;
SDL_GetMouseState(&player.x, NULL);
player.x -= PLAYER_WIDTH / 2;
if (player.x < 0) {
player.x = 0;
}
else if (player.x > SCREEN_WIDTH - PLAYER_WIDTH) {
player.x = SCREEN_WIDTH - PLAYER_WIDTH;
}
stepVysledky();
// Collision Check
if (object.y + OBJECT_SIZE >= player.y && object.x + OBJECT_SIZE >= player.x && object.x <= player.x + PLAYER_WIDTH) {
score++;
std::cout << "Score: " << score << std::endl;
}
// Render
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
// Draw Score
drawScore(score, 20, 20);
drawPriklad(200, 20);
// Draw Player
SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
SDL_RenderFillRect(renderer, &player);
//printf("%d %d\n", object.x, object.y);
// Draw Falling Object
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
SDL_RenderFillRect(renderer, &object);
SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
for (int i = 0; i< sizeof(vysledky)/sizeof(Vysledok); i++) {
SDL_SetRenderDrawColor(renderer, 20, 20, 20, 255);
SDL_RenderFillRect(renderer, &vysledky[i].rekt);
drawVysledok(vysledky[i]);
}
SDL_RenderPresent(renderer);
SDL_Delay(16);
}
close();
return 0;
}