pvjc20/final/commands.c
2020-05-21 19:06:40 +03:00

231 lines
7.3 KiB
C

#include "commands.h"
#include "game.h"
#include <curses.h>
#include <time.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <math.h>
void welcome_screen(){
box(stdscr, ACS_VLINE, ACS_HLINE);
mvprintw(LINES / 2 - 8, COLS / 2 - 12, "Use WASD to change direction");
mvprintw(LINES / 2 - 6, COLS / 2 - 15, "Dont touch the walls or your path");
mvprintw(LINES / 2 - 4, COLS / 2 - 10, "To exit anytime use 'q'");
mvprintw(LINES / 2 - 2, COLS / 2 - 11, "Press any key to continue");
getch();
erase();
}
int pick_color(){
mvprintw(LINES / 2 - 11, COLS / 2 - 20, "Pick color. To change use 's' and 'w'");
mvprintw(LINES / 2 - 9, COLS / 2 - 13, "To confirm use 'space'");
int color = 2;
while(1){
init_pair(1, COLOR_BLACK, (color == 5) ? 7 : color);
attron(COLOR_PAIR(1));
for(int i = 0; i < 10; i++){
for(int q = 0; q < 20; q++){
mvaddch(LINES / 2 - 3 + i, COLS / 2 - 2 + q - 10, ' ');
}
}
int ch = getch();
if(ch == ' ') break;
else if(ch == 's'){
color++;
if(color > 6) color = 1;
}
else if(ch == 'w'){
color--;
if(color < 1) color = 6;
}
else if(ch == 'q'){
endwin();
exit(0);
}
flushinp();
}
return (color == 5) ? 7 : color;
}
int pick_speed(){
box(stdscr, ACS_VLINE, ACS_HLINE);
mvprintw(LINES / 2 - 8, COLS / 2 - 12, "Pick speed. To change use 's'");
mvprintw(LINES / 2 - 6, COLS / 2 - 8, "To confirm use 'space'");
int speed = 60;
while(1){
mvprintw(LINES / 2 - 3, COLS / 2 + 2, "%d", 70 - speed);
int ch = getch();
if(ch == ' ') break;
else if(ch == 's'){
speed -= 10;
if(speed == 10) speed = 60;
}
}
erase();
box(stdscr, ACS_VLINE, ACS_HLINE);
return speed;
}
void init_screen(struct game* game){
initscr();
resize_term(LINES, (COLS % 2) ? COLS : COLS - 1);
curs_set(0);
noecho();
welcome_screen();
game->speed = pick_speed();
srand(time(NULL));
if(has_colors() == true){
start_color();
init_pair(7, COLOR_BLACK, COLOR_MAGENTA);
int color = pick_color();
init_pair(8, color, COLOR_BLACK);
init_pair(9, COLOR_WHITE, COLOR_BLACK);
erase();
attron(COLOR_PAIR(9));
box(stdscr, ACS_VLINE, ACS_HLINE);
attron(COLOR_PAIR(8));
}
game->y = rand() % (LINES - 5) + 2;
game->x = (rand() % (COLS - 5) + 2) / 2 * 2;
mvaddch(game->y, game->x, '@');
mvaddch(game->y + 1, game->x, ACS_HLINE);
mvaddch(game->y - 1, game->x, ACS_HLINE);
mvaddch(game->y, game->x + 2, ACS_VLINE);
mvaddch(game->y, game->x - 2, ACS_VLINE);
mvaddch(game->y + 1, game->x + 2, '+');
mvaddch(game->y + 1, game->x - 2, '+');
mvaddch(game->y - 1, game->x - 2, '+');
mvaddch(game->y - 1, game->x + 2, '+');
timeout(game->speed);
}
void draw_path(struct game* game){
static char save;
char line;
getyx(stdscr, game->y, game->x);
if(save != game->direction){
if(save == 'w' && game->direction == 'd') mvaddch(game->y, game->x - 1, ACS_ULCORNER);
else if(save == 'w' && game->direction == 'a') mvaddch(game->y, game->x - 1, ACS_URCORNER);
else if(save == 's' && game->direction == 'd') mvaddch(game->y, game->x - 1, ACS_LLCORNER);
else if(save == 's' && game->direction == 'a') mvaddch(game->y, game->x - 1, ACS_LRCORNER);
else if(save == 'a' && game->direction == 's'){
mvaddch(game->y, game->x, ACS_HLINE);
mvaddch(game->y, game->x - 1, ACS_ULCORNER);
}
else if(save == 'a' && game->direction == 'w'){
mvaddch(game->y, game->x, ACS_HLINE);
mvaddch(game->y, game->x - 1, ACS_LLCORNER);
}
else if(save == 'd' && game->direction == 's'){
mvaddch(game->y, game->x - 2, ACS_HLINE);
mvaddch(game->y, game->x - 1, ACS_URCORNER);
}
else if(save == 'd' && game->direction == 'w'){
mvaddch(game->y, game->x - 2, ACS_HLINE);
mvaddch(game->y, game->x - 1, ACS_LRCORNER);
}
save = game->direction;
}
else if(game->direction == 'w' || game->direction == 's'){
mvaddch(game->y, game->x - 1, ACS_VLINE);
}
else if(game->direction == 'd'){
mvaddch(game->y, game->x - 1, ACS_HLINE);
mvaddch(game->y, game->x - 2, ACS_HLINE);
}
else if(game->direction == 'a'){
mvaddch(game->y, game->x - 1, ACS_HLINE);
mvaddch(game->y, game->x, ACS_HLINE);
}
}
int direction_check(struct game* game ){
getyx(stdscr, game->y, game->x);
int read = -1;
switch(game->direction){
case 'w':
read = mvinch(game->y - 1, game->x - 1) & A_CHARTEXT;
break;
case 'a':
read = mvinch(game->y, game->x - 3) & A_CHARTEXT;
break;
case 's':
read = mvinch(game->y + 1, game->x - 1) & A_CHARTEXT;
break;
case 'd':
read = mvinch(game->y, game->x + 1) & A_CHARTEXT;
break;
}
usleep(100);
move(game->y, game->x);
if(read == (ACS_HLINE & A_CHARTEXT) || read == (ACS_VLINE & A_CHARTEXT) || read == ('#' & A_CHARTEXT) ) return 1;
return 0;
}
int movement(struct game* game){
static char save;
if((game->direction == 'w' && save == 's') || (game->direction == 's' && save == 'w') || (game->direction == 'a' && save == 'd') || (game->direction == 'd' && save == 'a')) game->direction = save;
if(direction_check(game)) return 0;
switch(game->direction){
case 'w':
draw_path(game);
mvaddch(game->y - 1, game->x - 1, '^');
break;
case 'a':
draw_path(game);
mvaddch(game->y, game->x - 3, '<');
break;
case 's':
draw_path(game);
mvaddch(game->y + 1, game->x - 1, 'v');
break;
case 'd':
draw_path(game);
mvaddch(game->y, game->x + 1, '>');
break;
}
save = game->direction;
return 1;
}
void spawn_blocks(struct game* game){
int y = (rand() % LINES - 4) + 2;
int x = (rand() % (COLS - 5) + 2) / 2 * 2;
if(abs(y - game->y) < 10 || abs(x - game->x) < 20) return;
attron(COLOR_PAIR(7));
for(int i = 0; i < 3; i++){
for(int q = 0; q < 6; q++){
mvaddch(y + i, x + q, '#');
}
}
attron(COLOR_PAIR(8));
}
void game_over(struct game* game){
timeout(9);
for(int i = 0, cycle = 0; i < LINES; i++){
flushinp();
for(int q = 0; q < COLS; q += 4){
attron(COLOR_PAIR(7));
mvaddch(i, q - (i % 2), ' ');
addch(' ');
attron(COLOR_PAIR(9));
addch(' ');
addch(' ');
refresh();
}
if(getch() != ERR) break;
}
attron(COLOR_PAIR(9));
timeout(-1);
flushinp();
erase();
mvprintw(LINES / 2 - 2, COLS / 2 - 5, "Score: %d", game->score);
mvprintw(LINES / 2, COLS / 2 - 10, "Press any key to exit");
getch();
endwin();
printf("\033[33mScore: %d\n\033[32mThanks for playing!\033[35m\n@Corupt Runner \033[37mby \033[36mArtem Horbunov\033[0m\n", game->score);
free(game);
}