チーム1913

課題名

BALL GAME

研究者名

Shota Yokoi
Takumi Yamaguchi

使用機器

PSoC基盤
PSoC MiniProg
シリアル変換ケーブル
ジャンパワイヤ
3軸加速度センサー(KXR94-2050)

概要

3軸加速度センサーを使用し、PSoC基盤のx軸方向の傾きを取得しシリアル通信を用いてPCに送ることでゲーム内のバーを操作できるようなアプリケーションを作成した。
3軸加速度センサーの値はTRIADCを利用してAD変換を行った。
以下にゲーム画面を載せる。

screenshot1.png

バーにボールが当たることでボールが跳ね返り、その回数がスコアとして表示される。

ソースコード(PSoC)

以下にPSocの構成とソースコードを示す。

screenshot3.png

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

void main(void)
{
  // M8C_EnableGInt ; // Uncomment this line to enable Global Interrupts
   // Insert your main routine code here.
   unsigned int adc_data;
   int x,y,z;
     char *strPtr, ePtr[7];
      UART_1_CmdReset();
      UART_1_IntCntl(UART_1_ENABLE_RX_INT); 
    UART_1_Start(UART_1_PARITY_NONE);
      Counter8_Start();
   PGA_1_Start(PGA_1_HIGHPOWER);
   PGA_2_Start(PGA_2_HIGHPOWER);
   PGA_3_Start(PGA_3_HIGHPOWER);
   LCD_Start();
   LCD_InitBG(LCD_SOLID_BG);
   M8C_EnableGInt;
   TRIADC_1_Start(TRIADC_1_HIGHPOWER);
    TRIADC_1_SetResolution(12);    
   TRIADC_1_GetSamples(0);
   for(;;)
   {
       while(TRIADC_1_fIsDataAvailable()==0);
       x = TRIADC_1_iGetData1();
       y = TRIADC_1_iGetData2();
       z = TRIADC_1_iGetData3ClearFlag();
       LCD_Position(0,0);
       LCD_PrHexInt(x);
       LCD_Position(1,0);
       LCD_PrHexInt(y);
          itoa(ePtr,x,10);
       UART_1_PutString(ePtr);
          UART_1_CPutString(",");
   }
}

ソースコード(Processing)

以下にPC側のProcessingのソースコードを示す。

float boll_x,boll_y,speedx,speedy;
int a,b,point,GAMEOVER_count,GAMEOVER_number,LIFE,startWordCount,mouseClickCount,quiteNumber;
String[] startWord = {"READY?"};

import processing.serial.*;
Serial port;
String rxBuffer;
String txBuffer;
int receive;
int BarWidth = 100;

int reverse=-1;
int bar_x;

void setup(){
printArray(Serial.list());
 port = new Serial(this, Serial.list()[1], 38400);
 
  size(400,600);
  bar_x=width/2;
 a=0;
 b=0;
 boll_x=0;
 boll_y=0;
 point=0;
 GAMEOVER_count=0;
 GAMEOVER_number=2;
 mouseClickCount=0;
 quiteNumber=0;
 speedx=1.0;
 speedy=5.0;
 
 rectMode(CENTER);
}
void draw(){
background(0,0,0,200);
 if(mouseClickCount==0) startWindow();
 else goGame();
}

void serialEvent(Serial p){
String myString = port.readStringUntil(',');
 if(myString == null){
   return;
 }
 String sensors[] = splitTokens(myString, ",");
 if (true){
   receive = int(sensors[0])*reverse;
   println(receive + ", ");
 }
}

void keyPressed(){
if(txBuffer == null){
   txBuffer = str(key);
 }else{
   txBuffer = txBuffer + key;
 }
 if(key == ENTER) {
   print(" Send ; " + txBuffer);
   port.write(txBuffer+"/r");
   txBuffer = null;
 }
}

void startWindow(){
title();
 startWord();
}


void title(){
fill(255);
 textAlign(CENTER);
 textSize(40);
 text("BALL GAME",width/2,height/3);
}

void startWord(){
fill(255);
 textAlign(CENTER);
 textSize(12);
 text("Click Screen",width/2,height*2/3);
}


