Best way to resize an object and Emulator/Device weirdness

Jan 6, 2011 at 4:23 PM


I've been trying to reliably change the size of an existing dynamic object for the past few days now, with little success. Maybe somebody can give me hint in the right direction? I've just upgraded my project to the latest Farseer Engine and Helper, that also took some time, but I'm about to go crazy on that particular issue.

What I'm trying to do should be really simple:

  • I have a player controlled ball, an Ellipse object (20x20px) with a gradient fill.
  • I can navigate that ball through a labyrinth.
  • I also have collectible powerup items that affect the ball. e.g. enhance speed.
  • One such powerup shrinks the ball, so it can fit through smaller passages.

What I've tried so far, in addition to using a ScaleTransform on the visualElement to make it look smaller:

  • Directly change the size of the ball's Fixture:
    var newRadius = _playerBall.BodyObject.FixtureList[0].Shape.Radius * _powerupStrength; // is 0.5f
    _playerBall.BodyObject.FixtureList[0].Shape.Radius = newRadius;
    I didn't really expect this to work, because I've read several times that resizing fixtures causes trouble with some sort of farseer collision caching. Oddly enough it worked GREAT, it does exactly what I want! At least on the Emulator ... on a real device it behaves complettely different, totally erratic, sticking my ball into a wall and actually scaling its collision radius up instead of down.
  • Next attempt is very similar, but probably more by the book. I add an additional CircleShape fixture to the PhysicsSprite:
    CircleShape newShape = new CircleShape(newRadius, 1f);
    Then I switch the original Fixture collision off (by turning it into a sensor). It takes a few more tweaks than the above method (the 2nd fixture isn't really positioned perfectly in relation to its parent body and the ScaleTransform I use to scale the visual element is harder to get right), but in the end I got it working in the Emulator, but again not on the physical device. Same as above. What's up with that?
  • Now I'm trying to instead add a smaller 2nd Ball and transfer all relevant data over (Direction, Velocity etc.), then toggle between those 2. I haven't really been able to get it to work 100% yet - ATM I can see the correctly sized smaller Ball in Debug mode, but the Element is invisible, probably just an oversight on my side somewhere). Yet again, it behaves completely different on the Emulator than on a real phone.

Has anybody ever encountered something similar? It almost looks like there's some conditional Code in Farseer or the Physics Helper Library, that makes it behave differently between the Emulator and a real device. Morelikely its just me being dull, but whoknows. I'm really out of ideas by now...

Mark Kane

Jan 8, 2011 at 9:41 PM

I haven't seen any different behavior between the device and emulator - other than slower performance on the device. Perhaps the slower performance is causing the issue?

If you have a small repro, I could try it on my device and emulator.

Jan 8, 2011 at 11:41 PM

I've solved the problem in a different way. I guess sometimes its good to write everything down like I did here, it took the frustration away and made me start over and choose a different aproach. I am now using 2 balls and a joint. The Effect simply triggers between the two balls. Note to anybody also trying this - don't deactivate the unused ball, just turn it invisible and switch IsSensor on. If its inactive the joint won't do its work and upon switching over, the "other" ball will still be at the beginning of the level.

As for the Emulator vs. Device issue. I took your advice Andy and tried to do a simple repro app in Blend. Just the ball, a choke and two buttons (shrink and reset). I couldn't reproduce the problem. Maybe its something in my code - though I don't really have any kind of device/emulator switches. If I run into a similar issue again I will do some more research, but for now I'm moving on to one of the 200 other TODOs on my list. ;)