チーム1548

課題名

スカッシュゲームのコントローラー

研究者名

Hiroyuki Kaseda
Yoshiki Okada

使用している部品

PSoC
PSoCMiniprog
通信用ケーブル
3軸加速度センサー
ジャンパー線×6
LCDディスプレイ

概要

使用している3軸加速度センサーの1軸(Y軸)を利用することによって
動いている球を跳ね返すための板が左右に移動するようになっている。
また,PsoCのスイッチにクリック機能を付けた.
傾きの変位は起動時の値を基準値とし、その位置からどの程度傾きが発生しているかを検知している。
このため、3軸加速度センサーの基盤の初期値の違いに左右されない。

これらの値をprocessingで作ったスカッシュゲームに渡すことでコントローラーとなっている.

<スカッシュゲームの仕様>
レベル(1~4)が選択できるようになっていて、レベルが上がるほど跳ね返ってくる球の速度が速くなる。
レベルはレベル選択画面にて、センサーをある程度傾けるかキーボードの1~4を打つことで調整できるようになっている。

scoreは球を一度跳ね返すごとに100点ずつ加算されるようにしている。
scoreが500増加するごとにレベルが1上がる。
レベルの初期設定は1~4までだが増加するレベルは無限になっている。

game_display.png

main.c


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

#define SW 0b00010000

void User_Function(int iResult)

{

  char    pszData[7];
   
   iResult *= (5000/4096);

  LCD_1_Position(0,8);

  LCD_1_PrCString("Y:");

  itoa(pszData,iResult,10);

  LCD_1_PrString(pszData);

  LCD_1_PrCString("    ");

}

void main()
{
int x,defx;
 PRT1DR &= (~SW);
 LCD_1_Start();
 PGA_2_Start(PGA_2_MEDPOWER);
 UART_CmdReset();
 UART_IntCntl(UART_ENABLE_RX_INT);
 Counter8_WritePeriod(155);
 Counter8_WriteCompareValue(77);
 Counter8_Start();
 UART_Start(UART_PARITY_NONE);

M8C_EnableGInt;                 // Enable global interrupts
 ADCINC_1_Start(ADCINC_1_HIGHPOWER);
 ADCINC_1_GetSamples(0);
 
 while(ADCINC_1_fIsDataAvailable() == 0);
 defx = ADCINC_1_wClearFlagGetData() / 10; 
 
 for(;;)    
 {    
 
   while(ADCINC_1_fIsDataAvailable() == 0);  // Wait for data to be ready    
   x = ADCINC_1_wClearFlagGetData() / 10 - defx;
                                           // and clear data ready flag    
   User_Function(x);
   if(PRT1DR & SW){
       UART_SendData(127);
       PRT1DR &= (~SW);
       }
   else{
       UART_SendData(x);
     }
 }

}

processingのコード

import processing.serial.*;

float boll_x,boll_y,speed_x,speed_y,high,low;
int change_x,change_y,click;
int point;
String[] startCount ={"","3","2","1"};
int scIndex;
int level;
int inByte;
int lu;
Serial myPort;
void setup(){
size(400,600);
 lu=1;
 level = 1;
 click = 0;
 change_x = 0;
 change_y = 0;
 point = 0;
 speed_x = 1.0;
 speed_y = 5.0;
 rectMode(CENTER);
 printArray(Serial.list());
 myPort = new Serial(this,"COM4",38400);
}

void draw(){
background(0);
 while(myPort.available()>0){
   inByte = myPort.read();
   println(inByte);
 }
 if(click == 0) startWindow();
 else goGame();
}

void setlevel(){
 if(inByte >= 40 && inByte <= 126&& level < 4){
   level++;
 }
 else if(inByte >= 128 &&inByte <= 226 && level >1){
   level--;
 }
 if(keyPressed==true){
   if(key=='1') level=1;
   else if(key=='2') level=2;
   else if(key=='3') level=3;
   else if(key=='4') level=4;
 }
   switch(level){
     case 1:high=4;low=2;break;
     case 2:high=5;low=3;break;
     case 3:high=6;low=4;break;
     case 4:high=7;low=5;break;
     default:high=4;low=2;break;
   }
 }
void startWindow(){
title();
 startWord();
 setlevel();
  delay(250);
 if(inByte==127){
   click++;
 }
}
void title(){
fill(255);
 textAlign(CENTER);
 textSize(40);
 text("Game",width/2,height/2);
}

