Changing the skin of a player - actionscript-3

I'm trying to make a game where the skin of my player would change in a particular scene only.
First, I've got a movieClip with frame names for specific character states. So when the code wants the character to look like it's walking it goes to the frame named "walk". The code goes like this :
public function startWalking(inputX:Number, inputY:Number):void{
targetX = inputX;
targetY = inputY;
getIncrements(targetX, targetY);
gotoAndStop("walk");
addEventListener(Event.ENTER_FRAME, walk, false, 0, true);
addEventListener("reachedPoint", stopWalking, false, 0, true);
dispatchEvent(new Event("playerWalking"));
Same thing for the standing position with a frame "default".
In order to change the skin of my player in a particular scene, I added a whole new frame for each of these states that is the name of the state plus the skin name, and I've created a set of animations that represent the new skin:
Using "walk" as an example:
Basic frame name: "walk"
Car skin frame name: "walkcar"
So, I've added a String variable called something like "skinValue":
public var skinValue:String;
And then in code I change the code from:
gotoAndStop("walk")
to:
gotoAndStop("walk"+skinValue)
I want to set the "skinValue" to "car", in this way the code "walk"+skinValue would evaluate to "walkcar" and it would go to the car frame.
But, I've got a problem with setting "skinValue"... And I really can't figure out how to define it properly...
If someone could help, it'll be awesome.
Thx.

When you go to a new scene, then you will get a key, like "car".
Your role movieclip will provider a function like
public function goToScene(sceneKey:String):void {
gotoAndStop("walk" + sceneKey)
}

Related

How to use CitrusSprite.velocity

I have the following function in a scene that extends citrus.core.starling.StarlingState - it loads the PlayerRun animation and displays it on the screen. For the most part, this code works: I see the sprite on the screen (it's running in place).
protected final override function DrawScene ():void
{
Player = new CitrusSprite ( "Player" );
Player.velocity = [60, 0]; // Doesn't seem to have an effect
Player.x = 40;
Player.y = 40;
var oClip:MovieClip = new MovieClip ( Resources.getTextures (
"PlayerRun" ), 24 );
Player.view = oClip;
add ( Player );
}
I'm not sure how I'm supposed to use the velocity property - there's no documentation for it and no matter what numbers I use in the code above, it doesn't change the display: the animation plays but the sprite is stationary (it doesn't move horizontally as I would expect it).
Am I using the velocity property incorrectly? Does Citrus support sprite velocity or is this something I'd have to implement myself?
As it turns out, CitrusSprite has a property, updateCallEnabled that's false by default and disables calls to update(). Once I set this property to true, the code started working as expected.
I haven't used Citrus yet, but looking at the source code it should work the way you've gone about it assuming that the update method is called on your player:
You can review the way the velocity property works at these locations:
The getter and setter for velocity.
The update loop for CitrusSprite.
MathVector, the type used for velocity internally.
I suspect you need to add the player to something that will queue it for updating.

AS3 - How can I change contents of all the same Movieclips runtime?

So, basically, what I want to do is replace the contents of a sword MovieClip that's inside a Player MovieClip already, and is animated, so it has multiple instances of the sword MovieClip across the Player MovieClip.
Can I somehow edit the contents of the sword MovieClip in actionscript so as all the sword MovieClips update and are changed?
What I want to achieve is just changing weapons of a character animation that doesn't require me to await every frame and removeChild() the previous weapon and addChild() the new one of every instance of the weapon.
I'm not sure I'm getting it but Maybe you need a weapons event class
package WeaponEvents{
import flash.events.Event;
[Event(name="sword1", type="event.sword1")]
[Event(name="sword2", type="event.sword2")]
public class SwordEvent extends Event
{
public static const SWORD_1 : String = "sword1";
public static const SWORD_2 : String = "sword2";
public var arg:*;
public function SwordEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false, ... a:*) {
super(type, bubbles, cancelable);
arg = a;
}
// Override clone
override public function clone():Event{
return new LoadEvent(type, bubbles, cancelable, arg);
}
}
}
Just add the event to when your user chagnes weapons.
I'm in a similar boat as you. Except I have 30-50 bodyparts to cover, so I really can't go the brute force way.
If it's just sword that you want replace though, I assume in the animation it is on its own layer? Then a "cheap way" I found is:
Copy paste all frames in that layer (and only that layer) into another movieclip i.e. Sword1Swing.
Remove that layer (and only that layer) from your MC animation.
In yet another movie layer, put Sword1Swing on frame 1, Sword2Swing on frame 2, etc.
MC.gotoAndStop("SwordSwing"); SwordMC.gotoAndStop("Sword1Swing");
As long as you keep the .x and .y of the SwordMC synchronized with MC, the animation should always line up.
Hand often goes over the top of the sword, in which case... You can copy the hand too. Or the whole arm. Or you can custom shape your sword symbol's basic graphics in the library to match exactly with the empty spaces between fingers (copy and paste hand graphics in place to remove unwanted portions, then delete the hand graphics, then you'll have the perfect shape).
It's the ghetto way I know, I am very much in need of an actual efficient swapping. But this may help you to get through the project fast.

AS3. How to set-up players for real-time game?

I'm creating flash fighting game 1vs1.
Here is Hero (local-player) and Enemy (remote-player). How I need to setup them correctly that after connection to arena they will be spawned successfully?
I mean if player 1 connects to arena he should be declared as Hero (local-player) and for him player 2 should look like Enemy (remote-player).
The same for player 2. He should be declared as Hero (local-player) and for him player 1 should look like Enemy (remote-player).
Here are 2 character's templates to choose and here is code:
public function selectHero(what:int):void {
// this is called with correct "what", design yourself. I use array index
var whatHero:Class = heroes[what]; // get selected hero symbol
if (Hero && Hero.parent) Hero.parent.removeChild(Hero);
// clean up previous hero. Drop listeners here, if any
Hero = new whatHero(); // get new hero
// process as usual, don't forget to "addChild(Hero)" somewhere
create_hero();
}
function choosePlayer(event:MouseEvent):void {
selectHero(0); // here choose first template
start(event);
}
function create_hero()
{
addChild(Hero);
}
So Hero added to stage (It is local-player).
This is how I declare Enemy:
public var Enemy:Priesas = new Priesas; //Priesas is instance name of Enemy
So as I understand I don't need to use addChild(Enemy); because will be added just template, how to add remote-player Hero (from other computer) that will be declared as Enemy? Or something like that.
This game is creating for Facebook. For that is needed AppWarp? Thank you for answers.
Yes, you would need AppWarp to connect the two players and to exchange messages between them. This seems similar to one of the samples of AppWarp (smiley space shooter). Have you already explored the samples and documentation?
http://appwarp.shephertz.com/game-development-center/actionscript3-game-developers-home/

How can I give flash stage instances unique properties in Flash Professional to pass to AS3 script?

I've started building a rough game engine framework in Flash Professional and I'm curious how I can create objects in the Flash library that I'm able to drag onto the stage and assign properties that are accessible from AS3.
Example:
I want to create a switch object (e.g. a light switch), so that when the player interactes with it, it triggers something specific in code such as a light in the room turns on.
I understand that Flash has built in UI components that you can define properties within the Flash Professional environment (see image below), and I'm wondering if there's a way to create my own custom style components so that I can essentially have my level file open in flash (.fla) and then drag a switch component from my library, and type in some information such as what light it is controlling, and any other information I want.
(above is an example of the type of parameter control I'm looking for)
I've read a bit about extending the flash UIComponent class but I feel that that's not the right approach because it's overkill for what I want. All I want is to pass some basic parameters from a library stage instance into AS3. I do not want to pass data via the instance name because this seems very messy if I want to have more complex interaction.
Thanks!
I would create a "switch" movie clip and export it to actionscrip, same with a "light" movie clip. The in the main class .as file I would inset them into the stage, using addChild (clips) and then add a click listener to the "switch" movie clip to control the "light".
This can be easily done.
Component(s) are wrong approach in my opinion.
Firstly you would want to setup Actionscript linkage / label your Library item.
In Library Panel.
- Right Click on "yourMC" >> click "Properties".
- In Properties dialog Tick "Export for Action Script"
- Then Name your Class eg "yourMC_Class"
now MC is ready to be referenced in your code.
next you would want to Dynamically add your "yourMC" from library to stage.
which can be done like such.
// first reference library item
var yourMC_ref:yourMC_Class = new yourMC_Class();
// Then load dynamic mc item into var
var your_MC_OBJ = yourMC_ref;
// then add your MC to stage.
this.addChild(your_MC_OBJ);
your_MC_OBJ.x = 200;
your_MC_OBJ.y = 100;
in a nutshell that's how I add library items to stage.
Obviously thats the basic function / code.
In a project I would have all code in an external class, in which case you would just set vars as public vars
public var yourMC_ref:yourMC_Class = new yourMC_Class();
public var your_MC_OBJ = yourMC_ref;
and the last 3 lines of code into a public function
public function ADD_First_MC()
{
this.addChild(your_MC_OBJ);
your_MC_OBJ.x = 200;
your_MC_OBJ.y = 100;
}
Now 'your_MC_OBJ' can be used in more complex ways.
eg. to create a light switch there are many options depending on how you need to approch functionality.
eg. Apply a different MC library item to "your_MC_OBJ"
play specific frame within MCs.
However If it was me I would just use mouse function to switch light on or off using addChild removeChild.
eg.
public var LightON = 0;
public var yourMC_ref:yourMC_Class = new yourMC_Class();
public var your_MC_OBJ = yourMC_ref;
then create a public function that handles on / off events
public function LightON_OFF()
{
if(LightON == 1)
{
this.addChild(your_MC_OBJ);
your_MC_OBJ.x = 200;
your_MC_OBJ.y = 100;
}
if(LightON == 0)
{
this.removeChild(your_MC_OBJ);
}
}
Hope this helps.
So, for what you want, while it may not be the best way to do what you want, I understand it's your experience you are constructing.
Use components, yes...in the following way (the most simple one):
Create a Movie Clip
Right-click it in library
Click on "Component Definitions"
Add a property, set a name, a variable name (var test, for this matter) and a default value
Click OK
Open your movie clip
Open code for the first frame and declare the variable without an initial value (var test:String;)
Trace it's value ( trace( test ); )
Go back to the stage root
Drag and drop the item from library to stage
Test it (Cmd/Ctrl + Enter) (maybe it will print null, dunno why, it ignores the default value sometimes)
Select your component on stage
Open the properties panel (Windows > Properties)
Go to Component Parameters on this panel and change the property value
You should see the value traced on console
And, I think, like this you can use properties from components for what you want, like using a String and getting the controlled mc by its name.
Good luck
I think what people are trying to say is that you can have the whole thing is data driven, and so you can combine the IDE with the data to come up with your final game.
But consider this ... it might be what you want.
If you have, for instance, a BaseSwitch Class:
public Class BaseSwitch extends MovieClip {
private var _lightName:String;
private var _light:Light;
public function get lightName():String {
return lightName;
}
public function set lightName(value:String):void {
if (value != _lightName) {
_lightnName = value;
//Note I don't advocate having children reach into their parents like this,
//but you sound like you don't want the parent involved in the process, so
//this is one way you could do it.
if (parent.hasOwnProperty(lightName) && parent[lightName] is Light) {
_light = parent[lightName];
} else {
trace('Could not find light', _lightName);
}
}
}
//other code to listen for gestures and operate the light
}
Now, when you want a switch to operate a specific light name, create a library instance and set its base class to BaseSwitch. When you close the dialog where you set the base Class, you'll notice that it gives you a dialogue that it couldn't find the Class in the Class path and one will be generated. You're going to replace it with a Class that sets the lightName. Create a new AS3 Class in the root directory with the same name as your library instance. It should look something like this:
public class SpecificSwitch {
public function SpecificSwitch() {
super();
lightName = 'theSwitch';
}
}
Other possible choices involve having the parent Class match up instances of switch with instances of light based on name, so if it finds a light1 and a light1Switch, it either gives a reference to the light to the switch or it simply sets up a mapping in its own event listening system.

AS3 Multiple instance names in one MC

I apologize for how confusing this question is.
I have a Movie Clip that is a car. In the car movie clip there are four different angles to the car. (e.g. left, right, front back). I dynamically change the body color of the car. In each angle of the car, the body of the car has an instance name "body." I change the color with the code :
var tempcar = "car_mc" + i;
var myNewTransform = new ColorTransform();
myNewTransform.color = 0x000000 //in real life this is a random value
this[tempcar].body.transform.colorTransform = myNewTransform;
Everything works fine, until I tell the car movie clip to gotoAndPlay the frame "front," where we see the front side of the car, and I try and apply the color change again to the body of the front of the car. I get the error :
TypeError: Error #1009: Cannot access a property or method of a null object reference.
Is there a better way to do what I am trying to do?
That's the old ActionScript 2 way of handling things. In ActionScript the container is not always a MovieClip, which would except the hash to access a dynamic field. Also, if you'd added it to the display list via addChild, the result would be different as well, since it is not the case in ActionScript 3, that could address the child automatically.
You should use an Array to store and access dynamically created instances.
// clazz would be the symbol
function createInstance(container:DisplayObjectContainer, clazz:Class, list:Array):Sprite
{
const child:MovieClip = new clazz() as MovieClip;
if (!child) throw new ArgumentError("Wrong type given");
return list[list.length] = container.addChild(child);
}
function getInstanceAt(index:int, list:Array):Sprite
{
return list[index] as Sprite;
}