I have this repeating pattern thoughout my code:
var scroller:Object = target;
while(scroller != null && !(scroller is Scroller) ) {
if(scroller.hasOwnProperty('parent')) {
scroller = scroller.parent;
} else return;
}
What I want is to make a generic function to call like so:
var scroller: Scroller = Scroller(dotParent(target, Class(Scroller)));
But I'm new to the language (I come from C#), so I don't know what to use for the comparison. I need it to handle any type, not just scrollers.
Here is the example of a such function:
protected function dotParent(target:DisplayObject, parentClass:Class):DisplayObject
{
var res:DisplayObject = target;
while(res && !(res is parentClass))
{
if(res.parent)
{
res = res.parent;
}
else
{
return null;
}
}
return res;
}
Test:
//create test display list: stage->movieclip->sprite
var sp:DisplayObject = (addChild(new MovieClip()) as MovieClip).addChild(new Sprite());
var st: Stage = dotParent(sp, Stage) as Stage;
trace(st);
var mc: MovieClip = dotParent(sp, MovieClip) as MovieClip;
trace(mc);
var sh: Shape = dotParent(sp, Shape) as Shape;
trace(sh);
output:
[object Stage]
[object MovieClip]
null
Please can you help me out I am new to as3 and I am trying to create a shuffled deck using the Fisher-Yates Algorithm. When I run the code with ctrl-enter it compiles with no errors but when I try to output it with trace(); it comes back with:
Scene 1, Layer 'actions', Frame 1, Line 6 1120: Access of undefined property shuffledArray.
Like I said I am new to this and it will be me doing something very stupid but all the same i'm stuck.
Here is the code
package src.CardDeck
{
public class CardDeck
{
public var allCards:Array = [];
public var cardNames:Array;
public var cardValues:Array;
public var gameType:String;
public var drawnCards:uint = 0;
public function CardDeck(game:String)
{
gameType = game;
cardNames = ["Ace","Two","Three",
"Four","Five","Six",
"Seven","Eight","Nine",
"Ten","Jack","Queen","King"];
if(gameType == "texasholdem")
{
cardValues = [1,2,3,4,5,6,7,8,9,10,10,10,10];
}
makeSuit("Spade");
makeSuit("Heart");
makeSuit("Diamond");
makeSuit("Club");
}
function makeSuit(suitString:String):void
{
var card:Object;
for(var i:uint = 0; i < cardNames.length; i++)
{
card = {};
card.cardType = suitString;
card.cardName = cardNames[i];
card.cardValue = cardValues[i];
card.isDrawn = false;
allCards.push(card);
}
}
public function shuffleFisherYates():Array
{
var shuffledArray:Array = [];
var randomCardIndex: int;
do
{
randomCardIndex = Math.floor(Math.random()* allCards.length);
shuffledArray.push(allCards[randomCardIndex]); // add to mix
allCards.splice(randomCardIndex,1); // remove from deck
}while(allCards.length); // Meaning while allCards.length != 0
return shuffledArray;
}
}
}
and here is the .fla actions layer
import src.CardDeck.CardDeck;
var deck:CardDeck = new CardDeck("texasholdem");
trace(shuffledArray);
I know its probably something silly but i'm struggling.
Thanks in advance!
Paul
var deck:CardDeck = new CardDeck("texasholdem");
trace(shuffledArray);
This doesn't work because shuffledArray isn't defined there.
Try :
var deck:CardDeck = new CardDeck("texasholdem");
var array:Array = deck.shuffleFisherYates();
for(var i:int=0; i<array.length; i++)
{
trace(array[i].cardName);
trace(array[i].cardType);
trace(array[i].cardValue);
trace(array[i].isDrawn);
}
"shuffledArray" is a property inside of your CardDeck object. To access public methods and properties within it, you need to use the dot syntax:
trace(deck.shuffleFisherYates());
However, depending on what you are doing, you may not need to really be accessing the array directly, if your CardDeck object is meant to control the entire deck.
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.
Hello I have this bit of code, and it what it must do is when there is some class (always extending the Box class) that must be spawned if there is already one of the same type it loads that one and if there is no one it creates a new one.
private var _l:Vector.<Box> = new Vector.<Box>();
public function respawn(shapeId:int, className:String = "Box"):Class {
var l:int = _l.length, i:int;
var c:Class;
var ct:Class = getDefinitionByName(className) as Class;
for (i = 0; i < l; i++) {
c = _l[i];
if (!c.active && c.shapeId == shapeId) {
return c;
}
}
c = new ct();
_l[l] = c;
return c;
}
If I try this code it generates these errors:
Implicit coercion of a value of type com.shapes:Box to an unrelated type Class.
Implicit coercion of a value of type Class to an unrelated type com.shapes:Box
How can I fix this so I can create different types of classes that all extend the Box class and get them into a Vector.<Box>?
Object is the superclass of all ActionScript classes, not Class.
Besides, you can:
var box:Object = new Box();
But you can not:
var box:Box = new Object();
Like Max Golovanchuk said I had to target the Object and not the class.
public function respawn(shapeId:int, className:Class):Object {
var l:int = _l.length, i:int;
var c:Box;
for (i = 0; i < l; i++) {
c = _l[i];
if (c.shapeId == shapeId) {
return c;
}
}
c = new className();
_l[l] = c;
return c;
}
I'm trying to mix two tutorials in one game. Level 3 is previously used in a action script file but I transferred it into a normal AS3 timeline.
I get this error:
ArgumentError: Error #1063: Argument count mismatch on adventure_fla::MainTimeline/newObjects(). Expected 0, got 1.
at flash.events::EventDispatcher/flash.events:EventDispatcher::dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at flash.utils::Timer/flash.utils:Timer::tick()
This is the code... sorry if its messy.
const speed:Number = 5.0;
var nextObject:Timer;
// array of objects
var objects:Array = new Array();
function initGame():void{
player.x=200;
player.y=400;
stage.addEventListener(MouseEvent.MOUSE_MOVE,movePlayer);
Mouse.hide();
player.gotoAndStop("arrow");
setGameTimer();
newObjects();
addEventListener(Event.ENTER_FRAME, moveObject);
}
function movePlayer(e:MouseEvent):void{
player.x=mouseX;
e.updateAfterEvent();}
function setGameTimer():void {
trace("GAME TIMER STARTED");
var gameTimer:Timer = new Timer(40000, 1);
gameTimer.addEventListener(TimerEvent.TIMER_COMPLETE, endGame);
gameTimer.start()
}
function endGame(e:Event):void {
trace("Game Over");
// remove all objects
for (var i:int=objects.length-1; i>=0; i--) {
removeChild(objects[i]);
objects.splice(i, 1);
} }
function setNextObject():void {
nextObject = new Timer(1000, 1);
nextObject.addEventListener(TimerEvent.TIMER_COMPLETE, newObjects);
nextObject.start();
function newObjects():void{
//create next object
// array of good and bad objects
var badObjects:Array = ["Bad_1", "Bad_2"]
var goodObjects:Array = ["Good_1", "Good_2"]
// create random number
if (Math.random() < .5 ) {
//based of treat object length
var r:int = Math.floor(Math.random()*goodObjects.length);
// get the treat object by name and cast it as its own class in a temporary variable
var classRef:Class = getDefinitionByName(goodObjects[r]) as Class;
// now we can make a new version of the class
var newObjects:MovieClip = new classRef();
// dynamic var (because mc is an object) typestr it as good
newObjects.typestr = "good";
} else {
// for bad same as above
r = Math.floor(Math.random()*badObjects.length);
var classRef:Class = getDefinitionByName(badObjects[r]) as Class;
var newObjects:MovieClip = new classRef();
// typestr it bad
newObjects.typestr = "bad";
}
// random pos
newObjects.x = Math.random()* 500;
newObjects.scaleX = newObjects.scaleY = .4;
addChild(newObjects);
// push it to array
objects.push(newObjects);
// create another one
setNextObject();
}
function moveObject(e:Event):void {
// cycle thru objects using a for loop
for (var i:int=objects.length-1; i>=0; i--) {
//move objects down based on speed
objects[i].y += speed;
objects[i].rotation += speed;
// if objects leaves the stage
if (objects[i].y > 400) {
removeChild(objects[i]);
objects.splice(i, 1);
}
}
}
newObjects does not take any arguments, but it's used as an event listener (which requires it to take the event object).
It should probably look something like function newObjects(event:TimerEvent):void.
A function used as event listener should accept one parameter of type Event, depending on what class of events it listens to. You are listening to an event of a TimerEvent class, so yes, declare parameter as TimerEvent. To add a function that does not need parameters passed to it as an event listener, use default value construction like this:
function newObjects(event:TimerEvent=null):void {...}
The "=null" addition will allow you to pass no parameters to your function, and the declared parameter will allow you to not get exceptions when it will be called as an event handler.