Month: May 2011

AG_E_PARSER_BAD_PROPERTY_VALUE

So you’re getting the most awful error Silverlight can throw… I really wish I could tell you that if you hope on one leg while reciting the alphabet in reverse order will give you a vaguely helpful error message, but I can’t. The most common causes are:

Basically if there’s anything Silverlight doesn’t like at runtime, it’ll tend to throw this error. I’ll try to help you with the last two on the list above.

Layout Issue

In the stack trace for the error, check for the tell tale references to ‘MeasureOverride’. This means you’ve probably got a layout issue. What you’ve likely got is a fixed-width element, and the children require more space than you’re providing. In my case I had a table column that was 2 pixels too narrow. If your layout allows it, try to avoid using pixel sizes even if you know the correct size since sometimes additional styling can change required sizes slightly.

Some other problem

This one is the trickiest to solve, for obvious reasons. The best way I’ve found to debug is to go completely old school and strip everything back to the bare minimum and see if your code works then. This includes removing data binding. You need to get the page to display without any errors. Once you’ve reached this point slowly start re-introducing code. Eventually the error will re-appear and you should have a much better idea of exactly where the problem is. Of course you have to solve the problem still, but at least you know roughly where it is now.

Posted by Dan in Windows Phone, 0 comments

Isolated Storage Settings In WP7

Recently I had a problem with Isolated Storage Settings on WP7 – the entire collection appeared to be wiped every single time I restarted the app. The problem turned out to be the deserialization stage of IsolatedStorageSettings, in essence if any object can’t be re-instantiated, then the entire collection is inaccessible. The collection will work correctly until you attempt to retrieve something that can’t be instantiated.

At the bare minimum the constructor of your class must be public.

All non-public properties will also fail to be restored, resulting in a rather empty object instance when you come to load the values that should have been saved (and have been… they just don’t come back). Be very careful with this issue, you may not notice the problem until it’s too late.

Posted by Dan in C#, Windows Phone, 1 comment

NLipsum for Windows Phone 7 (Auto Generate Lorem Ipsum For WP7)

While developing a Silverlight WP7 app, it’s often handy to display demo content in design view so you have an idea of how real content will look. This is one of the biggest advantages of the MVVM architecture – separate data for design and runtime, as demonstrated below:

Fortunately Alex Pendleton has created a Lorem Ipsum generator in .NET 2.0 called NLipsum. Unfortunately it doesn’t work directly on WP7 without a little massaging. Fear not, for I have done the work for you! You can download the project files here, or the binary here.

The dll contains some raw XML files for generating the lipsums, and these are loaded at runtime. For this reason it’s best not to have the binary included with release builds of your app, lest you get a slower startup and increased memory usage. I’ve put in some caching that should mean you can call the generator as much as you like without worrying too much about performance. To use the generator, include it into your project and import the namespace:

using NLipsum.Core;

Then, it’s a simple case of calling the generator to do your bidding:

return LipsumGenerator.Generate(1, Features.Paragraphs, null, Lipsums.LoremIpsum);

return LipsumGenerator.Generate(1, Features.Sentences, null, Lipsums.TheRaven);

return LipsumGenerator.Generate(2, Features.Words, null, Lipsums.LeMasque);

If the content doesn’t show in design view, try re-building your app. This will refresh your design-time databinding as well as bringing in any changes you’ve made to the model (such as adding the lorem ipsum).

Posted by Dan in C#, Windows Phone, 1 comment

Honeycomb for Advent Vega

Honeycomb for the Advent Vega is now at a stage where it’s mostly usable day to day, you an pick it up at Tabletroms. Very impressive work by newbe5 and Corvus to not only get Honeycomb working so quickly, but to get it working so well so quickly after the initial releases!

Posted by Dan in Android, 0 comments

Resizing WP7 WebBrowser Height to Fit Content

At some point you’re probably going to need to have the height of a WebBrowser on your Windows Phone app resize automatically to fit the content, so that the other content on the page can wrap nicely around it. Fortunately MS have provided all of the functionality you need to pull this off, albeit in a somewhat roundabout way.

