[Solved, yes there are]Are there any special considerations of FP.world.collideRect that I should know about before I commit to using it in my implementation?


(Helios) #1

For those who have found this via search, Jacobalbino gives a great answer:

It’s almost never a good idea to use FP.world for anything but actually setting the world. Don’t reference it to do collisions, or to count entities, or to add or remove entities. The only time you should be using it is when you do FP.world = new MyWorld().

So there you have it. Best to avoid it!.. Or is it?

@azrafe7 suggests that

Basically the only thing you should NOT do is using FP.world in your entities/worlds constructor, override Entity.added()/World.begin() and put your code in there instead. Just doing this should solve 99.9% of FP.world-related problems.

@Ultima2876 elaborates on that line of reasoning, proposing:

The rule of thumb: memory allocations = constructor, logic = added() (the same applies to Worlds - memory = constructor, logic = begin()).

Original Message follows



I’m afraid of using FP.world for anything now, because of some debugging messes I got into with calling things in the constructor of a world…

So I’m creating a system of “collision listeners” for everything that reacts to collisions.

lets say we have an auraCollision listener that checks for any collisons within a certain rectangular distance from the entity

What I am wondering is if the listener should be checking against an “FP.world.collideRect” in a set of screen coordinates, or if I should give the listeners their own entity with its own hitbox.


(Jacob Albano) #2

To strictly answer your question: Mathematically speaking? No.

Now to give the answer I think will actually help.

I feel like you’re probably overreacting here. I apologize if I sound blunt, but I’ve been sitting here for a good while trying to think of a good way to say this; instead of rewriting the systems you need from scratch, why not just learn how to use the API correctly?

It’s almost never a good idea to use FP.world for anything but actually setting the world. Don’t reference it to do collisions, or to count entities, or to add or remove entities. The only time you should be using it is when you do FP.world = new MyWorld().

Entities all have a world property. If it’s null, they’re not in a world, and any operations you want to do with them becomes moot. If it’s a valid reference, you can do all your collision checks through there.


(Linck) #3

Really? I didn’t know that. Can you explain why?


(Jacob Albano) #4

Here’s the example I gave in another thread:

  • FP.world is an empty instance of the default World class.
  • FP.world = new MyWorld();
  • In the constructor of MyWorld, you add an entity to FP.world…
  • …which is then overwritten with the newly constructed MyWorld.
  • Result: your entity was added to a world that isn’t being used any more.

(Ultima2876) #5

Should FP.world just be removed and replaced with an FP.changeWorld function perhaps? It’s usage is a bit of an anti-pattern and the way it is supposed to be used is a bit counter intuitive for a variable.

Though I guess this breaks games that use the ‘old way’ (if they weren’t subtly broken already ;P)


(Jacob Albano) #6

Yeah, that’s the way Flixel does it, and it certainly helps to avoid awkward situations like this. I’d be hesitant to have it removed outright because I know it can come in handy sometimes, but it’s a sticky situation for sure.

Definitely something to think about for a major-version change.


(Helios) #7

It’s almost never a good idea to use FP.world for anything but actually setting the world. Don’t reference it to do collisions, or to count entities, or to add or remove entities. The only time you should be using it is when you do FP.world = new MyWorld().

Good to know, thanks!

or to add or remove entities

How are you supposed to add or remove entities? I thought the only way to add or remove an entity was via FP.world.add()?


(azrafe7) #8

No there aren’t!

…or at least they’re not terrifying… just use it properly. :smile:

Basically the only thing you should NOT do is using FP.world in your entities/worlds constructor, override Entity.added()/World.begin() and put your code in there instead.

Just doing this should solve 99.9% of FP.world-related problems.

(I’d hate to break backward compatibility, but actually the path proposed by @Ultima2876 and @jacobalbano should need some consideration).


(Ultima2876) #9

Every entity has access to the world through the world variable. So instead of FP.world.add, use world.add. This also enforces the good practice of never create entities from another entity’s constructor. This won’t work because in an entity’s constructor world is still null - it is only set once the entity is actually added to the world. Thus, you must use the added() function (the correct place) to do logic. The rule of thumb: memory allocations = constructor, logic = added() (the same applies to Worlds - memory = constructor, logic = begin()).


(Helios) #10

No there aren’t! …or at least they’re not terrifying… just use it properly. :smile:

Hahaha, sorry for the sensationalist title. I’ll change it to editorialize less.

That’s interesting. If the only quirk about FP.world is it’s use in the constructor, why would jacobalbano have suggested that it is

never a good idea to use FP.world for anything but actually setting the world. Don’t reference it to do collisions, or to count entities, or to add or remove entities. The only time you should be using it is when you do FP.world = new MyWorld().

?

Are there still more landmines to find?


(Helios) #11

The rule of thumb: memory allocations = constructor, logic = added() (the same applies to Worlds - memory = constructor, logic = begin()).

Ahh, excellent! That’s excellent advice! I hadn’t been aware of that distinction and will be taking advantage of it now. I’m also going to move this bit of wisdom to the top.


(Jacob Albano) #12

It’s not necessarily about constructors, it’s just an order-of-operations problem. Consider this:

var world:World = new MyWorld();
FP.world.add(new MyEntity());
FP.world = world;

// huh? Why isn't MyEntity added to the current world?

It makes sense when you see it spelled out this way, but when the call to add() is within a constructor it’s not as obvious, despite doing exactly the same thing.


(azrafe7) #13

Oh, I didn’t mean to sound harsh, or seem to over-protect something I’ve not even coded… so sorry if that was the impression. :grin:

I actually quoted the title just to give some context to my reply… FlashPunk has its dark spots, but it’s quite powerful and malleable once you’re used to it.

\o/ But yeah!, hopefully this exchange has lead to a somewhat clearer understanding of how things work underneath. We were really all trying to say the same thing (and, apart from some specific cases, FP.world can be very handful - I use it all the time!).

The reasoning behind @jacobalbano’s response is that using FP.world only to switch to a different one effectively puts the coder in a position in which he/she will never encounter any related problem.

About landmines? We’re all about improving things, so if you find something strange (also like this one), please report it and we will try to fix it as soon as possible.


(Helios) #14

Oh no, no harshness inferred whatsoever! I just wanted to make sure I didn’t give off the impression that I was belittling someone else’s problem solving approach because it was different from my own – I know how frustrating that can be.

I love flashpunk and am learning it a little bit at a time. I will surely do anything I can to contribute to it’s further development.

I think I have a much clearer understanding of FP.world now, and thanks so much for your input!


(Zachary Lewis) #15

Do you use FP.world when storing a reference to the current game world (for implementing pause screens and stuff)? If not, how do you do it?


(Jacob Albano) #16

Yeah, that’s what I do. That’s why it’s a complicated problem. :confused: