Game Development with Flex and Action Script 3.0 -Baloon Shooter
What buddies, quiet excited about the title??Now I am going to narrate how i have developed a simple game with flex.
Development of Game Characters :
In this Game we have three game characters they are Balloon,Bow and Arrow.The Balloon.as Class is the balloon object which is formed by drawing a ellipse with a tail.The Balloon class has also motion associated with it and also a method to burst the balloon.In burst balloon we have redrawn the ellipse and changed the motion towards the land.
Next comes the Bow.as class which serves as a Bow on screen.This Object is made by drawing a curve and line(String to pull).The Bow Contains the pull Arrow method which makes the string line to curve based on the value that is passed.
Then we have the Arrow.as class which forms the Arrow object .This is also done by drawing line and then a triangle like appearance at the left end.
Development Of the Game Field
We have all the Game Objects in our hand and now we have to develop the field to put these objects together to watch the action.For this we have the BalloonField.mxml which has everything to make this happen.
In the Balloon Field I have a set Timer method which is going to generate balloons at equal intervals starting from random positions and with random speed.
Balloon Movement
On every Tick of the Timer tick method will be called which creates balloon instances with move effect from bottom to top with random durations.The reference of each move associated with a balloon will be tagged with associated balloon so that when the balloon bursts that tagged move effect’s moveYTo property will be changed to the height of application so that it starts moving downwards.
On every end of the balloon’s move effect(after that has been out of the screen ) that balloon object will be removed from the stage.
Bow and Arrow Pulling
When you press CTRL key loadArrow method will be called which creates a Arrow instance and a move effect instance will be associated with the arrow.The move effect will be moving the arrow from left to right.Like in case of Balloon Movement, in Arrow Movement also when the move effect is completed for the arrow the arrow is removed from the stage.
After loading the arrow when u hold space for some time u can see the bow’s string pulling the arrow producing a real effect of arching.You know how this has been done??I have started a timer on key down event and i am drawing a curve for a specified radius and on key up event the timer is stopped and the curve is again redrawn as a line .
When the timer is stopped the bow is brought back to normal state and the arrow is launched with the speed proportional to the “SPACE BAR” key holding time.
Collision Detection
The collision detection part in this game is done by maintaining two separate collections for holding the enemy(balloon here..) and the other for holding the weapon(arrow).
Then on Enterframe event the two enemy and weapon collection are checked with each other for their positions(x and y) for overlapping or touching each other.If they do so,then the enemy object (i.e balloon ) is said to get hit and hence at this stage the balloon is said to burst and fall downwards.
This may also have bugs, i will soon test it and publish a new version.
Game Instructions
- Press CTRL to load arrow
- Press and Hold SPACE bar to pull the arrow
- Release SPACE Bar to shoot at the target.
Any comments to improve the game and any better algorithm for collision detection are welcome.
Cheers.
Digital Clock in Flex
Hi Friends,
I have a class called seven segment display which contains seven segments to display a digit.The Digital clock has six seven segment display to display the time.In Digital clock class we have a timer which fetches system time and separates the hours,minutes and seconds and displays it in the respective seven segment display ,this is repeated for every 992 milli seconds ,which simulates a digital Clock.
Analog Clock In Flex
Hi Folks,
Here comes the analog clock in Flex,in this i have a component called wall clock in which we have a circle,minutes hand,hours hand and seconds hand.
Each Hands of the clock is a line drawn from the center of the circle to the circumference at an angle.The following post http://www.flashandmath.com/ helped me in drawing a line with specified angle.
The seconds hand line will be drawn and cleared every second,since the full angle in a circle is 360 and the no of seconds per minute is 60 for each second, the seconds hand line will be drawn with an incremented angle of 6 degrees.
The seconds hand keeps on ticking and when 60 ticks have been completed the tickcounter angle will be 180 so at that time i have increased the angle of minute hand to another 6 degrees.This Continues so that minute hand is moved at the rate of 6 degrees per minute.
The Hours hand is moved at the rate of 6 degree per 12 minutes.
Flex Event Calender
Hi Folks,
I have build a Event Calender based on the Dynamic calender at http://www.thetechlabs.com/.
The Dynamic calender has all the basic operations of a calender ,but i have added some more features to it.
Features Added :
- Drag and Drop support in Month View to switch events from one date to another date
- Editing Events Time line in the Day View and Week View by Dragging the Event panel
- Added New pop up for adding new events.
- Components working speed has been improved
- Multiple Events can be shown on the month view
Month View
Note
You can Drag the Event Panel in the Day View and keep wherever on the time line,and also you can re size the event panel on the Time Line according to the Interval of the event.
Click on the Month Cell to get Pop up for adding a new event and u can select the added event to go the day view for the particular date.
If a Single Day contains more Events then a more Button is introduced in which when u click on can get the entire events for that day.
View Demo Selva’s EventCalender
Download Source Selva’s EventCalender Src
This is a alpha release with some bugs check here for the next beta release.
Day View
Column Chart with Dashed Bars in Flex
Here comes the Column Chart with Dashed column series .In this i have a class dashed.as which is used to draw rectangle with dashed lines
DashedFill.as is the custom fill written to show dashed bars in the chart.Dashed fill must implement the IFill Interface in which the beginFill method is implemented to draw dashed rectangles using the static method drawRect of the dashed class.
You must pass the target Graphics as first parameter to drawRect and an object with style properties to customize the border and fill color of the dashed bar .
ScreenShot
Filling Series with Stroked Lines in Flex Charts
Hi folks,
I had an requirement saying to fill the column series with stroked lines.I tryed googling but it doesn’t helped ,hence i have developed my own fill to draw stroked lines inside the column series.
StrokeFill.as
package com.customcomponents
{
import flash.display.Graphics;
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;
import flash.geom.Rectangle;
import mx.graphics.IFill;
public class StrokeFill extends EventDispatcher implements IFill
{
public function StrokeFill(target:IEventDispatcher=null)
{
super();
}
public function begin(target:Graphics, rc:Rectangle):void
{
target.clear();
target.lineStyle(1,0×000000,1);
var j:int=0;
var i:int=0;
var yIncrement:int=rc.height/8;
var xIncrementer:int=rc.width/8;
for(i=0;i<rc.height;i=i+yIncrement)
{
target.moveTo(j,0);
target.lineTo(0,i);
if(j<rc.width)
j=j+xIncrementer;
}
var z:int=0;
var s:int=yIncrement;
j=rc.width;
while(s<rc.height)
{
target.moveTo(z,i);
target.lineTo(j,s);
i=i+xIncrementer;
if(z<rc.width)
z=z+xIncrementer;
s=s+yIncrement;
}
target.lineStyle(1,0×000000,1);
//target.moveTo(j-5,0);
target.drawRect(0,0,rc.width,rc.height);
rc.width=0;
}
public function end(target:Graphics):void
{
}
}
}
To write a fill we must implement the IFill interface and in the beginFill method i have drawn a rectangle with specified height and width according to the data.Then i have divided the width and height by 8 to get the incrementers for x and y positions ,so that 8 lines will be drawn along the width of the bar.
First 8 lines are drawn from the top of the bar to the bar height by incrementing the x and y positions by the repective incrementors so that the first half of the bar is filled then again in the while loop iam filling the second half by moving to the bottom left position and drawing lines till the bottom right .
Custom Slider Showing values on thumb
Hi all,
Just check out my Custom slider for flex with the valus shown on and above the thumb.
I have a Custom Slider in which the create children method has been overriden to add a label and its x and y positions are set.A listner for Mouse button up has been written to update the value of the label.Once the top label value is updated a custom event called ThumbUpdateEvent is triggered to notify the change in the value.
I have a slider thumb skin in which a uitextfield is used to display the value inside the thumb.The uitextfield is set when the ThumbUpdateEvent is dispatched.
CustomSlider.as
package com
{
import flash.events.MouseEvent;
import mx.controls.Label;
import mx.controls.sliderClasses.Slider;
import mx.controls.sliderClasses.SliderThumb;
import mx.core.mx_internal;
use namespace mx_internal;
public class CustomSlider extends SliderThumb
{
public var lab:Label;
public var ob:Array;
public var num:int;
public var index:int;
public function CustomSlider()
{
super();
this.addEventListener(MouseEvent.MOUSE_UP,onMouseUp);
this.width=20;
this.setStyle(“fontSize”,12);
this.setStyle(“Color”,”red”);
}
private function onMouseUp(evt:MouseEvent):void{
ob=Slider(owner).values;
num=ob[thumbIndex]
this.index=thumbIndex;
lab.text=num.toString();
//this.label=num.toString();
this.dispatchEvent(new ThumbUpdateEvent(ThumbUpdateEvent.Updated,num,true));
//Alert.show(ob.toString());
}
override protected function createChildren():void
{
if(!lab)
{
lab=new Label();
lab.x=-10;
lab.y=-20;
lab.width=100;
lab.height=100;
lab.setStyle(“color”,”blue”);
this.addChild(lab);
}
}
}
}
ThumbUpdateEvent.as
package com
{
import flash.events.Event;
public class ThumbUpdateEvent extends Event
{
public static var Updated:String=”Updated”;
public var ThumbVal:int;
public function ThumbUpdateEvent(type:String,Value:int, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
this.ThumbVal=Value;
}
}
}
Custom TimeInput(24 hrs) with TimeValidator in Flex
Hi all,
here comes the custom TimeInput for flex with time validator,I have Timevalidator.as extending Validator which validates for the 24 hrs Time format.
The CustomText.as extending the TextInput has overridden keyboardup and keyboarddown handlers in which the left and right arrow key cases are set to select the text .
Note that the delete and backspace keys doesnot have any effects as these keys are restricted by making the focus null during keyDown and again setting the focus in the text during keyUp
Screenshot
CustomText.as
package com
{
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import mx.controls.Alert;
import mx.controls.TextInput;
import mx.events.FlexEvent;
import mx.events.ValidationResultEvent;
public class CustomText extends TextInput
{
public var nameStr:String;
private var valid:TimeValidator;
private var _text:String;
private var selectionStart:int=0;
private var selectionEnd:int=0;
public var validTime:Function=new Function();
public var inValidTime:Function=new Function();
public function CustomText()
{
super();
this.maxChars=8;
this.addEventListener(FlexEvent.CREATION_COMPLETE,assignValues);
this.restrict=”0-9″;
valid=new TimeValidator();
valid.source=this;
valid.property=”text”;
valid.addEventListener(ValidationResultEvent.VALID,validTime);
valid.addEventListener(ValidationResultEvent.INVALID,inValidTime);
}
override public function set text(value:String):void
{
if(this.textField)
{
_text=value;
this.textField.text=value;
dispatchEvent(new Event(“textChanged”));
invalidateProperties();
invalidateSize();
invalidateDisplayList();
dispatchEvent(new FlexEvent(FlexEvent.VALUE_COMMIT));
}
}
override public function get text():String
{
if(textField)
return textField.text;
else
return “”;
}
private function assignValues(e:FlexEvent):void
{
this.text=”00:00:00″;
this.setFocus();
selectionStart=0;
selectionEnd=2;
this.setSelection(selectionStart,selectionEnd);
}
private function validRes(e:ValidationResultEvent):void
{
Alert.show(e.toString());
}
private function invalidRes(e:ValidationResultEvent):void
{
Alert.show(“invalid”);
}
override protected function keyDownHandler(event:KeyboardEvent):void
{
switch (event.keyCode)
{
case Keyboard.BACKSPACE:
stage.focus=null;
break;
case Keyboard.DELETE:
stage.focus=null;
event.preventDefault();
break;
case Keyboard.RIGHT:
if(selectionStart<=6)
{
selectionStart=selectionStart+3;
selectionEnd=selectionEnd+3;
}
else
{
selectionStart=6;
selectionEnd=8;
}
this.setSelection(selectionStart,selectionEnd);
break;
case Keyboard.LEFT:
if(selectionStart>0)
{
selectionStart=selectionStart-3;
selectionEnd=selectionEnd-3;
}
else
{
selectionStart=0;
selectionEnd=2;
}
this.setSelection(selectionStart,selectionEnd);
break;
case Keyboard.ENTER:
{
dispatchEvent(new FlexEvent(FlexEvent.ENTER));
break;
}
}
}
override protected function keyUpHandler(event:KeyboardEvent):void
{
switch(event.keyCode)
{
case Keyboard.BACKSPACE :
stage.focus=this;
this.setFocus();
break;
case Keyboard.DELETE :
stage.focus=this;
this.setFocus();
break;
}
}
override public function setFocus():void
{
this.setSelection(selectionStart,selectionEnd);
textField.setFocus();
}
}
}
TimeValidator.as
package com
{
import mx.controls.Alert;
import mx.validators.ValidationResult;
import mx.validators.Validator;
public class TimeValidator extends Validator
{
private var results:Array;
public function TimeValidator()
{
super();
}
override protected function doValidation(value:Object):Array
{
var str:String=value.toString();
results=super.doValidation(value);
if(int(str.slice(0,2))>=24)
{
results.push(new ValidationResult(false,null,”not a valid hour”,”Enter Hours less than 24″));
}
else if(int(str.slice(3,5))>=60)
{
results.push(new ValidationResult(false,null,”not a valid minute”,”Enter Minute less than 60″));
}
else if(int(str.slice(6,8))>=60)
{
results.push(new ValidationResult(false,null,”not a valid second”,”Enter Seconds less than 60″));
}
return results;
}
}
}
It may have bugs too ,so ill update a cleaner one soon
RobotLegs Framework Sample Application
Hi Everybody,
I have found one interesting framework for Flex/AS3 Applications called Robotlegs[http://www.robotlegs.org/].
It helps in wiring Objects together and also it handles dependency injection with its meta tags so that it helps to organize our code well.
Here comes the Structure of a Robotlegs application
for architectural flow diagram chkout[http://www.robotlegs.org/diagram/]
Context
Model
View
Mediator
Events
Command
Services
I have Done A Simple login page using Robot legs here comes a short description of each part in it.
View:
The View Part Contains Main View and LoginPanel
Mediator
In Mediator the Views are Injected and listeners are added in mediators andevent is dispatched from the mediator according to the user interaction.Here the main view listens for the login complete event through the context listener
Events
Here Events are normal Flex events that can be triggered from any places.
Context
Context is a Place Where we map events with commands and views with mediators and also specify rules for dependence injection.
Command
A command is mapped with a event in context so that the execute method of command gets called whenever that event is triggered.
Service
A service is called from the execute method of command and the results are handled in the service itself.Note that service should always implement an interface.In the result handler of the service again events are triggered to notify the arrival of data to process.
In this Application When the login complete event is triggered after service call the main view which is listening for this event updates the view.
For More Info Comment Here or Log on to http://www.robotlegs.org/
Custom Preloader (Download Progressbar)
MyPreload.as
package preload
{
import flash.display.DisplayObject;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.ProgressEvent;
import flash.filters.DisplacementMapFilterMode;
import flash.text.TextField;
import flash.utils.getTimer;
import mx.controls.Alert;
import mx.events.FlexEvent;
import mx.events.RSLEvent;
import mx.graphics.RoundedRectangle;
import mx.preloaders.IPreloaderDisplay;
public class Mypreload extends Sprite implements IPreloaderDisplay
{
private var _stageHeight:Number = 375;
private var _stageWidth:Number = 500;
private var _backgroundAlpha:Number;
private var _backgroundColor:uint;
private var _backgroundImage:Object;
private var _backgroundSize:String = “”;
private var _preloader:Sprite;
private var percentLoadedtext:TextField;
[Bindable]
private var bytesLoaded:uint;
[Bindable]
private var bytesTotal:uint;
private var _startTime:int;
private var _xOffset:Number = 20;
private var _yOffset:Number = 20;
private var progressOffSet:Number=10;
private var te:int=0;
//private var g:Shape=new Shape();
private var g:Sprite;
private var _borderRect:RoundedRectangle = borderRect;
private var percentLoaded:uint;
private var fillWidth:uint;
protected function get borderRect():mx.graphics.RoundedRectangle
{
return new RoundedRectangle(14, 39, 154, 200, 0);
}
public function initialize():void
{
_startTime = flash.utils.getTimer();
center(stageWidth,stageHeight);
}
protected function center(width:Number, height:Number):void
{
_xOffset = Math.floor((width – _borderRect.width) / 2);
_yOffset = Math.floor((height – _borderRect.height) / 2);
}
public function Mypreload()
{
super();
g=new Sprite();
}
public function get backgroundAlpha():Number
{
return _backgroundAlpha;
}
public function set backgroundAlpha(value:Number):void
{
_backgroundAlpha=value;
}
public function get backgroundColor():uint
{
return _backgroundColor;
}
public function set backgroundColor(value:uint):void
{
_backgroundColor=value;
}
public function get backgroundImage():Object
{
return _backgroundImage;
}
public function set backgroundImage(value:Object):void
{
_backgroundImage=value;
}
public function get backgroundSize():String
{
return _backgroundSize;
}
public function set backgroundSize(value:String):void
{
_backgroundSize=value;
}
public function set preloader(obj:Sprite):void
{
_preloader=obj;
obj.addEventListener(ProgressEvent.PROGRESS, progressHandler);
obj.addEventListener(Event.COMPLETE,completeHandler);
obj.addEventListener(FlexEvent.INIT_PROGRESS,initProgressHandler);
obj.addEventListener(FlexEvent.INIT_COMPLETE,initCompleteHandler);
obj.addEventListener(RSLEvent.RSL_PROGRESS,rslProgress);
obj.addEventListener(RSLEvent.RSL_ERROR,rslError);
obj.addEventListener(RSLEvent.RSL_COMPLETE,rslComplete);
}
private function rslError(e:RSLEvent):void
{
}
private function rslProgress(e:RSLEvent):void
{
}
private function rslComplete(e:RSLEvent):void
{
}
public function get stageHeight():Number
{
return _stageHeight;
}
public function set stageHeight(value:Number):void
{
_stageHeight=value;
}
public function get stageWidth():Number
{
return _stageWidth;
}
public function set stageWidth(value:Number):void
{
_stageWidth=value;
}
private function progressHandler(e:ProgressEvent):void
{
createChildren();
bytesLoaded=e.bytesLoaded;
bytesTotal=e.bytesTotal;
getPercentageLoaded(bytesLoaded);
trace(“progress”);
}
private function getPercentageLoaded(bytesLoaded:uint):void
{
percentLoaded=(bytesLoaded*100)/bytesTotal;
fillWidth=(fillWidth*100)/percentLoaded;
trace(“fillwidth”);
trace(bytesLoaded);
trace(bytesTotal);
setProgress();
drawlabel();
}
private function initCompleteHandler(e:FlexEvent):void
{
trace(“initcomp”)
g.visible=false;
dispatchEvent(new Event(Event.COMPLETE));
}
private function completeHandler(e:Event):void
{
}
protected function createChildren():void
{
//g.graphics.clear();
// g.graphics.lineStyle(2,1234);
//g.graphics.drawCircle(_xOffset,_yOffset,_borderRect.width)
//g.graphics.drawRect(_xOffset,_yOffset,_borderRect.width,_borderRect.height);
g.x=14;
g.y=39;
addChild(g);
}
private function initProgressHandler(e:FlexEvent):void
{
trace(“initProgress”);
// g.graphics.drawRect(_xOffset+1,_yOffset+1,fillWidth,_borderRect.height-1);
// trace(getTimer()-_startTime);
setProgress();
drawlabel();
}
private function drawlabel():void
{
if(!percentLoadedtext)
{
percentLoadedtext=new TextField()
percentLoadedtext.x=_xOffset+1;
percentLoadedtext.y=_yOffset+20;
g.addChild(percentLoadedtext);
}
percentLoadedtext.text=”Loading..”+percentLoaded.toString()+”%”;
}
private function setProgress():void
{
_xOffset=_xOffset+10;
te=te+10;
g.graphics.drawRect(_xOffset,_yOffset+progressOffSet,10,te);
trace(_xOffset)
progressOffSet=progressOffSet-10;
g.graphics.beginFill(1233,0.5);
}
}
}
Application
<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” layout=”vertical” creationComplete=”init()” preloader=”preload.Mypreload” >
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.controls.TextInput;
private function init():void
{
gri.dataProvider=new ArrayCollection([{dat:"test"},{dat:"test"}])
}
]]>
</mx:Script>
<mx:ApplicationControlBar width=”100%”>
<mx:Label text=”Application” fontWeight=”bold”/>
</mx:ApplicationControlBar>
<mx:DataGrid id=”gri”>
<mx:columns>
<mx:DataGridColumn headerText=”Test” dataField=”dat”/>
<mx:DataGridColumn headerText=”Test” dataField=”dat”/>
<mx:DataGridColumn headerText=”Test” dataField=”dat”/>
</mx:columns>
</mx:DataGrid>
</mx:Application>
In this for creating a custom preloader i have extended the Sprite and implemented the IPreloaderDisplay Interface which is required for creating a custom download progress bar.
In the Preloader Initialize Method the bar is centered and in the preloader setter method add listeners for download progress and complete and initialize progress and complete
In both the Initialize Progree and Download Progress set the loading text and set the Progress in the Progress Bar
View
lhttp://www.box.net/shared/x7kccjigh
DownloadSource








feedback