Hacking on GraphHopper - a Java road routing engine. Peter has posted 62 posts at DZone. You can read more from them at their website. View Full User Profile

Test-Driven Teaching – User Interface & More Game Features

01.24.2010
| 3888 views |
  • submit to reddit

This post belongs to some previous posts of this tutorial about "test-driven teaching":

0. Overview article

1. Hello World

2. Initial Box Game

3. Object Oriented Programming – Refactoring!

Now will go on with the last two sections.

In Section 4

you can learn a bit how to code with Swing and how to draw lines etc. with the Graphics class. This section can be securely skipped.

It is only necessary for the reader to have fun; not to get lost in Swing development. Get the project under the following URL

https://timefinder.svn.sourceforge.net/svnroot/timefinder/branches/tdteaching/TestDrivenTeaching4/

The handling and painting will be improved a bit in the next section.

In Section 5

you will learn

  • Why and how to use inheritance
  • the keyword this
  • the switch-case construct

Get the project under the following URL

https://timefinder.svn.sourceforge.net/svnroot/timefinder/branches/tdteaching/TestDrivenTeaching5/

Let us examine the project. If you run it you will get a window with several black boxes and two colored one. The red is the enemy and the other could be controlled by the arrow keys (up, down, left, right) … its you. Try to capture the enemy like it is shown below:

Block Game End State

 

There are some new classes and one interface called ‘Item’. Let me first explain the reason why I introduced a new Board class and then why we need this Item interface. Superclasses (and sub-classes) and also interfaces are directly supported in Java with its related keywords extends and interface, although you could write in an object oriented way even without native support of the language (e.g. in C), but this is for another topic…

Board Class

Instead of the borders I am using one object of the class Board where the different items will have its positions (of course there are other solutions to store different items at different positions, try thinking about them; email me if you think that you found one). Within the Board class a 2-dimensional array is used to hold all the objects at different locations. We need to duplicate the information of the position (x,y) within the Man class not only within the Board class, because this way the Board class does not need to know how to paint the different items: it just calls item.paintComponent().

Another change was to remove the move method from the Man class and put it into Board, because moving now does not only mean to change the position, it is necessary to check if the new position is empty etc.

Item Interface

As you can see in the project an interface has actual no function, it only provides a contract of methods (and static fields) which all classes should implement and other classes could rely on. A class can implement several interfaces via the implements keyword.

All objects implementing the interface ‘Item’ (here Man and Block) can be placed on the board.

I introduced the interface to avoid sth. like:

if(item instanceof Block) {
drawTheBlockThisWay((Block) item, g);
} else if(item instanceof Man) {
drawManThatWay((Man) item, g);
}
  

instead the Board class just needs:

item.paintComponent(g) 

And as explained earlier the additional setters/getters for x and y are necessary within the paintComponent of each item: “the man or the block must know its position to draw itself”.

Inheritance

To avoid re-implementing the “x and y”-functionality for every Item-implementation again and again, I chose to write a common super class called ItemImpl which provides this functionality for all Item subclasses. Look into the code to understand that now the variables x and y are available in the Man and Block class although they do not declare them directly. This leads to less duplicated code. This extension mechanism is called inheritance.

Note three things here:

  1. Not always the object oriented way is the golden way, e.g. in this case it leads to more classes and could lead to more problems in other areas (e.g. database schemas).
  2. Testing the class ItemImpl is ok, but not necessary as I think: “Test only what will go wrong or what went wrong”. In this case we only have to getters and setters – all should be fine.
  3. Inheritance should be avoided where composition or sometimes delegating could be used.

This, Switch and More

Some setter-methods use the this keyword. E.g. in the setX method of ItemImpl it is necessary to distinguish between the method parameter x and the local variable this.x. The keyword this means that you want to refer to the current object. You could also refer explicitly to the super class’ methods or variables via the keyword super: ’super.someMethod()’

Now look at the code in the BlockGameSwing class (method Thread.run) there I used the switch-case construct. Instead of several if-then-else statements I prefer using this construct if the type is integer or char. Please look in the class SwitchCaseTest under the test package to get the exact syntax and to directly compare with an if-then-else statement.

Two side-notes:

Future Tasks

The open task will be to decrease the energy if the man is colliding with an enemy.

  1. Introduce the energy variable within the BlockMan class and
  2. Uncomment the line with the energy in the method paintComponent of the BlockGameSwing class
  3. Additionally you should introduce movable blocks to catch the enemy without loosing energy

Other important concepts that are not covered in this tutorial:

In this section you have learned a lot of things. Maybe not as good explained as elsewhere, but with unit testing ;-) And please comment on this post to show where more explaination should be added!

If you like programming ‘the man’ you will love programming a robot. Warning: within the robocode project is very difficult to write unit-tested code. Although there exist other approaches to test a robot, I think the unit-testing would be very important.

From http://karussell.wordpress.com/

Published at DZone with permission of its author, Peter Karussell.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)