#include "isometricMap.h" #include #include #include "tile.h" #include "raymath.h" #include "raylib.h" #include "../Sprite/sprite.h" #include "../game.h" IsometricMap * IsometricMapInit(Game *game){ IsometricMap* map = malloc(sizeof(IsometricMap)); int counter = 0; for(counter = 0; counter < TE_TILES_LENGTH; counter++){ map->tileTextures[counter] = &(game->textures->textures[TE_TILES][counter]); } map->width = 500; map->height = 500; map->textureWidth = map->tileTextures[0]->width; map->textureHeight = map->tileTextures[0]->height; map->worldPixelWidth = map->width * map->textureWidth; map->worldPixelWidth = map->height * map->textureHeight; map->timer = 0; // mallocating the twodimensional Tiles Array Tile*** tiles = malloc(map->width*sizeof(Tile*)); int n = 0; for(n=0; n < map->width; n++){ tiles[n] = malloc(map->height*sizeof(Tile*)); } int i = 0; int j = 0; int halfTextureSize = map->textureWidth/2; int quarterTextureSize = map->textureWidth/4; for(i=0; i < map->width; i++){ for(j=0; j < map->height; j++){ Tile *tmp = malloc(sizeof(Tile)); // initially all the Tiles are "empty" tmp->textureId = -1; tmp->x = i; tmp->y = j; Vector2 *offset = IsometricMapCalcOffsetForTileAt(i,j, halfTextureSize, quarterTextureSize); tmp->offsetX = offset->x; tmp->offsetY = offset->y; free(offset); tiles[i][j] = tmp; } } map->tiles = tiles; return map; } // For Rendering: calculates coordinate offset for a single tile at arrayPosition x y // Only works for tiles with texture width == height (and for 22.5 degree?) Vector2 * IsometricMapCalcOffsetForTileAt(int x, int y, int halfTextureSize, int quarterTextureSize){ Vector2* offset = malloc(sizeof(Vector2)); offset->x = x * halfTextureSize - y * halfTextureSize; offset->y = x * quarterTextureSize + y * quarterTextureSize; return offset; } // Unproject: World Coordinates -> Screen Coordinates writes result in tmp Vector void IsometricMapProject(IsometricMap *isometricMap, Camera2D *camera, float x, float y, Vector2 *tmp){ x = (x+camera->target.x) / ((isometricMap->textureWidth)/2); y = (y+camera->target.y) / ((isometricMap->textureHeight)/4); tmp->x = ( x + y) * (isometricMap->textureWidth/2); tmp->y = ( -x + y) * (isometricMap->textureHeight/2); } // Unproject: World Coordinates -> Screen Coordinates writes result in tmp Vector void IsometricMapUnproject(Camera2D *camera, int x, int y, Vector2 *tmp){ tmp->x = ((x - y)/2) + camera->target.x; tmp->y = ((x + y)/4) + camera->target.y; } void IsometricMapUnprojectIgnoreCam(int x, int y, Vector2 *tmp){ tmp->x = ((x - y)/2); tmp->y = ((x + y)/4); } // USE INSIDE MODE2D!! void IsometricMapDrawRectangle(Vector2 from, Vector2 to, Color color){ from.x += 32; to.x += 32; Vector2 corner1 = {from.x, from.y}; IsometricMapUnprojectIgnoreCam(corner1.x, corner1.y, &corner1); Vector2 corner2 = {to.x, from.y}; IsometricMapUnprojectIgnoreCam(corner2.x, corner2.y, &corner2); Vector2 corner3 = {to.x, to.y}; IsometricMapUnprojectIgnoreCam(corner3.x, corner3.y, &corner3); Vector2 corner4 = {from.x, to.y}; IsometricMapUnprojectIgnoreCam(corner4.x, corner4.y, &corner4); DrawLineV(corner1, corner2, RED); DrawLineV(corner2, corner3, RED); DrawLineV(corner3, corner4, RED); DrawLineV(corner4, corner1, RED); } // returns Tile * -> tile at coordinates x y z=layer Tile * IsometricMapGetTileFromWorldCoordinates(IsometricMap *isometricMap, float x, float y){ x = (int)(x / isometricMap->textureWidth); y = (int)(y / isometricMap->textureHeight); if( x < isometricMap->width && y < isometricMap->height && x >= 0 && y >= 0 ){ if(isometricMap->tiles[(int)x][(int)y]->textureId != -1){ return (isometricMap->tiles[(int)x][(int)y]); } } return 0; } // changes to Texture ID of tile at x y on maplayer layer void IsometricMapChangeTextureIdOfTile(IsometricMap *map, int x, int y, int id){ if( x < map->width && y < map->height && x >= 0 && y >= 0 ){ (map->tiles[x][y])->textureId = id; } else{ printf("WARNING: trying to change Texture of Tile which is out of bounds!\n"); } } void IsometricMapDraw(Game *game){ game->map->timer += GetFrameTime(); if(game->map->timer > 0.2f){ game->map->tileTextures[7] = &(game->textures->textures[TE_TILES][9]); } if(game->map->timer > 0.4f){ game->map->tileTextures[7] = &(game->textures->textures[TE_TILES][10]); } if(game->map->timer > 0.6f){ game->map->tileTextures[7] = &(game->textures->textures[TE_TILES][11]); } if(game->map->timer > 0.8f){ game->map->tileTextures[7] = &(game->textures->textures[TE_TILES][7]); game->map->timer = 0; } int windowWidth = GetScreenWidth(); int windowHeight = GetScreenHeight(); Vector2 topleft = {0, 0}; IsometricMapProject(game->map, game->camera, topleft.x, topleft.y, &topleft); Vector2 topright = {windowWidth, 0}; IsometricMapProject(game->map, game->camera, topright.x, topright.y, &topright); Vector2 botleft = {0, windowHeight}; IsometricMapProject(game->map, game->camera, botleft.x, botleft.y, &botleft); Vector2 botright = {windowWidth, windowHeight}; IsometricMapProject(game->map, game->camera, botright.x, botright.y, &botright); int extraTiles = 1; int n = 0; int itmp = (int)(topleft.x / game->map->textureWidth) - extraTiles; int jtmp = (int)(topright.y / game->map->textureHeight) - extraTiles; int maxI = (int)(botright.x / game->map->textureWidth) + extraTiles; int maxJ = (int)(botleft.y / game->map->textureHeight) + extraTiles; if (itmp < 0){ itmp = 0; } if (jtmp < 0){ jtmp = 0; } if (maxI > game->map->width){ maxI = game->map->width; } if (maxJ > game->map->height){ maxJ = game->map->height; } register int i, j = 0; for (j = jtmp; j < maxJ; ++j){ for (i = itmp; i < maxI; ++i){ if (game->map->tiles[i][j]->textureId == -1){ continue; } else{ DrawTexture( *(game->map->tileTextures[game->map->tiles[i][j]->textureId]), game->map->tiles[i][j]->offsetX, game->map->tiles[i][j]->offsetY - game->map->tileTextures[game->map->tiles[i][j]->textureId]->height + 32, WHITE); continue; } } } }