AS3 addChild with multiple buttons top layer fails - actionscript-3

this seems like an odd one as it seems pretty straight forward, I have a movieclip that contains a back and forward button to invoke a tween for 2 groups of buttons to slide accross the screenI addChild then make the tween and then removeChild for the old group of buttons to leave the new one on the screen.
My question is when the second group comes in with all the buttons the button that is on the top layer of the movieclip fails to work (rollOver Tween and all) if I change which button is on the top layer then that one fails.
any ideas as to why this may occur so I can make a fix?
code for process is below.
import fl.transitions.Tween;
import fl.transitions.TweenEvent;
import fl.transitions.easing.Strong;
import flash.events.*;
import flash.display.MovieClip;
fOverlay.addEventListener(MouseEvent.ROLL_OVER, mOver);
fOverlay.addEventListener(MouseEvent.ROLL_OUT, mOut);
fOverlay.addEventListener(MouseEvent.CLICK, mDown);
bOverlay.addEventListener(MouseEvent.ROLL_OVER, mOverB);
bOverlay.addEventListener(MouseEvent.ROLL_OUT, mOutB);
bOverlay.addEventListener(MouseEvent.CLICK, mDownB);
var butts1:MovieClip = new sButtons1;
var butts2:MovieClip = new sButtons2;
addChild(butts1);
butts1.x = -10;
butts1.y = 0;
function mOver(e:MouseEvent)
{
var mouseOTween:Tween = new Tween(fBack, "alpha", Strong.easeOut,0.2,0.8,1,true);
}
function mOut(e:MouseEvent)
{
var mouseOTween:Tween = new Tween(fBack, "alpha", Strong.easeOut,0.8,0.2,1,true);
}
function mOverB(e:MouseEvent)
{
var mouseOTween:Tween = new Tween(bBack, "alpha", Strong.easeOut,0.2,0.8,1,true);
}
function mOutB(e:MouseEvent)
{
var mouseOTween:Tween = new Tween(bBack, "alpha", Strong.easeOut,0.8,0.2,1,true);
}
function mDown(e:MouseEvent)
{
if (butts1.stage)
{
addChild(butts2)
butts2.x = 1832;
butts2.y = 0;
var nTweenout1:Tween = new Tween(butts1,"x", Strong.easeInOut, -10, -1860, 1, true);
var nTweenin1:Tween = new Tween(butts2,"x", Strong.easeInOut, 1832, -10, 1, true);
nTweenout1.addEventListener(TweenEvent.MOTION_FINISH, moFinish1);
function moFinish1(e:TweenEvent)
{
removeChild(butts1);
}
}
else if (butts2.stage)
{
addChild(butts1)
butts1.x = 1832;
butts1.y = 0;
var nTweenout2:Tween = new Tween(butts2,"x", Strong.easeInOut, -10, -1860, 1, true);
var nTweenin2:Tween = new Tween(butts1,"x", Strong.easeInOut, 1832, -10, 1, true);
nTweenout2.addEventListener(TweenEvent.MOTION_FINISH, moFinish2);
function moFinish2(e:TweenEvent)
{
removeChild(butts2);
}
}
else
{
MovieClip(root).addChild(butts1)
butts1.x = -10;
butts1.y = 0;
}
}
function mDownB(e:MouseEvent)
{
if (butts1.stage)
{
addChild(butts2)
butts2.x = -1860;
butts2.y = 0;
var nTweenoutB1:Tween = new Tween(butts2,"x", Strong.easeInOut, -1860, -10, 1, true);
var nTweeninB1:Tween = new Tween(butts1,"x", Strong.easeInOut, -10, 1832, 1, true);
nTweenoutB1.addEventListener(TweenEvent.MOTION_FINISH, moFinish3);
function moFinish3(e:TweenEvent)
{
removeChild(butts1);
}
}
else if (butts2.stage)
{
addChild(butts1)
butts1.x = -1860;
butts1.y = 0;
var nTweenoutB2:Tween = new Tween(butts1,"x", Strong.easeInOut, -1860, -10, 1, true);
var nTweeninB2:Tween = new Tween(butts2,"x", Strong.easeInOut, -10, 1832, 1, true);
nTweenoutB2.addEventListener(TweenEvent.MOTION_FINISH, moFinish4);
function moFinish4(e:TweenEvent)
{
removeChild(butts2);
}
}
else
{
addChild(butts1)
butts1.x = -10;
butts1.y = 0;
}
}

