Thursday 27 January 2011

Frameworks, Toolkits and Libraries

Frameworks, Toolkits & Libraries.

I had an interesting question from some inquisitive 3rd years today and it was on the verge of dominating my afternoon so, since I spent a fair bit of my afternoon having a good think about it, I thought it only fair to share my views. NOTE: These are my views, not gospel. I have found that, especially in computing, terminology is easily (and incorrectly) substituted for other words that sound similar but are in fact different.

I was asked "What is the difference between a toolkit and library?" I answered, to the best of my knowledge and, of course within a programming context "A library is a set of related but non-linked programming classes. Now, just to be clear I mean non-linked from a programming perspective". The classes may be related but the bottom line is they do not rely on other classes to perform their function.

Libraries

A library. How to explain a library. Well, imagine a real-life library. If you walked into Dundee Central Library you'd find tens of thousands of books on thousands of subjects. A computer "library" is no different. Putting libraries into a programming context, a single book could be related to a single class

public class TreasureIsland
{
}

Again, if we go back to the real-life library scenario, most books are organised into subject area and, using the subject area is probably more similar to what you would find in a computer programming library.

Perhaps an example might explain it better and for this example I will choose the subject area of mathematics (don't worry, very simple mathematics!). I might have a class that looks like this (if you're still on the real-life library, this would be a book that describes how to add and subtract):


public static class MyMathClass
{
public static int Add(int num1, int num2)
{
int addedNum = num1 + num2;
return addedNum;
}
public static int Subtract(int num1,int num2)
{
int subtractedNum = num1 - num2;
return subtractedNum;
}
}

OK, so you may (or may not have) come across the static keyword before but now seems like a good time to briefly go over what it means and what it actually does.

The static keyword indicates that the class or the method does not need to be instantiated. In the case above, the class is MyMathClass and the methods are Add and Subtract. Now, I know the word instantiate sends shivers down the spines of programming students but if you don't know the difference have a look below. I will use a JME example because I know most of the students reading this blog are my JME students and if you're looking for a point of reference I am lifting this straight out of my Skeleton example.

...
public void MoveToGameScreen()
{
GameScreen myGameScreen=new GameScreen(this);
display.setCurrent(gameScreen);
}
...

Now, in the above snippet, the variable name is called myGameScreen and the class it relates to is called GameScreen but it is not instantiated until the = new GameScreen(this). We can tell a few things just by looking at the code.

1) We know that GameScreen is an instantiated class (and therefore NOT a static class) because we use the new keyword to create an instance of the GameScreen class called myGameScreen.

2) We know that GameScreen is an instantiated class because we use the new keyword and we supply it with a parameter. In this example we supply (this) which, if you look through your skeleton program is the midlet. Static classes cannot be instantiated and therefore cannot accept constructor parameters.

If you don't believe me (or still not quite grasping it) look at the original code snippet with MyMathClass. There is no constructor, only the class declaration

public class MyMathClass

and two methods

public static int Add(int num1, int num2)
{
int addedNum = num1 + num2;
return addedNum;
}
public static int Subtract(int num1,int num2)
{
int subtractedNum = num1 - num2;
return subtractedNum;
}

In fact, if you were to try to add a constructor to this class it would give you a compiler error telling you it is impossible to add a constructor to a static class because, well, that's the point of a static class.

Just before I move back to the original point of this post and just in case some are still struggling with instantiated classes (it's important, I assure you) I want you to have a think about any time you have had to put a debugging println() statement in your JME program.

System.out.Println("Prints to the console");

Look through any of your JME programs, at no point do you ever have to create a System class by typing System = new System(); That's because System is a static class provided by JME.

A library is (usually) a list of classes that provide functionality for very specific subjects. I say usually because there is no law on creating a programming library but you will find, through your own exploration of libraries available, this is a standard they try to follow.
NOTE: It isn't always possible to follow but if we considered the above example and wanted to add the ability to divide and then subtract a number to the MyMathClass above we could do something like

public static MyMathClass
{
.....
public static int DivideAndSubtract(int num1, int num2, int num3)
{
int divide = num1/num2;
int result = MyMathClass.Subtract(divide, num3);
return result;
}
.....
}

See how we take num1 and num2, divide them and then call the method Subtract. No need to instantiate the MyMathClass, we just call the subtract method using MyMathClass.Subtract(divide, num3);

So, back to the original point, a library is a set of routines that accomplishes many similar tasks that can be programmed independently of each other.

Now that we're done with libraries you'll be happy to hear that there wont be many code examples from here on in simply because toolkits and frameworks are too large to programmatically show.

Toolkits

Again, imagine a toolkit. You could imagine any sort of toolkit I suppose so let me contextualise it into a real-life scenario. Imagine being a carpenter, owning many planks of wood, a hammer and some nails. Now, I could ask you to build me a house but, given the toolkit you have, I'd be better off asking you for a kitchen unit. It should be noted that a carpenter would have had (and still would) have access to large amounts of study material in order to build a kitchen unit, like a library of books or the knowledge of the head woodworker and therefore it is safe to assume that most toolkits will contain libraries of some sort, one or many.

The challenge with toolkits is the that the onus is on the user to use their tools in the correct way. If you attempt to put a nail into your hammer your going to have issues. As a carpenter there would be an expectation that you understood why you hammer the nail and not the other way around! Similarly, for a programmer, a toolkit will provide you with a greater set of options, a greater freedom in how you construct your program. "Yes, you can build a kitchen unit but only if you tell me the correct way to do it. I mean, you're setting my angles wrong to my adjoining unit but if you want the dishwasher in the living room then I wont argue . . .

From a personal programming point of view, I have, on a few occasions, turned large libraries into small toolkits. For my PhD project, I did not have the luxury of a GUI manager that you might find in Windows Forms in C# or even Java layouts, I had to create all my user interface components by myself.

At first it was fine, but once I realised I had added 21 buttons across the top of my screen they started to act strange. They wouldn't automatically reposition themselves depending on my screen width, I had to constantly change the screen position of my buttons in a vain attempt to keep them on screen.

Originally I had my buttons positioned based on what my GUI library told me it should be and it was based on a List of how many buttons I had on screen. I soon realised that I needed to expand it to encompass more than just the number of buttons I had on screen, I needed to account for screen width. It wasn't just my screen width I had to account for either. Once I started testing on other machines I realised not everyone has access to a full HD-compatible screen resolution. So, rather than extend my already large library of static classes and methods I enclosed all the functionality I wanted into a custom programmed ButtonManager. My ButtonManager was great, all I needed to do was something similar to

public void Init()
{
Button startButton = new Button("Start",upTexture,downTexture,"Up",Down");
AddButtonToGUI(startButton);
}

I completely understand that means very little to anyone, since it is my program, but I can give you an example of what it looked like before I created my ButtonManager Toolkit.

Button startButton = newButton();
startButton.SetUpTexture(upTexture);
startButton.SetDownTexture(downTexture);
startButton.SetUpTextureTooltip("Up");
startButton.SetDownTextureTooltip("Down");
Vector2 tempVec = startButton.GetParentPosition();
this.theGUI.AddButton(startButton, tempVec);

I know you can't see the underlying code for either example but surely we can agree that placing a button on screen is much more code friendly in the first example than the second.

I guess the bottom line is that once you can no longer call static methods of your library that will solve your task it's time to create a cleaner solution and that solution would be called a toolkit. While creating a toolkit may sound daunting it's simply the ability to identify when one type of programming solution is no longer sufficient for your needs and upgrading to a new one.

Frameworks

I am going to spend one paragraph on frameworks and one only simply because I have a vague understanding of your coursework and can tell you that a "true" framework is not something you will ever be asked to develop at any university. Developing a full toolkit would usually involve a team of programmers, with UML diagrams and wage of 30k+, well, frameworks are more complicated. Not more complicated to understand, just more complicated to implement. In the previous examples of toolkits I used a carpenter analogy so I will continue on that train of thought with the framework. A "real-life" toolkit might allow you to build a kitchen unit, it would probably let you build a room. Using this scenario, a framework would be more like the architectural plans. "This framework says that these are your specifications". Your house cannot be bigger than x,y,z. Your house cannot have more than x amount of rooms, these rooms cannot have ceiling's higher than y amount . . . . You get the idea. A framework, in actual fact, doesn't tell you what you can do, it tells you what you can't do. For anyone who thinks it's an easy task, try it. Write a simple class that doesn't allow you to send negative numbers to the console screen using System.out.println(). Now imagine doing that for every possible data type as well as user defined classes. To give some examples of the enormity of task in developing a framework I list a few well-known frameworks below.
  • The .NET language is a framework
  • The PHP language is a framework
  • and HTML is a framework.

Closing Thoughts

The first thing that comes to mind is the vast vocabulary that programmers now use to describe programming features. Mixing and matching the words "libraries", "toolkits" and "frameworks" as a form of verbal description is not a sin, it doesn't make you a bad programmer and doesn't mean that you mis-understand the meaning of certain programming "catchphrases". The truth is they are "catchphrases" and "buzzwords" and as long as you communicate what you want done or you can identify what a client communicates to you, you should be in a better position to deal with what is being asked of you. In fact, there has never been (and probably never will be) an International definition for these terms. The important thing is that YOU, the programmer, can define between what they mean. I am simply trying to give you something for your brain to chew on.

Finally, and probably most importantly, certainly for Abertay students. I am not the person who sets your coursework. In this post I have been talking about the 3rd year, 2nd semester module Allan Milne has set. Any pertinent questions about your coursework should be directed to him. Not only will Allan know what is expected of you better than I will, Allan has a vast amount of knowledge that will not be rivalled within the University. I would encourage anyone with questions to make an appointment to discuss those questions with him. From my under-graduate experience he was always one of the most approachable and thoroughly decent lecturers.

Anyone interested in further reading should direct themselves to the links below.

Chris

Yes, a wiki link, yuk
Stack Overflow link.
Perhaps a slightly biased story but some good comments at the bottom
Specifically the post by Stanimir Stoyanov

Thursday 26 November 2009

Skeleton Program (Coursework)

Hi folks,

OK, I am sorry for those that expected this yesterday but it took about 4 hours longer than expected! At the bottom of this post is a link to a skeleton program that contains 4 screens, a thread and the RMS that you need to save and load user data. The RMS took a lot longer than expected and the music player you will get in tomorrow's lecture had to be coded tonight as well.

OK, so here's the details.

* You have a skeleton program that provides you with four screens
* Splash Screen
* User Info Screen
* Game Screen
* Game Over Screen

The example also shows you how to setup a game canvas with a game loop and provides the code to setting up and accessing persistent storage on a phone. If I am being totally honest I think you have all done rather well with this code!! I would STRONGLY advise you download the files and re-type them out. I feel that you get a better understanding when you are forced to type the code rather than copy and paste. It should take you about an hour to recopy my code into netbeans but I would encourage you to do so!

Regardless, I have tried my best to comment it to the point of ridicule so start with programming (or reading) in the following order

* GameMidlet
* SplashScreen
* UserInfoScreen
* GameScreen
* GameOverScreen

While I am happy to help in any way I can I would appreciate if you, as students, understood the effort and time that went into both your tutorial for Friday and this skeleton. All I ask is that you spend some of your time looking over it. You are welcome to rip off the code completely or pick and choose what you want to use.

If you have questions you are able to post to this blog or email me at c.mccreadie@abertay.ac.uk
You can of course wait until we have the next tutorial but feedback from the code is always helpful so any constructive criticism is welcome and encouraged.

See you all next week

See HERE for code.

EDIT: After downloading and extracting you should be able to open in netbeans if you "open project". I would still suggest re-typing the program but for those that need the quick fix ....

Chris

Tuesday 6 October 2009

Chessboard Tutorial

Some of you may have noticed the time of this post ( 10 hours before your class for some of you) but regardless....I cast aside my beer and my personal life and hacked up a very quick tutorial for you. Before I go any further I should say a big thank you to Scott Macaulay who not only gave me the idea for this tutorial but also part of the code!

There are three files to this tutorial. You can find them here but please read below before downloading.

The MIDlet is the ChessBoardMidlet.java file. When creating a new project make sure that you create a new Midlet before copying and pasting the code into it. The other 2 files are POJO's (Plain Old Java Objects) and should be created just as Java Class files.

The result should be a chessboard that has a green box that reacts to user input using the down button only. To carry on with this tutorial you should add code for the UP, LEFT and RIGHT key.

There is no real objective to the tutorial. The program starts off with a form asking for a username and an age (which does not need to be filled in) there are two or three buttons depending on which emulator you are using and all you need to do is click on the "Start Game" button to load the chess set. If you see any button that say qwerty please do not click on it as it is well outside the scope of your module. I hope it might give some of you a starter for your coursework or, at least, a better understanding of J2ME programming. There are plenty of comments but please feel free to ask for more info on anything. Please note that this is NOT a substitute for Geoff Lund's Tutorials and this should be considered as an additional but important extra.

For those that are interested in this tutorial, think about the following

1) Make the green cursor move down one square at a time, not 3/4 of a square.
2) Add methods for MoveRight(), MoveLeft(), MoveUp() to get the green "selection" square moving around the whole chessboard.
3) Think about different ways (perhaps even write them down) that you could visualise different chess pieces...text, sprites etc.

