Tic Tac Toe Game in Flex - actionscript-3

I am newer in FLEX and currently i am using FLEX 3.0
I want to develop a Tic Tac Toe game in FLEX. At first i think this one is the easiest for me but now its going to be very tough for me. I have searched on Internet but not a single link helps me that much so please give me proper Idea with proper code. Here i am giving you the sample code. its a bit of complex so sorry for that.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" backgroundColor="#000000"
horizontalAlign="center" verticalAlign="middle" height="100%" width="100%" verticalGap="0" horizontalGap="0">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.controls.Image;
private var blnFirst:Boolean = true;
private var arr0:Array = new Array();
private var arr1:Array = new Array();
private var arr2:Array = new Array();
private var count:int = 0;
private var arr:Array = new Array();
private var pl1Won:Boolean = false;
private var pl2Won:Boolean = false;
public function img_click(event:Event):void
{
if(event.currentTarget.enabled)
{
count++;
if(blnFirst)
{
blnFirst = false;
var itemp:Image = new Image();
itemp.percentHeight = 100;
itemp.percentWidth = 100;
itemp.source = "Images/Circle.png";
event.currentTarget.addChild(itemp);
event.currentTarget.enabled = false;
arrayInsert(event.currentTarget.id,true);
}
else
{
blnFirst = true;
var itemp:Image = new Image();
itemp.percentHeight = 100;
itemp.percentWidth = 100;
itemp.source = "Images/Cross.png";
event.currentTarget.addChild(itemp);
event.currentTarget.enabled = false;
arrayInsert(event.currentTarget.id,false);
}
}
if(count == 9)
{
arr = [arr0, arr1, arr2];
}
}
private function arrayInsert(id:String,value:Boolean):void
{
if(id == "box00")
arr0[0] = value;
if(id == "box01")
arr0[1] = value;
if(id == "box02")
arr0[2] = value;
if(id == "box10")
arr1[0] = value;
if(id == "box11")
arr1[1] = value;
if(id == "box12")
arr1[2] = value;
if(id == "box20")
arr2[0] = value;
if(id == "box21")
arr2[1] = value;
if(id == "box22")
arr2[2] = value;
}
private function btn_click():void
{
for(var i:int=0;i<3;i++)
{
for(var j:int=0;j<3;j++)
{
//very confused in this part
}
}
}
]]>
</mx:Script>
<mx:VBox height="500" width="500" borderStyle="solid" borderThickness="3" borderColor="#000000"
backgroundColor="#ffffff" verticalGap="0" horizontalGap="0">
<mx:HBox width="100%" height="33.3%" horizontalGap="0" verticalGap="0">
<mx:Box height="100%" width="33.3%" borderStyle="solid" borderThickness="3" borderColor="#000000" backgroundColor="#ffffff"
click="{img_click(event);}" id="box00" >
</mx:Box>
<mx:Box height="100%" width="33.3%" borderStyle="solid" borderThickness="3" borderColor="#000000" backgroundColor="#ffffff"
click="{img_click(event);}" id="box01">
</mx:Box>
<mx:Box height="100%" width="33.4%" borderStyle="solid" borderThickness="3" borderColor="#000000" backgroundColor="#ffffff"
click="{img_click(event);}" id="box02">
</mx:Box>
</mx:HBox>
<mx:HBox width="100%" height="33.3%" horizontalGap="0" verticalGap="0">
<mx:Box height="100%" width="33.3%" borderStyle="solid" borderThickness="3" borderColor="#000000" backgroundColor="#ffffff"
click="{img_click(event);}" id="box10">
</mx:Box>
<mx:Box height="100%" width="33.3%" borderStyle="solid" borderThickness="3" borderColor="#000000" backgroundColor="#ffffff"
click="{img_click(event);}" id="box11">
</mx:Box>
<mx:Box height="100%" width="33.4%" borderStyle="solid" borderThickness="3" borderColor="#000000" backgroundColor="#ffffff"
click="{img_click(event);}" id="box12">
</mx:Box>
</mx:HBox>
<mx:HBox width="100%" height="33.4%" horizontalGap="0" verticalGap="0">
<mx:Box height="100%" width="33.3%" borderStyle="solid" borderThickness="3" borderColor="#000000" backgroundColor="#ffffff"
click="{img_click(event);}" id="box20">
</mx:Box>
<mx:Box height="100%" width="33.3%" borderStyle="solid" borderThickness="3" borderColor="#000000" backgroundColor="#ffffff"
click="{img_click(event);}" id="box21">
</mx:Box>
<mx:Box height="100%" width="33.4%" borderStyle="solid" borderThickness="3" borderColor="#000000" backgroundColor="#ffffff"
click="{img_click(event);}" id="box22">
</mx:Box>
</mx:HBox>
</mx:VBox>
<mx:Button click="{btn_click();}" />
</mx:Application>
I have check the winning condition on btn_click() function but you can give me the idea to change it when the one row is completed.
I want to know how to handle the array of TicTacToe Game.

