Guides

Guides for how to do little things

Enum in Java with int conversion

If you’ve found this post, chances are you want to convert from an enum to an int, or alternatively from an int to an enum in Java. Well… you can’t. Java has the most robust implementation of the ‘enum pattern’ of any language, in essence enums are a class that can only be instantiated once. This makes them ideal as singletons by the way…

Anyway, since enums are a class, you need to provide the int functionality yourself. For my example, I’m going to be making a ‘difficulty’ enum which should be very familiar with anyone making games for Android. First declare your enum:

public enum Difficulty
{
    EASY(0),
    MEDIUM(1),
    HARD(2);

    /**
     * Value for this difficulty
     */
    public final int Value;

    private Difficulty(int value)
    {
        Value = value;
    }
}

This should be fairly familiar to you if you’ve worked with Java enums for any length of time. Each enum is effectively an instance of itself, so we can pass values to the constructor. We store the value in a final field (enums are by definition immutable – don’t go breaking this without good reason!) for future retrieval. Ideally the value should be accessed by a getter rather than directly, but I think in this case it makes more sense to making it a public field. The user can’t change it, and we don’t need any code to run on access; so I think a getter would just reduce performance and make consumption that little bit more tedious.

Now we need to add the important part, the conversion from int to the enum itself:

// Mapping difficulty to difficulty id
private static final Map<Integer, Difficulty> _map = new HashMap<Integer, Difficulty>();
static
{
    for (Difficulty difficulty : Difficulty.values())
        _map.put(difficulty.Value, difficulty);
}

/**
 * Get difficulty from value
 * @param value Value
 * @return Difficulty
 */
public static Difficulty from(int value)
{
    return _map.get(value);
}

So what are we doing here, exactly? Well we create a map that will be our lookup table, we do this rather than a switch statement to minimise long-term maintenance. If someone added an extra enumeration in the future, they may forget to update the switch statement – and this error won’t be picked up until runtime, and even then it may appear as incorrect behaviour rather than throwing an exception. After we’ve created the map, we populate it automatically by looping through all of the enums and adding them and their value to the map.

So there you have it, the proper pattern for adding int values to an enumeration. The code in full is below:

public enum Difficulty
{
    EASY(0),
    MEDIUM(1),
    HARD(2);

    /**
     * Value for this difficulty
     */
    public final int Value;

    private Difficulty(int value)
    {
        Value = value;
    }

    // Mapping difficulty to difficulty id
    private static final Map<Integer, Difficulty> _map = new HashMap<Integer, Difficulty>();
    static
    {
        for (Difficulty difficulty : Difficulty.values())
            _map.put(difficulty.Value, difficulty);
    }

    /**
     * Get difficulty from value
     * @param value Value
     * @return Difficulty
     */
    public static Difficulty from(int value)
    {
        return _map.get(value);
    }
}

Bonus

OK I can’t leave you with just this without providing a little ‘from here’ info. Switching on an enum in Java isn’t ideal since you can add all sorts of information to the enum to minimise the necessity for a glorified if..elseif statement. For this difficulty example, we could add a ‘multiplier’ field that allows code to automatically modify state values based on the selected difficulty. See below:

public enum Difficulty
{
    EASY(0, 0.5f),
    MEDIUM(1, 1.0f),
    HARD(2, 2.0f);

    /**
     * Value for this difficulty
     */
    public final int Value;

    /**
     * Multiplier for difficulty
     */
    public final float DifficultyMultiplier;

    private Difficulty(int value, float multiplier)
    {
        Value = value;
        DifficultyMultiplier = multiplier;
    }
}

So now we’ve added the multiplier to the difficulty, we could use it like so:

enemy.speed = baseSpeed * difficulty.DifficultyMultiplier;
player.speed = baseSpeed / difficulty.DifficultyMultiplier;

This has the added advantage that you can manipulate the global difficulty in a single central place.

Posted by Dan in Guides, Java, 7 comments

Network Game Synchronisation

This is going to be a slightly more ‘abstract’ post compared to what I normally do, but I think it’ll be useful for anyone making multi-player games. The biggest problem with multi-player games is network latency & bandwidth. This is something you just have to design for with your game mechanics, for example many MMOs have ‘cast times’ for most actions to cover the latency between the various clients and the server.

In this post I’m going to show clock synchronisation, a kind of synchronisation where you can ensure your various clients are all sharing the same timestamp as the host, give or take a few ms. For my game, having the same clock on all clients means I can time actions to occur simultaneously across all users. The code below is Java for Android, but it can be ported across to other platforms easily enough.

First you need to request the host’s current timestamp:

_timeRequest = System.currentTimeMillis();
_networkDroid.sendMessage(address, GameMessage.REQUEST_TIME);

_timeRequest in this case is a long field, while _networkDroid is my networking layer. Next when you get a response, you need to get the offset between the host’s timestamp and the client’s:

long currentTime = System.currentTimeMillis();
long travelTime = (currentTime - _timeRequest) / 2;

_timeDifference = (int)(currentTime - (remoteTimestamp + travelTime));
_timeRequest = 0;

