【发布时间】:2016-12-07 14:52:02
【问题描述】:
我对 C 编程非常陌生,总体而言,我的编程技能相当生疏。为了学习 C 并重新调整自己的编程方向,我正在挑战自己尝试使用 ncurses 制作简单的 rougelike。
我已经设置了一个“日志”,我应该能够将消息推送到该日志 - 应该显示最近的 10 条消息。为了测试这一点,我已经做到了,每当玩家或非常简单的随机移动的生物迈出一步时,都会推送一条日志消息,上面写着“step [direction]”。然而,尽管他们每个人只采取了一步,但由于某种原因,有四条消息被推送到日志中。倒数第二个始终是角色移动的实际方向,我假设其他两个之一是暴徒移动,但我不知道其他两个的来源。有没有人在我的代码中发现任何可能导致此问题的明显内容?感谢所有帮助,谢谢!
(我认为唯一需要查看的主要相关部分应该是 main() 函数、pushToLog()、printLog() 和 moveCreature()。也就是说,问题可能出在其他地方。我'不确定。)
#include <stdlib.h>
#include <stdio.h>
#include <ncurses.h>
#include <unistd.h>
#include <string.h>
#define up 65
#define down 66
#define right 67
#define left 68
#define quit 113
struct creature {
int x;
int y;
int hp;
int maxhp;
};
void setupMap();
struct creature setupCreature();
void moveCreature();
void pushToLog();
void printLog();
int breakFlag = FALSE;
char mapShape[15][15];
char mapFeatures[15][15];
char outputLog[10][60];
int main(int argc, char *argv[]){
struct creature player = setupCreature(4, 4, 100, 100);
struct creature mob = setupCreature(5, 7, 100, 100);
setupMap();
initscr();
noecho();
curs_set(FALSE);
while(1){
for (int i = 0; i < 15; i++){
for (int c = 0; c < 15; c++){
mvprintw(c, i, "%c", mapShape[i][c]);
}
}
mvprintw(player.y, player.x, "%c", '@');
mvprintw(mob.y, mob.x, "%c", 'd');
printLog();
int input = getch();
moveCreature(input, &player);
int mobDir = rand() % (68 + 1 - 65) + 65;
moveCreature(mobDir, &mob);
refresh();
usleep(300);
if (breakFlag == TRUE){
break;
}
}
endwin();
return 0;
}
void moveCreature(int dir, struct creature *subject){
int next;
if (dir == up){
next = (subject->y - 1);
if (mapShape[subject->x][next] != '#'){
subject->y = next;
pushToLog("step up ");
}
}
else if (dir == down){
next = (subject->y + 1);
if (mapShape[subject->x][next] != '#'){
subject->y = next;
pushToLog("step down ");
}
}
else if (dir == right){
next = (subject->x + 1);
if (mapShape[next][subject->y] != '#'){
subject->x = next;
pushToLog("step right ");
}
}
else if (dir == left){
next = (subject->x - 1);
if (mapShape[next][subject->y] != '#'){
subject->x = next;
pushToLog("step left ");
}
}
else if (dir == quit){
breakFlag = TRUE;
}
}
void pushToLog(char string[]){
for (int i = 10; i > 0; i--){
strcpy(outputLog[i], outputLog[i-1]);
}
strcpy(outputLog[0], string);
}
void printLog(){
for (int i = 0; i < 10; i++){
mvprintw(28-i, 0, outputLog[i]);
}
}
struct creature setupCreature(int x,int y,int hp,int maxhp){
struct creature frankenstien;
frankenstien.x = x;
frankenstien.y = y;
frankenstien.hp = hp;
frankenstien.maxhp = maxhp;
return frankenstien;
}
void setupMap(){
for (int i = 0; i < 15; i++){
for (int c = 0; c < 15; c++){
mapShape[i][c] = '.';
}
}
for (int i = 0; i < 15; i++){
mapShape[0][i] = '#';
mapShape[14][i] = '#';
mapShape[i][0] = '#';
mapShape[i][14] = '#';
}
}
【问题讨论】:
-
通过调试器运行它。
-
如果可以,请删除所有不直接相关的代码。见minimal reproducible example。我们不需要看到你的完整游戏。我们所需要的只是一个不能按您期望的方式工作的简短示例程序。这不仅是发布到 SO 的指南;缩小问题范围也是调试代码的好方法。
-
另外,请发布您期望的输出和您实际得到的输出。
-
粗略检查告诉我你的 printLog() 是可疑的。它打印队列的全部内容,而不考虑是否已经打印了一行。处理这个问题的一种方法是在 printLog() 的末尾清除队列。 (当然,还有很多其他方法可以解决这个问题。)