1

我正在用 C 语言制作 Roguelike 游戏,但我无法让我的角色按照我想要的方式移动。我在点 (x, y) 处创建了一个带有字符的 2D 字符数组,绘制了数组,并更改了 x 和 y 值,并在输入要前进的方向时重新绘制了数组(有点像 Zork,但有图形)。但这不符合我的计划。该代码将解释更多:

/* 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 游戏。

4

3 回答 3

3

你的地板声明对我来说看起来有点奇怪尝试做这样的事情:

//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'}};

此处为 http://ideone.com/O7UG8g示例。我在该示例中更改了 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 行。

于 2013-04-09T00:06:52.343 回答
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' },
};

而且,实际上,您的数据也很短几个字符。但是,由于您打印它的方式,它看起来不错,但是如果您进行了完全括号初始化,您会发现如果您将括号放在原始布局中的每一行周围,就会出现问题。

我很想在初始化中使用名称而不是数字来表示字符:

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' },
};
于 2013-04-09T00:18:44.423 回答
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]);
        }
    }
}

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

于 2013-04-09T00:22:10.937 回答