In this code we first get the client’s current time, we get this as early as possible to minimise the error margin. Next we work out how long it took the packet to arrive from the host – we do this by dividing the total transit time by 2 (the first half was sending the request). Next we work out the difference between the hosts timestamp (with transit time taken into account) and the client’s timestamp.

Finally to get the synchronised timestamp is simple:

return System.currentTimeMillis() - _timeDifference;

And there you have it, synchronised clocks!

Posted by Dan in Game, Guides, Programming, 0 comments

Global ProgressBar in WP7

I quite like to have a global Performance Progress Bar in my Windows Phone 7 apps so the user has a consistent frame of reference when I’m interacting with web services. The requirements are simple, a progress bar that appears on all pages without any special requirements (ie. no custom controls, special code snippets, etc.). It should be managed in one place, and be easy to extend. Fortunately the extreme flexibility Silverlight offers makes this a doddle:

First add the following style to your App.xaml file:

<Style x:Key="mainFrameStyle" TargetType="phone:PhoneApplicationFrame">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="phone:PhoneApplicationFrame">
                <Border x:Name="ClientArea"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}"
                        Background="{TemplateBinding Background}"
                        HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
                        VerticalAlignment="{TemplateBinding VerticalAlignment}">
                    <Grid>
                        <toolkit:PerformanceProgressBar
                            IsIndeterminate="True"
                            VerticalAlignment="Top"
                            Canvas.ZIndex="999"
                            Foreground="{StaticResource PhoneAccentBrush}"
                            Visibility="Collapsed"
                            Loaded="globalProgressBar_Loaded"
                            />
                        <layout:ContentControl
                                ContentTemplate="{TemplateBinding ContentTemplate}"
                                Content="{TemplateBinding Content}"
                                HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
                                HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
                                VerticalAlignment="{TemplateBinding VerticalAlignment}"
                                VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
                                Margin="{TemplateBinding Padding}">
                        </layout:ContentControl>
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Next go into the code behind, and add the following variable to the top of the class:

private PerformanceProgressBar _globalProgressBar = null;

Next add the following methods to the bottom the App class:

private void globalProgressBar_Loaded(object sender, RoutedEventArgs e)
{
    _globalProgressBar = sender as PerformanceProgressBar;
}

public void ShowProgressBar()
{
    if (_globalProgressBar != null)
        _globalProgressBar.Visibility = Visibility.Visible;
}

public void HideProgressBar()
{
    if (_globalProgressBar != null)
        _globalProgressBar.Visibility = Visibility.Collapsed;
}

Now find the InitializePhoneApplication() method, and amend the RootFrame instantiation code to the following:

RootFrame = new PhoneApplicationFrame()
{
    Style = (Style)Resources["mainFrameStyle"]
};

And you’re done! You can call the progress bar like so:

((App)App.Current).ShowProgressBar();
((App)App.Current).HideProgressBar();

You can download the sample project here for your reference.

Update: This method for displaying a global ProgressBar doesn’t always play well with the WP7 Toolkit Transitions. However, I would highly recommend using the WP7Contrib Transitions anyway (they work well with the global ProgressBar too). I’ve created a 3-part guide on the transitions here.

Posted by Dan in C#, Guides, Windows Phone, 3 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

Customising Eclipse

Eclipse is a very good IDE, I hesitate to say ‘excellent’ because it does have its drawbacks. For example it constantly gets in a muddle with dependencies when you deal with plugins. It’s also developed in Java, so it’s not the fastest IDE in the world. Still, it does offer the most important functionality necessary for fast development of Android applications. Of course being a programmer means I’m notoriously fickle about my development environment – all IDEs should follow Visual Studio and that includes Eclipse. First on the agenda is code hinting, Visual Studio provides this instantly and so should Eclipse!

To bring up the handy dropdowns instantly, go to Window > Preferences. Then go to Java > Editor > Content Assist. Set the Auto activation delay to 0. Of course you’ll need a fast PC, but I’m sure you do.

Next up is the colour scheme, I have my own (which is the correct one) and many other programmers have their own (which are incorrect). Fortunately Eclipse Color Themes have your back. Install their plugin, then download the theme that most closely matches your ideal colour scheme. A minor tweak later and you should get a good match to what you’re used to:


Lastly you’ll probably want to change the code formatting. What do you mean it’s fine as it is? OK OK, I was taught a specific code formatting style and to be frank while it’s not necessarily ‘standard’ in Java, it is very clear. I prefer code to be as clear as possible, giving bugs fewer places to hide. Fortunately Eclipse has the most advanced code formatting customisation I’ve ever seen. First up is the code style:


This lets you set up some basic prefixes / suffixes along with a few other style tweaks. The best part though, is the formatter:

This really lets you customise the code formatting, ensuring all code is formatted in the correct manner – my manner. The customisation is extremely extensive, and it’ll probably take you a while to make it format in exactly the manner you desire. Once you’re happy you can open up any source file and press CTRL + Shift + F to reformat the code, it’s extremely effective.

So that’s it for this little guide. There’s a lot to explore in the Eclipse preferences, and it’s well worth taking the time out to see just what’s available.

Posted by Dan in Guides, 1 comment