Steven

Members
  • Content count

    271
  • Joined

  • Last visited

Community Reputation

136 Neutral

About Steven

  • Rank
    Member
  1. Have you looked at the iso article on here that I wrote? http://www.gamedev.net/reference/articles/article2026.asp That article deals with adding height to your diamond / rotated maps, but it has all the code in there to help you work out your mouse maps.
  2. Firstly, I'm glad that the rest of the board answered your questions last time about my article, and I wish I had answered sooner. Anyho onto your questions. Quote:Original post by Ezbez My problem is the exact problem that the above article adresses; getting a mouse click to be turned into isometric tile coordinates. I've read through the article several times, and tried to implement it into my game, but it just doesn't work. Hmm, I really must re-do that article as I've just re-read it, and even though it's my article, I've got no idea what I'm doing in it :D. I've made some notes so watch out for an update on it soon. Quote:Original post by Ezbez A little information about my game. Everything is written in c++. It uses SDL for graphics/everything, and is 2D only. I have the TileMap[10000] array wich is used as a 100x100 array, but for some reason I decided to make it a one dimensional array instead of two dimensional. Thats why you see alot of TileMap[x + 100*y] in my program. My tiles are displayed onto the screen in the shape of a large, isometric tile. That's how I do most of my tile maps, it's not too daft a way of doing the tile map as it allows you to wrap the tiles as if your worls is spherical, or use zones, so that instead of loading 10k bit of tile data yyou load 9 loads of 100 tiles (if your view area is 10x10 for instance. Quote:Original post by Ezbez A picture of my current program is here (Like the randomly generated terrain? :) ) I have marked a problem with the tile drawing code, by the looks of it your calculations for the change in the Y offset from one row to the next is wrong. Quick formula for the drawing code: xp = ( ( x - y ) * 32 ); yp = ( ( x + y ) * 16 ); Please note that the 32 is half the width and the 16 is half the height of the flat tile. I'm not sure what's going on in your code, but you should look at your drawing code again Quote:Original post by Ezbez My numbering system for my tiles are similiar to how they number Pascal's Triangle, its like you took a standard grid and then rotated it and squished it to fit within an isometric square. (0, 0) would address the top square on the screen, (1,0) would address the square to the right and a little down of (0,0). (0,1) would address the square a down and a little to the left of (0,0). Hopefully you understand. So your using a "diamond" isometric rendering engine, like I did in my article. I'm saying diamond as that is what TANSTAAFL calls it in his book. Quote:Original post by Ezbez I'm actually using the graphics used in the above tutorial until I get this to work and bother to draw new ones. I use this picture for screen coordinates to isometric coordinates. So your using my tile maps, that's good so we are on the same page here. Quote:Original post by Ezbez Okay, enough about the game, heres some code I've got. *** Source Snippet Removed *** What happens? Well, when I run this and click the left mouse button(which calls the first function), the program goes into an infinite loop. When I press the right mouse button(which calls the second function), the program works fine, but the tile that it thinks I've clicked on, is caclulated as if I had flat terrain. Any suggestions? Oh, and sorry for the long post. Edit: added links. Right where do I begin with pulling your code apart??? At the start I suppose :D, well your infinate loop is easy to spot (this is your code cleaned up a little)... while(corner == 0) { tileNum = regionX + 100 * regionY; if(mouseMapY+tileMap[tileNum]->getLow()*8 <= 63) { color = getpixel(isoMap,mouseMapX+64*tileMap[tileNum]->getType(),mouseMapY+tileMap[tileNum]->getLow()*8); } if(color == 0xff0000)//red { regionY--; mouseMapY+=32; printf("red"); } if(color == 0xffff00)//yellow { regionX++; regionY--; mouseMapX-=32; mouseMapY+=16; printf("yellow"); } if(color == 0x00ffff)//Cyan { regionY++; mouseMapY-=32; printf("Cyan"); } //THIS IS THE CODE for when you've gotten into the correct square. //This would be the white part of the picture in the tutorial, but //since I need to get the corners too, I have corresponded each corner //to a different shade of grey. I doubt that this part of the code is //wrong, so you can probably ignore it //In the square if(color == 0x646464) { regionDX = 0; regionDY = 0; corner=2; break; } if(color == 0x6e6e6e) { regionDX = 0; regionDY = 0; corner=1; break; } if(color == 0x787878) { regionDX = 0; regionDY = 0; corner=0; break; } if(color == 0x808080) { regionDX = 0; regionDY = 0; corner=3; break; } if(color == 0x00ff00)//green { regionX--; regionY++; mouseMapX+=32; mouseMapY-=16; printf("green"); } if(color == 0x0000ff)//blue { regionX--; moveY = 0; mouseMapX+=32; mouseMapY+=16; printf("blue"); } if(color == 0xff00ff)//Magenta { regionX++; moveY = 0; mouseMapX-=32; mouseMapY-=16; printf("Magenta"); } if(mouseMapY+tileMap[tileNum]->getLow()*8 > 63) { regionY++; mouseMapY+=32; } } Tell you what here's the same code but re-written using a switch statement instead of those multiple if(...) statements: while( corner == 0 ) { tileNum = regionX + 100 * regionY; if(mouseMapY+tileMap[tileNum]->getLow()*8 <= 63) { color = getpixel(isoMap,mouseMapX+64*tileMap[tileNum]->getType(),mouseMapY+tileMap[tileNum]->getLow()*8); } else { regionY++; mouseMapY+=32; } switch( color ) { case 0xFF0000: // Red regionY--; mouseMapY+=32; printf("red"); break; case 0xFFFF00:// Yellow regionX++; regionY--; mouseMapX-=32; mouseMapY+=16; printf("yellow"); break; case 0x00FFFF: // Cyan regionY++; mouseMapY-=32; printf("Cyan"); break; case 0x00ff00)// Green regionX--; regionY++; mouseMapX+=32; mouseMapY-=16; printf("green"); break; case 0x0000ff)// Blue regionX--; moveY = 0; mouseMapX+=32; mouseMapY+=16; printf("blue"); break; case 0xff00ff)// Magenta regionX++; moveY = 0; mouseMapX-=32; mouseMapY-=16; printf("Magenta"); break; //THIS IS THE CODE for when you've gotten into the correct square. //This would be the white part of the picture in the tutorial, but //since I need to get the corners too, I have corresponded each corner //to a different shade of grey. I doubt that this part of the code is //wrong, so you can probably ignore it //In the square case 0x646464: regionDX = 0; regionDY = 0; corner=2; break; case 0x6e6e6e: regionDX = 0; regionDY = 0; corner=1; break; case 0x787878: regionDX = 0; regionDY = 0; corner=0; break; case 0x808080: regionDX = 0; regionDY = 0; corner=3; break; } } Spotted it yet? I'll give you a clue I think it has something to do with that if up at the top: if(mouseMapY+tileMap[tileNum]->getLow()*8 <= 63) { color = getpixel(isoMap,mouseMapX+64*tileMap[tileNum]->getType(),mouseMapY+tileMap[tileNum]->getLow()*8); } else { regionY++; mouseMapY+=32; } The reason I'm blaming this is it's the only bit of code that's an unknown, mainly as your calling a function that I do not know what it does. Also I've spotted some weird figures in there: //x=x-32; y=y-156; int regionX = x/67; int regionY = y/33; int mouseMapX = x % 67; int mouseMapY = y % 33; What size iso tiles are you using? the tiles I use in that article are either 64x32 or 32x16, you may want to re-look at those first few lines. Also your loop will never end if your mouse is in corner 0, change your while loop to: int corner = -1; while( corner == -1 ) { ... } this will eliminate one source of your inf loop. I take it that you are going to be adding the ability to raise an lower the corners of the tiles, this is something I was looking into, and ended up dumping the idea of a tile map, and instead used a grid of heights, with links to the objects on the virtual tile below that point, this way the terrain was generated at run time and it was faster than itterating though the entire map with a recursive function...
  3. random iso map

    Quote:Original post by web_scripter Um there's something wrong with the code. there are two if statements that are the same but contain different code. else if ( ( x == 0 ) && ( y > 0 ) ) map[y][x] = map[y-1][x] + ( ( rand() * 3 ) - 1 ); else if ( ( x == 0 ) && ( y > 0 ) ) map[y][x] = map[y][x-1] + ( ( rand() * 3 ) - 1 ); Well I did say it was from memory :D The correct lines should be: else if ( ( x == 0 ) && ( y > 0 ) ) map[y][x] = map[y-1][x] + ( ( rand() * 3 ) - 1 ); else if ( ( x > 0 ) && ( y == 0 ) ) map[y][x] = map[y][x-1] + ( ( rand() * 3 ) - 1 );
  4. random iso map

    C# - Urg I'm not touching that with a barge pole - well not for a while at least :D I've been trying to find an old article I read about a simple random terrain generator, but alas I can not, so this is from memory. This is in C using the rand() functiona... for( x = 0; x < 6; x ++ ) { for( y = 0; y < 6; y ++ ) { if( ( x == 0 ) && ( y == 0 ) ) /* First pos, pick a random height */ map[y][x] = rand() * 5; else if ( ( x == 0 ) && ( y > 0 ) ) map[y][x] = map[y-1][x] + ( ( rand() * 3 ) - 1 ); else if ( ( x == 0 ) && ( y > 0 ) ) map[y][x] = map[y][x-1] + ( ( rand() * 3 ) - 1 ); else map[y][x] = ( ( map[y-1][x] + map[y][x-1] ) / 2 ) + ( ( rand() * 3 ) - 1 ); } } Of couse you will have to put in some checks to make sre that the height that has just been done does not break the rules of your tile set, but that code can produce some interesting maps with the right seed for the random number generator. Doesn't C# use Direct8+ which means your working in DirectGrpahics, if that's the case then I'd sugest forgetting about the tileset, and making the engine use the hieghts that you are generating with your terrrain generator it would look better, and you can change the rand() * 3 - 1 to something like rand() * 5 - 2, which would give you a more random map...
  5. random iso map

    Are they the tiles I supplied in my article? If not, why do you have a hole for tile 16? Anyway... How I'd did it was to create a 6x6 grid and do the usual random height generator, making sre you only change the height by one along the X / Y axis... the 6x6 grid for your test map is (ignore the X rows for now): 0 0 1 1 0 0 X X X X X 0 0 1 1 0 0 X X X X X 0 0 1 1 0 0 X X X X X 0 1 1 1 1 1 X X X X X 0 1 1 1 1 1 X X X X X 0 1 1 0 1 1 Now to convert this into the 5x5 map take the 4 values around an X and assign these to a bit field: 8 4 2 1 BL BR TR TL Making sure that the values you put in are the diference between the lowest height for that 4 and the corner your looking at. Once you put these values into a bitfield, you will have the tile you need. If there is a case where the height between the lowest and highest point is 2 then you use the special tiles at the end of that tile set you pasted. First row conversion: 0 0 0 0 = Tile 0 or a flat tile ( 1 1 1 1 = tile 0 as well ) 0 1 1 0 = Tile 6 or the slope up at the bottom right 1 1 1 1 = Tile 0 as the lowest point is also the same height as the rest of the tile 1 0 0 1 = Tile 9 or slope down from top right 0 0 0 0 = Tile 0 or a flat tile ( 1 1 1 1 = tile 0 as well ) Nice and easy 2 stage process... Of course you could add a further tileset for water - ground (basically all the edges at height 0 have some sand on them, and the flat tile is blue) or a rocky set (brown tiles) and finally a white set for snow.
  6. Quote:Original post by Wyrframe Just reducing Tile_width to 63 from 64 ought to do it. You really want odd-width, odd-height tiles, anyway; preserves perspective and shape better in practise. As it is, if those tiles are even-width, you'll get some overlap, but it will prevent those seams. I've never had any overlap with those tiles, as they are 64 width and 31 height. Also they are the same size as TANSTAAFL uses in his book (smallest tile you can make is 1x4 for software rendering) Edit: void draw_tiles(void) { for(Tileset.y=0; Tileset.y <Mapy;Tileset.y++) { for(Tileset.x=0; Tileset.x < Mapx; Tileset.x++) { //what does this do? Tileset.scroll_x = Tileset.x + ( Tileset.world_camerax / Tileset.Tile_Width );//this allows scrolling on y axis Tileset.scroll_y = Tileset.y + ( Tileset.world_cameray / Tileset.Tile_Hight );//this allows scrolling on x axis Tileset.offset_x = Tileset.world_camerax + ( screenx / 2 ); Tileset.offset_y = Tileset.world_cameray + ( screeny / 2 ); Tileset.tiles = map[ Tileset.y ][ Tileset.x ]; tile_src.left = ( ( Tileset.tiles ) % 20 ) * Tileset.Tile_Width; tile_src.top = ( ( Tileset.tiles ) / 20 ) * Tileset.Tile_Hight; tile_src.right = tile_src.left + Tileset.Tile_Width; tile_src.bottom = tile_src.top + Tileset.Tile_Hight; dstr.left = ( ( Tileset.x - Tileset.y ) * Tileset.Tile_Width / 2 ) + Tileset.offset_x; dstr.right = dstr.left + Tileset.Tile_Width; dstr.top = ( ( Tileset.y + Tileset.x ) * Tileset.Tile_Hight / 4 ) - Tileset.offset_y; dstr.bottom = dstr.top + Tileset.Tile_Hight; lpBackBuffer->Blt(&dstr,g_pddTile,&tile_src,DDBLT_WAIT|DDBLT_KEYSRC,NULL); } } } I fixed a couple of errors in your code, the main one was to do with you shrinking the tile in the vertical axis by half, and posibly putting 2 tiles on the screen in one go. The other error I spotted was to do with getting the Y locations you were using half the tile height, but your tile height was 4 times the size it should actually be, so fixing those 2 errors you should have all the tiles sitting snuggly next to each other. [Edited by - Steven on May 24, 2005 12:38:28 PM]
  7. Your tiles are not true iso tiles. Those are true isometric tiles (well true as far as AOE is conserend) From looking at your tiles I think your doing something funky to them as they do not look 1:1 ( 45 degree rotation ) or isometric ( 45 degree rotation about 2 axis in a 3D art package ). to make an iso metric tile use the above tiles as an example of how they should look in your paint package, IIRC they are the right size for your engine. If you want you could just use them until you get your graphics re-done to the correct aspect ratio. If your converting your graphics from 2D squares at load up, then I'd sugest going back to the artist / paint package and re-drawing them from scratch, unless your tiles are 16x16 your going to have to re-do them. I've got some code to do a software blit of a 16x16 square to an isometric tile somewhere, it's slow, but it can be used at load time to change your graphics. Using that code will help a little, but your end result would look better with correctly redrawn sprites [Edited by - Steven on May 22, 2005 4:40:38 AM]
  8. I use this: void clear( DWORD Colour ) { DDBLTFX ddfx; DXSTRUCTINIT( ddfx ); ddfx.dwFillColor = Colour; lpBackBuffer->Blt( NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddfx ); }
  9. Simple answer to your 'ghosting' problem would be to clear your back buffer before you start to draw the next screen. For the height maps and the scrolling look at my article here it uses 2:1 diamond tiles, not 1:1 tiles that you are using. The other 2 things you are working on is down to your drawing loop, so once you get the drawing sorted, the other two (animation and layers) will fall into place very easily.
  10. Could you post a screen shot of how the times are being drawn to the screen? this might help us determine exactly what's happening. Your doing everything correctly as far as I can see, but without a pic of what your getting then I'm unable to help determine the exact problem. Also as for the clipper, I never use it, I don't think I've ever used a clipper on DirectDraw (just checked my game engine that I'm working on now, and the clipper code is all commented out). You can get away with manual clipping of the image, it's a little harder to do initially, but once you work it out it's very easy to do, this also means you can do custom clipping rects without having to ploay around with the clipper. If your base / land layer uses iso tiles that are 32x16 (stored in a 32x32 size tile) then your second / object layers can be any height and width, BUT you are better off kepping your width to 32, and splitting up larger objects into multiple objects.
  11. Quote:Original post by Rozik This is my code for the mouse location: the x position is right and at the top of the map the y position is right too but at the lower map tiles the y coordinate is off case WM_MOUSEMOVE: { x = (int)LOWORD(lparam); y = (int)HIWORD(lparam); tile[RegionX][RegionY]->next=NULL; RegionX=int(x/40) ; RegionY=int((y/21)*2); int MouseMapX=x % 40; int MouseMapY=y % 21; HDC hdc; MouseMap->name->GetDC(&hdc); COLORREF ERG= GetPixel(hdc,MouseMapX,MouseMapY); red = GetRValue(ERG); green = GetGValue(ERG); blue = GetBValue(ERG); if(red==255 & green==255 & blue==255){ } if(red==255 & green==0 & blue==0){ RegionX-=1; RegionY-=1; } if(red==0 & green==255 & blue==0){ RegionX-=1; RegionY+=1; } if(red==0 & green==0 & blue==255){ RegionY+=1; } if(red==255 & green==255 & blue==0){ RegionY-=1; } MouseMap->name->ReleaseDC(hdc); if(RegionX<0) RegionX=0; if(RegionX>24) RegionX=24; if(RegionY<0) RegionY=0; if(RegionY>64) RegionY=64; tile[RegionX][RegionY]->next=new Image(lpddsback,Marker); tile[RegionX][RegionY]->next->SetXpos(tile[RegionX][RegionY]->GetXpos()); tile[RegionX][RegionY]->next->SetYpos(tile[RegionX][RegionY]->GetYpos()); // change=TRUE; return(0); } If your coding this in C++ then there is a few problems with your code allocating and de-allocating memory (read this as huge memory leaks), if it's Java ... then you might be doing it right, but IIRC java does not do pointers, or GDI. This section of code: COLORREF ERG= GetPixel(hdc,MouseMapX,MouseMapY); red = GetRValue(ERG); green = GetGValue(ERG); blue = GetBValue(ERG); if(red==255 & green==255 & blue==255){ } if(red==255 & green==0 & blue==0){ RegionX-=1; RegionY-=1; } if(red==0 & green==255 & blue==0){ RegionX-=1; RegionY+=1; } if(red==0 & green==0 & blue==255){ RegionY+=1; } if(red==255 & green==255 & blue==0){ RegionY-=1; } can be changed to a switch: COLORREF ERG= GetPixel(hdc,MouseMapX,MouseMapY); switch( erg ) { case RGB(255,0,0): RegionX-=1; RegionY-=1; break; case RGB(0,255,0): RegionX-=1; RegionY+=1; break; case RGB(0,0,255): RegionY+=1; break; case RGB(255,255,0): RegionY-=1; break; case RGB(255,255,255): //do nothing; break; } Also I'm hoping that the if statements are incorrectly copied as: if( red == 255 & green == 255 & blue == 255 ) means, brackets used to empisize the way the code is looked at if red == ( 255 and green == ( 255 and blue == 255 ) ) what you want is: if ( ( red == 255 ) && ( green == 255 ) && ( blue == 255 ) ) Another good article on mouse maps (and I allow height in my iso maps) http://www.gamedev.net/reference/articles/article2026.asp If your getting TANSTAAFL's Iso book, then the code in my article above is based on his code from his book, which in turn is based on the article you first linked to ( which is also his ) If you have any queries about my article I've changed ISP and my e-mail is now sharriso AT nildram DOT com ( do the normal replace information as I was getting a lot of spam mail on my old accout by handing out my e-mail in forums )
  12. Your first method should work fine, and the reason your moving off the map is down to your keyboard decoding setion, this is me running though the code by hand, so I might be out a little. if you hit all 4 directions at one the following will happen: Current DestX/Y = 100,100 Update(); DestX = 100 DestY = 100 state = 4 Which means that it's going left, and the line: if (x - speed * FPS.Instance.FrameTime < destX) will always be true, unless speed = 0; Now onto what I would sugest: you know how long it would take the unit to move 1 tile, lets make this 1 tile (32x32) in 8 seconds (easy maths), or 4 pixels / second or 0.004 pixels / 1 millisecs which is at a scale we can use with the FPS counter, so we know that we can safely use this speed variable to move, BUT with pc's being what they are, you will end up with a nice problem of over or under arriving, this is sorted by adding a dest value and testing against this, this way you will not only get a nice smooth movement but also a static STOP at the end. Or in otherwords use both your methods, but fix the code to grab your keyboard input as the way it is now, does not help you with silly people hitting all 4 direction keys at once.
  13. Quote:Original post by ArchG Thank you for your responses... Quote: How many tiles do you have in each layer? Hmm, I'm not sure if I understand this question right..but with the fixed size of 128x128 there would be about 16k tiles in every layer..(if they were filled) I will have no background bitmap or anything, so everything is made completely in tiles No what I meant was how many different tiles does your map support.. No even that reads wrong :D OK you said you have a grass tile, and I'll assume some other tile images (grass, mud, water, etc), how many different tile images do you have for each layer? As furiousuk haas sugested, using linked lists for your map storage in memory would be a better way to do the storage. Also when you make your stuct to store your tile information make sure it's doubleword aligned and that it is in total a multiple of 4 bytes (using pure int's your fine, using bytes add some filler bytes to make up to the 4 byte multiples) as this will speed up access time to the tile info. Also count any pointers as 4 bytes (IIRC a pointer is a 32 bit value) Also final sugestion for the layers - make a new map and a test program that displays your different layers as an on/off with real time FPS counter, this way you can see how many layers you can handle, if you can code that up and uploadit somewhere with instuctions (press 2 to turn on/off layer 2, etc) I'm sure some of the members of GameDev will try it out (hell even crappy grafix will be fine for this test of your engine), this way to can see if the 6 layers are too much, and if you leave the code in place for the optional layer drawing, then you can make the final product dyamically draw the layers depending on the FPS of the end PC, slower PC = less layers, fast PC = more layers drawn, just make sure that you have some of the layers set to alway's on...
  14. OK so just to get this into my mind correctly your map file has the following: fixed maximum size for file name 128 chars without the extention fixed map seize 128x128. Ok now that sorted a couple of questions: How many tiles do you have in each layer? Why do you need 3 background layers? Does your tiles have transparency? Going off your map format 1 map file will be 128 * 128 tile = 16384 tiles (16K tiles) 1 tile = 8 * 4 = 32 bytes ( 1 int = 4 bytes IIRC ) = 524228 or 512Kb Thats half a meg of memory for storing a single map. If your limiting your tiles to 256 per level, and had a maximum of 255 zones, then you can drop the amount of memory down to 1/4 that size by using char's or BYTE sized variables (approx 128k) now onto your drawing code, yes this could be optomised, if you are not allowing your tiles to have transparency then you can do a simpler draw cycle, if your not in the zone then draw the character and roof layers only, if your in the zone draw the background, char and forground layers. Also limiting to only drawing tiles that would be visible to the screen would make the game draw the world faster, thus giving more time to AI and other mechanics. if you are allowing your tiles to have transparency then your stuck drawing everything on every visible tile. How I do my 2D tile maps is: My layer - Your Layer Background bitmap - Layer1 Floor Tiles - Layer2 Characters - Chars Forground - Layer4 UI - UI I've not donw any top down with roofs yet, but they would be drawn just before the UI level, in total only 4 levels would be saved (the last / missing level would be objects). The more layers you have to draw, the more overdraw you create, which in turn will cause your game loop to slow dowm, try and remove some of the unneeded layers, as I previously said why 3 backdround layers? why 2 forground layers?
  15. Are you using only 1 terrain set at a time? if so make the height change in my article a variable according to your terrain, in fact if you look at the code you could use the height map article and add the ability for it to read the terrain tile height info and change it's up down offsets via the terrain offset for the height. For example: Assuming that you have the different terrains in their own stucts with a height offset then instead of using the following code: fy -= 8; // My hieght offset You would use this: fy -= ter[ currentTerrain ].heightOffset ; // My hieght offset Please note that this is untested and may not work 100 percent, but should work with a little bit of thought, I had a ream of A4 paper when I worked out the original article.