Adding the browser

First of all put a WebBrowser in to your XAML file, or alternatively add it pragmatically. Make sure IsScriptEnabled is set to true, by default it’s false.

If you’re adding the browser in code, make sure the height is at least 1 pixel.

Hooking up events

You’ll need to hook up the ‘ScriptNotify’ event, use the following code in the event handler:

protected void WebBrowser_ScriptNotify(object sender, NotifyEventArgs e)
{
	WebBrowser thisBrowser = (WebBrowser)sender;
	int height = Convert.ToInt32(e.Value);
	double newHeight = height * 1.5;

	thisBrowser.Height = newHeight;
}

This gets the browser that fired the event (so feel free to re-use the event for multiple browsers), gets the height the browser thinks it needs to display the content. The height value is actually set by the JavaScript, so due to the built-in scaling of the content you’ll need to multiply it by 1.5. Finally the browser’s height is set to the correct value to fit the content.

Add a teaspoon of JavaScript

Lastly, you need to add some JavaScript to the HTML you pass into the browser:

<script type="text/javascript">
    window.onload = function () {
        var elem = document.getElementById('content');
        window.external.Notify(elem.scrollHeight + '');
    }
</script>

This code will find an element with the ID of ‘content’, and send the height to your program. This means you’ll need to wrap all of your content in a div like so:

<div id="content">
    <p>Hello World</p>
</div>

You may be wondering why we don’t just get the scrollHeight of body. While experimenting I found this was the most reliable – but if body works for you then it is the more elegant solution. You may also be wondering why we add ” to the scrollHeight in the JavaScript. This is due to window.external.Notify only supporting text strings, however the height is a number. By adding ” we convert the number to a string meaning window.external.Notify will work as intented. If you ever find Notify not working – check the datatype, it fails silently.

Finishing up

This should be enough for you to get started. You’ll probably want to customise the CSS to match the phone’s current theme, but that’s another guide for another day. One tweak you should probably think about doing now is to add some padding to the content div, otherwise the HTML you output tends to look out of place rammed right up against the border of the WebBrowser.

If you find the height returned isn’t correct, it’s most likely due to the scaling of the web content. Set the viewport width to a fixed value (you can pass in the width of the WebBrowser if generating the HTML on the fly, or you have the ability to process it before the browser reads in the HTML). You may also need to set the width of the div as well, using the aforementioned method.

Setting the viewport:

<meta name="viewport" content="width=320" />

Setting the div width + padding:

<style type="text/css">#content { padding: 10px; width: 300px; }</style>
Posted by Dan in C#, Guides, Windows Phone, 1 comment

How To Make A Simple Android Game with Cocos2D Part 2 – Rotating Turrets

Update: This code is using an outdated version of the Cocos2D port. It’ll still work if you use the sample download linked at the end – but it’s using outdated API calls. Unfortunately I don’t have time to update the tutorial to the new release of Cocos2D. Sorry guys 🙁

This is the second tutorial in the Simple Android Cocos2D Game Tutorial series, originally written by Ray Wenderlich for the iPhone. This one builds on the first tutorial by replacing the ninja with a rotating turret, and the projectiles with cannon balls.

Getting Set Up

Ideally you’ll have followed the first tutorial, in which case you can continue from where you left of. Failing that you can download the code from the previous tutorial and use that as your base – however, I highly recommend starting from the beginning.

Now download a new player sprite and projectile sprite, put both in the ‘assets’ folder of your project. You’ll need to update your code to use these new sprites, so without further ado let’s get modifying. In the GameLayer constructor, update the player line with the following:

CCSprite player = CCSprite.sprite("Player2.png");

Next update the ccTouchesEnded method, find where you create the projectile sprite and replace with the following:

CCSprite projectile = CCSprite.sprite("Projectile2.png");

Compile and run your project, it should now look like the following screenshot:


You’ve probably noticed it doesn’t look quite right, the turret doesn’t rotate with the projectile direction. Let’s fix that now.

Rotating To Shoot

Before we can rotate the turret, we need to store a reference to the player sprite so we can rotate it elsewhere in the program. In the GameLayer class, add the following field:

