Create a Flash app using Union Platform,
* where you can collaborate with more than 4 people online.
*
* Particle Wrangler is a simple game that involves collecting
* many particles as you can.
*
* @author Painteroflight
* @date August 2009
* @location Los Angeles, USA
/**
* Copyright painteroflight ( http://wonderfl.net/user/painteroflight )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/40Wb
*/
// forked from checkmate's colin challenge for professionals
/**
* Create a Flash app using Union Platform,
* where you can collaborate with more than 4 people online.
*
* Particle Wrangler is a simple game that involves collecting
* many particles as you can.
*
* @author Painteroflight
* @date August 2009
* @location Los Angeles, USA
*/
package {
import __AS3__.vec.Vector;
import flash.display.*;
import flash.events.*;
import flash.filters.*;
import flash.geom.*;
import flash.ui.Keyboard;
import net.user1.reactor.*;
import net.user1.logger.Logger;
// The main application class
[SWF(width="250", height="250", frameRate="30", backgroundColor="0x1F1F1F")]
public class ParticleWrangler extends Sprite {
// Union objects
protected var reactor:Reactor;
protected var gameArenaRoom:Room;
// game management objects
protected var hunters:Vector.<Hunter>;
private var _BLUR:Boolean = false;
private var quarks:Vector.<Quark>;
private var background:Bitmap;
// Visual objects
protected var gameArenaSprite:Sprite;
// Constructor
public function ParticleWrangler () {
// Create the visuals
buildUI();
connectToServer()
}
// sets up the connection to the union socket server
protected function connectToServer():void {
// Make the UConnection object
reactor = new Reactor();
// Run readyListener() when the connection is ready
reactor.addEventListener(ReactorEvent.READY, readyListener);
// Connect to Union
reactor.connect("tryunion.com", 9100);
reactor.getLog().setLevel(Logger.DEBUG);
}
// Method invoked when the connection is ready
protected function readyListener (e:ReactorEvent):void {
// Create the application room
// use a unique identifier for your app
gameArenaRoom = reactor.getRoomManager().createRoom("wonderfl.ParticleWrangler");
// Listen for the ADD_NARUTO message from other users
gameArenaRoom.addMessageListener("ADD_NARUTO", addNarutoListener);
// Join the application room
gameArenaRoom.join();
}
// Creates the user interface
protected function buildUI ():void {
// Listen for key presses
stage.addEventListener(KeyboardEvent.KEY_UP,
keyUpListener);
// Create the game arena
gameArenaSprite = new Sprite();
addChild(gameArenaSprite);
background = new Bitmap(new BitmapData(stage.stageWidth, stage.stageHeight, true, 0x000000));
addChild(background);
// set up the quarks
quarks = new Vector.<Quark>;
for (var i:int = 0; i < Config._TOTAL_QUARKS; i++) {
quarks.push(new Quark(new Rectangle(30, 60, Config.GAME_ARENA_WIDTH - 30, Config.GAME_ARENA_HEIGHT), 5,
.25, Config.PALATTE[Math.floor(Math.random()*Config.PALATTE.length)]));
}
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
// Keyboard listener for outgoingMessages
protected function keyUpListener (e:KeyboardEvent):void {
// If the connection isn't ready, don't process
// key presses
if (!reactor.isReady()) {
return;
}
// If the 'n' key was pressed...
if (e.keyCode == 78) {
// ...add naruto to the bowl
gameArenaRoom.sendMessage("ADD_NARUTO",
true,
null);
}
}
// Method invoked when an ADD_NARUTO message
// is received from another user
protected function addNarutoListener (fromClient:IClient):void {
// If there are more than 15 pieces of naruto in the
// bowl already, remove the oldest one before adding
// the new one
if (gameArenaSprite.numChildren > 15) {
gameArenaSprite.removeChildAt(0);
}
// Add a new piece of Naruto to the bowl
var naruto:Hunter = new Hunter();
naruto.x = Math.floor(Math.random()*Config.GAME_ARENA_WIDTH);
naruto.y = Math.floor(Math.random()*Config.GAME_ARENA_HEIGHT);
gameArenaSprite.addChild(naruto);
}
protected function onEnterFrame(event:Event=null):void {
var rectangle:Rectangle;
var dp:Point;
if(!_BLUR) background.bitmapData = new BitmapData(background.width, background.height, true, 0x000000);
for (var i:int = 0; i < quarks.length; i++) {
quarks[i].onUpdate();
background.bitmapData.setPixel32(quarks[i].x, quarks[i].y, quarks[i].color);
}
if (_BLUR) {
// blur the new image
var bgFilter:BitmapFilter = new BlurFilter(2, 2, BitmapFilterQuality.MEDIUM);
rectangle = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
dp = new Point(0, 0);
background.bitmapData.applyFilter(background.bitmapData, rectangle, dp, bgFilter);
}
}
}
}
// CONFIGURATION DATA
class Config {
public static const GAME_ARENA_WIDTH:uint = 250; // width of game play area
public static const GAME_ARENA_HEIGHT:uint = 250; // height of game play area
public static const _TOTAL_QUARKS:uint = 1500;
public static const PALATTE:Vector.<uint> = Vector.<uint>([0xFFA3A948, 0xFFEDB92E, 0xFFF85931, 0xFFCE1836, 0xFF009989]);
}
// HUNTER CLASS :: creates the visual representation of the hunter
import flash.display.Sprite;
class Hunter extends Sprite {
public function Hunter (color:uint=0x000000) {
draw(color);
}
protected function draw (color:uint):void {
graphics.beginFill(color);
graphics.drawRect( -5, -5, 10, 10);
graphics.endFill();
}
}
import flash.events.Event;
internal class Quark
{
protected static const TARGET_DISTANCE_THRESHOLD:int = 10; // minimum distance in pixels quark must be from
// target point to trigger a reset of the target point
protected var _maxSpeed:Number; // max speed of quark in pixels
protected var _curSpeed:Number; // current speed of quark in pixels
protected var _acceleration:Number; // acceleration of quark in pixels
protected var _travelBounds:Rectangle; // the area that our quark must stay in
protected var _targetPoint:Point; // the point we are currently trying to get too
protected var _targetAngle:Number; // the angle in degrees between the quark and the target point
public var x:Number, y:Number, rotation:Number; // x and y coords as well as rotation of the quark
public var color:uint;
public function Quark(boundaries:Rectangle, maxSpeed:Number=3, acceleration:Number=.25, color:uint=0xff55ffff)
{
// set variables
_maxSpeed = maxSpeed;
_acceleration = acceleration;
_curSpeed = _maxSpeed;
_travelBounds = boundaries;
rotation = 90;
_targetPoint = new Point();
setTargetPoint();
x = _travelBounds.width / 2;
y = _travelBounds.height / 2;
this.color = color;
}
public function onUpdate(event:Event = null):void {
if (Math.abs(x - _targetPoint.x) > TARGET_DISTANCE_THRESHOLD && Math.abs(y - _targetPoint.y) > TARGET_DISTANCE_THRESHOLD) {
if (rotation != _targetAngle) {
rotation = rotation > _targetAngle ? rotation - _maxSpeed:rotation += _maxSpeed;
}
var v:Point = MoreMath.getVectorFromDegrees(_curSpeed, rotation);
x += v.x;
y += v.y;
}else {
setTargetPoint();
}
}
protected function setTargetPoint():void {
_targetPoint.x = _travelBounds.x + Math.round(Math.random() * (_travelBounds.width - _travelBounds.x));
_targetPoint.y = _travelBounds.y + Math.round(Math.random() * (_travelBounds.height - _travelBounds.y));
_targetAngle = MoreMath.VectorToAngleInDegrees(new Point(x, y), new Point(_targetPoint.x, _targetPoint.y));
}
}
import flash.geom.*;
internal class MoreMath {
//** PUBLIC STATIC CONSTS **\\
public static const DEG_TO_RAD:Number = Math.PI / 180;
public static const RAD_TO_DEG:Number = 180 / Math.PI;
public function MoreMath() {
throw new Error("MoreMath is a static class and cannot be instantiated.");
}
// returns the dot product of two vectors
public static function dot(v1:Point, v2:Point):Number {
return v1.x * v2.x + v1.y * v2.y;
}
// returns the normalized version of a supplied vector
public static function normalizeVector(vector:Point):Point {
var length:Number = getVectorLength(vector);
vector.x /= length;
vector.y /= length;
return vector;
}
// returns the length of a supplied vector
public static function getVectorLength(vector:Point):Number {
return Math.sqrt(vector.x * vector.x + vector.y * vector.y);
}
// returns a vector based on supplied angle (in degrees) and distance
public static function getVectorFromDegrees(distance:Number, angle:Number):Point {
return new Point(distance * Math.sin(angle * DEG_TO_RAD),- distance * Math.cos(angle * DEG_TO_RAD));
}
// returns the reflection vector of vector01 against normailised vector02
public static function reflectVector(vector01:Point,vector02:Point):Point {
var dp:Number = dot(vector01, vector02);
return new Point(vector01.x - 2 * dp * vector02.x,vector01.y - 2 * dp * vector02.y);
}
// returns an angle in degrees based off of two suplied vectors
public static function VectorToAngleInDegrees(vector01:Point, vector02:Point):Number {
return - Math.atan2(vector01.x - vector02.x,vector01.y - vector02.y) / DEG_TO_RAD;
}
}