2013-03-14 50 views
-5

我一直在這個項目上工作了一段時間,現在我無法在我的項目中找到我的問題。 URL:https://github.com/blackwolf12333/Snake 蛇是離身體幾個點,似乎並沒有移動。我之前有過一段段錯誤,但我找不到這個錯誤的問題!我幾乎嘗試了幾乎所有的東西,重新編寫代碼從頭到尾閱讀它。它在Linux中編碼!蛇的頭部距離身體有幾點距離(C++遊戲)

的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); 
    } 
} 

move.c

#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++; 
} 

move.h

#ifndef MOVE_H 
#define MOVE_H 

void move_up(); 
void move_down(); 
void move_left(); 
void move_right(); 

#endif 

position.c

#include "position.h" 

void initialize_position(position_t *pos, int x, int y) { 
pos->x = x; 
pos->y = y; 
} 

position.h

#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 

snake.c

#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; 
} 
} 
} 

snake.h

#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 
+5

請發佈您的問題的簡短,自包含,正確(可編譯),示例(http://sscce.org/)。不要指望有人拉你的github項目併爲你解決所有問題。 – meyumer 2013-03-14 18:20:04

+0

整個代碼不超過200行,我認爲github會更容易閱讀,但很快就會在第一篇文章中添加代碼。 – 2013-03-14 18:24:30

+0

@約翰史密斯,你錯過了「短而自足」的部分。 – 2013-03-14 18:51:40

回答

1

我認爲你的問題可能是部分在get_next_position_to功能,在這裏你增加的位置身體部分傳入功能。我認爲這應該只能增加。 「正確」的情況下,還修改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); 
    } 
} 
+0

終於有人決定查看我的代碼並幫助我。我非常感謝你的幫助,我會盡快解決我的錯誤。 – 2013-03-14 20:32:14