Skip to content

Instantly share code, notes, and snippets.

@Skaruts
Last active May 13, 2020 21:53
Show Gist options
  • Save Skaruts/dc5d10a69fc5893921e6d528213041e5 to your computer and use it in GitHub Desktop.
Save Skaruts/dc5d10a69fc5893921e6d528213041e5 to your computer and use it in GitHub Desktop.
#*******************************************************************************************
#
# 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