【问题标题】:ncurses based mini game is printing the bullet twice基于 ncurses 的迷你游戏正在打印两次子弹
【发布时间】:2020-11-30 22:24:38
【问题描述】:

我正在使用 c 语言开发一个微型游戏,前端使用 ncurses 库。

我将代码简化到最低限度,预期的结果应该是定期发射一枚炸弹的航天飞机。 问题是当程序运行时,第一次拍摄总是重复然后有时会再次出现问题。

有 2 个进程通过管道进行通信。

这里是突出显示错误的程序的最小版本:

#include <curses.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#define ENEMYSPRITE "()"
#define BOMB "#"

typedef struct {
  char * c;
  int x;
  int y;
  int oldx;
  int oldy;
}
pos;

void bombe(int pipeout, pos pos_enemy) {
  pos pos_bomba;
  pos_bomba.c = BOMB;
  pos_bomba.x = pos_enemy.x;
  pos_bomba.y = pos_enemy.y + 1;

  write(pipeout, & pos_bomba, sizeof(pos_bomba));

  while (1) {
    pos_bomba.oldy = pos_bomba.y;
    pos_bomba.oldx = pos_bomba.x;
    pos_bomba.y++;
    write(pipeout, & pos_bomba, sizeof(pos_bomba));
    usleep(150000);
  }
  _exit(0);
}

void gameBoard(int pipein) {
  pos pos_enemy, pos_bomba, readValue;

  while (1) {
    read(pipein, & readValue, sizeof(readValue));

    if (strcmp(readValue.c, BOMB) == 0) {
      mvaddstr(pos_bomba.oldy, pos_bomba.oldx, " "); // deleting the old bullet's position
      pos_bomba = readValue;
    }
    mvaddstr(readValue.y, readValue.x, readValue.c);
    refresh();
  }
}

void enemy(int pipeout) {
  pid_t pid_bomba;
  pos pos_enemy;
  pos_enemy.c = ENEMYSPRITE;
  pos_enemy.x = 10;
  pos_enemy.y = 5;

  write(pipeout, & pos_enemy, sizeof(pos_enemy));

  while (1) {
    pid_bomba = fork();
    if (pid_bomba == 0) {
      bombe(pipeout, pos_enemy);
    }

    write(pipeout, & pos_enemy, sizeof(pos_enemy));
    usleep(1000000);
  }
}

int main(int argc, char ** argv) {
  initscr();
  noecho();
  curs_set(0);

  int fdescriptor[2];
  pipe(fdescriptor);
  pid_t pidEnemy = fork();
  if (pidEnemy == 0) {
    close(fdescriptor[0]);
    enemy(fdescriptor[1]);
  } else {
    close(fdescriptor[1]);
    gameBoard(fdescriptor[0]);
  }
  return 0;
}

【问题讨论】:

  • 我建议将gameBoard中的ncurses输出替换为接收结构中所有值的文本输出,删除所有其他ncurses相关函数调用并检查接收到的数据是否是你的期望以及 ncurses 函数调用将从数据中产生什么。也许让程序变慢一点,或者让循环在一定数量的循环后终止。还要检查所有函数调用的返回值,尤其是readwrite。我建议将发送进程的PID添加到结构类型pos中并打印出来。

标签: c pipe fork ncurses


【解决方案1】:

我相信我们代码的问题在于函数bombe()。这是解决最初拍摄两次问题的修订版。

void bombe(int pipeout, pos pos_enemy) {
    pos pos_bomba = pos_enemy;
    pos_bomba.c = BOMB;
    pos_bomba.y = pos_enemy.y + 1;

    while (1) {
        pos_bomba.oldy = pos_bomba.y;
        pos_bomba.oldx = pos_bomba.x;
        write(pipeout, & pos_bomba, sizeof(pos_bomba));

        ++pos_bomba.y;

        usleep(1155000);
    }
  _exit(0);
}

注意现在这个函数里面只有一个write()

【讨论】:

    猜你喜欢
    • 2021-03-03
    • 1970-01-01
    • 2011-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-30
    • 1970-01-01
    相关资源
    最近更新 更多