Assuming that you are creating a tic tac toe of 3x3 grid.
Create a two dimensional array for better visualization.
Initialize them to 0.
Each time a 0 is entered at a[i,j] assign -1 to a[i,j] if empty
Check the ith row and jth column for sum -3, also if i=j or i+j=2 check for diagonals to have sum -3, you have a winner.
Each time a X is entered at a[i,j] assign 1 to a[i,j] if empty
Check the ith row and jth column for sum 3, also if i=j or i+j=2 check for diagonals to have sum 3, you have a winner

This game can develop using different Logic.
Refer 1 and 2 Which source enabled.
and try to accomplish your game.

The below was written as an assignment for students (total beginners)
The classwork: http://code.google.com/p/as3-workshop/source/browse/#svn%2Ftrunk%2Fsrc%2Ftld%2Fcourse%2Flesson1 (the game played by the player herself consequently taking sides of "O" and "X".
The homework: http://code.google.com/p/as3-workshop/source/browse/#svn%2Ftrunk%2Fsrc%2Ftld%2Fcourse%2Fhomework1 (the computer plays against the human).
The examples aren't very well documented (we did commenting and explanation in class, which I didn't record), but considering there's not much code, you should get through it.

package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.display.Graphics;
import flash.text.TextField;
import flash.text.TextFormat;
/**
* ...
* #author Jeet Chauhan
*/
public class TicTacToe extends Sprite
{
private var crossTurn:Boolean = true;
private var rects:Vector.<Rect>;
var currentMove:Number = 0;
public function TicTacToe()
{
createBoard();
}
private function createBoard():void
{
var g:flash.display.Graphics = this.graphics;
g.lineStyle(2, 0x000000);
g.beginFill(0xffff00);
g.drawRect(10, 10, 190, 190);
rects = new Vector.<Rect>();
var r:Rect
for (var i:int = 0; i < 9; i++)
{
r = new Rect();
this.addChild(r);
r.id = i;
r.y = 20 + Math.floor(i % 3) * 60;
r.x = 20 + Math.floor(i / 3) * 60;
r.addEventListener(MouseEvent.CLICK, moveNextTurn);
rects.push(r);
}
}
private function moveNextTurn(e:MouseEvent):void
{
var target:Rect = e.target as Rect
target.removeEventListener(MouseEvent.CLICK, moveNextTurn);
var turn:Sprite;
if (crossTurn) {
turn = target.addChild(new Cross) as Sprite;
target.occupied = "X";
} else {
turn = target.addChild(new Circle) as Sprite;
target.occupied = "O";
}
turn.x = 15;
turn.y = 15;
currentMove++;
if (currentMove > 4) checkAnswer();
crossTurn = !crossTurn;
}
private function checkAnswer():void
{
var winner:String = "_";
for (var i:int = 0, j = 0; i < 9; i += 3, j++)
{
if ((rects[i].occupied != "_") && (rects[i].occupied == rects[i+1].occupied) && (rects[i+1].occupied == rects[i+2].occupied))
{
winner = rects[i].occupied;
}
if ((rects[j].occupied != "_") && (rects[j].occupied == rects[j+3].occupied) && (rects[j+6].occupied == rects[j+3].occupied))
{
winner = rects[j].occupied;
}
}
if(rects[4].occupied != "_"){
if ((rects[0].occupied == rects[4].occupied) && (rects[8].occupied == rects[4].occupied))
{
winner = rects[0].occupied;
}
if ((rects[2].occupied == rects[4].occupied) && (rects[6].occupied == rects[4].occupied))
{
winner = rects[2].occupied;
}
}
if(winner != "_"){
trace("WINNER" + winner);
for (i = 0; i < 9; i++)
{
if (rects[i].hasEventListener(MouseEvent.CLICK))
{
rects[i].removeEventListener(MouseEvent.CLICK,moveNextTurn)
}
}
var tf:TextField = addChild(new TextField()) as TextField;
tf.defaultTextFormat = new TextFormat("", 20, 0xff0000);
tf.text = winner + " wins";
tf.x = 200;
tf.y = 200;
}
if (currentMove == 9 && winner == "_") {
trace("DRAW REEPLAy");
//TODO: replay logic
}
}
}
}
import flash.display.Graphics;
import flash.display.Sprite;
class Rect extends Sprite {
public var id:Number;
public var occupied:String = "_";// should be 0/_/X
function Rect() {
var g:Graphics = this.graphics;
g.lineStyle(1, 0x00ff00);
g.beginFill(0x000000);
g.drawRect(0, 0, 50, 50);
}
}
class Circle extends Sprite {
function Circle() {
var g:Graphics = this.graphics;
g.lineStyle(5, 0xff0000);
g.drawCircle(10, 10, 10);
}
}
class Cross extends Sprite {
function Cross() {
var g:Graphics = this.graphics;
g.lineStyle(5, 0x0000ff);
g.moveTo(0, 0);
g.lineTo(20, 20);
g.moveTo(20, 0);
g.lineTo(0, 20);
}
}
its a working example you can compile it, no need of graphics, hope it help

Related

Global Variables and GlowFilters is not working