Cheers

Chris

Sunday 27 September 2009

Welcome: Abertay 3rd years

I realised that it had been a rather long time since my last post and, since I made most of you write down this blog, I felt it only fair to post on it and welcome you all to 3rd year and the joy (no, seriously) that is mobile development.

This blog should be looked upon as just part of your learning experience just as your lectures and tutorials do.


Anyways, more will be added this coming week.

Chris

Friday 31 October 2008

A Quick Update

Hi All,

Just a quick post about what I've been focused on over the last few weeks and what my plans are for the next couple of months that should take me up to the Christmas holiday season (apologies for mention Christmas in October!).

Firstly, Happy Halloween! Hope you all get right in the spirit and scare off your demons!

Secondly, I have recieved some really good feedback on the J2ME Pong tutorial so thanks to all the people who left a comment or spoke to me personally, your enthusiasm has given me the motivation to continue the series for those who are interested so there will certainly be a few more tutorials with things like Networking over the air and bluetooth, some AI and perhaps a tutorial on application writing rather than games programming.

This coming week I have a conference in Nottingham that focuses on the use of visualisation techniques in alternative computing. Later in the week, I will be in Edinburgh to meet with my other PhD supervisor and hopefully get some data on the Agent Based Models I will be using and a decision will hopefully be made on what area we are going to be focusing the project on so expect some more moaning about Agent Based Models, C'# and XNA.

Chris

Wednesday 22 October 2008

J2ME Pong Game - Walkthrough & Tutorial

Ok, first things first, a brief explanation of what we are going to be doing, but before I do let me say this is the first tutorial I have ever written, I usually find good ones and re-write them! I make no apologies for my style of writing or the flow of this tutorial.
Ok, so we are going to create a pong clone that will run on the Netbeans emulator. The tutorial will cover some J2ME game programming basics such as the Game Canvas and some of its classes, the use of images and sprites, sprite frame sequences in order to animate the sprites, multi-threading and collision detection. Now that might seem a lot but I can promise you it takes no more than two classes and less than 400 lines of code (which I think is pretty damn good to be honest).
The way I have written the game is to encourage flexibility and good programming practice, I will go into detail about plenty of things and I strongly recommend you read the whole tutorial line by line. When appropriate, I will provide screenshots and the source code will be given bit by bit. It should take you no more than an hour to complete. So, without further delay, let me present MobilePong, your next (and possibly first) J2ME game.
Okay, lets start Netbeans and create a new Mobile Application. The usual rules apply, create a completely empty project, call it MobilePong, do not create a visual MIDlet and make sure you select MIDP 2.0 as your target rather than 2.1.
Now, you NEED to download this zip file. The zip file contains three images in PNG format. One is the pong table that looks more like an air hockey table, one image contains the ball that will be used and one is an image of 8 different coloured pong paddles.
Now you need to navigate to your MobilePong project folder, this is usually “My Documents\NetbeansProjects\MobilePong. Now, when your there, create a new folder called “res” and put the three image files into the root of the newly created directory. The “res” stands for resources and this is where you should get into the habit of putting any external images and sounds you may use in your J2ME game.
Okay, back to Netbeans. Now we want to tell the project that we want to use the res folder for some of our resources. Click on the + symbol next to your project if it isn’t already expanded and right click on the Resources tag and select “Add Folder”.

You will be prompted to add the folder, just navigate to the res folder you just created with the three images in it.
Notice that we haven’t even created a class or MIDlet yet so perhaps we should do that now! Right click on the source packages and select New –> Midlet. Name the MIDlet “MobilePong” and if you understand how packages work you can create a package while you are at it but it will not affect the tutorial. I will assume you DO NOT but if you did, remember that you must make that your first declaration in every class including the MIDlet.

1: package packagename;

Okay, so we have create the MIDlet, but there’s not going to be too much going on there as we will have one main class that runs the game. So, lets create a new Java Class. Right click the source packages like you did for creating the MIDlet but this time it’s New –> Java Class. We will call this class “MainGame”.
Okay, if you made it this far, well done, I can promise you that everything from here on is is coding and no more setting up and messing about. The MainGame class is going to be responsible for displaying the graphics for our game so we need to import some libraries and extends the game canvas.
Right before the class declaration, import the required libraries and extends the class to use the GameCanvas like this

