snek_vs_snacc/player.c

143 lines
3.0 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <curses.h>
#include "game.h"
#include "player.h"
void init_player(PLAYER* player, int x, int y) {
player -> head_dir_x = 1;
player -> head_dir_y = 0;
player -> next_head_dir_x = 1;
player -> next_head_dir_y = 0;
player -> length = 6;
player -> head_ptr = player -> length - 1;
player -> body = malloc(sizeof(POINT*) * player -> length);
player -> old_tail = NULL;
for (int i = 0; i < player -> length; i++) {
POINT* pt = malloc(sizeof(POINT));
pt -> x = x + i;
pt -> y = y;
player -> body[i] = pt;
}
}
void destroy_player(PLAYER* player) {
for (int i = 0; i < player -> length; i++) {
free(player -> body[i]);
}
if (player -> old_tail)
free(player -> old_tail);
free(player -> body);
free(player);
}
int bit_self(PLAYER* player, POINT* head_pos) {
for (int i = 0; i < player -> length; i++) {
if (player -> body[i] != head_pos &&
player -> body[i] -> x == head_pos -> x &&
player -> body[i] -> y == head_pos -> y) {
return 1;
}
}
return 0;
}
int hit_head(FIELD* field, POINT* head) {
return head -> x == 0 ||
head -> y == 0 ||
head -> x == field -> width - 1 ||
head -> y == field -> height - 1;
}
void move_player(FIELD* field) {
PLAYER* player = field -> player;
player -> head_dir_x = player -> next_head_dir_x;
player -> head_dir_y = player -> next_head_dir_y;
POINT* oldhead = player -> body[player -> head_ptr];
player -> head_ptr = (player -> head_ptr + 1) % player -> length;
free(player -> old_tail);
player -> old_tail = player -> body[player -> head_ptr];
POINT* newhead = malloc(sizeof(POINT));
newhead -> x = oldhead -> x + player -> head_dir_x;
newhead -> y = oldhead -> y + player -> head_dir_y;
for (int i = 0; i < field -> ball_count; i++) {
if (field -> balls[i] -> position.x == newhead -> x &&
field -> balls[i] -> position.y == newhead -> y) {
eat_ball(field, i);
}
}
player -> body[player -> head_ptr] = newhead;
if (bit_self(player, newhead) ||
hit_head(field, newhead)) {
set_lost(field -> state);
}
}
void handle_control(PLAYER* player) {
int ch = getch();
switch(ch) {
case CTRL_LEFT:
case 'h':
case 'a':
if (player -> head_dir_x != 1) {
player -> next_head_dir_x = -1;
player -> next_head_dir_y = 0;
}
break;
case CTRL_RIGHT:
case 'l':
case 'd':
if (player -> head_dir_x != -1) {
player -> next_head_dir_x = 1;
player -> next_head_dir_y = 0;
}
break;
case CTRL_UP:
case 'k':
case 'w':
if (player -> head_dir_y != 1) {
player -> next_head_dir_x = 0;
player -> next_head_dir_y = -1;
}
break;
case CTRL_DOWN:
case 'j':
case 's':
if (player -> head_dir_y != -1) {
player -> next_head_dir_x = 0;
player -> next_head_dir_y = 1;
}
break;
default:
break;
}
}
int is_on_player(PLAYER* player, POINT* point) {
for (int i = 0; i < player -> length; i++) {
if (player -> body[i] -> x == point -> x &&
player -> body[i] -> y == point -> y) {
return 1;
}
}
return 0;
}