Beautifl - Flash Gallery

Thumbnail : MultiSnakeGame
MultiSnakeGame
coppieee 2009-09-02 MIT License

再生するにはFlash Playerが必要です。デスクトップのブラウザでご覧ください。

// forked from checkmate's colin challenge for professionals

/**
 * やっぱネットワークするならゲームだろ!
 * ということで前のSnake Game「http://wonderfl.net/code/7f8f78663b1487a4dda53dcc7be1fc81ae6706f4」のリベンジ
 * 
 * Tweetでtwitterで「仲間を呼ぶ」ボタン
 * 勝手に「http://wonderfl.net/code/7bc146049d06410fea6c857e542597666671d1e6」を参考に追加した。
 * 
 * ローカル部分(Main)とネットワーク部分(UnionRamen)と完全に切り離せるのがウリ。
 * @author coppieee
 */

package {
	import com.bit101.components.PushButton;
	import flash.display.Sprite;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.net.navigateToURL;
	import flash.net.URLRequest;
	import flash.text.TextField;
	import flash.ui.Keyboard;
	import flash.utils.escapeMultiByte;
	import net.user1.reactor.*;
	import net.user1.logger.Logger;
	
	public class UnionRamen extends Sprite {
		protected var _reactor:Reactor;
		protected var _room:Room;
		private var _main:Main;
		public function UnionRamen ()
		{
			_main = new Main();
			_main.x = (465 -_main.width) / 2;
			addChild(_main);
			
			var twitButton:PushButton = new PushButton(this);
			twitButton.label = "Tweet";
			twitButton.x = (465 - twitButton.width) / 2;
			twitButton.y = (465 - twitButton.height);
			twitButton.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void {
				navigateToURL(new URLRequest("http://twitter.com/home/?status=" 
					+ escapeMultiByte("Let's Snake Game! http://wonderfl.net/code/912e5bbfb8bfc055345361cee2b222d2c8a182a8")
				));
			});
			
			_reactor = new Reactor();
			_reactor.addEventListener(ReactorEvent.READY, onReady);
			_reactor.connect("tryunion.com", 9100);
			//_reactor.getLog().setLevel(Logger.DEBUG);
			
			 Wonderfl.capture_delay( 15 );
		}
		
		private function onReady(e:ReactorEvent):void 
		{
			_main.addEventListener(PixelChangeEvent.PIXEL_CHANGE, function(e:PixelChangeEvent):void {
				_room.sendMessage("PICEL_GANGE", false, null, e.toDataString());
			});
			_main.addEventListener(PixelChangeEvent.PIXEL_CLEAR, function(e:PixelChangeEvent):void { 
				_room.sendMessage("PICEL_CLEAR", false, null, e.toDataString());
			});
			_room = _reactor.getRoomManager().createRoom("wonderfl.coppieee.MultiSnakeGame");
			//_room.addMessageListener("ADD_NARUTO", addNarutoListener);
			_room.addMessageListener("PICEL_GANGE", onPixelChangeMessage);
			_room.addMessageListener("PICEL_CLEAR", onPixelClearMessage);
			_room.join();
		}
		private function onPixelChangeMessage(from:IClient,data:String):void
		{
			trace(data);
			var buffer:/*String*/Array = data.split(",");
			var row:int = int(buffer[0]);
			var column:int = int(buffer[1]);
			var color:uint = uint(buffer[2]);
			trace(row, column, color);
			_main.setPixel(new Position(row, column), color);
		}
		private function onPixelClearMessage(from:IClient, data:String):void
		{
			var buffer:/*String*/Array = data.split(",");
			var row:int = int(buffer[0]);
			var column:int = int(buffer[1]);
			var color:uint = uint(buffer[2]);
			_main.clearPixel(new Position(row,column), color);
		}
		
	}
}
//pakage{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.ui.Keyboard;
	import frocessing.color.ColorHSV;
	
	class Main extends Sprite
	{
		private var _bitmapData:BitmapData;
		public static const LENGTH:int = 16;
		private static const BACKGROUND_COLOR:uint = 0x000000;
		private static const FOOD_COLOR:uint = 0xFFFFFF;
		
		private var _snake:Snake;
		private var _food:Position;
		public function Main():void
		{
			_bitmapData = new BitmapData(LENGTH, LENGTH, false, BACKGROUND_COLOR);
			var bitmap:Bitmap = new Bitmap(_bitmapData);
			bitmap.width = 16 * 27;
			bitmap.height = 16 * 27;
			addChild(bitmap);
			
			_snake = new Snake(Position.createRamdom());
			_food = Position.createRamdom();
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
			addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
			
		}
		
		
		private function onKeyDown(e:KeyboardEvent):void 
		{
			var angle:Angle = Angle.keyCodeToAngle(e.keyCode);
			if (!angle) { return; }
			_snake.nextAngle = angle;
		}
		private var _count:int = 0;
		private function onEnterFrame(e:Event):void
		{
			stage.focus = this;
			if (_count > 5)
			{
				_count = 0;
			
				var data:SnakeUpdateData = _snake.update();
				var nextColor:uint = getPixel(data.createPosition);
			
				if (data.deletePosition)
				{
					clearPixel(data.deletePosition, _snake.color);
					dispatchEvent(new PixelChangeEvent(PixelChangeEvent.PIXEL_CLEAR, data.deletePosition, _snake.color));
				}
				
				if (nextColor == FOOD_COLOR)
				{
					_snake.grow();
				}
				else if (nextColor != BACKGROUND_COLOR)
				{
					for each(var index:Position in _snake.indexs)
					{
						clearPixel(index, _snake.color);
						dispatchEvent(new PixelChangeEvent(PixelChangeEvent.PIXEL_CLEAR, index, _snake.color));
					}
					_snake = new Snake(Position.createRamdom());
					return;
				}
				dispatchEvent(new PixelChangeEvent(PixelChangeEvent.PIXEL_CHANGE, data.createPosition, _snake.color));
				setPixel(data.createPosition, _snake.color);
			}
			_count ++;
			
			if (getPixel(_food) != FOOD_COLOR)
			{
				_food = Position.createRamdom();
				setPixel(_food, FOOD_COLOR);
				dispatchEvent(new PixelChangeEvent(PixelChangeEvent.PIXEL_CHANGE, _food, FOOD_COLOR));
			}
		}
		public function clearPixel(p:Position, color:uint):void
		{
			if (getPixel(p) != color) { return; }
			_bitmapData.setPixel(p.column, p.row, BACKGROUND_COLOR);
		}
		public function getPixel(p:Position):uint
		{
			return _bitmapData.getPixel(p.column, p.row);
		}
		public function setPixel(p:Position, color:uint):void
		{
			_bitmapData.setPixel(p.column, p.row, color);
		}
	}