1: import java.io.*;
2: import java.util.*;
3: import javax.microedition.lcdui.*;
4: import javax.microedition.lcdui.game.*;
5:
6: public class MainGame extends GameCanvas
7: {
8:
9: }

Now you should notice a red warning line under the class declaration on line 6 saying that GameCanvas(boolean) cannot be declared as (). What this means is that the GameCanvas constructor (which you do not need to worry about) take a boolean parameter that tells it whether or not to suppress regular Canvas key presses. Don’t worry about this too much but basically, we need to create a constructor for MainGame and tell it that we want to suppress key events.
To do this we put the following code after the class declaration (line 8).

public MainGame()
{
super(true);
}

Okay, that got rid of the error so lets start thinking about what we use a constructor for. A constructor (like above) uses exactly the same name as the class name, is public 99.9% of the time and never has a return type, that’s how the compiler determines it is the constructor. Imagine the constructor being the place that all your initial setup code will go since it is only called whenever a new instance of the class is called (which in this example will be only once, we can only play one game at a time after all)!
This makes the constructor the best place to load in our images and change them into Sprites! So, just under the super(true) create a call to a method called loadImages() and create a method called loadImages after the constructor that is public and has a void return type.
Your code should now look like this

1: public class MainGame extends GameCanvas
2: {
3: public MainGame()
4: {
5: super(true);
6:
7: loadImages();
8: }
9:
10: public void loadImages()
11: {
12:
13: }
14: }

So, everytime we start a game, loadImages will be called and in this method we can put all our code to load as many images as we want! Of course, the images and the sprites will be accessed from outside the loadImages() method so we need to create a link for all the images we are going to be loading in the variable declaration part of the class which is before the constructor but after the class name. We have three images to load, the table, the ball and the paddle so lets do that now

// Links to the Images we load
private Image tableImage;
private Image paddleImage;
private Image ballImage;

public MainGame()
{
........
}
......
}

The dots represent code that is already written and the constructor is only in there to let you know where to put the code so it’s just the three Image variables you want to put in your code!
This DOES NOT create the image, it simply tells the compiler you have three Images that you are calling “pongTable”, “paddleImage” and “tableImage”. We will create them in the loadImages() method.

public void loadImages()
{
try
{
//Remember to load the res folder into netbeans
tableImage = Image.createImage("/PongTable.png");
paddleImage = Image.createImage("/Paddle.png");
ballImage = Image.createImage("/PongBall.png");
System.out.println("Loaded Images!");
}
catch(IOException ioex)
{
System.err.println(ioex+" Error loading images");
}
}

Everything in this method is surrounded with a try catch because it has to make sure the files can be found. If you haven’t added the res folder to the project, you would get an error when trying to run this. Creating an image is simple, you make the image variable you already declared equal Image.createImage(), real simple! I have put a print statement so that when we run it we can see that the images were loaded fine.
If you try and run this now IT WILL NOT WORK. That’s because we haven’t told the MIDlet to load the MainGame class so we’ll do that now. In your MIDlet code, declare a variable called myDisplay of type Display and a variable called theGame of type MainGame, just like this

public class MobilePong extends MIDlet
{
private Display myDisplay;
private MainGame theGame;

.....
}

Again, these do nothing on their own so we need to get the display from the phone, create a new instance of the MainGame class (which will load all the images now) and then set the display to the MainGame instance called theGame

public void startApp()
{
myDisplay = Display.getDisplay(this);
theGame = new MainGame();
myDisplay.setCurrent(theGame);
}

If you run this code you should see the emulator pop up and once you start the MIDlet the screen should appear white but Netbeans should write a statement saying the images were loaded. Congratulations, you have just imported your images to the game.
I know this is rather tedious but we’re getting to the good bits and if you can stop yourself from trying to run the code, the next time we run it we will have something to show on screen!
Before we move on, I said I was going to explain sprites (which I will) but one of the advantages of using the GameCanvas is that you can use something called a LayerManager where you can store all your sprites and, rather than drawing every single sprite you have in your game (which would get annoying with even a slightly larger game than this) we can draw the LayerManager to the screen and the phone will take care of the rest. So, you may have guessed, we’re going to create a LayerManager which takes only two lines of code.
We need to declare it just below where we declared our images and we need to instantiate it just after we load the images (in our constructor remember?).


1: private Image ballImage;
2: private LayerManager manager;
3:
4: public MainGame()
5: {
6: super(true);
7: loadImages();
8: manager = new LayerManager();
9: }

Line 2 is where we say we are using a LayerManager called “manager” and line 8 is where we create it. Now all we have to do is add our sprites to it. Well, I guess we should make some sprites then. Just under line 8 add a new method called loadSprites() and create the method for it, making it public with a void return type, just like so . . .

public void loadSprites()
{

}

Don’t forget to put the call just under the “manager = new LayerManager()” in the constructor.
Ok, a little on sprites. A sprite is just taking the image we previously created and making it a Sprite. There are some differences we will go into with the paddle because we are going to animate it but for now, just follow along. Now we need to declare them like we did with the images. So just under the images and LayerManager declaration we need to put

.....
private Sprite tableSprite;
private Sprite paddleSprite;
private Sprite ballSprite;

public MainGame()
{
.....
}
......
}

and in the loadSprites() method we just created, put the following code

tableSprite = new Sprite(pongTable);
paddleSprite = new Sprite(paddleImage, 10, 50);
ballSprite = new Sprite(ballImage);

Now, what we are going to do is add the newly created sprites to the our layer manager. Add the following under that code but still in the loadSprites() method

//Remember the z-order
manager.append(ballSprite);
manager.append(paddleSprite);
manager.append(tableSprite);

If you’re wondering why the paddleSprite looks slightly different, I’ll explain that really soon, just go with it just now.
Notice the comment? “What is Z-Order” I hear you scream! Well, the Z-Order is the order in which things appear on top of each other. We don’t want the table to cover the pong ball or the paddle, we want the ball and paddle to sit on top of the table so we have to make sure we add them to the manager in order from closest to furthest away. Since we will be performing collision detection on the paddle and the ball, they could be swapped around but the table needs to be added last.
Now, we can almost get something running on the screen. First, we’re going to need to go over Threads and how they work. In J2ME, when you want a class to be executed in a separate thread you need to implement an Interface called runnable.
At your class declaration add the words “implements Runnable” like this

public class MainGame extends GameCanvas implements Runnable
{
// Links to the Images we load
private Image tableImage;
private Image paddleImage;
.....
}

Notice the new “implements” statement at the end of the class? You should have a red line that, when you hover over it, tells you that you do not override the abstract method run(). This means that whenever you use this implementation, you MUST write your own run() method and create a variable link to the Thread just like you do with the Images and the Sprites so lets do that now !
Underneath the constructor we are going to create two new methods called “start” and “run” both are public and both have a void return type. The start method is just a convenience method that we can call from the MIDlet so don’t worry about that too much just now.

public MainGame()
{
super(true);
loadImages();
manager = new LayerManager();
loadSprites();
isGameRunning = true;
}

public void start()
{

}
public void run()
{

}

Don’t forget the link to the Thread at variable declaration

......
private Thread gameThread;

public MainGame()
{
.....
}

Now, what happens is that all the code is executed in a separate thread from the rest of the code. In practice, the way we are using it is a little bit of overkill but it gives you a good idea of how to use Threads. Imagine you had a large and complex amount of network data to send from one computer to another but you also have a large amount of processing of raw data as well. Do you really want to stop processing the raw data in order to send and receive a message from a server? No, you create a separate thread, do the time consuming networking in that and continue with the processing of raw data as well.
We want the start method to start the thread and run it so if we look back to the MIDlet again, we want to add this code just under the display code that we wrote a while ago we want to call the start method.

1: public void startApp()
2: {
3: myDisplay = Display.getDisplay(this);
4: theGame = new MainGame();
5: myDisplay.setCurrent(theGame);
6: theGame.start();
7: }

The only addition here is line 6 where we call the start method. At this moment, the start method is empty so lets code it! Back to the MainGame class.

public void start()
{
gameThread = new Thread(this);
gameThread.run();
}

