Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Starling MasterMind!

  • Loading branch information...
commit 83d47f09ba51100e8340fbf279acc85e1d392d6b 1 parent faad7c9
Patrick Devine authored
View
69 client/Game.as
@@ -0,0 +1,69 @@
+package
+{
+ import MovingPip;
+ import Vector2D;
+ import Menu;
+
+ import flash.display.Stage;
+ import flash.text.TextField;
+ import flash.events.Event;
+ import flash.events.MouseEvent;
+
+ import com.bit101.components.Component;
+ import com.bit101.components.List;
+ import com.bit101.components.Label;
+ import com.bit101.utils.MinimalConfigurator;
+
+ import starling.core.Starling;
+ import starling.display.Sprite;
+ import starling.events.Event;
+ import starling.events.TouchEvent;
+
+ public class Game extends Sprite
+ {
+ private var _pip:MovingPip;
+ private var _pips:Array;
+
+ public var myLabel:Label;
+
+ public function Game ()
+ {
+ _pips = new Array();
+
+ addEventListener(starling.events.Event.ADDED_TO_STAGE, onAddedToStage);
+ addEventListener(starling.events.Event.ENTER_FRAME, onEnterFrame);
+ }
+
+ private function onAddedToStage(event:starling.events.Event):void
+ {
+ for(var i:int = 0; i < 50; i++)
+ {
+ _pip = new MovingPip();
+ _pip.position = new Vector2D(Math.random() * stage.stageWidth, Math.random() * stage.stageHeight);
+ _pip.velocity = new Vector2D(Math.random() * 20 - 10, Math.random() * 20 - 10);
+
+ addChild(_pip);
+ _pips.push(_pip);
+ }
+
+ var nativeStage:flash.display.Stage;
+ nativeStage = Starling.current.nativeStage;
+
+ var myMenu:Menu = new Menu(nativeStage);
+ nativeStage.addChild(myMenu);
+
+ }
+
+ private function onEnterFrame(event:starling.events.Event):void
+ {
+ for(var i:int = 0; i < _pips.length; i++)
+ {
+ //_pips[i].flock(_pips);
+ _pips[i].wander();
+ _pips[i].update();
+ }
+ }
+
+ }
+}
+
View
22 client/MasterMind.as
@@ -0,0 +1,22 @@
+package
+{
+ import flash.display.Sprite;
+ import flash.display.StageAlign;
+ import flash.display.StageScaleMode;
+ import starling.core.Starling;
+
+ [SWF(width="1280", height="752", frameRate="60", backgroundColor="#ffffff")]
+ public class MasterMind extends Sprite
+ {
+ private var _starling:Starling;
+
+ public function MasterMind()
+ {
+ stage.align = StageAlign.TOP_LEFT;
+ stage.scaleMode = StageScaleMode.NO_SCALE;
+
+ _starling = new Starling(Game, stage);
+ _starling.start();
+ }
+ }
+}
View
1  client/MasterMind.html
@@ -0,0 +1 @@
+<embed src="MasterMind.swf" width=100% height=98% wmode='direct' />
View
74 client/Menu.as
@@ -0,0 +1,74 @@
+package
+{
+ import flash.display.Sprite;
+ import flash.display.Stage;
+ import flash.events.MouseEvent;
+
+ import com.bit101.components.Component;
+ import com.bit101.utils.MinimalConfigurator;
+ import com.bit101.components.Label;
+ import com.bit101.components.PushButton;
+ import com.bit101.components.List;
+
+ import flash.net.*;
+
+ public class Menu extends Sprite
+ {
+
+ public var myLabel:Label;
+ public var pushButton:PushButton;
+ public var gameList:List;
+
+ public var netConnection:NetConnection;
+ public var responder:Responder;
+
+ public function Menu(myStage:Stage):void
+ {
+ Component.initStage(myStage);
+
+ netConnection = new NetConnection();
+ netConnection.connect("http://192.168.137.156:8080");
+
+
+ var xml:XML = <comps>
+ <Panel x="10" y="10" width="200" height="500"/>
+ <VBox x="20" y="10">
+ <Label id="myLabel" text="Current Games"/>
+ <List id="gameList" width="170"/>
+ <PushButton id="pushButton" label="Select Game"/>
+ </VBox>
+ </comps>;
+
+ var config:MinimalConfigurator = new MinimalConfigurator(this);
+ config.parseXML(xml);
+
+ responder = new Responder(onComplete, onFail);
+ netConnection.call("mastermind.listGames", responder);
+
+ pushButton.addEventListener(MouseEvent.CLICK, onClick);
+ }
+
+ public function onClick(event:MouseEvent):void
+ {
+ trace("I'm clicked!");
+ }
+
+ public function onComplete(results):void
+ {
+ trace("success!");
+ for each (var thisGame in results)
+ {
+ trace(thisGame['_key'])
+ trace(thisGame);
+ gameList.addItem(thisGame['_key']);
+ }
+ }
+
+ public function onFail(results):void
+ {
+ trace("failed!");
+ trace(results);
+ }
+
+ }
+}
View
157 client/MovingPip.as
@@ -0,0 +1,157 @@
+package
+{
+ import starling.display.Sprite;
+
+ public class MovingPip extends Pip
+ {
+ private var _maxForce:Number = 1;
+ private var _steeringForce:Vector2D;
+ private var _arrivalThreshold:Number = 100;
+ private var _wanderAngle:Number = 0;
+ private var _wanderDistance:Number = 10;
+ private var _wanderRadius:Number = 5;
+ private var _wanderRange:Number = 1;
+ private var _inSightDist:Number = 200;
+
+ public function MovingPip()
+ {
+ _steeringForce = new Vector2D();
+ super();
+ }
+
+ public function set maxForce(value:Number):void
+ {
+ _maxForce = value;
+ }
+
+ public function get maxForce():Number
+ {
+ return _maxForce;
+ }
+
+ public function set arrivalThreshold(value:Number):void
+ {
+ _arrivalThreshold = value;
+ }
+
+ public function get arrivalThreshold():Number
+ {
+ return _arrivalThreshold;
+ }
+
+ public function set wanderDistance(value:Number):void
+ {
+ _wanderDistance = value;
+ }
+
+ public function get wanderDistance():Number
+ {
+ return _wanderRadius;
+ }
+
+ public function set wanderRange(value:Number):void
+ {
+ _wanderRange = value;
+ }
+
+ public function get wanderRange():Number
+ {
+ return _wanderRange;
+ }
+
+ override public function update():void
+ {
+ _steeringForce.truncate(_maxForce);
+ _steeringForce = _steeringForce.divide(_mass);
+ _velocity = _velocity.add(_steeringForce);
+ _steeringForce = new Vector2D();
+ super.update();
+ }
+
+ public function seek(target:Vector2D):void
+ {
+ var desiredVelocity:Vector2D = target.subtract(_position);
+ desiredVelocity.normalize();
+ desiredVelocity = desiredVelocity.multiply(_maxSpeed);
+ var force:Vector2D = desiredVelocity.subtract(_velocity);
+ _steeringForce = _steeringForce.add(force);
+ }
+
+ public function flee(target:Vector2D):void
+ {
+ var desiredVelocity:Vector2D = target.subtract(_position);
+ desiredVelocity.normalize();
+ desiredVelocity = desiredVelocity.multiply(_maxSpeed);
+ var force:Vector2D = desiredVelocity.subtract(_velocity);
+ _steeringForce = _steeringForce.subtract(force);
+ }
+
+ public function arrive(target:Vector2D):void
+ {
+ var desiredVelocity:Vector2D = target.subtract(_position);
+ desiredVelocity.normalize();
+
+ var dist:Number = _position.dist(target);
+ if(dist > arrivalThreshold)
+ desiredVelocity = desiredVelocity.multiply(_maxSpeed);
+ else
+ desiredVelocity =
+ desiredVelocity.multiply(
+ _maxSpeed * dist / arrivalThreshold);
+
+ var force:Vector2D = desiredVelocity.subtract(_velocity);
+ _steeringForce = _steeringForce.add(force);
+ }
+
+ public function flock(pips:Array):void
+ {
+ var averageVelocity:Vector2D = _velocity.clone();
+ var averagePosition:Vector2D = new Vector2D();
+ var inSightCount:int = 0;
+
+ for(var i:int = 0; i < pips.length; i++)
+ {
+ var pip:Pip = pips[i] as Pip;
+ if(pip != this && inSight(pip))
+ {
+ averageVelocity = averageVelocity.add(pip.velocity);
+ averagePosition = averagePosition.add(pip.position);
+ inSightCount++;
+ }
+ }
+ if(inSightCount > 0)
+ {
+ averageVelocity = averageVelocity.divide(inSightCount);
+ averagePosition = averagePosition.divide(inSightCount);
+ seek(averagePosition);
+ _steeringForce.add(averageVelocity.subtract(_velocity));
+ }
+ }
+
+ public function inSight(pip:Pip):Boolean
+ {
+ if(_position.dist(pip.position) > _inSightDist)
+ return false;
+ var heading:Vector2D = _velocity.clone().normalize();
+ var difference:Vector2D = pip.position.subtract(_position);
+ var dotProd:Number = difference.dotProd(heading);
+
+ if(dotProd < 0)
+ return false;
+
+ return true;
+ }
+
+ public function wander():void
+ {
+ var center:Vector2D =
+ velocity.clone().normalize().multiply(_wanderDistance);
+ var offset:Vector2D = new Vector2D(0);
+ offset.length = _wanderRadius;
+ offset.angle = _wanderAngle;
+ _wanderAngle += Math.random() * _wanderRange - _wanderRange * .5;
+ var force:Vector2D = center.add(offset);
+ _steeringForce = _steeringForce.add(force);
+ }
+ }
+}
View
272 client/Pip.as
@@ -0,0 +1,272 @@
+package
+{
+ import flash.display.Sprite;
+ import flash.display.BitmapData;
+
+ import starling.display.Sprite;
+ import starling.textures.Texture;
+ import starling.display.Image;
+
+ public class Pip extends starling.display.Sprite
+ {
+ protected var _edgeBehavior:String = BOUNCE;
+ protected var _mass:Number = 1.0;
+ protected var _maxSpeed:Number = 10;
+ protected var _position:Vector2D;
+ protected var _velocity:Vector2D;
+
+ public static const WRAP:String = "wrap";
+ public static const BOUNCE:String = "bounce";
+
+ public static const COLORS:Array = [
+ 0xecd078,
+ 0xd95b43,
+ 0xc02942,
+ 0x542437,
+ 0x53777a,
+ 0x9ead6a,
+ 0xe3933c,
+ 0xce30c3,
+ ];
+
+ private var _pipValue:int = 0;
+ private var _showValue:Boolean;
+ private var _selected:Boolean = false;
+
+ private static const EMPTY_COLOR:uint = 0xb0b0b0;
+ private static const EMPTY_RADIUS:uint = 10;
+ private static const COLORED_RADIUS:uint = 10;
+
+ public function Pip(pipValue:uint=0, _showValue:Boolean=true)
+ {
+ this._showValue = _showValue;
+ this.pipValue = pipValue;
+
+ _position = new Vector2D();
+ _velocity = new Vector2D();
+ }
+
+ private function drawEmptyPip():void
+ {
+ var pip:flash.display.Sprite = new flash.display.Sprite();
+
+ pip.graphics.beginFill(EMPTY_COLOR);
+ pip.graphics.drawCircle(EMPTY_RADIUS, EMPTY_RADIUS, EMPTY_RADIUS);
+ pip.graphics.endFill();
+
+ var bmd:BitmapData = new BitmapData(
+ EMPTY_RADIUS*2,
+ EMPTY_RADIUS*2,
+ true, 0x00000000);
+ bmd.draw(pip);
+
+ var texture:Texture = Texture.fromBitmapData(bmd, false, false);
+ var image:Image = new Image(texture);
+
+ addChild(image);
+
+ }
+
+ private function drawColoredPip():void
+ {
+ var pip:flash.display.Sprite = new flash.display.Sprite();
+
+ pip.graphics.clear();
+ pip.graphics.beginFill(COLORS[_pipValue]);
+ pip.graphics.drawCircle(0, 0, COLORED_RADIUS);
+ pip.graphics.endFill();
+
+ // XXX - pulse this?
+ if(_selected)
+ {
+ pip.graphics.lineStyle(1);
+ pip.graphics.drawCircle(0, 0, COLORED_RADIUS);
+ }
+
+ }
+
+ private function drawHiddenPip():void
+ {
+ var pip:flash.display.Sprite = new flash.display.Sprite();
+
+ pip.graphics.clear();
+
+ // can this be transparent?
+ pip.graphics.beginFill(0xffffff);
+ pip.graphics.drawRect(-5, -5, 10, 10);
+ pip.graphics.endFill();
+
+ pip.graphics.lineStyle(1);
+ pip.graphics.beginFill(0x000000);
+ pip.graphics.moveTo(-5, -5);
+ pip.graphics.lineTo(5, 5);
+ pip.graphics.moveTo(-5, 5);
+ pip.graphics.lineTo(5, -5);
+ pip.graphics.endFill();
+ }
+
+ public function set showValue(b:Boolean):void
+ {
+ _showValue = b;
+
+ if(_showValue)
+ drawColoredPip();
+ else
+ drawHiddenPip();
+ }
+
+ public function set pipValue(pipValue:uint):void
+ {
+ _pipValue = pipValue;
+
+ //graphics.clear();
+
+ if(!pipValue)
+ drawEmptyPip();
+ else
+ drawHiddenPip();
+
+ }
+
+ public function get pipValue():uint
+ {
+ return _pipValue;
+ }
+
+ public function set selected(b:Boolean):void
+ {
+ _selected = b;
+ drawColoredPip();
+ }
+
+ public function get selected():Boolean
+ {
+ return _selected;
+ }
+
+ public function update():void
+ {
+ _velocity.truncate(_maxSpeed);
+
+ _position = _position.add(_velocity);
+
+ if(_edgeBehavior == WRAP)
+ wrap();
+ else if (_edgeBehavior == BOUNCE)
+ bounce();
+
+ x = position.x;
+ y = position.y;
+
+ //rotation = _velocity.angle * 180 / Math.PI;
+ }
+
+ private function bounce():void
+ {
+ if(stage != null)
+ {
+ if(position.x > stage.stageWidth)
+ {
+ position.x = stage.stageWidth;
+ velocity.x *= -1;
+ }
+ else if(position.x < 0)
+ {
+ position.x = 0;
+ velocity.x *= -1;
+ }
+
+ if(position.y > stage.stageHeight)
+ {
+ position.y = stage.stageHeight;
+ velocity.y *= -1;
+ }
+ else if(position.y < 0)
+ {
+ position.y = 0;
+ velocity.y *= -1;
+ }
+ }
+ }
+
+ private function wrap():void
+ {
+ if(stage != null)
+ {
+ if(position.x > stage.stageWidth)
+ position.x = 0;
+ else if(position.x < 0)
+ position.x = stage.stageWidth;
+
+ if(position.y > stage.stageHeight)
+ position.y = 0;
+ else if (position.y < 0)
+ position.y = stage.stageHeight;
+ }
+ }
+
+ public function set edgeBehavior(value:String):void
+ {
+ _edgeBehavior = value;
+ }
+
+ public function get edgeBehavior():String
+ {
+ return _edgeBehavior;
+ }
+
+ public function set mass(value:Number):void
+ {
+ _mass = value;
+ }
+
+ public function get mass():Number
+ {
+ return _mass;
+ }
+
+ public function set maxSpeed(value:Number):void
+ {
+ _maxSpeed = value;
+ }
+
+ public function get maxSpeed():Number
+ {
+ return _maxSpeed;
+ }
+
+ public function set position(value:Vector2D):void
+ {
+ _position = value;
+ x = _position.x;
+ y = _position.y;
+ }
+
+ public function get position():Vector2D
+ {
+ return _position;
+ }
+
+ public function set velocity(value:Vector2D):void
+ {
+ _velocity = value;
+ }
+
+ public function get velocity():Vector2D
+ {
+ return _velocity;
+ }
+
+ override public function set x(value:Number):void
+ {
+ super.x = value;
+ _position.x = x;
+ }
+
+ override public function set y(value:Number):void
+ {
+ super.y = value;
+ _position.y = y;
+ }
+ }
+}
View
191 client/Vector2D.as
@@ -0,0 +1,191 @@
+package
+{
+ import flash.display.Graphics;
+
+ public class Vector2D
+ {
+ private var _x:Number;
+ private var _y:Number;
+
+ public function Vector2D(x:Number = 0, y:Number = 0)
+ {
+ _x = x;
+ _y = y;
+ }
+
+ public function draw(graphics:Graphics, color:uint = 0):void
+ {
+ graphics.lineStyle(0, color);
+ graphics.moveTo(0, 0);
+ graphics.lineTo(_x, _y);
+ }
+
+ public function clone():Vector2D
+ {
+ return new Vector2D(_x, _y);
+ }
+
+ public function zero():Vector2D
+ {
+ _x = 0;
+ _y = 0;
+ return this;
+ }
+
+ public function isZero():Boolean
+ {
+ return _x == 0 && _y == 0;
+ }
+
+ public function set length(value:Number):void
+ {
+ var a:Number = angle;
+ _x = Math.cos(a) * value;
+ _y = Math.sin(a) * value;
+ }
+
+ public function get length():Number
+ {
+ return Math.sqrt(lengthSQ);
+ }
+
+ public function get lengthSQ():Number
+ {
+ return _x * _x + _y * _y;
+ }
+
+ public function set angle(value:Number):void
+ {
+ var len:Number = length;
+ _x = Math.cos(value) * len;
+ _y = Math.sin(value) * len;
+ }
+
+ public function get angle():Number
+ {
+ return Math.atan2(_y, _x);
+ }
+
+
+ // set the length to 1
+ public function normalize():Vector2D
+ {
+ if(length == 0)
+ {
+ _x = 1;
+ return this;
+ }
+
+ var len:Number = length;
+ _x /= len;
+ _y /= len;
+ return this;
+ }
+
+ public function truncate(max:Number):Vector2D
+ {
+ length = Math.min(max, length);
+ return this;
+ }
+
+ public function reverse():Vector2D
+ {
+ _x = -_x;
+ _y = -_y;
+ return this;
+ }
+
+ public function isNormalized():Boolean
+ {
+ return length == 1.0;
+ }
+
+ // dot product
+ public function dotProd(v2:Vector2D):Number
+ {
+ return _x * v2.x + _y * v2.y;
+ }
+
+ public function angleBetween(v1:Vector2D, v2:Vector2D):Number
+ {
+ if(!v1.isNormalized())
+ v1 = v1.clone().normalize();
+ if(!v2.isNormalized())
+ v2 = v2.clone().normalize();
+
+ return Math.acos(v1.dotProd(v2));
+ }
+
+ public function sign(v2:Vector2D):int
+ {
+ return perp.dotProd(v2) < 0 ? -1 : 1;
+ }
+
+ public function get perp():Vector2D
+ {
+ return new Vector2D(-_y, _x);
+ }
+
+ public function dist(v2:Vector2D):Number
+ {
+ return Math.sqrt(distSQ(v2));
+ }
+
+ public function distSQ(v2:Vector2D):Number
+ {
+ var dx:Number = v2.x - _x;
+ var dy:Number = v2.y - _y;
+ return dx * dx + dy * dy;
+ }
+
+ public function add(v2:Vector2D):Vector2D
+ {
+ return new Vector2D(_x + v2.x, _y + v2.y);
+ }
+
+ public function subtract(v2:Vector2D):Vector2D
+ {
+ return new Vector2D(_x - v2.x, _y - v2.y);
+ }
+
+ public function multiply(value:Number):Vector2D
+ {
+ return new Vector2D(_x * value, _y * value);
+ }
+
+ public function divide(value:Number):Vector2D
+ {
+ return new Vector2D(_x / value, _y / value);
+ }
+
+ public function equals(v2:Vector2D):Boolean
+ {
+ return _x == v2.x && _y == v2.y;
+ }
+
+ public function set x(value:Number):void
+ {
+ _x = value;
+ }
+
+ public function get x():Number
+ {
+ return _x;
+ }
+
+ public function set y(value:Number):void
+ {
+ _y = value;
+ }
+
+ public function get y():Number
+ {
+ return _y;
+ }
+
+ public function toString():String
+ {
+ return "[Vector2D (x:" + _x + ", y:" + _y + ")]";
+ }
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.