Good day all,
I m new to actionscript3 , and I cant solve few problems on my code. The first problem is glowfilter is not run. According to my research glowfilter 's alpha is set like that but , when ı click true answer it do not response. But the ı try algorithm ıt enter the right case. The second problem is I want to define write answer as global but when ı changed the rightAnswer in a function it is not change,how can ı over this problem ? I think defining global variable in actionscript is different from c .
Thank you for your help and sorry for my bad english!
<s:Button id="answer1" width="388" height="68" label="" cornerRadius="16"
fontFamily="Georgia" fontSize="17" click="checkanswers(1)">
<s:filters>
<mx:GlowFilter id="answer1_glow" color="0x00ff00" alpha="0" strength="3"/>
<mx:GlowFilter id="answer1_glow2" color="0xff0000" alpha="0" strength="3"/>
</s:filters>
</s:Button>
<s:Button id="answer2" width="388" height="68" label="" cornerRadius="16"
fontFamily="Georgia" fontSize="17" click="checkanswers(2)">
<s:filters>
<mx:GlowFilter id="answer2_glow" color="0x00ff00" alpha="0" strength="3"/>
<mx:GlowFilter id="answer2_glow2" color="0xff0000" alpha="0" strength="3"/>
</s:filters>
</s:Button>
<s:Button id="answer3" width="388" height="68" label="" cornerRadius="16"
fontFamily="Georgia" fontSize="17" click="checkanswers(3)">
<s:filters>
<mx:GlowFilter id="answer3_glow" color="0x00ff00" alpha="0" strength="3"/>
<mx:GlowFilter id="answer3_glow2" color="0xff0000" alpha="0" strength="3"/>
</s:filters>
</s:Button>
<s:Button id="answer4" width="388" height="68" label="" cornerRadius="16"
fontFamily="Georgia" fontSize="17" click="checkanswers(4)">
<s:filters>
<mx:GlowFilter id="answer4_glow" color="0x00ff00" alpha="0" strength="3"/>
<mx:GlowFilter id="answer4_glow2" color="0xff0000" alpha="0" strength="3"/>
</s:filters>
</s:Button>
</s:VGroup>
<fx:Script>
<![CDATA[
import flash.events.TimerEvent;
import flash.utils.Timer;
import mx.controls.Alert;
import mx.events.FlexEvent;
import mx.core.FlexGlobals;
import mx.events.FlexEvent;
private var baseTimer:int;
private var t:Timer;
private const TIMER_INTERVAL:Number = 10;
public var rightAnswer:int = 0 ; // ---> ı want to use a global rightAnswer .
public function checkanswers(answer:int):void{
trace("answer is " + answer );
trace("rightanswer is " + rightAnswer);
if ( answer == rightAnswer) {
switch (answer) {
case 1 :
answer1.label = "green";
answer1.alpha = 1; // ı want to change glowfilters alpha in there.
break;
case 2 :
answer2.label = "green";
answer2_glow.alpha = 1;
break;
case 3 :
answer3.label = "green";
answer3_glow.alpha = 1;
break;
case 4 :
answer4.label = "green";
answer4_glow.alpha = 1;
break;
default :
break;
}
}
else{
switch (answer) {
case 1 :
answer1.label = "red";
answer1_glow2.alpha = 1;
break;
case 2 :
answer2.label = "red";
answer2_glow2.alpha = 1.0;
break;
case 3 :
answer3.label = "red;
answer3_glow2.alpha = 1.0;
break;
case 4 :
answer4.label = "red";
answer4_glow2.alpha = 1.0;
break;
default :
break;
}
switch (rightAnswer) {
case 1 :
answer1.label = "green";
answer1_glow.alpha = 1;
break;
case 2 :
answer2.label = "green";
answer2_glow.alpha = 1;
break;
case 3 :
answer3.label = "green";
answer3_glow.alpha = 1;
break;
case 4 :
answer4.label = "green";
answer4_glow.alpha = 1;
break;
default :
break;
}
}
}
public function application1_creationCompleteHandler(event:FlexEvent):void
{
// TODO Auto-generated method stub
soru.text = " En büyük kim ?";
answer1.label = "Galasaray";
answer2.label = "Bursaspor";
answer3.label = "Beşiktaş";
answer4.label = "Fenerbahçe";
var rightAnswer:int = 2;
trace(" rightAnswer fonkideki " + rightAnswer);
}
]]>
</fx:Script>
You issue is with variable scope, it is not doing what you think it is doing.
When you use keyword "var" you re creating a new variable in the current scope.
In this case you are trying to assign 2 to the class level variable "rightAnswer" when in fact you are creating a new variable called "rightAnswer" scoped to function level.
public function application1_creationCompleteHandler(event:FlexEvent):void
{
// TODO Auto-generated method stub
soru.text = " En büyük kim ?";
answer1.label = "Galasaray";
answer2.label = "Bursaspor";
answer3.label = "Beşiktaş";
answer4.label = "Fenerbahçe";
var rightAnswer:int = 2; // <<<<--- right here is your problem
trace(" rightAnswer fonkideki " + rightAnswer);
}
So instead do this.
public function application1_creationCompleteHandler(event:FlexEvent):void
{
// TODO Auto-generated method stub
soru.text = " En büyük kim ?";
answer1.label = "Galasaray";
answer2.label = "Bursaspor";
answer3.label = "Beşiktaş";
answer4.label = "Fenerbahçe";
var rightAnswer:int = 12345678; // <<<<--- right here is your problem
this.rightAnswer = 2; // <<<<--- here is your correction
trace(" rightAnswer class level" + this.rightAnswer);
trace(" rightAnswer function level" + rightAnswer);// << -- this can only be accessed inside of the current function
}

