Interaction between classes - actionscript-3

In my main Actionscript file i have a instance of a body class that moves the person body arms legs etc. and a gun class which has methods and properties to do with the person gun.
Right now i have a function in the Main class which is called move gun and looks like this and is called everyframe to move the gun to the bodys arm. I was hoping to move this function to the guns class so i could call it like gun.moveGun(); but the body dosent exist inside the gun variable. so i wonder if i could call the body.getArm(); function from inside the gun. I know i could call the function and pass the bodys arm location to it from the main file. But don't know if this is the best way to do it.
private function moveGun():void
{
gun.x = body.getArm('left').x;
gun.y = body.getArm('left').y;
}
It seems like keeping the gun related functions inside the gun class is the best way to organise everything but i dont know how to do this.
Also depending what button someone clicks at the start the person will either have a basketBall or gun in there hand. Ive added the swf online at Here so you can see how it works. i just wanna change how its organised because the main file is very full and though i should learn how to organise things better. There are lots of other part of the program that would be organised better if i knew how to get the object to interact or what is the best way to do it. Starting to think passing the x,y coordinates to the moveGun function inside the gun Class is the best way. If so just tell me please and ill do that.

From the code you posted, I think you need to move the gun with every frame to stick to the player's arm.
The answer you're looking for is Composition, since every person gets one and only one gun, I think you better put a reference (variable) in the person class for its gun.
and here is your player (person) class:
class Person
{
private var m_gun:Gun;
public function Person()
{
this.m_gun = new Gun();
}
// a function which is called each frame
private function updateFrame()
{
// Here you can provide your own logic in Gun class
this.m_gun.doSomething();
}
}

generally, you want to communicate between classes using the built-in event listener and dispatcher system. if 'something' happens - regardless of 'where' that occurs - dispatch an event. whenever something should react, it should have a listener.
for example, from the main class you mentioned, you might want to dispatch an event:
private function moveGun():void
{
var e:Event = new Event('moveGun', true);
dispatchEvent(e);
}
then the appropriate instance (the body? - not sure how you have things set up) listen for that:
body.addEventListener('moveGun', moveGunHandler, false, 0, true);
function moveGunHandler(event:Event):void{
gun.x = body.getArm('left').x;
gun.y = body.getArm('left').y;
}
the above is obviously psuedo-code since i have no way of knowing how your display list is set up. also, i used simple string literal event types - best practice would probably be to use custom event classes with event types defined as static constants.

Related

AS3 - Get reference of instance who called a function

I have two classes, "player" and "Stickman", "player" extends "Stickman".
The class "Stickman" contains functions that all characters will have in the game such as moving and handling animations (all use the same animations) while the "player" class contains player-exclusive actions.
When I call an action from a player instance that is inherited from the "Stickman" base class, how do I correctly point (from the stickman base class) to that player instance that called the function?
For example, to handle running animations
Trigger code in player.as:
moveType("running");
moveType function in Stickman.as:
public function moveType(type:String):void{
this.gotoAndPlay("running");
trace("testing");
}
To start playing frame with frame label "running" inside the player object (which is an extend of Stickman). I know this doesn't work, so I would like to replace this with something that would point to the caller of the function (i.e. the player object).The trace statement still runs so there (should) be no problem with the linkage. Is there a way to do this without passing the childId of the player object?
It's all about so called inheritance. Player IS actually a Stickman. So when you call moveType you are calling it ON Player object. If you don't have such function inside it, it looks up in the inheritance chain, and finds it inside Stickman.
Inheritance is one-directional. Which means that Player knows all methods of Stickman, but the opposite is not true - Stickman works only by itself and does not know who extended it and who not.
That said - you must use the Player class as a starting point and decide what to do from there on.
Long story short - you need to override the function from Stickman into Player and then decide what to do and what not. Example:
Stickman:
public function move(type:String):void {
this.gotoAndPlay(type); // regular workflow for reach Stickman
}
Player:
override public function move(type:String):void {
if (type == 'player_specific') {
this.gotoAndPlay('frameAvailableOnlyForPlayerClip');
// maybe something else, player specific, like play sound or smth else
} else {
super.move(type); // calls whatever is inside Stickman::move
}
}
Remember - this is always the very same object that you are calling the function for. But you can decide if you want something specific (player case) or you want the very usual flow. super.move will call what's in the parent class.
Inheritance is very important and I cheer you for deciding to use it! With a little more practice you will master it!

Flash Platformer Game changing between two characters