I suspect you've got objects overlapping eachother. In that case, only the top-most object will receive the mouse event. If so, it is expected behavior. An example of this can be seen with a transparent png.
Without the rest of your DisplayList structure or appearance of your UI, I can't say exactly what's plaguing your events. However, I think the code below might help clear up some things.
import fl.transitions.Tween;
import fl.transitions.TweenEvent;
import fl.transitions.easing.Strong;
import flash.events.*;
import flash.display.MovieClip;
var butts1:MovieClip = new sButtons1;
var butts2:MovieClip = new sButtons2;
var lookup:Dictionary = new Dictionary(true);
var removeTarget:MovieClip = null; // This is the next object to be removed from onscreen
var onComplete:Tween = null; // A reference to the tween the calls our remove
function init():void {
// It's healthy to keep your initialization routine grouped away from the rest of your program logic.
// Optionally, you can recall the function to rerun first time setup, if necessary.
addChild(butts1);
butts1.x = -10;
butts1.y = 0;
// Use event target as a key in our dictionary to correspond which objects should be hidden/shown
// This way, we can keep our code consistent and maintainable from one function.
lookup[fOverlay] = {
"back":fBack,
"out":butts1,
"in":butts2
}
lookup[bOverlay] = {
"back":bBack,
"out":butts2,
"in":butts1
}
// Because we're registering the same events to the same functions, we can handle it through a loop.
var overlayEvents:Array = ["rollOver", "rollOut", "click"];
for (var overlay in lookup) {
for each (var type:String in overlayEvents) {
overlay.addEventListener(type, overlayListener, false, 0, true);
}
}
}
function overlayListener(e:MouseEvent):void {
// Having generalized our objects, we swap for the appropriate object based on the type of event.
switch (e.type) {
case "rollOver":
new Tween(lookup[e.currentTarget].back, "alpha", Strong.easeOut,0.2,0.8,1,true);
break;
case "rollOut":
new Tween(lookup[e.currentTarget].back, "alpha", Strong.easeOut,0.8,0.2,1,true);
break;
case "click":
var show:MovieClip, hide:MovieClip;
if (lookup[e.currentTarget].out.stage) {
hide = lookup[e.currentTarget].out;
show = lookup[e.currentTarget].in;
} else if (lookup[e.currentTarget].in.stage) {
hide = lookup[e.currentTarget].in;
show = lookup[e.currentTarget].out;
} else {
show = butts1;
addChild(show);
}
show.x = 1832;
show.y = 0;
new Tween(hide, "x", Strong.easeInOut, -10, -1860, 1, true);
if (hide != null) {
removeTarget = hide;
if (onComplete != null) {
onComplete.stop()
onComplete.rewind()
}
onComplete = new Tween(show, "x", Strong.easeInOut, 1832, -10, 1, true);
onComplete.addEventListener("motionFinish", remove, false, 0, true);
}
break;
}
}
function remove(e:Event):void {
if (removeTarget != null) {
removeChild(removeTarget)
removeTarget = null;
onComplete.removeEventListener("motionFinish", remove);
onComplete = null;
}
}
init();

Related

How do I adjust drag speed of an object?

Ok, I am developing a game that requires the player to drag an object and place it inside of a jar. I found it to be much easier to designate an x coordinate limitation in order to determine when the object they are dragging should simulate dropping into the jar. The code that I have so far works perfectly. However, the action script that is initiated when the object crosses the x coordinate limit is ignored when the players move the object too fast over the x limit. I think that I can fix this problem by limiting how fast the object can be dragged. Does anyone have any direction on how this can be accomplished?
Here is my code:
jarFront.mouseEnabled = false; jarFront.mouseChildren = false;
// animate buttons in
import fl.transitions.Tween;
import fl.transitions.easing.*;
import fl.transitions.TweenEvent;
import flash.events.Event;
var objArray:Array = new Array;
objArray.push(obj1);
objArray.push(obj2);
objArray.push(obj3);
var objPosition:Point;
function dragobj(e:Event):void {
e.currentTarget.startDrag();
objPosition = new Point( e.currentTarget.x, e.currentTarget.y);
}
function dragobjStop(e:Event):void {
e.currentTarget.stopDrag();
e.currentTarget.x = e.currentTarget.x;
e.currentTarget.y = objPosition.y;
objPosition = null;
}
for (var i:uint = 0; i < objArray.length; i++) {
objArray[i].addEventListener(MouseEvent.MOUSE_DOWN, dragobj);
objArray[i].addEventListener(MouseEvent.MOUSE_UP, dragobjStop);
}
// Drop in jar
var HighH:int=400;
var HighW:int=400;
var LowH:int=-200; var LowW:int=0;
var HighyH:int=170;
var HighyW:int=170;
var LowyH:int=0; var LowyW:int=0;
this.addEventListener( Event.ENTER_FRAME, goJar)
function goJar( e:Event ):void
{
if (obj1.x > 400 && obj1.x < 440) {
obj1.stopDrag();
//set back or tween position
obj1.x = 83;
obj1.y = -300;
this.setChildIndex(obj1,1)
var ct1_1:Tween = new Tween(obj1, "y", None.easeNone, obj1.y, obj1.y=Math.floor(Math.random()*(1+HighyH-LowyH))+LowyH, .2, true);
var ct1_2:Tween = new Tween(obj1, "rotation", Bounce.easeOut, 0, 180, 1, true);
var ct1_3:Tween = new Tween(obj1, "x", None.easeNone, obj1.x, obj1.x=Math.floor(Math.random()*(1+HighH-LowH))+LowH, .2, true);
} else {
// keep inside jar
if (obj1.x > -330 && obj1.x < -260) {
obj1.stopDrag();
//set back or tween position
obj1.x = 83;
obj1.y = -300;
this.setChildIndex(obj1,1)
var ct1_4:Tween = new Tween(obj1, "y", None.easeNone, obj1.y, obj1.y=Math.floor(Math.random()*(1+HighyH-LowyH))+LowyH, .2, true);
var ct1_5:Tween = new Tween(obj1, "rotation", Bounce.easeOut, 0, 180, 1, true);
var ct1_6:Tween = new Tween(obj1, "x", None.easeNone, obj1.x, obj1.x=Math.floor(Math.random()*(1+HighH-LowH))+LowH, .2, true);
}
}
}
Also, it would be VERY helpful if there was a way to include everything below "//Drop in jar" in the array functions above so that this action script can be automatically applied to obj2 and obj3.
You have no code in there that limits the movement of the dragged object whatsoever. If you want to limit the object position simply pass a Rectangle object to the startDrag method.
Thanks BotMaster, based on your direction I modified my code like so:
var rectangle1:Rectangle = new Rectangle(400, -665, 1156, 1052);
var rectangle2:Rectangle = new Rectangle(-376, -665, 721, 1052);
var candyPosition:Point;
function dragCandy(e:Event):void {
if (e.currentTarget.x > 400) {
e.currentTarget.startDrag(false, rectangle1);
candyPosition = new Point( e.currentTarget.x, e.currentTarget.y);
} else {
e.currentTarget.startDrag(false, rectangle2);
candyPosition = new Point( e.currentTarget.x, e.currentTarget.y);
}
}
Basically, what happens here:
If the object is at an x position greater than 400, then dragging will be constrained to rectangle1
Once the object has been dragged to a specific x position outside of the jar, it will be tweened inside of the jar.
Now that the object is in the jar, its new x position will be less than 400 and dragging will now be constrained to rectangle2.
Now, when the object is dragged up our of the jar and on top of the hitTestObject, it will be tweened back to a random position out side of the jar.

Remove all created symbols from stage