Flex 4.6 Control timer in itemRenderer of TIleList

I am working with Flex 4.6 AIR application. I have a tile list and there is an image as an itemRenderer. When i search images, the data is not filtered but is selected the indices(selected items) of the tilelist and i set a custom property in arrayCollection(dataProvider) then updateDisplayList called and i start a timer in this function. Which perform play the inner images in the selected item.
Now the problem is when if i search the item and click the non selected item the timer is not stoped. How can i achieve that.
The code of itemRenderer is below
<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
autoDrawBackground="true" buttonMode="true"
click="itemrenderer2_clickHandler(event)"
doubleClick="itemrenderer1_doubleClickHandler(event)" doubleClickEnabled="true"
rightClick="itemrenderer1_rightClickHandler(event)"
rollOut="itemrenderer1_rollOutHandler(event)"
rollOver="itemrenderer1_rollOverHandler(event)" useHandCursor="true">
<fx:Script>
<![CDATA[
import customs.customcomponents.LibraryReDownloadComponent;
import customs.customcomponents.VideoUploadBox;
import dbconnection.Connection;
import globalData.DataModel;
import mx.collections.ArrayCollection;
import mx.core.FlexGlobals;
import mx.core.UIComponent;
import mx.events.ItemClickEvent;
import mx.managers.PopUpManager;
import mx.utils.ObjectProxy;
import mx.utils.UIDUtil;
private var isLoaded:Boolean = false;
private var timer:Timer;
private var rollOverFlag:Boolean = false;
private var countThumb:int = 0;
private var arrThumnail:ArrayCollection;
private var loaderThumb:Loader;
private var request:URLRequest;
private var requestThumb:URLRequest;
private var loader:Loader;
private var sqlStatStatus:SQLStatement;
private var downloadVideoPath:String = "";
private var videoUrlStream:URLStream;
private var videoFileStream:FileStream;
private var uploadvidbox:VideoUploadBox = new VideoUploadBox();
private var dtStartVideo:Date;
private var videoFileName:String = "";
private var videoFile:File;
private var IsRollOver:Boolean = false;
[Bindable]
private var modellocator:DataModel=DataModel.getInstance();
private var connection:Connection = Connection.getInstance();
override public function set data(value:Object):void
{
if(value != null)
{
super.data = value;
if(timer != null)
{
timer.stop();
timer.removeEventListener(TimerEvent.TIMER, showFrame);
timer = null;
}
loaderThumb = new Loader();
rollOverFlag = false;
countThumb = 0;
if(flash.system.Capabilities.os.indexOf("Mac") > -1)
{
requestThumb = new URLRequest("file://" + data.Videothumbnail);
}
else
{
requestThumb = new URLRequest(data.Videothumbnail);
}
loaderThumb.contentLoaderInfo.addEventListener(Event.COMPLETE,onThumbComplete);
loaderThumb.load(requestThumb);
if(data.VideoBuyFlag == "yes")
{
if(data.VideoIsDeleted == "No")
{
bContain.setStyle("borderColor", "#00FF18");
bContain.alpha = 1;
}
else
{
bContain.setStyle("borderColor", "#888888");
bContain.alpha = 0.3;
}
}
else
{
if(data.VideoIsDeleted == "No")
{
bContain.setStyle("borderColor", "#C50000");
bContain.alpha = 1;
}
else
{
bContain.setStyle("borderColor", "#888888");
bContain.alpha = 0.3;
}
}
if(data.VideoStatus == "Active")
{
imgActive.source = "assets/btn_Active.jpg";
bContain.alpha = 1;
}
else
{
imgActive.source = "assets/btn_InActive.jpg";
bContain.alpha = 0.3;
}
arrThumnail = new ArrayCollection();
if(data.Videothumbdata.thumbimage != null)
{
if(data.Videothumbdata.thumbimage.source.item.length > 1)
{
for(var i:int = 0; i < data.Videothumbdata.thumbimage.source.item.length; i++)
{
arrThumnail.addItem(data.Videothumbdata.thumbimage.source.item[i]);
}
}
else
{
arrThumnail.addItem(data.Videothumbdata.thumbimage.source.item);
}
}
}
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
/* trace(data.Videoname);
trace("IsRollOver : " + IsRollOver.toString());
trace("IsSearching : " + data.IsSearching.toString());
trace("rollOverFlag : " + rollOverFlag.toString()); */
if(data.IsSearching == false)
{
if(IsRollOver == false)
{
if(timer != null)
{
trace("inner");
loaderThumb = new Loader();
rollOverFlag = false;
if(flash.system.Capabilities.os.indexOf("Mac") > -1)
{
requestThumb = new URLRequest("file://" + data.Videothumbnail);
}
else
{
requestThumb = new URLRequest(data.Videothumbnail);
}
loaderThumb.contentLoaderInfo.addEventListener(Event.COMPLETE,onThumbComplete);
loaderThumb.load(requestThumb);
timer.stop();
timer.removeEventListener(TimerEvent.TIMER, showFrame);
countThumb= 0;
System.gc();
System.gc();
}
}
}
else
{
if(rollOverFlag == false)
{
rollOverFlag = true;
trace("Hi");
timer = new Timer(1000);
timer.addEventListener(TimerEvent.TIMER, showFrame);
timer.start();
}
else
{
if(timer != null)
{
trace("SecondInner");
loaderThumb = new Loader();
rollOverFlag = false;
if(flash.system.Capabilities.os.indexOf("Mac") > -1)
{
requestThumb = new URLRequest("file://" + data.Videothumbnail);
}
else
{
requestThumb = new URLRequest(data.Videothumbnail);
}
loaderThumb.contentLoaderInfo.addEventListener(Event.COMPLETE,onThumbComplete);
loaderThumb.load(requestThumb);
timer.stop();
timer.removeEventListener(TimerEvent.TIMER, showFrame);
countThumb= 0;
System.gc();
System.gc();
}
}
}
}
protected function showFrame(event:TimerEvent):void
{
var file:File;
trace("hello");
if(countThumb < arrThumnail.length)
{
if(flash.system.Capabilities.os.indexOf("Mac") > -1)
{
file = new File("file://" + arrThumnail[countThumb]);
}
else
{
file = new File(arrThumnail[countThumb]);
}
if(file.exists)
{
loader = new Loader();
if(flash.system.Capabilities.os.indexOf("Mac") > -1)
{
request=new URLRequest("file://" + arrThumnail[countThumb]);
}
else
{
request=new URLRequest(arrThumnail[countThumb]);
}
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onComplete);
loader.load(request);
if(countThumb == (arrThumnail.length - 1))
{
countThumb = 0;
}
else
{
countThumb++;
}
}
else
{
countThumb++;
}
}
else
{
countThumb = 0;
}
}
protected function itemrenderer1_rollOverHandler(event:MouseEvent):void
{
if(data.IsSearching == false)
{
rollOverFlag = true;
IsRollOver = true;
if(arrThumnail != null && arrThumnail.length > 0)
{
timer = new Timer(1000);
timer.addEventListener(TimerEvent.TIMER, showFrame);
timer.start();
}
}
}
private function onComplete(event:Event):void
{
if(rollOverFlag)
{
imgThumb.source = loader;
}
}
private function onThumbComplete(event:Event):void
{
imgThumb.source = loaderThumb;
}
protected function itemrenderer1_rollOutHandler(event:MouseEvent):void
{
if(data.IsSearching == false)
{
rollOverFlag = false;
IsRollOver = false;
imgThumb.source = loaderThumb;
if(timer != null)
{
timer.stop();
timer.removeEventListener(TimerEvent.TIMER, showFrame);
timer = null;
}
countThumb = 0;
System.gc();
System.gc();
}
}
protected function itemrenderer2_clickHandler(event:MouseEvent):void
{
for(var i:int=0; i < modellocator.libraryvideoac.length; i++)
{
modellocator.libraryvideoac[i].IsSearching = false;
}
parentDocument.parentDocument.txt_search.text = resourceManager.getString('languages','lblSearchText');
parentDocument.parentDocument.unCheckSelection();
if(data.VideoIsDeleted == "Yes")
{
var popupReDownload:LibraryReDownloadComponent = new LibraryReDownloadComponent();
popupReDownload = PopUpManager.createPopUp(UIComponent(this.parentApplication), LibraryReDownloadComponent, true) as LibraryReDownloadComponent;
popupReDownload.addEventListener("downloadMovie", redownloadMovie);
PopUpManager.centerPopUp(popupReDownload);
}
}
]]>
</fx:Script>
<fx:Declarations>
<mx:NumberFormatter id="numFormat" precision="2"/>
</fx:Declarations>
<s:BorderContainer id="bContain" left="2" top="2" width="92" height="67" backgroundAlpha="1"
backgroundColor="#000000" borderColor="#030304" borderWeight="3">
<s:Image id="imgThumb" width="86" height="61" fillMode="scale" scaleMode="stretch"/>
<s:Image id="imgActive" right="0" bottom="0" width="15" height="15" buttonMode="true"
useHandCursor="true"/>
</s:BorderContainer>
</s:ItemRenderer>
You have timer instantiation at different places in the code. I can't be sure of the actual program flow, but maybe you instantiate the timer two times? In that case program would overwrite the timer variable, and lose reference to the first timer. So, when you call timer.stop() you actually only stop one timer, while the other keeps running in the background.
You didn't set weak reference attribute here:
timer.addEventListener(TimerEvent.TIMER, showFrame);
so the timer will not be garbage collected if you lose its reference (even if you call System.gc() twice :-)). Check that situation out, and try adding a listener with:
timer.addEventListener(TimerEvent.TIMER, showFrame, false, 0, true);

