0

Update my code

So i am working on a 2d game in c, now i am using threads to do different stuff in the same time, to move the player, cars etc.

But somehow i don't get it how can i move my player just one step, i know that the problem lays in my global variable movement. But can figure it how to do it the right way. So i hope someone can help me.

The code is huge so i will not passt all of it but the parts that are interesting for the player movement.

void moveFroggy() {
    //    froggy.y = SCREEN_HEIGHT - OUTER_BORDER;
    if((movement == 'a') && (froggy.x > OUTER_BORDER))
        froggy.x--;
    if((movement == 'd') && (froggy.x < (SCREEN_WIDTH - OUTER_BORDER)))
        froggy.x++;
    if ((movement == 'w') && (froggy.y >= (SCREEN_HEIGHT - NUM_LANES - OUTER_BORDER - GRASS_BORDER)))
        froggy.y--;
    if ((movement == 's') && (froggy.y < (SCREEN_HEIGHT - OUTER_BORDER)))
        froggy.y++;
    if(movement == 'q')
        quit = 1;
    if(froggy.y <= (SCREEN_HEIGHT - NUM_LANES - OUTER_BORDER - GRASS_BORDER))
    player_won = 1;
    movement = '0';
    }

Now inside the main we have a while loop that runs all the time, till the player complete the game or quit it.

pthread_create(&input_t, NULL, input_runner, NULL);

while(!quit && !error && !player_lost && !player_won) {
    moveFroggy();
    moveCarsOnMotorway();
    startCar((SCREEN_WIDTH - OUTER_BORDER));
    drawScreen();
    usleep(GAME_SPEED);
}

pthread_join(input_t, NULL);

So my input_t thread is calling the input_runner function inside that function i get the user input.

void *input_runner(void* arg) {
  char input;
  if(!player_lost || !player_won){
    while((input = getchar()) != EOF){
     movement = input;
    }
  }
  pthread_exit(0);

}

Just to know movement is a global variable so i can use it for moveFroggy function. but that is the problem to because it stores "w" and it just repeat itself till the user hit any other command. But it should move the player just one step ahead, so how can i reset the value and how to do proper clean up for threads if one is needed.

I am new in using thread,

twistedhat
  • 55
  • 10
  • a) Note that getchar() returns int, and may return EOF (-1). You need to check for errors. b) Create the thread once, not in a loop. c) The problem may be that input_runner() blocks on getchar() while the other thread runs. Therefore movement stays the same, i.e., the last value given. If you want do use threads, the input thread probably needs to notify the other thread that a new event (an input event) has occured. – Bjorn A. Oct 26 '16 at 18:27
  • `movefroggy` takes no arguments and refers to globals ... and you want to do this in a thread? – Kaz Oct 26 '16 at 18:29
  • b) how do you mean create once and not loop if i do so i will just get the first input and the map will not be loaded before the user hit a keyword. c) i can hit a and he will move to the left just he will get stuck moving to left till i dont' hit other keywod, i don't think that is the problem. For a) yes that is a good idea :) – twistedhat Oct 26 '16 at 18:36
  • @BjornA. can you check the code now, i edit it a little bit, do you know how to delete threads when i don't need them. – twistedhat Oct 26 '16 at 19:15
  • The current solution won't work since the input thread will be stuck in getchar() even after a player has won or lost. As others have mentioned, you need non-blocking IO and select(). Also, have a look at pthread_cond_wait(), pthread_cond_signal() and pthread_mutex_lock()/unlock(). It's not the easiest stuff to learn, a good tutorial is probably nice to have. Good luck – Bjorn A. Oct 26 '16 at 19:34

2 Answers2

1

Well, it seems the simple way to only move one step would be, at the bottom of moveFroggy() to clear movement value.

As an aside, it looks like you're creating an input-processing thread on every iteration of your game loop; is that really what you intend? If you want an input-processing thread, why not have it run its own loop to constantly read input until the game is over?

I'm also not sure of this overall multithreading strategy, but perhaps it will work for you...

Mark Adelsberger
  • 42,148
  • 4
  • 35
  • 52
  • User input can be gathered using getchar() but the problem with it is, that it would block the whole program waiting for the user to type in a character if used in a single-threaded environment. – twistedhat Oct 26 '16 at 18:29
0

This is not a good use of threads, and will be prone to synchronization errors.

Variables that are accessed by multiple threads must be protected by a mutex or accessed using atomic methods. Failing to do so will result in unpredictable behavior.

In any case, you don't need threads for this. If you want to read from the keyboard without blocking, there are a number of ways of doing that, including:

  • If on Linux, use the ncurses library, which natively provides non-blocking keyboard input through getch().
  • If on Windows, use kbhit().
  • Use fcntl() with F_SETFL to set standard input as non-blocking.
  • Use select() or poll() to check for input before trying to read.
  • Avoid the console entirely, and use a graphics library such as SDL.
Community
  • 1
  • 1