I don't usually do this, but i'm lost here.
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.utils.Timer;
var first_tile:colors;
var second_tile:colors;
var pause_timer:Timer;
var game_timer:Timer;
var colordeck:Array = new Array(1,1,2,2,3,3,4,4,5,5,6,6);
function color_match() {
game_timer = new Timer(10000,1);
for (x=1; x<=4; x++) {
for (y=1; y<=3; y++) {
var random_card = Math.floor(Math.random()*colordeck.length);
var tile:colors = new colors();
tile.col = colordeck[random_card];
colordeck.splice(random_card,1);
tile.gotoAndStop(7);
tile.x = ((x-1)*70)+30;
tile.y = ((y-1)*100)+30;
tile.addEventListener(MouseEvent.CLICK,tile_clicked);
game_timer.addEventListener(TimerEvent.TIMER_COMPLETE,end_game);
addChild(tile);
}
}
game_timer.start();
}
function tile_clicked(event:MouseEvent) {
var clicked:colors = (event.currentTarget as colors);
if (first_tile == null) {
first_tile = clicked;
first_tile.gotoAndStop(clicked.col);
}
else if (second_tile == null && first_tile != clicked) {
second_tile = clicked;
second_tile.gotoAndStop(clicked.col);
if (first_tile.col == second_tile.col) {
pause_timer = new Timer(1000,1);
pause_timer.addEventListener(TimerEvent.TIMER_COMPLETE,remove_tiles);
pause_timer.start();
}
else {
pause_timer = new Timer(1000,1);
pause_timer.addEventListener(TimerEvent.TIMER_COMPLETE,reset_tiles);
pause_timer.start();
}
}
}
function reset_tiles(event:TimerEvent) {
first_tile.gotoAndStop(7);
second_tile.gotoAndStop(7);
first_tile = null;
second_tile = null;
pause_timer.removeEventListener(TimerEvent.TIMER_COMPLETE,reset_tiles);
}
function remove_tiles(event:TimerEvent) {
removeChild(first_tile);
removeChild(second_tile);
first_tile = null;
second_tile = null;
pause_timer.removeEventListener(TimerEvent.TIMER_COMPLETE,remove_tiles);
}
function end_game(event:TimerEvent) {
}
This is a little colour matching game. Click two tiles, they dissappear if matched, or turn back to grey if not. The loop creates instances of colour, in randomly placed pairs, and sets them to frame 7 (grey colour).
I cant work out how to remove any remaining colour blocks when the game time hits zero. Everything i try is throwing errors. The idea is then to let people play again, or a win script.
You don't have to necessarily code it for me, i just need to understand the process! Thanks.
I believe the best way is to create a container, so you can add all tiles and manage them on the best way you decide to.
var tileContainer:Sprite = new Sprite();
addChild(tileContainer);
// instead of addChild(tile);
tileContainer.addChild(tile);
// to remove all tiles
tileContainer.removeChildren();

AS3: Issues with multiple save/load slots

I'm trying to take this very simple "game" and give it three save/load slots. Following a separate tutorial I can make it work with a single save slot but once I try adding more, it gives me the following error message.
1046:Type was not found or was not compile-time constant: save2.
1046:Type was not found or was not compile-time constant: save3.
I am new to actionscript 3 so I'm sure I'm being very newbish but I have tried to figure this out for quite some time now but just can't seem to. The whole thing is controlled by buttons already placed on the scene. I appreciate any help I can get.
The code:
import flash.net.SharedObject;
var saveDataObject:SharedObject;
var currentScore:Number = 0
init();
function init():void{
btnAdd.addEventListener(MouseEvent.CLICK, addScore);
btnSave1.addEventListener(MouseEvent.CLICK, save1);
btnSave1.addEventListener(MouseEvent.CLICK, saveData);
btnSave2.addEventListener(MouseEvent.CLICK, save2);
btnSave2.addEventListener(MouseEvent.CLICK, saveData);
btnSave3.addEventListener(MouseEvent.CLICK, save3);
btnSave3.addEventListener(MouseEvent.CLICK, saveData);
btnLoad1.addEventListener(MouseEvent.CLICK, save1);
btnLoad1.addEventListener(MouseEvent.CLICK, loadData);
btnLoad2.addEventListener(MouseEvent.CLICK, save2);
btnLoad2.addEventListener(MouseEvent.CLICK, loadData);
btnLoad3.addEventListener(MouseEvent.CLICK, save3);
btnLoad3.addEventListener(MouseEvent.CLICK, loadData);
}
function save1(e:MouseEvent):void{
saveDataObject = SharedObject.getLocal("savefile1");
}
function save2(e:MouseEvent):void{
saveDataObject = SharedObject.getLocal("savefile2");
}
function save3(e:MouseEvent):void{
saveDataObject = SharedObject.getLocal("savefile3");
}
function addScore(e:MouseEvent):void{
currentScore += 1;
updateScoreText();
}
function saveData(e:MouseEvent):void{
saveDataObject.data.savedScore = currentScore;
trace("Data Saved!");
saveDataObject.flush();
trace(saveDataObject.size);
}
function loadData(e:MouseEvent):void{
currentScore = saveDataObject.data.savedScore;
updateScoreText();
trace("Data Loaded!");
}
function updateScoreText():void
{
txtScore.text = ("Score: " + currentScore);
trace("Score text updated");
}
I tried your code and it works like a charm...
Anyways, I've made a simpler version that doesn't use so many functions and Events.
Here is a pure AS3 version of it (just save it as Test.as3 and use as Document Class in Flash), but you can copy the content of the Test() method and paste in a action frame.
package
{
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.net.SharedObject;
import flash.text.TextField;
public class Test extends Sprite
{
public function Test()
{
/***** START: Faking buttons and field *****/
var txtScore:TextField = new TextField();
addChild(txtScore);
var btnAdd:Sprite = new Sprite();
var btnSave1:Sprite = new Sprite();
var btnSave2:Sprite = new Sprite();
var btnSave3:Sprite = new Sprite();
var btnLoad1:Sprite = new Sprite();
var btnLoad2:Sprite = new Sprite();
var btnLoad3:Sprite = new Sprite();
var items:Array = [btnAdd, null, btnSave1, btnSave2, btnSave3, null, btnLoad1, btnLoad2, btnLoad3];
for (var i:int = 0; i < items.length; ++i)
{
var item:Sprite = items[i];
if (item)
{
item.graphics.beginFill(Math.random() * 0xFFFFFF);
item.graphics.drawRect(0, 0, 100, 25);
item.graphics.endFill();
item.x = 25;
item.y = i * 30 + 25;
addChild(item);
}
}
/***** END: Faking buttons and field *****/
var saveDataObject:SharedObject;
var currentScore:Number = 0
btnAdd.addEventListener(MouseEvent.CLICK, addScore);
btnSave1.addEventListener(MouseEvent.CLICK, save);
btnSave2.addEventListener(MouseEvent.CLICK, save);
btnSave3.addEventListener(MouseEvent.CLICK, save);
btnLoad1.addEventListener(MouseEvent.CLICK, load);
btnLoad2.addEventListener(MouseEvent.CLICK, load);
btnLoad3.addEventListener(MouseEvent.CLICK, load);
function getLocal(target:Object):String
{
if (target == btnSave1 || target == btnLoad1)
{
return "savefile1";
}
else if (target == btnSave3 || target == btnLoad2)
{
return "savefile2";
}
else if (target == btnSave2 || target == btnLoad3)
{
return "savefile3";
}
}
function save(e:MouseEvent):void
{
var local:String = getLocal(e.target);
saveDataObject = SharedObject.getLocal(local);
saveDataObject.data.savedScore = currentScore;
trace("Data Saved!");
saveDataObject.flush();
trace(saveDataObject.size);
}
function load(e:MouseEvent):void
{
var local:String = getLocal(e.target);
saveDataObject = SharedObject.getLocal(local);
currentScore = saveDataObject.data.savedScore;
updateScoreText();
trace("Data Loaded!");
}
function addScore(e:MouseEvent):void
{
currentScore += 1;
updateScoreText();
}
function updateScoreText():void
{
txtScore.text = ("Score: " + currentScore);
trace("Score text updated");
}
}
}
}

