[SOLVED] addGraphic() not rendering mah graphic!


(Helios) #1

Take a look at jacalbano’s answer, he explains it far better than I can. The takeaway is to be very careful when using FP.world!

okay this is really frustrating. If I call addGraphic() in the update function, then it shows up. If I call it in my constructor, it doesn’t show up. What is going on?

Rather than myEntity having its own graphic, I am trying to make myEntity hold a reference to a helperObject which manages its own state and renders an image relative to myEntity.

the constructor for the helperObject looks sort of like this:

public function helperObject(myEntityReference:Entity, image:Image, xOffset:int, yOffset:int)
{
     //store arguments into private variables
     subject = myEntityReference;
     this.image = image;
     this.xOffset = xOffset;
     this.yOffset = yOffset;

     //calculate where I want the image rendered
     x = subject.x + xOffset;
     y = subject.y + yOffset;

     //add the graphic to the world and store the reference to a private variable
     graphic = FP.world.addGraphic(image, subject.layer, x, y)
}

It all compiles, but nothing shows up on screen. Furthermore, the console says there’s only one entity!

There should be 2 entities (myEntity and the graphic entity that was added in the helperObject constructor)


(Mike Evmm) #2

I am a bit confused. Do you want to add an entity, or a graphic?


(Mike Evmm) #3

You sound like you’d want to do something like

    public function helperObject(myEntityReference:Entity, image:Image, xOffset:int, yOffset:int)
    {
         subject = myEntityReference;
         this.graphic = image;
         this.xOffset = xOffset;
         this.yOffset = yOffset;
    
         //calculate where I want the image rendered
         x = subject.x + xOffset;
         y = subject.y + yOffset;
    
         FP.world.add(this);
    }

Personally, I’d rather do it like this:

    public function helperObject(myEntityReference:Entity, image:Image, xOffset:int, yOffset:int)
    {
         subject = myEntityReference;
         //have private variable img hold image
         img = image;
         img.xOffset = xOffset;
         img.yOffset = yOffset;
    
         img.x = subject.x + xOffset;
         img.y = subject.y + yOffset;
    
         FP.world.addGraphic(img);
    }

(I didn’t test this, may be bugged!)


(Ultima2876) #4

Yeah, as Miguel says you’d be better having a separate entity with its own graphic that follows a ‘parent’ entity. Tying your entities together as closely as sharing graphics overrides the point of having an entity system in place (that is, to keep your game entities as separate, reusable modules) and will result in bad juju down the line!


(Helios) #5

Whoops! I made a booboo in my post. the last line of that code should have been:

graphic = FP.world.addGraphic(image, subject.layer, x, y) 

where graphic is an entity. My post title even says im using addGraphic, but I said add in the code.

the key difference there is that “addGraphic” adds an entity with “image” as its graphic. so yeah, I agree haha.


(Helios) #6

So, if you check my recent edit, you’ll see that I goofed in copying the code into the post. I actually did use addGraphic() and not add(). Storing the result in graphic gives me a reference to the entity which was added with the appropriate image.

So, bearing that in mind (and I know I just pulled a bait and switch on you) the only difference between your code and my code is that you gave the coordinates directly to the image instead of the entity in addGraphic() - is that significant to the approach you are using?


(Mike Evmm) #7

well, I’d say the only difference is that I feel more comfortable handling an image instead of assigning it to the helper entity (so that I can have more than one image at a time) (sorry I’m not being very clear though, it’s not too easy for me to explain this in english). Anyway, if you already have to have an image variable to pass to the function wouldn’t it be easier to simply edit its properties (x, y, offset yaddayadda) directly and add it from inside the entity you already have on stage? (which kinda makes me wonder: if objecthelper is an Entity, wouldn’t you want to add it to the world before adding the image (on added())?)


(Helios) #8

Firstly, helperObject is not an entity, so I won’t be adding it to the world.

Secondly, yes, it would be easier, but I want to decouple the image from the entity :slight_smile:

I love you guys, but I’m not really asking for design advice. I just want to know why the image isn’t showing up on screen and the entity that was supposedly added in “helperObject” is not showing up.


(Mike Evmm) #9

Welp sorry, I was just trying to understand your code structure. ^^’
Hey, maybe someone can be of better help!


(Helios) #10

I just meant that it might be over-complicated to go into it, and it might not help figure out the problem.

Okay, I will explain the structure, but first I want to add that for some reason, the image does show up if I use addGraphic() every frame (the helper object gets updated in the update loop of the subject entity – if I move the addGraphic() call into the update loop, it works) albeit with the obvious memory leak.

Okay, so I’m toying with using OO design patterns to encapsulate areas of change in the program. Primarily, I’m using the Strategy pattern to encapsulate things like “movement behavior” “action behavior” “collision behavior” “control behavior” “visual behavior” and “stat behavior”

Everything in the game world is made by composing an entity with various helper objects which extend its basic functionality. So if I want an entity to move, I just add a new movementBehavior to it. If I want it to shoot a gun, I just add a new actionBehavior. This allows me to extend the behavior of the entity without modifying any existing code. I can even change the behavior at runtime (and even add new behaviors to existing entities! So a boss could suddenly learn to jump in the middle of a fight just by calling boss.addMoveBehavior(new Jump()))

I’ve implemented that and tested it and it works just fine, now im working on composing entities with visual display algorithms! It seems like it should work, but maybe garbage collection doesn’t like my encapsulation and is cleaning it up?

^^^see, I know that was a terrible explanation, and it probably didn’t help hahaha


(Mike Evmm) #11

Actually that was a pretty nice explanation (and an even better idea). Are you calling that function on class initialization or added()?
(I’ve had problems before with FP.world.addGraphic() and FP.world.add(), and found that it’s usually solved by placing the code either on Update() or Added())


(Jacob Albano) #12

Garbage collection shouldn’t have anything to do with it. As long as you hold a reference to an object somewhere, it won’t be freed.

The problem is most likely that you’re constructing helperObject in the constructor of your world class, then setting it to the active world by assigning to FP.world.

Here’s what’s happening:

  • 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…
  • …then overwrite it with the newly constructed MyWorld.
  • Result: your entity was added to a world that isn’t being used any more.

To get around this, never use FP.world for anything but changing worlds. Don’t add or remove entities from it directly. If you have to have one entity add another, use the world property in an added() override; don’t try to do it in the constructor.


(Helios) #13

That’s exactly what happened once I moved it to the update function it worked fine! I haven’t tested it with the added function, but you are probably right!


(Helios) #14

WOW, that is profound information. You just saved me a million hours of scouring.

I just updated the post title to include a [solved] tag. Thanks again.


(Jacob Albano) #15

Awesome! Glad I could help. :thumbsup:


(Ultima2876) #16

Not using FP.world sounds like a great idea. I’ll start doing that in future games (if I ever have time to make one again!).

Maybe we should compile a list of mind-blowing little nuggets of win like that and get it up on the main page?

EDIT: Perhaps even a little box on the MAIN main page that shows a random nugget preview. Something like:

“NEVER use FP.world for anything other than changing world. Read more…”

That would take you to the main tip page for that particular one. Then from there you could have ‘View more like this’.