snek_vs_snacc/field.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);
}