No problem, I am already happy you spent your valuable time to help me!
I am sure I will encounter more problems that I need help with trying to find my way around CGE.
The upload size has been increased to 100 MB and I hope @Carring can upload it here. This way others can help â I do not want to be a bottleneck
I know
TFloatRectangle.Collides
works but remember my topic "starling vs. castle-sprites It is too rough as it takes the largest sprite-scene in the atlas (for instance character walking with wide legs) and does not shrink/bound with a smaller scene (standing character).
If this is the reason why you use physics, then itâs not a good reason.
If you use .castle-sprite-sheet
and the default bounding box is too large for you, you can:
-
continue using
.starling-xml
with TexturePacker for now. -
or decrease the rectantangle size manually, by whatever is needed. E.g. using
BoundingBox.RectangleXY.Grow(-10, -20).Collides(OtherRectangle)
instead ofBoundingBox.RectangleXY.Collides(OtherRectangle)
.
Trying to use physics will not change anything here. Physics engine doesnât calculate bounding box by default, and if you try to pass there BoundingBox
you will land in the same problem.
If you have too large bounding box/rect, then you have to make it smaller.
I thought when I watched the white bounding box expanding and shrinking around the walking character in the editor that it would make the collision âcornersâ directly around the image (scene).
With BoundingBox.Rectangle I noticed there is always collision around the size of the maximum sized image, so it does not âlookâ at smaller images / scenes (for instance when the character is less wide with his legs), even not with starling-xml. So there is no real âboundingâ box it appears?
With the physics thing you were my last resort.
Thanks for increasing the upload size but it appears not to be 100 mb?
Which is why I say to use Grow(-10, -20)
in my examples above. You need to make collision bounds smaller manually, at least in .castle-sprite-sheet
without trimming.
Using physics does not help you here, and likely complicate things.
Hm that is 100 MB (100 * 1024 KB). Can I just upload what you send me through email here?
You could also upload it yourself wherever you prefer (Google Drive, Dropbox), or put on GitHub. I want 1. others to have chance to answer 2. others to benefit from answers
Yes, sure.
Text is:
Character moves or holds by pressing arrow keys once.
With line 230 in the code switched off (MakePlayerPhysics) the character moves okay with all scenes following the parent Playerscene translation.
Problems:
With line 230 âonâ and thus calling procedure MakePlayerPhysics the character slowly moves down (unwanted).
and now switching direction the scenes do not follow the parent PlayerScene translation anymore which results inâscene jumpingâ.
There should be collision between mouse scene (eye icon) and playerscene but there is not. What is wrong?
I am reposting here @Carring sample code (relevant to above question) with permission. It turns out I did not increase attachment size successfully on Discourse last time â now it is 100 MB, so your next attachments should work, if need arises.
Rescue_Island.zip (68.8 MB)
Iâll try to analyze the problem and answer this weekend (although if anyone can help, youâre more than welcome ). Have a good weekend everyone
These are not messages from the compiler, these are messages emitted by CGE when running your application.
They indicate that physics has difficulty with processing necessary calculations âfast enoughâ. It may indicate that you have some very complicated physics setup, or you did something time-consuming (like loading something heavy) during the game, i.e. once physics is running. It may also be completely ignored â if it happens very seldom during very long application execution, it may be that your system was just busy doing something else with other applications.
@Carring First of all, thanks for preparing a good minimal testcase of your problem. This was exactly what I asked for â a simple, instantly working, minimal application that demonstrated your questions. This allowed me to investigate the problem very quickly.
I finally got to test it, sorry for delay
Note: While I provide some solutions to your physics questions below, I also found a problem in CGE physics engine that prevents it from really doing what you want. I write more details below, but you basically need collisions between 2 rigid bodies that both have Dynamic
= false
, and this is just not supported. Use TFloatRectangle.Collides
for this case instead.
This points me back to what I wrote before in this thread and in other: Your usage of physics in this example is somewhat unnecessary. You have
- 2 bodies,
- 2D,
- and you want to calculate a collision between their bounding volumes.
This is easy using TFloatRectangle.Collides
. Setting up physics for this purpose is a bit âoverkillâ
Use Mouse.WorldBoundingBox.RectangleXY.Collides(PlayerScene.WorldBoundingBox.RectangleXY)
in every Update
to test for collisions, and you can throw away physics code. I confirmed it adding
if Mouse.WorldBoundingBox.RectangleXY.Collides(PlayerScene.WorldBoundingBox.RectangleXY) then
Label1.Caption := 'collision!'
else
Label1.Caption := ' ';
to the TStatePlay.Update
. You have there similar code already, just commented out, so I guess you know it works
Note that I just used WorldBoundingBox
instead of BoundingBox
â it doesnât really matter in your case. Although I should have pointed you to WorldBoundingBox
earlier, it is better if in the future you will have more complicated transformation hierarchy and PlayerScene
will have some additional parent transformation moving it.
If you want to make the rectangle smaller than bounding box calculated by the engine, you need to account for it manually, using Grow(...)
as I shown above. Using physics doesnât help you here at all â you still provide explicit collider sizes to the physics engine, it doesnât know any âbetterâ collider sizes than what you set, and you set it based on LocalBoundingBox
size.
OK, onward with physics questions:
Once you assign PlayerScene.RigidBody
, the PlayerScene
is affected by gravity. See the manual, Physics | Manual | Castle Game Engine âââYou can turn any TCastleTransform instance into a rigid body, which means that it will be affected by gravity and collisions with other rigid bodies.âââ.
Solution: You can toggle TRigidBody.Gravity
to false
. See Castle Game Engine: CastleTransform: Class TRigidBody . I.e. just add RBody.Gravity := false;
to PlayerScenePhysics
.
Your code sets PlayerScene.Translation
and PlayerScene.Scale
. But once you assign PlayerScene.RigidBody
, then physics takes care of updating this object transformation, and it assumes that nothing âinterferesâ. Dynamic
is documented at Castle Game Engine: CastleTransform: Class TRigidBody , by default it is true
and as we say there âââIn this case you cannot change the TCastleTransform.Translation and other transformation properties of the related TCastleTransform after assigning TCastleTransform.RigidBody. They are under the control of the physics engine. You can still reliably read them.âââ .
Note: Your code sets RBody.Dynamic:= true;
, which doesnât do anything, Dynamic
is by default true
.
Solution: From what I understand your usecase, you just donât want physics to touch your object. So you want RBody.Dynamic := false;
. Moreover, as you update the transformation of PlayerScene
potentially every frame, it is good for performance to set RBody.Animated := true
(see Castle Game Engine: CastleTransform: Class TRigidBody ). So just add
RBody.Dynamic := false;
RBody.Animated := true;
to your PlayerScenePhysics
.
Note: This advise actually makes my previous advise (RBody.Gravity := false;
) not relevant anymore. If you set RBody.Dynamic := false;
, then gravity is also deactivated, regardless of RBody.Gravity
value. It will not hurt, but feel free to remove RBody.Gravity := false;
now.
I found here 3 problems, and Iâm afraid 3rd is a problem in CGE physics engine that we simply cannot fix now:
-
Same advise as above needs to be applied to
TStatePlay.MakeMousePhysics
: you want to modifyMouse
transformation (likeMouse.Translation
) yourself, you donât want physics engine to actually calculate any gravity etc. for it. So placeRBody.Dynamic := false; RBody.Animated := true;
inside
MakeMousePhysics
as well. -
The collisions of physics are resolved using 3D boxes, so the Z position and Z size of everything matters. (It would be easier if one day weâll have a dedicated 2D-only physics engine as an option, like Box2d, it may happen one day. But for now, our physics engine is 3D, and you need to account for it, even when you want to just do 2D games.)
And you have used boxes that have very small size in Z (both
PlayerScenePhysics
andMakeMousePhysics
set box size in Z to 0.1, effectively) and at the same time you have spread your objects in Z far away:PlayerScene
has Z = 1,PlayerScene
children likeStandIdleAnim
have Z = 1 + 1 = 2 (as designed in CGE editor), andMouse
ha Z = 9 (as set byMouse.Translation := Vector3(Mainviewport.PositionTo2DWorld(Container.MousePosition, true), 9)
).So the boxes of mouse and sprites never touch in Z.
Solution: Do not set small size, like
Size.Z := Max(0.1, Size.Z);
. Instead set big size, likeSize.Z := 1000;
, in bothMakeMousePhysics
andPlayerScenePhysics
. This way you donât need to modify Z position of anything, everything will work the same, and you will see collisions.I recall that line
Size.Z := Max(0.1, Size.Z);
was coming from my earlier advise, but I didnât know your usecase, that you will spread boxes far away in Z Sorry! -
Unfortunaltey, we are forced into a situation not supported by Kraft, our physics engine, as far as I can see in testing (I also adjusted a similar approach to
examples/physics/physics_2d_collisions/
to confirm).You have now 2 bodies with
Dynamic
=false
, and our current physics engine doesnât detect collisions between them. I do not have a solution for this one, I just spent an evening searching. UsingTRigidBody.Trigger
doesnât help, Kraft just doesnât set âcollidesâ flag on these bodies.
The 3rd point above is CGE / Kraft problem, and it doesnât have a solution for now. You are trying to use physics engine as a mere âcollision detectionâ, and this internally is not supported, and it is not a case we can easily fix without changing physics engine. We plan to support other physics engines (in particular, Bullet, I also mentioned Box2d above) as an option, but this is for the future.
Thanks for sorting this out!
Overall conclusion is that I should stick to the RectangleXY.Collides.
Which is not bad after all because I use different spritescreens for different animations, so a âstandidleâ animation by default has a smaller rectangle around it than a âwide leggedâ walking character, so the scene box will be smaller also.