From a7a81ca7492772637c43cb48a92405784872f857 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Wed, 2 Sep 2015 02:41:21 +0200 Subject: [PATCH] Added example: box collisions --- examples/makefile | 5 ++ examples/models_box_collisions.c | 119 +++++++++++++++++++++++++++++ examples/models_box_collisions.png | Bin 0 -> 22077 bytes 3 files changed, 124 insertions(+) create mode 100644 examples/models_box_collisions.c create mode 100644 examples/models_box_collisions.png diff --git a/examples/makefile b/examples/makefile index 15a4bd0ac..dac378cef 100644 --- a/examples/makefile +++ b/examples/makefile @@ -179,6 +179,7 @@ EXAMPLES = \ text_format_text \ text_font_select \ models_geometric_shapes \ + models_box_collisions \ models_billboard \ models_obj_loading \ models_heightmap \ @@ -325,6 +326,10 @@ text_font_select: text_font_select.c models_geometric_shapes: models_geometric_shapes.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) +# compile [models] example - box collisions +models_box_collisions: models_box_collisions.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) + # compile [models] example - basic window models_planes: models_planes.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) diff --git a/examples/models_box_collisions.c b/examples/models_box_collisions.c new file mode 100644 index 000000000..18fca0912 --- /dev/null +++ b/examples/models_box_collisions.c @@ -0,0 +1,119 @@ +/******************************************************************************************* +* +* raylib [models] example - Detect basic 3d collisions (box vs sphere vs box) +* +* This example has been created using raylib 1.3 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2015 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [models] example - box collisions"); + + // Define the camera to look into our 3d world + Camera camera = {{ 0.0, 10.0, 10.0 }, { 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }}; + + Vector3 playerPosition = { 0, 1, 2 }; + Vector3 playerSize = { 1, 2, 1 }; + Color playerColor = GREEN; + + Vector3 enemyBoxPos = { -4, 1, 0 }; + Vector3 enemyBoxSize = { 2, 2, 2 }; + + Vector3 enemySpherePos = { 4, 0, 0 }; + float enemySphereSize = 1.5f; + + bool collision = false; + + 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 + //---------------------------------------------------------------------------------- + + // Move player + if (IsKeyDown(KEY_RIGHT)) playerPosition.x += 0.2f; + else if (IsKeyDown(KEY_LEFT)) playerPosition.x -= 0.2f; + else if (IsKeyDown(KEY_DOWN)) playerPosition.z += 0.2f; + else if (IsKeyDown(KEY_UP)) playerPosition.z -= 0.2f; + + collision = false; + + // Check collisions player vs enemy-box + if (CheckCollisionBoxes((Vector3){ playerPosition.x - playerSize.x/2, + playerPosition.y - playerSize.y/2, + playerPosition.z - playerSize.z/2 }, + (Vector3){ playerPosition.x + playerSize.x/2, + playerPosition.y + playerSize.y/2, + playerPosition.z + playerSize.z/2 }, + (Vector3){ enemyBoxPos.x - enemyBoxSize.x/2, + enemyBoxPos.y - enemyBoxSize.y/2, + enemyBoxPos.z - enemyBoxSize.z/2 }, + (Vector3){ enemyBoxPos.x + enemyBoxSize.x/2, + enemyBoxPos.y + enemyBoxSize.y/2, + enemyBoxPos.z + enemyBoxSize.z/2 })) collision = true; + + // Check collisions player vs enemy-sphere + if (CheckCollisionBoxSphere((Vector3){ playerPosition.x - playerSize.x/2, + playerPosition.y - playerSize.y/2, + playerPosition.z - playerSize.z/2 }, + (Vector3){ playerPosition.x + playerSize.x/2, + playerPosition.y + playerSize.y/2, + playerPosition.z + playerSize.z/2 }, + enemySpherePos, enemySphereSize)) collision = true; + + if (collision) playerColor = RED; + else playerColor = GREEN; + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + Begin3dMode(camera); + + // Draw enemy-box + DrawCube(enemyBoxPos, enemyBoxSize.x, enemyBoxSize.y, enemyBoxSize.z, GRAY); + DrawCubeWires(enemyBoxPos, enemyBoxSize.x, enemyBoxSize.y, enemyBoxSize.z, DARKGRAY); + + // Draw enemy-sphere + DrawSphere(enemySpherePos, enemySphereSize, GRAY); + DrawSphereWires(enemySpherePos, enemySphereSize, 16, 16, DARKGRAY); + + // Draw player + DrawCubeV(playerPosition, playerSize, playerColor); + + DrawGrid(10.0, 1.0); // Draw a grid + + End3dMode(); + + DrawText("Move player with cursors to collide", 220, 40, 20, GRAY); + + DrawFPS(10, 10); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} \ No newline at end of file diff --git a/examples/models_box_collisions.png b/examples/models_box_collisions.png new file mode 100644 index 0000000000000000000000000000000000000000..d01fd9dd28b6109f20aea95c72678c727ff45dcc GIT binary patch literal 22077 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