2013-04-08 35 views
1

我在C制作Roguelike游戏,我无法让我的角色以我想要的方式移动。我在点(x,y)上创建了一个2D字符数组,并绘制了该数组,并更改了x和y值,并根据输入的方向重新排列了数组(有点像Zork,但是与图形)。但是这并不能解决我的计划。该代码会解释比我更可以:C:Roguelike地图很扭曲

/* game.h (header file for globals) */ 

#define GAME_H 

char character = '@'; 
//char monster = '&'; 

int x = 2; 
int y = 2; 

/* my beginning floor 
(will not be implemented, just for testing movement) */ 
char floor[10][6] = { /* 219 = filled block, 32 = space */ 
     219, 219, 219, 219, 219, 219, 219, 219, 219, '\n', 
     219, 32, 32, 32, 32, 32, 32, 32, 219, '\n', 
     219, 32, 32, 32, 32, 32, 32, 32, 219, '\n', 
     219, 32, 32, 32, 32, 32, 32, 32, 219, '\n', 
     219, 219, 219, 219, 219, 219, 219, 219, 219, '\n'}; 



/* game.c (main file) */ 
#include <stdio.h> 
#include "game.h" 

int main(void){ 
     system("cls"); 
     floor[x][y] = character; 
     printf("%s", floor); 
     char move; 

     redo: 

     printf("\nTravel which way?\n"); 
     printf("a = left\ns = down\nd = up\nf = right\n\n>"); 
     scanf("%s", &move); 

     /* 
     array oftentimes gets desroyed because the newlines are 
     being overwritten by the assignments. 
     the if statements should have prevented this. 
     why didn't they? 
     */ 

     if (move == 'a'){ /* LEFT */ 
       if (x < 1){ 
         x = 1;} 
       x--; 
       floor[x][y] = character; 
       floor[x+1][y] = ' '; 
       system("cls"); 
       printf("%s", floor); 
       goto redo; 

     } else if (move == 's'){ /* DOWN (works, but goes right. Sometimes clones itself) */ 
       if (y > 3){ 
         y = 3;} /*bounds may be wrong*/ 
       y++; 
       floor[x][y] = character; 
       floor[x][y-1] = ' '; 
       system("cls"); 
       printf("%s", floor); 
       goto redo; 

     } else if (move == 'd'){ /* UP */ 
       if (y < 1){ 
         y = 1;} 
       y--; 
       floor[x][y] = character; 
       floor[x][y+1] = ' '; 
       system("cls"); 
       printf("%s", floor); 
       goto redo; 

     } else if (move == 'f'){ /* RIGHT */ 
       if (x > 7){ 
         x = 7;} 
       x++; 
       floor[x][y] = character; 
       floor[x-1][y] = ' '; 
       system("cls"); 
       printf("%s", floor); 
       goto redo;} 
     else { 
       goto done; 
     } 

     done: 
     return 0; 
} 

谁能告诉我什么,我做错了什么?

注意:此地图设置只是一个草稿。一旦机制完成,我将完全不同,但我会计划以同样的方式沿着阵列移动角色,所以我宁愿帮助这个特定的设置,而不愿意在如何建立做得更好/不同。然而,相关的答案和源代码显示更好的实现仍然是有用的和赞赏的,因为我自己可能会做它完全错误的第一位,因为这是我的第一个Roguelike游戏。

+2

它有什么问题?假设我们大多数人不会在可能的情况下编写代码。 – Pubby 2013-04-08 23:14:57

+0

问题是,如果我告诉它向左移动,角色不会移动,比如离开。如果我放置命令来移动字符,它应该向左移动1,但是在重复调用该命令时不会这样做。它以Z字形而不是直线形式移动,有时候字符会出现在数组中的多个位置。 – 2013-04-08 23:19:29

+2

好吧,我会建议保持球员和地图分开。使用curses库来绘制所有内容而不是printf。无论如何,简单看看你的代码让我觉得对's''的边界检查是不正确的。 – Pubby 2013-04-08 23:24:28

回答

2

鉴于此代码:

char character = '@'; 
int x = 2; 
int y = 2; 

char floor[10][6] = { /* 219 = filled block, 32 = space */ 
     219, 219, 219, 219, 219, 219, 219, 219, 219, '\n', 
     219, 32, 32, 32, 32, 32, 32, 32, 219, '\n', 
     219, 32, 32, 32, 32, 32, 32, 32, 219, '\n', 
     219, 32, 32, 32, 32, 32, 32, 32, 219, '\n', 
     219, 219, 219, 219, 219, 219, 219, 219, 219, '\n'}; 


/* game.c (main file) */ 
#include <stdio.h> 
#include "game.h" 

