2013/06/18

簡単なゲームを作ってみよう(1)

簡単なゲームを作ってみましょう。

まずはスプライトの画像を用意します。
なんとなくペンギンの絵を描いてみました。

ファミリーベーシックのペンペンに似てますが
微妙に違いますので気にしないで下さい。

画像のファイルはここからダウンロードできます。

Test5.c
#include <stdio.h>
#include <gb.h>

// タイルデータ
#include "PenguinSpr.c"

#define SPR_HERO        0
#define SPR_HERO_SHADOW 2

#define HERO_ACT_NONE      0
#define HERO_ACT_WALK      1
#define HERO_ACT_JUMP      2
#define HERO_ACT_MISS      3

//プレイヤ用構造体
struct st_hero {
 UBYTE act; //アクションno
 UBYTE x;   //X座標
 UBYTE y;   //Y座標
 UBYTE cnt; //汎用カウンタ
 UBYTE jmp; //ジャンプカウンタ
} hero;

//アニメ用テーブル
UBYTE ani_tiles[]={0, 4, 12, 20};

//ジャンプ用テーブル
#define JMPTBL_MAX     31
BYTE jmptbl[]={
   0, -2, -4, -6, -8, -9,-10,-11,-12,-12,-13,-13,-14,-14,-15,-15,
 -15,-15,-14,-14,-13,-13,-12,-12,-11,-10, -9, -8, -6, -4, -2,  0,
 };

UBYTE input;//キー入力用

void hero_ctrl();
void hero_disp();

void main()
{
 UBYTE i;//ループ用

 DISPLAY_OFF;// 画面全体を非表示
 HIDE_SPRITES;// スプライトを非表示

 SPRITES_8x16;// スプライトモードを8*16に設定
 set_sprite_data(0, 52, PenguinSpTileLabel); // タイルデータをスプライトとして設定(0番から52個)


 SHOW_SPRITES;// スプライトを表示
 DISPLAY_ON;// 画面全体を表示

 // 初期値を設定
 hero.act = 1;
 hero.x = 88;
 hero.y = 64;
 hero.cnt = 0;
 hero.jmp = 0;
 scry = 0;

 while (1) {// 無限ループ
  input = joypad();// キー入力
  
  hero_ctrl();//ペンギンコントロール
  hero_disp();//ペンギン表示
  
  delay(10);//10ミリ秒待つ
 }
}

//ペンギンコントロール
void hero_ctrl()
{
 // 右入力
 if (input & J_RIGHT && hero.x <  160) hero.x++;
 // 左入力
 if (input & J_LEFT  && hero.x >   16) hero.x--;
 // A入力
 if (input & J_A     && hero.jmp == 0 && hero.act == HERO_ACT_WALK) {
  hero.jmp = 1;//ジャンプ開始
  hero.act = HERO_ACT_JUMP;
  hero.cnt = 0;
 }
 //ジャンプ中
 if (hero.jmp > 0) {
  hero.jmp++;
  if (hero.jmp >= JMPTBL_MAX) {
   hero.jmp = 0;//ジャンプ終了
   hero.act = HERO_ACT_WALK;
   hero.cnt = 0;
  }
 }
}

//ペンギン表示
void hero_disp()
{
 UBYTE i;//ループ用
 UBYTE ani;//アニメ用

 //左右の2枚を表示
 for (i = 0; i < 2; i++) {
  //ペンギン表示
  ani = ani_tiles[(hero.act)] + (i*2) + ((hero.cnt/2) & 0x04);
  set_sprite_tile( SPR_HERO+i, ani);// スプライトを設定
  move_sprite( SPR_HERO+i, hero.x-8+(i*8), hero.y-16+jmptbl[(hero.jmp)]);// スプライトの座標を設定
  //影表示
  if (hero.act < HERO_ACT_MISS) {
   set_sprite_tile( SPR_HERO_SHADOW+i, 2);// スプライトを設定
   move_sprite( SPR_HERO_SHADOW+i, hero.x-8+(i*8), hero.y-3);// スプライトの座標を設定
  } else {
   //表示座標を画面外にすることで非表示にしている
   move_sprite( SPR_HERO_SHADOW+i, 0, 0);// スプライトの座標を設定
  }
 }
 //影の右側だけ左右反転
 set_sprite_prop( SPR_HERO_SHADOW+1, S_FLIPX);
 //カウンタをインクリメント
 hero.cnt++;
}

これでペンギンが左右に動き、Aボタンでジャンプします。
変数の一部をグローバル変数にして、ペンギン関連の変数は構造体にしました。
影の左側はset_sprite_prop関数で左右反転を指定しています。

C言語においてグローバル変数はあまり使うべきではないと言われたりしますが
メモリ容量の少ないゲームボーイでは、全体的に使用される変数は
グローバル変数にして使いまわしたほうがメモリ効率が良くなると考えられます。

0 件のコメント:

コメントを投稿