protected CCSprite _player;

Next we need to use the new field, update the Constructor instantiation code to the following:

_player = CCSprite.sprite("Player2.png");
_player.setPosition(CGPoint.ccp(_player.getContentSize().width / 2.0f, winSize.height / 2.0f));

addChild(_player);

Rotating the turret with the projectile is easier said than done, we’re forced to use a little maths to work out the angle. For this we’ll use a little Trigonometry, which means remembering back to SOH CAH TOA. In this example we’ll be using the ‘TOA’, or Tangent of an angle is equal to the Opposite over the Adjacent. The following illustration should help:

As you can see from the graphic, the angle we want to rotate to is equal to the arctangent of the Y offset divided by the X offset. Seems easy enough right? Unfortunately there are two caveats you must be aware off before we can go implementing general geometry in our games:

  1. The maths functions in Java use and return radians, not degrees
  2. Cocos2D rotations are clockwise rather than anti-clockwise, which is the opposite to what is expected, as shown in the graphic below:

Fortunately the solutions are very simple. The Java Math class provides a method to convert to and from radians. The second solution is to invert the angle by multiplying by negative 1. So for example 20° x -1 = -20°. This will effectively convert the counter-clockwise rotation to the clockwise rotation Cocos2D expects:

Let’s put what we’ve learned into practice. Add the following code to the ccTouchesEnded code, just before we play the sound effect:

// Determine angle to face
double angleRadians = Math.atan((double)offRealY / (double)offRealX);
double angleDegrees = Math.toDegrees(angleRadians);
double cocosAngle = -1 * angleDegrees;
_player.setRotation((float)cocosAngle);

You may have noticed we’re using doubles rather than floats. According to Google doubles are just as fast as floats with the only trade-off being increased memory consumption. Since there is no float version of Math.atan or Math.toDegrees, it’s better to stick with doubles so we don’t waste CPU cycles converting between double and float repeatedly.

Now compile and run, and you should have a rotating turret!

Rotate Then Shoot

We’ve got a great game here, but it could be better. The turret rotates instantly, which is unlikely given we’re firing cannon balls. It would be much better for immersion and realism if we smoothly rotate the turret to its new direction. This will take a little refactoring.

Add the following field to the GameLayer class:

protected CCSprite _nextProjectile;

Replace the projectile instantiation code in ccTouchesEnded with the following:

_nextProjectile = CCSprite.sprite("Projectile2.png");

Next replace all occurrences of ‘projectile’ with ‘_nextProjectile’ within ccTouchesEnded. While you’re replacing these occurrences, make sure to delete the following lines:

addChild(projectile);
_projectiles.add(projectile);

Update the turret rotation code (also in ccTouchesEnded) with the following:

// Determine angle to face
double angleRadians = Math.atan((double)offRealY / (double)offRealX);
double angleDegrees = Math.toDegrees(angleRadians);
double cocosAngle = -1 * angleDegrees;
double rotationSpeed = 0.5 / Math.PI;
double rotationDuration = Math.abs(angleRadians * rotationSpeed);
_player.runAction(CCSequence.actions(
		CCRotateTo.action((float)rotationDuration, (float)cocosAngle),
		CCCallFunc.action(this, "finishShoot")));

This code will rotate the turret with a rotation speed of half a second (0.5) for half a circle’s worth of rotation (since full circle in radians is 2 PI, a half circle is 1 PI).
Once the rotation is complete, we then call a method called ‘finishShoot’. Since we haven’t created that method, we should create it now:

public void finishShoot()
{
	addChild(_nextProjectile);
	_projectiles.add(_nextProjectile);
}

This method adds the projectile to the game. Since it’s called once the turret has finished rotating we can guarantee that projectiles will only fire once the turret is in position.
That’s it, we’re all finished! Have a play, and enjoy your handiwork.

What’s Next?

You can download the full source code here.

In the future I should be porting Ray’s final part of the series, but in the meantime you could have a look at his tutorial and see if you can port it yourself!

Posted by Dan in Java, Programming, Tutorials, 31 comments