itsukichang

フロントエンドが得意なエンジニア.ダーツと旅行とギターが好き

Daily Arduino×Flash #2

今回も距離センサ使っての作品.

前回よりもちょっと遊び要素があるよ.

#2 距離センサとゲーム

距離センサから読み取った値,つまり物体との距離を用いた入力で遊ぶゲーム.

ボールが8個並べられて,距離に応じて注目されるボールが変化する.(注目しているボールは色が薄くなる)
赤いボールに重なるように,センサと物体(手とか)の距離を変化させ,重なったら1ポイント.
10秒で何度重ねられるか.
といったシンプルなゲームです.

回路図

準備中なう.
(準備とか言ってるけど,ただ距離センサを5VとGNDとanalogInputに刺すだけだよ!111)

プログラム
  • Main.as
package {
	
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.utils.Timer;
	import flash.events.TimerEvent;
	import flash.events.Event;
	
	import funnel.*;
	import itsukichang.*;
	
	public class Main extends Sprite {
		
		private var _ballList:Vector.<Ball>;
		private var _ball:Ball;
		private var _oldAns:uint = 0;
		private var _ans:uint = 0;
		
		private var _cnt:uint = 0;
		private var _highScore:uint = 0;
		
		private var _label:Texts;
		private var _countText:Texts;
		private var _highScoreText:Texts;
		
		private var _nowTime:Number;
		private var _ansTime:Number = 10000;
		
		private var _playFlag:Boolean;
		
		private var _pin:Pin;
		private var _arduino:Arduino;
		private const MAX:Number = 70; //センサでとれる最大値
		private const N:Number = 70 / 8; //閾値
		private var _valueCnt:uint = 0;
		private var _sum:Number = 0;
		private var _value:Number = 0;
		
		public function Main() {
			_ballList = new Vector.<Ball>;
			_arduino = new Arduino(Arduino.FIRMATA);
			_pin = _arduino.analogPin(0);
			
			init();
		}
		
		private function init():void {
			textInit();
			for (var i:uint = 0; i < 10; i++) {
				_ball = new Ball(30, 0x333366);
				_ball.x = i * (stage.stageWidth / 8) - (stage.stageWidth / 16);
				_ball.y = stage.stageHeight / 2; //- _ball.height;
				_ballList[i] = _ball;
				addChild(_ballList[i]);
				
			}
			stage.addEventListener(MouseEvent.CLICK, onClick);
			
		}
		
		private function textInit():void {
			_label = new Texts("クリックでスタート!",30);
			_label.x = stage.stageWidth / 2 - _label.width / 2;
			_label.y = 300;
			addChild(_label);
			
			_countText = new Texts("",30);
			_countText.x = stage.stageWidth / 2 - _countText.width / 2;
			_countText.y = 270;
			addChild(_countText);
			_highScoreText = new Texts("",15);
			addChild(_highScoreText);
		}
		
		private function nextAns():void {
			do {
				_ans = Math.round(Math.random()*7) + 1;
				trace(_ans);
			} while(_ans == _oldAns);
			
			_ballList[_ans].colorTrans(0x990033);
			
			_ballList[_oldAns].colorTrans(0x333366);
			_oldAns = _ans;
		}
		
		private function onClick(e:MouseEvent):void {
			//_title.visible = false;
			if (!_playFlag) {
				_label.txt = "";
				_cnt = 0;
				_countText.txt = _cnt.toString() + "回";
				do {
					_ans = Math.round(Math.random()*7) + 1;
					trace(_ans);
				} while(_ans == _oldAns);
				
				_ballList[_ans].colorTrans(0x990033);
				_ballList[_oldAns].colorTrans(0x333366);
				_oldAns = _ans;
				stage.addEventListener(Event.ENTER_FRAME,onLoop);
				var d:Date = new Date();
				_nowTime = d.getTime();
				_playFlag = true;
			}
		}
		
		private function onLoop(e:Event):void {
			
			/*平均とってノイズ無くす*/
			if ( _valueCnt < 3) {
				_sum += _pin.value;
				_valueCnt++;
			} else {
				_valueCnt = 0;
				_value = (_sum / 3) * 100;
				_sum = 0;
			}
			
			//trace(_value); //debug
			var n = Math.round(_value / N) + 1;
			
			for (var i:uint = 1; i < 9; i++) {
				_ballList[i].alpha = 1.0;
			}
			
			_ballList[n].alpha = 0.3;
			_ballList[n-1].alpha = 0.6;
			_ballList[n+1].alpha = 0.6;
			
			if (n == _ans && _playFlag) {
				trace("ok!");
				nextAns();
				_cnt++;
				_countText.txt = _cnt.toString() + "回";
				_countText.x = stage.stageWidth / 2 - _countText.width / 2;
			}
			
			var d:Date = new Date();
			var rem:Number = (_ansTime - (d.getTime() - _nowTime));
			
			if (rem < 0) { //タイムが0になったら
				_label.txt = "そこまで!";
				endProcess();					
			} else {
				var sec:int = rem / 1000;
				var msec:int = (rem % 1000) / 10;
				_label.txt = sec + "." +  msec +  "秒";
			}
				_label.x = stage.stageWidth / 2 - _label.width / 2;
		}
		
		//終了後の処理
		private function endProcess():void {
			stage.removeEventListener(Event.ENTER_FRAME, onLoop);
			if (_cnt > _highScore) {
				_highScoreText.txt = "HIGI_SCORE: " + _cnt.toString();
			}
			_playFlag = false;
		}
	}
}
  • Ball.as
