#include "map.h" #include "game.h" #include "world.h" #include "player.h" void repositionMap(Map* map) { map->rect.x = GetRenderWidth() - map->rect.width; } void initMapHeightmap(Map* map, const World* world) { Image image = LoadImageFromTexture(world->heightmapTexture); Color* colors = LoadImageColors(image); UnloadImage(image); for (int index = 0; index < WORLD_IMAGE_WIDTH * WORLD_IMAGE_HEIGHT; ++index) { unsigned char grayValue = GRAY_VALUE(colors[index]); unsigned char alpha = colors[index].a; if (grayValue >= 170) { colors[index] = (Color){grayValue, 0, 0, alpha}; } else if (grayValue >= 85) { colors[index] = (Color){0, grayValue * 2, grayValue, alpha}; } else { colors[index] = (Color){grayValue, 0, grayValue, alpha}; } } image = (Image){ .data = colors, .width = WORLD_IMAGE_WIDTH, .height = WORLD_IMAGE_HEIGHT, .format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, .mipmaps = 1 }; ImageColorContrast(&image, 25.0); map->heightmap = LoadTextureFromImage(image); UnloadImage(image); } void initMap(Map* map, const World* world, const Settings* settings) { *map = (Map){ .rect = (Rectangle){0.0, 0.0, settings->mapPreviewWidth, settings->mapPreviewHeight}, .render = LoadRenderTexture(settings->mapPreviewWidth, settings->mapPreviewHeight), .camera = (Camera2D){ .offset = (Vector2){settings->mapPreviewWidth / 2.0, settings->mapPreviewHeight / 2.0}, .target = Vector2Zero(), .rotation = 0.0, .zoom = settings->mapPreviewZoomDefault }, .playerPosition = Vector2Zero(), .isEnabled = settings->isMapPreviewEnabledDefault, .isFullSize = false }; initMapHeightmap(map, world); repositionMap(map); } void drawMapPlayer(Map* map, Player* player, Vector2 position, float width, float height) { Vector2 playerPreview[3] = { (Vector2){0.0, height}, (Vector2){width, -height}, (Vector2){-width, -height} }; // Move player to position. for (int index = 0; index < 3; ++index) { playerPreview[index] = Vector2Rotate(playerPreview[index], player->cameraAngle.x); playerPreview[index] = Vector2Add(playerPreview[index], position); } // Draw triangles. DrawTriangle(playerPreview[0], playerPreview[1], playerPreview[2], BLACK); DrawTriangleLines(playerPreview[0], playerPreview[1], playerPreview[2], WHITE); } void updateMapPreview(Map* map, Game* game) { const Settings* settings = &game->settings; const World* world = &game->world; // Player position. map->playerPosition = (Vector2){ WORLD_IMAGE_WIDTH / world->size.x * game->player.position.x, WORLD_IMAGE_HEIGHT / world->size.z * game->player.position.z }; // Zoom. float mouseScroll = GetMouseWheelMove(); if (mouseScroll != 0.0) { map->camera.zoom = expf(logf(map->camera.zoom) + ((float)GetMouseWheelMove() * 0.1f)); map->camera.zoom = Clamp(map->camera.zoom, MAP_ZOOM_MIN, MAP_ZOOM_MAX); } // Camera follow player. map->camera.target = map->playerPosition; // Draw map scene. BeginTextureMode(map->render); BeginMode2D(map->camera); ClearBackground(BLANK); // Draw height map. DrawTexture(map->heightmap, 0.0, 0.0, (Color){255, 255, 255, settings->mapAlpha}); EndMode2D(); EndTextureMode(); // Draw render texture. DrawTexturePro(map->render.texture, (Rectangle){0.0, 0.0, map->render.texture.width, -map->render.texture.height}, map->rect, (Vector2){0.0, 0.0}, 0.0, WHITE); // Draw player. Vector2 mapCenter = (Vector2){map->rect.x + (map->rect.width / 2.0), map->rect.y + (map->rect.height / 2.0)}; drawMapPlayer(map, &game->player, mapCenter, 3.0, 6.0); DrawRectangleLinesEx(map->rect, 3.0, BLUE); } void updateMap(Map* map, Game* game) { const Settings* settings = &game->settings; // Handle window resize. if (IsWindowResized()) { repositionMap(map); } // Toggle preview. if (IsKeyPressed(settings->toggleMapPreviewKey)) { map->isEnabled = !map->isEnabled; } if (!map->isEnabled) { return; } updateMapPreview(map, game); } void closeMap(Map* map) { UnloadRenderTexture(map->render); UnloadTexture(map->heightmap); }