I’ll talk these two lines through. The first instantiates the Thread object. The Thread constructor takes one parameter called “this”. That is just a fancy way to say “I want this class to be the class that is run in a thread”.
The second line calls the run method which we have created but not coded yet so we will do that now.
So, in this run method is going to be your game loop. The game loop will do what you would expect a game loop to do.
1) Check to see if there is any user input on the phone’s keypad.
2) Move any objects that need to be moved.
3) Check if there is any collisions between objects that you would want to act on (especially since the step before we have just moved things).
4) Update the mobile display.
There is an extremely easy control function that can accomplish all that and most of you will have encountered it…..it’s called the mighty while loop!
Let’s put a boolean value in our variable declarations (where we declare our images and sprites) and let’s call it “isGameRunning” and set it to the value true in the constructor, because, if we are creating an instance of MainGame then we can assume that we want the game to be running!

1: private Sprite ballSprite;
2: private boolean isGameRunning;
3:
4: public MainGame()
5: {
6: super(true);
7: loadImages();
8: manager = new LayerManager();
9: loadSprites();
10: isGameRunning = true;
11: }

Notice the additions in line 2 and line 10. We add the boolean variable called “isGameRunning” and set it to a value of TRUE in the constructor.
Now, back to the run method. There’s gonna be a few lines of code so struggle through and read the explanation afterwards to get a better understanding of it.

1: public void run()
2: {
3: Graphics g = getGraphics();
4: while(isGameRunning)
5: {
6: checkUserInput();
7: moveObjects();
8: collisionDetection();
9: updateGameScreen(g);
10: flushGraphics();
11: try
12: {
13: gameThread.sleep(60);
14: }
15: catch(InterruptedException ie)
16: {
17: System.err.println(ie);
18: }
19: }
20: }

Let’s go through this line by line and make sure you understand this before moving on.
Line 3 is where we get the graphics adapter for your phone. This isn’t as complicated as it sounds, it just gives you a way to draw Images, Sprites and basic shapes if you wanted. The only thing you need this for is to pass it as a parameter to another method that we haven’t coded yet.
In line 4 we start the game loop. Remember, in the constructor we set this to true so it will run indefinitely until we tell it otherwise and set it to false.
Lines 6, 7, 8 and 9 are calls to method that we are going to create in just a minute so don’t worry about them just now but the names should suggest what they will do.
Line 10 is a method that is used because we extend the GameCanvas right at the start. Flushing the graphics is common in game programming because we are using double buffering. Double buffering means we are drawing every frame to a screen that isn’t actually shown on the phone. Once we have drawn everything onto the screen, then we show it in one go. If we didn’t the screen would tear as we updated because not everything is updated at the same time and this is why you get “tearing” in games. So flushGraphics() basically takes the frame and sticks it onto the phone’s screen. It is imperative to put this just after updating your game screen.
Lines 11 to 18 is a try catch that makes the thread take the human equivalent of a breather. This game isn’t demanding at all so we don’t want to run this process as fast as we can. We tell the thread to sleep for 60 milliseconds by passing the number 60 as a parameter to gameThread.sleep(60);. You can of course change this and you would see your game speed up or slow down depending on the number you set.
Now I know I promised you that things would be shown on screen so I will keep to my promise. All you need to do is create three empty methods and one last method that draws all your hard work.
If you look at the code you have just written we need to create a method for:
1) checkUserInput()
2) moveObjects();
3) collisionDetection()
4) updateGameScreen(g)
All these methods are public and return void but let’s do the first three first then we’ll talk about the fourth one and get something on screen.
Underneath the last method we wrote in the MainGame class (which should have been loadSprites) we will put the rest of these methods

public void loadSprites()
{
tableSprite = new Sprite(tableImage);
paddleSprite = new Sprite(paddleImage, 10, 50);
ballSprite = new Sprite(ballImage);
}

public void checkUserInput()
{

}

public void moveObjects()
{

}

public void collisionDetection()
{

}

This just stops errors from appearing when we run the code (which will be very soon, I promise).
Last method to implement is the updateGameScreen method which we will put just under the collisionDetection(). If you look at the call we make to it in the run method, we pass it “g” which is the Graphics Adapter so it’s very similar to the other but with one parameter. Also, in the method, since it is just the sprites we want to draw, and remember, all the sprites are loaded into our manager, we want to draw the manager and let the phone do the hard work

public void updateGameScreen(Graphics g)
{
manager.paint(g, 0, 0);
}

Ok, I know you don’t really want me to explain anything just now so run the code!
You should see something similar to this

Notice that with one call of the manager’s paint method, everything was drawn to screen. We pass the (Graphics g) parameter so it has a link to the graphics adapter which is, in turn, passed to the managers paint method with “manager.paint(g, 0, 0);” Now the “g” part is easy enough to understand. The “0, 0” part is what part of the screen it should update. We want it to update the whole screen so we set it to 0, 0 which is top left on the mobile phone. If we had a score counter at the very top we might want to set it to 0, 20 and update the score a different way but that’s outside the scope of this particular tutorial.
Before I move on, I’m going to post the whole code up to this point in case anyone is having trouble or daft errors (I mean daft as in spelling mistakes and forgetting to initialise variables because we all do it!).
So, first, the MIDlet.

1: import javax.microedition.midlet.*;
2: import javax.microedition.lcdui.*;
3:
4: public class MobilePong extends MIDlet
5: {
6: private Display myDisplay;
7: private MainGame theGame;
8:
9: public void startApp()
10: {
11: myDisplay = Display.getDisplay(this);
12: theGame = new MainGame();
13: myDisplay.setCurrent(theGame);
14: theGame.start();
15: }
16:
17: public void pauseApp()
18: {
19:
20: }
21:
22: public void destroyApp(boolean unconditional)
23: {
24:
25: }
26: }

Now the MainGame class.

1: import java.io.*;
2: import java.util.*;
3: import javax.microedition.lcdui.*;
4: import javax.microedition.lcdui.game.*;
5:
6: public class MainGame extends GameCanvas implements Runnable
7: {
8: // Links to the Images we load
9: private Image tableImage;
10: private Image paddleImage;
11: private Image ballImage;
12: private LayerManager manager;
13: private Sprite tableSprite;
14: private Sprite paddleSprite;
15: private Sprite ballSprite;
16: private Thread gameThread;
17: private boolean isGameRunning;
18:
19: public MainGame()
20: {
21: super(true);
22: loadImages();
23: manager = new LayerManager();
24: loadSprites();
25: isGameRunning = true;
26: }
27:
28: public void start()
29: {
30: gameThread = new Thread(this);
31: gameThread.run();
32: }
33: public void run()
34: {
35: Graphics g = getGraphics();
36: while(isGameRunning)
37: {
38: checkUserInput();
39: moveObjects();
40: collisionDetection();
41: updateGameScreen(g);
42: flushGraphics();
43: try
44: {
45: gameThread.sleep(60);
46: }
47: catch(InterruptedException ie)
48: {
49: System.err.println(ie);
50: }
51: }
52: }
53:
54: public void loadImages()
55: {
56: try
57: {
58: //Remember to load the res folder into netbeans
59: tableImage = Image.createImage("/PongTable.png");
60: paddleImage = Image.createImage("/Paddle.png");
61: ballImage = Image.createImage("/PongBall.png");
62: System.out.println("Loaded Images!");
63: }
64: catch(IOException ioex)
65: {
66: System.err.println(ioex+" Error loading images");
67: }
68: }
69:
70: public void loadSprites()
71: {
72: tableSprite = new Sprite(tableImage);
73: paddleSprite = new Sprite(paddleImage, 10, 50);
74: ballSprite = new Sprite(ballImage);
75:
76: manager.append(ballSprite);
77: manager.append(paddleSprite);
78: manager.append(tableSprite);
79: }
80:
81: public void checkUserInput()
82: {
83:
84: }
85:
86: public void moveObjects()
87: {
88:
89: }
90:
91: public void collisionDetection()
92: {
93:
94: }
95:
96: public void updateGameScreen(Graphics g)
97: {
98: manager.paint(g, 0, 0);
99: }
100: }

Hopefully you have the game showing something similar to what my screenshot shows. Now having a static screen like this isn’t very exciting so we want to move the ball around the screen without user input and we want the paddle to move with user input. In order to do this and make it look at least semi-professional, we should put the paddle in the middle of the “goal” and the ball on the centre circle. Since these are starting positions and will never need to be set more than once we can set them in the constructor. So, to continue with good coding practice, we will make a method that sets them up and put the code there. If you can think ahead just a little bit, we are going to do collision detection on both the paddle and the ball so we are going to want to capture the coordinates of the X and Y position of both the ball and the paddle. In order to do this we will need to add 4 new variables to the growing variable declaration list where we added the Images, Sprites, the Thread and the isGameRunning declaration. So, add the following

So, in the constructor put the following call to the method “setInitialPositions” with public access and a void return type.
Your constructor should now look like this

