It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center。
7年前关闭。
我已经在这个项目上工作了一段时间,但我在项目中找不到问题。
网址:https://github.com/blackwolf12333/Snake
蛇离身体几点之遥,似乎没有动。我之前有一个段错误,已修复,但我找不到此错误的问题!我已经尝试了几乎所有内容,重新编写了代码以从头到尾阅读它。它用Linux编码!
main.c
移动
移动
位置
位置
蛇
蛇
此外,您的move_snake函数不会更新以下身体部位。由于您使用的是链表,因此可以将列表的最后一个元素移到头部之后,然后将位置等从头部复制到下一个元素,然后再移动头部。为此,您需要将列表更改为双向列表。您可以使用循环缓冲区来更有效地进行编码。
您的列表清理功能是错误的,因为您在再次访问之前释放了下一个元素。您需要存储一个临时对象并进行迭代,然后释放该临时对象。而且您绝对不应该释放&snake.head,因为您没有malloc。应该是这样的:
7年前关闭。
我已经在这个项目上工作了一段时间,但我在项目中找不到问题。
网址:https://github.com/blackwolf12333/Snake
蛇离身体几点之遥,似乎没有动。我之前有一个段错误,已修复,但我找不到此错误的问题!我已经尝试了几乎所有内容,重新编写了代码以从头到尾阅读它。它用Linux编码!
main.c
#include "snake.h"
#include "ncurses.h"
void update();
void draw_snake();
void check_move(int c);
void cleanup();
int main() {
initscr();
noecho();
cbreak();
snake = create_snake_at(20, 10);
add_body_part(&snake.head);
//add_body_part(snake.head.next);
int key;
printw("Press any key to continue...");
while((key = getch()) != 'q') { // when 'q' is pressed the game will exit.
check_move(key);
update(); // updates game logic/graphics
refresh();
}
refresh();
endwin();
cleanup();
return 0;
}
void update() {
//clear();
move_snake();
draw_snake();
}
void check_move(int c) {
switch(c) {
case 6517: // up arrow
move_up();
break;
case 6617:
move_down();
break;
case 6817:
move_left();
break;
case 6717:
move_right();
break;
default:
break;
}
draw_snake();
}
void print_body_part(body_part_t *part) {
move(part->pos.y, part->pos.x);
if(part->head) {
addch('$');
} else {
addch('*');
}
}
void draw_snake() {
body_part_t *next = &snake.head;
int i = 0;
while(next) {
move(i, 0);
printw("part is head: %d\tpart x: %d\tpart y: %d\n", next->head, next->pos.x, next->pos.y);
print_body_part(next);
next = next->next;
i++;
}
}
void cleanup() {
body_part_t *next;
for(next = &snake.head; next != NULL; next = next->next) {
//free(next);
}
}
移动
#include "move.h"
#include "snake.h"
//TODO: add collision logic here!
void move_up() {
snake.head.pos.y++;
}
void move_down() {
snake.head.pos.y--;
}
void move_left() {
snake.head.pos.x--;
}
void move_right() {
snake.head.pos.x++;
}
移动
#ifndef MOVE_H
#define MOVE_H
void move_up();
void move_down();
void move_left();
void move_right();
#endif
位置
#include "position.h"
void initialize_position(position_t *pos, int x, int y) {
pos->x = x;
pos->y = y;
}
位置
#ifndef POSITION_H
#define POSITION_H
typedef struct position {
int x;
int y;
} position_t;
void initialize_position(position_t *pos, int x, int y);
#endif
蛇
#include "snake.h"
body_part_t create_body_part(int head, int x, int y);
position_t get_position_next_to(body_part_t *part);
void add_body_part(body_part_t *prev) {
body_part_t *part = malloc(sizeof(body_part_t));
part->head = prev->head & 0;
part->pos = get_position_next_to(prev);
part->dir = prev->dir;
part->next = NULL;
prev->next = part;
}
snake_t create_snake_at(int x, int y) {
snake_t *snake = malloc(sizeof(snake_t));
body_part_t head = create_body_part(1, x, y);
snake->head = head;
snake->health = MAX_HEALTH;
return *snake;
}
body_part_t create_body_part(int head, int x, int y) {
body_part_t *part = malloc(sizeof(body_part_t));
part->head = head;
initialize_position(&part->pos, x, y);
part->dir = LEFT;
part->next = NULL;
return *part;
}
position_t get_position_next_to(body_part_t *part) {
position_t pos;
switch(part->dir) {
case UP:
initialize_position(&pos, part->pos.x, part->pos.y++);
break;
case DOWN:
initialize_position(&pos, part->pos.x, part->pos.y--);
break;
case LEFT:
initialize_position(&pos, part->pos.x--, part->pos.y);
break;
case RIGHT:
initialize_position(&pos, part->pos.x++, part->pos.y++);
break;
default:
break;
}
return pos;
}
void move_snake() {
body_part_t *next;
for(next = &snake.head; next != NULL; next = next->next) {
switch(next->dir) {
case UP:
move_up();
break;
case DOWN:
move_down();
break;
case LEFT:
move_left();
break;
case RIGHT:
move_right();
break;
}
}
}
蛇
#ifndef SNAKE_H
#define SNAKE_H
#include "stdlib.h"
#include "position.h"
#include "move.h"
#define MAX_HEALTH 20
typedef struct body_part body_part_t;
typedef enum DIR {
UP,
DOWN,
LEFT,
RIGHT
} direction;
typedef struct body_part {
int head;
position_t pos;
direction dir;
body_part_t *next;
} body_part_t;
typedef struct snake {
body_part_t head;
int health;
} snake_t;
/*
This is the main snake struct, if later multiple snakes will be implemented this should be replaced with something else
*/
snake_t snake;
snake_t create_snake_at(int x, int y);
void add_body_part(body_part_t *prev);
void move_snake();
#endif
最佳答案
我认为您的问题可能部分在get_next_position_to函数中,您可以在其中增加传递给该函数的正文部分的位置。我认为应该只补充一下。 “ RIGHT”案例还修改了X和Y。
position_t get_position_next_to(body_part_t *part) {
position_t pos;
switch(part->dir) {
case UP:
initialize_position(&pos, part->pos.x, part->pos.y + 1);
break;
case DOWN:
initialize_position(&pos, part->pos.x, part->pos.y - 1);
break;
case LEFT:
initialize_position(&pos, part->pos.x - 1, part->pos.y);
break;
case RIGHT:
initialize_position(&pos, part->pos.x + 1, part->pos.y);
break;
default:
break;
}
return pos;
}
此外,您的move_snake函数不会更新以下身体部位。由于您使用的是链表,因此可以将列表的最后一个元素移到头部之后,然后将位置等从头部复制到下一个元素,然后再移动头部。为此,您需要将列表更改为双向列表。您可以使用循环缓冲区来更有效地进行编码。
您的列表清理功能是错误的,因为您在再次访问之前释放了下一个元素。您需要存储一个临时对象并进行迭代,然后释放该临时对象。而且您绝对不应该释放&snake.head,因为您没有malloc。应该是这样的:
void cleanup() {
body_part_t* tmp;
body_part_t *next = snake.head.next;
while (next) {
tmp = next;
next = next->next;
free(tmp);
}
}
10-08 11:22