Isometric Tiling and General Object Oriented Woes

Hey guys, recently I have been getting into a lot of Java game development after a semester course on Java at university. I’m doing everything in my own spare time and sometimes it’s hard to wrap my head around the more technical aspects of the language.

I have been experimenting with the Slick2D library and have been having a lot of fun making small games based off this Entity Engine Tutorial --> http://slick.cokeandcode.com/wiki/doku.php?id=entity_tutorial

Now the problem I have at the moment is creating a isometric “board” built by separate diamonds. What would be the best way for me to do this? Rather, what would be the most efficient way to do this?

I know how I can store the tiles in a 2 dimensional array based on this --> http://www.java-gaming.org/topics/drawing-isometric-tiles-inside-a-screen/24922/view.html

However what I don’t understand is how I should go about implementing this code.

Should I create a new TileMap class that builds the map in another class?

If so how do I go about re-using the one image over and over without creating a new entity every time?

I think I’ve hit a bit of a wall, and am getting confused with the complexity of some object oriented aspects of coding in general, I am very new!

Any help would be very appreciated! ( Sorry if I’m rambling, I REALLY want to get this stuff!!! :frowning: )

I’m in a similar boat for learning to program but I hope I can give you a few tips.

As far as creating a separate class, I would definitely recommend it. Usually the answer for me is yes anytime I ask myself if I should create another class. It is good OOP and helps a ton with keeping things organized. The fewer classes I have, the harder I find it to remember what each one does haha. When you separate them logically, it’s easy to remember each class’s function and to remember what you plan with each part.

Also, if you want to get a good idea of how to organize your game, I HIGHLY recommend looking at other game developers’ source. I’ve got a couple projects set up in my Eclipse that Notch wrote for Ludum Dare. They might not be a perfect example because they were done in 48 hours, but they still help guide me through the process.

Best of luck man, good to see someone doing the same thing as me. MORE GAMES!!!