1: public MainGame()
2: {
3: super(true);
4: loadImages();
5: manager = new LayerManager();
6: loadSprites();
7: isGameRunning = true;
8: setInitialPositions();
9: }

The only change should be on line 8 where you add a call to “setInitialPositions”. Next, under the last method you created which should have been “public void updateGameScreen(Graphics g)”, you want to create that “setInitalPositions()” method. I will write in the code we will use, type it in and then I will explain it.

1: public void setInitialPositions()
2: {
3: //Remember the size of the sprite and the ref pixel is top left
4: paddleSprite.setRefPixelPosition(paddleSprite.getWidth(), tableSprite.getHeight() / 2 - (paddleSprite.getHeight() / 2));
5: paddleX = paddleSprite.getRefPixelX();
6: paddleY = paddleSprite.getRefPixelY();
7:
8: ballSprite.setRefPixelPosition(tableSprite.getWidth() /2 - (ballSprite.getWidth() / 2), tableSprite.getHeight() / 2 - (ballSprite.getWidth() / 2));
9: ballX = ballSprite.getRefPixelX();
10: }

Let’s walk through it line by line. Line 4 is the first thing that needs explanation. You have a link to the paddle called paddleSprite (look at your loadSprite method in case you forgot). By calling the “setRefPixelPosition” method from the paddle’s sprite class we can set where it is position on the screen (in this case only initially as we will move the paddle up and down later with input from the keypad). The method takes two parameters which are the X and Y coordinates of the new position (if you are not really understanding all that, highlight the “setRefPixelPosition” and press ALT + F1 to bring up the javadoc.). This will the position of the paddle to be re-located to the X and Y coordinates of the parameters that are passed through the method. Let’s look at what we are passing. Sadly, this is the part where Math kicks in and since some people have trouble with numbers (including myself may I add) and a certain person has had two bottles of wine (yeah, that would be me)! This may be the worst part of the tutorial but please please please struggle through it. 2D coordinates are easy to understand when you think about it long enough!
paddleSprite.setRefPixelPosition(paddleSprite.getWidth(), tableSprite.getHeight() / 2 - (paddleSprite.getHeight() / 2));
Okay, look at the first part of the line. “paddleSprite.setRePixel”. This is us saying “this is where we want the paddle to originally be positioned”. We want it smack-bang in the middle of the table and a little bit away from the left hand edge. Just remember that! Now, the X coordinate goes left to right and the Y coordinate goes from top to bottom. So, the X coordinate we want a little bit away from the left hand edge. Let’s just make it the size of a “paddle” away from the left hand edge. So we say “paddleSprite.getWidth()” which will be 10 (look at your loadSprite() method if you don’t believe me). So this says set it 10 pixels to the right of the edge. The next part of the code says “tableSprite.getWidth() / 2 - (paddleSprite.getHeight() /2 ))” Okay, it looks complicated but lets look at it logically and sequentially.
“tableSprite.getWidth() / 2” is easy it’s whatever the table width is but halved. Who cares what screen size we have, the table is of “n” size so whatever size it is, half it! Great, we have our X coordinate. Now we need the Y coordinate. The Y coordinate needs to be halfway down the screen. What you need to remember is that the way the phone measures the sprite is from a top-left coordinate of the sprite. That means we need half the height of the Sprite to be subtracted from the table’s height otherwise it will be slightly closer to the top than the bottom. So, for the Y coordinate we say “tableSprite.getHeight() / 2 - (paddleSprite.getHeight() /2))” this subtracts half the paddle height from the middle of the table height and makes the paddle show up in the middle. If it didn’t make sense, read it again. I’m sure it will this time.
We set paddleX and paddleY to the appropriate positions by coding
paddleX = paddleSprite.getRefPixelX();
paddleY = paddleSprite.getRefPixelY();
We will use this later for both collision detection and checking user input.
Next, we do the exact same for the ball but place it in the middle of the table.
ballSprite.setRefPixelPosition(tableSprite.getWidth() /2 - (ballSprite.getWidth() / 2), tableSprite.getHeight() / 2 - (ballSprite.getWidth() / 2));
Remember, the reference pixel is at the top left of the ball so we need to subtract half the ball’s width and half the ball’s height in order to get it dead centre on the screen.
By now you should have the paddle sitting in the middle of the goals and the ball in the centre. Remember when we created the paddle sprite and we created it slightly differently from the other two. What we said was
paddleSprite = new Sprite(10, 50);
Well, if you get the chance, open up the paddle image in paint or Photoshop and look at it. Notice that the first colour is a light green and is followed by 7 other colours? Well these are the different frames we are going to animate. The two values that we passed into the Sprite constructor (10, 50) is the width and height of each frame. Because I created the images, I already knew this, if you were creating your own they can technically be any size you want. The whole image was loaded into the sprite but only the first frame (10 pixels by 50 pixels) is ever drawn. If we want another of the frames to be drawn, all we have to do is add one line of code.
We are going to draw each frame sequentially. It is possible to setup a custom frame sequence but I suggest you look at the javadoc if you wish to that (it is very easy though). So, in the main game loop, just after we call the “flushGraphics()” method we want to add this

1: public void run()
2: {
3: Graphics g = getGraphics();
4: while(isGameRunning)
5: {
6: checkUserInput();
7: moveObjects();
8: collisionDetection();
9: updateGameScreen(g);
10: flushGraphics();
11: paddleSprite.nextFrame();
12: try
13: {
14: gameThread.sleep(60);
15: }
16: catch(InterruptedException ie)
17: {
18: System.err.println(ie);
19: }
20: }
21: }

The only difference is line 11. Run the code now and you should see the paddle changing colours! That’s how you animate a sprite! We have put that in the main game loop so it will continue to do that while the game is running, you could of course map it to a key press or an event just as easily.
Now, let’s get the paddle responding to user input. We already have an empty method for this called “checkUserInput()” so put this code in and we will go through it line by line.

1: public void checkUserInput()
2: {
3: int button = getKeyStates();
4: if((button & UP_PRESSED) != 0)
5: {
6: //Check the paddle is not already at the top
7: if(paddleY >0)
8: {
9: paddleY -= 4;
10: }
11: }
12: if((button & DOWN_PRESSED) != 0)
13: {
14: //Check the paddle isn't at the bottom of the screen
15: if(paddleY < tableSprite.getHeight() - paddleSprite.getHeight())
16: {
17: paddleY += 4;
18: }
19: }
20: //Set the new location
21: paddleSprite.setRefPixelPosition(paddleX, paddleY);
22: }

When you press a get on the keypad, it gets a numerical value. To access these values we link an integer to it in line 3.
Then we use if statements to determine whether a button has been pressed. The UP_PRESSED is a static field and there are plenty more that you can use (check the javadoc) for all the different buttons on the phone.
We check to see if the value does not equal zero (which means the key is pressed) and then we have a nested if after that because we would only want to move the paddle up if it was not already at the top of the screen. We then set paddleY to 4 less than it was. Remember the Y-axis starts at the top left to the bottom left.
We exit both those if statements and immediately start a new one, this time to check if the down button has been pressed (line 12). Again, we want to check that the paddle is not at the bottom of the table (not the bottom of the screen as they are two different sizes). We need to subtract the height of the paddle as well since the reference pixel is located at the top left of the paddle. Right at the end of the method, we call a method of paddleSprite that we have already used when we initially setup the position, the “setRefPixelPosition(paddleX, paddleY)”. We give it the x and y coordinates of where the paddle now is.
Run your code and press up and down either on your keyboard or on the phone’s game pad and you should see the paddle moving.
Just to keep you up to date, this is the full code listing so far
The MobilePong MIDlet

1: import javax.microedition.midlet.*;
2: import javax.microedition.lcdui.*;
3:
4: public class MobilePong extends MIDlet
5: {
6: private Display myDisplay;
7: private MainGame theGame;
8:
9: public void startApp()
10: {
11: myDisplay = Display.getDisplay(this);
12: theGame = new MainGame();
13: myDisplay.setCurrent(theGame);
14: theGame.start();
15: }
16:
17: public void pauseApp()
18: {
19:
20: }
21:
22: public void destroyApp(boolean unconditional)
23: {
24:
25: }
26: }

The MainGame class