//}
import flash.geom.Point;
import flash.utils.Dictionary;
import flash.ui.Keyboard;
import frocessing.color.ColorHSV;
import flash.events.Event;
class Snake
{
	private static const COLOR:uint =  new ColorHSV(Math.random() * 360).value;
	public function get nextAngle():Angle { return _nextAngle; }
	public function set nextAngle(value:Angle):void
	{
		if ((value.row + _prevAngle.row) == 0 && (value.column + _prevAngle.column) == 0)
		{
			return;
		}
		_nextAngle = value;
	}
	private var _nextAngle:Angle = Angle.RIGHT;
	private var _prevAngle:Angle = Angle.RIGHT;
	public var indexs:/*Position*/Array;
	public const color:uint = COLOR;
	public function Snake(position:Position)
	{
		indexs = [];
		indexs.push(position);
	}
	public function update():SnakeUpdateData
	{
		_prevAngle = nextAngle;
		
		var nextHead:Position = nextAngle.add(indexs[indexs.length - 1]);
		
		indexs.push(nextHead);
		var data:SnakeUpdateData =  new SnakeUpdateData();
		data.createPosition = nextHead;
		if (_isGrowed)
		{
			_isGrowed = false;
			return data;
		}
		var tail:Position = indexs[0];
		indexs.shift();
		data.deletePosition = tail;
		return data;
	}
	private var _isGrowed:Boolean = false;
	public function grow():void
	{
		_isGrowed = true;
	}
}
class SnakeUpdateData
{
	public var createPosition:Position;
	public var deletePosition:Position;
	public function SnakeUpdateData(){}
}
class PixelChangeEvent extends Event
{
	public static const PIXEL_CHANGE:String = "pixelChange";
	public static const PIXEL_CLEAR:String = "pixelClear";
	
	public function toDataString():Object { return position.row+","+position.column+","+color; }
	public var position:Position;
	public var color:uint;
	public function PixelChangeEvent(type:String,position:Position,color:uint)
	{
		super(type);
		this.position = position;
		this.color = color;
	}
}
class Position
{
	public static function createRamdom():Position
	{
		return new Position(Main.LENGTH * Math.random(),Main.LENGTH *Math.random());
	}
	
	public function get row():int { return _row; }
	public function set row(value:int):void 
	{ 
		_row = value % Main.LENGTH;
		if (_row < 0) { _row += Main.LENGTH; }
	}
	public var _row:int;
	public function get column():int { return _column; }
	public function set column(value:int):void 
	{ 
		_column = value % Main.LENGTH;
		if (_column < 0) { _column += Main.LENGTH; }
	}
	public var _column:int;
	public function Position(row:int,column:int)
	{
		this.row = row;
		this.column = column;
	}
}
class Angle
{
	public static const LEFT:Angle = new Angle( 0, -1);
	public static const RIGHT:Angle = new Angle(0, 1);
	public static const UP:Angle = new Angle( -1, 0);
	public static const DOWN:Angle = new Angle(1, 0);
	
	public static function keyCodeToAngle(keyCode:int):Angle
	{
		return _angles[keyCode];
	}
	private static var _angles:Dictionary;
	
	//static initializer
	{
		_angles = new Dictionary();
		_angles[Keyboard.LEFT] = LEFT;
		_angles[Keyboard.RIGHT] = RIGHT;
		_angles[Keyboard.UP] = UP;
		_angles[Keyboard.DOWN] = DOWN;
	}
	
	public function get row():int { return _row; }
	private var _row:int;
	public function get column():int { return _column; }
	private var _column:int;
	public function Angle(row:int, column:int)
	{
		_row = row;
		_column = column;
	}
	public function add(p:Position):Position
	{
		return new Position(p.row + this.row, p.column + this.column);
	}
	public function toString():String
	{
		return "[Angle " + row + "," + column + "]";
		return "[Angle row:" + row + ",column:" + column + "]";
	}
}