void startWord(){
fill(255);
 textAlign(CENTER);
 textSize(20);
 text("level:",width/2-100,height*2/3-28);
 text(level,width/2,height*2/3-28);
 textSize(15);
 text("Please Click",width/2,height*2/3);
}
void goGame(){
if(scIndex >= startCount.length){
   ball();
   game();
 }
 else{
   beforeGame();
   scIndex++;
 }
}

void beforeGame(){
frameRate(1);
 textSize(30);
 textAlign(CENTER);
 text(startCount[scIndex],width/2,height/2);
}


void ball()
{
noStroke();
 ellipse(boll_x,boll_y,10,10);
 fill(255);
 if(inByte >=60 && inByte <=126){
   inByte = 60;
 }
 else if(inByte == 127){
   click++;
 }
 else if(inByte >=128 && inByte >= 197){
   inByte = inByte - 256;
 }
 else if(inByte >= 128 &&inByte <= 197){
   inByte = -60;
 }
 rect(inByte*3+200,580,50,10);
}
void game()
{
frameRate(100);
 
 //atarihantei
 //x
 if(change_x==0) boll_x+=speed_x;
 if(boll_x>=width-5){
   change_x = 1;
   speed_x = random(low,high);
 }
 
 if(change_x == 1) boll_x-=speed_x;
 if(boll_x<=5){
   change_x = 0;
   speed_x =random(low,high);
 }
 
 //y
 //0 down
 if(change_y==0) boll_y +=speed_y;
 //gameover
 if(boll_y>=height){
   GameOver();
 }
 
 //1 up
 if(change_y==1) boll_y -=speed_y;
 
 // top
 if(boll_y<=5){
   change_y=0;
   speed_y = random(low,high);
 }
 if(inByte >=60 && inByte <=128){
   inByte = 60;
 }
 else if(inByte >=128 && inByte >= 197){
   inByte = inByte - 256;
 }
 else if(inByte >= 128 &&inByte <= 197){
   inByte = -60;
 }
 if(boll_x>=inByte*3+200-30 && boll_y>=565 && boll_y<=585 && boll_x<=inByte*3+200+30){
   change_y=1;
   point+=100;
   if(point == 500*lu){
     lu++;
     upLevel();
   }
 }
 if(boll_x>=inByte*3+200-30 && boll_y>=565 && boll_y<=585 && boll_x<inByte*3+200-10) change_x=1;
 if(boll_x>inByte*3+200+10 && boll_y>=565 && boll_y<=585 && boll_x<=inByte*3+200+30) change_x=0;
  if(boll_y>=575 && boll_x==inByte*3+200-30 && boll_y<=585){
  change_x=0;
  change_y=1;
  //point+=100;
  }
  if(boll_y>=575 && boll_x==inByte*3+200+30 && boll_y<=585){
   change_x=1;
   change_y=1;
   //point+=100;
  }
  
  textSize(16);
  text("Score:",40,20);
  text(point,100,20);
  text("level:",160,20);
  text(level,220,20);
}

void upLevel(){
high++;
 low++;
 level++;
}

void GameOver(){
background(0);
 printScore();
 gameEnd();
 if(inByte == 127){
   exit();
 }
}
void printScore(){
textAlign(CENTER);
 textSize(30);
 text("GameOver",width/2,height/3);
 text("Score:",width/2-100,height/3+28);
 text(point,width/2,height/3+28);
}

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


ブロック図

15482.png

考察

今回はy軸1方向のみの値を使ったが2軸使うことができればマウスの実装も可能になる.

今回作った装置は,スイッチ入力と加速度センサーの入力はポーリングによって受け付けているため,
2つ同時にデータを送信することができない.
そのため,スイッチのデータを使わない数字に割り当ててデータの送信を行っている.

割り込みを使用することができればスイッチの入力を別の方法で送れるのではないだろうかと考える.

またprocessingにおいては,PSoCコントローラーを使用すると震えるため時々scoreが一気に増加してしまうことが
ある.あたり判定をもっと厳密にすればこのような事態にはならないと考える

また,スコアを保存してランキングなどを設定することができれば,よりアプリなどに近づいたのではないかと考える.

  • 最終更新:2015-10-20 17:23:24

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

認証パスワード