1: import java.io.*;
2: import java.util.*;
3: import javax.microedition.lcdui.*;
4: import javax.microedition.lcdui.game.*;
5:
6: public class MainGame extends GameCanvas implements Runnable
7: {
8: // Links to the Images we load
9: private Image tableImage;
10: private Image paddleImage;
11: private Image ballImage;
12: private LayerManager manager;
13: private Sprite tableSprite;
14: private Sprite paddleSprite;
15: private Sprite ballSprite;
16: private Thread gameThread;
17: private boolean isGameRunning;
18:
19: private int paddleX;
20: private int paddleY;
22:
23:
24: public MainGame()
25: {
26: super(true);
27: loadImages();
28: manager = new LayerManager();
29: loadSprites();
30: isGameRunning = true;
31: setInitialPositions();
32: }
33:
34: public void start()
35: {
36: gameThread = new Thread(this);
37: gameThread.run();
38: }
39: public void run()
40: {
41: Graphics g = getGraphics();
42: while(isGameRunning)
43: {
44: checkUserInput();
45: moveObjects();
46: collisionDetection();
47: updateGameScreen(g);
48: flushGraphics();
49: paddleSprite.nextFrame();
50: try
51: {
52: gameThread.sleep(60);
53: }
54: catch(InterruptedException ie)
55: {
56: System.err.println(ie);
57: }
58: }
59: }
60:
61: public void loadImages()
62: {
63: try
64: {
65: //Remember to load the res folder into netbeans
66: tableImage = Image.createImage("/PongTable.png");
67: paddleImage = Image.createImage("/Paddle.png");
68: ballImage = Image.createImage("/PongBall.png");
69: System.out.println("Loaded Images!");
70: }
71: catch(IOException ioex)
72: {
73: System.err.println(ioex+" Error loading images");
74: }
75: }
76:
77: public void loadSprites()
78: {
79: tableSprite = new Sprite(tableImage);
80: paddleSprite = new Sprite(paddleImage, 10, 50);
81: ballSprite = new Sprite(ballImage);
82:
83: manager.append(ballSprite);
84: manager.append(paddleSprite);
85: manager.append(tableSprite);
86: }
87:
88: public void checkUserInput()
89: {
90: int button = getKeyStates();
91: if((button & UP_PRESSED) != 0)
92: {
93: //Check the paddle is not already at the top
94: if(paddleY >0)
95: {
96: paddleY -= 4;
97: }
98: }
99: if((button & DOWN_PRESSED) != 0)
100: {
101: //Check the paddle isn't at the bottom of the screen
102: if(paddleY < tableSprite.getHeight() - paddleSprite.getHeight())
103: {
104: paddleY += 4;
105: }
106: }
107: //Set the new location
108: paddleSprite.setRefPixelPosition(paddleX, paddleY);
109: }
110:
111: public void moveObjects()
112: {
113:
114: }
115:
116: public void collisionDetection()
117: {
118:
119: }
120:
121: public void updateGameScreen(Graphics g)
122: {
123: manager.paint(g, 0, 0);
124: }
125:
126: public void setInitialPositions()
127: {
128: //Remember the size of the sprite and the ref pixel is top left
129: paddleSprite.setRefPixelPosition(paddleSprite.getWidth(), tableSprite.getHeight() / 2 - (paddleSprite.getHeight() / 2));
130: paddleX = paddleSprite.getRefPixelX();
131: paddleY = paddleSprite.getRefPixelY();
132:
133: ballSprite.setRefPixelPosition(tableSprite.getWidth() /2 - (ballSprite.getWidth() / 2), tableSprite.getHeight() / 2 - (ballSprite.getWidth() / 2));
134: ballX = ballSprite.getRefPixelX();
135: ballY = ballSprite.getRefPixelY();
136: }
137: }

Okay, now we are going to move the ball and all the code for that will be written in the “moveObjects” method.
Now let’s think about what we are going to need in order to make the ball bounce around the screen. We are going to want to know what vertical direction it is moving in (either up or down) and the horizontal direction (either left or right). We are also going to need to update the balls position on the screen like we did with the paddle so we need the x and y coordinates of the ball at each frame. We shall start with coding the ball going up and down the screen and we need three variables to hold the information we are going to use. In the variable declarations part, just under the “private int paddleX” and “private int paddleY” we are going to put the following

1: private int paddleY;
2: private int ballX;
3: private int ballY;
4: private boolean isMovingDown;
5:
6: public MainGame()
7: {
8: super(true);
9: isMovingDown = true;
10: ....
11: }

Notice the additions at line 2, 3 and 9. We declare three variables, two of type int and one boolean and we set the boolean to true in our constructor. Now to the moveObjects method. Type in the following then I’ll give an explanation

1: public void moveObjects()
2: {
3: if(isMovingDown)
4: {
5: if(ballY < tableSprite.getHeight() - ballSprite.getHeight())
6: {
7: ballY += 3;
8: }
9: else
10: {
11: isMovingDown = false;
12: }
13: }
14: if(!isMovingDown)
15: {
16: if(ballY < tableSprite.getHeight() && ballY > 0)
17: {
18: ballY -= 3;
19: }
20: else if(ballY <= 0)
21: {
22: isMovingDown = true;
23: }
24: }
25: ballSprite.setRefPixelPosition(ballX, ballY);
26: }

First we say if the ball is moving down (which initially it is as we set the variable to true in the constructor), then we check to see if the Y Coordinate of the ball is not off the table yet. Again, the x, y coordinates for the ball are top left which is why we coded
if(ballY < tableSprite.getHeight() - ballSprite.getHeight())
If both these condition are true, we move the ball down 3.
The else statement means that the ball is at the bottom of the table and now we want the ball to go back up so we set isMovingDown to false.
Next set of if statements. First we ask if the ball is NOT moving down, i.e should it be moving up. Then we say if the Y coordinate of the ball is less than the height of the table AND is not at the top of the screen THEN we move it up 3
The last thing we do is tell the phone where the x and y coordinates of the ballSprite is by calline the “setRefPixelPosition(ballX, ballY)” method.
Now we want to allow the ball to go left and right so lets add a boolean variable called “isMovingRight” and set it to true in the constructor just like this

1: private int ballY;
2: private boolean isMovingDown;
3: private boolean isMovingRight;
4:
5: public MainGame()
6: {
7: super(true);
8: isMovingDown = true;
9: isMovingRight = true;
10: ....
11: }

Note the additions on line 3 and line 9 into your code. Now back to the moveObject() method and add the following code at the very top of the method.

1: if(isMovingRight)
2: {
3: if(ballX < tableSprite.getWidth() - ballSprite.getWidth())
4: {
5: ballX += 3;
6: }
7:
8: if(ballX >= tableSprite.getWidth() - ballSprite.getWidth())
9: {
10: isMovingRight = false;
11: }
12: }
13: else if(!isMovingRight) //If its supposed to move left
14: {
15: if(ballX > 0)
16: {
17: ballX -= 3;
18: }
19:
20: if(ballX <= 0)
21: {
22: isMovingRight = true;
23: }
24: }
25:}

This is very similar to the code for moving up and down so I will not explain it.
The full code listing at this point is
MobilePong MIDlet

1: /*
2: * To change this template, choose Tools | Templates
3: * and open the template in the editor.
4: */
5:
6: import javax.microedition.midlet.*;
7: import javax.microedition.lcdui.*;
8:
9: /**
10: * @author Chris McCready
11: */
12: public class MobilePong extends MIDlet
13: {
14: private Display myDisplay;
15: private MainGame theGame;
16:
17: public void startApp()
18: {
19: myDisplay = Display.getDisplay(this);
20: theGame = new MainGame();
21: myDisplay.setCurrent(theGame);
22: theGame.start();
23: }
24:
25: public void pauseApp()
26: {
27:
28: }
29:
30: public void destroyApp(boolean unconditional)
31: {
32:
33: }
34: }

MainGame class

