Okay when I was going through different resources on Flashpunk I found three ways of adding entities to the world:
add(new Entity(10, 10));
//***************
var _entity:Entity;
//In constructor:
_entity = new Entity(10,10);
add(_entity);
//***************
FP.world.add(new Entity(10,10));
So my question is which one should I use and when.
Thank you.
add(new Entity(10, 10));
This will only work in whichever context add() is defined. I haven't used this specific library, but assuming that will be in a class called something similar to World and anything that inherits from it.
var entity:Entity = new Entity(10, 10);
add(entity);
This just breaks up the first example into two lines. It will also let you refer to that specific Entity before and after adding it to the world, whereas in the other example you have no way to reference the Entity you added.
FP.world.add(new Entity(10,10));
Here I'm assuming there's a class FP with the static property world representing a current relevant instance of the World. It does the same thing as the first example except that you can do this in any context. I would avoid using this; you'll find yourself using it as an excuse to add things to the world from unexpected locations in your code, leading to reduced code readability, frustration and a much harder debugging experience.
My preference is example 2. It's more readable, it suggests that you're using add within an appropriate context, and it lets you make changes to the Entity that you create:
var entity:Entity = new Entity();
entity.property = newValue;
add(entity);
Related
There are many examples of doing this in axml, but I would like to have a complete binding using code behind. To be honest, I would like to have NO axml, but seems like creating all the controls programmatically is a nightmare.
I first tried the suggestions at:
MvxListView create binding for template layout from code
I have my list binding from code-behind, and I get six rows (so source binding is working); but the cells itself does not bind.
Then at the following url:
Odd issue with MvvmCross, MvxListViewItem on Android
Stuart has the following comment: Have looked through. In this case, I don't think you want to use DelayBind. DelayBind is used to delay the binding action until next time the DataContext is set. In Android's MvxAdapter/MvxListItemView case, the DataContext is passed in the ctor - so DataContext isn't set again until the cell is reused. (This is different to iOS MvxTableDataSource).
So in essence, the only example I see shows DelayBind, which shouldn't work.
Can someone please show me some examples... thanks in advance.
Added reply to Comments:
Cheesebaron, first of all, a huge thank you and respect for all your contributions;
Now, why not use axml? Well, as programmers, we all have our own preferences and way of doing stuff - I guess I am old school where we didn't have any gui designer (not really true).
Real reasons:
Common Style: I have a setup where Core has all the style details, including what all the colors would be. My idea is, each platform would get the style details from core and update accordingly. It's easy for me to create controls with the correct style this way.
Copy-Paste across platform (which then I can even have as linked files if I wanted). For example, I have a login screen with web-like verification, where a red error text appears under a control; overall on that screen I have around 10 items that needs binding. I have already got iOS version working - so starting on Droid, I copied the whole binding section from ios, and it worked perfectly. So, the whole binding, I can make it same across all platform... Any possible error in my way will stop at building, which I think is a major advantage over axml binding. Even the control creation is extremely similar, where I have helpers with same method name.
Ofcourse I understand all the additional layout that has to be handled; to be honest, it's not that bad if one really think it through; I have created a StackPanel for Droid which is based on WP - that internally handles all the layouts for child views; so for LinearLayout, all I do is setup some custom parameters, and let my panel deal with it. Relative is a different story; so far, I have only one screen that's relative, and I can even make it Linear to reduce my additional layout code.
So, from my humble point of view, for my style, code-behind creation allows me to completely copy all my bindings (I do have some custom binding factories to allow that), copy all my control create lines; then only adding those controls to the view is the only part that is different (then again, droid and WP are almost identical). So there is no way I can miss something on one platform and all are forced to be the same. It also allows me to change all the styles for every platform just by changing the core. Finally, any binding error is detected during compile - and I love that.
My original question wasn't about NOT using axml... it was on how to use MvxListView where all the binding is done in code-behind; as I have explained, I got the list binding, but not the item/cell binding working.
Thanks again in advance.
Here is part of my LoginScreen from droid; I think it's acceptable amount of code for being without axml file.
//======================================================================================================
// create and add all controls
//======================================================================================================
var usernameEntry = ControlHelper.GetUITextFieldCustom(this, "Username.", maxLength: 20);
var usernameError = AddErrorLabel<UserAuthorization, string>(vm => ViewModel.Authorization.Username);
var passwordEntry = ControlHelper.GetUITextFieldCustom(this, "Password.", maxLength: 40, secureTextEntry: true);
var passwordError = AddErrorLabel<UserAuthorization, string>(vm => ViewModel.Authorization.Password);
var loginButton = ControlHelper.GetUIButtonMain(this);
var rememberMe = new UISwitch(this);
var joinLink = ControlHelper.GetUIButtonHyperLink(this, textAlignment: UITextAlignment.Center);
var copyRightText = ControlHelper.GetUILabel(this, textAlignment: UITextAlignment.Center);
var copyRightSite = ControlHelper.GetUIButtonHyperLink(this, textAlignment: UITextAlignment.Center);
var layout = new StackPanel(this, Orientation.Vertical)
{
Spacing = 15,
SubViews = new View[]
{
ControlHelper.GetUIImageView(this, Resource.Drawable.logo),
usernameEntry,
usernameError,
passwordEntry,
passwordError,
loginButton,
rememberMe,
joinLink,
ControlHelper.GetSpacer(this, ViewGroup.LayoutParams.MatchParent, weight: 2),
copyRightText,
copyRightSite
}
};
I just came across a similar situation myself using Mvx4.
The first link you mentioned had it almost correct AND when you combine it from Staurts comment in the second link and just remove the surrounding DelayBind call, everything should work out ok -
public class CustomListItemView
: MvxListItemView
{
public MvxListItemView(Context context,
IMvxLayoutInflater layoutInflater,
object dataContext,
int templateId)
: base(context, layoutInflater, dataContext, templateId)
{
var control = this.FindViewById<TextView>(Resource.Id.list_complex_title);
var set = this.CreateBindingSet<CustomListViewItem, YourThing>();
set.Bind(control).To(vm => vm.Title);
set.Apply();
}
}
p.s. I have asked for an Edit to the original link to help others.
I have this:
public class Base {
public function whoAmI() {
trace("base");
}
}
public class Extended extends Base {
public function Extended() {
this.whoAmI() //prints extended
super.whoAmI() //prints base
var test = super;
test.whoAmI() //prints extended
}
public override function whoAmI() {
trace("extended");
}
}
The problem is when I do var test = super, it seems like this is assigned to test instead of super.
Is it possible to do the assignment so that test.whoAmI() prints "base"?
Edit: In the comments it is being said that using super in the way I propose would break overriding. I don't think that's the case. The way I am thinking of it, super could be used the same way as this. I understand that is not the way super is implemented, but using it that way would not break overriding as people are claiming. So for example the same way this is possible:
var test = this;
test.whoAmI();
This should be possible:
var test = super;
super.whoAmI();
It is obviously the choice of the language implementer to not do things this way, and I don't understand the reason why. It doesn't break things, but I guess it does make them more complicated.
I am not suggesting type-casting this to the super class. Obviously that wouldn't work.
You are thinking of "this" and "super" as 2 different instances, 2 different things but they in fact point to the same object (obviously) so at the end it's always "this". Using super is just a special keyword that allows the instance to point to the overrided definitions up the inheritance chain, it does not point to a different object. So "super" does correctly its job, it points to the instance and allow you each time you use it to access overrided definitions and that's it. There's of course no point on trying to store that keyword in a variable since in that case it just return correctly the instance it points to which is always "this".
It's simply a case of misunderstood inheritance principle and I've seen it before, super is mistaken for some kind of instance wrapper up the inheriatnce chain around the object "this" while it's in fact and always the same object.
No, this is not possible.
If this were possible, then overriding methods wouldn't be possible!
For example, take this function...
public function test(a:Object):void {
trace(a.toString());
}
You'd only get [object Object] back if your idea was how things worked.
Ok I understand what you mean your question is more about language definition and specification.
Look at this exemple in c# that explain how you can manage more precisely overriding in c# :
http://www.dotnet-tricks.com/Tutorial/csharp/U33Y020413-Understanding-virtual,-override-and-new-keyword-in-C
But
let's explain a litlle how it's work.
when you extend a class, it's like if you create an object composed of all the object in the inheritance tree so if B extends A and C extends B you have two objects like this:
(B+A) and (C+B+A) with hierarchy between each other B->A and C->B->A. Super is just a way to ascend in the hierachy.
When you cast a C in A for example. In memory you always have an object (C+B+A) but interpreted as A. When you override you just say that a method in child has an higher priority than in parent.
You can try downcasting this manually to any of your class's predecessors. The pointer will still be equal to this but the methods called will use the class table of the class used to downcast.
public class Extended extends Base {
public function Extended() {
this.whoAmI() //prints extended
super.whoAmI() //prints base
var test:Base = this;
test.whoAmI() //should print base
}
public override function whoAmI() {
trace("extended");
}
}
Should your Base extend something, which methods are known or the superclass is dynamic, and there is code that adds methods to prototype of a class, you might use such a downcast to call a superclass's method that might not be there at compile time, but make sure you first call hasOwnProperty in case of a dynamic class to determine whether a method or property exists.
Im currently learning as3 but I come from several years of as2 experience, so what I was used to do is attach movieclips using string with a numeric variable to get the right identifier like this and maybe I was thinking about using eval here but of course its not available in as3 so here is what I was doing in as2:
currentlevel=1;
myString = "levelMc"+currentlevel;
And then of course use the constructed string in "attachMovie" function to get the right clip attached.
attachMovie(myString,myString+mydepth,mydepth);
But I see in as3 all is about classes and all different so I cant seem to find a way to dynamically get the right class name for the child to be added, is there an actual way to make that possible? because as far as I have gone I see that I should get the class name to make new object and then put that in "addChild" so therefore I cant find a way to pass any kind of dynamically constructed string or element refering my needed clip there, is it still possible?.
Thanks beforehand for any clues =)
EDIT I added the attachmovie call as a clarifying line, I know all you got what I was asking but as I cant find a right approach I prefer to clarify. Additionally I shouldnt have mentioned the "eval" here, sorry, I just can ask my as2 with string usage
EDIT Solved, thanks to you all guys, you saved me, I wish I could give you all kudos because all of your ideas and tips are awesome and really helpful, I marked that answer as correct because it was the one that lead me to getDefinitionByName which is what Im going to use in the end, but as said all tips and ideas to face new as3 world will help me greatly, so as said I wish I could give reputation to you all, thanks a lot =)
You still can set a name for your object, for instance:
var mc : MovieClip;
for (var i : int = 0; i < 5; i++) {
mc = new MovieClip();
mc.name = "myMc"+ i;
addChild(mc);
}
and you can get a specific child using:
this["myMc1"] as MovieClip
or
this["myMc"+ i] as MovieClip;
How about a simple array?
Because if you only need to access a set of levels in a ascending numeric fashion, this approach is easier.
var levels:Array = new Array();
levels[0] = //your level1 movieclip
levels[1] = //your level2 movieclip
...
function jumpToLevel(index:int):void{
//remove added levels beforehand
removeChildren(); //assuming the only children you added to this displaylist
//are levels, otherwise you will need another approach
addChild(levels[index]);
}
In AS2, we would store information about instances in instance name - button_0, button_1, etc. In AS3, you don't need/use instance names for anything other than keeping your code clear to you and to reference stuff you create by hand.
Use arrays to reference your instances. So, if you're making buttons, you create a button and push it into an array of buttons. Then just reference it as aMyButtons[i] instead of mcMyButtons["button_" + i]
Here's example code.
function fCreateButtons(): void {
var i: int = 0;
for (i = 0; i < 5; i++) {
var mcNewButton: McButton = new McButton();
mcNewButton.x = i * 200;
mcNewButton.iButtonNumber = i;
mcNewButton.tMain.text = "About Us";
mcNewButton.bButton.addEventListener(MouseEvent.MOUSE_DOWN, fButtonPress);
mcNewButton.bButton.addEventListener(MouseEvent.MOUSE_OVER, fButtonOver);
mcNewButton.bButton.addEventListener(MouseEvent.MOUSE_OUT, fButtonOut);
aButtons.push(mcNewButton);
}
}
function fButtonPress(e: MouseEvent): void {
var iButtonNumber: int = e.currentTarget.parent.iButtonNumber;
trace("fButtonPress(): iButtonNumber: " + iButtonNumber);
}
This is how you'd add the buttons to a holder clip and remove them.
mcButtonsHolder.addChild(aButtons[i]);
mcButtonsHolder.removeChild(aButtons[i]);
Well as I said above I managed to solve it finally using getDefinitionByName which is the closer I think I can get to "eval", that function managed to bring dinamycally formed class name to be used to call the new clips on run time which is perfect for me, at least make the code cleaner and easier to change if needed. As I said in last edit, thanks a lot to you all who helped, all your tips and ideas will be of great use for me in the as3 time, wish I could give you all reputation, thanks a lot =).
I'm getting my feet wet with AS3, Flixel and component/entity systems (yes, all at the same time), and my entities (which subclass FlxSprite) aren't being added correctly (i.e., not at all). I've just spent a good two hours nailing down the offending line. If I remove it, the rest of the game chugs along happily.
What's wrong with this code?
public function addComponent(c:Component):void
{
var type:String = Object(c).constructor.toString();
FlxG.log("type=" + type);
this._components[type] = c; // The evil line
FlxG.log("now type=" + _components[type]);
c.setData(this);
}
components is an Object field being used as a map/dictionary. type gets set to [class PlayerComponent]. Based on googling, this is valid and should work as intended.
Based on the output from the console, it's just bailing after that line--not crashing entirely. What's going on? More details gladly offered upon request.
I'm not certain about Component - not my forte - but I do know that FlxGroup and its children (which include FlxState) have a method called add() which adds children to them.
So if you have an FlxSprite, the correct way (in flixel) to add it to the chain of things to update/draw is to use that; you can add it directly to your state or to a group that is a child of the state.
Function docs: http://flixel.org/docs/org/flixel/FlxGroup.html#add()
Please tell me how to create an object if the name is stored in a variable.
var className:String = 'Config';
var MySprite:Sprite = new ???
class Config extends Sprite {
...
}
var configClass:Class = getDefinitionByName("Config") as Class;
var configInstance:Config = new configClass as Config;
EDIT: Aurel300 has a point. Statically typing to an exact class is senseless, simply because if you can explicitly code the exact type of what it is going to be, then you might as well create a class as per normal.
That being said, you will probably have somewhat of an idea of what the type could be, for example if you are dealing with audio you know it will inherit from Sound, or images you know it will inherit from Sprite. So in those cases best practise would be to statically type it as the lowest common base class. If it can be literally any class then there is no point in statically typing it at all, but I can not think of any useful reason why you would create classes that could be anything.
So if you are expecting the type to be Config or classes that inherit from Config then the code above is correct. Otherwise my guess is that you are expecting classes that extend Sprite (so you can add them to stage perhaps) so then you would change it to:
var configClass:Class = getDefinitionByName("Config") as Class;
var configInstance:Sprite= new configClass as Sprite;