void goGame(){
if(startWordCount >= startWord.length){
   aboutBall();
   game();
 }else{
   areYouReady();
   startWordCount++;
 }
}


void areYouReady(){
frameRate(1);
 textSize(100);
 textAlign(CENTER);
 text(startWord[startWordCount], width/2, height/2);
}


void game(){
frameRate(100);
 bar_x+=receive/100;
 if(bar_x>400 - BarWidth/2)bar_x=400 - BarWidth/2;
 if(bar_x<BarWidth/2) bar_x=BarWidth/2;
 if(a==0) boll_x+=speedx;
 
 if(boll_x>=width-5){
   a=1;
   speedx=random(3);
 }

 if(a==1) boll_x-=speedx;

 if(boll_x<=5){
   a=0;
   speedx=random(3);
 }

 if(b==0) boll_y+=speedy;
 
 if(boll_y>=height){
   boll_y=0;
   GAMEOVER_count++;
 }

 if(b==1) boll_y-=speedy;
 
 if(boll_y<=5){
   b=0;
   speedy=random(3,5);
 }

 if(boll_x>=bar_x-BarWidth/2+5 && boll_y>=565 && boll_y<=575 && boll_x<=bar_x+BarWidth/2+5){
   b=1;
  
   if(GAMEOVER_count<=GAMEOVER_number){
     point+=100;
     speedx=random(3);
     speedy=random(3,5);
   }
 }

if(boll_x>=bar_x-BarWidth/2+5 && boll_y>=565 && boll_y<=585 && boll_x<bar_x-10) a=1;
 if(boll_x>bar_x+10 && boll_y>=565 && boll_y<=585 && boll_x<=bar_x+BarWidth/2+5) a=0;
 if(boll_y>=575 && boll_x==bar_x-BarWidth/2+5 && boll_y<=585){
  a=0;
  b=1;
  if(GAMEOVER_count<=GAMEOVER_number) point+=100;
 }
 if(boll_y>=575 && boll_x==bar_x+BarWidth/2+5 && boll_y<=585){
   a=1;
   b=1;
   if(GAMEOVER_count<=GAMEOVER_number) point+=100;
 }
 
 GAMEOVER();
}


void aboutBall(){
noStroke();
 ellipse(boll_x,boll_y,10,10);
 fill(255);
 rect(bar_x,580,BarWidth,10);
}


void beforeGAMEOVER_Display(){
LIFE = GAMEOVER_number-(GAMEOVER_count-1);
 textSize(16);
 text("POINT:",40,20);
 text(point,100,20);
 text("LIFE:",140,20);
 text(LIFE,170,20);
}


void afterGAMEOVER(){
background(0);
 GAMEOVER_Comment();
 finishStar();
 reStartGame();
}


void GAMEOVER(){
if(GAMEOVER_count > GAMEOVER_number) afterGAMEOVER();
 else beforeGAMEOVER_Display();
}


void GAMEOVER_Comment(){
textAlign(CENTER);
 textSize(30);
 text("GAME OVER",width/2,height/3);
 text("GET",width/2-100,height/3+28);
 text(point,width/2,height/3+28);
 text("POINT",width/2+100,height/3+28);
}


void reStartGame(){
fill(255);
 textAlign(CENTER);
 textSize(12);
 text("You click screen and finish this game",width/2,height*2/3);
 quiteNumber=1;
}


void finishStar(){
frameRate(60);
 
}


void mouseClicked(){
mouseClickCount++;
 println(mouseClickCount);
 if(quiteNumber==1){
   exit();
 }
}

考察

3軸加速度センサを使用する際、加速度という言葉から水平方向の加速度を調べるセンサであると想像し、x軸とz軸方向の加速度を出すことでセンサーの傾きを計算することが出来ると考えた。
しかしセンサを傾けた際にx軸方向の加速度の値が常に大きい値のまま固定されることが分かった。そのため傾きを調べるときはx軸方向の加速度をセンサーから読み取るだけで利用することができる。加速度センサーで傾きを読み取ることが出来るのは重力がセンサーに力を加えているためであると考えられる。

  • 最終更新:2019-05-21 17:54:37

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

認証パスワード