I use Texturepacker for creating spritescreens and tested the new castle-sprite-sheet editor.
I noticed there’s a standard large box around the image using the resulting castle-sprite-sheet editor result, where .starling-xml scales the box directly around the borders of the image without much background. It seems to me that collision is too rough. Does the box not shrink around every single image?
Good to know that new Sprite Sheet Editor options are still in progress.
In the “to-do” list it would be cool also if one can import a range of single image sprites instead of one by one. So ‘shift-select’. (yeah, this can be done in Texture Packer).
There is also a “Sprite Illuminator” utility that complements Texture Packer. Is it possible to add such lightning effects on sprites during running of a game?
The removal of empty space is important as I can really see a bounding box around the image running it in the editor, so I guess the Scene shrinks and expands directly around the image which makes collision more accurate?
See my topic on 2D collision. Eugene is helping me a lot here but I still can’t get it to work with physics.
For now I have the MyScene.BoundingBox.RectangleXY.Collides(StatePlay.OtherScene.BoundingBox.RectangleXY) but there is no bounding box here, it takes the whole sprite grid as in the new sprite editor; the scene dimensions do not shrink to smaller images.
This is already available. When you use the “Add…” menu item to add new frames (either by right-clicking on the “Frames” area, or by using main menu “Frame → Add”) then you can choose multiple files in the resulting “open” box (from Windows or GTK). Select the files using Shift or Ctrl as you wish.
I do not know the “Sprite Illuminator”. But if you want to add normalmaps to sprite sheets, and then illuminate them, this is certainly possible. You will need to process the scene nodes (MyScene.RootNode) a bit, to
find the TUnlitMaterialNode there
replace it with TPhysicalMaterialNode
and set there BaseTexture, NormalTexture to have lighting working on the sprite sheet.
Doing this would look something like this:
....
begin
...
// put this somewhere at loading, e.g. in TStateXxx.Start:
MyScene.RootNode.EnumerateReplaceChildren(@ReplaceNodes);
end;
procedure TStateXxx.ReplaceNodes(ParentNode: TX3DNode; var Node: TX3DNode);
var
NewNode: TPhysicalMaterialNode;
begin
if Node is TUnlitMaterialNode then
begin
NewNode := TPhysicalMaterialNode.Create;
NewNode.BaseTexture := Node.EmissiveTexture;
NewNode.NormalTexture := TImageTextureNode.Create;
TImageTextureNode(NewNode.NormalTexture).SetUrl(['castle-data:/my-normal-map.png']);
Node := NewNode;
end;
end;
The above is a pseudo-code, I didn’t test it, but hopefully it should get you started.
The removal of empty space is important as I can really see a bounding box around the image running it in the editor, so I guess the Scene shrinks and expands directly around the image which makes collision more accurate?
The bounding box of the scene just follows the geometry (underlying quad) created. I agree that removal of this is important to have smaller atlases. Note that for collisions, the workaround it to manually use smaller rectangle – e.g. instead of SomeScene.BoundingBox.RectangleXY you can use SomeScene.BoundingBox.RectangleXY.Grow(-10, -20).
That was a pseudo-code, really not tested. You need to cast Node to TUnlitMaterialNode in this case. Like
if Node is TUnlitMaterialNode then
begin
UnlitNode := TUnlitMaterialNode(Node);
....
NewNode.BaseTexture := UnlitNode.EmissiveTexture;
...
As for missing RootNode, you need to have a TCastleScene instance, as only TCastleScene exposes a RootNode with something loaded. So declare and cast PlayerScene to TCastleScene, not just TCastleTransform, making sure it is actually of TCastleScene class in the editor.
If you don’t know about normal maps or how to make them, I’d say to just ignore this part of my suggestion. Lighting will work without them too, you just will not see detailed “bumps”.
Update, as I just saw your hierarchy in 2D Scene Collision - #35 by Carring : your PlayerScenedoes not descend from TCastleScene. The operation I described has to be done TCastleScene instances, so in your case you have to do this on StandIdleAnim, WalkLeftAnim etc. instances.