Calling the zoom in and out of context menu from custom button in flex3

I want to call the zoom in and zoom out function of context menu from custom button In adobe flex application.
Code something like this :
onZoomInButtonClick()
{
this.contextMenu.customItems.zoom.doIn();
}
There is (at least to my knowledge) no way for you to access the flash player zoom in/out commands via code.
You can fake it though by doing the following in your document class (top-most display object under stage)
stage.addEventListener(MouseEvent.MOUSE_WHEEL,mouseWheel,true,2); //listen on the capture phase of the event and give a higher priority than default so it reacts before your grid
function mouseWheel(e:MouseEvent):void {
if(!e.ctrlKey) return; //Ctrl has to be pressed or we ignore the wheel
e.stopImmediatePropagation(); //this stops the event from firing on anything else, like your data grid
var tmpScale:Number = scaleX + (e.delta > 0 ? .2 : -.2); //lets zoom in/out in incriments of 20% (.1)
if(tmpScale < 1){ //if the scale is less than one now, lets keep it at 1
tmpScale = 1;
this.scaleX = 1;
this.x = 0;
this.scaleY = 1;
this.y = 0;
return;
}
if(tmpScale > 4){ //lets set the max to 4
tmpScale = 4;
}
scaleAroundMouse(this,tmpScale);
}
function scaleAroundMouse(objectToScale:DisplayObject, scaleAmount:Number, bounds:Rectangle = null):void {
// scaling will be done relatively
var relScaleX:Number = scaleAmount / objectToScale.scaleX;
var relScaleY:Number = scaleAmount / objectToScale.scaleY;
// map vector to centre point within parent scope
var scalePoint:Point = objectToScale.localToGlobal( new Point(objectToScale.mouseX, objectToScale.mouseY));
scalePoint = objectToScale.parent.globalToLocal( scalePoint );
// current registered postion AB
var AB:Point = new Point( objectToScale.x, objectToScale.y );
// CB = AB - scalePoint, objectToScale vector that will scale as it runs from the centre
var CB:Point = AB.subtract( scalePoint );
CB.x *= relScaleX;
CB.y *= relScaleY;
// recaulate AB, objectToScale will be the adjusted position for the clip
AB = scalePoint.add( CB );
// set actual properties
if(bounds){
var limits:Rectangle = new Rectangle(
bounds.x + (bounds.width - (objectToScale.width * relScaleX)),
bounds.y + (bounds.height - (objectToScale.height * relScaleY)),
(objectToScale.width * relScaleX) - bounds.width,
(objectToScale.height * relScaleY) - bounds.height
);
if(AB.x < limits.x) AB.x = limits.x;
if(AB.x > limits.x + limits.width) AB.x = limits.x + limits.width;
if(AB.y < limits.y) AB.y = limits.y;
if(AB.y > limits.y + limits.height) AB.y = limits.y + limits.height;
}
objectToScale.scaleX = scaleAmount;
objectToScale.scaleY = scaleAmount;
objectToScale.x = AB.x;
objectToScale.y = AB.y;
}
Ok, advancedatagrid may listen keyboard events, when ctrl key down - listen mousewheel events and change scale, see example:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
<fx:Script>
<![CDATA[
protected function doMouseWheel(evt:MouseEvent):void
{
scaleX = scaleY += evt.delta * 0.1;
}
protected function adg_keyDownHandler(event:KeyboardEvent):void
{
if (event.ctrlKey)
{
systemManager.addEventListener(MouseEvent.MOUSE_WHEEL, doMouseWheel);
}
}
protected function adg_keyUpHandler(event:KeyboardEvent):void
{
if (!event.ctrlKey)
{
systemManager.removeEventListener(MouseEvent.MOUSE_WHEEL, doMouseWheel);
}
}
]]>
</fx:Script>
<mx:AdvancedDataGrid id="adg" keyDown="adg_keyDownHandler(event)" keyUp="adg_keyUpHandler(event)"
horizontalCenter="0" verticalCenter="0">
<mx:columns>
<mx:AdvancedDataGridColumn dataField="#label"/>
<mx:AdvancedDataGridColumn dataField="#data" />
</mx:columns>
<mx:dataProvider>
<s:XMLListCollection id="dp">
<s:source>
<fx:XMLList>
<product label="Product 1" data="3" />
<product label="Product 2" data="1" />
<product label="Product 3" data="4" />
<product label="Product 4" data="1" />
<product label="Product 5" data="5" />
<product label="Product 6" data="9" />
</fx:XMLList>
</s:source>
</s:XMLListCollection>
</mx:dataProvider>
</mx:AdvancedDataGrid>
</s:Application>
In order to zoom in/out a vector graphics, you plainly change its scaleX and scaleY properties uniformly. The vector renderer of Flash will draw you a correct picture. In order to zoom in on a Bitmap and not get pixelated output, you have to convert it into a vector graphics object like this:
var sh:Shape=new Shape();
sh.graphics.beginBitmapFill(yourBitmap);
sh.graphics.lineStyle(0,0,0); // to not have border lines
sh.graphics.drawRect(0,0,yourBitmap.width,yourBitmap.height);
sh.graphics.endFill();
And then adjusting scaleX and scaleY of that shape will produce interpolated output as you seemingly want.