#2007: Parameter format must be non-null?

i have a problem with my as3 code,
i try to link a movie clip to different scene (quiz scene).
so,i have 2 quiz in total, first quiz is using external script (as)
And the second quiz have the same script like first quiz, but i placed the action script inside fla. and it had different xml.
but then this error message appeared:
TypeError: Error #2007: Parameter format must be non-null.
at flash.text::TextField/set defaultTextFormat()
at hiragana/createText()[E:\flash\!!!! FLASH JADI\PAK ASHAR FIX\hiragana.as:80]
at hiragana/kuisdua()[hiragana::frame209:48]
at hiragana/frame209()[hiragana::frame209:249]
this is the code:
// creates a text field
public function createText(text:String, tf:TextFormat, s:Sprite, x,y: Number, width:Number): TextField {
var tField:TextField = new TextField();
tField.x = x;
tField.y = y;
tField.width = width;
tField.defaultTextFormat = tf; //looks like this is the source of problem (-.-)
tField.selectable = false;
tField.multiline = true;
tField.wordWrap = true;
if (tf.align == "left") {
tField.autoSize = TextFieldAutoSize.LEFT;
} else {
tField.autoSize = TextFieldAutoSize.CENTER;
}
tField.text = text;
s.addChild(tField);
return tField;
}
and this is the ettire code
import flash.display.*;
import flash.text.*;
import flash.events.*;
import flash.net.URLLoader;
import flash.net.URLRequest;
///*public class*/ kuisduaa extends MovieClip {
// question data
/*private*/ var dataXML2:XML;
// text formats
/*private*/ var questionFormat2:TextFormat;
/*private*/ var answerFormat2:TextFormat;
/*private*/ var scoreFormat2:TextFormat;
// text fields
/*private*/ var messageField2:TextField;
/*private*/ var questionField2:TextField;
/*private*/ var scoreField2:TextField;
// sprites and objects
/*private*/ var gameSprite2:Sprite;
/*private*/ var questionSprite2:Sprite;
/*private*/ var answerSprites2:Sprite;
/*private*/ var gameButton2:GameButton;
// game state variables
/*private*/ var questionNum2:int;
/*private*/ var correctAnswer2:String;
/*private*/ var numQuestionsAsked2:int;
/*private*/ var numCorrect2:int;
/*private*/ var answers2:Array;
/*public*/ function kuisdua() {
// create game sprite
gameSprite2 = new Sprite();
addChild(gameSprite2);
// set text formats
questionFormat2 = new TextFormat("Arial",80,0xffffff,true,false,false,null,null,"center");
answerFormat2 = new TextFormat("Arial",50,0xffffff,true,false,false,null,null,"left");
scoreFormat2 = new TextFormat("Arial",30,0xffffff,true,false,false,null,null,"center");
// create score field and starting message text
scoreField2 = createText("",scoreFormat,gameSprite,-30,550,550);
messageField2 = createText("Loading Questions...",questionFormat,gameSprite,0,50,550);
// set up game state and load questions
questionNum2 = 0;
numQuestionsAsked2 = 0;
numCorrect2 = 0;
showGameScore2();
xmlImport2();
}
// start loading of questions
/*public*/ function xmlImport2() {
var xmlURL:URLRequest = new URLRequest("kuis2.xml");
var xmlLoader:URLLoader = new URLLoader(xmlURL);
xmlLoader.addEventListener(Event.COMPLETE, xmlLoaded);
}
// questions loaded
/*public*/ function xmlLoaded2(event:Event) {
dataXML = XML(event.target.data);
gameSprite.removeChild(messageField);
messageField = createText("Tap Untuk Memulai",scoreFormat,gameSprite,-10,250,500);
showGameButton("mulai");
}
// creates a text field
/*public*/ function createText2(text:String, tf:TextFormat, s:Sprite, x,y: Number, width:Number): TextField {
var tField2:TextField = new TextField();
tField2.x = x;
tField2.y = y;
tField2.width = width;
tField2.defaultTextFormat = tf;
tField2.selectable = false;
tField2.multiline = true;
tField2.wordWrap = true;
if (tf.align == "left") {
tField2.autoSize = TextFieldAutoSize.LEFT;
} else {
tField2.autoSize = TextFieldAutoSize.CENTER;
}
tField2.text = text;
s.addChild(tField2);
return tField2;
}
// updates the score
/*public*/ function showGameScore2() {
scoreField2.text = "Soal: "+numQuestionsAsked2+" Benar: "+numCorrect2;
}
// ask player if they are ready for next question
/*public*/ function showGameButton2(buttonLabel:String) {
gameButton = new GameButton();
gameButton.label.text = buttonLabel;
gameButton.x = 240;
gameButton.y = 480;
gameSprite2.addChild(gameButton);
gameButton.addEventListener(MouseEvent.CLICK,pressedGameButton2);
}
// player is ready
/*public*/ function pressedGameButton2(event:MouseEvent) {
// clean up question
if (questionSprite2 != null) {
gameSprite2.removeChild(questionSprite2);
}
// remove button and message
gameSprite2.removeChild(gameButton);
gameSprite2.removeChild(messageField2);
// ask the next question
if (questionNum >= dataXML.child("*").length()) {
gotoAndStop(6);
} else {
askQuestion2();
}
}
// set up the question
/*public*/ function askQuestion2() {
// prepare new question sprite
questionSprite2 = new Sprite();
gameSprite2.addChild(questionSprite2);
// create text field for question
var question2:String = dataXML.item[questionNum].question2;
if (dataXML.item[questionNum].question.#type == "text") {
questionField2 = createText(question2,questionFormat2,questionSprite2,50,150,300);
} else {
var questionLoader2:Loader = new Loader();
var questionRequest2:URLRequest = new URLRequest("triviaimages/"+question2);
questionLoader2.load(questionRequest2);
questionLoader2.y = 150;
questionLoader2.x = 180;
questionSprite2.addChild(questionLoader2);
}
// create sprite for answers, get correct answer and shuffle all
correctAnswer2 = dataXML.item[questionNum2].answers.answer[0];
answers2 = shuffleAnswers(dataXML.item[questionNum2].answers);
// put each answer into a new sprite with a icon
answerSprites2 = new Sprite();
var xpos:int = 0;
var ypos:int = 0;
for(var i:int=0;i<answers2.length;i++) {
var answerSprite2:Sprite = new Sprite();
if (answers2[i].type == "text") {
var answerField2:TextField = createText(answers2[i].value,answerFormat2,answerSprite2,30,-35,200);
} else {
var answerLoader2:Loader = new Loader();
var answerRequest2:URLRequest = new URLRequest("triviaimages/"+answers2[i].value);
answerLoader2.load(answerRequest2);
answerLoader2.y = -22;
answerLoader2.x = 25;
answerSprite2.addChild(answerLoader2);
}
var letter:String = String.fromCharCode(65+i); // A-D
var circle:Circle = new Circle(); // from Library
circle.letter.text = letter;
circle.answer = answers[i].value;
answerSprite2.x = 100+xpos*250;
answerSprite2.y = 350+ypos*100;
xpos++
if (xpos > 1) {
xpos = 0;
ypos += 1;
}
answerSprite2.addChild(circle);
answerSprite2.addEventListener(MouseEvent.CLICK,clickAnswer); // make it a button
// set a larger click area
answerSprite2.graphics.beginFill(0x000000,0);
answerSprite2.graphics.drawRect(-50, 0, 200, 80);
answerSprites2.addChild(answerSprite2);
}
questionSprite2.addChild(answerSprites2);
}
// take all the answers and shuffle them into an array
/*public*/ function shuffleAnswers2(answers:XMLList) {
var shuffledAnswers2:Array = new Array();
while (answers2.child("*").length() > 0) {
var r:int = Math.floor(Math.random()*answers.child("*").length());
shuffledAnswers2.push({type: answers2.answer[r].#type, value: answers2.answer[r]});
delete answers2.answer[r];
}
return shuffledAnswers2;
}
// player selects an answer
/*public*/ function clickAnswer2(event:MouseEvent) {
// get selected answer text, and compare
var selectedAnswer2 = event.currentTarget.getChildAt(1).answer;
if (selectedAnswer2 == correctAnswer2) {
numCorrect++;
messageField2 = createText("Hai, kamu benar ! ",scoreFormat2,gameSprite2,-30,280,550);
} else {
messageField2 = createText("Iie, Jawabanmu Salah, yang benar adalah:",scoreFormat2,gameSprite2,53,280,370);
}
finishQuestion();
}
/*public*/ function finishQuestion2() {
// remove all but the correct answer
for(var i:int=0;i<4;i++) {
answerSprites2.getChildAt(i).removeEventListener(MouseEvent.CLICK,clickAnswer);
if (answers2[i].value != correctAnswer2) {
answerSprites2.getChildAt(i).visible = false;
} else {
answerSprites2.getChildAt(i).x = 200;
answerSprites2.getChildAt(i).y = 400;
}
}
// next question
questionNum2++;
numQuestionsAsked2++;
showGameScore2();
showGameButton2("Lanjutkan");
}
// clean up sprites
/*public*/ function CleanUp2() {
removeChild(gameSprite);
gameSprite2 = null;
questionSprite2 = null;
answerSprites2 = null;
dataXML2 = null;
}
the first quiz played perfectly with that code,
and i have no clue why this error appeared,
i'm beginner in as3 so i'm still lack in many ways,
can anyone help me,?
i really apreciate it.. :)
Are you sure that you're parsing a non-null TextFormat instance as the second argument of createText()?
The error means that you're supplying a null value for tf:TextFormat.
Unless I am missing something, your issue is here:
messageField2 = createText("Loading Questions...",questionFormat,gameSprite,0,50,550);
&
messageField = createText("Tap Untuk Memulai",scoreFormat,gameSprite,-10,250,500);
I see questionFormat2 and scoreFormat2 are instantiated, but I never see a questionFormat or scoreFormat. Your error says that the defaultTextFormat (or TextFormat supplied using setTextFormat(), for future reference), cannot be null. Null means that the object has not been instantiated/created yet. questionFormat and scoreFormat are never instantiated. Hell, their variables do not even exist. If you were using a proper development IDE (FlashBuilder, FlashDevelop, etc), you'd never be able to compile this code.
Switch those two lines to use the correct formats and you should be fine.

Chess board interface. Cannot remove child. Any suggestions?

Hello
I am in the process of creating a chess board where you can move the pieces. Currently i am working on the rook and the coding is below. I know it is not elegant and probably the most inefficient code out there, but this is day 2 of my actionscript 3.0 life and i am kinda a beginner. Anyway, so the thing is, when you click the piece the code below figures out the possible ways to go. Then green squares appear at those places. You can then press those green squares and then the rook will move there.
Ok, now to the problem. The squares will not go away. I want them all to be deleted when i have clicked on one of them and the rook will move there.
I have tried removeChild(), but since that happens in a different function it does not work. So if you are so kind to look through the code and suggest a solution, your help is much appreciated.
Kind Regards Emile
https://picasaweb.google.com/109156245246626370734/Jun42011?authkey=Gv1sRgCMy4v_b01aikzAE&feat=directlink
import flash.display.Sprite
import flash.events.MouseEvent
import flash.text.TextField;
import flash.geom.Point;
import caurina.transitions.*
myPoint.addEventListener(MouseEvent.MOUSE_DOWN, startMove);
function startMove(evt:MouseEvent) {
var boxNum:int = Math.floor(myPoint.y/100)+1;
for (var i:int = 1; i <boxNum; i++) {
var box:Ball = new Ball();
box.x = myPoint.x;
box.y = myPoint.y - i * box.height;
addChild(box);
Tweener.addTween(box, {alpha:0.5});
box.buttonMode = true;
box.addEventListener(MouseEvent.ROLL_OVER, onOver,
false, 0, true);
box.addEventListener(MouseEvent.ROLL_OUT, onOut,
false, 0, true);
box.addEventListener(MouseEvent.MOUSE_DOWN, onclick);
}
var boxNum1:int = Math.floor((800-myPoint.y)/100)+1;
for (var i:int = 1; i <boxNum1; i++) {
var box1:Ball = new Ball();
box1.x = myPoint.x;
box1.y = myPoint.y + i * box.height;
addChild(box1);
Tweener.addTween(box1, {alpha:0.5});
box1.buttonMode = true;
box1.addEventListener(MouseEvent.ROLL_OVER, onOver,
false, 0, true);
box1.addEventListener(MouseEvent.ROLL_OUT, onOut,
false, 0, true);
box1.addEventListener(MouseEvent.CLICK, onclick);
}
var boxNum2:int = Math.floor(myPoint.x/100)+1;
for (var i:int = 1; i <boxNum2; i++) {
var box2:Ball = new Ball();
box2.x = myPoint.x - i * box.height;
box2.y = myPoint.y;
addChild(box2);
Tweener.addTween(box2, {alpha:0.5});
box2.buttonMode = true;
box2.addEventListener(MouseEvent.ROLL_OVER, onOver,
false, 0, true);
box2.addEventListener(MouseEvent.ROLL_OUT, onOut,
false, 0, true);
box2.addEventListener(MouseEvent.CLICK, onclick);
}
var boxNum3:int = Math.floor((800-myPoint.x)/100)+1;
for (var i:int = 1; i <boxNum3; i++) {
var box3:Ball = new Ball();
box3.x = myPoint.x + i * box.height;
box3.y = myPoint.y;
addChild(box3);
Tweener.addTween(box3, {alpha:0.5});
box3.buttonMode = true;
box3.addEventListener(MouseEvent.ROLL_OVER, onOver, false, 0, true);
box3.addEventListener(MouseEvent.ROLL_OUT, onOut, false, 0, true);
box3.addEventListener(MouseEvent.CLICK, onclick);
}
}
function onOver(evt:Event):void {
var box:MovieClip = MovieClip(evt.target);
addChild(box)
box.scaleX = box.scaleY = 1.1;
}
function onOut(evt:Event):void {
evt.target.scaleX = evt.target.scaleY = 1;
}
function onclick(Event:MouseEvent):void {
var xcod:int = Math.ceil(mouseX/100)*100-50;
var ycod:int = Math.ceil(mouseY/100)*100-50;
Tweener.addTween(myPoint, {x:xcod, y:ycod, time:1, transition:"linear"});
}
alxx's answer is correct, you wouldn't need to keep a special list for them. The other way you could do it, using an Array to save references, would look like this:
var boxes:Array = new Array();
function startMove(evt:MouseEvent):void {
...
var box:Ball = new Ball();
addChild(box);
boxes.push(box);
...
var box1:Ball = new Ball();
addChild(box1);
boxes.push(box1);
...
}
function onClick(evt:MouseEvent):void {
for each (var box:Ball in boxes) {
removeChild(box);
}
boxes = new Array();
}
You can put temporary highlights in separate Sprite. Then your board will looks as follows:
Stage children: base board, highlights, pieces, in that order.
When you need to remove highlights, you can iterate highlights' children with numChildren and getChildAt and call removeChild on each, you don't even need a special list for them.