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.

161 lines
5.4 KiB

#include "isometricMap.h"
#include <stdio.h>
#include <stdlib.h>
#include "tile.h"
#include "raymath.h"
#include "raylib.h"
// returns pointer to IsometricMap Instance
IsometricMap * IsometricMapInit(int layer){
IsometricMap* map = (IsometricMap *) malloc(sizeof(IsometricMap));
map->tileTextures[0] = LoadTexture("assets/grass.png");
map->tileTextures[1] = LoadTexture("assets/grass_selected.png");
map->tileTextures[2] = LoadTexture("assets/tower.png");
//map->tileTextures[0] = LoadTexture("assets/desert.png");
//map->tileTextures[1] = LoadTexture("assets/bigtower.png");
map->width = 200;
map->height = 200;
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->layer = layer;
// mallocating the twodimensional Tiles Array
Tile*** tiles = (Tile***)malloc(map->width*sizeof(Tile*));
int n = 0;
for(n=0; n < map->width; n++){
tiles[n] = (Tile**)malloc(map->height*sizeof(Tile*));
}
int i = 0;
int j = 0;
for(i=0; i < map->width; i++){
for(j=0; j < map->height; j++){
Tile *tmp = (Tile *) malloc(sizeof(Tile));
// initially all the Tiles are "empty"
tmp->textureId = -1;
tmp->x = i;
tmp->y = j;
tmp->z = layer;
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 textureSize){
Vector2* offset = (Vector2 *)malloc(sizeof(Vector2));
offset->x = x * textureSize/2 - y * textureSize/2;
offset->y = x * textureSize/4 + y * textureSize/4;
return offset;
}
Vector2 * IsometricMapCalcOffsetForTileAtEfficient(int x, int y, int halfTextureSize, int quarterTextureSize){
Vector2* offset = (Vector2 *)malloc(sizeof(Vector2));
offset->x = x * halfTextureSize - y * halfTextureSize;
offset->y = x * quarterTextureSize + y * quarterTextureSize;
return offset;
}
// returns Tile at x y on layer isometricMap
Tile * IsometricMapGetTileFromArrayPosition(IsometricMap *map, int x, int y){
return map->tiles[x][y];
}
// Unproject: World Coordinates -> Screen Coordinates writes result in tmp Vector
void IsometricMapProject(IsometricMap *isometricMap, Camera2D *camera, float x, float y, Vector2 *tmp){
float tileWidthHalf = isometricMap->textureWidth / 2;
float tileHeightQuarter = isometricMap->textureHeight / 4;
x += camera->target.x;
y += camera->target.y;
float xPos = (float) x;
float yPos = (float) y;
float isoX = 0.5 * ( xPos / tileWidthHalf + yPos / tileHeightQuarter);
float isoY = 0.5 * ( -xPos / tileWidthHalf + yPos / tileHeightQuarter);
tmp->x = isoX * isometricMap->tileTextures[0].width;
tmp->y = isoY * isometricMap->tileTextures[0].height;
}
// Unproject: World Coordinates -> Screen Coordinates writes result in tmp Vector
void IsometricMapUnproject(IsometricMap **isometricMap, Camera2D *camera, int x, int y, float z, Vector2 *tmp){
float xPos = (float) x;
float yPos = (float) y;
float screenX = (xPos - yPos) / 2;
float screenY = (xPos + yPos) / 4;
screenX += camera->target.x;
screenY += camera->target.y;
// z is currently implemented as z=1 equals 1 layer, z=2 would be two layers height (could be smoothed)
// hardcoded tile height
screenY -= z * 10;
tmp->x = screenX;
tmp->y = screenY;
}
// returns Tile * -> tile at coordinates x y z=layer
Tile * IsometricMapGetTileFromWorldCoordinates(IsometricMap **isometricMap, float x, float y, float z){
int layer = (int) z;
x = (int)(x / isometricMap[layer]->textureWidth);
y = (int)(y / isometricMap[layer]->textureHeight);
if( x < isometricMap[layer]->width && y < isometricMap[layer]->height && x >= 0 && y >= 0 ){
if(isometricMap[layer]->tiles[(int)x][(int)y]->textureId != -1){
return (isometricMap[layer]->tiles[(int)x][(int)y]);
}
}
Tile *ptr = 0;
return ptr;
}
// Gives the most upper Tile above *tile
Tile * IsometricMapGetMostUpperTile(IsometricMap **isometricMap, Tile *tile){
Tile *ptr = (Tile *) malloc(sizeof(Tile *));
// hardcoded layer amount
int n = 9;
for(n=9;n>=0;n--){
if( tile->x < isometricMap[n]->width && tile->y < isometricMap[n]->height &&
tile->x >= 0 && tile->y >= 0 ){
if(isometricMap[n]->tiles[tile->x][tile->y]->textureId != -1){
ptr->x = isometricMap[n]->tiles[tile->x][tile->y]->x;
ptr->y = isometricMap[n]->tiles[tile->x][tile->y]->y;
ptr->z = isometricMap[n]->tiles[tile->x][tile->y]->z;
return ptr;
}
}
}
ptr = 0;
return ptr;
}
// changes to Texture ID of tile at x y on maplayer layer
void IsometricMapChangeTextureIdOfTile(IsometricMap **map, int x, int y, int layer, int id){
if( x < map[layer]->width && y < map[layer]->height &&
x >= 0 && y >= 0 ){
(map[layer]->tiles[x][y])->textureId = id;
}
else{
printf("WARNING: trying to change Texture of Tile which is out of bounds!\n");
}
}