Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I have a 2d game where you look down from above and can scroll up, down, left and right using a viewport and a much bigger map.

I have been having trouble drawing a rectangle around the block under the cursor but finally cracked it more through luck than anything else but ended up with this code. Can you help me optimise it and simplify it?

int blockwidth=gridsize-2;

//Draw coloured blocks
for (int x=0;x<sizex;x++){
   int thex=-(int)locationx+(x*gridsize);
        for (int y=0;y<sizey;y++){
        int they=-(int)locationy+(y*gridsize);                
        //if (thex>-blockwidth && thex<800){
            g.setColor(new Color( tiles[x][y][1]));
            g.fillRect(thex,they,blockwidth,blockwidth);   
        //}
    }
 }       

Especially this piece

//Cursor co-ords updated       
cursorx=(int)locationx+(int)GameInput.mousex;
cursorx=(int)cursorx/gridsize;
cursorx=-(int)locationx+(cursorx*gridsize);

//Draw on screen cursor
        g.setColor(Color.yellow);
        g.drawRect(cursorx,cursory,blockwidth,blockwidth);  
share|improve this question
    
"rectangle around the block under the cursor", your question isn't clear at least for me, can you please tell us in more details what were you trying to achieve? –  concept3d Mar 9 '14 at 21:03
    
The second piece of code works bust is very messy, what it does is take the mouse cursor position and places a square yellow rectangle under it. This is aligned with the blocks that make up the background so you can then select one of them. E.g. If there are 80 blocks wide and 40 blocks down that make up the background and each block is 20x20 pixels if the mouse cursor is at 31,21 then block 2,2 would be highlighted with a yellow rectangle around it. What I am asking is can someone suggest ways of tidying up / optimising the code? –  Munkybunky Mar 9 '14 at 22:16

1 Answer 1

up vote 0 down vote accepted

You have three coordinate systems, all using x,y.

  1. The grid/block coordinates. Each block is gridsize X gridsize pixels.
  2. The world coordinates. These are grid coordinates multiplied by gridsize.
  3. The screen coordinates. These are world coordinates minus the camera position (locationx,locationy)

You're asking how to tidy up the code. I think the way to start is to be use a naming convention so that you know for each x,y variable, which of these three coordinates you're using. For example, you have thex = -(int)locationx+(x*gridsize). The x here is in grid coordinates, locationx is the camera position in world coordinates, and thex is in screen coordinates. When you multiply grid coordinates by gridsize, you get world coordinates, so x*gridsize in world coordinates. When you subtract the camera position from world coordinates, you get screen coordinates, so thex is in screen coordinates.

Consider renaming your x, y to grid_x, grid_y and your thex, they to screen_x, screen_y and your locationx, locationy to camera_x, camera_y.

The second piece of code, dealing with cursors, is similarly transforming coordinate systems. The mouse position is in screen coordinates. The first line is finding the world coordinates for the cursor. Since we know that world - camera = screen, it follows from algebra that world = screen + camera. And that's what your code does: it adds the camera (locationx,locationy) to the screen (mouse) to get world coordinates (cursor): cursorx=(int)locationx+(int)GameInput.mousex

The second line there is cursorx=(int)cursorx/gridsize. What does it do? It's taking the world coordinates from the previous line and converting it into grid coordinates. We know that grid coordinates multiplied by gridsize is world coordinates. Therefore world coordinates divided by gridsize produces grid coordinates.

The third line there is cursorx=-(int)locationx+(cursorx*gridsize). You're taking the grid coordinates from the previous line and multiplying by gridsize, so that produces world coordinates. You then subtract the camera location, so that produces screen coordinates.

So my suggestion for those three lines of code is to be clear about which coordinate system it is:

cursorx_world = (int)locationx + (int)GameInput.mousex;
cursorx_grid = (int)cursorx_world / gridsize;
cursorx_screen = -(int)locationx + (cursorx_grid*gridsize);

To make it even clearer, you might consider using a Point class that lets you handle both x and y at once, so that you don't have to duplicate this code. You could write methods such as toWorld and toScreen to make it easier to read this kind of code.

Optimization of this part of the code is unlikely to make any difference. I'd strive for clarity over microoptimizations. (Also, I don't see a way to make those three lines much faster.)

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.