1: /*
2: * To change this template, choose Tools | Templates
3: * and open the template in the editor.
4: */
5: import java.io.*;
6: import java.util.*;
7: import javax.microedition.lcdui.*;
8: import javax.microedition.lcdui.game.*;
9:
10: public class MainGame extends GameCanvas implements Runnable
11: {
12: // Links to the Images we load
13: private Image tableImage;
14: private Image paddleImage;
15: private Image ballImage;
16: private LayerManager manager;
17: private Sprite tableSprite;
18: private Sprite paddleSprite;
19: private Sprite ballSprite;
20: private Thread gameThread;
21: private boolean isGameRunning;
22:
23: private int paddleX;
24: private int paddleY;
25: private int ballX;
26: private int ballY;
27: private boolean isMovingDown;
28: private boolean isMovingRight;
29:
30: public MainGame()
31: {
32: super(true);
33: isMovingDown = true;
34: isMovingRight = true;
35: loadImages();
36: manager = new LayerManager();
37: loadSprites();
38: isGameRunning = true;
39: setInitialPositions();
40: }
41:
42: public void start()
43: {
44: gameThread = new Thread(this);
45: gameThread.run();
46: }
47: public void run()
48: {
49: Graphics g = getGraphics();
50: while(isGameRunning)
51: {
52: checkUserInput();
53: moveObjects();
54: collisionDetection();
55: updateGameScreen(g);
56: flushGraphics();
57: paddleSprite.nextFrame();
58: try
59: {
60: gameThread.sleep(60);
61: }
62: catch(InterruptedException ie)
63: {
64: System.err.println(ie);
65: }
66: }
67: }
68:
69: public void loadImages()
70: {
71: try
72: {
73: //Remember to load the res folder into netbeans
74: tableImage = Image.createImage("/PongTable.png");
75: paddleImage = Image.createImage("/Paddle.png");
76: ballImage = Image.createImage("/PongBall.png");
77: System.out.println("Loaded Images!");
78: }
79: catch(IOException ioex)
80: {
81: System.err.println(ioex+" Error loading images");
82: }
83: }
84:
85: public void loadSprites()
86: {
87: tableSprite = new Sprite(tableImage);
88: paddleSprite = new Sprite(paddleImage, 10, 50);
89: ballSprite = new Sprite(ballImage);
90:
91: manager.append(ballSprite);
92: manager.append(paddleSprite);
93: manager.append(tableSprite);
94: }
95:
96: public void checkUserInput()
97: {
98: int button = getKeyStates();
99: if((button & UP_PRESSED) != 0)
100: {
101: //Check the paddle is not already at the top
102: if(paddleY >0)
103: {
104: paddleY -= 4;
105: }
106: }
107: if((button & DOWN_PRESSED) != 0)
108: {
109: //Check the paddle isn't at the bottom of the screen
110: if(paddleY < tableSprite.getHeight() - paddleSprite.getHeight())
111: {
112: paddleY += 4;
113: }
114: }
115: //Set the new location
116: paddleSprite.setRefPixelPosition(paddleX, paddleY);
117: }
118:
119: public void moveObjects()
120: {
121: if(isMovingRight)
122: {
123: if(ballX < tableSprite.getWidth() - ballSprite.getWidth())
124: {
125: ballX += 3;
126: }
127:
128: if(ballX >= tableSprite.getWidth() - ballSprite.getWidth())
129: {
130: isMovingRight = false;
131: }
132: }
133: else if(!isMovingRight) //If its supposed to move left
134: {
135: if(ballX > 0)
136: {
137: ballX -= 3;
138: }
139:
140: if(ballX <= 0)
141: {
142: isMovingRight = true;
143: }
144: }
145:
146: if(isMovingDown)
147: {
148: if(ballY < tableSprite.getHeight() - ballSprite.getHeight())
149: {
150: ballY += 3;
151: }
152: else
153: {
154: isMovingDown = false;
155: }
156: }
157: if(!isMovingDown)
158: {
159: if(ballY < tableSprite.getHeight() && ballY > 0)
160: {
161: ballY -= 3;
162: }
163: else
164: {
165:
166: isMovingDown = true;
167: }
168: }
169: ballSprite.setRefPixelPosition(ballX, ballY);
170: }
171:
172: public void collisionDetection()
173: {
174:
175: }
176:
177: public void updateGameScreen(Graphics g)
178: {
179: manager.paint(g, 0, 0);
180: }
181:
182: public void setInitialPositions()
183: {
184: //Remember the size of the sprite and the ref pixel is top left
185: paddleSprite.setRefPixelPosition(paddleSprite.getWidth(), tableSprite.getHeight() / 2 - (paddleSprite.getHeight() / 2));
186: paddleX = paddleSprite.getRefPixelX();
187: paddleY = paddleSprite.getRefPixelY();
188:
189: ballSprite.setRefPixelPosition(tableSprite.getWidth() /2 - (ballSprite.getWidth() / 2), tableSprite.getHeight() / 2 - (ballSprite.getWidth() / 2));
190: ballX = ballSprite.getRefPixelX();
191: ballY = ballSprite.getRefPixelY();
192: }
193: }

Now we just need to do collision detection and you have a fully working (if rather basic) game.
Go to your collisionDetection() method and type in the following


1: public void collisionDetection()
2: {
3: if(ballSprite.collidesWith(paddleSprite, false))
4: {
5: isMovingRight = true;
6: }
7: }

All sprites have a method that can be called named “collidesWith()”. This method take two parameters, the first is what you want to check the collision with. In our case we check if the ball has collided with our paddle. The second parameter is a boolean value and is used if you want pixel perfect collision. We set this to false as pixel perfect collision detection is well outside the scope of this tutorial. All you need to know is that when you set it to false it will put a boundary box around the two objects and check if they are ever in the same x, y location which works fine for our simple game.
If they ever do hit, we simply tell the isMovingRight to move right as if reacting to hitting the paddle.
Run the code and move your paddle to a position that will cause a collision and what the ball bounce off the paddle!
There is only one last thing to do. Since we need to have an objective of the game (this objective being don’t let the ball hit the left hand wall) we need to change the code slightly in the moveObjects() method and add a gameOver method to our midlet.
We add all control methods (such as starting, pausing, unpausing and closing) in the midlet. So add this to the bottom of our MIDlet class.

public void gameOver()
{
destroyApp(true);
notifyDestroyed();
}

Now we need to be able to call this method from the MainGame class so, to accomplish this, we pass a reference to our MIDlet to the MainGame class. Look at this code in your startApp method (still in the MIDlet).

1: public void startApp()
2: {
3: myDisplay = Display.getDisplay(this);
4: theGame = new MainGame(this);
5: myDisplay.setCurrent(theGame);
6: theGame.start();
7: }

The only addition here is to line 4. Now we pass a reference to “this” to the MainGame constructor. Again, “this” is just a fancy way of saying “this class” which in this case is our MIDlet.
All we need to do now is change our MainGame constructor slightly after we have added a variable to link it in our variable declarations

1: private boolean isMovingRight;
2: MobilePong theMidlet;
3:
4: public MainGame(MobilePong m)
5: {
6: super(true);
7: theMidlet = m;
8: isMovingDown = true;
9: ....
10: }

Again, the only changes are on line 2 where we say we want a variable called theMidlet and it will be of type MobilePong (which is the name of your MIDlet).
We also added “MobilePong m” to the parameters on line 4 which will accept the “this” that we pass through in our midlet and on line 7 we simply say that we want our variable “theMidlet” to equal “m”.
One more step and we’re finished. We want to call the gameOver method when the ball hits the left hand wall. We have already coded it to bounce back so move to the moveObjects method and look for this

1: else if(!isMovingRight) //If its supposed to move left
2: {
3: if(ballX > 0)
4: {
5: ballX -= 3;
6: }
7:
8: if(ballX <= 0)
9: {
10: isMovingRight = true;
11: }
12: }

All we need to do is change line 10 to

theMidlet.gameOver();
isGameRunning = false;

Make sure you set the “isGameRunning” variable to false othewise the while loop that controls the game loop will not end.
That’s it! Well done, if you made it this far congratulations. Just to finish off this is how your final code should look.
PongGame MIDlet


1: import javax.microedition.midlet.*;
2: import javax.microedition.lcdui.*;
3:
4: public class MobilePong extends MIDlet
5: {
6: private Display myDisplay;
7: private MainGame theGame;
8:
9: public void startApp()
10: {
11: myDisplay = Display.getDisplay(this);
12: theGame = new MainGame(this);
13: myDisplay.setCurrent(theGame);
14: theGame.start();
15: }
16:
17: public void pauseApp()
18: {
19:
20: }
21:
22: public void destroyApp(boolean unconditional)
23: {
24: System.out.println("In destroyApp");
25: }
26:
27: public void gameOver()
28: {
29: destroyApp(true);
30: notifyDestroyed();
31: }
32: }

MainGame class

