2013-04-08 38 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