Search code examples
c++cncursescurses

movement not working ncurses game


I am making an ncurses game which has a spaceship fire bullets at other enemies. I've got the ship firing bullets how ever when I fire more than one bullet, only the latest bullet will move and the rest will stay still.

int i=0 , j=-1;
switch(key){ 
    case KEY_UP: playership.row=changeRow(playership.row,-1,playership.col); /* move up */ 
    break; 
    case KEY_DOWN: playership.row=changeRow(playership.row,+1,playership.col); /* move down */ 
    break; 
    case KEY_LEFT:playership.col=changeColumn(playership.col,-1,playership.row); /* move left */ 
    break; 
    case KEY_RIGHT:playership.col=changeColumn(playership.col,+1,playership.row); /* move right */ 
    break; 
    case ' ': {j++; bullets[0].col=playership.col+5; bullets[j].row=playership.row-2 ;break;}
    default: break; /* do nothing if other keys */ 

    }
 if (j!=-1){
     attrset(COLOR_PAIR(2));
     mvprintw(bullets[j].row,bullets[0].col,"%c",bullet);
     mvprintw(bullets[j].row+1,bullets[0].col," ");
     bullets[j].row=bullets[j].row-1;
     refresh();
 }

I tried to implement the suggestion from the comments in this answer to my earlier question, but I don't think I've done it right:

If you can have 5 bullets at once, you need to store their positions. If you have int bullet_pos[5] that would be fine. You could use -1 in each position to say that no bullets are active. Then when you want to fire one you search the array to find the first position that is -1 and change it to 0. When you draw the bullets, you go through the array and draw a bullet for any position that is not -1, and update its position.


Solution

  • If you don't already, try adding a flag to your bullet structure. Something like alive.

    When you want to fire, you check through your array and find an unused bullet position (if any):

    for( int i = 0; i < MAX_BULLETS; i++ ) {
        if( !bullets[i].alive ) {
            bullets[i].alive = true;
            bullets[i].row = playership.row;
            bullets[i].col = playership.col+5;
            break;
        }
    }
    

    Then when you update or draw:

    for( int i = 0; i < MAX_BULLETS; i++ ) {
        if( bullets[i].alive ) {
            attrset(COLOR_PAIR(2));
            mvprintw(bullets[i].row, bullets[i].col, "%c", bullet);
            mvprintw(bullets[i].row+1, bullets[i].col, " " );
            bullets[i].col++;
    
            // TODO check for bullet death.  If bullet is done, set `alive` to false.
        }
    }
    
    refresh();