package {
	
	import flash.display.Sprite;
	
	public class Ball extends Sprite  {
		
		private var _col:uint;
		private var _r:Number;
		private var _sp:Sprite;
		
		public function Ball(r:Number = 10, col:uint = 0x0) {
			_r = r;
			_col = col;
			init();
		}
		
		private function init():void {
			_sp = new Sprite();
			_sp.graphics.beginFill(_col);
			_sp.graphics.drawCircle(0, 0, _r);
			_sp.graphics.endFill();	
			addChild(_sp);
		}
		
		public function colorTrans(col:uint):void {
			_col = col;	
			reDraw();
		}
		
		private function reDraw():void {
			_sp.graphics.clear();
			_sp.graphics.beginFill(_col);
			_sp.graphics.drawCircle(0, 0, _r);
			_sp.graphics.endFill();	
		}
	}
}
  • Texts.as
package itsukichang{
	
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.text.TextFieldAutoSize;
	
	public class Texts extends TextField {
		
		private var _s:String;
		private var _size:Number;
		private var _col:uint;
		
		public function Texts(s:String, n:Number = 10, col:uint = 0x0) {
			_s = s;
			_size = n;
			_col = col
			init();
		}
		
		private function init():void {
			this.defaultTextFormat = new TextFormat("", _size, _col);
			this.autoSize = TextFieldAutoSize.LEFT;
			this.text = _s;
		}
		
		public function set txt(s:String):void {
			this.text = s;
		}
	}
}
動作してる図(動画とか)




動画準備中なう (果たしてupされるかは不明)

wonderfl

マウスで操作するPC版も用意して,wonderflに上げてみた.
Arduino版だと,左右の移動を距離センサを使ってやるよ!

simpleGame - wonderfl build flash online

余談

昨日のやつもそうだけど,別に距離センサじゃなくてもアナログな値が取得できるものなら,なんでも遊べます.

距離センサ使うと,こう,手をブンブン動かして入力するので,なんか新鮮で楽しい気がするから使ってます.

それにしても

コードに頼り過ぎである^o^
回路の方ももっとなんか作り込みたいなー.


まぁ,入力方法(センサ)に応じた,楽しい演出(今回だとゲーム)を作るのも面白いから良いんだけど.