So I'm new to coding as a whole and though I've messed a little with AS before I'm at an absolute loss. I've been using a pretty helpful website that gives a step-by-step on making a platformer/sidescroller, but one of the key things I want to include in my game is the ability to swap between two characters- i.e., if the player hit space or any other key, you could swap out to the other character (with different abilities and all).
My game only really has one big stage, and it's nothing complicated at all (it's something I'm trying to get done in about a little over 24 hours) which is why I decided not to make the character change for each "level"- because there's only one big one. I want the player to be able to decide when they want to play whichever character they fancy, but I have no idea how to go about it.
Uh, and if it helps clarify anything, I basically tried to follow that tutorial site as closely as I could without copying source code.
Thanks so much for taking the time.
You need to do a thing named "separate graphics from code". The tutorial says "convert your player to a Movie Clip Symbol ... create new Player(), add it to stage", then it teaches about how to control the player. You need to split your Player class into two, one remains as Player and contains code, the other is a skin class, barely a MovieClip without code. In your Player class you need to make a method to operate skins, the interface is up to you, I suggest a string lookup of a skin class, then you can tell your player to change skins both at costruction time and probably at runtime. An example:
public static const SKIN_DEFAULT:String="default";
public static const SKIN_RED:String="red";
public static const SKIN_BLUE:String="blue";
private static var SKINS:Object={
SKIN_DEFAULT:DefaultFace;
SKIN_RED:RedFace;
SKIN_BLUE:BlueFace;
}
Here, SKINS is a lookup object with keys as strings and value as Class references, these are the MovieClip symbol names an example expects to exist. Say you want a gray blob, a red angry face and a blue smiley save to be available, you name them DefaultFace, RedFace, BlueFace and put these names into this lookup object. Then, you need to make your player change skins. It's pretty easy once you get the drill.
public class Player extends Sprite {
// Sprite should do, as Player is now code-only
private var skin:MovieClip; // this will hold our player's skin
public function setSkin(newSkin:String):void {
// call this to change the skin
var newSkin:Class=SKINS[newSkin] as Class;
if (newSkin==null) return; // sanity check
if (skin) if (skin is newSkin) return;
// ^ changing skin for the same? We're that skin already!
if (skin) if (contains(skin)) removeChild(skin); // remove old skin
skin=new newSkin(); // create a new skin object
addChild(skin); // make it attached to the player
} // we're done!
// rest of code here
}
Make sure that your Player will at least put on default skin when created, or else you won't be able to see player move.
In order to trigger skin change, you can create an array of buttons, up to making them out of all possible SKINS (for this, either expose SKINS variable by declaring it public instead of private as it's now, or provide another means to get the list of classes), which will call player.setSkin() with a correct parameter.

Pros and Cons of creating a separate class for the GUI (in actionscript)

This is related to a similar question I just asked; however, this one is specifically tailored to my individual project, rather than object-oriented programming in general.
I am working on a version of hangman with some interesting programming twists. I don't need to go into detail of what they are as the logic for the game is already finished. I can run an entire game by hard-coding variables for the user input (such as guess selection). I am now in the process of replacing all those bits that require user interaction with the trappings of an actual game like buttons, images, sounds, etc.
I am trying to figure out whether it is better to have all of this stuff be part of my main class, or whether I should create another class to handle it all. For example, I want my players to be able to click on an on-screen keyboard to make their guess, with each button firing a separate event listener call to the makeGuess function. Would it be better to create the buttons as direct children of my main game class, or should I create a subclass (called Keyboard, for example) that creates the keyboard section of the board with the appropriate events, then add the keyboard class as a child to the main rather than all the pieces? What are the pros and cons of each of these choices?
For the record, I'm programming using FlashDevelop, so nothing like a timeline for me.
I say you'd better create at least the Keyboard class that will parse the events fired by tapping/clicking keys inside, and give it a callback reference to your Main class, or GameLogic class, so that it can do theMain.guess(letter); and then the Main class logic will come to life and process the callback. Since this structure is not exactly related to game logic, and technically it can then be reused by implementing an interface for the callback, so that you can use this keyboard elsewhere where you want to have your player to type letters using mouse, it's better be separated from main logic.
public class Keyboard extends Sprite {
public var callback:AcceptingKeys; // an interface
... // class implementation, with all the listeners, children and stuff
// and you call in there: callback.acceptKey(key);
}
public interface AcceptingKeys {
public function acceptKey(key:String):void; // or whatever type you need
}
And you do with your Main class:
public class Main extends Sprite
implements AcceptingKeys {
...
var keyboard:Keyboard;
private function init(e:Event=null):void {
... // other code. It's FD, then this function exists
keyboard=new Keyboard();
keyboard.callback=this;
// past this point your instances can talk
}
public function acceptKey(key:String):void {
// match interface description
... // do game logic for parsing a key
}
}

Unable to access children in movie clip

Inside flash cs6 I have drawn a flash movieclip in which I set export settings as abc.Gameboard. Inside gameboard I have a bunch of pieces (symbol:Piece) which I export as abc.Piece - both base class set to MovieClip and with class files. The piece has frame labels like hit, over etc.. My problem is accessing the pieces in code so I can eg. gotoAndPlay("mine") - at the moment the event only fires once which is the last piece on the board.
I can set the frame action on this last piece but would like to figure out how to do same for each piece.
I add a gameboard to the stage like so
var gb:Gameboard = new Gameboard();
gb.name = "gb001";
contextView.addChild(gb);
Then
contextView.addEventListener(Event.ADDED, thingAdded);
private function thingAdded(event:Event):void
{
var type:String = event.target.toString();
switch(type)
{
// this runs only once - i want it to run for each piece that is inside the symbol
case "[object Piece]":
var p:MovieClip = event.target as Piece;
p.gotoAndPlay("mine");
break;
}
}
or if there's a better way that would be great.. this looks pretty clunky
Edit: Bit more info about how I'm trying to build the gameboard
Draw a collection of shapes in illustrator - mask it (Gameboard region). Import into Flash as Graphic. Convert graphic to several movie clip symbols (So JSFL can drill down and access masked pieces) - run JSFL script & create 00's of pieces. Then I set export settings on Piece and Gameboard and add Gameboard to the contextView.
I actually wrote an entire article about this once. The ADDED event should fire once for every DisplayObject that gets added. Are you sure that you're not using ADDED_TO_STAGE, which does not bubble? If you're using ADDED_TO_STAGE, then you need to set the useCapture flag to true to get it to fire for all children.
If you want to involve RobotLegs in the process, probably the better way is to simply create a "marker" Class for each specific button that you want to have behave in a different way, then register a mediator for each Class that will manage the behvior. Robotlegs already has the hooks built in to listen for ADDED_TO_STAGE and do this.
However, you could also consider using the Flash IDE for what it's for, which is putting stuff on stage. In that case, your GameBoard instance will be ready in the constructor of your main document Class for you to do whatever you want with it.
MPO is that logic that is outside Gameboard shouldn't know or care how it works internally, and honestly it probably shouldn't even be GameBoard's responsibility to handle simple stuff like button over states and things. That should be up to the button itself. If the buttons don't need to toggle or anything beyond what SimpleButton handles, you can just declare the button instances as Button in the library instead of MovieClip and get all that stuff for free instead of coding it yourself.
Part of being a good coder is in being able to figure out ways not to code everything.
in their Gameboard inside Piece? I want know exactly your Gameboard Structure.
If you're right. try this:
function thingAdded(e:Event):void
{
if(!e.target is Gameboard) return;
var mc:Gameboard = Gameboard(e.target);
var i:int = 0;
while(i<mc.numChildren)
{
if( mc.getChildAt(i) is Piece)
{
var piece:Piece = Piece(mc.getChildAt(i));
piece.gotoAndStop(2);
}
i++;
}
}
Here is my Sample code: Gameboard

GUI - Call setters or dispatch events?

I'm in the process of developing an advanced modular GUI system. I need it to be as flexible as possible and hopefully as useful to as many people as possible (however it will be reasonably niche).
The part of my design that is causing me to think, is how each component should best interact with the rest of the application.
I see two approaches:
Pass in the class and name of a setter, on which the component should act upon. This still allows events to be dispatched from within the setter if desired.
Pass in a CustomEvent which the component should dispatch, with relevant data. Though I feel this may lead to a lot of Event Listeners, and extra complexity.
But What is best practice? What are the pros and cons of each? Is there a better method?
Basic example:
public class Button extends Sprite
{
private var _property:String;
private var _object:*;
public function Button(label:String, object:*, property:String)
{
_property = property;
_object = object;
addEventListener(MouseEvent.CLICK, onClick);
}
private function onClick(e:MouseEvent):void
{
_object[_property] = "Changed";
}
}
Basic Example:
public class Button extends Sprite
{
private var _event:GuiEvent;
public function Button(label:String, event:GuiEvent)
{
_event = event;
addEventListener(MouseEvent.CLICK, onClick);
}
private function onClick(e:MouseEvent):void
{
dispatchEvent(new GuiEvent(_event.type, "Changed"));
}
}
If you want your GUI framework to be useful to everybody, you should use standard events instead of inventing new ones. The second option is the way to go but you should try to keep things simple. The code you wrote in example 2 seems incredibly complicated. It could simply be written like that:
public class Button extends Sprite
{
public function Button(label:String)
{
}
}
Then anybody can handle clicks using the event they know:
button.addEventListener(MouseEvent.CLICK, onClick);
Slightly offtopic and not really an answer to your question:
Why recreate something that already exists? There are already proven libraries with GUI components.
For example, take the AS3 Temple Library
http://code.google.com/p/templelibrary/
It has all types of form element components; checkbox, radiobutton, combobox, inputfield, filefield, scrollcomponent, date selectors, (step)sliders, list, scrollbars, autocomplete field and all types of buttons.
It also has a Form class, whichs helps in validation, deliver data to any type of services. It also manages the tabindexes right and all controls can be used with keyboard too, just like everyone expects it to work. There are also codecomponents for a mockup, but you can use the same code to style it with endless creativity with library items, timelines, or however you want it. Most of the gui components are designed so they can be extended to make it fit your needs.
Most of the gui components work with normal eventlisteners (most dispatch Event.CHANGE when content change), in most cases there is no need to wrap it into new type of events.