2d Level creator Scale problem

Good day all,

   I am beginning to put together an old school, retro-Metroid kind of game, and realized that one of the issues I will run into the future with this kind of games is the creation of large tile-based levels. As much as I enjoy working with the SDK, it would take a lot less time to build a level if I create it in an image editor, like paint, and have jmonkey take each pixel, and use the coordinates of each pixel as a reference to insert spatials (blocks, enemies, power ups, etc....).

Basically, I have a method, which will become an AppState once I get it to work, that takes an image for parameter, and reads each pixel; from there, it takes the RGB values, and based on the RGB values assigns a spatial. For example, if the values of block at location (0,1) are R-255, G-0, B-0, it would draw a red block at position (0,1) and so on.

I created a method that works, as long as my block size is .5f. For a tile based game, I need my blocks to be under .25. So I’ve made adjustments, and got my X coordinate to work. however, the Y coordinate gets screwed each time, regardless of any adjustment I keep getting a gap on the Y axis for my blocks. So I guess my question is, by looking at this snippet, what am I missing to calculate my Y coordinate? I know this is an algorithm specific question, and it is my concern to find a solution to that; but I thought that maybe someone out there has been in similar position. Anyway, enough talk, this is the code to my method:
PS, code is not cleaned, its a quick down and dirty get the job done kind of code…sorry.

public void loadLevel(BufferedImage level){//loads an image for a level
        int w = level1.getWidth();
        int h = level1.getHeight();        
        float offx=0;
        float offy = 0f;
        for(int xx =0; xx<w; xx++){
            for(int yy=0; yy<h; yy++){
                int pixel = level.getRGB(xx, yy);
                int red = (pixel>>16) & 0xff;
                int green = (pixel>>8) & 0xff;
                int blue = (pixel>>0)& 0xff;
                if(red==0 && green ==255 &&  blue ==0){                     
                   levelNode.attachChild(getSpatial("/Textures/RockTop/RockTop.mesh.j3o", new Vector3f(xx-offx, yy, 0)));
                   System.out.println("Green YY "+yy);
                if(red==0 && green ==0 &&  blue ==255){
                    //rootNode.attachChild(myBox("Box", new Vector3f( (xx-offsetX), (yy-offsetY),0), ColorRGBA.Blue));                   
                    levelNode.attachChild(getSpatial("/Textures/RockTop/Rock.mesh.j3o", new Vector3f(xx-offx, yy, 0)));                  
                    System.out.println("Blue YY "+yy);
                if(red==255 && green ==0 &&  blue ==0){
                    //playerNode.setLocalTranslation(new Vector3f(xx-offsetX, yy-offsetY, 0));
                    //playerNode.addControl(new BlockTrackControl(levelNode));     
                } <img src="/uploads/default/original/2X/2/20ddf1fb5cccb06c6f067d6dd439613996235230.png" width="620" height="500"> 
            }//End yy 
            offx+=.5f;//Works with block size of .25 for x values          
        }//End xx
    }//end loadLevel

This is the image used to build levels

This is the result scaled at .25

This is the result for the same image, scaled at .5f and removing the increment offx+=.5f

Your code is munged in some important parts so I can’t really see what’s wrong with the math. It is interesting maybe that you add 0.5 to offx but not to an offy. (shrug)

Thought you might find this article interesting, though:

Edit: note use three back ticks ` for code blocks before and after the block.

I used offY before, but it is accessed in the inner loop, so it applied the increment to each instance of the block, thus throwing everything of. I guess what I really aim to do is, keep the same offy value for one entire column, then add the increment when moving to the next column in the y axis. thanks for the link, checking it out.

I don’t understand : why don’t you use/create a function that convert coord from grid (int, int) to 3D space (Vector3f). Then you will have a unit testable and tunable function.
something like:

Vector3f toLocation(int x, int y, float scale) {
  // + 0.5f, 0.5f, 0.5f because anchor of cube is its center
  return new Vector3f((x + 0.5f) * scale, (y+ 0.5f) * scale, 0.5f * scale);

In your code you mix both referential (image, and space), and you increment your offset at each loop.

Good point, didn’t think about it that way, thanks for the suggestion, I will give it a try.