简体   繁体   English

c中的线程,如何使用它们移动播放器?

[英]threads in c, how to use them to move a player?

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. 所以我正在用C开发2D游戏,现在我正在使用线程在同一时间做不同的事情,以移动玩家,汽车等。

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. 现在在主体内部,我们有一个while循环,该循环一直运行,直到玩家完成游戏或退出游戏为止。

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. 所以我的input_t线程正在调用该函数中的input_runner函数,以获取用户输入。

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. 只是知道运动是一个全局变量,所以我可以将其用于moveFroggy函数。 but that is the problem to because it stores "w" and it just repeat itself till the user hit any other command. 但这就是问题所在,因为它存储了“ w”,并且会重复执行直到用户按下任何其他命令。 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, 我是使用线程的新手,

Well, it seems the simple way to only move one step would be, at the bottom of moveFroggy() to clear movement value. 好吧,似乎只移动一步的简单方法就是在moveFroggy()的底部清除movement值。

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... 我也不确定这种整体多线程策略,但是也许它将对您有用...

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() . 如果在Linux上,请使用ncurses库,该库本身通过getch()提供非阻塞键盘输入。
  • If on Windows, use kbhit() . 如果在Windows上,请使用kbhit()
  • Use fcntl() with F_SETFL to set standard input as non-blocking. fcntl()F_SETFL一起使用可将标准输入设置为非阻塞。
  • Use select() or poll() to check for input before trying to read. 在尝试读取之前,请使用select()poll()检查输入。
  • Avoid the console entirely, and use a graphics library such as SDL. 完全避免使用控制台,而应使用SDL之类的图形库。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM