Custom entity and associate sprite : strange offset

Started by Realguigui, January 27, 2017, 09:59:28 PM

Previous topic - Next topic
Hello.

I've reuse and modify the code of this thread for making a moving plateform.
Sadly, I have an offset between the custom entity and the associate sprite.
It seems normal in the editor because even I set the origin point of the 32x32 sprite at (16,16), at the opposite it's impossible to set the origin point of the 32x32 custom entity.

Sprite parameters:


Offset in the editor:


On the second picture, the origin point of the sprite (16,16) seems to be at same coordinates of the default origin point (8,13) of the 16x16 upper left square of the 32x32 custom entity. This is probably normal but the result is identical even with this code in the model of custom entity where I modify the origin point of the custom entity:
Code (lua) Select
--****************************************************************************************************
-- EVENEMENT : A LA CREATION DE L'ENTITE PLATEFORME MOBILE AVEC DES VALEURS PAR DEFAUT
--****************************************************************************************************
function entity:on_created()
  -- On créé un sprite a affecter à l'entité
  self:create_sprite("entities/platform")
  -- On parametre la taille de l'entité en px
  self:set_size(32, 32)
  -- On parametre le point d'origine de l'entité par rapport à son coin haut gauche en px
  self:set_origin(16, 16)
...


Game screen


Like you can see, in the game the offset is exactly the same as in the editor.

Try setting the origin of the sprite to (8, 13).

The reason this happens is due to the fact that the engine hard codes rendering the sprite of a custom entity by rendering the origin of the image 8 pixels right and 13 pixels down from the top left corner of the entity instead of rendering at the center or rendering the sprite center horizontally and subtraction 3 pixels from the total entity size.
This signature was way too long before, but now it's short!
Also, I am Still Alive!
On ad Off I go!

Do you ever get the feeling that the fandom of a product(s) ruin the potential that you could have had to enjoy the product?

January 28, 2017, 01:07:41 AM #2 Last Edit: January 28, 2017, 01:22:35 AM by Diarandor
Quote from: YoshiMario2000 on January 28, 2017, 12:03:41 AM
Try setting the origin of the sprite to (8, 13).

The reason this happens is due to the fact that the engine hard codes rendering the sprite of a custom entity by rendering the origin of the image 8 pixels right and 13 pixels down from the top left corner of the entity instead of rendering at the center or rendering the sprite center horizontally and subtraction 3 pixels from the total entity size.

I had this same problem some time ago when coding my own platforms, and changing the origin of the sprite to (8, 13) does indeed solve the problem. But I don't think this is the reason why this is not working: note that he is changing the origin in the script (line 10).

The problem is probably that the function "custom_entity:set_origin()" shifts the bounding box (with the custom ground of the platform too) instead of shifting the sprites; it would be more natural if the engine shifted the sprites instead of the bounding box. Note that the sprite position remains fixed after changing the origin in the script (in the same position where it is shown in the Editor), but the bounding box is shifted!!!
@Christopho: Is this intended? Or could this be an engine bug?

@Realguigui: Anyway, if you create a sprite from the editor, you should not add it again from the script. Your entity has two identical sprites one above the other, I think.

EDIT: it would be nice to have some tutorial explaining and clarifying the differences and uses for the coordinates (of entities and sprites): bounding_box, position, ground_position, center, origin; and also some explanation of which coordinates are used to synchronize the sprites and HOW this is done (what is shifted and what is not).
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

Advice: Use the entity size to set your platform size, you might use larger plarform in the future  :P

entity:set_size(entity:get_size()) (is it necessary though ?)

When you call custom_entity:set_origin(), the bounding box (as returned by entity:get_bounding_box()) should not have changed. The coordinates of the entity (as returned by entity:get_position()) should have.

January 28, 2017, 11:35:10 AM #5 Last Edit: January 28, 2017, 11:37:42 AM by Diarandor
Quote from: Christopho on January 28, 2017, 09:24:51 AM
When you call custom_entity:set_origin(), the bounding box (as returned by entity:get_bounding_box()) should not have changed. The coordinates of the entity (as returned by entity:get_position()) should have.

Ok, I have checked this with a custom entity and I can confirm that there is a bug; this explains the weird and non-intuitive behavior. I used this code:
Code (Lua) Select

  local x,y,bx,by,ox,oy,w,h
  x,y = self:get_position()
  ox,oy = self:get_origin()
  bx,by,w,h = self:get_bounding_box()
  print("BEFORE CHANGING:")
  print("pos: ".. x, y)
  print("ori: ".. ox,oy)
  print("bb: ".. bx,by,w,h)

  self:set_origin(50,50)
  x,y = self:get_position()
  ox,oy = self:get_origin()
  bx,by,w,h = self:get_bounding_box()

  print("AFTER CHANGING:")
  print("pos: ".. x, y)
  print("ori: ".. ox,oy)
  print("bb: ".. bx,by,w,h)

And I got this output:
BEFORE CHANGING:
pos: 176 189
ori: 16 13
bb: 160 176 32 32
AFTER CHANGING:
pos: 176 189
ori: 50 50
bb: 126 139 32 32


EDIT: After you confirm this is a bug, I will open an issue on github.
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

Warning: Note that when this bug is fixed for future releases of the engine, some scripts using custom entities may need a change (for instance, platform scripts). Fortunately, most part of the scripts using custom entities will not need any change.
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

I will have to think, maybe the current behavior is actually the intended one. What I know for sure is that it is undocumented, so there is at least a documentation bug :)


Quote from: Christopho on January 28, 2017, 02:27:43 PM
I will have to think, maybe the current behavior is actually the intended one. What I know for sure is that it is undocumented, so there is at least a documentation bug :)

I think the current behavior and the new one have the same posibilities but the second is probably more comprehensible.

Maybe it would be interesting to could modify the origin point of custom entity directly in the editor. We could align precisely the entity and his sprite and see if the positioning is correct before launching the game.

I won't change the behavior because of it would break existing scripts.
Maybe it was not the best choice but at least it is now documented: http://www.solarus-games.org/doc/1.6/lua_api_custom_entity.html#lua_api_custom_entity_set_origin

You can easily fix the problem by calling entity:set_position() after entity:set_origin().

Sometimes making new versions require revisions isn't the worst thing, if it makes the new version so much more intuative for newer users.

But anyway, I was wondering if this is related to how npc sprites and like, door sprites for example draw sprites differently relative to their origins. If you've ever tried to use a door sprite as an NPC or vice versa, you'll see what I mean. Can there be some standardization of where the origin point is relative to or is there a reason different types of entities draw sprites relative to their origins differently?

For historical reasons, doors and NPCs have different origins. The origin of doors is (0,0) and the origin of NPCs is (8,13). I had a tendency to choose (8,13) for entities that are standing, like the hero, enemies, NPCs, and to keep (0,0) for flat entities like doors or tiles. This was because the origin point is supposed to represent the point where the entity touches the soil. Like the center of the feet of a character. That did not make sense for doors and tiles.
Anyway, this historical choice no longer makes a lot of sense for entities like custom entities for example, since the engine cannot guess what they are supposed to represent.

Good news: in Solarus 1.6, you can change the origin and even the size of all entities from your scripts :)

Okay, that makes sense. It'll help me remember, too : )
Can't wait for 1.6 then!