我正在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游戏。
答案 0 :(得分: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行。
答案 1 :(得分: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' },
};
答案 2 :(得分: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]);
}
}
}
其余的代码然后工作正常。