チーム1315

課題名

私[i]、行きます!!!!

研究者名

2-15-52 福田将大
2-15-64 和久井貴幸

概要

加速度センサーとスイッチを用いた障害物を避けるゲーム。
ゲームはLCDに表示する。LCDの右方から障害物(*)が流れてくるので、自分のキャラ(i)を操作して避ける。
上下段には別々に障害物が流れてくる。
基本的にiはLCDの下段にいるので下段に流れてくる障害物を、スイッチを押し、iをジャンプさせることでかわす。
また、上段の障害物はジャンプしたときに当たってしまうことがあるため、当たらないように加速度センサーを傾け、iを左右に動かしてかわす。
一つの障害物をよけるごとにゲームスピードが上がっていく。
障害物に当たってしまったらGAME OVER!!となる。
一応30個の障害物をよけたらGAME CLEARED!!となる。

使用器具

PSoC本体 1個
PSoC MiniProg 1個
加速度センサー 1個
ジャンパー線 4本

ソースコード

#include <m8c.h> // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules
#define SW 0b00010000

void main()
{
int iResult1,horizon;
 int chara_posX = 0;
 int chara_posY = 1;
 int jumpcount = 0;
 int gamecount;
 int teki0 = 15;
 int teki1 = 15;
 unsigned char prtData;
 int score = 0;
 
 //INIT
 LCD_1_Start();
 PGA_1_Start(PGA_1_MEDPOWER);
 M8C_EnableGInt;                 // Enable global interrupts    
 TRIADC_1_Start(TRIADC_1_HIGHPOWER); // Turn on Analog section    
 TRIADC_1_SetResolution(12);       // Set resolution to 10 Bits    
 TRIADC_1_GetSamples(0);           // Start ADC to read continuously   
 
 //ゲームスタート時の傾きを水平とする
 while(TRIADC_1_fIsDataAvailable() == 0);  // Wait for data to be ready    
   iResult1 = TRIADC_1_iGetData1();          // Get Data from ADC Input1    
   horizon = iResult1;
   
   //ゲームループ部
   while(1)  
     {    
         LCD_1_Control(0x01); //LCDクリア
       
       //chara_posX
         if(gamecount % 4 == 0){
           while(TRIADC_1_fIsDataAvailable() == 0);  // Wait for data to be ready    
           iResult1 = TRIADC_1_iGetData1();          // Get Data from ADC Input1    
           if( iResult1 - horizon > 200 && chara_posX >0){
               chara_posX--;
           }
           if(horizon - iResult1 > 200 && chara_posX < 15){
               chara_posX++;
           }
       }
   
       //jump
       prtData = PRT1DR;
       if(prtData & SW && chara_posY == 1 && jumpcount == 0){
           chara_posY = 0;
           jumpcount++;
       }
       if(jumpcount == 19){
           chara_posY = 1;
       }
       //一度ジャンプすると着地後しばらくは再ジャンプできないようにする
       if(jumpcount ==25){
           jumpcount = 0;
       }
       if(jumpcount != 0){
           jumpcount++;
       }
       
       
       //判定
       if(chara_posY == 0 && chara_posX == teki0){
           gameover(score);
       }
       if(chara_posY == 1 && chara_posX == teki1){
           gameover(score);
       }
       
       //敵の動き
       if(gamecount % 6 == 0){
           teki0--;
       }
       
       if(gamecount % 10 == 0){
            teki1--;
       }

      //描画
       LCD_1_Position(chara_posY,chara_posX);
       LCD_1_PrCString("i");
       LCD_1_Position(0,teki0);
       LCD_1_PrCString("*");
       LCD_1_Position(1,teki1);
       LCD_1_PrCString("*");
       
       //判定
       if(chara_posY == 0 && chara_posX == teki0){
           gameover(score);
       }
       if(chara_posY == 1 && chara_posX == teki1){
           gameover(score);
       }
       
       
       //jumpの長さ
       if(chara_posY == 0){
           jumpcount++;
       }
       
       if(teki0 == 0){
           teki0 = 16;
           score++;
       }    
       if(teki1 == 0){
           teki1 = 16;
           score++;
       }
       //score30でクリア
       if(score == 30){
           gameclear();
       }
       
       //scoreが上がるにつれ、waitが短くなるのでゲームスピードが速くなる
       wait_ms(30-score);
       gamecount++;    //ゲーム内時刻
 }
}
void wait_ms(WORD ms)
{
for (; ms ;ms--) LCD_1_Delay50uTimes(20);
}

//ゲームクリア用のメソッド
void gameclear(void){
LCD_1_Control(0x01); //LCDクリア
LCD_1_Position(0,3);
       LCD_1_PrCString("GAME CLEARED!!");
       while(1);    //無限ループ
}

 void gameover(int score){
    LCD_1_Control(0x01); //LCDクリア
    while(1){
       LCD_1_Position(0,3);
       LCD_1_PrCString("GAME OVER!!");
       LCD_1_Position(1,3);
       LCD_1_PrCString("score");
       LCD_1_Position(1,9);
       
       //scoreは16進数で表示されるため、10以上はif文によって手動で表示
       if(score < 10 | | score > 30){
           LCD_1_PrHexInt(score);
       }
       else if(score == 10)LCD_1_PrCString("0010");
       else if(score == 11)LCD_1_PrCString("0011");
       else if(score == 12)LCD_1_PrCString("0012");
       else if(score == 13)LCD_1_PrCString("0013");
       else if(score == 14)LCD_1_PrCString("0014");
       else if(score == 15)LCD_1_PrCString("0015");
       else if(score == 16)LCD_1_PrCString("0016");
       else if(score == 17)LCD_1_PrCString("0017");
       else if(score == 18)LCD_1_PrCString("0018");
       else if(score == 19)LCD_1_PrCString("0019");
       else if(score == 20)LCD_1_PrCString("0020");
       else if(score == 21)LCD_1_PrCString("0021");
       else if(score == 22)LCD_1_PrCString("0022");
       else if(score == 23)LCD_1_PrCString("0023");
       else if(score == 24)LCD_1_PrCString("0024");
       else if(score == 25)LCD_1_PrCString("0025");
       else if(score == 26)LCD_1_PrCString("0026");
       else if(score == 27)LCD_1_PrCString("0027");
       else if(score == 28)LCD_1_PrCString("0028");
       else if(score == 29)LCD_1_PrCString("0029");
       else if(score == 30)LCD_1_PrCString("0030");    
   }
}

考察

自分のキャラや障害物の移動速度の設定が少し大変だった。
ジャンプの時間や再ジャンプまでの拘束時間の設定を行わないと、実質上永遠にジャンプし続けられるという状況になってしまった。
当たり判定を自分のキャラと障害物の移動行った後に行うと判定をすり抜けることがあった。したがって、自分のキャラの移動と障害物の移動の2回に分けて行うことで回避した。
加速度センサーは、ゲーム開始時の傾きを水平として認識するように設定した。

  • 最終更新:2013-05-14 16:25:59

このWIKIを編集するにはパスワード入力が必要です

認証パスワード