int main(void){ 
     system("cls"); 
     floor[x][y] = character; 
     printf("%s", floor); /* print the map and character */ 

有几个问题。 首先,你的数组不是空终止;打印它是不安全的。该数组中只有5 * 10 = 50个字符,因此它终究为空。直到后来我才注意到这种错误。如果你有第六行数据,你必须使用:

 printf("%.*s", (int)sizeof(floor), floor); 

另一个问题是,你误解了数组;它是10行6个字符,而不是6行10个字符。

char floor[10][6] = 
{ /* 219 = filled block, 32 = space */ 
     { 219, 219, 219, 219, 219, 219, }, 
     { 219, 219, 219, '\n', 219, 32, }, 
     { 32, 32, 32, 32, 32, 32, }, 
     { 219, '\n', 219, 32, 32, 32, }, 
     { 32, 32, 32, 32, 219, '\n', }, 
     { 219, 32, 32, 32, 32, 32, }, 
     { 32, 32, 219, '\n', 219, 219, }, 
     { 219, 219, 219, 219, 219, 219, }, 
     { 219, '\n' }, 
}; 

而且,实际上,您的数据也会缩短几个字符。但是,由于打印方式的原因,它会显示OK,但如果您完全使用括号初始化,则会发现如果将原始布局中的每一行括起来,则会出现问题。

我会忍不住用名称代替号码在initializatio人物:

enum { WALL = 219, OPEN = 32, ENDL = '\n' }; 

它们被均匀每4个字母,使得在初始化一个更系统的布局。

注意,当您将字符在2,2,要修改这样的数组:

char floor[10][6] = 
{ /* 219 = filled block, 32 = space */ 
     { 219, 219, 219, 219, 219, 219, }, 
     { 219, 219, 219, '\n', 219, 32, }, 
     { 32, 32, '@', 32, 32, 32, }, // Change here! 
     { 219, '\n', 219, 32, 32, 32, }, 
     { 32, 32, 32, 32, 219, '\n', }, 
     { 219, 32, 32, 32, 32, 32, }, 
     { 32, 32, 219, '\n', 219, 219, }, 
     { 219, 219, 219, 219, 219, 219, }, 
     { 219, '\n' }, 
}; 
+0

哇!这正是我期待的解释!我想知道我做错了什么。我认为通过按照我所做的方式制作数组,我用逗号分隔每个元素,我将制作一个10 x和6 y的网格,每个元素都是完全独立的,并在x处放置一个字符,y会把它从左上角放到右边,然后从那里下来,但显然不是。我还没有机会改变它,但是我今晚会修改它,如果它有效,我会标记为已回答。感谢您的解释:) – 2013-04-11 21:14:37

+0

我切换x和y,我的阵列效果更好。我不得不重写它,并修改边界检查像昨天晚上3小时,但我终于得到它的工作,就像它应该:) – 2013-04-12 17:39:11

3

你的地板的声明看起来有点怪我尝试做这样的事情:这里http://ideone.com/O7UG8g

//c arrays are generally array[rows][columns] 
int rows = 6, cols = 10; 
char floor[rows][cols] = { 
    {219, 219, 219, 219, 219, 219, 219, 219, 219, '\n'}, 
    {219, 32, 32, 32, 32, 32, 32, 32, 219, '\n'}, 
    {219, 32, 32, 32, 32, 32, 32, 32, 219, '\n'}, 
    {219, 32, 32, 32, 32, 32, 32, 32, 219, '\n'}, 
    {219, 219, 219, 219, 219, 219, 219, 219, 219, '\n'}}; 

例。在那个例子中,我改变了219-> 35,因为我认为打印扩展ascii不适用于该网站。

而且我想绑定的检查应该是这样的:

//move left (go one column left) 
//if current position is array[curRow][curCol] 
//assuming array[0][0] is top left of map 
//check if left is a wall 
if((curCol - 1) == charForAWall) 
    return; 
else 
    curCol--; 

右键将+1列,最多-1行,倒排+1。

+0

我确实将x和y更改为'rows'和'cols',这有所帮助。我不知道C数组是否是行优势或列优势,所以这也有帮助。我重写了数组,并将x和y切换到了左右,并且在绕过边界检查之后,它可以正常工作:)我将对此进行标记,感谢您的帮助 – 2013-04-12 17:51:22

1

有什么不妥处理移动代码的,它看起来像这个问题是做用你分配数组的方式。对于初学者来说,你只有5列,而不是6.我分组这样的元素:

char floor[10][5] = { 
    {219,219,219,219,219}, 
    {219,32,32,32,219}, 
    {219,32,32,32,219}, 
    {219,32,32,32,219}, 
    {219,32,32,32,219}, 
    {219,32,32,32,219}, 
    {219,32,32,32,219}, 
    {219,32,32,32,219}, 
    {219,219,219,219,219}, 
    {'\n','\n','\n','\n','\n'} 
}; 

然后我又写了功能打印阵列(更换printf语句,这将不再是这样工作)像这样:

int printArray() { 
    int i, j; 

    for(i=0; i<5; i++) { 
     for(j=0; j<10; j++) { 
      printf("%c", floor[j][i]); 
     } 
    } 
} 

其余的代码然后工作正常。

+0

谢谢,我今晚会尝试这个,如果它的工作回复你。尽管如此,从你的第二句话:“你只有5列,而不是6”。我发布的原始代码是'floor [10] [6]'。你发布的代码是'floor [10] [5]'。这是你的错误还是对我的误解?或者你是否展示了一些完全不同的东西,我只是没有跟上? – 2013-04-11 21:19:30

+0

您的printArray()函数工作得很漂亮,除了我必须在printf语句中更改i和j。我会很多地使用这个功能。谢谢:D – 2013-04-12 17:40:46

+0

太棒了!如果你看看你的原始数组声明,你会看到你有10列的值,但只有5行。当我说你只有5个(实际上,而不是列)时,这就是我的意思。祝你好运! – mikeyq6 2013-04-12 21:56:01