金子邦彦研究室プログラミングC/C++ でキーボード,マウス,テキスト描画(C/C++, Allegro 5 を使用)月面飛行ゲームの例u

月面飛行ゲームの例

 

Allegro サンプルプログラムです。

以下のように作成

#define ALLEGRO_STATICLINK
#include<stdio.h>
#include<allegro.h>
#include<stdlib.h>
#include<sys/time.h>
#include<allegro_ttf.h>
#include<allegro_primitives.h>

extern bool pressed_keys[ALLEGRO_KEY_MAX];
static ALLEGRO_FONT *font12;

/* WW and HH decide the window size and mountain size */
#define WW 320
#define HH 200

#define REFRESH_RATE 60
#define GRAVITY 0.06


/* window size */
static const int WIDTH = WW;
static const int HEIGHT = HH;

/* initial position and velocity */
static const double x00 = 0.0;
static const double y00 = 30.0;
static const double vx00 = 1.0;
static const double vy00 = 0.0;

/* for screen refresh */
static const double delta = 1.0/REFRESH_RATE;

/* engine power */
static const double power = 0.13;

/* engine power */
#define SKIP 8
static int mountain[(WW/SKIP)];

static int disp_orbit( double x, double y )
{
  al_draw_textf(font12, /* color */ al_map_rgb(0, 0, 0), /* x */ x,  /* y */ y, ALLEGRO_ALIGN_CENTER, "A" );
  // textout_centre_ex(screen, font, "A", x, y, /* color */ makecol(0,0,0), /* bg */ -1);
  return 0;
}

static int disp_right( double x, double y )
{
  al_draw_textf(font12, /* color */ al_map_rgb(0, 0, 0), /* x */ x + 8,  /* y */ y, ALLEGRO_ALIGN_CENTER, "<" );
  // textout_centre_ex(screen, font, "<", x + 8, y, /* color */ makecol(0,0,0), /* bg */ -1);
  return 0;
}

static int disp_left( double x, double y )
{
  al_draw_textf(font12, /* color */ al_map_rgb(0, 0, 0), /* x */ x - 8,  /* y */ y, ALLEGRO_ALIGN_CENTER, ">" );
  // textout_centre_ex(screen, font, ">", x - 8, y, /* color */ makecol(0,0,0), /* bg */ -1);
  return 0;
}

static int disp_upper( double x, double y )
{
  al_draw_textf(font12, /* color */ al_map_rgb(0, 0, 0), /* x */ x,  /* y */ y - 8, ALLEGRO_ALIGN_CENTER, "|" );
  // textout_centre_ex(screen, font, "|", x, y - 8, /* color */ makecol(0,0,0), /* bg */ -1);
  return 0;
}

static int disp_lower( double x, double y )
{
  al_draw_textf(font12, /* color */ al_map_rgb(0, 0, 0), /* x */ x, /* y */ y + 8, ALLEGRO_ALIGN_CENTER, "|" );
  // textout_centre_ex(screen, font, "|", x, y + 8, /* color */ makecol(0,0,0), /* bg */ -1);
  return 0;
}

static int draw_world( double x, double y, double vx, double vy, double ax, double ay )
{
  int i;

  disp_orbit( x, y );
  if ( ax < 0 ) disp_right( x, y );  
  if ( ax > 0 ) disp_left( x, y );  
  if ( ay < 0 ) disp_lower( x, y );  
  if ( ay > 0 ) disp_upper( x, y );  

  /* draw mountain */
  for ( i = 0; i < (WW/SKIP); i++ ) {
    al_draw_textf(font12, /* color */ al_map_rgb(0, 0, 0), /* x */ i * SKIP, /* y */ mountain[i], ALLEGRO_ALIGN_CENTER, "o" );
    // textout_centre_ex(screen, font, "o", /* x */ i * SKIP, mountain[i], /* color */ makecol(0,0,0), /* bg */ -1);
  }

  al_draw_textf(font12, /* color */ al_map_rgb(0, 0, 0), /* x */ 80, /* y */ 10, ALLEGRO_ALIGN_CENTER, "vx : %f3.2", vx );
  al_draw_textf(font12, /* color */ al_map_rgb(0, 0, 0), /* x */ 200, /* y */ 10, ALLEGRO_ALIGN_CENTER, "vy : %f3.2", vy );
  // textprintf_ex(screen, font, /* x */ 10, /* y */ 10, /* color */ makecol(0,0,0), /* bg */ -1, "vx : %f3.2", vx );
  // textprintf_ex(screen, font, /* x */ 80, /* y */ 10, /* color */ makecol(0,0,0), /* bg */ -1, "vy : %f3.2", vy );

  return 0;
}

