Merge branch 'raysan5:master' into master
This commit is contained in:
commit
c74aa74731
138 changed files with 1500 additions and 639 deletions
88
.github/workflows/update_examples.yml
vendored
88
.github/workflows/update_examples.yml
vendored
|
|
@ -11,7 +11,7 @@ on:
|
|||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-latest
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
|
@ -22,49 +22,51 @@ jobs:
|
|||
with:
|
||||
version: 'latest'
|
||||
actions-cache-folder: 'emsdk-cache'
|
||||
|
||||
- name: Setup MSBuild
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
|
||||
- name: Clone raylib.com repo to update files
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
git clone https://x-access-token:${GITHUB_TOKEN}@github.com/raysan5/raylib.com.git
|
||||
shell: cmd
|
||||
|
||||
- name: Build and run rexm tool (VS2022 solution)
|
||||
# rexm should update all required files in raylib and even raylib.com repo,
|
||||
# but not sure if it can do that from an Action, maybe it requires manual copy
|
||||
run: |
|
||||
cd tools/rexm/VS2022
|
||||
msbuild.exe rexm.sln /target:rexm /property:Configuration=Release /property:Platform=x64
|
||||
cd ../../..
|
||||
set REXM_EXAMPLES_BASE_PATH="examples"
|
||||
set REXM_EXAMPLES_WEB_PATH="../raylib.com/examples"
|
||||
set REXM_EXAMPLES_TEMPLATE_FILE_PATH="examples/examples_template.c"
|
||||
set REXM_EXAMPLES_TEMPLATE_SCREENSHOT_PATH="examples/examples_template.png"
|
||||
set REXM_EXAMPLES_COLLECTION_FILE_PATH="examples/examples_list.txt"
|
||||
set REXM_EXAMPLES_VS2022_SLN_FILE="projects/VS2022/raylib.sln"
|
||||
set EMSDK_PATH="D:/a/raylib/raylib/emsdk-cache/emsdk-main"
|
||||
.\tools\rexm\VS2022\build\rexm\bin\x64\Release\rexm.exe update
|
||||
cd ../..
|
||||
shell: cmd
|
||||
|
||||
- name: Commit changes to raylib repo
|
||||
run: |
|
||||
#git config user.name "github-actions[bot]"
|
||||
#git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
#git add -A
|
||||
#git commit -m "Update examples collection"
|
||||
#git push
|
||||
|
||||
- name: Push changes to raylib.com repo
|
||||
- name: Clone raylib.com repo to update files
|
||||
run: |
|
||||
git clone https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/raysan5/raylib.com.git
|
||||
shell: bash
|
||||
|
||||
- name: Build and run rexm tool (requires GNU Makefile)
|
||||
# "rexm update" validates and updates all required examples in raylib and even raylib.com repos,
|
||||
# note that it calls examples/Makefile.Web internally, so it requires [make] tool available
|
||||
run: |
|
||||
sudo apt-get update && sudo apt-get install -y libopengl0 libglu1-mesa libx11-dev libxrandr-dev libxcursor-dev libxi-dev libxinerama-dev libgl1-mesa-dev libglu1-mesa-dev
|
||||
cd "${{ github.workspace }}/src"
|
||||
make PLATFORM=PLATFORM_DESKTOP
|
||||
sudo make install
|
||||
make clean
|
||||
make PLATFORM=PLATFORM_WEB
|
||||
cd ../tools/rexm/
|
||||
make
|
||||
export REXM_EXAMPLES_BASE_PATH="${{ github.workspace }}/examples"
|
||||
export REXM_EXAMPLES_WEB_PATH="${{ github.workspace }}/raylib.com/examples"
|
||||
export REXM_EXAMPLES_TEMPLATE_FILE_PATH="${{ github.workspace }}/examples/examples_template.c"
|
||||
export REXM_EXAMPLES_TEMPLATE_SCREENSHOT_PATH="${{ github.workspace }}/examples/examples_template.png"
|
||||
export REXM_EXAMPLES_COLLECTION_FILE_PATH="${{ github.workspace }}/examples/examples_list.txt"
|
||||
export REXM_EXAMPLES_VS2022_SLN_FILE="${{ github.workspace }}/projects/VS2022/raylib.sln"
|
||||
export EMSDK_PATH="${{ github.workspace }}/emsdk-cache/emsdk-main"
|
||||
./rexm update
|
||||
shell: bash
|
||||
|
||||
- name: Commit changes to raylib repo (DISABLED)
|
||||
if: github.event_name == 'push' && false
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
#git config --global user.name "github-actions[bot]"
|
||||
#git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
#git add examples
|
||||
#git commit -m "Update web examples"
|
||||
#git push origin
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
git add -A
|
||||
git commit -m "Update examples collection" || echo "git exited with code 1, nothing changed"
|
||||
git push
|
||||
shell: bash
|
||||
|
||||
- name: Push changes to raylib.com repo (DISABLED)
|
||||
if: github.event_name == 'push' && false
|
||||
run: |
|
||||
cd raylib.com
|
||||
git add -A
|
||||
git commit -m "Update web examples" || echo "git exited with code 1, nothing changed"
|
||||
git push origin
|
||||
shell: bash
|
||||
|
|
|
|||
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -116,3 +116,6 @@ tools/parser/raylib_parser
|
|||
tools/rexm/rexm.exe
|
||||
tools/rexm/rexm
|
||||
|
||||
# CI
|
||||
emsdk-cache/
|
||||
raylib.com/
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ const config_h_flags = outer: {
|
|||
break :outer flags[0..i].*;
|
||||
};
|
||||
|
||||
fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, options: Options) !*std.Build.Step.Compile {
|
||||
pub fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, options: Options) !*std.Build.Step.Compile {
|
||||
var raylib_flags_arr: std.ArrayList([]const u8) = .empty;
|
||||
defer raylib_flags_arr.deinit(b.allocator);
|
||||
|
||||
|
|
|
|||
|
|
@ -507,7 +507,7 @@ CORE = \
|
|||
core/core_3d_camera_free \
|
||||
core/core_3d_camera_mode \
|
||||
core/core_3d_camera_split_screen \
|
||||
core/core_3d_fps_controller \
|
||||
core/core_3d_camera_fps \
|
||||
core/core_3d_picking \
|
||||
core/core_automation_events \
|
||||
core/core_basic_screen_manager \
|
||||
|
|
@ -599,6 +599,7 @@ TEXT = \
|
|||
text/text_raylib_fonts \
|
||||
text/text_rectangle_bounds \
|
||||
text/text_unicode \
|
||||
text/text_unicode_ranges \
|
||||
text/text_writing_anim
|
||||
|
||||
MODELS = \
|
||||
|
|
|
|||
|
|
@ -507,7 +507,7 @@ CORE = \
|
|||
core/core_3d_camera_free \
|
||||
core/core_3d_camera_mode \
|
||||
core/core_3d_camera_split_screen \
|
||||
core/core_3d_fps_controller \
|
||||
core/core_3d_camera_fps \
|
||||
core/core_3d_picking \
|
||||
core/core_automation_events \
|
||||
core/core_basic_screen_manager \
|
||||
|
|
@ -599,6 +599,7 @@ TEXT = \
|
|||
text/text_raylib_fonts \
|
||||
text/text_rectangle_bounds \
|
||||
text/text_unicode \
|
||||
text/text_unicode_ranges \
|
||||
text/text_writing_anim
|
||||
|
||||
MODELS = \
|
||||
|
|
@ -703,7 +704,7 @@ core/core_3d_camera_mode: core/core_3d_camera_mode.c
|
|||
core/core_3d_camera_split_screen: core/core_3d_camera_split_screen.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
core/core_3d_fps_controller: core/core_3d_fps_controller.c
|
||||
core/core_3d_camera_fps: core/core_3d_camera_fps.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
core/core_3d_picking: core/core_3d_picking.c
|
||||
|
|
@ -999,14 +1000,14 @@ text/text_input_box: text/text_input_box.c
|
|||
|
||||
text/text_raylib_fonts: text/text_raylib_fonts.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file text/resources/fonts/alagard.png@resources/fonts/alagard.png \
|
||||
--preload-file text/resources/fonts/pixelplay.png@resources/fonts/pixelplay.png \
|
||||
--preload-file text/resources/fonts/mecha.png@resources/fonts/mecha.png \
|
||||
--preload-file text/resources/fonts/setback.png@resources/fonts/setback.png \
|
||||
--preload-file text/resources/fonts/romulus.png@resources/fonts/romulus.png \
|
||||
--preload-file text/resources/fonts/pixantiqua.png@resources/fonts/pixantiqua.png \
|
||||
--preload-file text/resources/fonts/alpha_beta.png@resources/fonts/alpha_beta.png \
|
||||
--preload-file text/resources/fonts/jupiter_crash.png@resources/fonts/jupiter_crash.png
|
||||
--preload-file text/resources/sprite_fonts/alagard.png@resources/sprite_fonts/alagard.png \
|
||||
--preload-file text/resources/sprite_fonts/pixelplay.png@resources/sprite_fonts/pixelplay.png \
|
||||
--preload-file text/resources/sprite_fonts/mecha.png@resources/sprite_fonts/mecha.png \
|
||||
--preload-file text/resources/sprite_fonts/setback.png@resources/sprite_fonts/setback.png \
|
||||
--preload-file text/resources/sprite_fonts/romulus.png@resources/sprite_fonts/romulus.png \
|
||||
--preload-file text/resources/sprite_fonts/pixantiqua.png@resources/sprite_fonts/pixantiqua.png \
|
||||
--preload-file text/resources/sprite_fonts/alpha_beta.png@resources/sprite_fonts/alpha_beta.png \
|
||||
--preload-file text/resources/sprite_fonts/jupiter_crash.png@resources/sprite_fonts/jupiter_crash.png
|
||||
|
||||
text/text_rectangle_bounds: text/text_rectangle_bounds.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
|
@ -1017,6 +1018,10 @@ text/text_unicode: text/text_unicode.c
|
|||
--preload-file text/resources/noto_cjk.fnt@resources/noto_cjk.fnt \
|
||||
--preload-file text/resources/symbola.fnt@resources/symbola.fnt
|
||||
|
||||
text/text_unicode_ranges: text/text_unicode_ranges.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) \
|
||||
--preload-file text/resources/NotoSansTC-Regular.ttf@resources/NotoSansTC-Regular.ttf
|
||||
|
||||
text/text_writing_anim: text/text_writing_anim.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ You may find it easier to use than other toolchains, especially when it comes to
|
|||
- `zig build [module]` to compile all examples for a module (e.g. `zig build core`)
|
||||
- `zig build [example]` to compile _and run_ a particular example (e.g. `zig build core_basic_window`)
|
||||
|
||||
## EXAMPLES COLLECTION [TOTAL: 161]
|
||||
## EXAMPLES COLLECTION [TOTAL: 162]
|
||||
|
||||
### category: core [37]
|
||||
|
||||
|
|
@ -40,7 +40,7 @@ Examples using raylib[core](../src/rcore.c) platform functionality like window c
|
|||
| [core_3d_camera_free](core/core_3d_camera_free.c) | <img src="core/core_3d_camera_free.png" alt="core_3d_camera_free" width="80"> | ⭐☆☆☆ | 1.3 | 1.3 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [core_3d_camera_first_person](core/core_3d_camera_first_person.c) | <img src="core/core_3d_camera_first_person.png" alt="core_3d_camera_first_person" width="80"> | ⭐⭐☆☆ | 1.3 | 1.3 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [core_3d_camera_split_screen](core/core_3d_camera_split_screen.c) | <img src="core/core_3d_camera_split_screen.png" alt="core_3d_camera_split_screen" width="80"> | ⭐⭐⭐☆ | 3.7 | 4.0 | [Jeffery Myers](https://github.com/JeffM2501) |
|
||||
| [core_3d_fps_controller](core/core_3d_fps_controller.c) | <img src="core/core_3d_fps_controller.png" alt="core_3d_fps_controller" width="80"> | ⭐⭐⭐☆ | 5.5 | 5.5 | [Agnis Aldins](https://github.com/nezvers) |
|
||||
| [core_3d_camera_fps](core/core_3d_camera_fps.c) | <img src="core/core_3d_camera_fps.png" alt="core_3d_camera_fps" width="80"> | ⭐⭐⭐☆ | 5.5 | 5.5 | [Agnis Aldins](https://github.com/nezvers) |
|
||||
| [core_3d_picking](core/core_3d_picking.c) | <img src="core/core_3d_picking.png" alt="core_3d_picking" width="80"> | ⭐⭐☆☆ | 1.3 | 4.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [core_world_screen](core/core_world_screen.c) | <img src="core/core_world_screen.png" alt="core_world_screen" width="80"> | ⭐⭐☆☆ | 1.3 | 1.4 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [core_custom_logging](core/core_custom_logging.c) | <img src="core/core_custom_logging.png" alt="core_custom_logging" width="80"> | ⭐⭐⭐☆ | 2.5 | 2.5 | [Pablo Marcos Oltra](https://github.com/pamarcos) |
|
||||
|
|
@ -122,7 +122,7 @@ Examples using raylib textures functionality, including image/textures loading/g
|
|||
| [textures_image_rotate](textures/textures_image_rotate.c) | <img src="textures/textures_image_rotate.png" alt="textures_image_rotate" width="80"> | ⭐⭐☆☆ | 1.0 | 1.0 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [textures_textured_curve](textures/textures_textured_curve.c) | <img src="textures/textures_textured_curve.png" alt="textures_textured_curve" width="80"> | ⭐⭐⭐☆ | 4.5 | 4.5 | [Jeffery Myers](https://github.com/JeffM2501) |
|
||||
|
||||
### category: text [12]
|
||||
### category: text [13]
|
||||
|
||||
Examples using raylib text functionality, including sprite fonts loading/generation and text drawing, provided by raylib [text](../src/rtext.c) module.
|
||||
|
||||
|
|
@ -140,6 +140,7 @@ Examples using raylib text functionality, including sprite fonts loading/generat
|
|||
| [text_unicode](text/text_unicode.c) | <img src="text/text_unicode.png" alt="text_unicode" width="80"> | ⭐⭐⭐⭐️ | 2.5 | 4.0 | [Vlad Adrian](https://github.com/demizdor) |
|
||||
| [text_draw_3d](text/text_draw_3d.c) | <img src="text/text_draw_3d.png" alt="text_draw_3d" width="80"> | ⭐⭐⭐⭐️ | 3.5 | 4.0 | [Vlad Adrian](https://github.com/demizdor) |
|
||||
| [text_codepoints_loading](text/text_codepoints_loading.c) | <img src="text/text_codepoints_loading.png" alt="text_codepoints_loading" width="80"> | ⭐⭐⭐☆ | 4.2 | 4.2 | [Ramon Santamaria](https://github.com/raysan5) |
|
||||
| [text_unicode_ranges](text/text_unicode_ranges.c) | <img src="text/text_unicode_ranges.png" alt="text_unicode_ranges" width="80"> | ⭐⭐⭐⭐️ | 2.5 | 4.0 | [Vlad Adrian](https://github.com/demizdor) |
|
||||
|
||||
### category: models [23]
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ int main(void)
|
|||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [audio] example - processing mixed output");
|
||||
InitWindow(screenWidth, screenHeight, "raylib [audio] example - mixed audio processing");
|
||||
|
||||
InitAudioDevice(); // Initialize audio device
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [audio] example - Module playing (streaming)
|
||||
* raylib [audio] example - module playing (streaming)
|
||||
*
|
||||
* Example complexity rating: [★☆☆☆] 1/4
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [audio] example - Music playing (streaming)
|
||||
* raylib [audio] example - music playing (streaming)
|
||||
*
|
||||
* Example complexity rating: [★☆☆☆] 1/4
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [audio] example - Raw audio streaming
|
||||
* raylib [audio] example - raw audio streaming
|
||||
*
|
||||
* Example complexity rating: [★★★☆] 3/4
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [audio] example - Sound loading and playing
|
||||
* raylib [audio] example - sound loading and playing
|
||||
*
|
||||
* Example complexity rating: [★☆☆☆] 1/4
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [audio] example - spatialized 3D sound
|
||||
* raylib [audio] example - 3d sound positioning
|
||||
*
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
|
|
@ -32,7 +32,7 @@ int main(void)
|
|||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [audio] example - spatialized 3D sound");
|
||||
InitWindow(screenWidth, screenHeight, "raylib [audio] example - 3d sound positioning");
|
||||
|
||||
InitAudioDevice();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [audio] example - Music stream processing effects
|
||||
* raylib [audio] example - stream effects
|
||||
*
|
||||
* Example complexity rating: [★★★★] 4/4
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - 2D Camera system
|
||||
* raylib [core] example - 2d camera
|
||||
*
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - 2D Camera platformer
|
||||
* raylib [core] example - 2d camera platformer
|
||||
*
|
||||
* Example complexity rating: [★★★☆] 3/4
|
||||
*
|
||||
|
|
@ -54,7 +54,7 @@ int main(void)
|
|||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - 2d camera");
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - 2d camera platformer");
|
||||
|
||||
Player player = { 0 };
|
||||
player.position = (Vector2){ 400, 280 };
|
||||
|
|
|
|||
330
examples/core/core_3d_camera_fps.c
Normal file
330
examples/core/core_3d_camera_fps.c
Normal file
|
|
@ -0,0 +1,330 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - 3d first-person camera controller
|
||||
*
|
||||
* Example complexity rating: [★★★☆] 3/4
|
||||
*
|
||||
* Example originally created with raylib 5.5, last time updated with raylib 5.5
|
||||
*
|
||||
* Example contributed by Agnis Aldins (@nezvers) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2025-2025 Agnis Aldins (@nezvers)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include "raymath.h"
|
||||
#include "rcamera.h"
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Defines and Macros
|
||||
//----------------------------------------------------------------------------------
|
||||
// Movement constants
|
||||
#define GRAVITY 32.0f
|
||||
#define MAX_SPEED 20.0f
|
||||
#define CROUCH_SPEED 5.0f
|
||||
#define JUMP_FORCE 12.0f
|
||||
#define MAX_ACCEL 150.0f
|
||||
// Grounded drag
|
||||
#define FRICTION 0.86f
|
||||
// Increasing air drag, increases strafing speed
|
||||
#define AIR_DRAG 0.98f
|
||||
// Responsiveness for turning movement direction to looked direction
|
||||
#define CONTROL 15.0f
|
||||
#define CROUCH_HEIGHT 0.0f
|
||||
#define STAND_HEIGHT 1.0f
|
||||
#define BOTTOM_HEIGHT 0.5f
|
||||
|
||||
#define NORMALIZE_INPUT 0
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
// Body structure
|
||||
typedef struct {
|
||||
Vector3 position;
|
||||
Vector3 velocity;
|
||||
Vector3 dir;
|
||||
bool isGrounded;
|
||||
} Body;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
static Vector2 sensitivity = { 0.001f, 0.001f };
|
||||
|
||||
static Body player = { 0 };
|
||||
static Vector2 lookRotation = { 0 };
|
||||
static float headTimer = 0.0f;
|
||||
static float walkLerp = 0.0f;
|
||||
static float headLerp = STAND_HEIGHT;
|
||||
static Vector2 lean = { 0 };
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module functions declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
static void DrawLevel(void);
|
||||
static void UpdateCameraAngle(Camera *camera);
|
||||
static void UpdateBody(Body *body, float rot, char side, char forward, bool jumpPressed, bool crouchHold);
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d first-person camera controller");
|
||||
|
||||
// Initialize camera variables
|
||||
// NOTE: UpdateCameraAngle() takes care of the rest
|
||||
Camera camera = { 0 };
|
||||
camera.fovy = 60.0f;
|
||||
camera.projection = CAMERA_PERSPECTIVE;
|
||||
camera.position = (Vector3){
|
||||
player.position.x,
|
||||
player.position.y + (BOTTOM_HEIGHT + headLerp),
|
||||
player.position.z,
|
||||
};
|
||||
|
||||
UpdateCameraAngle(&camera); // Update camera parameters
|
||||
|
||||
DisableCursor(); // Limit cursor to relative movement inside the window
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
Vector2 mouseDelta = GetMouseDelta();
|
||||
lookRotation.x -= mouseDelta.x*sensitivity.x;
|
||||
lookRotation.y += mouseDelta.y*sensitivity.y;
|
||||
|
||||
char sideway = (IsKeyDown(KEY_D) - IsKeyDown(KEY_A));
|
||||
char forward = (IsKeyDown(KEY_W) - IsKeyDown(KEY_S));
|
||||
bool crouching = IsKeyDown(KEY_LEFT_CONTROL);
|
||||
UpdateBody(&player, lookRotation.x, sideway, forward, IsKeyPressed(KEY_SPACE), crouching);
|
||||
|
||||
float delta = GetFrameTime();
|
||||
headLerp = Lerp(headLerp, (crouching ? CROUCH_HEIGHT : STAND_HEIGHT), 20.0f*delta);
|
||||
camera.position = (Vector3){
|
||||
player.position.x,
|
||||
player.position.y + (BOTTOM_HEIGHT + headLerp),
|
||||
player.position.z,
|
||||
};
|
||||
|
||||
if (player.isGrounded && ((forward != 0) || (sideway != 0)))
|
||||
{
|
||||
headTimer += delta*3.0f;
|
||||
walkLerp = Lerp(walkLerp, 1.0f, 10.0f*delta);
|
||||
camera.fovy = Lerp(camera.fovy, 55.0f, 5.0f*delta);
|
||||
}
|
||||
else
|
||||
{
|
||||
walkLerp = Lerp(walkLerp, 0.0f, 10.0f*delta);
|
||||
camera.fovy = Lerp(camera.fovy, 60.0f, 5.0f*delta);
|
||||
}
|
||||
|
||||
lean.x = Lerp(lean.x, sideway*0.02f, 10.0f*delta);
|
||||
lean.y = Lerp(lean.y, forward*0.015f, 10.0f*delta);
|
||||
|
||||
UpdateCameraAngle(&camera);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
BeginMode3D(camera);
|
||||
DrawLevel();
|
||||
EndMode3D();
|
||||
|
||||
// Draw info box
|
||||
DrawRectangle(5, 5, 330, 75, Fade(SKYBLUE, 0.5f));
|
||||
DrawRectangleLines(5, 5, 330, 75, BLUE);
|
||||
|
||||
DrawText("Camera controls:", 15, 15, 10, BLACK);
|
||||
DrawText("- Move keys: W, A, S, D, Space, Left-Ctrl", 15, 30, 10, BLACK);
|
||||
DrawText("- Look around: arrow keys or mouse", 15, 45, 10, BLACK);
|
||||
DrawText(TextFormat("- Velocity Len: (%06.3f)", Vector2Length((Vector2){ player.velocity.x, player.velocity.z })), 15, 60, 10, BLACK);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module functions definition
|
||||
//----------------------------------------------------------------------------------
|
||||
void UpdateBody(Body* body, float rot, char side, char forward, bool jumpPressed, bool crouchHold)
|
||||
{
|
||||
Vector2 input = (Vector2){ (float)side, (float)-forward };
|
||||
|
||||
#if defined(NORMALIZE_INPUT)
|
||||
// Slow down diagonal movement
|
||||
if ((side != 0) && (forward != 0)) input = Vector2Normalize(input);
|
||||
#endif
|
||||
|
||||
float delta = GetFrameTime();
|
||||
|
||||
if (!body->isGrounded) body->velocity.y -= GRAVITY*delta;
|
||||
|
||||
if (body->isGrounded && jumpPressed)
|
||||
{
|
||||
body->velocity.y = JUMP_FORCE;
|
||||
body->isGrounded = false;
|
||||
|
||||
// Sound can be played at this moment
|
||||
//SetSoundPitch(fxJump, 1.0f + (GetRandomValue(-100, 100)*0.001));
|
||||
//PlaySound(fxJump);
|
||||
}
|
||||
|
||||
Vector3 front = (Vector3){ sin(rot), 0.f, cos(rot) };
|
||||
Vector3 right = (Vector3){ cos(-rot), 0.f, sin(-rot) };
|
||||
|
||||
Vector3 desiredDir = (Vector3){ input.x*right.x + input.y*front.x, 0.0f, input.x*right.z + input.y*front.z, };
|
||||
body->dir = Vector3Lerp(body->dir, desiredDir, CONTROL*delta);
|
||||
|
||||
float decel = (body->isGrounded ? FRICTION : AIR_DRAG);
|
||||
Vector3 hvel = (Vector3){ body->velocity.x*decel, 0.0f, body->velocity.z*decel };
|
||||
|
||||
float hvelLength = Vector3Length(hvel); // Magnitude
|
||||
if (hvelLength < (MAX_SPEED*0.01f)) hvel = (Vector3){ 0 };
|
||||
|
||||
// This is what creates strafing
|
||||
float speed = Vector3DotProduct(hvel, body->dir);
|
||||
|
||||
// Whenever the amount of acceleration to add is clamped by the maximum acceleration constant,
|
||||
// a Player can make the speed faster by bringing the direction closer to horizontal velocity angle
|
||||
// More info here: https://youtu.be/v3zT3Z5apaM?t=165
|
||||
float maxSpeed = (crouchHold? CROUCH_SPEED : MAX_SPEED);
|
||||
float accel = Clamp(maxSpeed - speed, 0.f, MAX_ACCEL*delta);
|
||||
hvel.x += body->dir.x*accel;
|
||||
hvel.z += body->dir.z*accel;
|
||||
|
||||
body->velocity.x = hvel.x;
|
||||
body->velocity.z = hvel.z;
|
||||
|
||||
body->position.x += body->velocity.x*delta;
|
||||
body->position.y += body->velocity.y*delta;
|
||||
body->position.z += body->velocity.z*delta;
|
||||
|
||||
// Fancy collision system against the floor
|
||||
if (body->position.y <= 0.0f)
|
||||
{
|
||||
body->position.y = 0.0f;
|
||||
body->velocity.y = 0.0f;
|
||||
body->isGrounded = true; // Enable jumping
|
||||
}
|
||||
}
|
||||
|
||||
// Update camera
|
||||
static void UpdateCameraAngle(Camera *camera)
|
||||
{
|
||||
const Vector3 up = (Vector3){ 0.0f, 1.0f, 0.0f };
|
||||
const Vector3 targetOffset = (Vector3){ 0.0f, 0.0f, -1.0f };
|
||||
|
||||
// Left and right
|
||||
Vector3 yaw = Vector3RotateByAxisAngle(targetOffset, up, lookRotation.x);
|
||||
|
||||
// Clamp view up
|
||||
float maxAngleUp = Vector3Angle(up, yaw);
|
||||
maxAngleUp -= 0.001f; // Avoid numerical errors
|
||||
if ( -(lookRotation.y) > maxAngleUp) { lookRotation.y = -maxAngleUp; }
|
||||
|
||||
// Clamp view down
|
||||
float maxAngleDown = Vector3Angle(Vector3Negate(up), yaw);
|
||||
maxAngleDown *= -1.0f; // Downwards angle is negative
|
||||
maxAngleDown += 0.001f; // Avoid numerical errors
|
||||
if ( -(lookRotation.y) < maxAngleDown) { lookRotation.y = -maxAngleDown; }
|
||||
|
||||
// Up and down
|
||||
Vector3 right = Vector3Normalize(Vector3CrossProduct(yaw, up));
|
||||
|
||||
// Rotate view vector around right axis
|
||||
float pitchAngle = -lookRotation.y -
|
||||
lean.y;
|
||||
pitchAngle = Clamp(pitchAngle, -PI / 2 + 0.0001f, PI / 2 - 0.0001f); // Clamp angle so it doesn't go past straight up or straight down
|
||||
Vector3 pitch = Vector3RotateByAxisAngle(yaw, right, pitchAngle);
|
||||
|
||||
// Head animation
|
||||
// Rotate up direction around forward axis
|
||||
float headSin = sin(headTimer*PI);
|
||||
float headCos = cos(headTimer*PI);
|
||||
const float stepRotation = 0.01f;
|
||||
camera->up = Vector3RotateByAxisAngle(up, pitch, headSin*stepRotation + lean.x);
|
||||
|
||||
// Camera BOB
|
||||
const float bobSide = 0.1f;
|
||||
const float bobUp = 0.15f;
|
||||
Vector3 bobbing = Vector3Scale(right, headSin*bobSide);
|
||||
bobbing.y = fabsf(headCos*bobUp);
|
||||
|
||||
camera->position = Vector3Add(camera->position, Vector3Scale(bobbing, walkLerp));
|
||||
camera->target = Vector3Add(camera->position, pitch);
|
||||
}
|
||||
|
||||
// Draw game level
|
||||
static void DrawLevel(void)
|
||||
{
|
||||
const int floorExtent = 25;
|
||||
const float tileSize = 5.0f;
|
||||
const Color tileColor1 = (Color){ 150, 200, 200, 255 };
|
||||
|
||||
// Floor tiles
|
||||
for (int y = -floorExtent; y < floorExtent; y++)
|
||||
{
|
||||
for (int x = -floorExtent; x < floorExtent; x++)
|
||||
{
|
||||
if ((y & 1) && (x & 1))
|
||||
{
|
||||
DrawPlane((Vector3){ x*tileSize, 0.0f, y*tileSize}, (Vector2){ tileSize, tileSize }, tileColor1);
|
||||
}
|
||||
else if (!(y & 1) && !(x & 1))
|
||||
{
|
||||
DrawPlane((Vector3){ x*tileSize, 0.0f, y*tileSize}, (Vector2){ tileSize, tileSize }, LIGHTGRAY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const Vector3 towerSize = (Vector3){ 16.0f, 32.0f, 16.0f };
|
||||
const Color towerColor = (Color){ 150, 200, 200, 255 };
|
||||
|
||||
Vector3 towerPos = (Vector3){ 16.0f, 16.0f, 16.0f };
|
||||
DrawCubeV(towerPos, towerSize, towerColor);
|
||||
DrawCubeWiresV(towerPos, towerSize, DARKBLUE);
|
||||
|
||||
towerPos.x *= -1;
|
||||
DrawCubeV(towerPos, towerSize, towerColor);
|
||||
DrawCubeWiresV(towerPos, towerSize, DARKBLUE);
|
||||
|
||||
towerPos.z *= -1;
|
||||
DrawCubeV(towerPos, towerSize, towerColor);
|
||||
DrawCubeWiresV(towerPos, towerSize, DARKBLUE);
|
||||
|
||||
towerPos.x *= -1;
|
||||
DrawCubeV(towerPos, towerSize, towerColor);
|
||||
DrawCubeWiresV(towerPos, towerSize, DARKBLUE);
|
||||
|
||||
// Red sun
|
||||
DrawSphere((Vector3){ 300.0f, 300.0f, 0.0f }, 100.0f, (Color){ 255, 0, 0, 255 });
|
||||
}
|
||||
BIN
examples/core/core_3d_camera_fps.png
Normal file
BIN
examples/core/core_3d_camera_fps.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.9 KiB |
|
|
@ -1,6 +1,6 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Initialize 3d camera free
|
||||
* raylib [core] example - 3d camera free
|
||||
*
|
||||
* Example complexity rating: [★☆☆☆] 1/4
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Initialize 3d camera mode
|
||||
* raylib [core] example - 3d camera mode
|
||||
*
|
||||
* Example complexity rating: [★☆☆☆] 1/4
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - 3d cmaera split screen
|
||||
* raylib [core] example - 3d camera split screen
|
||||
*
|
||||
* Example complexity rating: [★★★☆] 3/4
|
||||
*
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue