Last active
May 13, 2020 21:53
-
-
Save Skaruts/dc5d10a69fc5893921e6d528213041e5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#******************************************************************************************* | |
# | |
# raylib [models] example - first person maze | |
# | |
# This example has been created using raylib 2.5 (www.raylib.com) | |
# raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) | |
# | |
# Copyright (c) 2019 Ramon Santamaria (@raysan5) | |
# | |
#*******************************************************************************************/ | |
import raylib, system/[ansi_c] | |
#include <stdlib.h> # Required for: free() | |
# Initialization | |
#-------------------------------------------------------------------------------------- | |
const screenWidth = 800 | |
const screenHeight = 450 | |
InitWindow(screenWidth, screenHeight, "raylib [models] example - first person maze") | |
# Define the camera to look into our 3d world | |
var camera = Camera( | |
position: Vector3(x: 0.2, y: 0.4, z: 0.2), | |
target: Vector3(x: 0.0, y: 0.0, z: 0.0), | |
up: Vector3(x: 0.0, y: 1.0, z: 0.0), | |
fovy: 45.0, | |
typex: 0 | |
) | |
let imMap = LoadImage("resources/cubicmap.png") # Load cubicmap image (RAM) | |
let cubicmap = LoadTextureFromImage(imMap) # Convert image to texture to display (VRAM) | |
let mesh = GenMeshCubicmap(imMap, Vector3(x: 1.0, y: 1.0, z: 1.0)) | |
# NOTE: By default each cube is mapped to one part of texture atlas | |
let texture = LoadTexture("resources/cubicmap_atlas.png") # Load map texture | |
let model = LoadModelFromMesh(mesh) | |
# model.materials[0].maps[MAP_DIFFUSE].texture = texture # <--- Original line | |
let mats = cast[ptr UncheckedArray[Material]](model.materials) | |
let maps = cast[ptr UncheckedArray[MaterialMap]](mats[0].maps) | |
maps[MAP_DIFFUSE.int].texture = texture # Set map diffuse texture | |
# Get map image data to be used for collision detection | |
let mapPixels = cast[ptr UncheckedArray[Color]](GetImageData(imMap)) | |
UnloadImage(imMap) # Unload image from RAM | |
let mapPosition = Vector3(x: -16.0, y: 0.0, z: -8.0) # Set model position | |
let playerPosition = camera.position # Set player position | |
SetCameraMode(camera, CAMERA_FIRST_PERSON) # Set camera mode | |
SetTargetFPS(60) # Set our game to run at 60 frames-per-second | |
#-------------------------------------------------------------------------------------- | |
# Main game loop | |
while not WindowShouldClose(): # Detect window close button or ESC key | |
# Update | |
#---------------------------------------------------------------------------------- | |
let oldCamPos = camera.position # Store old camera position | |
UpdateCamera(camera.addr) # Update camera | |
# Check player collision (we simplify to 2D collision detection) | |
let playerPos = Vector2(x: camera.position.x, y: camera.position.z) | |
let playerRadius = 0.1 # Collision radius (player is modelled as a cilinder for collision) | |
var playerCellX = int(playerPos.x - mapPosition.x + 0.5) | |
var playerCellY = int(playerPos.y - mapPosition.z + 0.5) | |
# Out-of-limits security check | |
if playerCellX < 0: playerCellX = 0 | |
elif playerCellX >= cubicmap.width: playerCellX = cubicmap.width - 1 | |
if playerCellY < 0: playerCellY = 0 | |
elif playerCellY >= cubicmap.height: playerCellY = cubicmap.height - 1 | |
# Check map collisions using image data and player position | |
# TODO: Improvement: Just check player surrounding cells for collision | |
for y in 0..<cubicmap.height: | |
for x in 0..<cubicmap.width: | |
if mapPixels[y*cubicmap.width + x].r == 255 and | |
CheckCollisionCircleRec( playerPos, playerRadius, | |
Rectangle(x: mapPosition.x - 0.5 + x.float*1.0, y: mapPosition.z - 0.5 + y.float*1.0, width: 1.0, height: 1.0) | |
): | |
# Collision detected, reset camera position | |
camera.position = oldCamPos | |
#---------------------------------------------------------------------------------- | |
# Draw | |
#---------------------------------------------------------------------------------- | |
BeginDrawing() | |
ClearBackground(RAYWHITE) | |
BeginMode3D(camera) | |
DrawModel(model, mapPosition, 1.0, WHITE) # Draw maze map | |
#DrawCubeV(playerPosition, Vector3(x: 0.2, y: 0.4, z: 0.2), RED) # Draw player | |
DrawGrid(100, 1.0) # TODO (Skaruts): delete this (it's just a temporary way to see something on screen) | |
EndMode3D() | |
DrawTextureEx(cubicmap, Vector2(x: float(GetScreenWidth() - cubicmap.width*4) - 20.0, y: 20.0), 0.0, 4.0, WHITE) | |
DrawRectangleLines(GetScreenWidth() - cubicmap.width*4 - 20, 20, cubicmap.width*4, cubicmap.height*4, GREEN) | |
# Draw player position radar | |
DrawRectangle(GetScreenWidth() - cubicmap.width*4 - 20 + playerCellX*4, 20 + playerCellY*4, 4, 4, RED) | |
DrawFPS(10, 10) | |
EndDrawing() | |
#---------------------------------------------------------------------------------- | |
# De-Initialization | |
#-------------------------------------------------------------------------------------- | |
c_free(mapPixels) # Unload color array # TODO: is this how to free a 'ptr UncheckedArray'? | |
UnloadTexture(cubicmap) # Unload cubicmap texture | |
UnloadTexture(texture) # Unload map texture | |
UnloadModel(model) # Unload map model | |
CloseWindow() # Close window and OpenGL context | |
#-------------------------------------------------------------------------------------- |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment