Java-Gaming.org Hi !
 Featured games (91) games approved by the League of Dukes Games in Showcase (757) Games in Android Showcase (229) games submitted by our members Games in WIP (844) games currently in development
 News: Read the Java Gaming Resources, or peek at the official Java tutorials
 Home Help Search Login Register
Pages: [1]
 ignore  |  Print
 [SOLVED]I sometric game get what tiles to draw to the screen  (Read 5491 times) 0 Members and 1 Guest are viewing this topic.
hapsburgabsinth

Junior Devvie

 « Posted 2014-10-29 08:38:47 »

I just finish drawing a 2d cartesian tile array to an isometric screen.

I now wonder how to get what tiles to draw. As my code is now it draw the tiles within the screen, but it takes the cartesian coordinates, and not the isometric tiles within the screen.

My code for selcting what tiles to draw follows here:

 1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28 public void isometricRender(int xScroll, int yScroll, Screen screen) {      screen.setOffsets(xScroll, yScroll);      int x0 = xScroll / Tile.WIDTH;      int x1 = (xScroll + screen.getWidth() + Tile.WIDTH) / Tile.WIDTH - 1;      int y0 = yScroll / Tile.HEIGHT;      int y1 = (yScroll + screen.getHeight() + Tile.WIDTH) / Tile.WIDTH + 1;      for (int y = y0; y < y1; y++) {         for (int x = x0; x < x1; x++) {            getTile(x, y).isometricRender(x, y, screen);         }      }      for (int i = 0; i < _entities.size(); i++) {         _entities.get(i).isometricRender(screen);      }      for (int i = 0; i < _players.size(); i++) {         // _players.get(i).isometricRender(screen);      }      for (int i = 0; i < _projectiles.size(); i++) {         _projectiles.get(i).isometricRender(screen);      }      for (int i = 0; i < _particles.size(); i++) {         _particles.get(i).isometricRender(screen);      }   }

I need help to set the offsets so that it draws the tiles within the screen.

The game looks like this:

Really appriciate you help
moogie

JGO Ninja

Medals: 16
Projects: 6
Exp: 10 years

Java games rock!

 « Reply #1 - Posted 2014-10-29 11:59:52 »

This is the stripped down version of my isometric rendering code I have used for a java4k entry that is on the back burner:

 1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37 private static final int VIEW_PORT_HEIGHT = 20; // in cartesian map scale   private static final int TILE_SIZE_DIV_2 = 16; // in pixels. half of the tile size   private static final int MAP_SIZE_MINUS_ONE = 99; // maximum size of the map to be rendered minus one. assuming square map.    private static final int VIEW_PORT_WIDTH = 30; // in cartesian map scale   {      float scrollYScreenUnit=0; // should be updated when scrolling the view port. the unit is in cartesian map scale. i.e. 1 unit = 1 tile        float scrollXScreenUnit=0; // should be updated when scrolling the view port. the unit is in cartesian map scale.             int alternateScanline = (int) ((scrollYScreenUnit%1) * 2); // determine whether to start on an "alternative" line. i.e. offset x by half the tile width      int scrollMapX = (int) ((scrollYScreenUnit+0.5F)+0.5F*(scrollXScreenUnit)); // determine the cartesian co ordinate of the top left corner of the current view.      int scrollMapY = (int) ((scrollYScreenUnit+0.5F)-0.5F*(scrollXScreenUnit)); // determine the cartesian co ordinate of the top left corner of the current view.      // iterate over the view port      for (int vy = -1; vy < VIEW_PORT_HEIGHT*2; vy++)      {         alternateScanline=(++alternateScanline)%2;         int xGame=scrollMapX;  // cartesian co-ordniate of current tile to be rendered         int yGame=scrollMapY;  // cartesian co-ordniate of current tile to be rendered         for (int vx = -2; vx < VIEW_PORT_WIDTH ; vx += 2)         {            int x = (int) ((xGame-yGame-scrollXScreenUnit-1.0F)*TILE_SIZE_DIV_2); // convert to isometric X            int y = (int) ((0.5F*(xGame+yGame)-scrollYScreenUnit-0.25F)*TILE_SIZE_DIV_2); // convert to isometric Y                        // is the tile visible            if (xGame > 0 && yGame > 0 && xGame < MAP_SIZE_MINUS_ONE && yGame < MAP_SIZE_MINUS_ONE)            {               g.drawImage(images[map[xGame][yGame]], x, y, null); // get the tile from the map at the cartesian co-ordniate and render at isometric coordinates.             }               xGame++;            yGame--;         }         scrollMapY+=alternateScanline; // update the statring point of the next line of tiles based on whether it is an alternative line         scrollMapX+=1-alternateScanline; // or not. if it is then the line is shifted out of phase by half.      }   }

it may or may not help you as it is not the nicest code around. however it does work (well at least for me ) as proven by the following screen capture:

Java4k RIP 2014
hapsburgabsinth

Junior Devvie

 « Reply #2 - Posted 2014-10-31 07:28:02 »

Quote
 1  2  3  4 private static final int VIEW_PORT_HEIGHT = 20; // in cartesian map scale   private static final int TILE_SIZE_DIV_2 = 16; // in pixels. half of the tile size   private static final int MAP_SIZE_MINUS_ONE = 99; // maximum size of the map to be rendered minus one. assuming square map.    private static final int VIEW_PORT_WIDTH = 30; // in cartesian map scale

VIEW_PORT_HEIGHT is that the total height of Tiles? And is it the isometric-tiles height?
MAP_SIZE_MINUS_ONE is that the number of tiles to be rendered?
And the same for VIEW_PORT_WIDTH

Quote
 1  2 float scrollYScreenUnit=0; // should be updated when scrolling the view port. the unit is in cartesian map scale. i.e. 1 unit = 1 tile        float scrollXScreenUnit=0; // should be updated when scrolling the view port. the unit is in cartesian map scale.

Are these 2 variables for the Screen top-left corner?
 Games published by our own members! Check 'em out!
moogie

JGO Ninja

Medals: 16
Projects: 6
Exp: 10 years

Java games rock!

 « Reply #3 - Posted 2014-10-31 09:59:57 »

VIEW_PORT_HEIGHT is the "size" of the screen as a multiples of tile height. Similarly with VIEW_PORT_WIDTH is multiples of tile width. Note that my code assumes that the width and heigh of the tiles are the same, however the actual opaque pixels comprising the tile occur from 0.25 to 0.75 of the height of the tile:

MAP_SIZE_MINUS_ONE  is just the size of the map array minus one... i.e. int[][] map = new int[100][100] would mean MAP_SIZE_MINUS_ONE is 99

scrollYScreenUnit - yes i believe it is the top left corner... but that can come later... leave as 0 for now.

Java4k RIP 2014
hapsburgabsinth

Junior Devvie

 « Reply #4 - Posted 2014-10-31 21:03:43 »

Quote
 1  2  3 int alternateScanline = (int) ((scrollYScreenUnit%1) * 2); // determine whether to start on an "alternative" line. i.e. offset x by half the tile width      int scrollMapX = (int) ((scrollYScreenUnit+0.5F)+0.5F*(scrollXScreenUnit)); // determine the cartesian co ordinate of the top left corner of the current view.      int scrollMapY = (int) ((scrollYScreenUnit+0.5F)-0.5F*(scrollXScreenUnit)); // determine the cartesian co ordinate of the top left corner of the current view.

alternateScanline <- this is for figuring out if its an odd line right?

scrollMapX and scrollMapY <- these are the coordinates of the top left corner tile in the cartesian map?

Thank you for the help, I really appriciate it
hapsburgabsinth

Junior Devvie

 « Reply #5 - Posted 2014-10-31 21:40:42 »

I've implemented you solution into my game, but now it doesn't render any Tiles on the screen. Maybe some offSet isn't right? The player is rendered in the middle of the screen, but the screen doesn't follow the player, when the player moves, also the movement isn't right...

Quote
 1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36 public void isometricRender(int xScroll, int yScroll, Screen screen) {      screen.setOffsets(xScroll, yScroll);      int VIEW_PORT_HEIGHT = 5; // in cartesian map scale      int VIEW_PORT_WIDTH = 5; // in cartesian map scale      float scrollYScreenUnit = 0;       float scrollXScreenUnit = 0;       int alternateScanline = (int) ((scrollYScreenUnit % 1) * 2);      int scrollMapX = (int) ((scrollYScreenUnit + 0.5F) + 0.5F * (scrollXScreenUnit));      int scrollMapY = (int) ((scrollYScreenUnit + 0.5F) - 0.5F * (scrollXScreenUnit));      for (int y = -1; y < VIEW_PORT_HEIGHT * 2; y++) {         alternateScanline = (++alternateScanline) % 2;         int xGame = scrollMapX;         int yGame = scrollMapY;         for (int x = -2; x < VIEW_PORT_WIDTH; x++) {            int isoX = (int) ((xGame - yGame - scrollXScreenUnit - 1.0F)                  * Tile.WIDTH / 2);            int isoY = (int) ((0.5F * (xGame + yGame) - scrollYScreenUnit - 0.25F)                  * Tile.HEIGHT / 2);            if (xGame > 0 && yGame > 0 && xGame < _width - 1                  && yGame < _height - 1) {               getTile(x, y).render(isoX, isoY, screen);            }            xGame++;            yGame--;         }         scrollMapY += alternateScanline;         scrollMapX += 1 - alternateScanline;      }   //Code for render other objects...}
moogie

JGO Ninja

Medals: 16
Projects: 6
Exp: 10 years

Java games rock!

 « Reply #6 - Posted 2014-10-31 22:03:44 »

Well, it does not scroll due to the fact that scrollYScreenUnit is not being updated. What unit is the yScroll in? if it is in pixels then:
 1  2 scrollYScreenUnit = ((float) yScroll) / Tile.HEIGHT*2;scrollXScreenUnit = ((float) xScroll) / Tile.WIDTH;

I am not sure what effect the call to screen.setOffsets(xScroll, yScroll) has...

I am suspicious of what getTile(x, y).render(isoX, isoY, screen); does... it should be simply drawing the tile at the isoX, isoY cooridnates. These are in screen co-ordinate space... meaning that 0,0 will be the top left corner of the screen.

Java4k RIP 2014
hapsburgabsinth

Junior Devvie

 « Reply #7 - Posted 2014-11-01 05:32:55 »

Quote
I am not sure what effect the call to screen.setOffsets(xScroll, yScroll) has...
xScroll and yScroll is the top-left corner of the cartesian map, with the player centered.

Quote
I am suspicious of what getTile(x, y).render(isoX, isoY, screen)
This method gets the Tile at x,y (cartesian) in the map array, and on that Tile it calls the renderTile method on screen, which draws it to the screen in isometric coordinates.
moogie

JGO Ninja

Medals: 16
Projects: 6
Exp: 10 years

Java games rock!

 « Reply #8 - Posted 2014-11-01 09:15:51 »

Quote
I am not sure what effect the call to screen.setOffsets(xScroll, yScroll) has...
xScroll and yScroll is the top-left corner of the cartesian map, with the player centered.

Quote
I am suspicious of what getTile(x, y).render(isoX, isoY, screen)
This method gets the Tile at x,y (cartesian) in the map array, and on that Tile it calls the renderTile method on screen, which draws it to the screen in isometric coordinates.

sure, but how do the two methods interact.... i.e. does calling setOfffsets mean that the later render call has these offsets applied to isoX and isoY? if so then you are doubly taking scrolling into account. The isoX and isoY values already have scrolling taken into account and should be used directly when rendering.

Java4k RIP 2014
hapsburgabsinth

Junior Devvie

 « Reply #9 - Posted 2014-11-01 10:26:58 »

Quote
sure, but how do the two methods interact.... i.e. does calling setOfffsets mean that the later render call has these offsets applied to isoX and isoY? if so then you are doubly taking scrolling into account. The isoX and isoY values already have scrolling taken into account and should be used directly when rendering.

Levels isometricRender method:
 1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60  61  62  63  64  65  66  67  68  69 public void isometricRender(int xScroll, int yScroll, Screen screen) {      screen.setOffsets(xScroll, yScroll);      int VIEW_PORT_HEIGHT = 5; // in cartesian map scale      // minus one. assuming square map.      int VIEW_PORT_WIDTH = 5; // in cartesian map scale      float scrollYScreenUnit = 0; // should be updated when scrolling the      // view port. the unit is in cartesian      // map scale. i.e. 1 unit = 1 tile      float scrollXScreenUnit = 0; // should be updated when scrolling the      // view port. the unit is in cartesian      // map scale.      // determine whether to start on an "alternative" line. i.e. offset x by      // half the tile width      int alternateScanline = (int) ((scrollYScreenUnit % 1) * 2);      // determine the cartesian co ordinate of the top left corner of the      // current view.      int scrollMapX = (int) ((scrollYScreenUnit + 0.5F) + 0.5F * (scrollXScreenUnit));      // determine the cartesian co ordinate of the top left corner of the      // current view.      int scrollMapY = (int) ((scrollYScreenUnit + 0.5F) - 0.5F * (scrollXScreenUnit));      for (int y = -1; y < VIEW_PORT_HEIGHT * 2; y++) {         alternateScanline = (++alternateScanline) % 2;         // cartesian co-ordniate of current tile to be rendered         int xGame = scrollMapX;         // cartesian co-ordniate of current tile to be rendered         int yGame = scrollMapY;         for (int x = -2; x < VIEW_PORT_WIDTH; x++) {            // convert to isometric X            int isoX = (int) ((xGame - yGame - scrollXScreenUnit - 1.0F)                  * Tile.WIDTH / 2);            // convert to isometric Y            int isoY = (int) ((0.5F * (xGame + yGame) - scrollYScreenUnit - 0.25F)                  * Tile.HEIGHT / 2);            if (xGame > 0 && yGame > 0 && xGame < _width - 1                  && yGame < _height - 1) {               getTile(x, y).render(isoX, isoY, screen);            }            xGame++;            yGame--;         }         // update the statring point of the next line of tiles based on         // whether it is an alternative line         scrollMapY += alternateScanline;         // or not. if it is then the line is shifted out of phase by half.         scrollMapX += 1 - alternateScanline;      }      for (int i = 0; i < _entities.size(); i++) {         _entities.get(i).isometricRender(screen);      }      for (int i = 0; i < _players.size(); i++) {         // _players.get(i).isometricRender(screen);      }      for (int i = 0; i < _projectiles.size(); i++) {         _projectiles.get(i).isometricRender(screen);      }      for (int i = 0; i < _particles.size(); i++) {         _particles.get(i).isometricRender(screen);      }   }

Render method in Tile:
 1  2  3 public void render(int x, int y, Screen screen) {      screen.renderTile(x * WIDTH, y * HEIGHT, this);   }

Screens renderTile method:
 1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24 public void renderTile(int xp, int yp, Tile tile) {      xp -= _xOffset;      yp -= _yOffset;      int color;      for (int y = 0; y < tile.getSprite().getHeight(); y++) {         int ya = y + yp;         for (int x = 0; x < tile.getSprite().getWidth(); x++) {            int xa = x + xp;            if (xa < -tile.getSprite().getWidth() || xa >= _width || ya < 0                  || ya >= _height) {               break;            }            if (xa < 0) {               xa = 0;            }            color = tile.getSprite().getPixels()[x + y                  * tile.getSprite().getWidth()];            if (color != 0xffff00ff) {               _pixels[xa + ya * _width] = color;            }         }      }   }

The render method for player:
 1  2  3  4  5 public void isometricRender(Screen screen) {      int isoX = (int) Math.round(_x - _y);      int isoY = (int) Math.round((_x + _y));      screen.renderNPC(isoX - (SIZE / 2), isoY - (SIZE / 2), _sprite, 0);   }
 Games published by our own members! Check 'em out!
moogie

JGO Ninja

Medals: 16
Projects: 6
Exp: 10 years

Java games rock!

 « Reply #10 - Posted 2014-11-01 11:44:32 »

 1  2  3 public void renderTile(int xp, int yp, Tile tile) {      xp -= _xOffset;      yp -= _yOffset;

exactly as I had mentioned might be the case... you are doubling applying scrolling... remove this as it is not necessary

Java4k RIP 2014
hapsburgabsinth

Junior Devvie

 « Reply #11 - Posted 2014-11-01 12:18:52 »

If I remove the lines which using the offsets in renderTile. It renders the player in the top left corner (0,0) but no tiles. :/
moogie

JGO Ninja

Medals: 16
Projects: 6
Exp: 10 years

Java games rock!

 « Reply #12 - Posted 2014-11-01 20:37:06 »

Have you used the debugger at all? i.e. have you determined where the problem is occuring? what values does scrollMapX and scrollMapY produce? is it within the range of your tile map? they both should be 0 if no scrolling has occurred.

How about the isoX and isoY values that are passed into the getTile(x, y).render(isoX, isoY, screen) call... are they within the range of pixels of the screen's width and height?

Java4k RIP 2014
hapsburgabsinth

Junior Devvie

 « Reply #13 - Posted 2014-11-02 08:20:33 »

Yes, and it getting me weird outputs

I think my problem is understading the logic in how to approach this matter. I know that I should figure out the top left corner tile on the scrren, but I am unsure  on how to select the right tiles to draw.
moogie

JGO Ninja

Medals: 16
Projects: 6
Exp: 10 years

Java games rock!

 « Reply #14 - Posted 2014-11-02 12:04:00 »

I can provide complete source of my implementation if desired. Be warned, however that it is probably only going to confuse you more due to the fact that a) it has not been cleaned up in any form, b) it is not completely finished so has a lot of commented out code and c) it was for a java4k entry... thus it is using hacks, dodgy inefficient code so it is not the best to learn from.

Java4k RIP 2014
moogie

JGO Ninja

Medals: 16
Projects: 6
Exp: 10 years

Java games rock!

 « Reply #15 - Posted 2014-11-03 06:24:17 »

Here is a standalone version of the program using the code above that was used when making the animated GIF.

Java4k RIP 2014
hapsburgabsinth

Junior Devvie

 « Reply #16 - Posted 2014-11-04 05:24:10 »

Thank you for the help so far. I willt ake a closer look at your code Thnks.
hapsburgabsinth

Junior Devvie

 « Reply #17 - Posted 2014-11-04 07:25:32 »

So now I have almost fixed it. I converted the xScroll and yScroll into isometric co-ordinates, and changed the nested-for-loop from cartesian into isometric, and then converted the x and y (in isometric co-ordinates) into cartesian and called the the getTile(cartX,cartY).render(cartX,cartY,screen);

My problem now is, that the screen doesn't scroll fast enough, when you walk left and right. I think that it is the xScroll, that doens't get the right update. The code follows:

Setting the xScroll and yScroll in Games render method:
 1  2  3  4  5 int xScroll = (int) Math.round((_player.getX() - _player.getY())            - (_screen.getWidth() / 2));int yScroll = (int) Math.round((_player.getX() + _player.getY())            - (_screen.getHeight() / 2));_level.isometricRender(xScroll, yScroll, _screen);

Render method in Level:
 1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18 public void isometricRender(int xScroll, int yScroll, Screen screen) {      screen.setOffsets(xScroll, yScroll);      int x0 = xScroll / Tile.WIDTH - 4;      int x1 = x0 + 11;      int y0 = yScroll / Tile.HEIGHT;      int y1 = y0 + 7;      int cartX = 0;      int cartY = 0;      for (int y = y0; y < y1; y++) {         for (int x = x0; x < x1; x++) {            cartX = (2 * y + x) / 2;            cartY = (2 * y - x) / 2;            getTile(cartX, cartY).isometricRender(cartX, cartY, screen);         }      }}

A little help on understanding how to update the xScroll would be nice.

moogie

JGO Ninja

Medals: 16
Projects: 6
Exp: 10 years

Java games rock!

 « Reply #18 - Posted 2014-11-04 08:00:10 »

I am not I can help you... it looks like you have changed the algorithm significantly...

However from looking at your code I am not sure how you are correctly rendering your tiles... it looks like you are just rendering tiles in a grid.... there is no concept of alternating rows of tiles that are out of phase such that they completely cover the screen with no gaps.

But ignoring that issue, you need to be scrolling in isometric space not cartesian space.

Java4k RIP 2014
Pages: [1]
 ignore  |  Print

 EgonOlsen (42 views) 2018-06-10 19:43:48 EgonOlsen (22 views) 2018-06-10 19:43:44 EgonOlsen (43 views) 2018-06-10 19:43:20 DesertCoockie (197 views) 2018-05-13 18:23:11 nelsongames (124 views) 2018-04-24 18:15:36 nelsongames (123 views) 2018-04-24 18:14:32 ivj94 (863 views) 2018-03-24 14:47:39 ivj94 (124 views) 2018-03-24 14:46:31 ivj94 (768 views) 2018-03-24 14:43:53 Solater (140 views) 2018-03-17 05:04:08
 Java Gaming Resourcesby philfrei2017-12-05 19:38:37Java Gaming Resourcesby philfrei2017-12-05 19:37:39Java Gaming Resourcesby philfrei2017-12-05 19:36:10Java Gaming Resourcesby philfrei2017-12-05 19:33:10List of Learning Resourcesby elect2017-03-13 14:05:44List of Learning Resourcesby elect2017-03-13 14:04:45SF/X Librariesby philfrei2017-03-02 08:45:19SF/X Librariesby philfrei2017-03-02 08:44:05
 java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org