convert submodules to normal folders for now
5757
raylib/examples/shapes/raygui.h
Normal file
263
raylib/examples/shapes/reasings.h
Normal file
|
|
@ -0,0 +1,263 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* reasings - raylib easings library, based on Robert Penner library
|
||||
*
|
||||
* Useful easing functions for values animation
|
||||
*
|
||||
* This header uses:
|
||||
* #define REASINGS_STATIC_INLINE // Inlines all functions code, so it runs faster.
|
||||
* // This requires lots of memory on system.
|
||||
* How to use:
|
||||
* The four inputs t,b,c,d are defined as follows:
|
||||
* t = current time (in any unit measure, but same unit as duration)
|
||||
* b = starting value to interpolate
|
||||
* c = the total change in value of b that needs to occur
|
||||
* d = total time it should take to complete (duration)
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* int currentTime = 0;
|
||||
* int duration = 100;
|
||||
* float startPositionX = 0.0f;
|
||||
* float finalPositionX = 30.0f;
|
||||
* float currentPositionX = startPositionX;
|
||||
*
|
||||
* while (currentPositionX < finalPositionX)
|
||||
* {
|
||||
* currentPositionX = EaseSineIn(currentTime, startPositionX, finalPositionX - startPositionX, duration);
|
||||
* currentTime++;
|
||||
* }
|
||||
*
|
||||
* A port of Robert Penner's easing equations to C (http://robertpenner.com/easing/)
|
||||
*
|
||||
* Robert Penner License
|
||||
* ---------------------------------------------------------------------------------
|
||||
* Open source under the BSD License.
|
||||
*
|
||||
* Copyright (c) 2001 Robert Penner. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* - Neither the name of the author nor the names of contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ---------------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (c) 2015-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose, including commercial
|
||||
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim that you
|
||||
* wrote the original software. If you use this software in a product, an acknowledgment
|
||||
* in the product documentation would be appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
|
||||
* as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#ifndef REASINGS_H
|
||||
#define REASINGS_H
|
||||
|
||||
#define REASINGS_STATIC_INLINE // NOTE: By default, compile functions as static inline
|
||||
|
||||
#if defined(REASINGS_STATIC_INLINE)
|
||||
#define EASEDEF static inline
|
||||
#else
|
||||
#define EASEDEF extern
|
||||
#endif
|
||||
|
||||
#include <math.h> // Required for: sinf(), cosf(), sqrtf(), powf()
|
||||
|
||||
#ifndef PI
|
||||
#define PI 3.14159265358979323846f //Required as PI is not always defined in math.h
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" { // Prevents name mangling of functions
|
||||
#endif
|
||||
|
||||
// Linear Easing functions
|
||||
EASEDEF float EaseLinearNone(float t, float b, float c, float d) { return (c*t/d + b); } // Ease: Linear
|
||||
EASEDEF float EaseLinearIn(float t, float b, float c, float d) { return (c*t/d + b); } // Ease: Linear In
|
||||
EASEDEF float EaseLinearOut(float t, float b, float c, float d) { return (c*t/d + b); } // Ease: Linear Out
|
||||
EASEDEF float EaseLinearInOut(float t, float b, float c, float d) { return (c*t/d + b); } // Ease: Linear In Out
|
||||
|
||||
// Sine Easing functions
|
||||
EASEDEF float EaseSineIn(float t, float b, float c, float d) { return (-c*cosf(t/d*(PI/2.0f)) + c + b); } // Ease: Sine In
|
||||
EASEDEF float EaseSineOut(float t, float b, float c, float d) { return (c*sinf(t/d*(PI/2.0f)) + b); } // Ease: Sine Out
|
||||
EASEDEF float EaseSineInOut(float t, float b, float c, float d) { return (-c/2.0f*(cosf(PI*t/d) - 1.0f) + b); } // Ease: Sine In Out
|
||||
|
||||
// Circular Easing functions
|
||||
EASEDEF float EaseCircIn(float t, float b, float c, float d) { t /= d; return (-c*(sqrtf(1.0f - t*t) - 1.0f) + b); } // Ease: Circular In
|
||||
EASEDEF float EaseCircOut(float t, float b, float c, float d) { t = t/d - 1.0f; return (c*sqrtf(1.0f - t*t) + b); } // Ease: Circular Out
|
||||
EASEDEF float EaseCircInOut(float t, float b, float c, float d) // Ease: Circular In Out
|
||||
{
|
||||
if ((t/=d/2.0f) < 1.0f) return (-c/2.0f*(sqrtf(1.0f - t*t) - 1.0f) + b);
|
||||
t -= 2.0f; return (c/2.0f*(sqrtf(1.0f - t*t) + 1.0f) + b);
|
||||
}
|
||||
|
||||
// Cubic Easing functions
|
||||
EASEDEF float EaseCubicIn(float t, float b, float c, float d) { t /= d; return (c*t*t*t + b); } // Ease: Cubic In
|
||||
EASEDEF float EaseCubicOut(float t, float b, float c, float d) { t = t/d - 1.0f; return (c*(t*t*t + 1.0f) + b); } // Ease: Cubic Out
|
||||
EASEDEF float EaseCubicInOut(float t, float b, float c, float d) // Ease: Cubic In Out
|
||||
{
|
||||
if ((t/=d/2.0f) < 1.0f) return (c/2.0f*t*t*t + b);
|
||||
t -= 2.0f; return (c/2.0f*(t*t*t + 2.0f) + b);
|
||||
}
|
||||
|
||||
// Quadratic Easing functions
|
||||
EASEDEF float EaseQuadIn(float t, float b, float c, float d) { t /= d; return (c*t*t + b); } // Ease: Quadratic In
|
||||
EASEDEF float EaseQuadOut(float t, float b, float c, float d) { t /= d; return (-c*t*(t - 2.0f) + b); } // Ease: Quadratic Out
|
||||
EASEDEF float EaseQuadInOut(float t, float b, float c, float d) // Ease: Quadratic In Out
|
||||
{
|
||||
if ((t/=d/2) < 1) return (((c/2)*(t*t)) + b);
|
||||
return (-c/2.0f*(((t - 1.0f)*(t - 3.0f)) - 1.0f) + b);
|
||||
}
|
||||
|
||||
// Exponential Easing functions
|
||||
EASEDEF float EaseExpoIn(float t, float b, float c, float d) { return (t == 0.0f) ? b : (c*powf(2.0f, 10.0f*(t/d - 1.0f)) + b); } // Ease: Exponential In
|
||||
EASEDEF float EaseExpoOut(float t, float b, float c, float d) { return (t == d) ? (b + c) : (c*(-powf(2.0f, -10.0f*t/d) + 1.0f) + b); } // Ease: Exponential Out
|
||||
EASEDEF float EaseExpoInOut(float t, float b, float c, float d) // Ease: Exponential In Out
|
||||
{
|
||||
if (t == 0.0f) return b;
|
||||
if (t == d) return (b + c);
|
||||
if ((t/=d/2.0f) < 1.0f) return (c/2.0f*powf(2.0f, 10.0f*(t - 1.0f)) + b);
|
||||
|
||||
return (c/2.0f*(-powf(2.0f, -10.0f*(t - 1.0f)) + 2.0f) + b);
|
||||
}
|
||||
|
||||
// Back Easing functions
|
||||
EASEDEF float EaseBackIn(float t, float b, float c, float d) // Ease: Back In
|
||||
{
|
||||
float s = 1.70158f;
|
||||
float postFix = t/=d;
|
||||
return (c*(postFix)*t*((s + 1.0f)*t - s) + b);
|
||||
}
|
||||
|
||||
EASEDEF float EaseBackOut(float t, float b, float c, float d) // Ease: Back Out
|
||||
{
|
||||
float s = 1.70158f;
|
||||
t = t/d - 1.0f;
|
||||
return (c*(t*t*((s + 1.0f)*t + s) + 1.0f) + b);
|
||||
}
|
||||
|
||||
EASEDEF float EaseBackInOut(float t, float b, float c, float d) // Ease: Back In Out
|
||||
{
|
||||
float s = 1.70158f;
|
||||
if ((t/=d/2.0f) < 1.0f)
|
||||
{
|
||||
s *= 1.525f;
|
||||
return (c/2.0f*(t*t*((s + 1.0f)*t - s)) + b);
|
||||
}
|
||||
|
||||
float postFix = t-=2.0f;
|
||||
s *= 1.525f;
|
||||
return (c/2.0f*((postFix)*t*((s + 1.0f)*t + s) + 2.0f) + b);
|
||||
}
|
||||
|
||||
// Bounce Easing functions
|
||||
EASEDEF float EaseBounceOut(float t, float b, float c, float d) // Ease: Bounce Out
|
||||
{
|
||||
if ((t/=d) < (1.0f/2.75f))
|
||||
{
|
||||
return (c*(7.5625f*t*t) + b);
|
||||
}
|
||||
else if (t < (2.0f/2.75f))
|
||||
{
|
||||
float postFix = t-=(1.5f/2.75f);
|
||||
return (c*(7.5625f*(postFix)*t + 0.75f) + b);
|
||||
}
|
||||
else if (t < (2.5/2.75))
|
||||
{
|
||||
float postFix = t-=(2.25f/2.75f);
|
||||
return (c*(7.5625f*(postFix)*t + 0.9375f) + b);
|
||||
}
|
||||
else
|
||||
{
|
||||
float postFix = t-=(2.625f/2.75f);
|
||||
return (c*(7.5625f*(postFix)*t + 0.984375f) + b);
|
||||
}
|
||||
}
|
||||
|
||||
EASEDEF float EaseBounceIn(float t, float b, float c, float d) { return (c - EaseBounceOut(d - t, 0.0f, c, d) + b); } // Ease: Bounce In
|
||||
EASEDEF float EaseBounceInOut(float t, float b, float c, float d) // Ease: Bounce In Out
|
||||
{
|
||||
if (t < d/2.0f) return (EaseBounceIn(t*2.0f, 0.0f, c, d)*0.5f + b);
|
||||
else return (EaseBounceOut(t*2.0f - d, 0.0f, c, d)*0.5f + c*0.5f + b);
|
||||
}
|
||||
|
||||
// Elastic Easing functions
|
||||
EASEDEF float EaseElasticIn(float t, float b, float c, float d) // Ease: Elastic In
|
||||
{
|
||||
if (t == 0.0f) return b;
|
||||
if ((t/=d) == 1.0f) return (b + c);
|
||||
|
||||
float p = d*0.3f;
|
||||
float a = c;
|
||||
float s = p/4.0f;
|
||||
float postFix = a*powf(2.0f, 10.0f*(t-=1.0f));
|
||||
|
||||
return (-(postFix*sinf((t*d-s)*(2.0f*PI)/p )) + b);
|
||||
}
|
||||
|
||||
EASEDEF float EaseElasticOut(float t, float b, float c, float d) // Ease: Elastic Out
|
||||
{
|
||||
if (t == 0.0f) return b;
|
||||
if ((t/=d) == 1.0f) return (b + c);
|
||||
|
||||
float p = d*0.3f;
|
||||
float a = c;
|
||||
float s = p/4.0f;
|
||||
|
||||
return (a*powf(2.0f,-10.0f*t)*sinf((t*d-s)*(2.0f*PI)/p) + c + b);
|
||||
}
|
||||
|
||||
EASEDEF float EaseElasticInOut(float t, float b, float c, float d) // Ease: Elastic In Out
|
||||
{
|
||||
if (t == 0.0f) return b;
|
||||
if ((t/=d/2.0f) == 2.0f) return (b + c);
|
||||
|
||||
float p = d*(0.3f*1.5f);
|
||||
float a = c;
|
||||
float s = p/4.0f;
|
||||
|
||||
if (t < 1.0f)
|
||||
{
|
||||
float postFix = a*powf(2.0f, 10.0f*(t-=1.0f));
|
||||
return -0.5f*(postFix*sinf((t*d-s)*(2.0f*PI)/p)) + b;
|
||||
}
|
||||
|
||||
float postFix = a*powf(2.0f, -10.0f*(t-=1.0f));
|
||||
|
||||
return (postFix*sinf((t*d-s)*(2.0f*PI)/p)*0.5f + c + b);
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // REASINGS_H
|
||||
0
raylib/examples/shapes/resources/.gitkeep
Normal file
86
raylib/examples/shapes/shapes_basic_shapes.c
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - Draw basic shapes 2d (rectangle, circle, line...)
|
||||
*
|
||||
* Example originally created with raylib 1.0, last time updated with raylib 4.2
|
||||
*
|
||||
* 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) 2014-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - basic shapes drawing");
|
||||
|
||||
float rotation = 0.0f;
|
||||
|
||||
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
|
||||
//----------------------------------------------------------------------------------
|
||||
rotation += 0.2f;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawText("some basic shapes available on raylib", 20, 20, 20, DARKGRAY);
|
||||
|
||||
// Circle shapes and lines
|
||||
DrawCircle(screenWidth/5, 120, 35, DARKBLUE);
|
||||
DrawCircleGradient(screenWidth/5, 220, 60, GREEN, SKYBLUE);
|
||||
DrawCircleLines(screenWidth/5, 340, 80, DARKBLUE);
|
||||
|
||||
// Rectangle shapes and lines
|
||||
DrawRectangle(screenWidth/4*2 - 60, 100, 120, 60, RED);
|
||||
DrawRectangleGradientH(screenWidth/4*2 - 90, 170, 180, 130, MAROON, GOLD);
|
||||
DrawRectangleLines(screenWidth/4*2 - 40, 320, 80, 60, ORANGE); // NOTE: Uses QUADS internally, not lines
|
||||
|
||||
// Triangle shapes and lines
|
||||
DrawTriangle((Vector2){ screenWidth/4.0f *3.0f, 80.0f },
|
||||
(Vector2){ screenWidth/4.0f *3.0f - 60.0f, 150.0f },
|
||||
(Vector2){ screenWidth/4.0f *3.0f + 60.0f, 150.0f }, VIOLET);
|
||||
|
||||
DrawTriangleLines((Vector2){ screenWidth/4.0f*3.0f, 160.0f },
|
||||
(Vector2){ screenWidth/4.0f*3.0f - 20.0f, 230.0f },
|
||||
(Vector2){ screenWidth/4.0f*3.0f + 20.0f, 230.0f }, DARKBLUE);
|
||||
|
||||
// Polygon shapes and lines
|
||||
DrawPoly((Vector2){ screenWidth/4.0f*3, 330 }, 6, 80, rotation, BROWN);
|
||||
DrawPolyLines((Vector2){ screenWidth/4.0f*3, 330 }, 6, 90, rotation, BROWN);
|
||||
DrawPolyLinesEx((Vector2){ screenWidth/4.0f*3, 330 }, 6, 85, rotation, 6, BEIGE);
|
||||
|
||||
// NOTE: We draw all LINES based shapes together to optimize internal drawing,
|
||||
// this way, all LINES are rendered in a single draw pass
|
||||
DrawLine(18, 42, screenWidth - 18, 42, BLACK);
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/shapes/shapes_basic_shapes.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
82
raylib/examples/shapes/shapes_bouncing_ball.c
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - bouncing ball
|
||||
*
|
||||
* Example originally created with raylib 2.5, last time updated with raylib 2.5
|
||||
*
|
||||
* 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) 2013-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//---------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
SetConfigFlags(FLAG_MSAA_4X_HINT);
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - bouncing ball");
|
||||
|
||||
Vector2 ballPosition = { GetScreenWidth()/2.0f, GetScreenHeight()/2.0f };
|
||||
Vector2 ballSpeed = { 5.0f, 4.0f };
|
||||
int ballRadius = 20;
|
||||
|
||||
bool pause = 0;
|
||||
int framesCounter = 0;
|
||||
|
||||
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
|
||||
//-----------------------------------------------------
|
||||
if (IsKeyPressed(KEY_SPACE)) pause = !pause;
|
||||
|
||||
if (!pause)
|
||||
{
|
||||
ballPosition.x += ballSpeed.x;
|
||||
ballPosition.y += ballSpeed.y;
|
||||
|
||||
// Check walls collision for bouncing
|
||||
if ((ballPosition.x >= (GetScreenWidth() - ballRadius)) || (ballPosition.x <= ballRadius)) ballSpeed.x *= -1.0f;
|
||||
if ((ballPosition.y >= (GetScreenHeight() - ballRadius)) || (ballPosition.y <= ballRadius)) ballSpeed.y *= -1.0f;
|
||||
}
|
||||
else framesCounter++;
|
||||
//-----------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//-----------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawCircleV(ballPosition, (float)ballRadius, MAROON);
|
||||
DrawText("PRESS SPACE to PAUSE BALL MOVEMENT", 10, GetScreenHeight() - 25, 20, LIGHTGRAY);
|
||||
|
||||
// On pause, we draw a blinking message
|
||||
if (pause && ((framesCounter/30)%2)) DrawText("PAUSED", 350, 200, 30, GRAY);
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//-----------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//---------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//----------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/shapes/shapes_bouncing_ball.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
117
raylib/examples/shapes/shapes_collision_area.c
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - collision area
|
||||
*
|
||||
* Example originally created with raylib 2.5, last time updated with raylib 2.5
|
||||
*
|
||||
* 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) 2013-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include <stdlib.h> // Required for: abs()
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//---------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - collision area");
|
||||
|
||||
// Box A: Moving box
|
||||
Rectangle boxA = { 10, GetScreenHeight()/2.0f - 50, 200, 100 };
|
||||
int boxASpeedX = 4;
|
||||
|
||||
// Box B: Mouse moved box
|
||||
Rectangle boxB = { GetScreenWidth()/2.0f - 30, GetScreenHeight()/2.0f - 30, 60, 60 };
|
||||
|
||||
Rectangle boxCollision = { 0 }; // Collision rectangle
|
||||
|
||||
int screenUpperLimit = 40; // Top menu limits
|
||||
|
||||
bool pause = false; // Movement pause
|
||||
bool collision = false; // Collision detection
|
||||
|
||||
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 box if not paused
|
||||
if (!pause) boxA.x += boxASpeedX;
|
||||
|
||||
// Bounce box on x screen limits
|
||||
if (((boxA.x + boxA.width) >= GetScreenWidth()) || (boxA.x <= 0)) boxASpeedX *= -1;
|
||||
|
||||
// Update player-controlled-box (box02)
|
||||
boxB.x = GetMouseX() - boxB.width/2;
|
||||
boxB.y = GetMouseY() - boxB.height/2;
|
||||
|
||||
// Make sure Box B does not go out of move area limits
|
||||
if ((boxB.x + boxB.width) >= GetScreenWidth()) boxB.x = GetScreenWidth() - boxB.width;
|
||||
else if (boxB.x <= 0) boxB.x = 0;
|
||||
|
||||
if ((boxB.y + boxB.height) >= GetScreenHeight()) boxB.y = GetScreenHeight() - boxB.height;
|
||||
else if (boxB.y <= screenUpperLimit) boxB.y = (float)screenUpperLimit;
|
||||
|
||||
// Check boxes collision
|
||||
collision = CheckCollisionRecs(boxA, boxB);
|
||||
|
||||
// Get collision rectangle (only on collision)
|
||||
if (collision) boxCollision = GetCollisionRec(boxA, boxB);
|
||||
|
||||
// Pause Box A movement
|
||||
if (IsKeyPressed(KEY_SPACE)) pause = !pause;
|
||||
//-----------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//-----------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawRectangle(0, 0, screenWidth, screenUpperLimit, collision? RED : BLACK);
|
||||
|
||||
DrawRectangleRec(boxA, GOLD);
|
||||
DrawRectangleRec(boxB, BLUE);
|
||||
|
||||
if (collision)
|
||||
{
|
||||
// Draw collision area
|
||||
DrawRectangleRec(boxCollision, LIME);
|
||||
|
||||
// Draw collision message
|
||||
DrawText("COLLISION!", GetScreenWidth()/2 - MeasureText("COLLISION!", 20)/2, screenUpperLimit/2 - 10, 20, BLACK);
|
||||
|
||||
// Draw collision area
|
||||
DrawText(TextFormat("Collision Area: %i", (int)boxCollision.width*(int)boxCollision.height), GetScreenWidth()/2 - 100, screenUpperLimit + 10, 20, BLACK);
|
||||
}
|
||||
|
||||
// Draw help instructions
|
||||
DrawText("Press SPACE to PAUSE/RESUME", 20, screenHeight - 35, 20, LIGHTGRAY);
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//-----------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//---------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//----------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/shapes/shapes_collision_area.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
104
raylib/examples/shapes/shapes_colors_palette.c
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - Colors palette
|
||||
*
|
||||
* Example originally created with raylib 1.0, last time updated with raylib 2.5
|
||||
*
|
||||
* 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) 2014-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#define MAX_COLORS_COUNT 21 // Number of colors available
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - colors palette");
|
||||
|
||||
Color colors[MAX_COLORS_COUNT] = {
|
||||
DARKGRAY, MAROON, ORANGE, DARKGREEN, DARKBLUE, DARKPURPLE, DARKBROWN,
|
||||
GRAY, RED, GOLD, LIME, BLUE, VIOLET, BROWN, LIGHTGRAY, PINK, YELLOW,
|
||||
GREEN, SKYBLUE, PURPLE, BEIGE };
|
||||
|
||||
const char *colorNames[MAX_COLORS_COUNT] = {
|
||||
"DARKGRAY", "MAROON", "ORANGE", "DARKGREEN", "DARKBLUE", "DARKPURPLE",
|
||||
"DARKBROWN", "GRAY", "RED", "GOLD", "LIME", "BLUE", "VIOLET", "BROWN",
|
||||
"LIGHTGRAY", "PINK", "YELLOW", "GREEN", "SKYBLUE", "PURPLE", "BEIGE" };
|
||||
|
||||
Rectangle colorsRecs[MAX_COLORS_COUNT] = { 0 }; // Rectangles array
|
||||
|
||||
// Fills colorsRecs data (for every rectangle)
|
||||
for (int i = 0; i < MAX_COLORS_COUNT; i++)
|
||||
{
|
||||
colorsRecs[i].x = 20.0f + 100.0f *(i%7) + 10.0f *(i%7);
|
||||
colorsRecs[i].y = 80.0f + 100.0f *(i/7) + 10.0f *(i/7);
|
||||
colorsRecs[i].width = 100.0f;
|
||||
colorsRecs[i].height = 100.0f;
|
||||
}
|
||||
|
||||
int colorState[MAX_COLORS_COUNT] = { 0 }; // Color state: 0-DEFAULT, 1-MOUSE_HOVER
|
||||
|
||||
Vector2 mousePoint = { 0.0f, 0.0f };
|
||||
|
||||
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
|
||||
//----------------------------------------------------------------------------------
|
||||
mousePoint = GetMousePosition();
|
||||
|
||||
for (int i = 0; i < MAX_COLORS_COUNT; i++)
|
||||
{
|
||||
if (CheckCollisionPointRec(mousePoint, colorsRecs[i])) colorState[i] = 1;
|
||||
else colorState[i] = 0;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawText("raylib colors palette", 28, 42, 20, BLACK);
|
||||
DrawText("press SPACE to see all colors", GetScreenWidth() - 180, GetScreenHeight() - 40, 10, GRAY);
|
||||
|
||||
for (int i = 0; i < MAX_COLORS_COUNT; i++) // Draw all rectangles
|
||||
{
|
||||
DrawRectangleRec(colorsRecs[i], Fade(colors[i], colorState[i]? 0.6f : 1.0f));
|
||||
|
||||
if (IsKeyDown(KEY_SPACE) || colorState[i])
|
||||
{
|
||||
DrawRectangle((int)colorsRecs[i].x, (int)(colorsRecs[i].y + colorsRecs[i].height - 26), (int)colorsRecs[i].width, 20, BLACK);
|
||||
DrawRectangleLinesEx(colorsRecs[i], 6, Fade(BLACK, 0.3f));
|
||||
DrawText(colorNames[i], (int)(colorsRecs[i].x + colorsRecs[i].width - MeasureText(colorNames[i], 10) - 12),
|
||||
(int)(colorsRecs[i].y + colorsRecs[i].height - 20), 10, colors[i]);
|
||||
}
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/shapes/shapes_colors_palette.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
88
raylib/examples/shapes/shapes_draw_circle_sector.c
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - draw circle sector (with gui options)
|
||||
*
|
||||
* Example originally created with raylib 2.5, last time updated with raylib 2.5
|
||||
*
|
||||
* Example contributed by Vlad Adrian (@demizdor) 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) 2018-2024 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include <raylib.h>
|
||||
|
||||
#define RAYGUI_IMPLEMENTATION
|
||||
#include "raygui.h" // Required for GUI controls
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - draw circle sector");
|
||||
|
||||
Vector2 center = {(GetScreenWidth() - 300)/2.0f, GetScreenHeight()/2.0f };
|
||||
|
||||
float outerRadius = 180.0f;
|
||||
float startAngle = 0.0f;
|
||||
float endAngle = 180.0f;
|
||||
float segments = 10.0f;
|
||||
float minSegments = 4;
|
||||
|
||||
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
|
||||
//----------------------------------------------------------------------------------
|
||||
// NOTE: All variables update happens inside GUI control functions
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawLine(500, 0, 500, GetScreenHeight(), Fade(LIGHTGRAY, 0.6f));
|
||||
DrawRectangle(500, 0, GetScreenWidth() - 500, GetScreenHeight(), Fade(LIGHTGRAY, 0.3f));
|
||||
|
||||
DrawCircleSector(center, outerRadius, startAngle, endAngle, (int)segments, Fade(MAROON, 0.3f));
|
||||
DrawCircleSectorLines(center, outerRadius, startAngle, endAngle, (int)segments, Fade(MAROON, 0.6f));
|
||||
|
||||
// Draw GUI controls
|
||||
//------------------------------------------------------------------------------
|
||||
GuiSliderBar((Rectangle){ 600, 40, 120, 20}, "StartAngle", TextFormat("%.2f", startAngle), &startAngle, 0, 720);
|
||||
GuiSliderBar((Rectangle){ 600, 70, 120, 20}, "EndAngle", TextFormat("%.2f", endAngle), &endAngle, 0, 720);
|
||||
|
||||
GuiSliderBar((Rectangle){ 600, 140, 120, 20}, "Radius", TextFormat("%.2f", outerRadius), &outerRadius, 0, 200);
|
||||
GuiSliderBar((Rectangle){ 600, 170, 120, 20}, "Segments", TextFormat("%.2f", segments), &segments, 0, 100);
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
minSegments = truncf(ceilf((endAngle - startAngle) / 90));
|
||||
DrawText(TextFormat("MODE: %s", (segments >= minSegments)? "MANUAL" : "AUTO"), 600, 200, 10, (segments >= minSegments)? MAROON : DARKGRAY);
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/shapes/shapes_draw_circle_sector.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
94
raylib/examples/shapes/shapes_draw_rectangle_rounded.c
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - draw rectangle rounded (with gui options)
|
||||
*
|
||||
* Example originally created with raylib 2.5, last time updated with raylib 2.5
|
||||
*
|
||||
* Example contributed by Vlad Adrian (@demizdor) 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) 2018-2024 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include <raylib.h>
|
||||
|
||||
#define RAYGUI_IMPLEMENTATION
|
||||
#include "raygui.h" // Required for GUI controls
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - draw rectangle rounded");
|
||||
|
||||
float roundness = 0.2f;
|
||||
float width = 200.0f;
|
||||
float height = 100.0f;
|
||||
float segments = 0.0f;
|
||||
float lineThick = 1.0f;
|
||||
|
||||
bool drawRect = false;
|
||||
bool drawRoundedRect = true;
|
||||
bool drawRoundedLines = 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
|
||||
//----------------------------------------------------------------------------------
|
||||
Rectangle rec = { ((float)GetScreenWidth() - width - 250)/2, (GetScreenHeight() - height)/2.0f, (float)width, (float)height };
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawLine(560, 0, 560, GetScreenHeight(), Fade(LIGHTGRAY, 0.6f));
|
||||
DrawRectangle(560, 0, GetScreenWidth() - 500, GetScreenHeight(), Fade(LIGHTGRAY, 0.3f));
|
||||
|
||||
if (drawRect) DrawRectangleRec(rec, Fade(GOLD, 0.6f));
|
||||
if (drawRoundedRect) DrawRectangleRounded(rec, roundness, (int)segments, Fade(MAROON, 0.2f));
|
||||
if (drawRoundedLines) DrawRectangleRoundedLinesEx(rec, roundness, (int)segments, lineThick, Fade(MAROON, 0.4f));
|
||||
|
||||
// Draw GUI controls
|
||||
//------------------------------------------------------------------------------
|
||||
GuiSliderBar((Rectangle){ 640, 40, 105, 20 }, "Width", TextFormat("%.2f", width), &width, 0, (float)GetScreenWidth() - 300);
|
||||
GuiSliderBar((Rectangle){ 640, 70, 105, 20 }, "Height", TextFormat("%.2f", height), &height, 0, (float)GetScreenHeight() - 50);
|
||||
GuiSliderBar((Rectangle){ 640, 140, 105, 20 }, "Roundness", TextFormat("%.2f", roundness), &roundness, 0.0f, 1.0f);
|
||||
GuiSliderBar((Rectangle){ 640, 170, 105, 20 }, "Thickness", TextFormat("%.2f", lineThick), &lineThick, 0, 20);
|
||||
GuiSliderBar((Rectangle){ 640, 240, 105, 20}, "Segments", TextFormat("%.2f", segments), &segments, 0, 60);
|
||||
|
||||
GuiCheckBox((Rectangle){ 640, 320, 20, 20 }, "DrawRoundedRect", &drawRoundedRect);
|
||||
GuiCheckBox((Rectangle){ 640, 350, 20, 20 }, "DrawRoundedLines", &drawRoundedLines);
|
||||
GuiCheckBox((Rectangle){ 640, 380, 20, 20}, "DrawRect", &drawRect);
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
DrawText(TextFormat("MODE: %s", (segments >= 4)? "MANUAL" : "AUTO"), 640, 280, 10, (segments >= 4)? MAROON : DARKGRAY);
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/shapes/shapes_draw_rectangle_rounded.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
100
raylib/examples/shapes/shapes_draw_ring.c
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - draw ring (with gui options)
|
||||
*
|
||||
* Example originally created with raylib 2.5, last time updated with raylib 2.5
|
||||
*
|
||||
* Example contributed by Vlad Adrian (@demizdor) 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) 2018-2024 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include <raylib.h>
|
||||
|
||||
#define RAYGUI_IMPLEMENTATION
|
||||
#include "raygui.h" // Required for GUI controls
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - draw ring");
|
||||
|
||||
Vector2 center = {(GetScreenWidth() - 300)/2.0f, GetScreenHeight()/2.0f };
|
||||
|
||||
float innerRadius = 80.0f;
|
||||
float outerRadius = 190.0f;
|
||||
|
||||
float startAngle = 0.0f;
|
||||
float endAngle = 360.0f;
|
||||
float segments = 0.0f;
|
||||
|
||||
bool drawRing = true;
|
||||
bool drawRingLines = false;
|
||||
bool drawCircleLines = 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
|
||||
//----------------------------------------------------------------------------------
|
||||
// NOTE: All variables update happens inside GUI control functions
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawLine(500, 0, 500, GetScreenHeight(), Fade(LIGHTGRAY, 0.6f));
|
||||
DrawRectangle(500, 0, GetScreenWidth() - 500, GetScreenHeight(), Fade(LIGHTGRAY, 0.3f));
|
||||
|
||||
if (drawRing) DrawRing(center, innerRadius, outerRadius, startAngle, endAngle, (int)segments, Fade(MAROON, 0.3f));
|
||||
if (drawRingLines) DrawRingLines(center, innerRadius, outerRadius, startAngle, endAngle, (int)segments, Fade(BLACK, 0.4f));
|
||||
if (drawCircleLines) DrawCircleSectorLines(center, outerRadius, startAngle, endAngle, (int)segments, Fade(BLACK, 0.4f));
|
||||
|
||||
// Draw GUI controls
|
||||
//------------------------------------------------------------------------------
|
||||
GuiSliderBar((Rectangle){ 600, 40, 120, 20 }, "StartAngle", TextFormat("%.2f", startAngle), &startAngle, -450, 450);
|
||||
GuiSliderBar((Rectangle){ 600, 70, 120, 20 }, "EndAngle", TextFormat("%.2f", endAngle), &endAngle, -450, 450);
|
||||
|
||||
GuiSliderBar((Rectangle){ 600, 140, 120, 20 }, "InnerRadius", TextFormat("%.2f", innerRadius), &innerRadius, 0, 100);
|
||||
GuiSliderBar((Rectangle){ 600, 170, 120, 20 }, "OuterRadius", TextFormat("%.2f", outerRadius), &outerRadius, 0, 200);
|
||||
|
||||
GuiSliderBar((Rectangle){ 600, 240, 120, 20 }, "Segments", TextFormat("%.2f", segments), &segments, 0, 100);
|
||||
|
||||
GuiCheckBox((Rectangle){ 600, 320, 20, 20 }, "Draw Ring", &drawRing);
|
||||
GuiCheckBox((Rectangle){ 600, 350, 20, 20 }, "Draw RingLines", &drawRingLines);
|
||||
GuiCheckBox((Rectangle){ 600, 380, 20, 20 }, "Draw CircleLines", &drawCircleLines);
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
int minSegments = (int)ceilf((endAngle - startAngle)/90);
|
||||
DrawText(TextFormat("MODE: %s", (segments >= minSegments)? "MANUAL" : "AUTO"), 600, 270, 10, (segments >= minSegments)? MAROON : DARKGRAY);
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/shapes/shapes_draw_ring.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
115
raylib/examples/shapes/shapes_easings_ball_anim.c
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - easings ball anim
|
||||
*
|
||||
* Example originally created with raylib 2.5, last time updated with raylib 2.5
|
||||
*
|
||||
* 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) 2014-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include "reasings.h" // Required for easing functions
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - easings ball anim");
|
||||
|
||||
// Ball variable value to be animated with easings
|
||||
int ballPositionX = -100;
|
||||
int ballRadius = 20;
|
||||
float ballAlpha = 0.0f;
|
||||
|
||||
int state = 0;
|
||||
int framesCounter = 0;
|
||||
|
||||
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
|
||||
//----------------------------------------------------------------------------------
|
||||
if (state == 0) // Move ball position X with easing
|
||||
{
|
||||
framesCounter++;
|
||||
ballPositionX = (int)EaseElasticOut((float)framesCounter, -100, screenWidth/2.0f + 100, 120);
|
||||
|
||||
if (framesCounter >= 120)
|
||||
{
|
||||
framesCounter = 0;
|
||||
state = 1;
|
||||
}
|
||||
}
|
||||
else if (state == 1) // Increase ball radius with easing
|
||||
{
|
||||
framesCounter++;
|
||||
ballRadius = (int)EaseElasticIn((float)framesCounter, 20, 500, 200);
|
||||
|
||||
if (framesCounter >= 200)
|
||||
{
|
||||
framesCounter = 0;
|
||||
state = 2;
|
||||
}
|
||||
}
|
||||
else if (state == 2) // Change ball alpha with easing (background color blending)
|
||||
{
|
||||
framesCounter++;
|
||||
ballAlpha = EaseCubicOut((float)framesCounter, 0.0f, 1.0f, 200);
|
||||
|
||||
if (framesCounter >= 200)
|
||||
{
|
||||
framesCounter = 0;
|
||||
state = 3;
|
||||
}
|
||||
}
|
||||
else if (state == 3) // Reset state to play again
|
||||
{
|
||||
if (IsKeyPressed(KEY_ENTER))
|
||||
{
|
||||
// Reset required variables to play again
|
||||
ballPositionX = -100;
|
||||
ballRadius = 20;
|
||||
ballAlpha = 0.0f;
|
||||
state = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_R)) framesCounter = 0;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
if (state >= 2) DrawRectangle(0, 0, screenWidth, screenHeight, GREEN);
|
||||
DrawCircle(ballPositionX, 200, (float)ballRadius, Fade(RED, 1.0f - ballAlpha));
|
||||
|
||||
if (state == 3) DrawText("PRESS [ENTER] TO PLAY AGAIN!", 240, 200, 20, BLACK);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/shapes/shapes_easings_ball_anim.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
141
raylib/examples/shapes/shapes_easings_box_anim.c
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - easings box anim
|
||||
*
|
||||
* Example originally created with raylib 2.5, last time updated with raylib 2.5
|
||||
*
|
||||
* 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) 2014-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include "reasings.h" // Required for easing functions
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - easings box anim");
|
||||
|
||||
// Box variables to be animated with easings
|
||||
Rectangle rec = { GetScreenWidth()/2.0f, -100, 100, 100 };
|
||||
float rotation = 0.0f;
|
||||
float alpha = 1.0f;
|
||||
|
||||
int state = 0;
|
||||
int framesCounter = 0;
|
||||
|
||||
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
|
||||
//----------------------------------------------------------------------------------
|
||||
switch (state)
|
||||
{
|
||||
case 0: // Move box down to center of screen
|
||||
{
|
||||
framesCounter++;
|
||||
|
||||
// NOTE: Remember that 3rd parameter of easing function refers to
|
||||
// desired value variation, do not confuse it with expected final value!
|
||||
rec.y = EaseElasticOut((float)framesCounter, -100, GetScreenHeight()/2.0f + 100, 120);
|
||||
|
||||
if (framesCounter >= 120)
|
||||
{
|
||||
framesCounter = 0;
|
||||
state = 1;
|
||||
}
|
||||
} break;
|
||||
case 1: // Scale box to an horizontal bar
|
||||
{
|
||||
framesCounter++;
|
||||
rec.height = EaseBounceOut((float)framesCounter, 100, -90, 120);
|
||||
rec.width = EaseBounceOut((float)framesCounter, 100, (float)GetScreenWidth(), 120);
|
||||
|
||||
if (framesCounter >= 120)
|
||||
{
|
||||
framesCounter = 0;
|
||||
state = 2;
|
||||
}
|
||||
} break;
|
||||
case 2: // Rotate horizontal bar rectangle
|
||||
{
|
||||
framesCounter++;
|
||||
rotation = EaseQuadOut((float)framesCounter, 0.0f, 270.0f, 240);
|
||||
|
||||
if (framesCounter >= 240)
|
||||
{
|
||||
framesCounter = 0;
|
||||
state = 3;
|
||||
}
|
||||
} break;
|
||||
case 3: // Increase bar size to fill all screen
|
||||
{
|
||||
framesCounter++;
|
||||
rec.height = EaseCircOut((float)framesCounter, 10, (float)GetScreenWidth(), 120);
|
||||
|
||||
if (framesCounter >= 120)
|
||||
{
|
||||
framesCounter = 0;
|
||||
state = 4;
|
||||
}
|
||||
} break;
|
||||
case 4: // Fade out animation
|
||||
{
|
||||
framesCounter++;
|
||||
alpha = EaseSineOut((float)framesCounter, 1.0f, -1.0f, 160);
|
||||
|
||||
if (framesCounter >= 160)
|
||||
{
|
||||
framesCounter = 0;
|
||||
state = 5;
|
||||
}
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
// Reset animation at any moment
|
||||
if (IsKeyPressed(KEY_SPACE))
|
||||
{
|
||||
rec = (Rectangle){ GetScreenWidth()/2.0f, -100, 100, 100 };
|
||||
rotation = 0.0f;
|
||||
alpha = 1.0f;
|
||||
state = 0;
|
||||
framesCounter = 0;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawRectanglePro(rec, (Vector2){ rec.width/2, rec.height/2 }, rotation, Fade(BLACK, alpha));
|
||||
|
||||
DrawText("PRESS [SPACE] TO RESET BOX ANIMATION!", 10, GetScreenHeight() - 25, 20, LIGHTGRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/shapes/shapes_easings_box_anim.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
123
raylib/examples/shapes/shapes_easings_rectangle_array.c
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - easings rectangle array
|
||||
*
|
||||
* NOTE: This example requires 'easings.h' library, provided on raylib/src. Just copy
|
||||
* the library to same directory as example or make sure it's available on include path.
|
||||
*
|
||||
* Example originally created with raylib 2.0, last time updated with raylib 2.5
|
||||
*
|
||||
* 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) 2014-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include "reasings.h" // Required for easing functions
|
||||
|
||||
#define RECS_WIDTH 50
|
||||
#define RECS_HEIGHT 50
|
||||
|
||||
#define MAX_RECS_X 800/RECS_WIDTH
|
||||
#define MAX_RECS_Y 450/RECS_HEIGHT
|
||||
|
||||
#define PLAY_TIME_IN_FRAMES 240 // At 60 fps = 4 seconds
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - easings rectangle array");
|
||||
|
||||
Rectangle recs[MAX_RECS_X*MAX_RECS_Y] = { 0 };
|
||||
|
||||
for (int y = 0; y < MAX_RECS_Y; y++)
|
||||
{
|
||||
for (int x = 0; x < MAX_RECS_X; x++)
|
||||
{
|
||||
recs[y*MAX_RECS_X + x].x = RECS_WIDTH/2.0f + RECS_WIDTH*x;
|
||||
recs[y*MAX_RECS_X + x].y = RECS_HEIGHT/2.0f + RECS_HEIGHT*y;
|
||||
recs[y*MAX_RECS_X + x].width = RECS_WIDTH;
|
||||
recs[y*MAX_RECS_X + x].height = RECS_HEIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
float rotation = 0.0f;
|
||||
int framesCounter = 0;
|
||||
int state = 0; // Rectangles animation state: 0-Playing, 1-Finished
|
||||
|
||||
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
|
||||
//----------------------------------------------------------------------------------
|
||||
if (state == 0)
|
||||
{
|
||||
framesCounter++;
|
||||
|
||||
for (int i = 0; i < MAX_RECS_X*MAX_RECS_Y; i++)
|
||||
{
|
||||
recs[i].height = EaseCircOut((float)framesCounter, RECS_HEIGHT, -RECS_HEIGHT, PLAY_TIME_IN_FRAMES);
|
||||
recs[i].width = EaseCircOut((float)framesCounter, RECS_WIDTH, -RECS_WIDTH, PLAY_TIME_IN_FRAMES);
|
||||
|
||||
if (recs[i].height < 0) recs[i].height = 0;
|
||||
if (recs[i].width < 0) recs[i].width = 0;
|
||||
|
||||
if ((recs[i].height == 0) && (recs[i].width == 0)) state = 1; // Finish playing
|
||||
|
||||
rotation = EaseLinearIn((float)framesCounter, 0.0f, 360.0f, PLAY_TIME_IN_FRAMES);
|
||||
}
|
||||
}
|
||||
else if ((state == 1) && IsKeyPressed(KEY_SPACE))
|
||||
{
|
||||
// When animation has finished, press space to restart
|
||||
framesCounter = 0;
|
||||
|
||||
for (int i = 0; i < MAX_RECS_X*MAX_RECS_Y; i++)
|
||||
{
|
||||
recs[i].height = RECS_HEIGHT;
|
||||
recs[i].width = RECS_WIDTH;
|
||||
}
|
||||
|
||||
state = 0;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
if (state == 0)
|
||||
{
|
||||
for (int i = 0; i < MAX_RECS_X*MAX_RECS_Y; i++)
|
||||
{
|
||||
DrawRectanglePro(recs[i], (Vector2){ recs[i].width/2, recs[i].height/2 }, rotation, RED);
|
||||
}
|
||||
}
|
||||
else if (state == 1) DrawText("PRESS [SPACE] TO PLAY AGAIN!", 240, 200, 20, GRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/shapes/shapes_easings_rectangle_array.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
109
raylib/examples/shapes/shapes_following_eyes.c
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - following eyes
|
||||
*
|
||||
* Example originally created with raylib 2.5, last time updated with raylib 2.5
|
||||
*
|
||||
* 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) 2013-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include <math.h> // Required for: atan2f()
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - following eyes");
|
||||
|
||||
Vector2 scleraLeftPosition = { GetScreenWidth()/2.0f - 100.0f, GetScreenHeight()/2.0f };
|
||||
Vector2 scleraRightPosition = { GetScreenWidth()/2.0f + 100.0f, GetScreenHeight()/2.0f };
|
||||
float scleraRadius = 80;
|
||||
|
||||
Vector2 irisLeftPosition = { GetScreenWidth()/2.0f - 100.0f, GetScreenHeight()/2.0f };
|
||||
Vector2 irisRightPosition = { GetScreenWidth()/2.0f + 100.0f, GetScreenHeight()/2.0f };
|
||||
float irisRadius = 24;
|
||||
|
||||
float angle = 0.0f;
|
||||
float dx = 0.0f, dy = 0.0f, dxx = 0.0f, dyy = 0.0f;
|
||||
|
||||
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
|
||||
//----------------------------------------------------------------------------------
|
||||
irisLeftPosition = GetMousePosition();
|
||||
irisRightPosition = GetMousePosition();
|
||||
|
||||
// Check not inside the left eye sclera
|
||||
if (!CheckCollisionPointCircle(irisLeftPosition, scleraLeftPosition, scleraRadius - irisRadius))
|
||||
{
|
||||
dx = irisLeftPosition.x - scleraLeftPosition.x;
|
||||
dy = irisLeftPosition.y - scleraLeftPosition.y;
|
||||
|
||||
angle = atan2f(dy, dx);
|
||||
|
||||
dxx = (scleraRadius - irisRadius)*cosf(angle);
|
||||
dyy = (scleraRadius - irisRadius)*sinf(angle);
|
||||
|
||||
irisLeftPosition.x = scleraLeftPosition.x + dxx;
|
||||
irisLeftPosition.y = scleraLeftPosition.y + dyy;
|
||||
}
|
||||
|
||||
// Check not inside the right eye sclera
|
||||
if (!CheckCollisionPointCircle(irisRightPosition, scleraRightPosition, scleraRadius - irisRadius))
|
||||
{
|
||||
dx = irisRightPosition.x - scleraRightPosition.x;
|
||||
dy = irisRightPosition.y - scleraRightPosition.y;
|
||||
|
||||
angle = atan2f(dy, dx);
|
||||
|
||||
dxx = (scleraRadius - irisRadius)*cosf(angle);
|
||||
dyy = (scleraRadius - irisRadius)*sinf(angle);
|
||||
|
||||
irisRightPosition.x = scleraRightPosition.x + dxx;
|
||||
irisRightPosition.y = scleraRightPosition.y + dyy;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawCircleV(scleraLeftPosition, scleraRadius, LIGHTGRAY);
|
||||
DrawCircleV(irisLeftPosition, irisRadius, BROWN);
|
||||
DrawCircleV(irisLeftPosition, 10, BLACK);
|
||||
|
||||
DrawCircleV(scleraRightPosition, scleraRadius, LIGHTGRAY);
|
||||
DrawCircleV(irisRightPosition, irisRadius, DARKGREEN);
|
||||
DrawCircleV(irisRightPosition, 10, BLACK);
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/shapes/shapes_following_eyes.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
85
raylib/examples/shapes/shapes_lines_bezier.c
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - Cubic-bezier lines
|
||||
*
|
||||
* Example originally created with raylib 1.7, last time updated with raylib 1.7
|
||||
*
|
||||
* 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) 2017-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
SetConfigFlags(FLAG_MSAA_4X_HINT);
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - cubic-bezier lines");
|
||||
|
||||
Vector2 startPoint = { 30, 30 };
|
||||
Vector2 endPoint = { (float)screenWidth - 30, (float)screenHeight - 30 };
|
||||
bool moveStartPoint = false;
|
||||
bool moveEndPoint = 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
|
||||
//----------------------------------------------------------------------------------
|
||||
Vector2 mouse = GetMousePosition();
|
||||
|
||||
if (CheckCollisionPointCircle(mouse, startPoint, 10.0f) && IsMouseButtonDown(MOUSE_BUTTON_LEFT)) moveStartPoint = true;
|
||||
else if (CheckCollisionPointCircle(mouse, endPoint, 10.0f) && IsMouseButtonDown(MOUSE_BUTTON_LEFT)) moveEndPoint = true;
|
||||
|
||||
if (moveStartPoint)
|
||||
{
|
||||
startPoint = mouse;
|
||||
if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) moveStartPoint = false;
|
||||
}
|
||||
|
||||
if (moveEndPoint)
|
||||
{
|
||||
endPoint = mouse;
|
||||
if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) moveEndPoint = false;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawText("MOVE START-END POINTS WITH MOUSE", 15, 20, 20, GRAY);
|
||||
|
||||
// Draw line Cubic Bezier, in-out interpolation (easing), no control points
|
||||
DrawLineBezier(startPoint, endPoint, 4.0f, BLUE);
|
||||
|
||||
// Draw start-end spline circles with some details
|
||||
DrawCircleV(startPoint, CheckCollisionPointCircle(mouse, startPoint, 10.0f)? 14.0f : 8.0f, moveStartPoint? RED : BLUE);
|
||||
DrawCircleV(endPoint, CheckCollisionPointCircle(mouse, endPoint, 10.0f)? 14.0f : 8.0f, moveEndPoint? RED : BLUE);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/shapes/shapes_lines_bezier.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
61
raylib/examples/shapes/shapes_logo_raylib.c
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - Draw raylib logo using basic shapes
|
||||
*
|
||||
* Example originally created with raylib 1.0, last time updated with raylib 1.0
|
||||
*
|
||||
* 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) 2014-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - raylib logo using shapes");
|
||||
|
||||
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
|
||||
//----------------------------------------------------------------------------------
|
||||
// TODO: Update your variables here
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawRectangle(screenWidth/2 - 128, screenHeight/2 - 128, 256, 256, BLACK);
|
||||
DrawRectangle(screenWidth/2 - 112, screenHeight/2 - 112, 224, 224, RAYWHITE);
|
||||
DrawText("raylib", screenWidth/2 - 44, screenHeight/2 + 48, 50, BLACK);
|
||||
|
||||
DrawText("this is NOT a texture!", 350, 370, 10, GRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/shapes/shapes_logo_raylib.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
165
raylib/examples/shapes/shapes_logo_raylib_anim.c
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - raylib logo animation
|
||||
*
|
||||
* Example originally created with raylib 2.5, last time updated with raylib 4.0
|
||||
*
|
||||
* 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) 2014-2024 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - raylib logo animation");
|
||||
|
||||
int logoPositionX = screenWidth/2 - 128;
|
||||
int logoPositionY = screenHeight/2 - 128;
|
||||
|
||||
int framesCounter = 0;
|
||||
int lettersCount = 0;
|
||||
|
||||
int topSideRecWidth = 16;
|
||||
int leftSideRecHeight = 16;
|
||||
|
||||
int bottomSideRecWidth = 16;
|
||||
int rightSideRecHeight = 16;
|
||||
|
||||
int state = 0; // Tracking animation states (State Machine)
|
||||
float alpha = 1.0f; // Useful for fading
|
||||
|
||||
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
|
||||
//----------------------------------------------------------------------------------
|
||||
if (state == 0) // State 0: Small box blinking
|
||||
{
|
||||
framesCounter++;
|
||||
|
||||
if (framesCounter == 120)
|
||||
{
|
||||
state = 1;
|
||||
framesCounter = 0; // Reset counter... will be used later...
|
||||
}
|
||||
}
|
||||
else if (state == 1) // State 1: Top and left bars growing
|
||||
{
|
||||
topSideRecWidth += 4;
|
||||
leftSideRecHeight += 4;
|
||||
|
||||
if (topSideRecWidth == 256) state = 2;
|
||||
}
|
||||
else if (state == 2) // State 2: Bottom and right bars growing
|
||||
{
|
||||
bottomSideRecWidth += 4;
|
||||
rightSideRecHeight += 4;
|
||||
|
||||
if (bottomSideRecWidth == 256) state = 3;
|
||||
}
|
||||
else if (state == 3) // State 3: Letters appearing (one by one)
|
||||
{
|
||||
framesCounter++;
|
||||
|
||||
if (framesCounter/12) // Every 12 frames, one more letter!
|
||||
{
|
||||
lettersCount++;
|
||||
framesCounter = 0;
|
||||
}
|
||||
|
||||
if (lettersCount >= 10) // When all letters have appeared, just fade out everything
|
||||
{
|
||||
alpha -= 0.02f;
|
||||
|
||||
if (alpha <= 0.0f)
|
||||
{
|
||||
alpha = 0.0f;
|
||||
state = 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (state == 4) // State 4: Reset and Replay
|
||||
{
|
||||
if (IsKeyPressed(KEY_R))
|
||||
{
|
||||
framesCounter = 0;
|
||||
lettersCount = 0;
|
||||
|
||||
topSideRecWidth = 16;
|
||||
leftSideRecHeight = 16;
|
||||
|
||||
bottomSideRecWidth = 16;
|
||||
rightSideRecHeight = 16;
|
||||
|
||||
alpha = 1.0f;
|
||||
state = 0; // Return to State 0
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
if (state == 0)
|
||||
{
|
||||
if ((framesCounter/15)%2) DrawRectangle(logoPositionX, logoPositionY, 16, 16, BLACK);
|
||||
}
|
||||
else if (state == 1)
|
||||
{
|
||||
DrawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, BLACK);
|
||||
DrawRectangle(logoPositionX, logoPositionY, 16, leftSideRecHeight, BLACK);
|
||||
}
|
||||
else if (state == 2)
|
||||
{
|
||||
DrawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, BLACK);
|
||||
DrawRectangle(logoPositionX, logoPositionY, 16, leftSideRecHeight, BLACK);
|
||||
|
||||
DrawRectangle(logoPositionX + 240, logoPositionY, 16, rightSideRecHeight, BLACK);
|
||||
DrawRectangle(logoPositionX, logoPositionY + 240, bottomSideRecWidth, 16, BLACK);
|
||||
}
|
||||
else if (state == 3)
|
||||
{
|
||||
DrawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, Fade(BLACK, alpha));
|
||||
DrawRectangle(logoPositionX, logoPositionY + 16, 16, leftSideRecHeight - 32, Fade(BLACK, alpha));
|
||||
|
||||
DrawRectangle(logoPositionX + 240, logoPositionY + 16, 16, rightSideRecHeight - 32, Fade(BLACK, alpha));
|
||||
DrawRectangle(logoPositionX, logoPositionY + 240, bottomSideRecWidth, 16, Fade(BLACK, alpha));
|
||||
|
||||
DrawRectangle(GetScreenWidth()/2 - 112, GetScreenHeight()/2 - 112, 224, 224, Fade(RAYWHITE, alpha));
|
||||
|
||||
DrawText(TextSubtext("raylib", 0, lettersCount), GetScreenWidth()/2 - 44, GetScreenHeight()/2 + 48, 50, Fade(BLACK, alpha));
|
||||
}
|
||||
else if (state == 4)
|
||||
{
|
||||
DrawText("[R] REPLAY", 340, 200, 20, GRAY);
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/shapes/shapes_logo_raylib_anim.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
330
raylib/examples/shapes/shapes_rectangle_advanced.c
Normal file
|
|
@ -0,0 +1,330 @@
|
|||
#include "raylib.h"
|
||||
#include "rlgl.h"
|
||||
#include <math.h>
|
||||
|
||||
// Draw rectangle with rounded edges and horizontal gradient, with options to choose side of roundness
|
||||
// Adapted from both `DrawRectangleRounded` and `DrawRectangleGradientH`
|
||||
void DrawRectangleRoundedGradientH(Rectangle rec, float roundnessLeft, float roundnessRight, int segments, Color left, Color right)
|
||||
{
|
||||
// Neither side is rounded
|
||||
if ((roundnessLeft <= 0.0f && roundnessRight <= 0.0f) || (rec.width < 1) || (rec.height < 1 ))
|
||||
{
|
||||
DrawRectangleGradientEx(rec, left, left, right, right);
|
||||
return;
|
||||
}
|
||||
|
||||
if (roundnessLeft >= 1.0f) roundnessLeft = 1.0f;
|
||||
if (roundnessRight >= 1.0f) roundnessRight = 1.0f;
|
||||
|
||||
// Calculate corner radius both from right and left
|
||||
float recSize = rec.width > rec.height ? rec.height : rec.width;
|
||||
float radiusLeft = (recSize*roundnessLeft)/2;
|
||||
float radiusRight = (recSize*roundnessRight)/2;
|
||||
|
||||
if (radiusLeft <= 0.0f) radiusLeft = 0.0f;
|
||||
if (radiusRight <= 0.0f) radiusRight = 0.0f;
|
||||
|
||||
if (radiusRight <= 0.0f && radiusLeft <= 0.0f) return;
|
||||
|
||||
float stepLength = 90.0f/(float)segments;
|
||||
|
||||
/*
|
||||
Diagram Copied here for reference, original at `DrawRectangleRounded` source code
|
||||
|
||||
P0____________________P1
|
||||
/| |\
|
||||
/1| 2 |3\
|
||||
P7 /__|____________________|__\ P2
|
||||
| |P8 P9| |
|
||||
| 8 | 9 | 4 |
|
||||
| __|____________________|__ |
|
||||
P6 \ |P11 P10| / P3
|
||||
\7| 6 |5/
|
||||
\|____________________|/
|
||||
P5 P4
|
||||
*/
|
||||
|
||||
// Coordinates of the 12 points also apdated from `DrawRectangleRounded`
|
||||
const Vector2 point[12] = {
|
||||
// PO, P1, P2
|
||||
{(float)rec.x + radiusLeft, rec.y}, {(float)(rec.x + rec.width) - radiusRight, rec.y}, { rec.x + rec.width, (float)rec.y + radiusRight },
|
||||
// P3, P4
|
||||
{rec.x + rec.width, (float)(rec.y + rec.height) - radiusRight}, {(float)(rec.x + rec.width) - radiusRight, rec.y + rec.height},
|
||||
// P5, P6, P7
|
||||
{(float)rec.x + radiusLeft, rec.y + rec.height}, { rec.x, (float)(rec.y + rec.height) - radiusLeft}, {rec.x, (float)rec.y + radiusLeft},
|
||||
// P8, P9
|
||||
{(float)rec.x + radiusLeft, (float)rec.y + radiusLeft}, {(float)(rec.x + rec.width) - radiusRight, (float)rec.y + radiusRight},
|
||||
// P10, P11
|
||||
{(float)(rec.x + rec.width) - radiusRight, (float)(rec.y + rec.height) - radiusRight}, {(float)rec.x + radiusLeft, (float)(rec.y + rec.height) - radiusLeft}
|
||||
};
|
||||
|
||||
const Vector2 centers[4] = { point[8], point[9], point[10], point[11] };
|
||||
const float angles[4] = { 180.0f, 270.0f, 0.0f, 90.0f };
|
||||
|
||||
#if defined(SUPPORT_QUADS_DRAW_MODE)
|
||||
rlSetTexture(GetShapesTexture().id);
|
||||
Rectangle shapeRect = GetShapesTextureRectangle();
|
||||
|
||||
rlBegin(RL_QUADS);
|
||||
// Draw all the 4 corners: [1] Upper Left Corner, [3] Upper Right Corner, [5] Lower Right Corner, [7] Lower Left Corner
|
||||
for (int k = 0; k < 4; ++k)
|
||||
{
|
||||
Color color;
|
||||
float radius;
|
||||
if (k == 0) color = left, radius = radiusLeft; // [1] Upper Left Corner
|
||||
if (k == 1) color = right, radius = radiusRight; // [3] Upper Right Corner
|
||||
if (k == 2) color = right, radius = radiusRight; // [5] Lower Right Corner
|
||||
if (k == 3) color = left, radius = radiusLeft; // [7] Lower Left Corner
|
||||
float angle = angles[k];
|
||||
const Vector2 center = centers[k];
|
||||
|
||||
for (int i = 0; i < segments/2; i++)
|
||||
{
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height);
|
||||
rlVertex2f(center.x, center.y);
|
||||
|
||||
rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength*2))*radius, center.y + sinf(DEG2RAD*(angle + stepLength*2))*radius);
|
||||
|
||||
rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*radius, center.y + sinf(DEG2RAD*(angle + stepLength))*radius);
|
||||
|
||||
rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*angle)*radius, center.y + sinf(DEG2RAD*angle)*radius);
|
||||
|
||||
angle += (stepLength*2);
|
||||
}
|
||||
|
||||
// End one even segments
|
||||
if ( segments % 2)
|
||||
{
|
||||
rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height);
|
||||
rlVertex2f(center.x, center.y);
|
||||
|
||||
rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*radius, center.y + sinf(DEG2RAD*(angle + stepLength))*radius);
|
||||
|
||||
rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*angle)*radius, center.y + sinf(DEG2RAD*angle)*radius);
|
||||
|
||||
rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height);
|
||||
rlVertex2f(center.x, center.y);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Here we use the `Diagram` to guide ourselves to which point receives what color.
|
||||
//
|
||||
// By choosing the color correctly associated with a pointe the gradient effect
|
||||
// will naturally come from OpenGL interpolation.
|
||||
//
|
||||
|
||||
// [2] Upper Rectangle
|
||||
rlColor4ub(left.r, left.g, left.b, left.a);
|
||||
rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height);
|
||||
rlVertex2f(point[0].x, point[0].y);
|
||||
rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height);
|
||||
rlVertex2f(point[8].x, point[8].y);
|
||||
|
||||
rlColor4ub(right.r, right.g, right.b, right.a);
|
||||
rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height);
|
||||
rlVertex2f(point[9].x, point[9].y);
|
||||
|
||||
rlColor4ub(right.r, right.g, right.b, right.a);
|
||||
rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height);
|
||||
rlVertex2f(point[1].x, point[1].y);
|
||||
|
||||
// [4] Left Rectangle
|
||||
rlColor4ub(right.r, right.g, right.b, right.a);
|
||||
rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height);
|
||||
rlVertex2f(point[2].x, point[2].y);
|
||||
rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height);
|
||||
rlVertex2f(point[9].x, point[9].y);
|
||||
rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height);
|
||||
rlVertex2f(point[10].x, point[10].y);
|
||||
rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height);
|
||||
rlVertex2f(point[3].x, point[3].y);
|
||||
|
||||
// [6] Bottom Rectangle
|
||||
rlColor4ub(left.r, left.g, left.b, left.a);
|
||||
rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height);
|
||||
rlVertex2f(point[11].x, point[11].y);
|
||||
rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height);
|
||||
rlVertex2f(point[5].x, point[5].y);
|
||||
|
||||
rlColor4ub(right.r, right.g, right.b, right.a);
|
||||
rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height);
|
||||
rlVertex2f(point[4].x, point[4].y);
|
||||
rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height);
|
||||
rlVertex2f(point[10].x, point[10].y);
|
||||
|
||||
// [8] left Rectangle
|
||||
rlColor4ub(left.r, left.g, left.b, left.a);
|
||||
rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height);
|
||||
rlVertex2f(point[7].x, point[7].y);
|
||||
rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height);
|
||||
rlVertex2f(point[6].x, point[6].y);
|
||||
rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height);
|
||||
rlVertex2f(point[11].x, point[11].y);
|
||||
rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height);
|
||||
rlVertex2f(point[8].x, point[8].y);
|
||||
|
||||
// [9] Middle Rectangle
|
||||
rlColor4ub(left.r, left.g, left.b, left.a);
|
||||
rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height);
|
||||
rlVertex2f(point[8].x, point[8].y);
|
||||
rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height);
|
||||
rlVertex2f(point[11].x, point[11].y);
|
||||
|
||||
rlColor4ub(right.r, right.g, right.b, right.a);
|
||||
rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height);
|
||||
rlVertex2f(point[10].x, point[10].y);
|
||||
rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height);
|
||||
rlVertex2f(point[9].x, point[9].y);
|
||||
|
||||
rlEnd();
|
||||
rlSetTexture(0);
|
||||
#else
|
||||
|
||||
//
|
||||
// Here we use the `Diagram` to guide ourselves to which point receives what color.
|
||||
//
|
||||
// By choosing the color correctly associated with a pointe the gradient effect
|
||||
// will naturally come from OpenGL interpolation.
|
||||
// But this time instead of Quad, we think in triangles.
|
||||
//
|
||||
|
||||
rlBegin(RL_TRIANGLES);
|
||||
|
||||
// Draw all of the 4 corners: [1] Upper Left Corner, [3] Upper Right Corner, [5] Lower Right Corner, [7] Lower Left Corner
|
||||
for (int k = 0; k < 4; ++k)
|
||||
{
|
||||
Color color;
|
||||
float radius;
|
||||
if (k == 0) color = left, radius = radiusLeft; // [1] Upper Left Corner
|
||||
if (k == 1) color = right, radius = radiusRight; // [3] Upper Right Corner
|
||||
if (k == 2) color = right, radius = radiusRight; // [5] Lower Right Corner
|
||||
if (k == 3) color = left, radius = radiusLeft; // [7] Lower Left Corner
|
||||
float angle = angles[k];
|
||||
const Vector2 center = centers[k];
|
||||
for (int i = 0; i < segments; i++)
|
||||
{
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
rlVertex2f(center.x, center.y);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*radius, center.y + sinf(DEG2RAD*(angle + stepLength))*radius);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*angle)*radius, center.y + sinf(DEG2RAD*angle)*radius);
|
||||
angle += stepLength;
|
||||
}
|
||||
}
|
||||
|
||||
// [2] Upper Rectangle
|
||||
rlColor4ub(left.r, left.g, left.b, left.a);
|
||||
rlVertex2f(point[0].x, point[0].y);
|
||||
rlVertex2f(point[8].x, point[8].y);
|
||||
rlColor4ub(right.r, right.g, right.b, right.a);
|
||||
rlVertex2f(point[9].x, point[9].y);
|
||||
rlVertex2f(point[1].x, point[1].y);
|
||||
rlColor4ub(left.r, left.g, left.b, left.a);
|
||||
rlVertex2f(point[0].x, point[0].y);
|
||||
rlColor4ub(right.r, right.g, right.b, right.a);
|
||||
rlVertex2f(point[9].x, point[9].y);
|
||||
|
||||
// [4] Right Rectangle
|
||||
rlColor4ub(right.r, right.g, right.b, right.a);
|
||||
rlVertex2f(point[9].x, point[9].y);
|
||||
rlVertex2f(point[10].x, point[10].y);
|
||||
rlVertex2f(point[3].x, point[3].y);
|
||||
rlVertex2f(point[2].x, point[2].y);
|
||||
rlVertex2f(point[9].x, point[9].y);
|
||||
rlVertex2f(point[3].x, point[3].y);
|
||||
|
||||
// [6] Bottom Rectangle
|
||||
rlColor4ub(left.r, left.g, left.b, left.a);
|
||||
rlVertex2f(point[11].x, point[11].y);
|
||||
rlVertex2f(point[5].x, point[5].y);
|
||||
rlColor4ub(right.r, right.g, right.b, right.a);
|
||||
rlVertex2f(point[4].x, point[4].y);
|
||||
rlVertex2f(point[10].x, point[10].y);
|
||||
rlColor4ub(left.r, left.g, left.b, left.a);
|
||||
rlVertex2f(point[11].x, point[11].y);
|
||||
rlColor4ub(right.r, right.g, right.b, right.a);
|
||||
rlVertex2f(point[4].x, point[4].y);
|
||||
|
||||
// [8] Left Rectangle
|
||||
rlColor4ub(left.r, left.g, left.b, left.a);
|
||||
rlVertex2f(point[7].x, point[7].y);
|
||||
rlVertex2f(point[6].x, point[6].y);
|
||||
rlVertex2f(point[11].x, point[11].y);
|
||||
rlVertex2f(point[8].x, point[8].y);
|
||||
rlVertex2f(point[7].x, point[7].y);
|
||||
rlVertex2f(point[11].x, point[11].y);
|
||||
|
||||
// [9] Middle Rectangle
|
||||
rlColor4ub(left.r, left.g, left.b, left.a);
|
||||
rlVertex2f(point[8].x, point[8].y);
|
||||
rlVertex2f(point[11].x, point[11].y);
|
||||
rlColor4ub(right.r, right.g, right.b, right.a);
|
||||
rlVertex2f(point[10].x, point[10].y);
|
||||
rlVertex2f(point[9].x, point[9].y);
|
||||
rlColor4ub(left.r, left.g, left.b, left.a);
|
||||
rlVertex2f(point[8].x, point[8].y);
|
||||
rlColor4ub(right.r, right.g, right.b, right.a);
|
||||
rlVertex2f(point[10].x, point[10].y);
|
||||
rlEnd();
|
||||
#endif
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - rectangle avanced");
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update rectangle bounds
|
||||
//----------------------------------------------------------------------------------
|
||||
float width = GetScreenWidth()/2.0f, height = GetScreenHeight()/6.0f;
|
||||
Rectangle rec = {
|
||||
GetScreenWidth() / 2.0f - width/2,
|
||||
GetScreenHeight() / 2.0f - (5)*(height/2),
|
||||
width, height
|
||||
};
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
// Draw All Rectangles with different roundess for each side and different gradients
|
||||
DrawRectangleRoundedGradientH(rec, 0.8f, 0.8f, 36, BLUE, RED);
|
||||
|
||||
rec.y += rec.height + 1;
|
||||
DrawRectangleRoundedGradientH(rec, 0.5f, 1.0f, 36, RED, PINK);
|
||||
|
||||
rec.y += rec.height + 1;
|
||||
DrawRectangleRoundedGradientH(rec, 1.0f, 0.5f, 36, RED, BLUE);
|
||||
|
||||
rec.y += rec.height + 1;
|
||||
DrawRectangleRoundedGradientH(rec, 0.0f, 1.0f, 36, BLUE, BLACK);
|
||||
|
||||
rec.y += rec.height + 1;
|
||||
DrawRectangleRoundedGradientH(rec, 1.0f, 0.0f, 36, BLUE, PINK);
|
||||
EndDrawing();
|
||||
//--------------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
return 0;
|
||||
}
|
||||
|
||||
BIN
raylib/examples/shapes/shapes_rectangle_advanced.png
Normal file
|
After Width: | Height: | Size: 6.7 KiB |
103
raylib/examples/shapes/shapes_rectangle_scaling.c
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - rectangle scaling by mouse
|
||||
*
|
||||
* Example originally created with raylib 2.5, last time updated with raylib 2.5
|
||||
*
|
||||
* Example contributed by Vlad Adrian (@demizdor) 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) 2018-2024 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#define MOUSE_SCALE_MARK_SIZE 12
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - rectangle scaling mouse");
|
||||
|
||||
Rectangle rec = { 100, 100, 200, 80 };
|
||||
|
||||
Vector2 mousePosition = { 0 };
|
||||
|
||||
bool mouseScaleReady = false;
|
||||
bool mouseScaleMode = 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
|
||||
//----------------------------------------------------------------------------------
|
||||
mousePosition = GetMousePosition();
|
||||
|
||||
if (CheckCollisionPointRec(mousePosition, (Rectangle){ rec.x + rec.width - MOUSE_SCALE_MARK_SIZE, rec.y + rec.height - MOUSE_SCALE_MARK_SIZE, MOUSE_SCALE_MARK_SIZE, MOUSE_SCALE_MARK_SIZE }))
|
||||
{
|
||||
mouseScaleReady = true;
|
||||
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) mouseScaleMode = true;
|
||||
}
|
||||
else mouseScaleReady = false;
|
||||
|
||||
if (mouseScaleMode)
|
||||
{
|
||||
mouseScaleReady = true;
|
||||
|
||||
rec.width = (mousePosition.x - rec.x);
|
||||
rec.height = (mousePosition.y - rec.y);
|
||||
|
||||
// Check minimum rec size
|
||||
if (rec.width < MOUSE_SCALE_MARK_SIZE) rec.width = MOUSE_SCALE_MARK_SIZE;
|
||||
if (rec.height < MOUSE_SCALE_MARK_SIZE) rec.height = MOUSE_SCALE_MARK_SIZE;
|
||||
|
||||
// Check maximum rec size
|
||||
if (rec.width > (GetScreenWidth() - rec.x)) rec.width = GetScreenWidth() - rec.x;
|
||||
if (rec.height > (GetScreenHeight() - rec.y)) rec.height = GetScreenHeight() - rec.y;
|
||||
|
||||
if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) mouseScaleMode = false;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawText("Scale rectangle dragging from bottom-right corner!", 10, 10, 20, GRAY);
|
||||
|
||||
DrawRectangleRec(rec, Fade(GREEN, 0.5f));
|
||||
|
||||
if (mouseScaleReady)
|
||||
{
|
||||
DrawRectangleLinesEx(rec, 1, RED);
|
||||
DrawTriangle((Vector2){ rec.x + rec.width - MOUSE_SCALE_MARK_SIZE, rec.y + rec.height },
|
||||
(Vector2){ rec.x + rec.width, rec.y + rec.height },
|
||||
(Vector2){ rec.x + rec.width, rec.y + rec.height - MOUSE_SCALE_MARK_SIZE }, RED);
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/shapes/shapes_rectangle_scaling.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
273
raylib/examples/shapes/shapes_splines_drawing.c
Normal file
|
|
@ -0,0 +1,273 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - splines drawing
|
||||
*
|
||||
* Example originally created with raylib 5.0, last time updated with raylib 5.0
|
||||
*
|
||||
* 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) 2023 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#define RAYGUI_IMPLEMENTATION
|
||||
#include "raygui.h" // Required for UI controls
|
||||
|
||||
#include <stdlib.h> // Required for: NULL
|
||||
|
||||
#define MAX_SPLINE_POINTS 32
|
||||
|
||||
// Cubic Bezier spline control points
|
||||
// NOTE: Every segment has two control points
|
||||
typedef struct {
|
||||
Vector2 start;
|
||||
Vector2 end;
|
||||
} ControlPoint;
|
||||
|
||||
// Spline types
|
||||
typedef enum {
|
||||
SPLINE_LINEAR = 0, // Linear
|
||||
SPLINE_BASIS, // B-Spline
|
||||
SPLINE_CATMULLROM, // Catmull-Rom
|
||||
SPLINE_BEZIER // Cubic Bezier
|
||||
} SplineType;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
SetConfigFlags(FLAG_MSAA_4X_HINT);
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - splines drawing");
|
||||
|
||||
Vector2 points[MAX_SPLINE_POINTS] = {
|
||||
{ 50.0f, 400.0f },
|
||||
{ 160.0f, 220.0f },
|
||||
{ 340.0f, 380.0f },
|
||||
{ 520.0f, 60.0f },
|
||||
{ 710.0f, 260.0f },
|
||||
};
|
||||
|
||||
// Array required for spline bezier-cubic,
|
||||
// including control points interleaved with start-end segment points
|
||||
Vector2 pointsInterleaved[3*(MAX_SPLINE_POINTS - 1) + 1] = { 0 };
|
||||
|
||||
int pointCount = 5;
|
||||
int selectedPoint = -1;
|
||||
int focusedPoint = -1;
|
||||
Vector2 *selectedControlPoint = NULL;
|
||||
Vector2 *focusedControlPoint = NULL;
|
||||
|
||||
// Cubic Bezier control points initialization
|
||||
ControlPoint control[MAX_SPLINE_POINTS-1] = { 0 };
|
||||
for (int i = 0; i < pointCount - 1; i++)
|
||||
{
|
||||
control[i].start = (Vector2){ points[i].x + 50, points[i].y };
|
||||
control[i].end = (Vector2){ points[i + 1].x - 50, points[i + 1].y };
|
||||
}
|
||||
|
||||
// Spline config variables
|
||||
float splineThickness = 8.0f;
|
||||
int splineTypeActive = SPLINE_LINEAR; // 0-Linear, 1-BSpline, 2-CatmullRom, 3-Bezier
|
||||
bool splineTypeEditMode = false;
|
||||
bool splineHelpersActive = true;
|
||||
|
||||
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
|
||||
//----------------------------------------------------------------------------------
|
||||
// Spline points creation logic (at the end of spline)
|
||||
if (IsMouseButtonPressed(MOUSE_RIGHT_BUTTON) && (pointCount < MAX_SPLINE_POINTS))
|
||||
{
|
||||
points[pointCount] = GetMousePosition();
|
||||
int i = pointCount - 1;
|
||||
control[i].start = (Vector2){ points[i].x + 50, points[i].y };
|
||||
control[i].end = (Vector2){ points[i + 1].x - 50, points[i + 1].y };
|
||||
pointCount++;
|
||||
}
|
||||
|
||||
// Spline point focus and selection logic
|
||||
for (int i = 0; i < pointCount; i++)
|
||||
{
|
||||
if (CheckCollisionPointCircle(GetMousePosition(), points[i], 8.0f))
|
||||
{
|
||||
focusedPoint = i;
|
||||
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) selectedPoint = i;
|
||||
break;
|
||||
}
|
||||
else focusedPoint = -1;
|
||||
}
|
||||
|
||||
// Spline point movement logic
|
||||
if (selectedPoint >= 0)
|
||||
{
|
||||
points[selectedPoint] = GetMousePosition();
|
||||
if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) selectedPoint = -1;
|
||||
}
|
||||
|
||||
// Cubic Bezier spline control points logic
|
||||
if ((splineTypeActive == SPLINE_BEZIER) && (focusedPoint == -1))
|
||||
{
|
||||
// Spline control point focus and selection logic
|
||||
for (int i = 0; i < pointCount - 1; i++)
|
||||
{
|
||||
if (CheckCollisionPointCircle(GetMousePosition(), control[i].start, 6.0f))
|
||||
{
|
||||
focusedControlPoint = &control[i].start;
|
||||
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) selectedControlPoint = &control[i].start;
|
||||
break;
|
||||
}
|
||||
else if (CheckCollisionPointCircle(GetMousePosition(), control[i].end, 6.0f))
|
||||
{
|
||||
focusedControlPoint = &control[i].end;
|
||||
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) selectedControlPoint = &control[i].end;
|
||||
break;
|
||||
}
|
||||
else focusedControlPoint = NULL;
|
||||
}
|
||||
|
||||
// Spline control point movement logic
|
||||
if (selectedControlPoint != NULL)
|
||||
{
|
||||
*selectedControlPoint = GetMousePosition();
|
||||
if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) selectedControlPoint = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Spline selection logic
|
||||
if (IsKeyPressed(KEY_ONE)) splineTypeActive = 0;
|
||||
else if (IsKeyPressed(KEY_TWO)) splineTypeActive = 1;
|
||||
else if (IsKeyPressed(KEY_THREE)) splineTypeActive = 2;
|
||||
else if (IsKeyPressed(KEY_FOUR)) splineTypeActive = 3;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
if (splineTypeActive == SPLINE_LINEAR)
|
||||
{
|
||||
// Draw spline: linear
|
||||
DrawSplineLinear(points, pointCount, splineThickness, RED);
|
||||
}
|
||||
else if (splineTypeActive == SPLINE_BASIS)
|
||||
{
|
||||
// Draw spline: basis
|
||||
DrawSplineBasis(points, pointCount, splineThickness, RED); // Provide connected points array
|
||||
|
||||
/*
|
||||
for (int i = 0; i < (pointCount - 3); i++)
|
||||
{
|
||||
// Drawing individual segments, not considering thickness connection compensation
|
||||
DrawSplineSegmentBasis(points[i], points[i + 1], points[i + 2], points[i + 3], splineThickness, MAROON);
|
||||
}
|
||||
*/
|
||||
}
|
||||
else if (splineTypeActive == SPLINE_CATMULLROM)
|
||||
{
|
||||
// Draw spline: catmull-rom
|
||||
DrawSplineCatmullRom(points, pointCount, splineThickness, RED); // Provide connected points array
|
||||
|
||||
/*
|
||||
for (int i = 0; i < (pointCount - 3); i++)
|
||||
{
|
||||
// Drawing individual segments, not considering thickness connection compensation
|
||||
DrawSplineSegmentCatmullRom(points[i], points[i + 1], points[i + 2], points[i + 3], splineThickness, MAROON);
|
||||
}
|
||||
*/
|
||||
}
|
||||
else if (splineTypeActive == SPLINE_BEZIER)
|
||||
{
|
||||
// NOTE: Cubic-bezier spline requires the 2 control points of each segnment to be
|
||||
// provided interleaved with the start and end point of every segment
|
||||
for (int i = 0; i < (pointCount - 1); i++)
|
||||
{
|
||||
pointsInterleaved[3*i] = points[i];
|
||||
pointsInterleaved[3*i + 1] = control[i].start;
|
||||
pointsInterleaved[3*i + 2] = control[i].end;
|
||||
}
|
||||
|
||||
pointsInterleaved[3*(pointCount - 1)] = points[pointCount - 1];
|
||||
|
||||
// Draw spline: cubic-bezier (with control points)
|
||||
DrawSplineBezierCubic(pointsInterleaved, 3*(pointCount - 1) + 1, splineThickness, RED);
|
||||
|
||||
/*
|
||||
for (int i = 0; i < 3*(pointCount - 1); i += 3)
|
||||
{
|
||||
// Drawing individual segments, not considering thickness connection compensation
|
||||
DrawSplineSegmentBezierCubic(pointsInterleaved[i], pointsInterleaved[i + 1], pointsInterleaved[i + 2], pointsInterleaved[i + 3], splineThickness, MAROON);
|
||||
}
|
||||
*/
|
||||
|
||||
// Draw spline control points
|
||||
for (int i = 0; i < pointCount - 1; i++)
|
||||
{
|
||||
// Every cubic bezier point have two control points
|
||||
DrawCircleV(control[i].start, 6, GOLD);
|
||||
DrawCircleV(control[i].end, 6, GOLD);
|
||||
if (focusedControlPoint == &control[i].start) DrawCircleV(control[i].start, 8, GREEN);
|
||||
else if (focusedControlPoint == &control[i].end) DrawCircleV(control[i].end, 8, GREEN);
|
||||
DrawLineEx(points[i], control[i].start, 1.0f, LIGHTGRAY);
|
||||
DrawLineEx(points[i + 1], control[i].end, 1.0f, LIGHTGRAY);
|
||||
|
||||
// Draw spline control lines
|
||||
DrawLineV(points[i], control[i].start, GRAY);
|
||||
//DrawLineV(control[i].start, control[i].end, LIGHTGRAY);
|
||||
DrawLineV(control[i].end, points[i + 1], GRAY);
|
||||
}
|
||||
}
|
||||
|
||||
if (splineHelpersActive)
|
||||
{
|
||||
// Draw spline point helpers
|
||||
for (int i = 0; i < pointCount; i++)
|
||||
{
|
||||
DrawCircleLinesV(points[i], (focusedPoint == i)? 12.0f : 8.0f, (focusedPoint == i)? BLUE: DARKBLUE);
|
||||
if ((splineTypeActive != SPLINE_LINEAR) &&
|
||||
(splineTypeActive != SPLINE_BEZIER) &&
|
||||
(i < pointCount - 1)) DrawLineV(points[i], points[i + 1], GRAY);
|
||||
|
||||
DrawText(TextFormat("[%.0f, %.0f]", points[i].x, points[i].y), (int)points[i].x, (int)points[i].y + 10, 10, BLACK);
|
||||
}
|
||||
}
|
||||
|
||||
// Check all possible UI states that require controls lock
|
||||
if (splineTypeEditMode) GuiLock();
|
||||
|
||||
// Draw spline config
|
||||
GuiLabel((Rectangle){ 12, 62, 140, 24 }, TextFormat("Spline thickness: %i", (int)splineThickness));
|
||||
GuiSliderBar((Rectangle){ 12, 60 + 24, 140, 16 }, NULL, NULL, &splineThickness, 1.0f, 40.0f);
|
||||
|
||||
GuiCheckBox((Rectangle){ 12, 110, 20, 20 }, "Show point helpers", &splineHelpersActive);
|
||||
|
||||
GuiUnlock();
|
||||
|
||||
GuiLabel((Rectangle){ 12, 10, 140, 24 }, "Spline type:");
|
||||
if (GuiDropdownBox((Rectangle){ 12, 8 + 24, 140, 28 }, "LINEAR;BSPLINE;CATMULLROM;BEZIER", &splineTypeActive, splineTypeEditMode)) splineTypeEditMode = !splineTypeEditMode;
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/shapes/shapes_splines_drawing.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
356
raylib/examples/shapes/shapes_top_down_lights.c
Normal file
|
|
@ -0,0 +1,356 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - top down lights
|
||||
*
|
||||
* Example originally created with raylib 4.2, last time updated with raylib 4.2
|
||||
*
|
||||
* Example contributed by Vlad Adrian (@demizdor) 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) 2022-2024 Jeffery Myers (@JeffM2501)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "raymath.h"
|
||||
#include "rlgl.h"
|
||||
|
||||
// Custom Blend Modes
|
||||
#define RLGL_SRC_ALPHA 0x0302
|
||||
#define RLGL_MIN 0x8007
|
||||
#define RLGL_MAX 0x8008
|
||||
|
||||
#define MAX_BOXES 20
|
||||
#define MAX_SHADOWS MAX_BOXES*3 // MAX_BOXES *3. Each box can cast up to two shadow volumes for the edges it is away from, and one for the box itself
|
||||
#define MAX_LIGHTS 16
|
||||
|
||||
// Shadow geometry type
|
||||
typedef struct ShadowGeometry {
|
||||
Vector2 vertices[4];
|
||||
} ShadowGeometry;
|
||||
|
||||
// Light info type
|
||||
typedef struct LightInfo {
|
||||
bool active; // Is this light slot active?
|
||||
bool dirty; // Does this light need to be updated?
|
||||
bool valid; // Is this light in a valid position?
|
||||
|
||||
Vector2 position; // Light position
|
||||
RenderTexture mask; // Alpha mask for the light
|
||||
float outerRadius; // The distance the light touches
|
||||
Rectangle bounds; // A cached rectangle of the light bounds to help with culling
|
||||
|
||||
ShadowGeometry shadows[MAX_SHADOWS];
|
||||
int shadowCount;
|
||||
} LightInfo;
|
||||
|
||||
|
||||
LightInfo lights[MAX_LIGHTS] = { 0 };
|
||||
|
||||
// Move a light and mark it as dirty so that we update it's mask next frame
|
||||
void MoveLight(int slot, float x, float y)
|
||||
{
|
||||
lights[slot].dirty = true;
|
||||
lights[slot].position.x = x;
|
||||
lights[slot].position.y = y;
|
||||
|
||||
// update the cached bounds
|
||||
lights[slot].bounds.x = x - lights[slot].outerRadius;
|
||||
lights[slot].bounds.y = y - lights[slot].outerRadius;
|
||||
}
|
||||
|
||||
// Compute a shadow volume for the edge
|
||||
// It takes the edge and projects it back by the light radius and turns it into a quad
|
||||
void ComputeShadowVolumeForEdge(int slot, Vector2 sp, Vector2 ep)
|
||||
{
|
||||
if (lights[slot].shadowCount >= MAX_SHADOWS) return;
|
||||
|
||||
float extension = lights[slot].outerRadius*2;
|
||||
|
||||
Vector2 spVector = Vector2Normalize(Vector2Subtract(sp, lights[slot].position));
|
||||
Vector2 spProjection = Vector2Add(sp, Vector2Scale(spVector, extension));
|
||||
|
||||
Vector2 epVector = Vector2Normalize(Vector2Subtract(ep, lights[slot].position));
|
||||
Vector2 epProjection = Vector2Add(ep, Vector2Scale(epVector, extension));
|
||||
|
||||
lights[slot].shadows[lights[slot].shadowCount].vertices[0] = sp;
|
||||
lights[slot].shadows[lights[slot].shadowCount].vertices[1] = ep;
|
||||
lights[slot].shadows[lights[slot].shadowCount].vertices[2] = epProjection;
|
||||
lights[slot].shadows[lights[slot].shadowCount].vertices[3] = spProjection;
|
||||
|
||||
lights[slot].shadowCount++;
|
||||
}
|
||||
|
||||
// Draw the light and shadows to the mask for a light
|
||||
void DrawLightMask(int slot)
|
||||
{
|
||||
// Use the light mask
|
||||
BeginTextureMode(lights[slot].mask);
|
||||
|
||||
ClearBackground(WHITE);
|
||||
|
||||
// Force the blend mode to only set the alpha of the destination
|
||||
rlSetBlendFactors(RLGL_SRC_ALPHA, RLGL_SRC_ALPHA, RLGL_MIN);
|
||||
rlSetBlendMode(BLEND_CUSTOM);
|
||||
|
||||
// If we are valid, then draw the light radius to the alpha mask
|
||||
if (lights[slot].valid) DrawCircleGradient((int)lights[slot].position.x, (int)lights[slot].position.y, lights[slot].outerRadius, ColorAlpha(WHITE, 0), WHITE);
|
||||
|
||||
rlDrawRenderBatchActive();
|
||||
|
||||
// Cut out the shadows from the light radius by forcing the alpha to maximum
|
||||
rlSetBlendMode(BLEND_ALPHA);
|
||||
rlSetBlendFactors(RLGL_SRC_ALPHA, RLGL_SRC_ALPHA, RLGL_MAX);
|
||||
rlSetBlendMode(BLEND_CUSTOM);
|
||||
|
||||
// Draw the shadows to the alpha mask
|
||||
for (int i = 0; i < lights[slot].shadowCount; i++)
|
||||
{
|
||||
DrawTriangleFan(lights[slot].shadows[i].vertices, 4, WHITE);
|
||||
}
|
||||
|
||||
rlDrawRenderBatchActive();
|
||||
|
||||
// Go back to normal blend mode
|
||||
rlSetBlendMode(BLEND_ALPHA);
|
||||
|
||||
EndTextureMode();
|
||||
}
|
||||
|
||||
// Setup a light
|
||||
void SetupLight(int slot, float x, float y, float radius)
|
||||
{
|
||||
lights[slot].active = true;
|
||||
lights[slot].valid = false; // The light must prove it is valid
|
||||
lights[slot].mask = LoadRenderTexture(GetScreenWidth(), GetScreenHeight());
|
||||
lights[slot].outerRadius = radius;
|
||||
|
||||
lights[slot].bounds.width = radius * 2;
|
||||
lights[slot].bounds.height = radius * 2;
|
||||
|
||||
MoveLight(slot, x, y);
|
||||
|
||||
// Force the render texture to have something in it
|
||||
DrawLightMask(slot);
|
||||
}
|
||||
|
||||
// See if a light needs to update it's mask
|
||||
bool UpdateLight(int slot, Rectangle* boxes, int count)
|
||||
{
|
||||
if (!lights[slot].active || !lights[slot].dirty) return false;
|
||||
|
||||
lights[slot].dirty = false;
|
||||
lights[slot].shadowCount = 0;
|
||||
lights[slot].valid = false;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
// Are we in a box? if so we are not valid
|
||||
if (CheckCollisionPointRec(lights[slot].position, boxes[i])) return false;
|
||||
|
||||
// If this box is outside our bounds, we can skip it
|
||||
if (!CheckCollisionRecs(lights[slot].bounds, boxes[i])) continue;
|
||||
|
||||
// Check the edges that are on the same side we are, and cast shadow volumes out from them
|
||||
|
||||
// Top
|
||||
Vector2 sp = (Vector2){ boxes[i].x, boxes[i].y };
|
||||
Vector2 ep = (Vector2){ boxes[i].x + boxes[i].width, boxes[i].y };
|
||||
|
||||
if (lights[slot].position.y > ep.y) ComputeShadowVolumeForEdge(slot, sp, ep);
|
||||
|
||||
// Right
|
||||
sp = ep;
|
||||
ep.y += boxes[i].height;
|
||||
if (lights[slot].position.x < ep.x) ComputeShadowVolumeForEdge(slot, sp, ep);
|
||||
|
||||
// Bottom
|
||||
sp = ep;
|
||||
ep.x -= boxes[i].width;
|
||||
if (lights[slot].position.y < ep.y) ComputeShadowVolumeForEdge(slot, sp, ep);
|
||||
|
||||
// Left
|
||||
sp = ep;
|
||||
ep.y -= boxes[i].height;
|
||||
if (lights[slot].position.x > ep.x) ComputeShadowVolumeForEdge(slot, sp, ep);
|
||||
|
||||
// The box itself
|
||||
lights[slot].shadows[lights[slot].shadowCount].vertices[0] = (Vector2){ boxes[i].x, boxes[i].y };
|
||||
lights[slot].shadows[lights[slot].shadowCount].vertices[1] = (Vector2){ boxes[i].x, boxes[i].y + boxes[i].height };
|
||||
lights[slot].shadows[lights[slot].shadowCount].vertices[2] = (Vector2){ boxes[i].x + boxes[i].width, boxes[i].y + boxes[i].height };
|
||||
lights[slot].shadows[lights[slot].shadowCount].vertices[3] = (Vector2){ boxes[i].x + boxes[i].width, boxes[i].y };
|
||||
lights[slot].shadowCount++;
|
||||
}
|
||||
|
||||
lights[slot].valid = true;
|
||||
|
||||
DrawLightMask(slot);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Set up some boxes
|
||||
void SetupBoxes(Rectangle *boxes, int *count)
|
||||
{
|
||||
boxes[0] = (Rectangle){ 150,80, 40, 40 };
|
||||
boxes[1] = (Rectangle){ 1200, 700, 40, 40 };
|
||||
boxes[2] = (Rectangle){ 200, 600, 40, 40 };
|
||||
boxes[3] = (Rectangle){ 1000, 50, 40, 40 };
|
||||
boxes[4] = (Rectangle){ 500, 350, 40, 40 };
|
||||
|
||||
for (int i = 5; i < MAX_BOXES; i++)
|
||||
{
|
||||
boxes[i] = (Rectangle){(float)GetRandomValue(0,GetScreenWidth()), (float)GetRandomValue(0,GetScreenHeight()), (float)GetRandomValue(10,100), (float)GetRandomValue(10,100) };
|
||||
}
|
||||
|
||||
*count = MAX_BOXES;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - top down lights");
|
||||
|
||||
// Initialize our 'world' of boxes
|
||||
int boxCount = 0;
|
||||
Rectangle boxes[MAX_BOXES] = { 0 };
|
||||
SetupBoxes(boxes, &boxCount);
|
||||
|
||||
// Create a checkerboard ground texture
|
||||
Image img = GenImageChecked(64, 64, 32, 32, DARKBROWN, DARKGRAY);
|
||||
Texture2D backgroundTexture = LoadTextureFromImage(img);
|
||||
UnloadImage(img);
|
||||
|
||||
// Create a global light mask to hold all the blended lights
|
||||
RenderTexture lightMask = LoadRenderTexture(GetScreenWidth(), GetScreenHeight());
|
||||
|
||||
// Setup initial light
|
||||
SetupLight(0, 600, 400, 300);
|
||||
int nextLight = 1;
|
||||
|
||||
bool showLines = 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
|
||||
//----------------------------------------------------------------------------------
|
||||
// Drag light 0
|
||||
if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) MoveLight(0, GetMousePosition().x, GetMousePosition().y);
|
||||
|
||||
// Make a new light
|
||||
if (IsMouseButtonPressed(MOUSE_BUTTON_RIGHT) && (nextLight < MAX_LIGHTS))
|
||||
{
|
||||
SetupLight(nextLight, GetMousePosition().x, GetMousePosition().y, 200);
|
||||
nextLight++;
|
||||
}
|
||||
|
||||
// Toggle debug info
|
||||
if (IsKeyPressed(KEY_F1)) showLines = !showLines;
|
||||
|
||||
// Update the lights and keep track if any were dirty so we know if we need to update the master light mask
|
||||
bool dirtyLights = false;
|
||||
for (int i = 0; i < MAX_LIGHTS; i++)
|
||||
{
|
||||
if (UpdateLight(i, boxes, boxCount)) dirtyLights = true;
|
||||
}
|
||||
|
||||
// Update the light mask
|
||||
if (dirtyLights)
|
||||
{
|
||||
// Build up the light mask
|
||||
BeginTextureMode(lightMask);
|
||||
|
||||
ClearBackground(BLACK);
|
||||
|
||||
// Force the blend mode to only set the alpha of the destination
|
||||
rlSetBlendFactors(RLGL_SRC_ALPHA, RLGL_SRC_ALPHA, RLGL_MIN);
|
||||
rlSetBlendMode(BLEND_CUSTOM);
|
||||
|
||||
// Merge in all the light masks
|
||||
for (int i = 0; i < MAX_LIGHTS; i++)
|
||||
{
|
||||
if (lights[i].active) DrawTextureRec(lights[i].mask.texture, (Rectangle){ 0, 0, (float)GetScreenWidth(), -(float)GetScreenHeight() }, Vector2Zero(), WHITE);
|
||||
}
|
||||
|
||||
rlDrawRenderBatchActive();
|
||||
|
||||
// Go back to normal blend
|
||||
rlSetBlendMode(BLEND_ALPHA);
|
||||
EndTextureMode();
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(BLACK);
|
||||
|
||||
// Draw the tile background
|
||||
DrawTextureRec(backgroundTexture, (Rectangle){ 0, 0, (float)GetScreenWidth(), (float)GetScreenHeight() }, Vector2Zero(), WHITE);
|
||||
|
||||
// Overlay the shadows from all the lights
|
||||
DrawTextureRec(lightMask.texture, (Rectangle){ 0, 0, (float)GetScreenWidth(), -(float)GetScreenHeight() }, Vector2Zero(), ColorAlpha(WHITE, showLines? 0.75f : 1.0f));
|
||||
|
||||
// Draw the lights
|
||||
for (int i = 0; i < MAX_LIGHTS; i++)
|
||||
{
|
||||
if (lights[i].active) DrawCircle((int)lights[i].position.x, (int)lights[i].position.y, 10, (i == 0)? YELLOW : WHITE);
|
||||
}
|
||||
|
||||
if (showLines)
|
||||
{
|
||||
for (int s = 0; s < lights[0].shadowCount; s++)
|
||||
{
|
||||
DrawTriangleFan(lights[0].shadows[s].vertices, 4, DARKPURPLE);
|
||||
}
|
||||
|
||||
for (int b = 0; b < boxCount; b++)
|
||||
{
|
||||
if (CheckCollisionRecs(boxes[b],lights[0].bounds)) DrawRectangleRec(boxes[b], PURPLE);
|
||||
|
||||
DrawRectangleLines((int)boxes[b].x, (int)boxes[b].y, (int)boxes[b].width, (int)boxes[b].height, DARKBLUE);
|
||||
}
|
||||
|
||||
DrawText("(F1) Hide Shadow Volumes", 10, 50, 10, GREEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawText("(F1) Show Shadow Volumes", 10, 50, 10, GREEN);
|
||||
}
|
||||
|
||||
DrawFPS(screenWidth - 80, 10);
|
||||
DrawText("Drag to move light #1", 10, 10, 10, DARKGREEN);
|
||||
DrawText("Right click to add new light", 10, 30, 10, DARKGREEN);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadTexture(backgroundTexture);
|
||||
UnloadRenderTexture(lightMask);
|
||||
for (int i = 0; i < MAX_LIGHTS; i++)
|
||||
{
|
||||
if (lights[i].active) UnloadRenderTexture(lights[i].mask);
|
||||
}
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
raylib/examples/shapes/shapes_top_down_lights.png
Normal file
|
After Width: | Height: | Size: 71 KiB |