There’s a link to the source of that thing beside the applet ( http://jonjavaweb.orgfree.com/IsoWorldSource.zip ).

Iirc it just stores the objects/blocks in a big 2d array of ArrayLists. The database of how to handle the objects is really nothing special, it’s just that the view is “warped” to look isometric when the game is drawn.

I’m glad someone else is feeling the same way as I am! :slight_smile: I am the point now where I understand simple OOP structure, but when it starts to get larger and more complex I’m totally lost.

We can do it! :slight_smile:

Thank you so much for the source code, so awesome! I may or may not have a few questions for you in the future if you’d be willing to help me out :slight_smile:

Hey, I’d love to hear your input on the stuff I’ve put on my blog. It’ll be good to hear from someone around my skill level. If you get a chance check it out. Link is in the signature. I’m actually working on tile maps for my game right now. We can probably learn some stuff from each other.

Also, if you have any requests for helpful tips or tutorials let me know. Thanks!

I know there are a lot of people around here who roar about it, but there’s something in me that can’t stand the idea of using ArrayList (Or any other sort of List structure/class) for this sort of thing. I’ve even been working on my own little library for dealing with them. Mainly, it’s for storing a map of a known, probably static size (Google Drive Version & Dropbox Version). I need to work on documenting it a bit better, but if you want to look at the code, you can probably get an understanding of most everything through it. The important classes in there for isometric will probably be ‘TwoDimensionalMap’ which includes a ‘Dense’ version which is written using an Array of Arrays and a ‘Sparse’ version which uses a HashMap (Perhaps not the best method). The former is meant for a map that probably 75% < full of objects, the latter is more for 25% >. I know that leaves the middle 50% open, but I just haven’t messed around to test it enough.

However, from what I’ve read so far you’re confusing the issue slightly. What jdgamedev said is correct: You should be attempting to separate your objects/classes into logical components that do their job and only their job. But, take this one step further, you need separate your concepts between “Logic/Backend” and “Graphics/Frontend”. The class that you’re using to store the data about the tiles should probably not know anything about how it’s going to be drawn. It shouldn’t even know that it is going to be drawn. Instead, it should probably know enough information that you could write several different renders (ASCII, sprite-based isometric, sprite-based isometric 30-degree, 3d, etc.) to draw it.

As for writing a regular 2D sprite-based one? Really, you have the Renderer which will have access to your map, it will iterate through your map in some form (Several different ways to do this based on how you’re going to set up your system) and then get the texture/image somewhere to draw it to the screen. Depending on how complex you want to go, you can just have your rendered hold the images internally, or fetched some how. I don’t have one written that uses Slick, but I do have a few that make use of LibGDX (They’re technically Hex-Isometric) that I can post if you’d like to see a specific instance.

On a side note, you should probably figure out how you’d draw it as a regular Sprite-based isometric (Meaning squares instead of diamonds), first. This will make sure you know how to draw stuff to the screen before you try to figure out the way you’d actually map it to a 30-degree isometric (Diamonds).

I use lists/collections over Arrays every time single time I can. Unless there’s a specific reason, I don’t see why anyone would bother with simple Arrays over Lists?

[quote=“Eyesackery,post:4,topic:39293”]
Of course.

I have never or rarely done that.
I would just have different methods, if different kinds of rendering were interesting - which I have never had the case… maybe debug render and normal render. But again its just 2 methods…
I like OOP but I dont like having 300 classes. I think game programming should be really pragmatic - cases that will never ever happen, dont really have to be coded. It depends of course.

Arrays have a set size. If you’ve got a structure (A game map) that will very rarely change sizes and that you don’t want to be able to change sizes accidentally then you set up an array for it. I mean, yes, you can use a List and always ensure that you prepopulate it objects to hold your tile data and ensure that when you remove something you’re actually switching it with null to ensure that your ArrayList remains square, but that really feels as though you’re using an Object list (Which is backed by an Array) to create the behavior of a regular array.

Don’t dis the idea of multiple renderers! Especially not when you’re trying to work on the logic of the game and don’t need to get bogged down with the graphical candy (Top-down square isometric is much easier to visualize path-finding on for most people, unless you’re implementing certain types of height-maps-- multiple tiles can occupy the same XZ but have a different Y). Either way, it’s considered a better practice (Correct me if this is incorrect!) not to tie your game logic to your renderer/GUI so that if you have to make a change to your GUI/Renderer you don’t have to go back and tear out all of the GUI/Renderer code that had leaked into your logic.

Nice to see some healthy discussion happening on this thread! :slight_smile: Thanks for all your helpful and knowledgeable advice!

I think I’m at the stage in my programming where I can understand how object oriented programming works, but am confused with when I should use it.

However, what UprightPath said really hit home to me and helped me to understand the logical aspects of a object oriented structure. (Thank you!)

The more I study source code, the more it is making sense to me also.

Nice blog jdgamedev, very cool idea! It’s inspiring to see someone just as enthusiastic as I am to get into game development! I will be sure to follow your blog! :slight_smile:

Well, they behave differently. If I know I’m at all times going to have 2K of an item I won’t use an ArrayList. The functionality the ArrayList provides is useless in my specific example. Also, I can change my array while I iterate it.

You can change your ArrayList while you iterate through it (Technically!) by using the Iterator’s methods rather than the List’s. Well, you can remove values, and if you need to add things at the end, then add them at the end of the iteration.

Lists are more for dynamic sets of elements. They’re suited to adding/removing/iterating type operations and obscure the actual code behind having to do that (ArrayLists shift elements on a mid-list remove, they grow the array backing it when you add enough elements, etc. and LinkedList obscures the creation of the List nodes).

Thing is, I never know before hand if I’m going to have exactly 2k of an item or what not. ArrayLists have it all with no additional costs. Unless there’s something peculiarly specific or something trivial, there’s no benefits of using the basic array over ArrayList.

The matter between Arrays and ArrayLists (Or Lists in general) is like comparing shears and scissors (They look alike, are used mostly in the same way, and in some ways you can say that one is just another form of the other). Yes, they’re alike to a point, however they’re tools made to do specific tasks. An ArrayList is, at its heart, a List. An Array is an array. While an ArrayList uses an array inside of it, they’re meant to perform different tasks. With an ArrayList there is a lot of internal code that is an additional costs over a regular array. There’s the code that shifts the elements in the backing array when you do a ‘remove’ or when you do an ‘addAt’, there’s extra fluff in the form of keeping track of updates/additions to make sure that an Iterator created for use with the ArrayList doesn’t break due to post-Iterator instantiation changes, and other such fun.

If you’re using an ArrayList as a List (Meaning an unbounded collection of ordered elements which are likely to change order) then all of that other code is good. If you’re using an ArrayList as an array (Meaning a size-bounded, index-accessed, ordered set of elements) then you’re probably going to spend more time fighting with the API to ensure that it meets the other constraints.

What do you mean by “additional costs”? If you mean it’s slower because of it then you’re wrong unless you’re nitpicking. However, in peculiar situations and trivial tasks the array could be easier to use but you’re certainly not gaining performance.

If in doubt, use an ArrayList. You really shouldn’t reach for raw arrays unless you need to save storage with primitives … and even then you should probably use something like Trove collections instead.

I disagree – most of the time you should be using ArrayLists – arrays tend to be for “special cases” (e.g. fixed size pixel data, performance critical areas, modifying buffers, etc).

In the vast majority of situations, the performance/memory difference between ArrayLists and arrays is extremely negligible and should not affect your decision to use one over the other. Instead, you should choose whichever leads to better ease of use and readability for your particular situation.

Using an ArrayList as if it were an array is often a good idea – it enables you to use generics with more freedom, allows you to use Collections API methods like sort(), etc – and I can’t imagine any reasons why it would lead to “fighting with the API”.

I have changed my mind about ArrayLists too. I use them much more often now. But I totally disagree using something like this:


ArrayList<Integer> list [...]

because the memory footprint of Integer is so heavy, so this is totally not a good Idea.

I was nitpicking there. I’ll admit it. When it comes to the amount of performance/memory difference between ArrayLists and arrays, there is very little. I just took issue with him saying “At no additional cost” earlier on. There is an additional cost, it’s just really really small.

Well, I am honestly talking about the special case that this topic is about: Isometric Maps. Which tend to be a specialized type of grid indexed collection. You wouldn’t be using many of the Collection API methods on it, like… Sort. How/why would you want to sort a map? I mean yes I can think of a few reasons why you would (Find the positions with the least number of X or something), but on the whole many of those operations do not have a logical application when thinking about what’s basically supposed to be the physical representation of a world. And even if you did want to do a sort on them, you probably wouldn’t want the map’s ordering to change.

As for the fighting with the API comment?

  1. When you instantiate an array each index is automatically given a default value. This means that as soon as you instantiate your array, the operation array[index] will return a value (It might be null, or 0, or something) but it won’t throw out an IndexOutOfBoundsException, which rather is nice when you’re dealing with a sparse map (Which is to say that you can do array[index] = thisElement without worrying that you didn’t fill in the ArrayList with the correct number of null values to ensure that it’s square).
  2. With the List API you can accidentally cause your data to shift by using an operation (list.addAt or list.remove), you can’t do that with an array.

Yes, both of those issues are easily taken care of. One by ensuring that when you generate your ArrayList<ArrayList> that you fill in everything correctly to make it square and the other by ensuring that you don’t use the addAt or remove functionality. But at that point, you’re really just using the ArrayList like you would a regular array, so… Why use the ArrayList?

I’ll admit that when I’m doing a map I don’t tend to directly access an array any more, but that’s because I took the time to define a data-structure just for dealing wit grid-based maps (Which is based off of the ArrayList’s method of dealing with a ‘Generic’ Array).

Edit: Really, I’m just trying to point out that the ArrayList VS Array thing is sort of a “When all you have is a hammer” mentality. Actually deciding what the best tool for the given situation is is better than automatically saying “This is better because it’s an Object” or something like that.

I don’t see anything wrong with it. I don’t see any particularly good uses for it either. But certainly nothing based on performance.

Premature optimization is much worse :frowning: