Automatyczne poruszanie obiektu bez interakcji gracza

0

Wlasciwie wszystko w grze skonczylem tylko teraz chcialbym zeby pilka poruszala sie sama, bo w tym momencie zeby ona sie gdzies ruszyla to ja musze sie ruszyc(tak jak w grach roguelike) a chcialbym zeby latala niezaleznie ode mnie, patrzylem podobny projekt na githubie ale nie wiem dlaczego tam to dziala a u mnie nie...

#include<ncurses.h>
#include<stdlib.h>
#include<time.h>

#define FORWARD 102
#define BACKWARD 98
#define ENTER 10
#define PADDLE_WIDTH 7
#define HEIGHT 15
#define WIDTH 45
#define STARTY (LINES - HEIGHT) / 2 - 4
#define STARTX (COLS - WIDTH) / 2 - 4

struct player_data{
  unsigned int x;
  unsigned int y;
  unsigned int deaths;
};
struct ball_data{
  unsigned int x;
  unsigned int y;
  bool mv_left;
  bool mv_right;
  bool mv_up;
  bool mv_down;
};
struct game_data{
  unsigned int max_field_x;
  unsigned int max_field_y;
  struct player_data *player;
  struct ball_data *ball;
};

struct game_data *init_game_data(void);
WINDOW *game_win(WINDOW *win, struct game_data *data);
WINDOW *stat_win(WINDOW *win, struct game_data *data);
int game(WINDOW *win1,WINDOW *win2);
int ball_inst(struct game_data *data);
void ball_launch(struct game_data *data);
void ball_move(struct game_data *data);
void menu();
void get_color();

int main(void){
  WINDOW *my_wins[2];
  srand(time(NULL));

  initscr();
  clear();
  curs_set(0);
  halfdelay(1);
  noecho();
  cbreak();
  get_color();


  menu();
  
  my_wins[0] = newwin(HEIGHT, WIDTH, STARTY, STARTX);
  my_wins[1] = newwin(HEIGHT - 6, WIDTH - 22, STARTY - 4, STARTX - 24);
  game(my_wins[0],my_wins[1]);
  
  endwin();
  return 0;
}

struct game_data *init_game_data(void){
  struct game_data *gd;
  
  gd = malloc(sizeof(struct game_data));
  if (gd == NULL) {
    return NULL;
  }
  gd->player = malloc(sizeof(struct player_data));
  if (gd->player == NULL) {
    free(gd);
    return NULL;
  }  
  gd->ball = malloc(sizeof(struct ball_data));
  if (gd->ball == NULL) {
    free(gd->player);
    free(gd);
    return NULL;
  }  


  gd->player->x = (WIDTH / 2) - (PADDLE_WIDTH / 2);
  gd->player->y = HEIGHT - 2;
  gd->player->deaths = 0;

  gd->max_field_x = HEIGHT;
  gd->max_field_y = WIDTH;

  gd->ball->x = gd->player->x + (PADDLE_WIDTH / 2);
  gd->ball->y = gd->player->y - 1;
  gd->ball->mv_left = false;
  gd->ball->mv_right = false;
  gd->ball->mv_up = false;
  gd->ball->mv_down = false;

