2017-02-15 11 views
0

私は昨日新しいプロジェクト(roguelike)を開始しました。それは私の最初の、私は同じエラーに実行し続けます。スクロールマップを実装しようとした後、私はプログラムを実行しましたが、キーを押すたびに、アクセス違反の読み取り場所があることを示すメッセージボックスが表示されます。CのPDCurses(アクセス違反の読み取り場所を表示し続ける)

#include "curses.h" 
#include <stdlib.h> 

#define MAX_HEIGHT 16 
#define MAX_WIDTH 21 

typedef struct tile 
{ 
    char *tile; 
    bool passable; 
}tile; 

typedef struct player 
{ 
    int xpos; 
    int ypos; 
    int dx; 
    int dy; 
}player; 

tile tileArray[] = { 
    {".",TRUE}, 
    {"#",FALSE}, 
    {"+",FALSE}, 
    {"/",TRUE} 
}; 

int mapArray[15][21] = { 
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 
    { 0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 
    { 0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 
    { 0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 
    { 0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 
    { 0,0,1,1,1,2,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } 

}; 

typedef struct camPos 
{ 
    int y; 
    int x; 
}camPos; 

void initSetup(); 
player *actorSetup(); 
void refreshScreenMap(); 
void handleInput(); 
void drawScreenMap(); 
void interactionOpen(); 
bool isPassable(int y, int x); 
void startupScreen(); 

player *user; 
camPos cam; 

int main() 
{ 
    initSetup(); 

    user = actorSetup(); 
    cam.y = 2; 
    cam.x = 2; 

    startupScreen(); 

    while (TRUE) 
    { 
     drawScreenMap(); 
     refreshScreenMap(); 
     handleInput(); 
     clear(); 
    } 
    endwin(); 
    return 0; 
} 

void initSetup() 
{ 
    initscr(); 
    noecho(); 
    raw(); 
    keypad(stdscr,TRUE); 
} 

player *actorSetup() 
{ 
    player *newactor; 
    newactor = malloc(sizeof(player)); 
    newactor->xpos = 10; 
    newactor->ypos = 10; 
    return newactor; 
} 

void handleInput() 
{ 
    char button = getch(); 
    switch (button) 
    { 
     case 's': 
      user->dy++; 
      break; 
     case 'w': 
      user->dy--; 
      break; 
     case 'a': 
      user->dx--; 
      break; 
     case 'd': 
      user->dx++; 
      break; 
     case 'o': 
      interactionOpen(user); 
      break; 
    } 
    if (isPassable(user->ypos + user->dy, user->xpos + user->dx)) 
    { 
     user->ypos += user->dy; 
     user->xpos += user->dx; 
    } 
    else 
    { 
     user->dx = 0; 
     user->dy = 0; 
    } 
} 

void refreshScreenMap() 
{ 
    mvprintw(6, 8, "@"); 
    cam.x += user->dx; 
    cam.y += user->dy; 
} 

void drawScreenMap() 
{ 
    for (int y = 1; y < 12; y++) 
    { 
     move(y,1); 
     for (int x = 1; x < 16; x++) 
     { 
      mvprintw(y, x, tileArray[mapArray[cam.y + y][cam.x + x]].tile); 
     } 
    } 
} 

void interactionOpen() 
{ 
    if (mapArray[user->ypos + 1][user->xpos] == 2) 
    { 
     mapArray[user->ypos + 1][user->xpos] = 3; 
    } 
    else if (mapArray[user->ypos - 1][user->xpos] == 2) 
    { 
     mapArray[user->ypos - 1][user->xpos] = 3; 
    } 
    else if (mapArray[user->ypos][user->xpos + 1] == 2) 
    { 
     mapArray[user->ypos][user->xpos + 1] = 3; 
    } 
    else if (mapArray[user->ypos][user->xpos - 1] == 2) 
    { 
     mapArray[user->ypos][user->xpos - 1] = 3; 
    } 
    else if (mapArray[user->ypos + 1][user->xpos] == 3) 
    { 
     mapArray[user->ypos + 1][user->xpos] = 2; 
    } 
    else if (mapArray[user->ypos - 1][user->xpos] == 3) 
    { 
     mapArray[user->ypos - 1][user->xpos] = 2; 
    } 
    else if (mapArray[user->ypos][user->xpos + 1] == 3) 
    { 
     mapArray[user->ypos][user->xpos + 1] = 2; 
    } 
    else if (mapArray[user->ypos][user->xpos - 1] == 3) 
    { 
     mapArray[user->ypos][user->xpos - 1] = 2; 
    } 
} 

bool isPassable(int y, int x) 
{ 
    bool pass = tileArray[mapArray[y][x]].passable; 
    if (pass == FALSE) 
    { 
     return FALSE; 
    } 
    else if (y < cam.y || y >= (cam.y + 11)) 
    { 
     return FALSE; 
    } 
    else if (x < cam.x || x >= (cam.x + 15)) 
    { 
     return FALSE; 
    } 
    else 
    { 
     return TRUE; 
    } 
} 

void startupScreen() 
{ 
    mvprintw(10, 20, "________"); 
    mvprintw(11, 20, "\\______ \\ __ __ ____ ____ ____ ____ ____ "); 
    mvprintw(12, 20, " | | \\| | \\/ \\/___\\_/ __ \\/ _ \\/ \\ "); 
    mvprintw(13, 20, " | ` \\ |/ | \\/ /_/ > ___( <_>) | \\ "); 
    mvprintw(14, 20, "/_______ /____/|___| /\\___/\\___ >____/|___|/"); 
    mvprintw(15, 20, "  \\/   \\//_____/  \\/   \\/"); 
    mvprintw(16, 20, "Made by Will Reid"); 
    mvprintw(17, 20, "Press any key to start..."); 
    getch(); 
    clear(); 
} 
+1

*正確に*クラッシュしますか?デバッガを使ってsegfaultを引き起こす行を教えてください。 –

+0

Game.exeの0x00221CD5で未処理の例外が発生しました:0xC0000005:0xBEE161B4の場所を読み取っているアクセス違反。 (Visual Studiosからのメッセージ)行は; bool pass = tileArray [mapArray [y] [x]]。passable;しかし、パスをTRUEに変更すると、ブレークポイントは; mvprintw(y、x、tileArray [mapArray [cam.y + y] [cam.x + x]]。tile);に移動します。 (drawScreenMap関数内)。それを見てくれてありがとう! –

+1

ちょっと推測します。配列に不正なインデックスを使用している可能性があります。 'int getMapValue(int x、int y);'と 'bool setMapValue(int x、int y、int value);'の2つの関数を作成することをお勧めします。 'mapArray'にアクセスするたびにこれらの関数を使います。次に、索引が範囲内にあることを保証するコードを追加できます。そうでない場合は、エラーを出力します。 –

答えて

0

問題がisPassableで使用される変数camが初期化されなかったことである。

は、ここでは、コードです。

私はこれを参照する(Linux上)valgrindのを使用:コンパイラの警告をオンにする、また

==11010== 1 errors in context 1 of 7: 
==11010== Invalid read of size 8 
==11010== at 0x400B72: drawScreenMap (foo.c:151) 
==11010== by 0x40091E: main (foo.c:77) 
==11010== Address 0x58e8c2a0 is not stack'd, malloc'd or (recently) free'd 
==11010== 
==11010== 
==11010== 7 errors in context 2 of 7: 
==11010== Conditional jump or move depends on uninitialised value(s) 
==11010== at 0x40100E: isPassable (foo.c:203) 
==11010== by 0x400A46: handleInput (foo.c:124) 
==11010== by 0x400928: main (foo.c:79) 
==11010== Uninitialised value was created by a heap allocation 
==11010== at 0x4C28BED: malloc (vg_replace_malloc.c:263) 
==11010== by 0x400974: actorSetup (foo.c:97) 
==11010== by 0x4008F9: main (foo.c:69) 

は、いくつかの問題(Visual Studioがコンパイラの警告を持っている...)を示しました。

関連する問題