815 lines
27 KiB
C
815 lines
27 KiB
C
#include <stdlib.h>
|
|
#include <math.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <time.h>
|
|
#include "game.h"
|
|
#include "world.h"
|
|
|
|
static short farby_riadkov_level1[7] = {
|
|
COLOR_RED, COLOR_MAGENTA, COLOR_YELLOW,
|
|
COLOR_GREEN, COLOR_CYAN, COLOR_BLUE, COLOR_WHITE,
|
|
};
|
|
|
|
static short farby_riadkov_level2[7] = {
|
|
COLOR_CYAN, COLOR_GREEN, COLOR_WHITE,
|
|
COLOR_YELLOW, COLOR_RED, COLOR_MAGENTA, COLOR_BLUE,
|
|
};
|
|
|
|
static short farby_riadkov_level3[7] = {
|
|
COLOR_YELLOW, COLOR_WHITE, COLOR_RED,
|
|
COLOR_CYAN, COLOR_MAGENTA, COLOR_GREEN, COLOR_BLUE,
|
|
};
|
|
|
|
static int von_lav(Hra* h) { (void)h; return 0; }
|
|
static int von_prav(Hra* h) { return h->sirka - 1; }
|
|
static int von_hor(Hra* h) { (void)h; return 0; }
|
|
static int von_dno(Hra* h) { return h->vyska - 2; }
|
|
|
|
static int lavy_okraj(Hra* h) { return h->sirka / 4; }
|
|
static int pravy_okraj(Hra* h) { return h->sirka - h->sirka / 4; }
|
|
static int horny_okraj(Hra* h) { (void)h; return 3; }
|
|
static int dolna_hranica(Hra* h) { return h->palka.y + 1; }
|
|
|
|
static int tehla_zacatek_x(Hra* h) {
|
|
return (h->sirka - MAX_STLPCOV * 3) / 2;
|
|
}
|
|
|
|
static int tehla_zac_y(Hra* h) {
|
|
return horny_okraj(h) + 2;
|
|
}
|
|
|
|
static int palka_default_y(Hra* h) {
|
|
return tehla_zac_y(h) + MAX_RIADKOV + 12;
|
|
}
|
|
|
|
static void inicializuj_boss(Hra* h) {
|
|
h->boss.ziva = 1;
|
|
h->boss.x = (float)(h->sirka / 2);
|
|
h->boss.y = 1.0f;
|
|
h->boss.dx = 0.5f;
|
|
h->boss.pada = 0;
|
|
}
|
|
|
|
void inicializuj_tehly(Hra* h) {
|
|
h->zostatok_tehiel = 0;
|
|
int dlzka = h->meno_dlzka > 0 ? h->meno_dlzka : 4;
|
|
|
|
static const int spirala[7][10] = {
|
|
{1,1,1,1,1,1,1,1,1,1},
|
|
{1,0,0,0,0,0,0,0,0,1},
|
|
{1,0,1,1,1,1,1,1,0,1},
|
|
{1,0,1,0,0,0,0,1,0,0},
|
|
{1,0,1,0,1,1,0,1,0,1},
|
|
{1,0,1,0,1,0,0,1,0,1},
|
|
{1,0,0,0,1,1,1,1,0,1},
|
|
};
|
|
|
|
short* farby;
|
|
switch (h->level) {
|
|
case 2: farby = farby_riadkov_level2; break;
|
|
case 3: farby = farby_riadkov_level3; break;
|
|
default: farby = farby_riadkov_level1; break;
|
|
}
|
|
|
|
for (int r = 0; r < MAX_RIADKOV; r++) {
|
|
for (int s = 0; s < MAX_STLPCOV; s++) {
|
|
if (spirala[r][s]) {
|
|
h->tehly[r][s].ziva = 1;
|
|
h->tehly[r][s].farba = farby[r % 7];
|
|
h->tehly[r][s].znak = h->meno[(r + s) % dlzka];
|
|
h->zostatok_tehiel++;
|
|
} else {
|
|
h->tehly[r][s].ziva = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void nastav_level(Hra* h) {
|
|
switch (h->level) {
|
|
case 1: h->riadkov = 7; h->rychlost = 0.7f; break;
|
|
case 2: h->riadkov = 7; h->rychlost = 0.9f; break;
|
|
case 3: h->riadkov = 7; h->rychlost = 1.1f; break;
|
|
default: h->riadkov = 7; h->rychlost = 0.7f; break;
|
|
}
|
|
}
|
|
|
|
static void pridaj_loptu(Hra* h, float x, float y, float dx, float dy) {
|
|
for (int i = 0; i < MAX_LOPT; i++) {
|
|
if (!h->lopty[i].ziva) {
|
|
h->lopty[i].x = x;
|
|
h->lopty[i].y = y;
|
|
h->lopty[i].dx = dx;
|
|
h->lopty[i].dy = dy;
|
|
h->lopty[i].ziva = 1;
|
|
h->pocet_lopt++;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void inicializuj_lopty(Hra* h) {
|
|
for (int i = 0; i < MAX_LOPT; i++) h->lopty[i].ziva = 0;
|
|
h->pocet_lopt = 0;
|
|
pridaj_loptu(h,
|
|
(float)(h->palka.x + h->palka.sirka / 2),
|
|
(float)(h->palka.y - 1),
|
|
h->rychlost, -h->rychlost);
|
|
}
|
|
|
|
static void vystrel_z_bossa(Hra* h, float bstred, float bposy) {
|
|
float smery[5][2] = {
|
|
{ 0.0f, h->rychlost },
|
|
{-h->rychlost, h->rychlost },
|
|
{ h->rychlost, h->rychlost },
|
|
{-h->rychlost * 0.7f, -h->rychlost * 0.7f },
|
|
{ h->rychlost * 0.7f, -h->rychlost * 0.7f },
|
|
};
|
|
for (int s = 0; s < 5; s++) {
|
|
if (h->pocet_lopt < MAX_LOPT)
|
|
pridaj_loptu(h, bstred, bposy, smery[s][0], smery[s][1]);
|
|
}
|
|
}
|
|
|
|
void pohni_palku(Hra* h, int smer) {
|
|
int novy_x = h->palka.x + smer * 2;
|
|
int lav = lavy_okraj(h);
|
|
int prav = pravy_okraj(h) - h->palka.sirka + 1;
|
|
if (novy_x < lav) novy_x = lav;
|
|
if (novy_x > prav) novy_x = prav;
|
|
h->palka.x = novy_x;
|
|
if (h->stav == STAV_CAKA)
|
|
h->lopty[0].x = (float)(h->palka.x + h->palka.sirka / 2);
|
|
}
|
|
|
|
static void vystrel_special(Hra* h) {
|
|
if (!h->special_dostupny) return;
|
|
if (h->stav != STAV_HRAJE) return;
|
|
h->special_dostupny = 0;
|
|
|
|
float stred = (float)(h->palka.x + h->palka.sirka / 2);
|
|
float y = (float)(h->palka.y - 1);
|
|
|
|
if (h->pocet_lopt < MAX_LOPT)
|
|
pridaj_loptu(h, stred - 1, y, -h->rychlost * 0.5f, -h->rychlost);
|
|
if (h->pocet_lopt < MAX_LOPT)
|
|
pridaj_loptu(h, stred + 1, y, h->rychlost * 0.5f, -h->rychlost);
|
|
}
|
|
|
|
static void uloz_skore(Hra* h) {
|
|
FILE* f = fopen("scores.txt", "a");
|
|
if (!f) return;
|
|
|
|
time_t t = time(NULL);
|
|
struct tm* tm_info = localtime(&t);
|
|
char datum[32];
|
|
strftime(datum, sizeof(datum), "%d.%m.%Y %H:%M:%S", tm_info);
|
|
|
|
int sekundy = h->cas_tikov * RYCHLOST_HRY / 1000;
|
|
int min = sekundy / 60;
|
|
int sek = sekundy % 60;
|
|
|
|
const char* vysledok;
|
|
if (h->stav == STAV_VYHRAL) vysledok = "VYHRAL";
|
|
else if (h->stav == STAV_KONIEC) vysledok = "GAME OVER";
|
|
else vysledok = "KONIEC";
|
|
|
|
fprintf(f, "+-------------------------------------------------+\n");
|
|
fprintf(f, "| Hrac : %-36s|\n", h->meno);
|
|
fprintf(f, "| Skore : %-36d|\n", h->skore);
|
|
fprintf(f, "| Level : %-36d|\n", h->level);
|
|
fprintf(f, "| Cas : %02d:%02d%-32s|\n", min, sek, "");
|
|
fprintf(f, "| Vysledok: %-36s|\n", vysledok);
|
|
fprintf(f, "| Datum : %-36s|\n", datum);
|
|
fprintf(f, "+-------------------------------------------------+\n\n");
|
|
|
|
fclose(f);
|
|
}
|
|
|
|
static void pohni_boss(Hra* h) {
|
|
if (!h->boss.ziva) return;
|
|
|
|
if (h->cas_tikov >= BOSS_CAS && !h->boss.pada) {
|
|
h->boss.pada = 1;
|
|
}
|
|
|
|
if (h->boss.pada) {
|
|
h->boss.y += 0.15f;
|
|
|
|
int tx0 = tehla_zacatek_x(h);
|
|
int ty0 = tehla_zac_y(h);
|
|
int by = (int)h->boss.y;
|
|
int bx = (int)h->boss.x;
|
|
|
|
for (int r = 0; r < MAX_RIADKOV; r++) {
|
|
for (int s = 0; s < MAX_STLPCOV; s++) {
|
|
if (!h->tehly[r][s].ziva) continue;
|
|
int tx = tx0 + s * 3;
|
|
int ty = ty0 + r;
|
|
if (by == ty && bx + 4 >= tx && bx <= tx + 2) {
|
|
h->tehly[r][s].ziva = 0;
|
|
h->zostatok_tehiel--;
|
|
h->skore -= 50;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((int)h->boss.y >= h->palka.y) {
|
|
h->stav = STAV_KONIEC;
|
|
uloz_skore(h);
|
|
return;
|
|
}
|
|
} else {
|
|
h->boss.x += h->boss.dx;
|
|
if (h->boss.x <= (float)lavy_okraj(h)) {
|
|
h->boss.x = (float)lavy_okraj(h);
|
|
h->boss.dx = fabsf(h->boss.dx);
|
|
}
|
|
if (h->boss.x + 4 >= (float)pravy_okraj(h)) {
|
|
h->boss.x = (float)(pravy_okraj(h) - 4);
|
|
h->boss.dx = -fabsf(h->boss.dx);
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < MAX_LOPT; i++) {
|
|
if (!h->lopty[i].ziva) continue;
|
|
int bx = (int)h->boss.x;
|
|
int by = (int)h->boss.y;
|
|
int lx = (int)h->lopty[i].x;
|
|
int ly = (int)h->lopty[i].y;
|
|
if (ly == by && lx >= bx && lx <= bx + 4) {
|
|
h->boss.ziva = 0;
|
|
h->skore += 200;
|
|
h->lopty[i].dy = fabsf(h->lopty[i].dy);
|
|
vystrel_z_bossa(h, h->boss.x + 2.0f, h->boss.y);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void pohni_powerupy(Hra* h) {
|
|
for (int i = 0; i < 2; i++) {
|
|
if (!h->powerupy[i].ziva) continue;
|
|
|
|
h->powerupy[i].y += 0.5f;
|
|
|
|
if ((int)h->powerupy[i].y >= h->palka.y &&
|
|
(int)h->powerupy[i].x >= h->palka.x &&
|
|
(int)h->powerupy[i].x < h->palka.x + h->palka.sirka) {
|
|
h->powerupy[i].ziva = 0;
|
|
|
|
if (i == 0) {
|
|
int idx = h->posledna_lopta;
|
|
if (h->lopty[idx].ziva) {
|
|
if (h->pocet_lopt < MAX_LOPT)
|
|
pridaj_loptu(h, h->lopty[idx].x, h->lopty[idx].y,
|
|
-h->lopty[idx].dx + 0.2f, -fabsf(h->lopty[idx].dy));
|
|
if (h->pocet_lopt < MAX_LOPT)
|
|
pridaj_loptu(h, h->lopty[idx].x, h->lopty[idx].y,
|
|
h->lopty[idx].dx - 0.2f, -fabsf(h->lopty[idx].dy));
|
|
}
|
|
} else {
|
|
h->palka.sirka = PALKA_SIRKA_MAX;
|
|
h->sirka_timer = 300;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if ((int)h->powerupy[i].y >= dolna_hranica(h))
|
|
h->powerupy[i].ziva = 0;
|
|
}
|
|
}
|
|
|
|
static int pohni_jednu_loptu(Hra* h, int idx) {
|
|
Lopta* l = &h->lopty[idx];
|
|
if (!l->ziva) return 0;
|
|
|
|
float nx = l->x + l->dx;
|
|
float ny = l->y + l->dy;
|
|
|
|
int lav = lavy_okraj(h);
|
|
int prav = pravy_okraj(h);
|
|
int hor = horny_okraj(h);
|
|
|
|
if (nx <= lav) { nx = (float)lav; l->dx = fabsf(l->dx); }
|
|
if (nx >= prav) { nx = (float)prav; l->dx = -fabsf(l->dx); }
|
|
if (ny <= hor) { ny = (float)hor; l->dy = fabsf(l->dy); }
|
|
|
|
if (h->boss.ziva) {
|
|
int bx = (int)h->boss.x;
|
|
int by = (int)h->boss.y;
|
|
if ((int)ny == by && (int)nx >= bx && (int)nx <= bx + 4) {
|
|
h->boss.ziva = 0;
|
|
h->skore += 200;
|
|
l->dy = fabsf(l->dy);
|
|
vystrel_z_bossa(h, h->boss.x + 2.0f, h->boss.y);
|
|
}
|
|
}
|
|
|
|
int py = h->palka.y;
|
|
if ((int)ny >= py - 1 && (int)ny <= py) {
|
|
if ((int)nx >= h->palka.x && (int)nx < h->palka.x + h->palka.sirka) {
|
|
float stred = (float)(h->palka.x) + h->palka.sirka / 2.0f;
|
|
float offset = (nx - stred) / (h->palka.sirka / 2.0f);
|
|
l->dx = offset * h->rychlost;
|
|
if (l->dx > h->rychlost) l->dx = h->rychlost;
|
|
if (l->dx < -h->rychlost) l->dx = -h->rychlost;
|
|
if (l->dx == 0.0f) l->dx = 0.3f;
|
|
l->dy = -h->rychlost;
|
|
ny = (float)(py - 1);
|
|
}
|
|
}
|
|
|
|
int tx0 = tehla_zacatek_x(h);
|
|
int ty0 = tehla_zac_y(h);
|
|
|
|
for (int r = 0; r < MAX_RIADKOV && h->zostatok_tehiel > 0; r++) {
|
|
for (int s = 0; s < MAX_STLPCOV; s++) {
|
|
if (!h->tehly[r][s].ziva) continue;
|
|
int tx = tx0 + s * 3;
|
|
int ty = ty0 + r;
|
|
if ((int)ny == ty && (int)nx >= tx && (int)nx < tx + 3) {
|
|
h->tehly[r][s].ziva = 0;
|
|
h->zostatok_tehiel--;
|
|
h->skore += 10 * h->level;
|
|
l->dy = -l->dy;
|
|
|
|
h->posledna_lopta = idx;
|
|
h->hit_counter++;
|
|
|
|
if (h->hit_counter % 3 == 0 && h->hit_counter % 12 != 0 && !h->powerupy[0].ziva) {
|
|
h->powerupy[0].ziva = 1;
|
|
h->powerupy[0].x = nx;
|
|
h->powerupy[0].y = ny;
|
|
h->powerupy[0].znak = '$';
|
|
h->powerupy[0].farba = COLOR_YELLOW;
|
|
}
|
|
|
|
if (h->hit_counter % 12 == 0 && !h->powerupy[1].ziva) {
|
|
h->powerupy[1].ziva = 1;
|
|
h->powerupy[1].x = nx;
|
|
h->powerupy[1].y = ny;
|
|
h->powerupy[1].znak = 'W';
|
|
h->powerupy[1].farba = COLOR_CYAN;
|
|
}
|
|
|
|
if (h->zostatok_tehiel == 0) {
|
|
h->stav = (h->level < 3) ? STAV_DALSI_LEVEL : STAV_VYHRAL;
|
|
if (h->stav == STAV_VYHRAL) uloz_skore(h);
|
|
return 0;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((int)ny >= dolna_hranica(h)) {
|
|
l->ziva = 0;
|
|
h->pocet_lopt--;
|
|
return 1;
|
|
}
|
|
|
|
l->x = nx;
|
|
l->y = ny;
|
|
return 0;
|
|
}
|
|
|
|
void pohni_lopty(Hra* h) {
|
|
if (h->stav != STAV_HRAJE) return;
|
|
|
|
h->cas_tikov++;
|
|
|
|
pohni_boss(h);
|
|
if (h->stav == STAV_KONIEC) return;
|
|
|
|
if (h->sirka_timer > 0) {
|
|
h->sirka_timer--;
|
|
if (h->sirka_timer == 0)
|
|
h->palka.sirka = PALKA_SIRKA_MIN;
|
|
}
|
|
|
|
pohni_powerupy(h);
|
|
|
|
for (int i = 0; i < MAX_LOPT; i++) {
|
|
if (h->lopty[i].ziva) pohni_jednu_loptu(h, i);
|
|
}
|
|
|
|
if (h->pocet_lopt <= 0) {
|
|
h->zivoty--;
|
|
if (h->zivoty <= 0) {
|
|
h->stav = STAV_KONIEC;
|
|
uloz_skore(h);
|
|
} else {
|
|
h->palka.sirka = PALKA_SIRKA_MIN;
|
|
h->stav = STAV_CAKA;
|
|
inicializuj_lopty(h);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void vykresli_uvod(Hra* h) {
|
|
int sx = h->sirka / 2;
|
|
int sy = h->vyska / 2 - 12;
|
|
|
|
static const char* logo[] = {
|
|
" _ ____ _ __ _ _ _ ___ ___ ____",
|
|
" / \\ | _ \\| |/ / / \\ | \\ | |/ _ \\|_ _| _ \\",
|
|
" / _ \\ | |_) | ' / / _ \\ | \\| | | | || | | | |",
|
|
" / ___ \\| _ <| . \\ / ___ \\| |\\ | |_| || | |_| |",
|
|
"/_/ \\_\\_| \\_\\_|\\_\\/_/ \\_\\_| \\_|\\___/|___|____/",
|
|
};
|
|
static const short logo_farby[] = {
|
|
COLOR_RED, COLOR_MAGENTA, COLOR_YELLOW, COLOR_GREEN, COLOR_CYAN,
|
|
};
|
|
|
|
int logo_x = sx - 25;
|
|
if (logo_x < 0) logo_x = 0;
|
|
|
|
for (int r = 0; r < 5; r++) {
|
|
const char* riadok = logo[r];
|
|
int dl = (int)strlen(riadok);
|
|
for (int c = 0; c < dl; c++) {
|
|
if (logo_x + c < h->sirka)
|
|
set_color_cell(riadok[c], logo_x + c, sy + r, logo_farby[r], COLOR_BLACK);
|
|
}
|
|
}
|
|
|
|
int b1y = sy + 6;
|
|
set_message("* . * . * . * . * . *", sx - 16, b1y);
|
|
|
|
int b2y = b1y + 2;
|
|
set_color_cell('[', sx - 14, b2y, COLOR_YELLOW, COLOR_BLACK);
|
|
set_message(" Zadaj meno a stlac ENTER ", sx - 13, b2y);
|
|
set_color_cell(']', sx + 13, b2y, COLOR_YELLOW, COLOR_BLACK);
|
|
|
|
int b3y = b2y + 2;
|
|
char riadok_mena[40];
|
|
snprintf(riadok_mena, sizeof(riadok_mena), "Meno: %s_", h->meno);
|
|
int meno_dl = (int)strlen(riadok_mena);
|
|
int meno_x = sx - meno_dl / 2;
|
|
set_color_cell('>', meno_x - 1, b3y, COLOR_CYAN, COLOR_BLACK);
|
|
set_message(riadok_mena, meno_x, b3y);
|
|
|
|
int b4y = b3y + 2;
|
|
static const short uk_farby[] = {
|
|
COLOR_RED, COLOR_MAGENTA, COLOR_YELLOW,
|
|
COLOR_GREEN, COLOR_CYAN, COLOR_BLUE, COLOR_WHITE
|
|
};
|
|
static const char* uk_znaky[] = {"[R]","[M]","[Y]","[G]","[C]","[B]","[W]"};
|
|
int uk_x = sx - 10;
|
|
for (int i = 0; i < 7; i++) {
|
|
const char* z = uk_znaky[i];
|
|
for (int c = 0; c < 3; c++)
|
|
set_color_cell(z[c], uk_x + i*3 + c, b4y, uk_farby[i], COLOR_BLACK);
|
|
}
|
|
|
|
int lpy = b4y + 2;
|
|
set_color_cell('O', sx - 12, lpy, COLOR_WHITE, COLOR_BLACK);
|
|
set_color_cell('o', sx - 8, lpy, COLOR_WHITE, COLOR_BLACK);
|
|
set_color_cell('.', sx - 5, lpy, COLOR_WHITE, COLOR_BLACK);
|
|
set_color_cell('.', sx + 5, lpy, COLOR_WHITE, COLOR_BLACK);
|
|
set_color_cell('o', sx + 8, lpy, COLOR_WHITE, COLOR_BLACK);
|
|
set_color_cell('O', sx + 12, lpy, COLOR_WHITE, COLOR_BLACK);
|
|
|
|
int pky = lpy + 1;
|
|
set_color_cell('<', sx - 10, pky, COLOR_CYAN, COLOR_BLACK);
|
|
for (int i = -9; i <= 9; i++)
|
|
set_color_cell('=', sx + i, pky, COLOR_CYAN, COLOR_BLACK);
|
|
set_color_cell('>', sx + 10, pky, COLOR_CYAN, COLOR_BLACK);
|
|
|
|
set_message("* . * . * . * . * . *", sx - 16, pky + 2);
|
|
}
|
|
|
|
void vykresli_hru(Hra* h) {
|
|
clear_screen();
|
|
|
|
if (h->stav == STAV_UVOD) {
|
|
vykresli_uvod(h);
|
|
return;
|
|
}
|
|
|
|
if (h->stav == STAV_DALSI_LEVEL) {
|
|
int sx = h->sirka / 2;
|
|
int sy = h->vyska / 2 - 2;
|
|
char msg[40];
|
|
snprintf(msg, sizeof(msg), "*** LEVEL %d DOKONCENY! ***", h->level);
|
|
set_message(msg, sx - 14, sy);
|
|
snprintf(msg, sizeof(msg), " Skore: %d", h->skore);
|
|
set_message(msg, sx - 14, sy + 1);
|
|
set_message(" Stlac MEDZERNIK na dalsi level", sx - 16, sy + 3);
|
|
return;
|
|
}
|
|
|
|
int vl = von_lav(h), vp = von_prav(h), vh = von_hor(h), vd = von_dno(h);
|
|
set_color_cell('+', vl, vh, COLOR_YELLOW, COLOR_BLACK);
|
|
set_color_cell('+', vp, vh, COLOR_YELLOW, COLOR_BLACK);
|
|
set_color_cell('+', vl, vd, COLOR_YELLOW, COLOR_BLACK);
|
|
set_color_cell('+', vp, vd, COLOR_YELLOW, COLOR_BLACK);
|
|
for (int x = vl + 1; x < vp; x++) {
|
|
set_color_cell('=', x, vh, COLOR_YELLOW, COLOR_BLACK);
|
|
set_color_cell('=', x, vd, COLOR_YELLOW, COLOR_BLACK);
|
|
}
|
|
for (int y = vh + 1; y < vd; y++) {
|
|
set_color_cell('|', vl, y, COLOR_YELLOW, COLOR_BLACK);
|
|
set_color_cell('|', vp, y, COLOR_YELLOW, COLOR_BLACK);
|
|
}
|
|
|
|
int il = lavy_okraj(h) - 1;
|
|
int ip = pravy_okraj(h) + 1;
|
|
int ih = horny_okraj(h) - 1;
|
|
int id = h->palka.y + 2;
|
|
set_color_cell('+', il, ih, COLOR_WHITE, COLOR_BLACK);
|
|
set_color_cell('+', ip, ih, COLOR_WHITE, COLOR_BLACK);
|
|
set_color_cell('+', il, id, COLOR_WHITE, COLOR_BLACK);
|
|
set_color_cell('+', ip, id, COLOR_WHITE, COLOR_BLACK);
|
|
for (int x = il + 1; x < ip; x++) {
|
|
set_color_cell('-', x, ih, COLOR_WHITE, COLOR_BLACK);
|
|
set_color_cell('-', x, id, COLOR_WHITE, COLOR_BLACK);
|
|
}
|
|
for (int y = ih + 1; y < id; y++) {
|
|
set_color_cell('|', il, y, COLOR_WHITE, COLOR_BLACK);
|
|
set_color_cell('|', ip, y, COLOR_WHITE, COLOR_BLACK);
|
|
}
|
|
|
|
if (h->boss.ziva) {
|
|
short boss_farba = h->boss.pada ? COLOR_RED : COLOR_MAGENTA;
|
|
int bx = (int)h->boss.x;
|
|
int by = (int)h->boss.y;
|
|
set_color_cell('[', bx, by, COLOR_WHITE, boss_farba);
|
|
set_color_cell('!', bx + 1, by, COLOR_WHITE, boss_farba);
|
|
set_color_cell('!', bx + 2, by, COLOR_WHITE, boss_farba);
|
|
set_color_cell('!', bx + 3, by, COLOR_WHITE, boss_farba);
|
|
set_color_cell(']', bx + 4, by, COLOR_WHITE, boss_farba);
|
|
if (h->boss.pada) {
|
|
int sx = h->sirka / 2;
|
|
set_message("!!! BOSS PADA !!!", sx - 8, vh + 1);
|
|
}
|
|
} else {
|
|
set_message("BOSS ZNICENY! +200", lavy_okraj(h), vh + 1);
|
|
}
|
|
|
|
int tx0 = tehla_zacatek_x(h);
|
|
int ty0 = tehla_zac_y(h);
|
|
for (int r = 0; r < MAX_RIADKOV; r++) {
|
|
for (int s = 0; s < MAX_STLPCOV; s++) {
|
|
if (!h->tehly[r][s].ziva) continue;
|
|
int tx = tx0 + s * 3;
|
|
int ty = ty0 + r;
|
|
short fc = h->tehly[r][s].farba;
|
|
set_color_cell('[', tx, ty, COLOR_WHITE, fc);
|
|
set_color_cell(h->tehly[r][s].znak, tx + 1, ty, COLOR_WHITE, fc);
|
|
set_color_cell(']', tx + 2, ty, COLOR_WHITE, fc);
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < h->palka.sirka; i++)
|
|
set_color_cell('=', h->palka.x + i, h->palka.y, COLOR_CYAN, COLOR_BLACK);
|
|
set_color_cell('<', h->palka.x, h->palka.y, COLOR_CYAN, COLOR_BLACK);
|
|
set_color_cell('>', h->palka.x + h->palka.sirka - 1, h->palka.y, COLOR_CYAN, COLOR_BLACK);
|
|
|
|
for (int i = 0; i < 2; i++) {
|
|
if (h->powerupy[i].ziva)
|
|
set_color_cell(h->powerupy[i].znak,
|
|
(int)h->powerupy[i].x, (int)h->powerupy[i].y,
|
|
h->powerupy[i].farba, COLOR_BLACK);
|
|
}
|
|
|
|
if (h->stav != STAV_KONIEC && h->stav != STAV_VYHRAL) {
|
|
for (int i = 0; i < MAX_LOPT; i++) {
|
|
if (h->lopty[i].ziva)
|
|
set_color_cell('O', (int)h->lopty[i].x, (int)h->lopty[i].y,
|
|
COLOR_WHITE, COLOR_BLACK);
|
|
}
|
|
}
|
|
|
|
char skore_msg[32];
|
|
snprintf(skore_msg, sizeof(skore_msg), "Skore: %d", h->skore);
|
|
set_message(skore_msg, vl + 1, vh + 1);
|
|
|
|
if (h->special_dostupny)
|
|
set_message("[E=SPECIAL]", vl + 1, vh + 2);
|
|
else
|
|
set_message("[E=POUZITY]", vl + 1, vh + 2);
|
|
|
|
if (h->sirka_timer > 0)
|
|
set_message("[WIDE]", vl + 1, vh + 3);
|
|
|
|
int sekundy = h->cas_tikov * RYCHLOST_HRY / 1000;
|
|
int min = sekundy / 60;
|
|
int sek = sekundy % 60;
|
|
char timer[16];
|
|
snprintf(timer, sizeof(timer), "%02d:%02d", min, sek);
|
|
set_message(timer, vp - 5, vh + 1);
|
|
|
|
if (h->boss.ziva && !h->boss.pada) {
|
|
int zostava = (BOSS_CAS - h->cas_tikov) / (1000 / RYCHLOST_HRY);
|
|
if (zostava < 0) zostava = 0;
|
|
char boss_msg[20];
|
|
snprintf(boss_msg, sizeof(boss_msg), "BOSS:%ds", zostava);
|
|
set_message(boss_msg, vp - 8, vh + 2);
|
|
}
|
|
|
|
char hud[120];
|
|
snprintf(hud, sizeof(hud),
|
|
" %s | Level: %d | Zivoty: %d | Lopty: %d | A/D=pohyb E=special Q=koniec",
|
|
h->meno, h->level, h->zivoty, h->pocet_lopt);
|
|
set_message(hud, 0, h->vyska - 1);
|
|
|
|
if (h->stav == STAV_CAKA) {
|
|
int sx = h->sirka / 2;
|
|
int tehly_koniec = tehla_zac_y(h) + MAX_RIADKOV;
|
|
int volny_stred = (tehly_koniec + h->palka.y) / 2;
|
|
set_message("** STLAC MEDZERNIK / KLIKNI **", sx - 15, volny_stred);
|
|
|
|
} else if (h->stav == STAV_KONIEC || h->stav == STAV_VYHRAL) {
|
|
|
|
int lav = lavy_okraj(h);
|
|
int prav = pravy_okraj(h);
|
|
int tehly_koniec = tehla_zac_y(h) + MAX_RIADKOV;
|
|
int volny_stred = (tehly_koniec + h->palka.y) / 2;
|
|
|
|
int sx2 = (lav + prav) / 2;
|
|
int cy = volny_stred - 5;
|
|
if (cy < tehly_koniec + 1) cy = tehly_koniec + 1;
|
|
|
|
for (int x = lav + 1; x < prav; x++)
|
|
set_color_cell('=', x, cy, COLOR_CYAN, COLOR_BLACK);
|
|
|
|
if (h->stav == STAV_VYHRAL) {
|
|
char t[] = "** VYHRAL SI! **";
|
|
set_color_cell('*', sx2 - 8, cy + 1, COLOR_YELLOW, COLOR_BLACK);
|
|
set_color_cell('*', sx2 + 7, cy + 1, COLOR_YELLOW, COLOR_BLACK);
|
|
set_message(t, sx2 - (int)strlen(t) / 2, cy + 1);
|
|
char s[] = "Gratulujeme, hrdina!";
|
|
set_message(s, sx2 - (int)strlen(s) / 2, cy + 2);
|
|
} else {
|
|
char t[] = "** GAME OVER **";
|
|
set_color_cell('X', sx2 - 8, cy + 1, COLOR_RED, COLOR_BLACK);
|
|
set_color_cell('X', sx2 + 7, cy + 1, COLOR_RED, COLOR_BLACK);
|
|
set_message(t, sx2 - (int)strlen(t) / 2, cy + 1);
|
|
char s[] = "Nevzdavaj sa, bojovnik!";
|
|
set_message(s, sx2 - (int)strlen(s) / 2, cy + 2);
|
|
}
|
|
|
|
char riadok[40];
|
|
snprintf(riadok, sizeof(riadok), "Skore: %d Level: %d", h->skore, h->level);
|
|
set_message(riadok, sx2 - (int)strlen(riadok) / 2, cy + 3);
|
|
|
|
for (int x = lav + 1; x < prav; x++)
|
|
set_color_cell('-', x, cy + 4, COLOR_CYAN, COLOR_BLACK);
|
|
|
|
char inf[] = "Skore zapisane do:";
|
|
set_message(inf, sx2 - (int)strlen(inf) / 2, cy + 5);
|
|
|
|
char sub[] = "> scores.txt <";
|
|
set_color_cell('>', sx2 - (int)strlen(sub) / 2, cy + 6, COLOR_YELLOW, COLOR_BLACK);
|
|
set_message(sub, sx2 - (int)strlen(sub) / 2, cy + 6);
|
|
set_color_cell('<', sx2 + (int)strlen(sub) / 2 - 1, cy + 6, COLOR_YELLOW, COLOR_BLACK);
|
|
|
|
char kde[] = "(priecinok hry)";
|
|
set_message(kde, sx2 - (int)strlen(kde) / 2, cy + 7);
|
|
|
|
for (int x = lav + 1; x < prav; x++)
|
|
set_color_cell('=', x, cy + 8, COLOR_CYAN, COLOR_BLACK);
|
|
|
|
char kon[] = "Stlac Q pre ukoncenie";
|
|
set_message(kon, sx2 - (int)strlen(kon) / 2, cy + 9);
|
|
}
|
|
}
|
|
|
|
void* init_game() {
|
|
Hra* h = (Hra*)malloc(sizeof(Hra));
|
|
if (!h) return NULL;
|
|
|
|
h->sirka = 60;
|
|
h->vyska = 30;
|
|
h->zivoty = ZIVOTY;
|
|
h->skore = 0;
|
|
h->level = 1;
|
|
h->stav = STAV_UVOD;
|
|
h->meno[0] = '\0';
|
|
h->meno_dlzka = 0;
|
|
h->hit_counter = 0;
|
|
h->sirka_timer = 0;
|
|
h->posledna_lopta = 0;
|
|
h->cas_tikov = 0;
|
|
h->special_dostupny = 1;
|
|
h->powerupy[0].ziva = 0;
|
|
h->powerupy[1].ziva = 0;
|
|
|
|
nastav_level(h);
|
|
|
|
h->palka.sirka = PALKA_SIRKA_MIN;
|
|
h->palka.y = palka_default_y(h);
|
|
h->palka.x = h->sirka / 2 - PALKA_SIRKA_MIN / 2;
|
|
|
|
inicializuj_boss(h);
|
|
inicializuj_lopty(h);
|
|
inicializuj_tehly(h);
|
|
game_speed(RYCHLOST_HRY);
|
|
return h;
|
|
}
|
|
|
|
void destroy_game(void* hra) {
|
|
free(hra);
|
|
}
|
|
|
|
int game_event(struct event* udalost, void* hra) {
|
|
Hra* h = (Hra*)hra;
|
|
|
|
if (udalost->width > 0) h->sirka = udalost->width;
|
|
if (udalost->height > 0) h->vyska = udalost->height;
|
|
|
|
if (h->stav == STAV_UVOD) {
|
|
if (udalost->type == EVENT_KEY) {
|
|
int k = udalost->key;
|
|
if (k == '\n' || k == KEY_ENTER) {
|
|
if (h->meno_dlzka == 0) {
|
|
strcpy(h->meno, "Hrac");
|
|
h->meno_dlzka = 4;
|
|
}
|
|
nastav_level(h);
|
|
inicializuj_tehly(h);
|
|
h->palka.sirka = PALKA_SIRKA_MIN;
|
|
h->palka.y = palka_default_y(h);
|
|
h->palka.x = h->sirka / 2 - PALKA_SIRKA_MIN / 2;
|
|
h->hit_counter = 0;
|
|
h->sirka_timer = 0;
|
|
h->posledna_lopta = 0;
|
|
h->cas_tikov = 0;
|
|
h->special_dostupny = 1;
|
|
h->powerupy[0].ziva = 0;
|
|
h->powerupy[1].ziva = 0;
|
|
inicializuj_boss(h);
|
|
inicializuj_lopty(h);
|
|
h->stav = STAV_CAKA;
|
|
} else if (k == KEY_BACKSPACE && h->meno_dlzka > 0) {
|
|
h->meno[--h->meno_dlzka] = '\0';
|
|
} else if (k >= 32 && k < 127 && h->meno_dlzka < 31) {
|
|
h->meno[h->meno_dlzka++] = (char)k;
|
|
h->meno[h->meno_dlzka] = '\0';
|
|
}
|
|
}
|
|
vykresli_hru(h);
|
|
return 0;
|
|
}
|
|
|
|
if (h->stav == STAV_DALSI_LEVEL) {
|
|
int next = 0;
|
|
if (udalost->type == EVENT_KEY && udalost->key == ' ') next = 1;
|
|
if (udalost->type == EVENT_MOUSE && udalost->mouse_left) next = 1;
|
|
if (next) {
|
|
h->level++;
|
|
nastav_level(h);
|
|
inicializuj_tehly(h);
|
|
h->palka.sirka = PALKA_SIRKA_MIN;
|
|
h->palka.y = palka_default_y(h);
|
|
h->palka.x = h->sirka / 2 - PALKA_SIRKA_MIN / 2;
|
|
h->hit_counter = 0;
|
|
h->sirka_timer = 0;
|
|
h->posledna_lopta = 0;
|
|
h->cas_tikov = 0;
|
|
h->special_dostupny = 1;
|
|
h->powerupy[0].ziva = 0;
|
|
h->powerupy[1].ziva = 0;
|
|
inicializuj_boss(h);
|
|
inicializuj_lopty(h);
|
|
h->stav = STAV_CAKA;
|
|
}
|
|
vykresli_hru(h);
|
|
return 0;
|
|
}
|
|
|
|
if (udalost->type == EVENT_MOUSE) {
|
|
int ciel_x = udalost->mouse_x - h->palka.sirka / 2;
|
|
int lav = lavy_okraj(h);
|
|
int prav = pravy_okraj(h) - h->palka.sirka + 1;
|
|
if (ciel_x < lav) ciel_x = lav;
|
|
if (ciel_x > prav) ciel_x = prav;
|
|
h->palka.x = ciel_x;
|
|
if (h->stav == STAV_CAKA)
|
|
h->lopty[0].x = (float)(h->palka.x + h->palka.sirka / 2);
|
|
if (udalost->mouse_left && h->stav == STAV_CAKA)
|
|
h->stav = STAV_HRAJE;
|
|
}
|
|
|
|
if (udalost->type == EVENT_KEY) {
|
|
int k = udalost->key;
|
|
if (k == 'q' || k == 'Q') return 1;
|
|
if (k == 'e' || k == 'E') {
|
|
vystrel_special(h);
|
|
} else if (k == KEY_LEFT || k == 'a' || k == 'A') {
|
|
pohni_palku(h, -1);
|
|
} else if (k == KEY_RIGHT || k == 'd' || k == 'D') {
|
|
pohni_palku(h, +1);
|
|
} else if (k == ' ' && h->stav == STAV_CAKA) {
|
|
h->stav = STAV_HRAJE;
|
|
}
|
|
}
|
|
|
|
pohni_lopty(h);
|
|
vykresli_hru(h);
|
|
return 0;
|
|
}
|