126 lines
3.2 KiB
C
126 lines
3.2 KiB
C
#include <stdlib.h>
|
|
#include <curses.h>
|
|
#include <math.h>
|
|
#include "game.h"
|
|
#include "ball.h"
|
|
#include "player.h"
|
|
#include "field.h"
|
|
|
|
|
|
|
|
void add_ball(FIELD* f, int max_value) {
|
|
POINT* playerhead = f -> player -> body[f -> player -> head_ptr];
|
|
BALL* b = malloc(sizeof(BALL));
|
|
|
|
//find a value
|
|
int value = (random() % max_value) + 1;
|
|
|
|
//get random position that's at least 10 away from the player's head
|
|
int x;
|
|
int y;
|
|
int dir = random() % 4;
|
|
do {
|
|
x = (random() % (f -> width - 2)) + 1;
|
|
y = (random() % (f -> height - 2)) + 1;
|
|
|
|
} while (sqrt((double)((x - playerhead -> x) * (x - playerhead -> x) +
|
|
(y - playerhead -> y) * (y - playerhead -> y))) < (double) (13 + value));
|
|
|
|
init_ball(b, x, y, dir, value);
|
|
f -> ball_count++;
|
|
|
|
|
|
//if ball buffer is too small, double it
|
|
if (f -> ball_count >= f -> max_allocated_balls) {
|
|
f -> max_allocated_balls *= 2;
|
|
f -> balls = realloc(f -> balls, f -> max_allocated_balls);
|
|
}
|
|
f -> balls[f -> ball_count - 1] = b;
|
|
}
|
|
|
|
void init_field(FIELD* f, int width, int height, GAME_STATE* state) {
|
|
f -> state = state;
|
|
f -> win = subwin(stdscr, height, 2 * width, 0, 0);
|
|
f -> width = width;
|
|
f -> height = height;
|
|
f -> max_allocated_balls = 1;
|
|
f -> balls = malloc(sizeof(BALL) * f -> max_allocated_balls);
|
|
f -> ball_count = 0;
|
|
f -> player = malloc(sizeof(PLAYER));
|
|
}
|
|
|
|
void destroy_field(FIELD* f) {
|
|
destroy_player(f -> player);
|
|
for (int i = 0; i < f -> ball_count; i++) {
|
|
free(f -> balls[i]);
|
|
}
|
|
|
|
free(f -> balls);
|
|
delwin(f -> win);
|
|
free(f);
|
|
}
|
|
|
|
|
|
void draw_outline(FIELD* f) {
|
|
wattrset(f -> win, COLOR_PAIR(1));
|
|
for (int i = 0; i < f -> width * 2 - 1; i++) {
|
|
mvwprintw(f -> win, 0, i , " ");
|
|
mvwprintw(f -> win, f -> height - 1, i , " ");
|
|
}
|
|
for (int i = 1; i < f -> height - 1; i++) {
|
|
mvwprintw(f -> win, i, 0 , " ");
|
|
mvwprintw(f -> win, i, f -> width * 2 - 2, " ");
|
|
}
|
|
}
|
|
|
|
|
|
void draw_player(FIELD* f) {
|
|
wattrset(f -> win, COLOR_PAIR(2));
|
|
PLAYER* player = f -> player;
|
|
POINT* p;
|
|
for (int i = 0; i < player -> length; i++) {
|
|
p = player -> body[i];
|
|
mvwprintw(f -> win, p -> y, p -> x * 2, " ");
|
|
}
|
|
}
|
|
|
|
void redraw_field(FIELD* f) {
|
|
clear();
|
|
wattrset(f -> win, COLOR_PAIR(1));
|
|
draw_outline(f);
|
|
|
|
for (int i = 0; i < f -> ball_count; i++) {
|
|
BALL* b = f -> balls[i];
|
|
wattrset(f -> win, COLOR_PAIR(b -> color));
|
|
mvwprintw(f -> win, b -> position.y, b -> position.x * 2, " ");
|
|
}
|
|
draw_player(f);
|
|
wrefresh(f -> win);
|
|
}
|
|
|
|
void update_ballpos(FIELD* f) {
|
|
for (int i = 0; i < f -> ball_count; i++) {
|
|
BALL* b = f -> balls[i];
|
|
// clear old ball position if it's not on player
|
|
if (! is_on_player(f -> player, & b -> old_position)) {
|
|
wattrset(f -> win, COLOR_PAIR(7));
|
|
mvwprintw(f -> win, b -> old_position.y, b -> old_position.x * 2, " ");
|
|
}
|
|
// draw ball at new position
|
|
wattrset(f -> win, COLOR_PAIR(b -> color));
|
|
mvwprintw(f -> win, b -> position.y, b -> position.x * 2, " ");
|
|
}
|
|
wrefresh(f -> win);
|
|
}
|
|
void update_playerpos(FIELD* f) {
|
|
PLAYER* player = f -> player;
|
|
wattrset(f -> win, COLOR_PAIR(7));
|
|
mvwprintw(f -> win, player -> old_tail -> y, player -> old_tail -> x * 2, " ");
|
|
wattrset(f -> win, COLOR_PAIR(2));
|
|
mvwprintw(f -> win,
|
|
player -> body[player -> head_ptr] -> y,
|
|
player -> body[player -> head_ptr] -> x * 2,
|
|
" ");
|
|
wrefresh(f -> win);
|
|
}
|