1: /*
2: * To change this template, choose Tools | Templates
3: * and open the template in the editor.
4: */
5: import java.io.*;
6: import java.util.*;
7: import javax.microedition.lcdui.*;
8: import javax.microedition.lcdui.game.*;
9:
10: public class MainGame extends GameCanvas implements Runnable
11: {
12: // Links to the Images we load
13: private Image tableImage;
14: private Image paddleImage;
15: private Image ballImage;
16: private LayerManager manager;
17: private Sprite tableSprite;
18: private Sprite paddleSprite;
19: private Sprite ballSprite;
20: private Thread gameThread;
21: private boolean isGameRunning;
22:
23: private int paddleX;
24: private int paddleY;
25: private int ballX;
26: private int ballY;
27: private boolean isMovingDown;
28: private boolean isMovingRight;
29: MobilePong theMidlet;
30:
31: public MainGame(MobilePong m)
32: {
33: super(true);
34: theMidlet = m;
35: isMovingDown = true;
36: isMovingRight = true;
37: loadImages();
38: manager = new LayerManager();
39: loadSprites();
40: isGameRunning = true;
41: setInitialPositions();
42: }
43:
44: public void start()
45: {
46: gameThread = new Thread(this);
47: gameThread.run();
48: }
49: public void run()
50: {
51: Graphics g = getGraphics();
52: while(isGameRunning)
53: {
54: checkUserInput();
55: moveObjects();
56: collisionDetection();
57: updateGameScreen(g);
58: flushGraphics();
59: paddleSprite.nextFrame();
60: try
61: {
62: gameThread.sleep(60);
63: }
64: catch(InterruptedException ie)
65: {
66: System.err.println(ie);
67: }
68: }
69: }
70:
71: public void loadImages()
72: {
73: try
74: {
75: //Remember to load the res folder into netbeans
76: tableImage = Image.createImage("/PongTable.png");
77: paddleImage = Image.createImage("/Paddle.png");
78: ballImage = Image.createImage("/PongBall.png");
79: System.out.println("Loaded Images!");
80: }
81: catch(IOException ioex)
82: {
83: System.err.println(ioex+" Error loading images");
84: }
85: }
86:
87: public void loadSprites()
88: {
89: tableSprite = new Sprite(tableImage);
90: paddleSprite = new Sprite(paddleImage, 10, 50);
91: ballSprite = new Sprite(ballImage);
92:
93: manager.append(ballSprite);
94: manager.append(paddleSprite);
95: manager.append(tableSprite);
96: }
97:
98: public void checkUserInput()
99: {
100: int button = getKeyStates();
101: if((button & UP_PRESSED) != 0)
102: {
103: //Check the paddle is not already at the top
104: if(paddleY >0)
105: {
106: paddleY -= 4;
107: }
108: }
109: if((button & DOWN_PRESSED) != 0)
110: {
111: //Check the paddle isn't at the bottom of the screen
112: if(paddleY < tableSprite.getHeight() - paddleSprite.getHeight())
113: {
114: paddleY += 4;
115: }
116: }
117: //Set the new location
118: paddleSprite.setRefPixelPosition(paddleX, paddleY);
119: }
120:
121: public void moveObjects()
122: {
123: if(isMovingRight)
124: {
125: if(ballX < tableSprite.getWidth() - ballSprite.getWidth())
126: {
127: ballX += 3;
128: }
129:
130: if(ballX >= tableSprite.getWidth() - ballSprite.getWidth())
131: {
132: isMovingRight = false;
133: }
134: }
135: else if(!isMovingRight) //If its supposed to move left
136: {
137: if(ballX > 0)
138: {
139: ballX -= 3;
140: }
141:
142: if(ballX <= 0)
143: {
144: theMidlet.gameOver();
145: isGameRunning = false;
146: }
147: }
148:
149: if(isMovingDown)
150: {
151: if(ballY < tableSprite.getHeight() - ballSprite.getHeight())
152: {
153: ballY += 3;
154: }
155: else
156: {
157: isMovingDown = false;
158: }
159: }
160: if(!isMovingDown)
161: {
162: if(ballY < tableSprite.getHeight() && ballY > 0)
163: {
164: ballY -= 3;
165: }
166: else
167: {
168:
169: isMovingDown = true;
170: }
171: }
172: ballSprite.setRefPixelPosition(ballX, ballY);
173: }
174:
175: public void collisionDetection()
176: {
177: if(ballSprite.collidesWith(paddleSprite, false))
178: {
179: isMovingRight = true;
180: }
181: }
182:
183: public void updateGameScreen(Graphics g)
184: {
185: manager.paint(g, 0, 0);
186: }
187:
188: public void setInitialPositions()
189: {
190: //Remember the size of the sprite and the ref pixel is top left
191: paddleSprite.setRefPixelPosition(paddleSprite.getWidth(), tableSprite.getHeight() / 2 - (paddleSprite.getHeight() / 2));
192: paddleX = paddleSprite.getRefPixelX();
193: paddleY = paddleSprite.getRefPixelY();
194:
195: ballSprite.setRefPixelPosition(tableSprite.getWidth() /2 - (ballSprite.getWidth() / 2), tableSprite.getHeight() / 2 - (ballSprite.getWidth() / 2));
196: ballX = ballSprite.getRefPixelX();
197: ballY = ballSprite.getRefPixelY();
198: }
199: }

So that’s it. It really is that easy.
On a final note, I would appreciate any feedback, comments and criticism. I am always looking for ways to improve both the tutorial and the actual code so if you did read this tutorial, it would be greatly appreciated if you would leave a comment on this blog letting me know how you found it.
If you want to play around some more with this code I have a few suggestions you may want to try on your own to show off your new found understanding.
1) Sprites can be rotated and mirrored using the “setTransform()” method. Look up the javadoc to see how it works but it is really simple. The only thing you have to keep in mind is that it is transformed around it reference pixel (which as you should all know, since I have written it about 100 times, is the top left). You can change the reference pixel to be anywhere so it would be advantageous to look at how transforms work.
2) Create a new class that extends the GameCanvas and create your own image in your favourite drawing package. Use that to display a game over screen rather than just a straight exit.
3) Similar to the above. Create a splash screen that extends the GameCanvas that shows the name of the game, instructions and your name (cause you wrote it, you wanna tell as many people as possible)! Display this first and load the game once you have finished loading all the appropriate classes and methods. Keep in mind that since we have an exceedingly simple game, you may want to put it on a timer as it only take about half a second to set up the constructor on this class!
Happy Coding, I hope to hear your feedback!
Chris

Monday 20 October 2008

J2ME Tutorial

Hey all,

I promised my J2ME class that I would post up a tutorial, I know I said it would be up over the weekend but I have been really busy over the last few days. The actual code I will be using is now complete and I will post the step by step tutorial of it tonight. The goal of the tutorial is to have an understanding of how to load images into your J2ME program, turn them into sprites and use frame sequencing to animate them. There is also multithreading in the game (which is a very poor Pong clone but it does the job) and collision detection, all of these things you will need to use and incorporate into your game (for the game programmers of the class) and plenty can still be used for the networkers if you wish. If you want a sneak look at the source code or even just the running demo, they can be found here.

Check back later tonight for the walkthrough of it, depending on how well this blog allows me to use code blocks I may just post a blog with a link to my staff webpage as the formatting may look odd when posted on this.

Thursday 16 October 2008

Repast and C# (again)!

Well, after my earlier rant I've been busy trying to find a solution to my Repast and C# problem and I think I may have found one.

I (semi)successfully managed to create a very simple Agent Based Model using Eclipse and RepastJ. After I had it running in Eclipse and under Java fine, I used a tool called IKVM. This tool allows the conversion of java class files, libraries and jars into .net executables and dll's. It is scarily easy to use even for a command line tool.

My only concern is that the tool may start throwing me a lot of nasty errors once my "Simple ABM" becomes much more complicated. I also need to convert it to a dll library for importing into my XNA environment as I will need to access the underlying data that the model contains (the tool does have an option to do this, I just haven't tried it yet).

For anyone who is interested, the source code for my (and I use "my" in the loosest possible definition) CarryDrop Agent Based Model can be found here. Also, a zip file with both the runnable jar and the converted .net executable can be found here.

Finally, in order to gain a better insight into ABM programming, I followed a magnificent tutorial written by John Murphy. It was written for Repast 3.1 so is incompatible with the new Repast Simphony but is still a great starting place for anyone wanting to try their hand at ABM programming. His tutorial can be found right here.

Happy Coding ;-)

Chris

Monday 13 October 2008

My first post

Not only is this my first post on my blog, it shall be my first moan!

I've been looking into using Repast for part of my PhD project. Now, usually I would link to it in an attempt to show it some support but I'm so fed up with it I decided against it.

I am using C# and XNA to develop the world in which my simulation will run but need to have something to run the underlying Agent Based Model. Repast has two version, a newer, hard to use version called simphony (yes, the spelling is correct), and Repast 3.1 which allows you to connect any part of the .NET framework to it.

Sadly, after trawling the Internet for hours I discovered that Visual Studio 2008 isn't supported, 30 minutes later I realised that neither is Visual Studio 2005. It seems to only like the old, out-dated and no longer supported version of 2003.

Now this is worse than it should be. There is no real need for me to use a development environment but in order for me to learn the way Repast makes models, I need one of the damn templates which refuse to import into either of the other two.

I have still to decide if I will be using Repast and if I am being honest, the decision isn't really mine to make as it will need to coincide with other research that is already happening at Edinburgh University but I hope that once I get home and fish out a version of Visual Studio.NET 2003 that the actual programming of ABM's in this environment is easier than attempting to find any Repast.NET documentation as it all seems to be Java based tutorials only.

Anyways, rant over.

Chris