143 lines
3.0 KiB
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;
|
|
}
|