You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

179 lines
6.6 KiB

#include "isometricMap.h"
#include <stdio.h>
#include <stdlib.h>
#include "tile.h"
#include "raymath.h"
#include "raylib.h"
#include "../Sprite/sprite.h"
#include "../game.h"
IsometricMap * IsometricMapInit(){
IsometricMap* map = malloc(sizeof(IsometricMap));
int counter = 0;
map->tileTextures[counter++] = LoadTexture("assets/tiles/grass.png");
map->tileTextures[counter++] = LoadTexture("assets/tiles/desert.png");
map->tileTextures[counter++] = LoadTexture("assets/tiles/desert_palm.png");
map->tileTextures[counter++] = LoadTexture("assets/tiles/tower.png");
map->tileTextures[counter++] = LoadTexture("assets/tiles/bigtower.png");
map->tileTextures[counter++] = LoadTexture("assets/tiles/grass_selected.png");
map->tileTextures[counter++] = LoadTexture("assets/tiles/ice.png");
map->tileTextures[counter++] = LoadTexture("assets/tiles/water.png");
map->tileTextures[counter++] = LoadTexture("assets/tiles/empty.png");
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;
// 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){
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;
}
}
}
}