Open World Map Generation Feedback

Hey guys, first post. I’m developing a game using LibGDX and it is going quite well!
I took Java in college, but my previous game dev experience is with C/C++ (and a library called Allegro).

My game is similar to the star stage of Spore, but it is just a wide open star field. Stars are generated randomly as the player moves into new space using a predictive algorithm so that the same stars are always generated.

The problem I have is with this tremendously ugly piece of code that is central to my game:


    StarMap_block[][] blocks;
    Stage stage;

    public void generateBlocks() {
        short center_x = gameData.player_x;
        short center_y = gameData.player_y;
        short one = (short)(1);
        stage.clear(); // scene2d stage, clear them out and add in the new stars

        blocks = new StarMap_block[][] {
                {
                        new StarMap_block((short)(center_x-one),(short)(center_y+one), stage),
                        new StarMap_block(center_x,(short)(center_y+one), stage),
                        new StarMap_block((short)(center_x+one),(short)(center_y+one), stage)
                },
                {
                        new StarMap_block((short)(center_x-one),center_y, stage),
                        new StarMap_block(center_x,center_y, stage),
                        new StarMap_block((short)(center_x+one),center_y, stage)
                },
                {
                        new StarMap_block((short)(center_x-one),(short)(center_y-one), stage),
                        new StarMap_block((short)(center_x),(short)(center_y-one), stage),
                        new StarMap_block((short)(center_x+one),(short)(center_y-one), stage)
                }
        };


        for(int i = 0; i < 3; i++) {
            for(int j = 0; j < 3; j++) {
                blocks[i][j].adjust(j * 480, i * 480);
            }
        }
    }

The 9 blocks make up a 1440x1440 pixel “active map”. Each StarMap_block contains a node list of stars, which are added to the stage.
This function is called each time the camera moves out of the current active blocks.

What is a better approach to accomplish this? Is this leaking memory? Is this actually not a bad way to do what I need to? Do I honestly need to constantly cast shorts like that in Java?

I’m at a point where I need to add more into this code, but am looking for some feedback before I shoot myself in the foot. :slight_smile:

Thanks for any help.

[edit]
I posted a little demo video if anyone is interested in checking it out:

WLm_PD201Lk

So is your question about Java syntax then?

short one = (short)(1);

No - “short one = 1;” would be fine. Obviously defining a constant like this is a bad idea but I see why you did it. Just don’t.

new StarMap_block((short)(center_x-one),(short)(center_y+one), stage)

Again no. As long as this constructor expects shorts then you don’t need to cast to shorts. If the constructor expected int s or long s or something then Java would automatically convert them to that type. byte s are another matter.

Also for your information “StarMap_block” is not a Java class name convention. In Java we do camel case starting with capital for class names. Letters and numbers only. No underscores. So I would change it to StarMapBlock. Or you can make it a static nested class (define the class inside another class and make it static) in which case it would be referenced as “StarMap.Block” or you can import it and just reference it as “Block.” I know your coming from C and you aren’t used to it but if you are looking for help on a Java forum, it annoys some people when they see stuff like this. Also “embrace the native culture” and stuff.

In the interest of correctness (since we’re there anyway) your resource names are slightly wrong.

In science a superscript number after an element refers to an isotope of that element.

So U232 is Uranium-232, the isotope of Uranium with a relative atomic mass of 232. Likewise with He3. Those are fine.

The problem is that the “2” in H20 and O2 is referring to the molecular formula and so it should be done with subscript. “H2O” and “O2”. Also if you are going to refer to Oxygen as O2 you should probably refer to Hydrogen and Nitrogen as H2 and N2 as they are generally diatomic molecules as well.

Sorry, I don’t like to pick holes but if I don’t, someone else will.

[quote]No - “short one = 1;” would be fine.
[/quote]
When I do that it errors out and says it cannot convert from integer to short. I did some googling, and it seemed that java programmers had just “accepted” that.

Likewise with “center_x-one” (or center_x-1). Because the - operator only works with integers, the result of a short - short is an integer for some reason, which it could not convert back to a short. I was yelling at my compiler (IntelliJ IDEA) for a while trying to figure out why I needed those casts. Eventually I just gave up and put them in.

[quote]you can make it a static nested class (define the class inside another class and make it static) in which case it would be referenced as “StarMap.Block”
[/quote]
That actually sounds interesting, I didn’t know one could do that :smiley:

My primary concern with this code was with re-allocating the blocks continually into the same variable. Is that OK in Java?
ie.
StarMapBlock block = new StarMapBlock();
block = new StarMapBlock();
block = new StarMapBlock();
block = new StarMapBlock();

The old ones get cleaned up ok?

[quote]The problem is that the “2” in H20 and O2 is referring to the molecular formula and so it should be done with subscript. “H2O” and “O2”. Also if you are going to refer to Oxygen as O2 you should probably refer to Hydrogen and Nitrogen as H2 and N2 as they are generally diatomic molecules as well.
[/quote]
Haha, that’s good! Thanks :smiley:

Yeah there’s no suffix for short literals…you gotta cast.

The GC takes care of the old versions (at some undefined point in the future)…that’s the short version.


short one = 1;

should compile. It does for me.

You were sort of right though with the method calling. In my defense I avoid using shorts and bytes because of this very problem. You should however be able to do:


new StarMap_block( (short) (center_x - 1), (short) (center_y + 1), stage)

The one thing I got right was not using “one” as a defined constant.

And as @Roquen says, it is actually quite hard to cause a memory leak in Java without using native code.

And http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html there you go. Can be extremely useful stuff. Also I don’t mean to patronize but in case you don’t know about it, read about anonymous classes (there’s a C thing called something like that - I can’t remember exactly what - but don’t be fooled, they are not the same thing) because when I learnt Java that wasn’t even on the tutorial and I didn’t know about them for several weeks. It made understanding other peoples code so much harder.

I just tried the short one = 1 code and it worked fine. I was trying all sorts of things and must have just left that in. Might as well get rid of it.

I do remember learning about anonymous classes, but will need to look them up for a refresher. Been awhile since “Introduction to Java” :wink:

Thanks guys, this forum seems pretty great so far :smiley:

Just wanted to hop into here and talk about things that you might think are interesting:

What java does is implicit conversion it converts the types of numbers implicitly.
The opposite of that would be explicit type conversion, which is needed in strongly typed languages, for example haskell:


// Java code:
int something = 0;
float ohItsAFloatNow = something;

// haskell:
something :: Int
something = 0

ohItsAFloatNow :: Float
ohItsAFloatNow = fromIntegral something 

Here, [icode]fromIntegral[/icode] is something like the cast icode[/icode] in java (except it works for every number type that an ‘Int’ can be converted to).

So, in haskell there are no implicit conversion. But implicit conversion is by no means a bad thing. For example in the programming language scala implicit conversions play a big role and are a big part of the language.

You can do something like this in scala:


class PrintingString(str: String) {
	def printThreeTimes = {
		println(str)
		println(str)
		println(str)
	}
}

implicit def string2PrintingString(str2Convert: String) = 
	new PrintingString(str2Convert)

"print me!".printThreeTimes

Output:

In this example, the scala compiler sees [icode].printThreeTimes[/icode] as a method invocation on [icode]class String[/icode], but String doesn’t actually have a method [icode]printThreeTimes[/icode], therefore it searches for a class that does have such a method and can be implicitly created using a String object. Searching for a solution it finds [icode]string2PrintingString[/icode] as a method for implicit conversion and [icode]class PrintingString[/icode] as a class that has a method [icode]printThreeTimes[/icode]. So the code that is ‘generated’ might look like this:


// ' "print me!".printThreeTimes' becomes:
string2PrintingString("print me!").printThreeTimes

But implicit conversion can be done in a bad way, too.
Say, for example, we want to pre-concatenate the number ‘5’ in front of the string “37” in javascript. We might have some code like this:


var myNumber = 5;
var myString = "37";
var myResult = myNumber + myString;

[s]In this case, [icode]myResult == 42[/icode], did you get why?

Since “+” was used together with a number (5 from ‘myNumber’), the string ‘myString’ was implicitly converted to a number.[/s]

Hope this was at least a little interesting and for you people reading this topic and maybe inspired you into learning a couple of new languages, there are so many out there and programming languages is quite an interesting topic! :slight_smile:

Wouldn’t the javascript one result in “537”?

I’m confused. It does, you’re right :slight_smile:

let’s change the example:


var myNumber = 5;
var myString = "37";
var myResult = myNumber * myString;

Though, it wouldn’t be a bad thing now anymore, yeah ::slight_smile: