I have Tile
s which represent the tiles in a game's 2-dimensional world. The tiles can have walls on any number of their 4 sides. I have something like this at the moment:
interface Tile {
boolean isWallAtTop();
boolean isWallAtRight();
boolean isWallAtLeft();
boolean isWallAtBottom();
}
Somewhere else I also have 16 images, one for each possible tile wall configuration. Something like this:
static final Image WALLS_ALL_AROUND = ...
static final Image WALL_ON_TOP_AND_RIGHT = ...
/* etc etc all 16 possibilities */
I want to write a
static Image getWallImage(Tile tile)
What I'd like to avoid is the torture of going through the possibilities like
if (tile.isWallTop && tile.isWallRight
&& !tile.isWallBottom && !tile.isWallLeft) {
return WALL_ON_TOP_AND_RIGHT;
}
Does anyone know a cuter way to do this?
The purpose of object oriented programming (OOP) is to produce well designed reusable code. In principle OOP can be done in any language, even assembly. This is because all OO language compilers/assemblers (e.g. C++) ultimately translate the high level constructs of the language into machine language.
C is extraordinarily modern for a 50-year-old programming language. Whether you're writing embedded code, low-level system routines, or high-performance applications, C is up to the challenge. This unique book, based on the latest C standards, exposes a modern perspective of this tried-and-true language.
Nice is a research programming language. It demonstrates how the powerful ML-Sub type system can be used in practice. Nice is an object-oriented language, with parametric, polymorphic types, higher-order functions, and more. It combines the advantages of object-orientation and functional programming.
Go go gadget bitmasks. Use a 4 bit mask for each tile, stating which side has a wall.
A B C D
Bit A indicates a wall on the top, B the right, C the bottom, D the left. Define constants to help you that you can just logically intersect with the mask, i.e.
if (tile.Walls & (WALL_LEFT | WALL_RIGHT))
// Do stuff
For finding the image, this 4 bit mask produces the 16 possibilities. Use it as an index into an images "array", so you can directly find the correct image without any effort.
Do the tile objects have any other properties? If not (or if you can factor out those), you could make the tile objects themselves into an enumeration of 16 constants with a Tile.getImage()
method that returns a fixed image passed to the constructor. This is known as the Flyweight pattern:
class Tile {
public final boolean isWallAtTop;
public final boolean isWallAtRight;
public final boolean isWallAtLeft;
public final boolean isWallAtBottom;
public final Image image;
private Tile(boolean top, boolean right, boolean left,
boolean bottom, Image image)
{
this.isWallAtTop = top;
this.isWallAtRight = right;
this.isWallAtLeft = left;
this.isWallAtBottom = bottom;
this.image = image;
}
public static final Tile WALLS_ALL_AROUND =
new Tile(true, true, true, true, new Image("allWalls.png"))
// more constants here, plus other methods that work with
// only the wall data
}
In Java, you could even implement this as a "real" enum.
For a map that consists of tiles, you could either have a simple 2-dimensional array of Tile references, or if you need other data for individual tiles, have another SpecificTile
class that contains the "other data" and a reference to one of the Tile objects above.
I suggest creating a bit flag enum like the following.
[Flags]
public enum WallLocations
{
None = 0,
Left = 1,
Right = 2,
Top = 4,
Bottom = 8
}
Then you can use a dictionary to map from the wall locations to the images.
Dictionary<WallLocations, Image> map = new Dictionary<WallLocations, Image>();
map.Add(WallLocations.None, image0000);
map.Add(WallLocations.Left, image1000);
map.Add(WallLocations.Right, image0100);
map.Add(WallLocations.Top, image0010);
map.Add(WallLocations.Bottom, image0001);
map.Add(WallLocations.Left | WallLocations.Right, image1100);
// ....
At least in C# you could also extend the enum definition with all 16 cases.
[Flags]
public enum WallLocations
{
None = 0,
Left = 1,
Right = 2,
Top = 4,
Bottom = 8,
LeftAndRight = Left | Right,
LeftAndTop = Left | Top,
LeftAndBottom = Left | Bottom,
RightAndTop = Right | Top,
RightAndBottom = Left | Bottom,
TopAndBottom = Top | Bottom,
AllExceptLeft = Right | Top | Bottom,
AllExceptRight = Left | Top | Bottom,
AllExceptTop = Left | Right | Bottom,
AllExceptBottom = Left | Right | Top,
All = Left | Right | Top | Bottom
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With