Flex UI Components disappear

I've implemented a method to change display size.
When I click on maximize, I reposition some buttons in a viewstack.
Problem is when I restore view the buttons disappear.
Can someone help me?
{
nativeWindow.addEventListener(NativeWindowBoundsEvent.RESIZING, onAppResize);
nativeWindow.addEventListener(NativeWindowBoundsEvent.RESIZE, onAppResize);
nativeWindow.addEventListener(NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGING,onAppMaximized);
var screenBounds:Rectangle = Screen.mainScreen.bounds;
nativeWindow.x = 10;
nativeWindow.y = 10;
}
private function onAppMaximized(e:NativeWindowDisplayStateEvent):void
{
if(String(e.afterDisplayState) == "maximized" && DisplayMaximized == false)
{
e.preventDefault();
nativeWindow.x = 10;
nativeWindow.y = 10;
AppImageWidth = 1280;
AppImageHeight = 900;
nativeWindow.width = 1280;
nativeWindow.height = 900;
viewstack.createComponentsFromDescriptors(true);
viewstackBuchungen.width = 1206;
viewstackBuchungen.height = 600;
Button.x = 1135;
Button.y = 608;
Button2.x = 1135;
Button2.y = 608;
DisplayMaximized = true;
}
else if(String(e.afterDisplayState) == "maximized" && DisplayMaximized == true)
{
e.preventDefault();
AppImageWidth = 1024;
AppImageHeight = 600;
nativeWindow.width = 1024;
nativeWindow.height = 600;
viewstackBuchungen.width = 950;
viewstackBuchungen.height = 313;
Button.x = 879;
Button.y = 321;
Button2.x = 879;
Button2.y = 321;
DisplayMaximized = false;
}
}
thanks for your answer.
I tried moving them with .move(x,y).
Nothing changed...
The buttons are on same position, because they are in different navigator content.
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" creationComplete="init();" width="1024" height="600">
private function init():void
{
nativeWindow.addEventListener(NativeWindowBoundsEvent.RESIZING, onAppResize);
nativeWindow.addEventListener(NativeWindowBoundsEvent.RESIZE, onAppResize);
nativeWindow.addEventListener(NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGING,onAppMaximized);
nativeWindow.x = 10;
nativeWindow.y = 10;
}
private function onAppResize(e:NativeWindowBoundsEvent):void
{
e.preventDefault();
}
private function onAppMaximized(e:NativeWindowDisplayStateEvent):void
{
if(String(e.afterDisplayState) == "maximized" && DisplayMaximized == false)
{
e.preventDefault();
nativeWindow.x = 10;
nativeWindow.y = 10;
nativeWindow.width = 1280;
nativeWindow.height = 900;
viewstack1.createComponentsFromDescriptors(true);
viewstack1.width = 1206;
viewstack1.height = 600;
button1.move(1135,608);
button2.move(1135,608);
DD1.move(1082,608);
DisplayMaximized = true;
}
else if(String(e.afterDisplayState) == "maximized" && DisplayMaximized == true)
{
e.preventDefault();
nativeWindow.width = 1024;
nativeWindow.height = 600;
viewstack1.width = 950;
viewstack1.height = 313;
button1.move(879,321);
button2.move(879,321);
DD1.move(826,321);
DisplayMaximized = false;
}
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Platzieren Sie nichtvisuelle Elemente (z. B. Dienste, Wertobjekte) hier -->
</fx:Declarations>
<s:Group x="16" y="113" width="1254" height="463">
<mx:ViewStack id="viewstack1" x="0" y="24" width="950" height="313" selectedIndex="0" creationPolicy="all">
<s:NavigatorContent width="100%" height="100%" label="Nav1" id="nav1" creationPolicy="all">
<mx:AdvancedDataGrid id="grid1" x="0" y="0" width="100%" height="100%"
designViewDataType="flat"
editable="true" horizontalScrollPolicy="off"
sortableColumns="false" resizableColumns="false" draggableColumns="false">
<mx:columns>
<mx:AdvancedDataGridColumn dataField="test1" headerText="test1" width="35"/>
</mx:columns>
</mx:AdvancedDataGrid>
<s:Button x="879" y="321" label="Button1" id="button1"/>
</s:NavigatorContent>
<s:NavigatorContent width="100%" height="100%" label="Nav2" id="nav2" creationPolicy="all">
<mx:AdvancedDataGrid id="grid2" x="0" y="0" width="100%" height="100%"
designViewDataType="flat"
editable="true" horizontalScrollPolicy="off"
sortableColumns="false" resizableColumns="false" draggableColumns="false">
<mx:columns>
<mx:AdvancedDataGridColumn dataField="test2" headerText="test2" width="35"/>
</mx:columns>
</mx:AdvancedDataGrid>
<s:Button x="879" y="321" label="Button2" id="button2" />
</s:NavigatorContent>
<s:NavigatorContent width="100%" height="100%" label="Nav3" id="nav3" creationPolicy="all">
<mx:AdvancedDataGrid id="grid3" x="0" y="0" width="100%" height="100%"
designViewDataType="flat"
editable="true" horizontalScrollPolicy="off"
sortableColumns="false" resizableColumns="false" draggableColumns="false">
<mx:columns>
<mx:AdvancedDataGridColumn dataField="test3" headerText="test3" width="35"/>
</mx:columns>
</mx:AdvancedDataGrid>
<s:DropDownList x="826" id="DD1" y="321" width="125" prompt="DD1" alpha="1"/>
</s:NavigatorContent>
</mx:ViewStack>
<s:TabBar x="0" y="0" dataProvider="{viewstack1}" />
</s:Group>

konami code in flex

What would be the best way to implement the konami code into a flex application?
I want to create a component to add it on all my proyects, just for fun.
thanks
UPDATE: I made a simple component, thanks to ZaBlanc
<?xml version="1.0" encoding="utf-8"?>
<mx:UIComponent xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()">
<mx:Metadata>
[Event(name="success", type="flash.events.Event")]
</mx:Metadata>
<mx:Script>
<![CDATA[
// up-up-down-down-left-right-left-right-B-A
public static const KONAMI_CODE:String = "UUDDLRLRBA";
// signature
private var signatureKeySequence:String = "";
private function init():void{
systemManager.stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
}
private function onKeyDown(event:KeyboardEvent):void{
var keyCode:int = event.keyCode;
switch (keyCode) {
case Keyboard.UP:
signatureKeySequence += "U";
break;
case Keyboard.DOWN:
signatureKeySequence += "D";
break;
case Keyboard.LEFT:
signatureKeySequence += "L";
break;
case Keyboard.RIGHT:
signatureKeySequence += "R";
break;
case 66: //Keyboard.B only for AIR :/
signatureKeySequence += "B";
break;
case 65: //Keyboard.A only for AIR too :(
signatureKeySequence += "A";
break;
default:
signatureKeySequence = "";
break;
}
// crop sequence
signatureKeySequence = signatureKeySequence.substr(0, KONAMI_CODE.length);
// check for konami code
if (signatureKeySequence == KONAMI_CODE) {
dispatchEvent(new Event("success"));
signatureKeySequence = "";
}
}
]]>
</mx:Script>
</mx:UIComponent>
to test it
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" xmlns:konamicode="konamicode.*">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
]]>
</mx:Script>
<konamicode:KonamiCodeCatch success="Alert.show('+30 lives!!!')" />
</mx:Application>
A state machine is fun to write, but in this case I'd go with a signature pattern. Depending on where you want to put the handler (on the stage of the component), here's some code that should work, though you can probably tighten it (and of course customize it to your specific need):
// up-up-down-down-left-right-left-right-B-A
public static const KONAMI_CODE:String = "UUDDLRLRBA";
// signature
private var signatureKeySequence:String = "";
private function onKeyDown(event:KeyboardEvent):void {
var keyCode:int = event.keyCode;
switch (keyCode) {
case Keyboard.UP:
signatureKeySequence += "U";
break;
case Keyboard.DOWN:
signatureKeySequence += "D";
break;
case Keyboard.LEFT:
signatureKeySequence += "L";
break;
case Keyboard.RIGHT:
signatureKeySequence += "R";
break;
case Keyboard.B:
signatureKeySequence += "B";
break;
case Keyboard.A:
signatureKeySequence += "A";
break;
default:
signatureKeySequence = "";
break;
}
// crop sequence
signatureKeySequence = signatureKeySequence.substr(0, KONAMI_CODE.length);
// check for konami code
if (signatureKeySequence == KONAMI_CODE) {
// 30 lives!
}
}
You may use Casalib. There are classes, Key and KeyCombo. You may listen for KeyComboEvent.SEQUENCE.
Working sample:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="init();">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import org.casalib.events.KeyComboEvent;
import org.casalib.ui.Key;
import org.casalib.ui.KeyCombo;
import org.casalib.util.StageReference;
private const KONAMI_CODE:KeyCombo = new KeyCombo([Keyboard.UP,Keyboard.UP,Keyboard.DOWN,Keyboard.DOWN,Keyboard.LEFT,Keyboard.RIGHT,Keyboard.LEFT,Keyboard.RIGHT,("B").charCodeAt(),("A").charCodeAt()]);
private function init():void {
StageReference.setStage(this.systemManager.stage);
Key.getInstance().addKeyCombo(KONAMI_CODE);
Key.getInstance().addEventListener(KeyComboEvent.SEQUENCE,onKonami);
}
private function onKonami(evt:KeyComboEvent):void {
if (evt.keyCombo == KONAMI_CODE){
Alert.show("You know Konami code?","WOW");
}
}
]]>
</mx:Script>
</mx:Application>
var unlockCode:Array = new Array(38,38,40,40,37,39,37,39,66,65,13);
var keyPressArray:Array = new Array();
stage.addEventListener(KeyboardEvent.KEY_DOWN, checkUnlockCode);
function checkUnlockCode(e:KeyboardEvent):void {
if (keyPressArray.length >= unlockCode.length) {
keyPressArray.splice(0,1);
keyPressArray.push(e.keyCode.toString());
} else {
keyPressArray.push(e.keyCode.toString());
}
trace(keyPressArray);
if (keyPressArray.toString() == unlockCode.toString()) {
trace(unlockCode);
}
}