  return gd;
}
WINDOW *game_win(WINDOW *win, struct game_data *data){
  werase(win);
  box(win, 0, 0);
  wbkgd(win, COLOR_PAIR(7));
  
  for(int i = 0; i < PADDLE_WIDTH; ++i)
    mvwaddch(win, data->player->y, data->player->x + i, '=');
  mvwaddch(win,data->ball->y, data->ball->x, 'o');
  wrefresh(win);
  return win;
}
WINDOW *stat_win(WINDOW *win, struct game_data *data){
  werase(win);
  box(win, 0, 0);
  wbkgd(win, COLOR_PAIR(7));
  
  attron(COLOR_PAIR(7));
  mvprintw(STARTY - 3, STARTX - 22, "Your position: %i", data->player->x);
  attroff(COLOR_PAIR(7));
  
  wrefresh(win);
  return win;
}
int game(WINDOW *win1,WINDOW *win2){
  char ch;
  struct game_data *gd;

  if ((gd = init_game_data()) == NULL) {
    mvprintw(0, 0, "Could not allocate memory for the game_data.");
    return -1;
  }
  refresh();
  game_win(win1, gd);
  stat_win(win2, gd);

  while((ch = getch()) != 10){
    switch(ch){
    case BACKWARD:
      if(gd->player->x > 1)
	--gd->player->x;
      break;
    case FORWARD:
      if(gd->player->x < (WIDTH - PADDLE_WIDTH) - 1)
	++gd->player->x;
      break;
    default:
      break;
    }
    ball_inst(gd);
    ball_move(gd);
    erase();
    refresh();
    game_win(win1, gd);
    stat_win(win2, gd);

  }

  return 0;
}
void draw_pong(){
  attron(COLOR_PAIR(7));
  mvprintw(STARTY - 4, STARTX + WIDTH / 4 + 2, " === PONG GAME === ");
  attroff(COLOR_PAIR(7));
}
void get_color(){
  if(has_colors() == FALSE){
    endwin();
    printf("Your terminal does not support color\n");
    exit(1);
  }
  start_color();
  init_pair(1, COLOR_GREEN, COLOR_WHITE);
  init_pair(2, COLOR_RED, COLOR_WHITE);
  init_pair(3, COLOR_BLUE, COLOR_WHITE);
  init_pair(4, COLOR_YELLOW, COLOR_WHITE);
  init_pair(5, COLOR_WHITE, COLOR_WHITE);
  init_pair(6, COLOR_MAGENTA, COLOR_WHITE);
  init_pair(7, COLOR_BLACK, COLOR_CYAN);
}
int ball_inst(struct game_data *data){
  if(data == NULL)
    return 1;
  
  if(data->ball->y == data->player->y - 1){
    if((data->ball->x >= data->player->x) &&
       (data->ball->x <= data->player->x + PADDLE_WIDTH)){
    
      data->ball->mv_left = false;
      data->ball->mv_right = false;
      data->ball->mv_up = true;
      data->ball->mv_down = false;

      if((data->ball->x < data->player->x + PADDLE_WIDTH / 2))
	data->ball->mv_left = true;

      if((data->ball->x > data->player->x + PADDLE_WIDTH / 2))
	data->ball->mv_right = true;
    }
  }
  
  if(data->ball->y == 1){
    data->ball->mv_up = false;
    data->ball->mv_down = true;
  }
  if(data->ball->y == data->player->y){
    data->ball->mv_left = false;
    data->ball->mv_right = false;
    data->ball->mv_up = false;
    data->ball->mv_down = false;
    
    ++data->player->deaths;

    ball_launch(data);
  }
  if(data->ball->x == 1){
    data->ball->mv_left = false;
    data->ball->mv_right = true;
  }
  if(data->ball->x == WIDTH - 2){
    data->ball->mv_left = true;
    data->ball->mv_right = false;
  }
  
  return 0;
}
void ball_move(struct game_data *data){
  if(data->ball->mv_left == true)
    --data->ball->x;

  else if(data->ball->mv_right == true)
    ++data->ball->x;

  if(data->ball->mv_up == true)
    --data->ball->y;

  else if(data->ball->mv_down == true)
    ++data->ball->y;
}
void ball_launch(struct game_data *data){
  char stop;
  
  while((stop = getch()) != ENTER)
    mvprintw(STARTY + 5, STARTX + WIDTH / 4 + 2, "Press ENTER to start");

  data->player->x = (WIDTH / 2) - (PADDLE_WIDTH / 2);
  data->player->y = HEIGHT - 2;
  
  data->ball->x = data->player->x + (PADDLE_WIDTH / 2) + 1;
  data->ball->y = data->player->y - 1;
  data->ball->mv_up = true;
  data->ball->mv_right = (rand() & 1);
  data->ball->mv_left = !data->ball->mv_right;
}
1

No bo czekasz na interakcję użytkownika jako główną zamiast traktować ją "w tle".

0

Pętla gry musi być niezależna od wejścia, dlatego potrzebne Ci jest non-blocking i/o

0

tylko jak takie non-blocking i/o zrobic, sprobowalem while(true) ale wtedy akcja za szybko sie dzieje i nie moge poruszac sie, podpowie ktos jak to zrobic ?

0

brutalnie będzie to wyglądało mniej-więcej tak:

if(keyboard_hitted())
    handle_input_key(get_keyboard_key());
0

A gdzie to dac ? Zamiast while czy co z tym dokladnie zrobic ? poza tym co znacza te funkcje ? nie moge znalezc w internecie

0

np spojrzcie na ten kod https://github.com/NearlyNeutral/pong/blob/master/pong.c <- on jest dosc podobny do mojego a petle loop ma prawie taka sama a jednak tu pilka lata niezaleznie od uzytkownika, co tutaj jest inaczej ??

0

Polecam czytać dokumentację bibliotek których się używa:
http://docs.oracle.com/cd/E36784_01/html/E36880/wgetch-3curses.html

In delay mode, the program waits until the system passes text through to the program. Depending on the setting of cbreak(), this is after one character (cbreak mode), or after the first newline (nocbreak mode). In half-delay mode, the program waits until a character is typed or the specified timeout has been reached.

https://docs.oracle.com/cd/E36784_01/html/E36880/halfdelay-3xcurses.html

The halfdelay() function is similar to cbreak(3XCURSES) in that when set, characters typed by the user are immediately processed by the program. The difference is that ERR is returned if no input is received after tenths tenths seconds.

0

Wiem, przeciez kombinowalem z halfdelay itp, nic mi nie pomoglo ;c nie wiem co z tym zrobic....

1 użytkowników online, w tym zalogowanych: 0, gości: 1