static int input_handle( double *ax, double *ay )
{
  ALLEGRO_KEYBOARD_STATE ret_state;
  al_get_keyboard_state(&ret_state);

  if ( al_key_down(&ret_state, ALLEGRO_KEY_LEFT ) ) {
      (*ax) = power;
      (*ay) = 0;
  }
  else if ( al_key_down(&ret_state, ALLEGRO_KEY_RIGHT ) ) {
      (*ax) = (-1.0) * power;
      (*ay) = 0;
  }
  else if ( al_key_down(&ret_state, ALLEGRO_KEY_UP ) ) {
      (*ax) = 0;
      (*ay) = power;
  }
  else if ( al_key_down(&ret_state, ALLEGRO_KEY_DOWN ) ) {
      (*ax) = 0;
      (*ay) = (-1.0) * power;
  }
  else {
      (*ax) = 0;
      (*ay) = 0;
  }

  return 0;
}

static double my_random( int n )
{
  int i;
  double r;

  r = 0.0;
  for ( i = 0; i < n; i++ ) {
    r = r + ( (double)rand()/RAND_MAX );
  }

  return r;
}

static int set_srand_seed()
{
  struct timeval tv;
  struct timezone tz;
  gettimeofday( &tv, &tz );
  const int seed = tv.tv_sec + tv.tv_usec;

  srand( seed );
}

static int create_mountain()
{
  int r;
  double h;
  int i;
  const int DIST = 70;  /* distribution of mountain */
  const int H = HH / 8;     /* average height */

  mountain[0] = HEIGHT - my_random( 2 * H );
  set_srand_seed();

  for ( i = 1; i < (WW/SKIP); i++ ) {
    h = my_random( DIST ) - (DIST/2.0) - 1.0 + ( ( (double)HH - (double)mountain[i-1] ) / H );
    mountain[i] = mountain[i-1] + h;
  }
  for ( i = 1; i < (WW/SKIP); i++ ) {
    if ( mountain[i] >= HEIGHT  ) mountain[i] = HEIGHT;
  }

  return 0;
}

int main()
{
  /* you should always do this at the start of Allegro programs */
  if(!al_init()) {
    return -1;
  }

  /* set up the keyboard handler */
  al_install_keyboard();
  /* set up the mouse handler */
  al_install_mouse();
  /* set up fonts */
  al_init_font_addon();
  al_init_ttf_addon();

  /* set a graphics mode sized WWxHH */
  ALLEGRO_DISPLAY *display = NULL;
  display = al_create_display(WW, HH);
  if(!display) {
    return -1;
  }

  /* load font */ 
  font12 = al_load_font("/usr/share/fonts/truetype/freefont/FreeSans.ttf",12,0);
  al_clear_to_color(al_map_rgb(255, 255, 255)); // clears the screen to the selected color
  
  /* initialize */
  double x, y, vx, vy, ax, ay;

  x = x00;
  y = y00;
  vx = vx00;
  vy = vy00;

  create_mountain();

  ALLEGRO_EVENT_QUEUE *EventQueue;
  ALLEGRO_EVENT Event;
  bool Exit = false;
  EventQueue = al_create_event_queue();
  al_register_event_source(EventQueue, al_get_display_event_source(display));
  al_register_event_source(EventQueue, al_get_keyboard_event_source());
  al_register_event_source(EventQueue, al_get_mouse_event_source());

  while(Exit == false) {
      al_flip_display();
      // al_wait_for_event(EventQueue, &Event);
      al_clear_to_color(al_map_rgb(255, 255, 255)); // clears the screen to the selected color
      input_handle( &ax, &ay );

    vx = vx + ( ax * delta );
    vy = vy + ( ay * delta ) + ( GRAVITY / REFRESH_RATE );
    x = x + ( vx * delta );
    y = y + ( vy * delta );
   
    draw_world( x, y, vx, vy, ax, ay );
    // vsync();

    }

  al_destroy_display(display);
  return 0;
}

次の手順でコンパイル

g++ hoge.cc -I/usr/local/include/allegro5 -L/usr/local/lib -lallegro -lallegro_font -lallegro_ttf -lm

次の手順で実行

./a.out