Merge remote-tracking branch 'refs/remotes/raysan5/develop' into develop
39
CHANGELOG
|
@ -1,11 +1,48 @@
|
|||
changelog
|
||||
---------
|
||||
|
||||
Current Release: raylib 1.3.0 (03 September 2015)
|
||||
Current Release: raylib 1.4.0 (22 February 2016)
|
||||
|
||||
NOTE: Only versions marked as 'Release' are available in installer, updates are only available as source.
|
||||
NOTE: Current Release includes all previous updates.
|
||||
|
||||
-----------------------------------------------
|
||||
Release: raylib 1.4.0 (22 February 2016)
|
||||
-----------------------------------------------
|
||||
NOTE:
|
||||
This version supposed another big improvement for raylib, inlcuding new modules and new features.
|
||||
More than 30 new functions have been added to previous raylib version.
|
||||
Around 8 new examples and +10 new game samples have been added.
|
||||
|
||||
BIG changes:
|
||||
[textures] IMAGE MANIPULATION: Functions to crop, resize, colorize, flip, dither and even draw image-to-image or text-to-image.
|
||||
[text] SPRITEFONT SUPPORT: Added support for AngelCode fonts (.fnt) and TrueType fonts (.ttf).
|
||||
[gestures] REDESIGN: Gestures system simplified and prepared to process generic touch events, including mouse events (multiplatform).
|
||||
[physac] NEW MODULE: Basic 2D physics support, use colliders and rigidbodies; apply forces to physic objects.
|
||||
|
||||
other changes:
|
||||
[rlgl] Removed GLEW library dependency, now using GLAD
|
||||
[rlgl] Implemented alternative to glGetTexImage() on OpenGL ES
|
||||
[rlgl] Using depth data on batch drawing
|
||||
[rlgl] Reviewed glReadPixels() function
|
||||
[core][rlgl] Reviewed raycast system, now 3D picking works
|
||||
[core] Android: Reviewed Android App cycle, paused if inactive
|
||||
[shaders] Implemented Blinn-Phong lighting shading model
|
||||
[textures] Implemented Floyd-Steinberg dithering - ImageDither()
|
||||
[text] Added line-break support to DrawText()
|
||||
[text] Added TrueType Fonts support (using stb_truetype)
|
||||
[models] Implement function: CalculateBoundingBox(Mesh mesh)
|
||||
[models] Added functions to check Ray collisions
|
||||
[models] Improve map resolution control on LoadHeightmap()
|
||||
[camera] Corrected small-glitch on zoom-in with mouse-wheel
|
||||
[gestures] Implemented SetGesturesEnabled() to enable only some gestures
|
||||
[gestures] Implemented GetElapsedTime() on Windows system
|
||||
[gestures] Support mouse gestures for desktop platforms
|
||||
[raymath] Complete review of the module and converted to header-only
|
||||
[easings] Added new module for easing animations
|
||||
[stb] Updated to latest headers versions
|
||||
[*] Lots of tweaks around
|
||||
|
||||
-----------------------------------------------
|
||||
Release: raylib 1.3.0 (01 September 2015)
|
||||
-----------------------------------------------
|
||||
|
|
|
@ -32,6 +32,8 @@ contact
|
|||
* Webpage: [http://www.raylib.com](http://www.raylib.com)
|
||||
* Twitter: [http://www.twitter.com/raysan5](http://www.twitter.com/raysan5)
|
||||
* Facebook: [http://www.facebook.com/raylibgames](http://www.facebook.com/raylibgames)
|
||||
|
||||
* Reddit: [https://www.reddit.com/r/raylib](https://www.reddit.com/r/raylib)
|
||||
* Twitch: [http://www.twitch.tv/raysan5](http://www.twitch.tv/raysan5)
|
||||
* Patreon: [https://www.patreon.com/raysan5](https://www.patreon.com/raysan5)
|
||||
|
||||
[raysan5]: mailto:raysan@raysanweb.com "Ramon Santamaria - Ray San"
|
||||
[raysan5]: mailto:raysan5@gmail.com "Ramon Santamaria - Ray San"
|
||||
|
|
28
README.md
|
@ -6,7 +6,6 @@ about
|
|||
raylib is a simple and easy-to-use library to learn videogames programming.
|
||||
|
||||
raylib is highly inspired by Borland BGI graphics lib and by XNA framework.
|
||||
Allegro and SDL have also been analyzed for reference.
|
||||
|
||||
NOTE for ADVENTURERS: raylib is a programming library to learn videogames programming;
|
||||
no fancy interface, no visual helpers, no auto-debugging... just coding in the most
|
||||
|
@ -15,7 +14,7 @@ pure spartan-programmers way. Are you ready to learn? Jump to [code examples!](h
|
|||
history
|
||||
-------
|
||||
|
||||
I've developed videogames for some years and last year I had to taught videogames development
|
||||
I've developed videogames for some years and 4 years ago I started teaching videogames development
|
||||
to young people with artistic profile, most of them had never written a single line of code.
|
||||
|
||||
I started with C language basis and, after searching for the most simple and easy-to-use library to teach
|
||||
|
@ -102,25 +101,25 @@ Lots of code changes and lot of testing have concluded in this amazing new rayli
|
|||
notes on raylib 1.4
|
||||
-------------------
|
||||
|
||||
On February 2016, after 4 months of raylib 1.3 release, it comes raylib 1.4.
|
||||
On February 2016, after 4 months of raylib 1.3 release, it comes raylib 1.4. For this new version, lots of parts of the library have been reviewed, lots of bugs have been solved and some interesting features have been added.
|
||||
|
||||
Lots of parts of the library have been reviewed to better accomodate to shaders systems and multiple new features have been added.
|
||||
First big addition is a set of [Image manipulation functions](https://github.com/raysan5/raylib/blob/develop/src/raylib.h#L673) have been added to crop, resize, colorize, flip, dither and even draw image-to-image or text-to-image. Now a basic image processing can be done before converting the image to texture for usage.
|
||||
|
||||
SpriteFonts system has been improved, adding support for AngelCode fonts (.fnt) and TTF fonts (using stb_truetype).
|
||||
SpriteFonts system has been improved, adding support for AngelCode fonts (.fnt) and TrueType Fonts (using [stb_truetype](https://github.com/nothings/stb/blob/master/stb_truetype.h) helper library). Now raylib can read standard .fnt font data and also generate at loading a SpriteFont from a TTF file.
|
||||
|
||||
Finally, raycast system for 3D picking is working, including some ray collision-detection functions.
|
||||
New [physac](https://github.com/raysan5/raylib/blob/develop/src/physac.h) physics module for basic 2D physics support. Still in development but already functional. Module comes with some usage examples for basic jump and level interaction and also force-based physic movements.
|
||||
|
||||
A set of Image manipulation functions have been added to crop, resize, colorize, dither and even draw image-to-image or text-to-image.
|
||||
[raymath](https://github.com/raysan5/raylib/blob/develop/src/raymath.h) module has been reviewed; some bugs have been solved and the module has been converted to a header-only file for easier portability, optionally, functions can also be used as inline.
|
||||
|
||||
Two new functions added for persistent data storage.
|
||||
[gestures](https://github.com/raysan5/raylib/blob/develop/src/gestures.c) module has redesigned and simplified, now it can process touch events from any source, including mouse. This way, gestures system can be used on any platform providing an unified way to work with inputs and allowing the user to create multiplatform games with only one source code.
|
||||
|
||||
New [physac](https://github.com/raysan5/raylib/blob/develop/src/physac.h) physics module!
|
||||
Raspberry Pi input system has been redesigned to better read raw inputs using generic Linux event handlers (keyboard:`stdin`, mouse:`/dev/input/mouse0`, gamepad:`/dev/input/js0`). Gamepad support has also been added (experimental).
|
||||
|
||||
Complete LUA scripting support to allow raylib usage from LUA and LUA scripts support within raylib.
|
||||
Other important improvements are the functional raycast system for 3D picking, including some ray collision-detection functions, and the addition of two simple functions for persistent data storage. Now raylib user can save and load game data in a file (only some platforms supported). A simple [easings](https://github.com/raysan5/raylib/blob/develop/src/easings.h) module has also been added for values animation.
|
||||
|
||||
Up to 8 new examples have been added to show the new raylib features.
|
||||
Up to 8 new code examples have been added to show the new raylib features and +10 complete game samples have been provided to learn how to create some classic games like Arkanoid, Asteroids, Missile Commander, Snake or Tetris.
|
||||
|
||||
Lots of code changes and lot of testing have concluded in this amazing new raylib 1.4.
|
||||
Lots of code changes and lots of hours of hard work have concluded in this amazing new raylib 1.4.
|
||||
|
||||
features
|
||||
--------
|
||||
|
@ -130,7 +129,7 @@ features
|
|||
* Hardware accelerated with OpenGL (1.1, 3.3 or ES2)
|
||||
* Unique OpenGL abstraction layer (usable as standalone module): [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.c)
|
||||
* Powerful fonts module with multiple SpriteFonts formats support (XNA bitmap fonts, AngelCode fonts, TTF)
|
||||
* Outstanding texture formats support, including compressed formats
|
||||
* Outstanding texture formats support, including compressed formats (DXT, ETC, PVRT, ASTC)
|
||||
* Basic 3d support for Shapes, Models, Billboards, Heightmaps and Cubicmaps
|
||||
* Powerful math module for Vector and Matrix operations: [raymath](https://github.com/raysan5/raylib/blob/master/src/raymath.c)
|
||||
* Audio loading and playing with streaming support (WAV and OGG)
|
||||
|
@ -181,6 +180,9 @@ contact
|
|||
* Webpage: [http://www.raylib.com](http://www.raylib.com)
|
||||
* Twitter: [http://www.twitter.com/raysan5](http://www.twitter.com/raysan5)
|
||||
* Facebook: [http://www.facebook.com/raylibgames](http://www.facebook.com/raylibgames)
|
||||
* Reddit: [https://www.reddit.com/r/raylib](https://www.reddit.com/r/raylib)
|
||||
* Twitch: [http://www.twitch.tv/raysan5](http://www.twitch.tv/raysan5)
|
||||
* Patreon: [https://www.patreon.com/raysan5](https://www.patreon.com/raysan5)
|
||||
|
||||
If you are using raylib and you enjoy it, please, [let me know][raysan5].
|
||||
|
||||
|
|
45
ROADMAP.md
|
@ -1,28 +1,37 @@
|
|||
roadmap
|
||||
-------
|
||||
|
||||
Current version of raylib is quite complete and functional but there is still a lot of things I would like to improve.
|
||||
Here it is a list of features I would like to add and functions to improve.
|
||||
Current version of raylib is quite complete and functional but there is still a lot of things to add and improve.
|
||||
Here it is a wish list of features I would like to add and functions to improve.
|
||||
|
||||
Around the source code there are multiple TODO points with pending revisions/bugs and here it is a list of desired features.
|
||||
Note that around the raylib source code there are multiple TODO points with pending revisions/bugs. Check [GitHub Issues](https://github.com/raysan5/raylib/issues) for further details!
|
||||
|
||||
raylib v1.4
|
||||
raylib 1.5
|
||||
|
||||
[DONE] TTF fonts support (using stb_truetype)
|
||||
[DONE] Raycast system for 3D picking (including collisions detection)
|
||||
[DONE] Floyd-Steinberg dithering on 16bit image format conversion
|
||||
[DONE] Basic image manipulation functions (crop, resize, draw...)
|
||||
[DONE] Storage load/save data functionality
|
||||
[DONE] Physics module
|
||||
[IN PROGRESS] LUA scripting support (wrapper to lua lib)
|
||||
- Remove GLEW dependency (use another solution... glad?)
|
||||
- Basic image procedural generation (spot, gradient, noise...)
|
||||
- Basic GPU stats sytem (memory, draws, time...)
|
||||
|
||||
|
||||
Check [GITHUB ISSUES][issues] for further details on implementation status for this features!
|
||||
Redesign Shaders/Textures system, use Materials
|
||||
Redesign physics module (physac)
|
||||
Basic GPU stats sytem (memory, draws, time...)
|
||||
Procedural image generation functions (spot, gradient, noise...)
|
||||
Procedural mesh generation functions (cube, cone, sphere...)
|
||||
Touch-based camera controls for Android
|
||||
Skybox and Fog support
|
||||
[IN PROGRESS] LUA scripting support (wrapper to lua lib)
|
||||
|
||||
raylib 1.4
|
||||
|
||||
[DONE] TTF fonts support (using stb_truetype)
|
||||
[DONE] Raycast system for 3D picking (including collisions detection)
|
||||
[DONE] Floyd-Steinberg dithering on 16bit image format conversion
|
||||
[DONE] Basic image manipulation functions (crop, resize, draw...)
|
||||
[DONE] Storage load/save data functionality
|
||||
[DONE] Add Physics module (physac)
|
||||
[DONE] Remove GLEW dependency -> Replaced by GLAD
|
||||
[DONE] Redesign Raspberry PI inputs system
|
||||
[DONE] Redesign gestures module to be multiplatform
|
||||
[DONE] Module raymath as header-only and functions inline
|
||||
[DONE] Add Easings module (easings.h)
|
||||
|
||||
Any feature missing? Do you have a request? [Let me know!][raysan5]
|
||||
|
||||
[raysan5]: mailto:raysan@raysanweb.com "Ramon Santamaria - Ray San"
|
||||
[raysan5]: mailto:raysan5@gmail.com "Ramon Santamaria - Ray San"
|
||||
[isssues]: https://github.com/raysan5/raylib/issues
|
||||
|
|
|
@ -22,7 +22,7 @@ int main()
|
|||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d camera first person");
|
||||
|
||||
// Define the camera to look into our 3d world
|
||||
// Define the camera to look into our 3d world (position, target, up vector)
|
||||
Camera camera = {{ 0.0f, 10.0f, 10.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }};
|
||||
|
||||
// Generates some random columns
|
||||
|
|
|
@ -22,10 +22,10 @@ int main()
|
|||
|
||||
// Define the camera to look into our 3d world
|
||||
Camera camera;
|
||||
camera.position = (Vector3){ 0.0f, 10.0f, 10.0f };
|
||||
camera.target = (Vector3){ 0.0f, 0.0f, 0.0f };
|
||||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
|
||||
|
||||
camera.position = (Vector3){ 0.0f, 10.0f, 10.0f }; // Camera position
|
||||
camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point
|
||||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
|
||||
|
||||
Vector3 cubePosition = { 0.0f, 0.0f, 0.0f };
|
||||
|
||||
SetCameraMode(CAMERA_FREE); // Set a free camera mode
|
||||
|
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 25 KiB |
|
@ -22,9 +22,9 @@ int main()
|
|||
|
||||
// Define the camera to look into our 3d world
|
||||
Camera camera;
|
||||
camera.position = (Vector3){ 0.0f, 10.0f, 10.0f };
|
||||
camera.target = (Vector3){ 0.0f, 0.0f, 0.0f };
|
||||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
|
||||
camera.position = (Vector3){ 0.0f, 10.0f, 10.0f }; // Camera position
|
||||
camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point
|
||||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
|
||||
|
||||
Vector3 cubePosition = { 0.0f, 0.0f, 0.0f };
|
||||
|
||||
|
|
|
@ -21,7 +21,10 @@ int main()
|
|||
InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d picking");
|
||||
|
||||
// Define the camera to look into our 3d world
|
||||
Camera camera = {{ 0.0f, 10.0f, 10.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }};
|
||||
Camera camera;
|
||||
camera.position = (Vector3){ 0.0f, 10.0f, 10.0f }; // Camera position
|
||||
camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point
|
||||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
|
||||
|
||||
Vector3 cubePosition = { 0.0f, 1.0f, 0.0f };
|
||||
Vector3 cubeSize = { 2.0f, 2.0f, 2.0f };
|
||||
|
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 24 KiB |
115
examples/core_gestures_detection.c
Normal file
|
@ -0,0 +1,115 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Gestures Detection
|
||||
*
|
||||
* This example has been created using raylib 1.4 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2016 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include <string.h>
|
||||
|
||||
#define MAX_GESTURE_STRINGS 20
|
||||
|
||||
int main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
int screenWidth = 800;
|
||||
int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - gestures detection");
|
||||
|
||||
Vector2 touchPosition = { 0, 0 };
|
||||
Rectangle touchArea = { 220, 10, screenWidth - 230, screenHeight - 20 };
|
||||
|
||||
int gesturesCount = 0;
|
||||
char gestureStrings[MAX_GESTURE_STRINGS][32];
|
||||
|
||||
int currentGesture = GESTURE_NONE;
|
||||
int lastGesture = GESTURE_NONE;
|
||||
|
||||
//SetGesturesEnabled(0b0000000000001001); // Enable only some gestures to be detected
|
||||
|
||||
SetTargetFPS(30);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
lastGesture = currentGesture;
|
||||
touchPosition = GetTouchPosition(0);
|
||||
|
||||
if (CheckCollisionPointRec(touchPosition, touchArea) && IsGestureDetected())
|
||||
{
|
||||
currentGesture = GetGestureType();
|
||||
|
||||
if (currentGesture != lastGesture)
|
||||
{
|
||||
// Store gesture string
|
||||
switch (currentGesture)
|
||||
{
|
||||
case GESTURE_TAP: strcpy(gestureStrings[gesturesCount], "GESTURE TAP"); break;
|
||||
case GESTURE_DOUBLETAP: strcpy(gestureStrings[gesturesCount], "GESTURE DOUBLETAP"); break;
|
||||
case GESTURE_HOLD: strcpy(gestureStrings[gesturesCount], "GESTURE HOLD"); break;
|
||||
case GESTURE_DRAG: strcpy(gestureStrings[gesturesCount], "GESTURE DRAG"); break;
|
||||
case GESTURE_SWIPE_RIGHT: strcpy(gestureStrings[gesturesCount], "GESTURE SWIPE RIGHT"); break;
|
||||
case GESTURE_SWIPE_LEFT: strcpy(gestureStrings[gesturesCount], "GESTURE SWIPE LEFT"); break;
|
||||
case GESTURE_SWIPE_UP: strcpy(gestureStrings[gesturesCount], "GESTURE SWIPE UP"); break;
|
||||
case GESTURE_SWIPE_DOWN: strcpy(gestureStrings[gesturesCount], "GESTURE SWIPE DOWN"); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
gesturesCount++;
|
||||
|
||||
// Reset gestures strings
|
||||
if (gesturesCount >= MAX_GESTURE_STRINGS)
|
||||
{
|
||||
for (int i = 0; i < MAX_GESTURE_STRINGS; i++) strcpy(gestureStrings[i], "\0");
|
||||
|
||||
gesturesCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else currentGesture = GESTURE_NONE;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawRectangleRec(touchArea, GRAY);
|
||||
DrawRectangle(225, 15, screenWidth - 240, screenHeight - 30, RAYWHITE);
|
||||
|
||||
DrawText("GESTURES TEST AREA", screenWidth - 270, screenHeight - 40, 20, Fade(GRAY, 0.5f));
|
||||
|
||||
for (int i = 0; i < gesturesCount; i++)
|
||||
{
|
||||
if (i%2 == 0) DrawRectangle(10, 30 + 20*i, 200, 20, Fade(LIGHTGRAY, 0.5f));
|
||||
else DrawRectangle(10, 30 + 20*i, 200, 20, Fade(LIGHTGRAY, 0.3f));
|
||||
|
||||
if (i < gesturesCount - 1) DrawText(gestureStrings[i], 35, 36 + 20*i, 10, DARKGRAY);
|
||||
else DrawText(gestureStrings[i], 35, 36 + 20*i, 10, MAROON);
|
||||
}
|
||||
|
||||
DrawRectangleLines(10, 29, 200, screenHeight - 50, GRAY);
|
||||
DrawText("DETECTED GESTURES", 50, 15, 10, GRAY);
|
||||
|
||||
if (currentGesture != GESTURE_NONE) DrawCircleV(touchPosition, 30, MAROON);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
}
|
BIN
examples/core_gestures_detection.png
Normal file
After Width: | Height: | Size: 19 KiB |
|
@ -21,6 +21,7 @@ int main()
|
|||
InitWindow(screenWidth, screenHeight, "raylib [core] example - mouse input");
|
||||
|
||||
Vector2 ballPosition = { -100.0f, -100.0f };
|
||||
Color ballColor = DARKBLUE;
|
||||
|
||||
SetTargetFPS(60);
|
||||
//---------------------------------------------------------------------------------------
|
||||
|
@ -30,10 +31,11 @@ int main()
|
|||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
|
||||
{
|
||||
ballPosition = GetMousePosition();
|
||||
}
|
||||
ballPosition = GetMousePosition();
|
||||
|
||||
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) ballColor = MAROON;
|
||||
else if (IsMouseButtonPressed(MOUSE_MIDDLE_BUTTON)) ballColor = LIME;
|
||||
else if (IsMouseButtonPressed(MOUSE_RIGHT_BUTTON)) ballColor = DARKBLUE;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
|
@ -42,9 +44,9 @@ int main()
|
|||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawCircleV(ballPosition, 40, GOLD);
|
||||
DrawCircleV(ballPosition, 40, ballColor);
|
||||
|
||||
DrawText("mouse click to draw the ball", 10, 10, 20, DARKGRAY);
|
||||
DrawText("move ball with mouse and click mouse button to change color", 10, 10, 20, DARKGRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* This example has been created using raylib 1.4 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
|
||||
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
|
@ -85,8 +85,8 @@ else
|
|||
# external libraries headers
|
||||
# GLFW3
|
||||
INCLUDES += -I../external/glfw3/include
|
||||
# GLEW
|
||||
INCLUDES += -I../external/glew/include
|
||||
# GLEW - Not required any more, replaced by GLAD
|
||||
#INCLUDES += -I../external/glew/include
|
||||
# OpenAL Soft
|
||||
INCLUDES += -I../external/openal_soft/include
|
||||
endif
|
||||
|
@ -102,8 +102,8 @@ else
|
|||
ifneq ($(PLATFORM_OS),OSX)
|
||||
# OpenAL Soft
|
||||
LFLAGS += -L../external/openal_soft/lib/$(LIBPATH)
|
||||
# GLEW
|
||||
LFLAGS += -L../external/glew/lib/$(LIBPATH)
|
||||
# GLEW - Not required any more, replaced by GLAD
|
||||
#LFLAGS += -L../external/glew/lib/$(LIBPATH)
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -126,7 +126,7 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
|||
else
|
||||
# libraries for Windows desktop compiling
|
||||
# NOTE: GLFW3 and OpenAL Soft libraries should be installed
|
||||
LIBS = -lraylib -lglfw3 -lglew32 -lopengl32 -lopenal32 -lgdi32
|
||||
LIBS = -lraylib -lglfw3 -lopengl32 -lopenal32 -lgdi32
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
@ -161,6 +161,8 @@ EXAMPLES = \
|
|||
core_random_values \
|
||||
core_color_select \
|
||||
core_drop_files \
|
||||
core_storage_values \
|
||||
core_gestures_detection \
|
||||
core_3d_mode \
|
||||
core_3d_picking \
|
||||
core_3d_camera_free \
|
||||
|
@ -177,10 +179,14 @@ EXAMPLES = \
|
|||
textures_raw_data \
|
||||
textures_formats_loading \
|
||||
textures_particles_trail_blending \
|
||||
textures_image_processing \
|
||||
textures_image_drawing \
|
||||
text_sprite_fonts \
|
||||
text_bmfont_ttf \
|
||||
text_rbmf_fonts \
|
||||
text_format_text \
|
||||
text_font_select \
|
||||
text_writing_anim \
|
||||
models_geometric_shapes \
|
||||
models_box_collisions \
|
||||
models_billboard \
|
||||
|
@ -195,8 +201,6 @@ EXAMPLES = \
|
|||
audio_music_stream \
|
||||
fix_dylib \
|
||||
|
||||
#core_input_gamepad \
|
||||
|
||||
|
||||
# typing 'make' will invoke the first target entry in the file,
|
||||
# in this case, the 'default' target entry is raylib
|
||||
|
@ -217,32 +221,44 @@ core_input_keys: core_input_keys.c
|
|||
core_input_mouse: core_input_mouse.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [core] example - gamepad input
|
||||
core_input_gamepad: core_input_gamepad.c
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
else
|
||||
@echo core_input_gamepad: Only supported on desktop platform
|
||||
endif
|
||||
|
||||
# compile [core] example - mouse wheel
|
||||
core_mouse_wheel: core_mouse_wheel.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [core] example - gamepad input
|
||||
core_input_gamepad: core_input_gamepad.c
|
||||
ifeq ($(PLATFORM), $(filter $(PLATFORM),PLATFORM_DESKTOP PLATFORM_RPI))
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
else
|
||||
@echo core_input_gamepad: Example not supported on PLATFORM_ANDROID or PLATFORM_WEB
|
||||
endif
|
||||
|
||||
# compile [core] example - generate random values
|
||||
core_random_values: core_random_values.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [core] example - color selection (collision detection)
|
||||
core_color_select: core_color_select.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [core] example - drop files
|
||||
core_drop_files: core_drop_files.c
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
else
|
||||
@echo core_drop_files: Only supported on desktop platform
|
||||
@echo core_drop_files: Example not supported on PLATFORM_ANDROID or PLATFORM_WEB or PLATFORM_RPI
|
||||
endif
|
||||
|
||||
# compile [core] example - generate random values
|
||||
core_random_values: core_random_values.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [core] example - color selection (collision detection)
|
||||
core_color_select: core_color_select.c
|
||||
# compile [core] example - storage values
|
||||
core_storage_values: core_storage_values.c
|
||||
ifeq ($(PLATFORM), $(filter $(PLATFORM),PLATFORM_DESKTOP PLATFORM_RPI))
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
else
|
||||
@echo core_storage_values: Example not supported on PLATFORM_ANDROID or PLATFORM_WEB
|
||||
endif
|
||||
|
||||
# compile [core] example - gestures detection
|
||||
core_gestures_detection: core_gestures_detection.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [core] example - 3d mode
|
||||
|
@ -309,9 +325,21 @@ textures_formats_loading: textures_formats_loading.c
|
|||
textures_particles_trail_blending: textures_particles_trail_blending.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [textures] example - texture image processing
|
||||
textures_image_processing: textures_image_processing.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [textures] example - texture image drawing
|
||||
textures_image_drawing: textures_image_drawing.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [text] example - sprite fonts loading
|
||||
text_sprite_fonts: text_sprite_fonts.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [text] example - bmfonts and ttf loading
|
||||
text_bmfont_ttf: text_bmfont_ttf.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [text] example - raylib bitmap fonts (rBMF)
|
||||
text_rbmf_fonts: text_rbmf_fonts.c
|
||||
|
@ -325,6 +353,10 @@ text_format_text: text_format_text.c
|
|||
text_font_select: text_font_select.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [text] example - text writing animation
|
||||
text_writing_anim: text_writing_anim.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [models] example - basic geometric 3d shapes
|
||||
models_geometric_shapes: models_geometric_shapes.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 54 KiB |
|
@ -21,13 +21,13 @@ int main()
|
|||
InitWindow(screenWidth, screenHeight, "raylib [models] example - heightmap loading and drawing");
|
||||
|
||||
// Define our custom camera to look into our 3d world
|
||||
Camera camera = {{ 24.0f, 18.0f, 24.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }};
|
||||
Camera camera = {{ 18.0f, 16.0f, 18.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }};
|
||||
|
||||
Image image = LoadImage("resources/heightmap.png"); // Load heightmap image (RAM)
|
||||
Texture2D texture = LoadTextureFromImage(image); // Convert image to texture (VRAM)
|
||||
Model map = LoadHeightmap(image, 32); // Load heightmap model
|
||||
SetModelTexture(&map, texture); // Bind texture to model
|
||||
Vector3 mapPosition = { -16.0f, 0.0f, -16.0f }; // Set model position (depends on model scaling!)
|
||||
Image image = LoadImage("resources/heightmap.png"); // Load heightmap image (RAM)
|
||||
Texture2D texture = LoadTextureFromImage(image); // Convert image to texture (VRAM)
|
||||
Model map = LoadHeightmap(image, (Vector3){ 16, 8, 16 }); // Load heightmap model with defined size
|
||||
SetModelTexture(&map, texture); // Bind texture to model
|
||||
Vector3 mapPosition = { -8.0f, 0.0f, -8.0f }; // Set model position (depends on model scaling!)
|
||||
|
||||
UnloadImage(image); // Unload heightmap image from RAM, already uploaded to VRAM
|
||||
|
||||
|
@ -54,7 +54,9 @@ int main()
|
|||
Begin3dMode(camera);
|
||||
|
||||
// NOTE: Model is scaled to 1/4 of its original size (128x128 units)
|
||||
DrawModel(map, mapPosition, 1/4.0f, RED);
|
||||
DrawModel(map, mapPosition, 1.0f, RED);
|
||||
|
||||
DrawGrid(20, 1.0f);
|
||||
|
||||
End3dMode();
|
||||
|
||||
|
|
Before Width: | Height: | Size: 121 KiB After Width: | Height: | Size: 95 KiB |
|
@ -2,20 +2,10 @@
|
|||
*
|
||||
* raylib [physac] physics example - Basic rigidbody
|
||||
*
|
||||
* Welcome to raylib!
|
||||
*
|
||||
* To test examples, just press F6 and execute raylib_compile_execute script
|
||||
* Note that compiled executable is placed in the same folder as .c file
|
||||
*
|
||||
* You can find all basic examples on C:\raylib\raylib\examples folder or
|
||||
* raylib official webpage: www.raylib.com
|
||||
*
|
||||
* Enjoy using raylib. :)
|
||||
*
|
||||
* This example has been created using raylib 1.3 (www.raylib.com)
|
||||
* This example has been created using raylib 1.4 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
|
||||
* Copyright (c) 2016 Victor Fisac and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
@ -33,13 +23,7 @@ int main()
|
|||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [physics] example - basic rigidbody");
|
||||
|
||||
InitPhysics(); // Initialize internal physics values (max rigidbodies/colliders available: 1024)
|
||||
|
||||
// Physics initialization
|
||||
Physics worldPhysics = { true, false, (Vector2){ 0, -9.81f } };
|
||||
|
||||
// Set internal physics settings
|
||||
SetPhysics(worldPhysics);
|
||||
InitPhysics(3); // Initialize physics system with maximum physic objects
|
||||
|
||||
// Object initialization
|
||||
Transform player = (Transform){(Vector2){(screenWidth - OBJECT_SIZE) / 2, (screenHeight - OBJECT_SIZE) / 2}, 0.0f, (Vector2){OBJECT_SIZE, OBJECT_SIZE}};
|
||||
|
@ -55,6 +39,8 @@ int main()
|
|||
float moveSpeed = 6.0f;
|
||||
float jumpForce = 5.0f;
|
||||
|
||||
bool physicsDebug = false;
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -91,14 +77,7 @@ int main()
|
|||
}
|
||||
|
||||
// Check debug mode toggle button input
|
||||
if(IsKeyPressed(KEY_P))
|
||||
{
|
||||
// Update program physics value
|
||||
worldPhysics.debug = !worldPhysics.debug;
|
||||
|
||||
// Update internal physics value
|
||||
SetPhysics(worldPhysics);
|
||||
}
|
||||
if (IsKeyPressed(KEY_P)) physicsDebug = !physicsDebug;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
|
@ -112,7 +91,7 @@ int main()
|
|||
DrawText("Use P to switch DEBUG MODE", (screenWidth - MeasureText("Use P to switch DEBUG MODE", 20)) / 2, screenHeight * 0.3f, 20, LIGHTGRAY);
|
||||
|
||||
// Check if debug mode is enabled
|
||||
if (worldPhysics.debug)
|
||||
if (physicsDebug)
|
||||
{
|
||||
// Draw every internal physics stored collider if it is active
|
||||
for (int i = 0; i < 2; i++)
|
||||
|
@ -122,14 +101,11 @@ int main()
|
|||
DrawRectangleLines(GetCollider(i).bounds.x, GetCollider(i).bounds.y, GetCollider(i).bounds.width, GetCollider(i).bounds.height, GREEN);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw player
|
||||
// Draw player and floor
|
||||
DrawRectangleRec((Rectangle){player.position.x, player.position.y, player.scale.x, player.scale.y}, GRAY);
|
||||
|
||||
// Draw floor
|
||||
DrawRectangleRec((Rectangle){floor.position.x, floor.position.y, floor.scale.x, floor.scale.y}, BLACK);
|
||||
}
|
||||
|
||||
|
@ -138,7 +114,9 @@ int main()
|
|||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadPhysics(); // Unload physic objects
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
*
|
||||
* raylib [physac] physics example - Rigidbody forces
|
||||
*
|
||||
* This example has been created using raylib 1.3 (www.raylib.com)
|
||||
* This example has been created using raylib 1.4 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
|
||||
* Copyright (c) 2016 Victor Fisac and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
@ -26,15 +26,9 @@ int main()
|
|||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [physics] example - rigidbodies forces");
|
||||
|
||||
InitPhysics(); // Initialize internal physics values (max rigidbodies/colliders available: 1024)
|
||||
InitPhysics(MAX_OBJECTS + 1); // Initialize physics system with maximum physic objects
|
||||
|
||||
// Physics initialization
|
||||
Physics worldPhysics = {true, false, (Vector2){0, -9.81f}};
|
||||
|
||||
// Set internal physics settings
|
||||
SetPhysics(worldPhysics);
|
||||
|
||||
// Objects initialization
|
||||
// Physic Objects initialization
|
||||
Transform objects[MAX_OBJECTS];
|
||||
|
||||
for (int i = 0; i < MAX_OBJECTS; i++)
|
||||
|
@ -49,6 +43,8 @@ int main()
|
|||
Transform floor = (Transform){(Vector2){0, screenHeight * 0.8f}, 0.0f, (Vector2){screenWidth, screenHeight * 0.2f}};
|
||||
AddCollider(MAX_OBJECTS, (Collider){true, COLLIDER_RECTANGLE, (Rectangle){floor.position.x, floor.position.y, floor.scale.x, floor.scale.y}, 0});
|
||||
|
||||
bool physicsDebug = false;
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -72,14 +68,7 @@ int main()
|
|||
}
|
||||
|
||||
// Check debug mode toggle button input
|
||||
if (IsKeyPressed(KEY_P))
|
||||
{
|
||||
// Update program physics value
|
||||
worldPhysics.debug = !worldPhysics.debug;
|
||||
|
||||
// Update internal physics value
|
||||
SetPhysics(worldPhysics);
|
||||
}
|
||||
if (IsKeyPressed(KEY_P)) physicsDebug = !physicsDebug;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
|
@ -89,10 +78,10 @@ int main()
|
|||
ClearBackground(RAYWHITE);
|
||||
|
||||
// Check if debug mode is enabled
|
||||
if (worldPhysics.debug)
|
||||
if (physicsDebug)
|
||||
{
|
||||
// Draw every internal physics stored collider if it is active (floor included)
|
||||
for (int i = 0; i < MAX_OBJECTS + 1; i++)
|
||||
for (int i = 0; i < MAX_OBJECTS; i++)
|
||||
{
|
||||
if (GetCollider(i).enabled)
|
||||
{
|
||||
|
@ -136,7 +125,9 @@ int main()
|
|||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadPhysics(); // Unload physic objects
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
|
BIN
examples/resources/cat.png
Normal file
After Width: | Height: | Size: 379 KiB |
99
examples/resources/fonts/bmfont.fnt
Normal file
|
@ -0,0 +1,99 @@
|
|||
info face="Arial Black" size=-32 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=2,2 outline=0
|
||||
common lineHeight=45 base=35 scaleW=512 scaleH=256 pages=1 packed=0 alphaChnl=0 redChnl=4 greenChnl=4 blueChnl=4
|
||||
page id=0 file="bmfont.png"
|
||||
chars count=95
|
||||
char id=32 x=423 y=141 width=3 height=45 xoffset=-1 yoffset=0 xadvance=11 page=0 chnl=15
|
||||
char id=33 x=323 y=141 width=9 height=45 xoffset=1 yoffset=0 xadvance=11 page=0 chnl=15
|
||||
char id=34 x=123 y=141 width=16 height=45 xoffset=0 yoffset=0 xadvance=16 page=0 chnl=15
|
||||
char id=35 x=221 y=47 width=21 height=45 xoffset=0 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=36 x=244 y=47 width=21 height=45 xoffset=0 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=37 x=70 y=0 width=30 height=45 xoffset=1 yoffset=0 xadvance=32 page=0 chnl=15
|
||||
char id=38 x=390 y=0 width=25 height=45 xoffset=2 yoffset=0 xadvance=28 page=0 chnl=15
|
||||
char id=39 x=378 y=141 width=8 height=45 xoffset=1 yoffset=0 xadvance=9 page=0 chnl=15
|
||||
char id=40 x=222 y=141 width=11 height=45 xoffset=1 yoffset=0 xadvance=12 page=0 chnl=15
|
||||
char id=41 x=499 y=94 width=11 height=45 xoffset=1 yoffset=0 xadvance=12 page=0 chnl=15
|
||||
char id=42 x=497 y=47 width=13 height=45 xoffset=2 yoffset=0 xadvance=18 page=0 chnl=15
|
||||
char id=43 x=394 y=94 width=19 height=45 xoffset=1 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=44 x=367 y=141 width=9 height=45 xoffset=1 yoffset=0 xadvance=11 page=0 chnl=15
|
||||
char id=45 x=261 y=141 width=11 height=45 xoffset=0 yoffset=0 xadvance=11 page=0 chnl=15
|
||||
char id=46 x=356 y=141 width=9 height=45 xoffset=1 yoffset=0 xadvance=11 page=0 chnl=15
|
||||
char id=47 x=248 y=141 width=11 height=45 xoffset=-1 yoffset=0 xadvance=9 page=0 chnl=15
|
||||
char id=48 x=382 y=47 width=21 height=45 xoffset=0 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=49 x=496 y=0 width=14 height=45 xoffset=2 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=50 x=134 y=94 width=20 height=45 xoffset=0 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=51 x=359 y=47 width=21 height=45 xoffset=0 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=52 x=313 y=47 width=21 height=45 xoffset=0 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=53 x=336 y=47 width=21 height=45 xoffset=0 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=54 x=178 y=94 width=20 height=45 xoffset=1 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=55 x=478 y=94 width=19 height=45 xoffset=1 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=56 x=290 y=47 width=21 height=45 xoffset=0 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=57 x=90 y=94 width=20 height=45 xoffset=0 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=58 x=345 y=141 width=9 height=45 xoffset=1 yoffset=0 xadvance=11 page=0 chnl=15
|
||||
char id=59 x=334 y=141 width=9 height=45 xoffset=1 yoffset=0 xadvance=11 page=0 chnl=15
|
||||
char id=60 x=0 y=141 width=19 height=45 xoffset=1 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=61 x=21 y=141 width=19 height=45 xoffset=1 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=62 x=310 y=94 width=19 height=45 xoffset=1 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=63 x=352 y=94 width=19 height=45 xoffset=1 yoffset=0 xadvance=20 page=0 chnl=15
|
||||
char id=64 x=279 y=0 width=26 height=45 xoffset=-1 yoffset=0 xadvance=24 page=0 chnl=15
|
||||
char id=65 x=193 y=0 width=27 height=45 xoffset=-1 yoffset=0 xadvance=25 page=0 chnl=15
|
||||
char id=66 x=150 y=47 width=22 height=45 xoffset=2 yoffset=0 xadvance=25 page=0 chnl=15
|
||||
char id=67 x=444 y=0 width=24 height=45 xoffset=1 yoffset=0 xadvance=25 page=0 chnl=15
|
||||
char id=68 x=174 y=47 width=22 height=45 xoffset=2 yoffset=0 xadvance=25 page=0 chnl=15
|
||||
char id=69 x=156 y=94 width=20 height=45 xoffset=2 yoffset=0 xadvance=23 page=0 chnl=15
|
||||
char id=70 x=63 y=141 width=18 height=45 xoffset=2 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=71 x=417 y=0 width=25 height=45 xoffset=1 yoffset=0 xadvance=27 page=0 chnl=15
|
||||
char id=72 x=125 y=47 width=23 height=45 xoffset=2 yoffset=0 xadvance=27 page=0 chnl=15
|
||||
char id=73 x=388 y=141 width=8 height=45 xoffset=2 yoffset=0 xadvance=12 page=0 chnl=15
|
||||
char id=74 x=200 y=94 width=20 height=45 xoffset=0 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=75 x=251 y=0 width=26 height=45 xoffset=2 yoffset=0 xadvance=27 page=0 chnl=15
|
||||
char id=76 x=373 y=94 width=19 height=45 xoffset=2 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=77 x=134 y=0 width=28 height=45 xoffset=1 yoffset=0 xadvance=30 page=0 chnl=15
|
||||
char id=78 x=100 y=47 width=23 height=45 xoffset=2 yoffset=0 xadvance=27 page=0 chnl=15
|
||||
char id=79 x=363 y=0 width=25 height=45 xoffset=1 yoffset=0 xadvance=27 page=0 chnl=15
|
||||
char id=80 x=112 y=94 width=20 height=45 xoffset=2 yoffset=0 xadvance=23 page=0 chnl=15
|
||||
char id=81 x=335 y=0 width=26 height=45 xoffset=1 yoffset=0 xadvance=27 page=0 chnl=15
|
||||
char id=82 x=470 y=0 width=24 height=45 xoffset=2 yoffset=0 xadvance=25 page=0 chnl=15
|
||||
char id=83 x=75 y=47 width=23 height=45 xoffset=0 yoffset=0 xadvance=23 page=0 chnl=15
|
||||
char id=84 x=50 y=47 width=23 height=45 xoffset=0 yoffset=0 xadvance=23 page=0 chnl=15
|
||||
char id=85 x=25 y=47 width=23 height=45 xoffset=2 yoffset=0 xadvance=27 page=0 chnl=15
|
||||
char id=86 x=307 y=0 width=26 height=45 xoffset=0 yoffset=0 xadvance=25 page=0 chnl=15
|
||||
char id=87 x=0 y=0 width=34 height=45 xoffset=-1 yoffset=0 xadvance=32 page=0 chnl=15
|
||||
char id=88 x=222 y=0 width=27 height=45 xoffset=-1 yoffset=0 xadvance=25 page=0 chnl=15
|
||||
char id=89 x=164 y=0 width=27 height=45 xoffset=-1 yoffset=0 xadvance=25 page=0 chnl=15
|
||||
char id=90 x=0 y=47 width=23 height=45 xoffset=0 yoffset=0 xadvance=23 page=0 chnl=15
|
||||
char id=91 x=274 y=141 width=11 height=45 xoffset=1 yoffset=0 xadvance=12 page=0 chnl=15
|
||||
char id=92 x=300 y=141 width=10 height=45 xoffset=-1 yoffset=0 xadvance=9 page=0 chnl=15
|
||||
char id=93 x=287 y=141 width=11 height=45 xoffset=0 yoffset=0 xadvance=12 page=0 chnl=15
|
||||
char id=94 x=457 y=94 width=19 height=45 xoffset=1 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=95 x=103 y=141 width=18 height=45 xoffset=-1 yoffset=0 xadvance=16 page=0 chnl=15
|
||||
char id=96 x=312 y=141 width=9 height=45 xoffset=0 yoffset=0 xadvance=11 page=0 chnl=15
|
||||
char id=97 x=474 y=47 width=21 height=45 xoffset=0 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=98 x=68 y=94 width=20 height=45 xoffset=1 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=99 x=267 y=47 width=21 height=45 xoffset=0 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=100 x=46 y=94 width=20 height=45 xoffset=0 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=101 x=198 y=47 width=21 height=45 xoffset=0 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=102 x=141 y=141 width=15 height=45 xoffset=-1 yoffset=0 xadvance=12 page=0 chnl=15
|
||||
char id=103 x=222 y=94 width=20 height=45 xoffset=0 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=104 x=415 y=94 width=19 height=45 xoffset=1 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=105 x=398 y=141 width=7 height=45 xoffset=2 yoffset=0 xadvance=11 page=0 chnl=15
|
||||
char id=106 x=235 y=141 width=11 height=45 xoffset=-2 yoffset=0 xadvance=11 page=0 chnl=15
|
||||
char id=107 x=405 y=47 width=21 height=45 xoffset=1 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=108 x=407 y=141 width=7 height=45 xoffset=2 yoffset=0 xadvance=11 page=0 chnl=15
|
||||
char id=109 x=102 y=0 width=30 height=45 xoffset=1 yoffset=0 xadvance=32 page=0 chnl=15
|
||||
char id=110 x=331 y=94 width=19 height=45 xoffset=1 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=111 x=428 y=47 width=21 height=45 xoffset=0 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=112 x=266 y=94 width=20 height=45 xoffset=1 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=113 x=288 y=94 width=20 height=45 xoffset=0 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=114 x=158 y=141 width=15 height=45 xoffset=1 yoffset=0 xadvance=14 page=0 chnl=15
|
||||
char id=115 x=244 y=94 width=20 height=45 xoffset=0 yoffset=0 xadvance=20 page=0 chnl=15
|
||||
char id=116 x=175 y=141 width=14 height=45 xoffset=0 yoffset=0 xadvance=14 page=0 chnl=15
|
||||
char id=117 x=436 y=94 width=19 height=45 xoffset=1 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=118 x=451 y=47 width=21 height=45 xoffset=0 yoffset=0 xadvance=20 page=0 chnl=15
|
||||
char id=119 x=36 y=0 width=32 height=45 xoffset=-1 yoffset=0 xadvance=30 page=0 chnl=15
|
||||
char id=120 x=0 y=94 width=21 height=45 xoffset=0 yoffset=0 xadvance=21 page=0 chnl=15
|
||||
char id=121 x=23 y=94 width=21 height=45 xoffset=0 yoffset=0 xadvance=20 page=0 chnl=15
|
||||
char id=122 x=83 y=141 width=18 height=45 xoffset=0 yoffset=0 xadvance=18 page=0 chnl=15
|
||||
char id=123 x=191 y=141 width=14 height=45 xoffset=-1 yoffset=0 xadvance=12 page=0 chnl=15
|
||||
char id=124 x=416 y=141 width=5 height=45 xoffset=2 yoffset=0 xadvance=9 page=0 chnl=15
|
||||
char id=125 x=207 y=141 width=13 height=45 xoffset=0 yoffset=0 xadvance=12 page=0 chnl=15
|
||||
char id=126 x=42 y=141 width=19 height=45 xoffset=1 yoffset=0 xadvance=21 page=0 chnl=15
|
BIN
examples/resources/fonts/bmfont.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
examples/resources/fonts/pixantiqua.ttf
Normal file
BIN
examples/resources/parrots.png
Normal file
After Width: | Height: | Size: 288 KiB |
|
@ -7,7 +7,9 @@ in vec3 vertexNormal;
|
|||
|
||||
// Projection and model data
|
||||
uniform mat4 mvpMatrix;
|
||||
|
||||
uniform mat4 modelMatrix;
|
||||
//uniform mat4 viewMatrix; // Not used
|
||||
|
||||
// Attributes to fragment shader
|
||||
out vec2 fragTexCoord;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#version 110
|
||||
#version 330
|
||||
|
||||
attribute vec3 vertexPosition;
|
||||
attribute vec2 vertexTexCoord;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#version 110
|
||||
#version 330
|
||||
|
||||
uniform sampler2D texture0;
|
||||
varying vec2 fragTexCoord;
|
||||
|
|
|
@ -14,6 +14,17 @@
|
|||
#define SHININESS_SPEED 1.0f
|
||||
#define LIGHT_SPEED 0.25f
|
||||
|
||||
// Light type
|
||||
typedef struct Light {
|
||||
Vector3 position;
|
||||
Vector3 direction;
|
||||
float intensity;
|
||||
float specIntensity;
|
||||
Color diffuse;
|
||||
Color ambient;
|
||||
Color specular;
|
||||
} Light;
|
||||
|
||||
int main()
|
||||
{
|
||||
// Initialization
|
||||
|
@ -48,6 +59,10 @@ int main()
|
|||
int cameraLoc = GetShaderLocation(shader, "cameraPos");
|
||||
int lightLoc = GetShaderLocation(shader, "lightPos");
|
||||
|
||||
// Model and View matrix locations (required for lighting)
|
||||
int modelLoc = GetShaderLocation(shader, "modelMatrix");
|
||||
//int viewLoc = GetShaderLocation(shader, "viewMatrix"); // Not used
|
||||
|
||||
// Light and material definitions
|
||||
Light light;
|
||||
Material matBlinn;
|
||||
|
@ -62,9 +77,9 @@ int main()
|
|||
light.specIntensity = 1.0f;
|
||||
|
||||
// Material initialization
|
||||
matBlinn.diffuse = WHITE;
|
||||
matBlinn.ambient = (Color){ 50, 50, 50, 255 };
|
||||
matBlinn.specular = WHITE;
|
||||
matBlinn.colDiffuse = WHITE;
|
||||
matBlinn.colAmbient = (Color){ 50, 50, 50, 255 };
|
||||
matBlinn.colSpecular = WHITE;
|
||||
matBlinn.glossiness = 50.0f;
|
||||
|
||||
// Setup camera
|
||||
|
@ -82,6 +97,10 @@ int main()
|
|||
//----------------------------------------------------------------------------------
|
||||
UpdateCamera(&camera); // Update camera position
|
||||
|
||||
// NOTE: Model transform can be set in model.transform or directly with params at draw... WATCH OUT!
|
||||
SetShaderValueMatrix(shader, modelLoc, model.transform); // Send model matrix to shader
|
||||
//SetShaderValueMatrix(shader, viewLoc, GetCameraMatrix(camera)); // Not used
|
||||
|
||||
// Glossiness input control
|
||||
if(IsKeyDown(KEY_UP)) matBlinn.glossiness += SHININESS_SPEED;
|
||||
else if(IsKeyDown(KEY_DOWN))
|
||||
|
@ -110,8 +129,8 @@ int main()
|
|||
SetShaderValue(shader, lSpecIntensityLoc, &light.specIntensity, 1);
|
||||
|
||||
// Send material values to shader
|
||||
SetShaderValue(shader, mAmbientLoc, ColorToFloat(matBlinn.ambient), 3);
|
||||
SetShaderValue(shader, mSpecularLoc, ColorToFloat(matBlinn.specular), 3);
|
||||
SetShaderValue(shader, mAmbientLoc, ColorToFloat(matBlinn.colAmbient), 3);
|
||||
SetShaderValue(shader, mSpecularLoc, ColorToFloat(matBlinn.colSpecular), 3);
|
||||
SetShaderValue(shader, mGlossLoc, &matBlinn.glossiness, 1);
|
||||
|
||||
// Send camera and light transform values to shader
|
||||
|
@ -127,7 +146,7 @@ int main()
|
|||
|
||||
Begin3dMode(camera);
|
||||
|
||||
DrawModel(model, position, 4.0f, matBlinn.diffuse);
|
||||
DrawModel(model, position, 4.0f, matBlinn.colDiffuse);
|
||||
DrawSphere(light.position, 0.5f, GOLD);
|
||||
|
||||
DrawGrid(20, 1.0f);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* raylib [shapes] example - raylib logo animation
|
||||
*
|
||||
* This example has been created using raylib 1.1 (www.raylib.com)
|
||||
* This example has been created using raylib 1.4 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
|
||||
|
@ -32,8 +32,6 @@ int main()
|
|||
int bottomSideRecWidth = 16;
|
||||
int rightSideRecHeight = 16;
|
||||
|
||||
char raylib[8] = " \0"; // raylib text array, max 8 letters
|
||||
|
||||
int state = 0; // Tracking animation states (State Machine)
|
||||
float alpha = 1.0f; // Useful for fading
|
||||
|
||||
|
@ -79,24 +77,13 @@ int main()
|
|||
framesCounter = 0;
|
||||
}
|
||||
|
||||
switch (lettersCount)
|
||||
{
|
||||
case 1: raylib[0] = 'r'; break;
|
||||
case 2: raylib[1] = 'a'; break;
|
||||
case 3: raylib[2] = 'y'; break;
|
||||
case 4: raylib[3] = 'l'; break;
|
||||
case 5: raylib[4] = 'i'; break;
|
||||
case 6: raylib[5] = 'b'; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
if (lettersCount >= 10) // When all letters have appeared, just fade out everything
|
||||
{
|
||||
alpha -= 0.02;
|
||||
alpha -= 0.02f;
|
||||
|
||||
if (alpha <= 0)
|
||||
if (alpha <= 0.0f)
|
||||
{
|
||||
alpha = 0;
|
||||
alpha = 0.0f;
|
||||
state = 4;
|
||||
}
|
||||
}
|
||||
|
@ -114,12 +101,7 @@ int main()
|
|||
bottomSideRecWidth = 16;
|
||||
rightSideRecHeight = 16;
|
||||
|
||||
for (int i = 0; i < 7; i++) raylib[i] = ' ';
|
||||
|
||||
raylib[7] = '\0'; // Last character is end-of-line
|
||||
|
||||
alpha = 1.0;
|
||||
|
||||
alpha = 1.0f;
|
||||
state = 0; // Return to State 0
|
||||
}
|
||||
}
|
||||
|
@ -158,7 +140,7 @@ int main()
|
|||
|
||||
DrawRectangle(screenWidth/2 - 112, screenHeight/2 - 112, 224, 224, Fade(RAYWHITE, alpha));
|
||||
|
||||
DrawText(raylib, screenWidth/2 - 44, screenHeight/2 + 48, 50, Fade(BLACK, alpha));
|
||||
DrawText(SubText("raylib", 0, lettersCount), screenWidth/2 - 44, screenHeight/2 + 48, 50, Fade(BLACK, alpha));
|
||||
}
|
||||
else if (state == 4)
|
||||
{
|
||||
|
|
68
examples/text_bmfont_ttf.c
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [text] example - BMFont and TTF SpriteFonts loading
|
||||
*
|
||||
* This example has been created using raylib 1.4 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2016 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
int screenWidth = 800;
|
||||
int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [text] example - bmfont and ttf sprite fonts loading");
|
||||
|
||||
const char msgBm[64] = "THIS IS AN AngelCode SPRITE FONT";
|
||||
const char msgTtf[64] = "THIS SPRITE FONT has been GENERATED from a TTF";
|
||||
|
||||
// NOTE: Textures/Fonts MUST be loaded after Window initialization (OpenGL context is required)
|
||||
SpriteFont fontBm = LoadSpriteFont("resources/fonts/bmfont.fnt"); // BMFont (AngelCode)
|
||||
SpriteFont fontTtf = LoadSpriteFont("resources/fonts/pixantiqua.ttf"); // TTF font
|
||||
|
||||
Vector2 fontPosition;
|
||||
|
||||
fontPosition.x = screenWidth/2 - MeasureTextEx(fontBm, msgBm, fontBm.size, 0).x/2;
|
||||
fontPosition.y = screenHeight/2 - fontBm.size/2 - 80;
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// TODO: Update variables here...
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawTextEx(fontBm, msgBm, fontPosition, fontBm.size, 0, MAROON);
|
||||
DrawTextEx(fontTtf, msgTtf, (Vector2){ 75.0f, 240.0f }, fontTtf.size*0.8f, 2, LIME);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadSpriteFont(fontBm); // AngelCode SpriteFont unloading
|
||||
UnloadSpriteFont(fontTtf); // TTF SpriteFont unloading
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
BIN
examples/text_bmfont_ttf.png
Normal file
After Width: | Height: | Size: 19 KiB |
60
examples/text_writing_anim.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [text] example - Text Writing Animation
|
||||
*
|
||||
* This example has been created using raylib 1.4 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2016 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
int screenWidth = 800;
|
||||
int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [text] example - text writing anim");
|
||||
|
||||
const char message[128] = "This sample illustrates a text writing\nanimation effect! Check it out! ;)";
|
||||
|
||||
int framesCounter = 0;
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
framesCounter++;
|
||||
|
||||
if (IsKeyPressed(KEY_ENTER)) framesCounter = 0;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawText(SubText(message, 0, framesCounter/10), 210, 160, 20, MAROON);
|
||||
|
||||
DrawText("PRESS [ENTER] to RESTART!", 240, 280, 20, LIGHTGRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
BIN
examples/text_writing_anim.png
Normal file
After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 77 KiB After Width: | Height: | Size: 123 KiB |
78
examples/textures_image_drawing.c
Normal file
|
@ -0,0 +1,78 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [textures] example - Image loading and drawing on it
|
||||
*
|
||||
* NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM)
|
||||
*
|
||||
* This example has been created using raylib 1.4 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2016 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
int screenWidth = 800;
|
||||
int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - image drawing");
|
||||
|
||||
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
|
||||
|
||||
Image cat = LoadImage("resources/cat.png"); // Load image in CPU memory (RAM)
|
||||
ImageCrop(&cat, (Rectangle){ 100, 10, 280, 380 }); // Crop an image piece
|
||||
ImageFlipHorizontal(&cat); // Flip cropped image horizontally
|
||||
ImageResize(&cat, 150, 200); // Resize flipped-cropped image
|
||||
|
||||
Image parrots = LoadImage("resources/parrots.png"); // Load image in CPU memory (RAM)
|
||||
|
||||
// Draw one image over the other with a scaling of 1.5f
|
||||
ImageDraw(&parrots, cat, (Rectangle){ 0, 0, cat.width, cat.height }, (Rectangle){ 30, 40, cat.width*1.5f, cat.height*1.5f });
|
||||
ImageCrop(&parrots, (Rectangle){ 0, 50, parrots.width, parrots.height - 100 }); // Crop resulting image
|
||||
|
||||
UnloadImage(cat); // Unload image from RAM
|
||||
|
||||
Texture2D texture = LoadTextureFromImage(parrots); // Image converted to texture, uploaded to GPU memory (VRAM)
|
||||
UnloadImage(parrots); // Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM
|
||||
|
||||
SetTargetFPS(60);
|
||||
//---------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// TODO: Update your variables here
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawTexture(texture, screenWidth/2 - texture.width/2, screenHeight/2 - texture.height/2 - 40, WHITE);
|
||||
DrawRectangleLines(screenWidth/2 - texture.width/2, screenHeight/2 - texture.height/2 - 40, texture.width, texture.height, DARKGRAY);
|
||||
|
||||
DrawText("We are drawing only one texture from various images composed!", 240, 350, 10, DARKGRAY);
|
||||
DrawText("Source images have been cropped, scaled, flipped and copied one over the other.", 190, 370, 10, DARKGRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadTexture(texture); // Texture unloading
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
BIN
examples/textures_image_drawing.png
Normal file
After Width: | Height: | Size: 410 KiB |
154
examples/textures_image_processing.c
Normal file
|
@ -0,0 +1,154 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [textures] example - Image processing
|
||||
*
|
||||
* NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM)
|
||||
*
|
||||
* This example has been created using raylib 1.4 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2016 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include <stdlib.h> // Required for: free()
|
||||
|
||||
#define NUM_PROCESSES 8
|
||||
|
||||
typedef enum {
|
||||
NONE = 0,
|
||||
COLOR_GRAYSCALE,
|
||||
COLOR_TINT,
|
||||
COLOR_INVERT,
|
||||
COLOR_CONTRAST,
|
||||
COLOR_BRIGHTNESS,
|
||||
FLIP_VERTICAL,
|
||||
FLIP_HORIZONTAL
|
||||
} ImageProcess;
|
||||
|
||||
static const char *processText[] = {
|
||||
"NO PROCESSING",
|
||||
"COLOR GRAYSCALE",
|
||||
"COLOR TINT",
|
||||
"COLOR INVERT",
|
||||
"COLOR CONTRAST",
|
||||
"COLOR BRIGHTNESS",
|
||||
"FLIP VERTICAL",
|
||||
"FLIP HORIZONTAL"
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
int screenWidth = 800;
|
||||
int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - image processing");
|
||||
|
||||
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
|
||||
|
||||
Image image = LoadImage("resources/parrots.png"); // Loaded in CPU memory (RAM)
|
||||
ImageFormat(&image, UNCOMPRESSED_R8G8B8A8); // Format image to RGBA 32bit (required for texture update)
|
||||
Texture2D texture = LoadTextureFromImage(image); // Image converted to texture, GPU memory (VRAM)
|
||||
|
||||
int currentProcess = NONE;
|
||||
bool textureReload = false;
|
||||
|
||||
Rectangle selectRecs[NUM_PROCESSES];
|
||||
|
||||
for (int i = 0; i < NUM_PROCESSES; i++) selectRecs[i] = (Rectangle){ 40, 50 + 32*i, 150, 30 };
|
||||
|
||||
SetTargetFPS(60);
|
||||
//---------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyPressed(KEY_DOWN))
|
||||
{
|
||||
currentProcess++;
|
||||
if (currentProcess > 7) currentProcess = 0;
|
||||
textureReload = true;
|
||||
}
|
||||
else if (IsKeyPressed(KEY_UP))
|
||||
{
|
||||
currentProcess--;
|
||||
if (currentProcess < 0) currentProcess = 7;
|
||||
textureReload = true;
|
||||
}
|
||||
|
||||
if (textureReload)
|
||||
{
|
||||
UnloadImage(image); // Unload current image data
|
||||
image = LoadImage("resources/parrots.png"); // Re-load image data
|
||||
|
||||
// NOTE: Image processing is a costly CPU process to be done every frame,
|
||||
// If image processing is required in a frame-basis, it should be done
|
||||
// with a texture and by shaders
|
||||
switch (currentProcess)
|
||||
{
|
||||
case COLOR_GRAYSCALE: ImageColorGrayscale(&image); break;
|
||||
case COLOR_TINT: ImageColorTint(&image, GREEN); break;
|
||||
case COLOR_INVERT: ImageColorInvert(&image); break;
|
||||
case COLOR_CONTRAST: ImageColorContrast(&image, -40); break;
|
||||
case COLOR_BRIGHTNESS: ImageColorBrightness(&image, -80); break;
|
||||
case FLIP_VERTICAL: ImageFlipVertical(&image); break;
|
||||
case FLIP_HORIZONTAL: ImageFlipHorizontal(&image); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
Color *pixels = GetImageData(image); // Get pixel data from image (RGBA 32bit)
|
||||
UpdateTexture(texture, pixels); // Update texture with new image data
|
||||
free(pixels); // Unload pixels data from RAM
|
||||
|
||||
textureReload = false;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawText("IMAGE PROCESSING:", 40, 30, 10, DARKGRAY);
|
||||
|
||||
// Draw rectangles
|
||||
for (int i = 0; i < NUM_PROCESSES; i++)
|
||||
{
|
||||
if (i == currentProcess)
|
||||
{
|
||||
DrawRectangleRec(selectRecs[i], SKYBLUE);
|
||||
DrawRectangleLines(selectRecs[i].x, selectRecs[i].y, selectRecs[i].width, selectRecs[i].height, BLUE);
|
||||
DrawText(processText[i], selectRecs[i].x + selectRecs[i].width/2 - MeasureText(processText[i], 10)/2, selectRecs[i].y + 11, 10, DARKBLUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawRectangleRec(selectRecs[i], LIGHTGRAY);
|
||||
DrawRectangleLines(selectRecs[i].x, selectRecs[i].y, selectRecs[i].width, selectRecs[i].height, GRAY);
|
||||
DrawText(processText[i], selectRecs[i].x + selectRecs[i].width/2 - MeasureText(processText[i], 10)/2, selectRecs[i].y + 11, 10, DARKGRAY);
|
||||
}
|
||||
}
|
||||
|
||||
DrawTexture(texture, screenWidth - texture.width - 60, screenHeight/2 - texture.height/2, WHITE);
|
||||
DrawRectangleLines(screenWidth - texture.width - 60, screenHeight/2 - texture.height/2, texture.width, texture.height, BLACK);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadTexture(texture); // Unload texture from VRAM
|
||||
UnloadImage(image); // Unload image from RAM
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
BIN
examples/textures_image_processing.png
Normal file
After Width: | Height: | Size: 253 KiB |
|
@ -55,6 +55,10 @@ int main()
|
|||
ClearBackground(RAYWHITE);
|
||||
|
||||
// NOTE: Using DrawTexturePro() we can easily rotate and scale the part of the texture we draw
|
||||
// sourceRec defines the part of the texture we use for drawing
|
||||
// destRec defines the rectangle where our texture part will fit (scaling it to fit)
|
||||
// origin defines the point of the texture used as reference for rotation and scaling
|
||||
// rotation defines the texture rotation (using origin as rotation point)
|
||||
DrawTexturePro(guybrush, sourceRec, destRec, origin, rotation, WHITE);
|
||||
|
||||
DrawLine(destRec.x, 0, destRec.x, screenHeight, GRAY);
|
||||
|
|
349
games/arkanoid.c
Normal file
|
@ -0,0 +1,349 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib - sample game: arkanoid
|
||||
*
|
||||
* Sample game Marc Palau and Ramon Santamaria
|
||||
*
|
||||
* This game has been created using raylib v1.3 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
#include <emscripten/emscripten.h>
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Some Defines
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
#define PLAYER_MAX_LIFE 5
|
||||
#define LINES_OF_BRICKS 5
|
||||
#define BRICKS_PER_LINE 20
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
typedef enum GameScreen { LOGO, TITLE, GAMEPLAY, ENDING } GameScreen;
|
||||
|
||||
typedef struct Player {
|
||||
Vector2 position;
|
||||
Vector2 size;
|
||||
int life;
|
||||
} Player;
|
||||
|
||||
typedef struct Ball {
|
||||
Vector2 position;
|
||||
Vector2 speed;
|
||||
int radius;
|
||||
bool active;
|
||||
} Ball;
|
||||
|
||||
typedef struct Brick {
|
||||
Vector2 position;
|
||||
bool active;
|
||||
} Brick;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Global Variables Declaration
|
||||
//------------------------------------------------------------------------------------
|
||||
static int screenWidth = 800;
|
||||
static int screenHeight = 450;
|
||||
|
||||
static int framesCounter;
|
||||
static bool gameOver;
|
||||
static bool pause;
|
||||
|
||||
static Player player;
|
||||
static Ball ball;
|
||||
static Brick brick[LINES_OF_BRICKS][BRICKS_PER_LINE];
|
||||
static Vector2 brickSize;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module Functions Declaration (local)
|
||||
//------------------------------------------------------------------------------------
|
||||
static void InitGame(void); // Initialize game
|
||||
static void UpdateGame(void); // Update game (one frame)
|
||||
static void DrawGame(void); // Draw game (one frame)
|
||||
static void UnloadGame(void); // Unload game
|
||||
static void UpdateDrawFrame(void); // Update and Draw (one frame)
|
||||
|
||||
// Additional module functions
|
||||
static void UpdateBall(void);
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "sample game: arkanoid");
|
||||
|
||||
InitGame();
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
emscripten_set_main_loop(UpdateDrawFrame, 0, 1);
|
||||
#else
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateGame();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
DrawGame();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
#endif
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadGame(); // Unload loaded data (textures, sounds, models...)
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module Functions Definitions (local)
|
||||
//------------------------------------------------------------------------------------
|
||||
|
||||
// Initialize game variables
|
||||
void InitGame(void)
|
||||
{
|
||||
brickSize = (Vector2){ GetScreenWidth()/BRICKS_PER_LINE, 40 };
|
||||
|
||||
// Initialize player
|
||||
player.position = (Vector2){ screenWidth/2, screenHeight*7/8 };
|
||||
player.size = (Vector2){ screenWidth/10, 20 };
|
||||
player.life = PLAYER_MAX_LIFE;
|
||||
|
||||
// Initialize ball
|
||||
ball.position = (Vector2){ screenWidth/2, screenHeight*7/8 - 30 };
|
||||
ball.speed = (Vector2){ 0, 0 };
|
||||
ball.radius = 7;
|
||||
ball.active = false;
|
||||
|
||||
// Initialize bricks
|
||||
int initialDownPosition = 50;
|
||||
|
||||
for (int i = 0; i < LINES_OF_BRICKS; i++)
|
||||
{
|
||||
for (int j = 0; j < BRICKS_PER_LINE; j++)
|
||||
{
|
||||
brick[i][j].position = (Vector2){ j*brickSize.x + brickSize.x/2, i*brickSize.y + initialDownPosition };
|
||||
brick[i][j].active = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update game (one frame)
|
||||
void UpdateGame(void)
|
||||
{
|
||||
if (!gameOver)
|
||||
{
|
||||
if (IsKeyPressed('P')) pause = !pause;
|
||||
|
||||
if (!pause)
|
||||
{
|
||||
// Player movement
|
||||
if (IsKeyDown(KEY_LEFT)) player.position.x -= 5;
|
||||
if ((player.position.x - player.size.x/2) <= 0) player.position.x = player.size.x/2;
|
||||
if (IsKeyDown(KEY_RIGHT)) player.position.x += 5;
|
||||
if ((player.position.x + player.size.x/2) >= screenWidth) player.position.x = screenWidth - player.size.x/2;
|
||||
|
||||
// Launch ball
|
||||
if (!ball.active)
|
||||
{
|
||||
if (IsKeyPressed(KEY_SPACE))
|
||||
{
|
||||
ball.active = true;
|
||||
ball.speed = (Vector2){ 0, -5 };
|
||||
}
|
||||
}
|
||||
|
||||
UpdateBall();
|
||||
|
||||
// Game over logic
|
||||
if (player.life <= 0) gameOver = true;
|
||||
else
|
||||
{
|
||||
gameOver = true;
|
||||
|
||||
for (int i = 0; i < LINES_OF_BRICKS; i++)
|
||||
{
|
||||
for (int j = 0; j < BRICKS_PER_LINE; j++)
|
||||
{
|
||||
if (brick[i][j].active) gameOver = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsKeyPressed(KEY_ENTER))
|
||||
{
|
||||
InitGame();
|
||||
gameOver = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Draw game (one frame)
|
||||
void DrawGame(void)
|
||||
{
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
if (!gameOver)
|
||||
{
|
||||
// Draw player bar
|
||||
DrawRectangle(player.position.x - player.size.x/2, player.position.y - player.size.y/2, player.size.x, player.size.y, BLACK);
|
||||
|
||||
// Draw player lives
|
||||
for (int i = 0; i < player.life; i++) DrawRectangle(20 + 40*i, screenHeight - 30, 35, 10, LIGHTGRAY);
|
||||
|
||||
// Draw ball
|
||||
DrawCircleV(ball.position, ball.radius, MAROON);
|
||||
|
||||
// Draw bricks
|
||||
for (int i = 0; i < LINES_OF_BRICKS; i++)
|
||||
{
|
||||
for (int j = 0; j < BRICKS_PER_LINE; j++)
|
||||
{
|
||||
if (brick[i][j].active)
|
||||
{
|
||||
if ((i + j) % 2 == 0) DrawRectangle(brick[i][j].position.x - brickSize.x/2, brick[i][j].position.y - brickSize.y/2, brickSize.x, brickSize.y, GRAY);
|
||||
else DrawRectangle(brick[i][j].position.x - brickSize.x/2, brick[i][j].position.y - brickSize.y/2, brickSize.x, brickSize.y, DARKGRAY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pause) DrawText("GAME PAUSED", screenWidth/2 - MeasureText("GAME PAUSED", 40)/2, screenHeight/2 - 40, 40, GRAY);
|
||||
}
|
||||
else DrawText("PRESS [ENTER] TO PLAY AGAIN", GetScreenWidth()/2 - MeasureText("PRESS [ENTER] TO PLAY AGAIN", 20)/2, GetScreenHeight()/2 - 50, 20, GRAY);
|
||||
|
||||
EndDrawing();
|
||||
}
|
||||
|
||||
// Unload game variables
|
||||
void UnloadGame(void)
|
||||
{
|
||||
// TODO: Unload all dynamic loaded data (textures, sounds, models...)
|
||||
}
|
||||
|
||||
// Update and Draw (one frame)
|
||||
void UpdateDrawFrame(void)
|
||||
{
|
||||
UpdateGame();
|
||||
DrawGame();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Additional module functions
|
||||
//--------------------------------------------------------------------------------------
|
||||
static void UpdateBall()
|
||||
{
|
||||
// Update position
|
||||
if (ball.active)
|
||||
{
|
||||
ball.position.x += ball.speed.x;
|
||||
ball.position.y += ball.speed.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
ball.position = (Vector2){ player.position.x, screenHeight*7/8 - 30 };
|
||||
}
|
||||
|
||||
// Bounce in x
|
||||
if (((ball.position.x + ball.radius) >= screenWidth) || ((ball.position.x - ball.radius) <= 0)) ball.speed.x *= -1;
|
||||
|
||||
// Bounce in y
|
||||
if ((ball.position.y - ball.radius) <= 0) ball.speed.y *= -1;
|
||||
|
||||
// Ball reaches bottom of the screen
|
||||
if ((ball.position.y + ball.radius) >= screenHeight)
|
||||
{
|
||||
ball.speed = (Vector2){ 0, 0 };
|
||||
ball.active = false;
|
||||
|
||||
player.life--;
|
||||
}
|
||||
|
||||
// Collision logic: ball vs player
|
||||
if (CheckCollisionCircleRec(ball.position, ball.radius,
|
||||
(Rectangle){ player.position.x - player.size.x/2, player.position.y - player.size.y/2, player.size.x, player.size.y}))
|
||||
{
|
||||
if (ball.speed.y > 0)
|
||||
{
|
||||
ball.speed.y *= -1;
|
||||
ball.speed.x = (ball.position.x - player.position.x)/(player.size.x/2)*5;
|
||||
}
|
||||
}
|
||||
|
||||
// Collision logic: ball vs bricks
|
||||
for (int i = 0; i < LINES_OF_BRICKS; i++)
|
||||
{
|
||||
for (int j = 0; j < BRICKS_PER_LINE; j++)
|
||||
{
|
||||
if (brick[i][j].active)
|
||||
{
|
||||
// Hit below
|
||||
if (((ball.position.y - ball.radius) <= (brick[i][j].position.y + brickSize.y/2)) &&
|
||||
((ball.position.y - ball.radius) > (brick[i][j].position.y + brickSize.y/2 + ball.speed.y)) &&
|
||||
((fabs(ball.position.x - brick[i][j].position.x)) < (brickSize.x/2 + ball.radius*2/3)) && (ball.speed.y < 0))
|
||||
{
|
||||
brick[i][j].active = false;
|
||||
ball.speed.y *= -1;
|
||||
}
|
||||
// Hit above
|
||||
else if (((ball.position.y + ball.radius) >= (brick[i][j].position.y - brickSize.y/2)) &&
|
||||
((ball.position.y + ball.radius) < (brick[i][j].position.y - brickSize.y/2 + ball.speed.y)) &&
|
||||
((fabs(ball.position.x - brick[i][j].position.x)) < (brickSize.x/2 + ball.radius*2/3)) && (ball.speed.y > 0))
|
||||
{
|
||||
brick[i][j].active = false;
|
||||
ball.speed.y *= -1;
|
||||
}
|
||||
// Hit left
|
||||
else if (((ball.position.x + ball.radius) >= (brick[i][j].position.x - brickSize.x/2)) &&
|
||||
((ball.position.x + ball.radius) < (brick[i][j].position.x - brickSize.x/2 + ball.speed.x)) &&
|
||||
((fabs(ball.position.y - brick[i][j].position.y)) < (brickSize.y/2 + ball.radius*2/3)) && (ball.speed.x > 0))
|
||||
{
|
||||
brick[i][j].active = false;
|
||||
ball.speed.x *= -1;
|
||||
}
|
||||
// Hit right
|
||||
else if (((ball.position.x - ball.radius) <= (brick[i][j].position.x + brickSize.x/2)) &&
|
||||
((ball.position.x - ball.radius) > (brick[i][j].position.x + brickSize.x/2 + ball.speed.x)) &&
|
||||
((fabs(ball.position.y - brick[i][j].position.y)) < (brickSize.y/2 + ball.radius*2/3)) && (ball.speed.x < 0))
|
||||
{
|
||||
brick[i][j].active = false;
|
||||
ball.speed.x *= -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
579
games/asteroids.c
Normal file
|
@ -0,0 +1,579 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib - sample game: asteroids
|
||||
*
|
||||
* Sample game developed by Ian Eito, Albert Martos and Ramon Santamaria
|
||||
*
|
||||
* This game has been created using raylib v1.3 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
#include <emscripten/emscripten.h>
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Some Defines
|
||||
//----------------------------------------------------------------------------------
|
||||
#define PLAYER_BASE_SIZE 20.0f
|
||||
#define PLAYER_SPEED 6.0f
|
||||
#define PLAYER_MAX_SHOOTS 10
|
||||
|
||||
#define METEORS_SPEED 2
|
||||
#define MAX_BIG_METEORS 4
|
||||
#define MAX_MEDIUM_METEORS 8
|
||||
#define MAX_SMALL_METEORS 16
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
typedef struct Player {
|
||||
Vector2 position;
|
||||
Vector2 speed;
|
||||
float acceleration;
|
||||
float rotation;
|
||||
Vector3 collider;
|
||||
Color color;
|
||||
} Player;
|
||||
|
||||
typedef struct Shoot {
|
||||
Vector2 position;
|
||||
Vector2 speed;
|
||||
float radius;
|
||||
float rotation;
|
||||
int lifeSpawn;
|
||||
bool active;
|
||||
Color color;
|
||||
} Shoot;
|
||||
|
||||
typedef struct Meteor {
|
||||
Vector2 position;
|
||||
Vector2 speed;
|
||||
float radius;
|
||||
bool active;
|
||||
Color color;
|
||||
} Meteor;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Global Variables Declaration
|
||||
//------------------------------------------------------------------------------------
|
||||
static int screenWidth = 800;
|
||||
static int screenHeight = 450;
|
||||
|
||||
static int framesCounter;
|
||||
static bool gameOver;
|
||||
static bool pause;
|
||||
static bool victory;
|
||||
|
||||
// NOTE: Defined triangle is isosceles with common angles of 70 degrees.
|
||||
static float shipHeight;
|
||||
|
||||
static Player player;
|
||||
static Shoot shoot[PLAYER_MAX_SHOOTS];
|
||||
static Meteor bigMeteor[MAX_BIG_METEORS];
|
||||
static Meteor mediumMeteor[MAX_MEDIUM_METEORS];
|
||||
static Meteor smallMeteor[MAX_SMALL_METEORS];
|
||||
|
||||
static int countMediumMeteors;
|
||||
static int countSmallMeteors;
|
||||
static int meteorsDestroyed;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module Functions Declaration (local)
|
||||
//------------------------------------------------------------------------------------
|
||||
static void InitGame(void); // Initialize game
|
||||
static void UpdateGame(void); // Update game (one frame)
|
||||
static void DrawGame(void); // Draw game (one frame)
|
||||
static void UnloadGame(void); // Unload game
|
||||
static void UpdateDrawFrame(void); // Update and Draw (one frame)
|
||||
|
||||
static void InitShoot(Shoot shoot);
|
||||
static void DrawSpaceship(Vector2 position, float rotation, Color color);
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "sample game: asteroids");
|
||||
|
||||
InitGame();
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
emscripten_set_main_loop(UpdateDrawFrame, 0, 1);
|
||||
#else
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateGame();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
DrawGame();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
#endif
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadGame(); // Unload loaded data (textures, sounds, models...)
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module Functions Definitions (local)
|
||||
//------------------------------------------------------------------------------------
|
||||
|
||||
// Initialize game variables
|
||||
void InitGame(void)
|
||||
{
|
||||
int posx, posy;
|
||||
int velx, vely;
|
||||
bool correctRange = false;
|
||||
victory = false;
|
||||
pause = false;
|
||||
|
||||
shipHeight = (PLAYER_BASE_SIZE/2)/tanf(20*DEG2RAD);
|
||||
|
||||
// Initialization player
|
||||
player.position = (Vector2){screenWidth/2, screenHeight/2 - shipHeight/2};
|
||||
player.speed = (Vector2){0, 0};
|
||||
player.acceleration = 0;
|
||||
player.rotation = 0;
|
||||
player.collider = (Vector3){player.position.x + sin(player.rotation*DEG2RAD)*(shipHeight/2.5f), player.position.y - cos(player.rotation*DEG2RAD)*(shipHeight/2.5f), 12};
|
||||
player.color = LIGHTGRAY;
|
||||
|
||||
meteorsDestroyed = 0;
|
||||
|
||||
// Initialization shoot
|
||||
for (int i = 0; i < PLAYER_MAX_SHOOTS; i++)
|
||||
{
|
||||
shoot[i].position = (Vector2){0, 0};
|
||||
shoot[i].speed = (Vector2){0, 0};
|
||||
shoot[i].radius = 2;
|
||||
shoot[i].active = false;
|
||||
shoot[i].lifeSpawn = 0;
|
||||
shoot[i].color = WHITE;
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_BIG_METEORS; i++)
|
||||
{
|
||||
posx = GetRandomValue(0, screenWidth);
|
||||
|
||||
while(!correctRange)
|
||||
{
|
||||
if (posx > screenWidth/2 - 150 && posx < screenWidth/2 + 150) posx = GetRandomValue(0, screenWidth);
|
||||
else correctRange = true;
|
||||
}
|
||||
|
||||
correctRange = false;
|
||||
|
||||
posy = GetRandomValue(0, screenHeight);
|
||||
|
||||
while(!correctRange)
|
||||
{
|
||||
if (posy > screenHeight/2 - 150 && posy < screenHeight/2 + 150) posy = GetRandomValue(0, screenHeight);
|
||||
else correctRange = true;
|
||||
}
|
||||
|
||||
bigMeteor[i].position = (Vector2){posx, posy};
|
||||
|
||||
correctRange = false;
|
||||
velx = GetRandomValue(-METEORS_SPEED, METEORS_SPEED);
|
||||
vely = GetRandomValue(-METEORS_SPEED, METEORS_SPEED);
|
||||
|
||||
while(!correctRange)
|
||||
{
|
||||
if (velx == 0 && vely == 0)
|
||||
{
|
||||
velx = GetRandomValue(-METEORS_SPEED, METEORS_SPEED);
|
||||
vely = GetRandomValue(-METEORS_SPEED, METEORS_SPEED);
|
||||
}
|
||||
else correctRange = true;
|
||||
}
|
||||
|
||||
bigMeteor[i].speed = (Vector2){velx, vely};
|
||||
bigMeteor[i].radius = 40;
|
||||
bigMeteor[i].active = true;
|
||||
bigMeteor[i].color = BLUE;
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_MEDIUM_METEORS; i++)
|
||||
{
|
||||
mediumMeteor[i].position = (Vector2){-100, -100};
|
||||
mediumMeteor[i].speed = (Vector2){0,0};
|
||||
mediumMeteor[i].radius = 20;
|
||||
mediumMeteor[i].active = false;
|
||||
mediumMeteor[i].color = BLUE;
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_SMALL_METEORS; i++)
|
||||
{
|
||||
smallMeteor[i].position = (Vector2){-100, -100};
|
||||
smallMeteor[i].speed = (Vector2){0,0};
|
||||
smallMeteor[i].radius = 10;
|
||||
smallMeteor[i].active = false;
|
||||
smallMeteor[i].color = BLUE;
|
||||
}
|
||||
|
||||
countMediumMeteors = 0;
|
||||
countSmallMeteors = 0;
|
||||
}
|
||||
|
||||
// Update game (one frame)
|
||||
void UpdateGame(void)
|
||||
{
|
||||
if (!gameOver)
|
||||
{
|
||||
if (IsKeyPressed('P')) pause = !pause;
|
||||
|
||||
if (!pause)
|
||||
{
|
||||
// Player logic
|
||||
|
||||
// Rotation
|
||||
if (IsKeyDown(KEY_LEFT)) player.rotation -= 5;
|
||||
if (IsKeyDown(KEY_RIGHT)) player.rotation += 5;
|
||||
|
||||
// Speed
|
||||
player.speed.x = sin(player.rotation*DEG2RAD)*PLAYER_SPEED;
|
||||
player.speed.y = cos(player.rotation*DEG2RAD)*PLAYER_SPEED;
|
||||
|
||||
// Controller
|
||||
if (IsKeyDown(KEY_UP))
|
||||
{
|
||||
if (player.acceleration < 1) player.acceleration += 0.04f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (player.acceleration > 0) player.acceleration -= 0.02f;
|
||||
else if (player.acceleration < 0) player.acceleration = 0;
|
||||
}
|
||||
if (IsKeyDown(KEY_DOWN))
|
||||
{
|
||||
if (player.acceleration > 0) player.acceleration -= 0.04f;
|
||||
else if (player.acceleration < 0) player.acceleration = 0;
|
||||
}
|
||||
|
||||
// Movement
|
||||
player.position.x += (player.speed.x*player.acceleration);
|
||||
player.position.y -= (player.speed.y*player.acceleration);
|
||||
|
||||
// Wall behaviour for player
|
||||
if (player.position.x > screenWidth + shipHeight) player.position.x = -(shipHeight);
|
||||
else if (player.position.x < -(shipHeight)) player.position.x = screenWidth + shipHeight;
|
||||
if (player.position.y > (screenHeight + shipHeight)) player.position.y = -(shipHeight);
|
||||
else if (player.position.y < -(shipHeight)) player.position.y = screenHeight + shipHeight;
|
||||
|
||||
// Activation of shoot
|
||||
if (IsKeyPressed(KEY_SPACE))
|
||||
{
|
||||
for (int i = 0; i < PLAYER_MAX_SHOOTS; i++)
|
||||
{
|
||||
if (!shoot[i].active)
|
||||
{
|
||||
shoot[i].position = (Vector2){ player.position.x + sin(player.rotation*DEG2RAD)*(shipHeight), player.position.y - cos(player.rotation*DEG2RAD)*(shipHeight) };
|
||||
shoot[i].active = true;
|
||||
shoot[i].speed.x = 1.5*sin(player.rotation*DEG2RAD)*PLAYER_SPEED;
|
||||
shoot[i].speed.y = 1.5*cos(player.rotation*DEG2RAD)*PLAYER_SPEED;
|
||||
shoot[i].rotation = player.rotation;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Shoot life timer
|
||||
for (int i = 0; i < PLAYER_MAX_SHOOTS; i++)
|
||||
{
|
||||
if (shoot[i].active) shoot[i].lifeSpawn++;
|
||||
}
|
||||
|
||||
// Shot logic
|
||||
for (int i = 0; i < PLAYER_MAX_SHOOTS; i++)
|
||||
{
|
||||
if (shoot[i].active)
|
||||
{
|
||||
// Movement
|
||||
shoot[i].position.x += shoot[i].speed.x;
|
||||
shoot[i].position.y -= shoot[i].speed.y;
|
||||
|
||||
// Wall behaviour for shoot
|
||||
if (shoot[i].position.x > screenWidth + shoot[i].radius)
|
||||
{
|
||||
shoot[i].active = false;
|
||||
shoot[i].lifeSpawn = 0;
|
||||
}
|
||||
else if (shoot[i].position.x < 0 - shoot[i].radius)
|
||||
{
|
||||
shoot[i].active = false;
|
||||
shoot[i].lifeSpawn = 0;
|
||||
}
|
||||
if (shoot[i].position.y > screenHeight + shoot[i].radius)
|
||||
{
|
||||
shoot[i].active = false;
|
||||
shoot[i].lifeSpawn = 0;
|
||||
}
|
||||
else if (shoot[i].position.y < 0 - shoot[i].radius)
|
||||
{
|
||||
shoot[i].active = false;
|
||||
shoot[i].lifeSpawn = 0;
|
||||
}
|
||||
|
||||
// Life of shoot
|
||||
if (shoot[i].lifeSpawn >= 60)
|
||||
{
|
||||
shoot[i].position = (Vector2){0, 0};
|
||||
shoot[i].speed = (Vector2){0, 0};
|
||||
shoot[i].lifeSpawn = 0;
|
||||
shoot[i].active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Collision Player to meteors
|
||||
player.collider = (Vector3){player.position.x + sin(player.rotation*DEG2RAD)*(shipHeight/2.5f), player.position.y - cos(player.rotation*DEG2RAD)*(shipHeight/2.5f), 12};
|
||||
|
||||
for (int a = 0; a < MAX_BIG_METEORS; a++)
|
||||
{
|
||||
if (CheckCollisionCircles((Vector2){player.collider.x, player.collider.y}, player.collider.z, bigMeteor[a].position, bigMeteor[a].radius) && bigMeteor[a].active) gameOver = true;
|
||||
}
|
||||
|
||||
for (int a = 0; a < MAX_MEDIUM_METEORS; a++)
|
||||
{
|
||||
if (CheckCollisionCircles((Vector2){player.collider.x, player.collider.y}, player.collider.z, mediumMeteor[a].position, mediumMeteor[a].radius) && mediumMeteor[a].active) gameOver = true;
|
||||
}
|
||||
|
||||
for (int a = 0; a < MAX_SMALL_METEORS; a++)
|
||||
{
|
||||
if (CheckCollisionCircles((Vector2){player.collider.x, player.collider.y}, player.collider.z, smallMeteor[a].position, smallMeteor[a].radius) && smallMeteor[a].active) gameOver = true;
|
||||
}
|
||||
|
||||
// Meteor logic
|
||||
for (int i = 0; i < MAX_BIG_METEORS; i++)
|
||||
{
|
||||
if (bigMeteor[i].active)
|
||||
{
|
||||
// movement
|
||||
bigMeteor[i].position.x += bigMeteor[i].speed.x;
|
||||
bigMeteor[i].position.y += bigMeteor[i].speed.y;
|
||||
|
||||
// wall behaviour
|
||||
if (bigMeteor[i].position.x > screenWidth + bigMeteor[i].radius) bigMeteor[i].position.x = -(bigMeteor[i].radius);
|
||||
else if (bigMeteor[i].position.x < 0 - bigMeteor[i].radius) bigMeteor[i].position.x = screenWidth + bigMeteor[i].radius;
|
||||
if (bigMeteor[i].position.y > screenHeight + bigMeteor[i].radius) bigMeteor[i].position.y = -(bigMeteor[i].radius);
|
||||
else if (bigMeteor[i].position.y < 0 - bigMeteor[i].radius) bigMeteor[i].position.y = screenHeight + bigMeteor[i].radius;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_MEDIUM_METEORS; i++)
|
||||
{
|
||||
if (mediumMeteor[i].active)
|
||||
{
|
||||
// movement
|
||||
mediumMeteor[i].position.x += mediumMeteor[i].speed.x;
|
||||
mediumMeteor[i].position.y += mediumMeteor[i].speed.y;
|
||||
|
||||
// wall behaviour
|
||||
if (mediumMeteor[i].position.x > screenWidth + mediumMeteor[i].radius) mediumMeteor[i].position.x = -(mediumMeteor[i].radius);
|
||||
else if (mediumMeteor[i].position.x < 0 - mediumMeteor[i].radius) mediumMeteor[i].position.x = screenWidth + mediumMeteor[i].radius;
|
||||
if (mediumMeteor[i].position.y > screenHeight + mediumMeteor[i].radius) mediumMeteor[i].position.y = -(mediumMeteor[i].radius);
|
||||
else if (mediumMeteor[i].position.y < 0 - mediumMeteor[i].radius) mediumMeteor[i].position.y = screenHeight + mediumMeteor[i].radius;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_SMALL_METEORS; i++)
|
||||
{
|
||||
if (smallMeteor[i].active)
|
||||
{
|
||||
// movement
|
||||
smallMeteor[i].position.x += smallMeteor[i].speed.x;
|
||||
smallMeteor[i].position.y += smallMeteor[i].speed.y;
|
||||
|
||||
// wall behaviour
|
||||
if (smallMeteor[i].position.x > screenWidth + smallMeteor[i].radius) smallMeteor[i].position.x = -(smallMeteor[i].radius);
|
||||
else if (smallMeteor[i].position.x < 0 - smallMeteor[i].radius) smallMeteor[i].position.x = screenWidth + smallMeteor[i].radius;
|
||||
if (smallMeteor[i].position.y > screenHeight + smallMeteor[i].radius) smallMeteor[i].position.y = -(smallMeteor[i].radius);
|
||||
else if (smallMeteor[i].position.y < 0 - smallMeteor[i].radius) smallMeteor[i].position.y = screenHeight + smallMeteor[i].radius;
|
||||
}
|
||||
}
|
||||
|
||||
// Collision behaviour
|
||||
for (int i = 0; i < PLAYER_MAX_SHOOTS; i++)
|
||||
{
|
||||
if ((shoot[i].active))
|
||||
{
|
||||
for (int a = 0; a < MAX_BIG_METEORS; a++)
|
||||
{
|
||||
if (bigMeteor[a].active && CheckCollisionCircles(shoot[i].position, shoot[i].radius, bigMeteor[a].position, bigMeteor[a].radius))
|
||||
{
|
||||
shoot[i].active = false;
|
||||
shoot[i].lifeSpawn = 0;
|
||||
bigMeteor[a].active = false;
|
||||
meteorsDestroyed++;
|
||||
for (int j = 0; j < 2; j ++)
|
||||
{
|
||||
if (countMediumMeteors%2 == 0)
|
||||
{
|
||||
mediumMeteor[countMediumMeteors].position = (Vector2){bigMeteor[a].position.x, bigMeteor[a].position.y};
|
||||
mediumMeteor[countMediumMeteors].speed = (Vector2){cos(shoot[i].rotation*DEG2RAD)*METEORS_SPEED*-1, sin(shoot[i].rotation*DEG2RAD)*METEORS_SPEED*-1};
|
||||
}
|
||||
else
|
||||
{
|
||||
mediumMeteor[countMediumMeteors].position = (Vector2){bigMeteor[a].position.x, bigMeteor[a].position.y};
|
||||
mediumMeteor[countMediumMeteors].speed = (Vector2){cos(shoot[i].rotation*DEG2RAD)*METEORS_SPEED, sin(shoot[i].rotation*DEG2RAD)*METEORS_SPEED};
|
||||
}
|
||||
|
||||
mediumMeteor[countMediumMeteors].active = true;
|
||||
countMediumMeteors ++;
|
||||
}
|
||||
//bigMeteor[a].position = (Vector2){-100, -100};
|
||||
bigMeteor[a].color = RED;
|
||||
a = MAX_BIG_METEORS;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((shoot[i].active))
|
||||
{
|
||||
for (int b = 0; b < MAX_MEDIUM_METEORS; b++)
|
||||
{
|
||||
if (mediumMeteor[b].active && CheckCollisionCircles(shoot[i].position, shoot[i].radius, mediumMeteor[b].position, mediumMeteor[b].radius))
|
||||
{
|
||||
shoot[i].active = false;
|
||||
shoot[i].lifeSpawn = 0;
|
||||
mediumMeteor[b].active = false;
|
||||
meteorsDestroyed++;
|
||||
for (int j = 0; j < 2; j ++)
|
||||
{
|
||||
if (countSmallMeteors%2 == 0)
|
||||
{
|
||||
smallMeteor[countSmallMeteors].position = (Vector2){mediumMeteor[b].position.x, mediumMeteor[b].position.y};
|
||||
smallMeteor[countSmallMeteors].speed = (Vector2){cos(shoot[i].rotation*DEG2RAD)*METEORS_SPEED*-1, sin(shoot[i].rotation*DEG2RAD)*METEORS_SPEED*-1};
|
||||
}
|
||||
else
|
||||
{
|
||||
smallMeteor[countSmallMeteors].position = (Vector2){mediumMeteor[b].position.x, mediumMeteor[b].position.y};
|
||||
smallMeteor[countSmallMeteors].speed = (Vector2){cos(shoot[i].rotation*DEG2RAD)*METEORS_SPEED, sin(shoot[i].rotation*DEG2RAD)*METEORS_SPEED};
|
||||
}
|
||||
|
||||
smallMeteor[countSmallMeteors].active = true;
|
||||
countSmallMeteors ++;
|
||||
}
|
||||
//mediumMeteor[b].position = (Vector2){-100, -100};
|
||||
mediumMeteor[b].color = GREEN;
|
||||
b = MAX_MEDIUM_METEORS;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((shoot[i].active))
|
||||
{
|
||||
for (int c = 0; c < MAX_SMALL_METEORS; c++)
|
||||
{
|
||||
if (smallMeteor[c].active && CheckCollisionCircles(shoot[i].position, shoot[i].radius, smallMeteor[c].position, smallMeteor[c].radius))
|
||||
{
|
||||
shoot[i].active = false;
|
||||
shoot[i].lifeSpawn = 0;
|
||||
smallMeteor[c].active = false;
|
||||
meteorsDestroyed++;
|
||||
smallMeteor[c].color = YELLOW;
|
||||
// smallMeteor[c].position = (Vector2){-100, -100};
|
||||
c = MAX_SMALL_METEORS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (meteorsDestroyed == MAX_BIG_METEORS + MAX_MEDIUM_METEORS + MAX_SMALL_METEORS) victory = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsKeyPressed(KEY_ENTER))
|
||||
{
|
||||
InitGame();
|
||||
gameOver = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw game (one frame)
|
||||
void DrawGame(void)
|
||||
{
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
if (!gameOver)
|
||||
{
|
||||
// Draw spaceship
|
||||
Vector2 v1 = { player.position.x + sinf(player.rotation*DEG2RAD)*(shipHeight), player.position.y - cosf(player.rotation*DEG2RAD)*(shipHeight) };
|
||||
Vector2 v2 = { player.position.x - cosf(player.rotation*DEG2RAD)*(PLAYER_BASE_SIZE/2), player.position.y - sinf(player.rotation*DEG2RAD)*(PLAYER_BASE_SIZE/2) };
|
||||
Vector2 v3 = { player.position.x + cosf(player.rotation*DEG2RAD)*(PLAYER_BASE_SIZE/2), player.position.y + sinf(player.rotation*DEG2RAD)*(PLAYER_BASE_SIZE/2) };
|
||||
DrawTriangle(v1, v2, v3, MAROON);
|
||||
|
||||
// Draw meteors
|
||||
for (int i = 0; i < MAX_BIG_METEORS; i++)
|
||||
{
|
||||
if (bigMeteor[i].active) DrawCircleV(bigMeteor[i].position, bigMeteor[i].radius, DARKGRAY);
|
||||
else DrawCircleV(bigMeteor[i].position, bigMeteor[i].radius, Fade(LIGHTGRAY, 0.3f));
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_MEDIUM_METEORS; i++)
|
||||
{
|
||||
if (mediumMeteor[i].active) DrawCircleV(mediumMeteor[i].position, mediumMeteor[i].radius, GRAY);
|
||||
else DrawCircleV(mediumMeteor[i].position, mediumMeteor[i].radius, Fade(LIGHTGRAY, 0.3f));
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_SMALL_METEORS; i++)
|
||||
{
|
||||
if (smallMeteor[i].active) DrawCircleV(smallMeteor[i].position, smallMeteor[i].radius, GRAY);
|
||||
else DrawCircleV(smallMeteor[i].position, smallMeteor[i].radius, Fade(LIGHTGRAY, 0.3f));
|
||||
}
|
||||
|
||||
// Draw shoot
|
||||
for (int i = 0; i < PLAYER_MAX_SHOOTS; i++)
|
||||
{
|
||||
if (shoot[i].active) DrawCircleV(shoot[i].position, shoot[i].radius, BLACK);
|
||||
}
|
||||
|
||||
if (victory) DrawText("VICTORY", screenWidth/2 - MeasureText("VICTORY", 20)/2, screenHeight/2, 20, LIGHTGRAY);
|
||||
|
||||
if (pause) DrawText("GAME PAUSED", screenWidth/2 - MeasureText("GAME PAUSED", 40)/2, screenHeight/2 - 40, 40, GRAY);
|
||||
}
|
||||
else DrawText("PRESS [ENTER] TO PLAY AGAIN", GetScreenWidth()/2 - MeasureText("PRESS [ENTER] TO PLAY AGAIN", 20)/2, GetScreenHeight()/2 - 50, 20, GRAY);
|
||||
|
||||
EndDrawing();
|
||||
}
|
||||
|
||||
// Unload game variables
|
||||
void UnloadGame(void)
|
||||
{
|
||||
// TODO: Unload all dynamic loaded data (textures, sounds, models...)
|
||||
}
|
||||
|
||||
// Update and Draw (one frame)
|
||||
void UpdateDrawFrame(void)
|
||||
{
|
||||
UpdateGame();
|
||||
DrawGame();
|
||||
}
|
383
games/asteroids_survival.c
Normal file
|
@ -0,0 +1,383 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib - sample game: asteroids survival
|
||||
*
|
||||
* Sample game developed by Ian Eito, Albert Martos and Ramon Santamaria
|
||||
*
|
||||
* This game has been created using raylib v1.3 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
#include <emscripten/emscripten.h>
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Some Defines
|
||||
//----------------------------------------------------------------------------------
|
||||
#define PLAYER_BASE_SIZE 20.0f
|
||||
#define PLAYER_SPEED 6.0f
|
||||
#define PLAYER_MAX_SHOOTS 10
|
||||
|
||||
#define METEORS_SPEED 2
|
||||
#define MAX_MEDIUM_METEORS 8
|
||||
#define MAX_SMALL_METEORS 16
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
typedef struct Player {
|
||||
Vector2 position;
|
||||
Vector2 speed;
|
||||
float acceleration;
|
||||
float rotation;
|
||||
Vector3 collider;
|
||||
Color color;
|
||||
} Player;
|
||||
|
||||
typedef struct Meteor {
|
||||
Vector2 position;
|
||||
Vector2 speed;
|
||||
float radius;
|
||||
bool active;
|
||||
Color color;
|
||||
} Meteor;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Global Variables Declaration
|
||||
//------------------------------------------------------------------------------------
|
||||
static int screenWidth = 800;
|
||||
static int screenHeight = 450;
|
||||
|
||||
static int framesCounter;
|
||||
static bool gameOver;
|
||||
static bool pause;
|
||||
|
||||
// NOTE: Defined triangle is isosceles with common angles of 70 degrees.
|
||||
static float shipHeight;
|
||||
|
||||
static Player player;
|
||||
static Meteor mediumMeteor[MAX_MEDIUM_METEORS];
|
||||
static Meteor smallMeteor[MAX_SMALL_METEORS];
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module Functions Declaration (local)
|
||||
//------------------------------------------------------------------------------------
|
||||
static void InitGame(void); // Initialize game
|
||||
static void UpdateGame(void); // Update game (one frame)
|
||||
static void DrawGame(void); // Draw game (one frame)
|
||||
static void UnloadGame(void); // Unload game
|
||||
static void UpdateDrawFrame(void); // Update and Draw (one frame)
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "sample game: asteroids survival");
|
||||
|
||||
InitGame();
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
emscripten_set_main_loop(UpdateDrawFrame, 0, 1);
|
||||
#else
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateGame();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
DrawGame();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
#endif
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadGame(); // Unload loaded data (textures, sounds, models...)
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module Functions Definitions (local)
|
||||
//------------------------------------------------------------------------------------
|
||||
|
||||
// Initialize game variables
|
||||
void InitGame(void)
|
||||
{
|
||||
int posx, posy;
|
||||
int velx, vely;
|
||||
bool correctRange = false;
|
||||
|
||||
pause = false;
|
||||
|
||||
framesCounter = 0;
|
||||
|
||||
shipHeight = (PLAYER_BASE_SIZE/2)/tanf(20*DEG2RAD);
|
||||
|
||||
// Initialization player
|
||||
player.position = (Vector2){screenWidth/2, screenHeight/2 - shipHeight/2};
|
||||
player.speed = (Vector2){0, 0};
|
||||
player.acceleration = 0;
|
||||
player.rotation = 0;
|
||||
player.collider = (Vector3){player.position.x + sin(player.rotation*DEG2RAD)*(shipHeight/2.5f), player.position.y - cos(player.rotation*DEG2RAD)*(shipHeight/2.5f), 12};
|
||||
player.color = LIGHTGRAY;
|
||||
|
||||
for (int i = 0; i < MAX_MEDIUM_METEORS; i++)
|
||||
{
|
||||
posx = GetRandomValue(0, screenWidth);
|
||||
|
||||
while(!correctRange)
|
||||
{
|
||||
if (posx > screenWidth/2 - 150 && posx < screenWidth/2 + 150) posx = GetRandomValue(0, screenWidth);
|
||||
else correctRange = true;
|
||||
}
|
||||
|
||||
correctRange = false;
|
||||
|
||||
posy = GetRandomValue(0, screenHeight);
|
||||
|
||||
while(!correctRange)
|
||||
{
|
||||
if (posy > screenHeight/2 - 150 && posy < screenHeight/2 + 150) posy = GetRandomValue(0, screenHeight);
|
||||
else correctRange = true;
|
||||
}
|
||||
|
||||
correctRange = false;
|
||||
velx = GetRandomValue(-METEORS_SPEED, METEORS_SPEED);
|
||||
vely = GetRandomValue(-METEORS_SPEED, METEORS_SPEED);
|
||||
|
||||
while(!correctRange)
|
||||
{
|
||||
if (velx == 0 && vely == 0)
|
||||
{
|
||||
velx = GetRandomValue(-METEORS_SPEED, METEORS_SPEED);
|
||||
vely = GetRandomValue(-METEORS_SPEED, METEORS_SPEED);
|
||||
}
|
||||
else correctRange = true;
|
||||
}
|
||||
mediumMeteor[i].position = (Vector2){posx, posy};
|
||||
mediumMeteor[i].speed = (Vector2){velx, vely};
|
||||
mediumMeteor[i].radius = 20;
|
||||
mediumMeteor[i].active = true;
|
||||
mediumMeteor[i].color = GREEN;
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_SMALL_METEORS; i++)
|
||||
{
|
||||
posx = GetRandomValue(0, screenWidth);
|
||||
|
||||
while(!correctRange)
|
||||
{
|
||||
if (posx > screenWidth/2 - 150 && posx < screenWidth/2 + 150) posx = GetRandomValue(0, screenWidth);
|
||||
else correctRange = true;
|
||||
}
|
||||
|
||||
correctRange = false;
|
||||
|
||||
posy = GetRandomValue(0, screenHeight);
|
||||
|
||||
while(!correctRange)
|
||||
{
|
||||
if (posy > screenHeight/2 - 150 && posy < screenHeight/2 + 150) posy = GetRandomValue(0, screenHeight);
|
||||
else correctRange = true;
|
||||
}
|
||||
|
||||
correctRange = false;
|
||||
velx = GetRandomValue(-METEORS_SPEED, METEORS_SPEED);
|
||||
vely = GetRandomValue(-METEORS_SPEED, METEORS_SPEED);
|
||||
|
||||
while(!correctRange)
|
||||
{
|
||||
if (velx == 0 && vely == 0)
|
||||
{
|
||||
velx = GetRandomValue(-METEORS_SPEED, METEORS_SPEED);
|
||||
vely = GetRandomValue(-METEORS_SPEED, METEORS_SPEED);
|
||||
}
|
||||
else correctRange = true;
|
||||
}
|
||||
smallMeteor[i].position = (Vector2){posx, posy};
|
||||
smallMeteor[i].speed = (Vector2){velx, vely};
|
||||
smallMeteor[i].radius = 10;
|
||||
smallMeteor[i].active = true;
|
||||
smallMeteor[i].color = YELLOW;
|
||||
}
|
||||
}
|
||||
|
||||
// Update game (one frame)
|
||||
void UpdateGame(void)
|
||||
{
|
||||
if (!gameOver)
|
||||
{
|
||||
if (IsKeyPressed('P')) pause = !pause;
|
||||
|
||||
if (!pause)
|
||||
{
|
||||
framesCounter++;
|
||||
|
||||
// Player logic
|
||||
|
||||
// Rotation
|
||||
if (IsKeyDown(KEY_LEFT)) player.rotation -= 5;
|
||||
if (IsKeyDown(KEY_RIGHT)) player.rotation += 5;
|
||||
|
||||
// Speed
|
||||
player.speed.x = sin(player.rotation*DEG2RAD)*PLAYER_SPEED;
|
||||
player.speed.y = cos(player.rotation*DEG2RAD)*PLAYER_SPEED;
|
||||
|
||||
// Controller
|
||||
if (IsKeyDown(KEY_UP))
|
||||
{
|
||||
if (player.acceleration < 1) player.acceleration += 0.04f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (player.acceleration > 0) player.acceleration -= 0.02f;
|
||||
else if (player.acceleration < 0) player.acceleration = 0;
|
||||
}
|
||||
if (IsKeyDown(KEY_DOWN))
|
||||
{
|
||||
if (player.acceleration > 0) player.acceleration -= 0.04f;
|
||||
else if (player.acceleration < 0) player.acceleration = 0;
|
||||
}
|
||||
|
||||
// Movement
|
||||
player.position.x += (player.speed.x*player.acceleration);
|
||||
player.position.y -= (player.speed.y*player.acceleration);
|
||||
|
||||
// Wall behaviour for player
|
||||
if (player.position.x > screenWidth + shipHeight) player.position.x = -(shipHeight);
|
||||
else if (player.position.x < -(shipHeight)) player.position.x = screenWidth + shipHeight;
|
||||
if (player.position.y > (screenHeight + shipHeight)) player.position.y = -(shipHeight);
|
||||
else if (player.position.y < -(shipHeight)) player.position.y = screenHeight + shipHeight;
|
||||
|
||||
// Collision Player to meteors
|
||||
player.collider = (Vector3){player.position.x + sin(player.rotation*DEG2RAD)*(shipHeight/2.5f), player.position.y - cos(player.rotation*DEG2RAD)*(shipHeight/2.5f), 12};
|
||||
|
||||
for (int a = 0; a < MAX_MEDIUM_METEORS; a++)
|
||||
{
|
||||
if (CheckCollisionCircles((Vector2){player.collider.x, player.collider.y}, player.collider.z, mediumMeteor[a].position, mediumMeteor[a].radius) && mediumMeteor[a].active) gameOver = true;
|
||||
}
|
||||
|
||||
for (int a = 0; a < MAX_SMALL_METEORS; a++)
|
||||
{
|
||||
if (CheckCollisionCircles((Vector2){player.collider.x, player.collider.y}, player.collider.z, smallMeteor[a].position, smallMeteor[a].radius) && smallMeteor[a].active) gameOver = true;
|
||||
}
|
||||
|
||||
// Meteor logic
|
||||
|
||||
for (int i = 0; i < MAX_MEDIUM_METEORS; i++)
|
||||
{
|
||||
if (mediumMeteor[i].active)
|
||||
{
|
||||
// movement
|
||||
mediumMeteor[i].position.x += mediumMeteor[i].speed.x;
|
||||
mediumMeteor[i].position.y += mediumMeteor[i].speed.y;
|
||||
|
||||
// wall behaviour
|
||||
if (mediumMeteor[i].position.x > screenWidth + mediumMeteor[i].radius) mediumMeteor[i].position.x = -(mediumMeteor[i].radius);
|
||||
else if (mediumMeteor[i].position.x < 0 - mediumMeteor[i].radius) mediumMeteor[i].position.x = screenWidth + mediumMeteor[i].radius;
|
||||
if (mediumMeteor[i].position.y > screenHeight + mediumMeteor[i].radius) mediumMeteor[i].position.y = -(mediumMeteor[i].radius);
|
||||
else if (mediumMeteor[i].position.y < 0 - mediumMeteor[i].radius) mediumMeteor[i].position.y = screenHeight + mediumMeteor[i].radius;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_SMALL_METEORS; i++)
|
||||
{
|
||||
if (smallMeteor[i].active)
|
||||
{
|
||||
// movement
|
||||
smallMeteor[i].position.x += smallMeteor[i].speed.x;
|
||||
smallMeteor[i].position.y += smallMeteor[i].speed.y;
|
||||
|
||||
// wall behaviour
|
||||
if (smallMeteor[i].position.x > screenWidth + smallMeteor[i].radius) smallMeteor[i].position.x = -(smallMeteor[i].radius);
|
||||
else if (smallMeteor[i].position.x < 0 - smallMeteor[i].radius) smallMeteor[i].position.x = screenWidth + smallMeteor[i].radius;
|
||||
if (smallMeteor[i].position.y > screenHeight + smallMeteor[i].radius) smallMeteor[i].position.y = -(smallMeteor[i].radius);
|
||||
else if (smallMeteor[i].position.y < 0 - smallMeteor[i].radius) smallMeteor[i].position.y = screenHeight + smallMeteor[i].radius;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsKeyPressed(KEY_ENTER))
|
||||
{
|
||||
InitGame();
|
||||
gameOver = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw game (one frame)
|
||||
void DrawGame(void)
|
||||
{
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
if (!gameOver)
|
||||
{
|
||||
// Draw spaceship
|
||||
Vector2 v1 = { player.position.x + sinf(player.rotation*DEG2RAD)*(shipHeight), player.position.y - cosf(player.rotation*DEG2RAD)*(shipHeight) };
|
||||
Vector2 v2 = { player.position.x - cosf(player.rotation*DEG2RAD)*(PLAYER_BASE_SIZE/2), player.position.y - sinf(player.rotation*DEG2RAD)*(PLAYER_BASE_SIZE/2) };
|
||||
Vector2 v3 = { player.position.x + cosf(player.rotation*DEG2RAD)*(PLAYER_BASE_SIZE/2), player.position.y + sinf(player.rotation*DEG2RAD)*(PLAYER_BASE_SIZE/2) };
|
||||
DrawTriangle(v1, v2, v3, MAROON);
|
||||
|
||||
// Draw meteor
|
||||
for (int i = 0;i < MAX_MEDIUM_METEORS; i++)
|
||||
{
|
||||
if (mediumMeteor[i].active) DrawCircleV(mediumMeteor[i].position, mediumMeteor[i].radius, GRAY);
|
||||
else DrawCircleV(mediumMeteor[i].position, mediumMeteor[i].radius, Fade(LIGHTGRAY, 0.3f));
|
||||
}
|
||||
|
||||
for (int i = 0;i < MAX_SMALL_METEORS; i++)
|
||||
{
|
||||
if (smallMeteor[i].active) DrawCircleV(smallMeteor[i].position, smallMeteor[i].radius, DARKGRAY);
|
||||
else DrawCircleV(smallMeteor[i].position, smallMeteor[i].radius, Fade(LIGHTGRAY, 0.3f));
|
||||
}
|
||||
|
||||
DrawText(FormatText("TIME: %.02f", (float)framesCounter/60), 10, 10, 20, BLACK);
|
||||
|
||||
if (pause) DrawText("GAME PAUSED", screenWidth/2 - MeasureText("GAME PAUSED", 40)/2, screenHeight/2 - 40, 40, GRAY);
|
||||
}
|
||||
else DrawText("PRESS [ENTER] TO PLAY AGAIN", GetScreenWidth()/2 - MeasureText("PRESS [ENTER] TO PLAY AGAIN", 20)/2, GetScreenHeight()/2 - 50, 20, GRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// Unload game variables
|
||||
void UnloadGame(void)
|
||||
{
|
||||
// TODO: Unload all dynamic loaded data (textures, sounds, models...)
|
||||
}
|
||||
|
||||
// Update and Draw (one frame)
|
||||
void UpdateDrawFrame(void)
|
||||
{
|
||||
UpdateGame();
|
||||
DrawGame();
|
||||
}
|
|
@ -338,7 +338,7 @@ int main()
|
|||
DrawTexture(title, screenWidth/2 - title.width/2, screenHeight/2 - title.height/2 - 80, WHITE);
|
||||
|
||||
// Draw blinking text
|
||||
if ((framesCounter/30) % 2) DrawTextEx(font, "PRESS ENTER", (Vector2){ screenWidth/2 - 150, 480 }, GetFontBaseSize(font), 0, WHITE);
|
||||
if ((framesCounter/30) % 2) DrawTextEx(font, "PRESS ENTER", (Vector2){ screenWidth/2 - 150, 480 }, font.size, 0, WHITE);
|
||||
|
||||
} break;
|
||||
case GAMEPLAY:
|
||||
|
@ -388,8 +388,8 @@ int main()
|
|||
DrawRectangle(20, 20, foodBar, 40, ORANGE);
|
||||
DrawRectangleLines(20, 20, 400, 40, BLACK);
|
||||
|
||||
DrawTextEx(font, FormatText("SCORE: %04i", score), (Vector2){ screenWidth - 300, 20 }, GetFontBaseSize(font), -2, ORANGE);
|
||||
DrawTextEx(font, FormatText("DISTANCE: %04i", (int)distance), (Vector2){ 550, 20 }, GetFontBaseSize(font), -2, ORANGE);
|
||||
DrawTextEx(font, FormatText("SCORE: %04i", score), (Vector2){ screenWidth - 300, 20 }, font.size, -2, ORANGE);
|
||||
DrawTextEx(font, FormatText("DISTANCE: %04i", (int)distance), (Vector2){ 550, 20 }, font.size, -2, ORANGE);
|
||||
|
||||
if (gameraMode)
|
||||
{
|
||||
|
@ -403,15 +403,15 @@ int main()
|
|||
// Draw a transparent black rectangle that covers all screen
|
||||
DrawRectangle(0, 0, screenWidth, screenHeight, Fade(BLACK, 0.4f));
|
||||
|
||||
DrawTextEx(font, "GAME OVER", (Vector2){ 300, 160 }, GetFontBaseSize(font)*3, -2, MAROON);
|
||||
DrawTextEx(font, "GAME OVER", (Vector2){ 300, 160 }, font.size*3, -2, MAROON);
|
||||
|
||||
DrawTextEx(font, FormatText("SCORE: %04i", score), (Vector2){ 680, 350 }, GetFontBaseSize(font), -2, GOLD);
|
||||
DrawTextEx(font, FormatText("DISTANCE: %04i", (int)distance), (Vector2){ 290, 350 }, GetFontBaseSize(font), -2, GOLD);
|
||||
DrawTextEx(font, FormatText("HISCORE: %04i", hiscore), (Vector2){ 665, 400 }, GetFontBaseSize(font), -2, ORANGE);
|
||||
DrawTextEx(font, FormatText("HIDISTANCE: %04i", (int)hidistance), (Vector2){ 270, 400 }, GetFontBaseSize(font), -2, ORANGE);
|
||||
DrawTextEx(font, FormatText("SCORE: %04i", score), (Vector2){ 680, 350 }, font.size, -2, GOLD);
|
||||
DrawTextEx(font, FormatText("DISTANCE: %04i", (int)distance), (Vector2){ 290, 350 }, font.size, -2, GOLD);
|
||||
DrawTextEx(font, FormatText("HISCORE: %04i", hiscore), (Vector2){ 665, 400 }, font.size, -2, ORANGE);
|
||||
DrawTextEx(font, FormatText("HIDISTANCE: %04i", (int)hidistance), (Vector2){ 270, 400 }, font.size, -2, ORANGE);
|
||||
|
||||
// Draw blinking text
|
||||
if ((framesCounter/30) % 2) DrawTextEx(font, "PRESS ENTER to REPLAY", (Vector2){ screenWidth/2 - 250, 520 }, GetFontBaseSize(font), -2, LIGHTGRAY);
|
||||
if ((framesCounter/30) % 2) DrawTextEx(font, "PRESS ENTER to REPLAY", (Vector2){ screenWidth/2 - 250, 520 }, font.size, -2, LIGHTGRAY);
|
||||
|
||||
} break;
|
||||
default: break;
|
||||
|
|
|
@ -351,7 +351,7 @@ int main()
|
|||
DrawTexture(title, screenWidth/2 - title.width/2, screenHeight/2 - title.height/2 - 80, WHITE);
|
||||
|
||||
// Draw blinking text
|
||||
if ((framesCounter/30) % 2) DrawTextEx(font, "PRESS ENTER", (Vector2){ screenWidth/2 - 150, 480 }, GetFontBaseSize(font), 0, WHITE);
|
||||
if ((framesCounter/30) % 2) DrawTextEx(font, "PRESS ENTER", (Vector2){ screenWidth/2 - 150, 480 }, font.size, 0, WHITE);
|
||||
|
||||
} break;
|
||||
case GAMEPLAY:
|
||||
|
@ -401,8 +401,8 @@ int main()
|
|||
DrawRectangle(20, 20, foodBar, 40, ORANGE);
|
||||
DrawRectangleLines(20, 20, 400, 40, BLACK);
|
||||
|
||||
DrawTextEx(font, FormatText("SCORE: %04i", score), (Vector2){ screenWidth - 300, 20 }, GetFontBaseSize(font), -2, ORANGE);
|
||||
DrawTextEx(font, FormatText("DISTANCE: %04i", (int)distance), (Vector2){ 550, 20 }, GetFontBaseSize(font), -2, ORANGE);
|
||||
DrawTextEx(font, FormatText("SCORE: %04i", score), (Vector2){ screenWidth - 300, 20 }, font.size, -2, ORANGE);
|
||||
DrawTextEx(font, FormatText("DISTANCE: %04i", (int)distance), (Vector2){ 550, 20 }, font.size, -2, ORANGE);
|
||||
|
||||
if (gameraMode)
|
||||
{
|
||||
|
@ -416,15 +416,15 @@ int main()
|
|||
// Draw a transparent black rectangle that covers all screen
|
||||
DrawRectangle(0, 0, screenWidth, screenHeight, Fade(BLACK, 0.4f));
|
||||
|
||||
DrawTextEx(font, "GAME OVER", (Vector2){ 300, 160 }, GetFontBaseSize(font)*3, -2, MAROON);
|
||||
DrawTextEx(font, "GAME OVER", (Vector2){ 300, 160 }, font.size*3, -2, MAROON);
|
||||
|
||||
DrawTextEx(font, FormatText("SCORE: %04i", score), (Vector2){ 680, 350 }, GetFontBaseSize(font), -2, GOLD);
|
||||
DrawTextEx(font, FormatText("DISTANCE: %04i", (int)distance), (Vector2){ 290, 350 }, GetFontBaseSize(font), -2, GOLD);
|
||||
DrawTextEx(font, FormatText("HISCORE: %04i", hiscore), (Vector2){ 665, 400 }, GetFontBaseSize(font), -2, ORANGE);
|
||||
DrawTextEx(font, FormatText("HIDISTANCE: %04i", (int)hidistance), (Vector2){ 270, 400 }, GetFontBaseSize(font), -2, ORANGE);
|
||||
DrawTextEx(font, FormatText("SCORE: %04i", score), (Vector2){ 680, 350 }, font.size, -2, GOLD);
|
||||
DrawTextEx(font, FormatText("DISTANCE: %04i", (int)distance), (Vector2){ 290, 350 }, font.size, -2, GOLD);
|
||||
DrawTextEx(font, FormatText("HISCORE: %04i", hiscore), (Vector2){ 665, 400 }, font.size, -2, ORANGE);
|
||||
DrawTextEx(font, FormatText("HIDISTANCE: %04i", (int)hidistance), (Vector2){ 270, 400 }, font.size, -2, ORANGE);
|
||||
|
||||
// Draw blinking text
|
||||
if ((framesCounter/30) % 2) DrawTextEx(font, "PRESS ENTER to REPLAY", (Vector2){ screenWidth/2 - 250, 520 }, GetFontBaseSize(font), -2, LIGHTGRAY);
|
||||
if ((framesCounter/30) % 2) DrawTextEx(font, "PRESS ENTER to REPLAY", (Vector2){ screenWidth/2 - 250, 520 }, font.size, -2, LIGHTGRAY);
|
||||
|
||||
} break;
|
||||
default: break;
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
|
||||
#include "raylib.h"
|
||||
|
||||
#include <math.h> // Used for sinf()
|
||||
|
||||
#define MAX_ENEMIES 10
|
||||
|
||||
typedef enum { TITLE, GAMEPLAY, ENDING } GameScreen;
|
||||
|
@ -128,7 +130,7 @@ int main()
|
|||
framesCounter++;
|
||||
|
||||
// Sea color tint effect
|
||||
blue = 210 + 25 * sin(timeCounter);
|
||||
blue = 210 + 25 * sinf(timeCounter);
|
||||
timeCounter += 0.01;
|
||||
|
||||
// Game screens management
|
||||
|
@ -374,7 +376,7 @@ int main()
|
|||
DrawTexture(title, screenWidth/2 - title.width/2, screenHeight/2 - title.height/2 - 80, WHITE);
|
||||
|
||||
// Draw blinking text
|
||||
if ((framesCounter/30) % 2) DrawTextEx(font, "PRESS ENTER", (Vector2){ screenWidth/2 - 150, 480 }, GetFontBaseSize(font), 0, WHITE);
|
||||
if ((framesCounter/30) % 2) DrawTextEx(font, "PRESS ENTER", (Vector2){ screenWidth/2 - 150, 480 }, font.size, 0, WHITE);
|
||||
|
||||
} break;
|
||||
case GAMEPLAY:
|
||||
|
@ -424,8 +426,8 @@ int main()
|
|||
DrawRectangle(20, 20, foodBar, 40, ORANGE);
|
||||
DrawRectangleLines(20, 20, 400, 40, BLACK);
|
||||
|
||||
DrawTextEx(font, FormatText("SCORE: %04i", score), (Vector2){ screenWidth - 300, 20 }, GetFontBaseSize(font), -2, ORANGE);
|
||||
DrawTextEx(font, FormatText("DISTANCE: %04i", (int)distance), (Vector2){ 550, 20 }, GetFontBaseSize(font), -2, ORANGE);
|
||||
DrawTextEx(font, FormatText("SCORE: %04i", score), (Vector2){ screenWidth - 300, 20 }, font.size, -2, ORANGE);
|
||||
DrawTextEx(font, FormatText("DISTANCE: %04i", (int)distance), (Vector2){ 550, 20 }, font.size, -2, ORANGE);
|
||||
|
||||
if (gameraMode)
|
||||
{
|
||||
|
@ -439,15 +441,15 @@ int main()
|
|||
// Draw a transparent black rectangle that covers all screen
|
||||
DrawRectangle(0, 0, screenWidth, screenHeight, Fade(BLACK, 0.4f));
|
||||
|
||||
DrawTextEx(font, "GAME OVER", (Vector2){ 300, 160 }, GetFontBaseSize(font)*3, -2, MAROON);
|
||||
DrawTextEx(font, "GAME OVER", (Vector2){ 300, 160 }, font.size*3, -2, MAROON);
|
||||
|
||||
DrawTextEx(font, FormatText("SCORE: %04i", score), (Vector2){ 680, 350 }, GetFontBaseSize(font), -2, GOLD);
|
||||
DrawTextEx(font, FormatText("DISTANCE: %04i", (int)distance), (Vector2){ 290, 350 }, GetFontBaseSize(font), -2, GOLD);
|
||||
DrawTextEx(font, FormatText("HISCORE: %04i", hiscore), (Vector2){ 665, 400 }, GetFontBaseSize(font), -2, ORANGE);
|
||||
DrawTextEx(font, FormatText("HIDISTANCE: %04i", (int)hidistance), (Vector2){ 270, 400 }, GetFontBaseSize(font), -2, ORANGE);
|
||||
DrawTextEx(font, FormatText("SCORE: %04i", score), (Vector2){ 680, 350 }, font.size, -2, GOLD);
|
||||
DrawTextEx(font, FormatText("DISTANCE: %04i", (int)distance), (Vector2){ 290, 350 }, font.size, -2, GOLD);
|
||||
DrawTextEx(font, FormatText("HISCORE: %04i", hiscore), (Vector2){ 665, 400 }, font.size, -2, ORANGE);
|
||||
DrawTextEx(font, FormatText("HIDISTANCE: %04i", (int)hidistance), (Vector2){ 270, 400 }, font.size, -2, ORANGE);
|
||||
|
||||
// Draw blinking text
|
||||
if ((framesCounter/30) % 2) DrawTextEx(font, "PRESS ENTER to REPLAY", (Vector2){ screenWidth/2 - 250, 520 }, GetFontBaseSize(font), -2, LIGHTGRAY);
|
||||
if ((framesCounter/30) % 2) DrawTextEx(font, "PRESS ENTER to REPLAY", (Vector2){ screenWidth/2 - 250, 520 }, font.size, -2, LIGHTGRAY);
|
||||
|
||||
} break;
|
||||
default: break;
|
||||
|
|
541
games/drturtle/drturtle_final_web.c
Normal file
|
@ -0,0 +1,541 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib game - Dr. Turtle & Mr. Gamera
|
||||
*
|
||||
* Welcome to raylib!
|
||||
*
|
||||
* To test examples, just press F6 and execute raylib_compile_execute script
|
||||
* Note that compiled executable is placed in the same folder as .c file
|
||||
*
|
||||
* You can find all basic examples on C:\raylib\raylib\examples folder or
|
||||
* raylib official webpage: www.raylib.com
|
||||
*
|
||||
* Enjoy using raylib. :)
|
||||
*
|
||||
* This game has been created using raylib 1.1 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include <math.h> // Used for sinf()
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
#include <emscripten/emscripten.h>
|
||||
#endif
|
||||
|
||||
#define MAX_ENEMIES 10
|
||||
|
||||
typedef enum { TITLE = 0, GAMEPLAY, ENDING } GameScreen;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
const int screenWidth = 1280;
|
||||
const int screenHeight = 720;
|
||||
|
||||
Texture2D sky;
|
||||
Texture2D mountains;
|
||||
Texture2D sea;
|
||||
Texture2D title;
|
||||
Texture2D turtle;
|
||||
Texture2D gamera;
|
||||
Texture2D shark;
|
||||
Texture2D orca;
|
||||
Texture2D swhale;
|
||||
Texture2D fish;
|
||||
Texture2D gframe;
|
||||
|
||||
SpriteFont font;
|
||||
|
||||
Sound eat;
|
||||
Sound die;
|
||||
Sound growl;
|
||||
|
||||
// Define scrolling variables
|
||||
int backScrolling = 0;
|
||||
int seaScrolling = 0;
|
||||
|
||||
// Define current screen
|
||||
GameScreen currentScreen = 0;
|
||||
|
||||
// Define player variables
|
||||
int playerRail = 1;
|
||||
Rectangle playerBounds;
|
||||
bool gameraMode = false;
|
||||
|
||||
// Define enemies variables
|
||||
Rectangle enemyBounds[MAX_ENEMIES];
|
||||
int enemyRail[MAX_ENEMIES];
|
||||
int enemyType[MAX_ENEMIES];
|
||||
bool enemyActive[MAX_ENEMIES];
|
||||
float enemySpeed = 10;
|
||||
|
||||
// Define additional game variables
|
||||
int score = 0;
|
||||
float distance = 0.0f;
|
||||
int hiscore = 0;
|
||||
float hidistance = 0.0f;
|
||||
int foodBar = 0;
|
||||
int framesCounter = 0;
|
||||
|
||||
unsigned char blue = 200;
|
||||
float timeCounter = 0;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
void UpdateDrawFrame(void); // Update and Draw one frame
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Main Enry Point
|
||||
//----------------------------------------------------------------------------------
|
||||
int main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Init window
|
||||
InitWindow(screenWidth, screenHeight, "Dr. Turtle & Mr. GAMERA");
|
||||
|
||||
// Initialize audio device
|
||||
InitAudioDevice();
|
||||
|
||||
// Load game resources: textures
|
||||
sky = LoadTexture("resources/sky.png");
|
||||
mountains = LoadTexture("resources/mountains.png");
|
||||
sea = LoadTexture("resources/sea.png");
|
||||
title = LoadTexture("resources/title.png");
|
||||
turtle = LoadTexture("resources/turtle.png");
|
||||
gamera = LoadTexture("resources/gamera.png");
|
||||
shark = LoadTexture("resources/shark.png");
|
||||
orca = LoadTexture("resources/orca.png");
|
||||
swhale = LoadTexture("resources/swhale.png");
|
||||
fish = LoadTexture("resources/fish.png");
|
||||
gframe = LoadTexture("resources/gframe.png");
|
||||
|
||||
// Load game resources: fonts
|
||||
font = LoadSpriteFont("resources/komika.png");
|
||||
|
||||
// Load game resources: sounds
|
||||
eat = LoadSound("resources/eat.wav");
|
||||
die = LoadSound("resources/die.wav");
|
||||
growl = LoadSound("resources/gamera.wav");
|
||||
|
||||
// Start playing streaming music
|
||||
PlayMusicStream("resources/speeding.ogg");
|
||||
|
||||
playerBounds = (Rectangle){ 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
|
||||
|
||||
// Init enemies variables
|
||||
for (int i = 0; i < MAX_ENEMIES; i++)
|
||||
{
|
||||
// Define enemy type (all same probability)
|
||||
//enemyType[i] = GetRandomValue(0, 3);
|
||||
|
||||
// Probability system for enemies type
|
||||
int enemyProb = GetRandomValue(0, 100);
|
||||
|
||||
if (enemyProb < 30) enemyType[i] = 0;
|
||||
else if (enemyProb < 60) enemyType[i] = 1;
|
||||
else if (enemyProb < 90) enemyType[i] = 2;
|
||||
else enemyType[i] = 3;
|
||||
|
||||
// define enemy rail
|
||||
enemyRail[i] = GetRandomValue(0, 4);
|
||||
|
||||
// Make sure not two consecutive enemies in the same row
|
||||
if (i > 0) while (enemyRail[i] == enemyRail[i - 1]) enemyRail[i] = GetRandomValue(0, 4);
|
||||
|
||||
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
|
||||
enemyActive[i] = false;
|
||||
}
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
emscripten_set_main_loop(UpdateDrawFrame, 0, 1);
|
||||
#else
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
UpdateDrawFrame();
|
||||
}
|
||||
#endif
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Unload textures
|
||||
UnloadTexture(sky);
|
||||
UnloadTexture(mountains);
|
||||
UnloadTexture(sea);
|
||||
UnloadTexture(gframe);
|
||||
UnloadTexture(title);
|
||||
UnloadTexture(turtle);
|
||||
UnloadTexture(shark);
|
||||
UnloadTexture(orca);
|
||||
UnloadTexture(swhale);
|
||||
UnloadTexture(fish);
|
||||
UnloadTexture(gamera);
|
||||
|
||||
// Unload font texture
|
||||
UnloadSpriteFont(font);
|
||||
|
||||
// Unload sounds
|
||||
UnloadSound(eat);
|
||||
UnloadSound(die);
|
||||
UnloadSound(growl);
|
||||
|
||||
StopMusicStream(); // Stop music
|
||||
CloseAudioDevice(); // Close audio device
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
void UpdateDrawFrame(void)
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateMusicStream();
|
||||
|
||||
framesCounter++;
|
||||
|
||||
// Sea color tint effect
|
||||
blue = 210 + 25 * sinf(timeCounter);
|
||||
timeCounter += 0.01;
|
||||
|
||||
// Game screens management
|
||||
switch (currentScreen)
|
||||
{
|
||||
case TITLE:
|
||||
{
|
||||
// Sea scrolling
|
||||
seaScrolling -= 2;
|
||||
if (seaScrolling <= -screenWidth) seaScrolling = 0;
|
||||
|
||||
// Press enter to change to gameplay screen
|
||||
if (IsKeyPressed(KEY_ENTER))
|
||||
{
|
||||
currentScreen = GAMEPLAY;
|
||||
framesCounter = 0;
|
||||
}
|
||||
|
||||
} break;
|
||||
case GAMEPLAY:
|
||||
{
|
||||
// Background scrolling logic
|
||||
backScrolling--;
|
||||
if (backScrolling <= -screenWidth) backScrolling = 0;
|
||||
|
||||
// Sea scrolling logic
|
||||
seaScrolling -= (enemySpeed - 2);
|
||||
if (seaScrolling <= -screenWidth) seaScrolling = 0;
|
||||
|
||||
// Player movement logic
|
||||
if (IsKeyPressed(KEY_DOWN)) playerRail++;
|
||||
else if (IsKeyPressed(KEY_UP)) playerRail--;
|
||||
|
||||
// Check player not out of rails
|
||||
if (playerRail > 4) playerRail = 4;
|
||||
else if (playerRail < 0) playerRail = 0;
|
||||
|
||||
// Update player bounds
|
||||
playerBounds = (Rectangle){ 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
|
||||
|
||||
// Enemies activation logic (every 40 frames)
|
||||
if (framesCounter > 40)
|
||||
{
|
||||
for (int i = 0; i < MAX_ENEMIES; i++)
|
||||
{
|
||||
if (enemyActive[i] == false)
|
||||
{
|
||||
enemyActive[i] = true;
|
||||
i = MAX_ENEMIES;
|
||||
}
|
||||
}
|
||||
|
||||
framesCounter = 0;
|
||||
}
|
||||
|
||||
// Enemies logic
|
||||
for (int i = 0; i < MAX_ENEMIES; i++)
|
||||
{
|
||||
if (enemyActive[i])
|
||||
{
|
||||
enemyBounds[i].x -= enemySpeed;
|
||||
}
|
||||
|
||||
// Check enemies out of screen
|
||||
if (enemyBounds[i].x <= 0 - 128)
|
||||
{
|
||||
enemyActive[i] = false;
|
||||
enemyType[i] = GetRandomValue(0, 3);
|
||||
enemyRail[i] = GetRandomValue(0, 4);
|
||||
|
||||
// Make sure not two consecutive enemies in the same row
|
||||
if (i > 0) while (enemyRail[i] == enemyRail[i - 1]) enemyRail[i] = GetRandomValue(0, 4);
|
||||
|
||||
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
|
||||
}
|
||||
}
|
||||
|
||||
if (!gameraMode) enemySpeed += 0.005;
|
||||
|
||||
// Check collision player vs enemies
|
||||
for (int i = 0; i < MAX_ENEMIES; i++)
|
||||
{
|
||||
if (enemyActive[i])
|
||||
{
|
||||
if (CheckCollisionRecs(playerBounds, enemyBounds[i]))
|
||||
{
|
||||
if (enemyType[i] < 3) // Bad enemies
|
||||
{
|
||||
if (gameraMode)
|
||||
{
|
||||
if (enemyType[i] == 0) score += 50;
|
||||
else if (enemyType[i] == 1) score += 150;
|
||||
else if (enemyType[i] == 2) score += 300;
|
||||
|
||||
foodBar += 15;
|
||||
|
||||
enemyActive[i] = false;
|
||||
|
||||
// After enemy deactivation, reset enemy parameters to be reused
|
||||
enemyType[i] = GetRandomValue(0, 3);
|
||||
enemyRail[i] = GetRandomValue(0, 4);
|
||||
|
||||
// Make sure not two consecutive enemies in the same row
|
||||
if (i > 0) while (enemyRail[i] == enemyRail[i - 1]) enemyRail[i] = GetRandomValue(0, 4);
|
||||
|
||||
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
|
||||
|
||||
PlaySound(eat);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Player die logic
|
||||
PlaySound(die);
|
||||
|
||||
currentScreen = ENDING;
|
||||
framesCounter = 0;
|
||||
|
||||
// Save hiscore and hidistance for next game
|
||||
if (score > hiscore) hiscore = score;
|
||||
if (distance > hidistance) hidistance = distance;
|
||||
}
|
||||
}
|
||||
else // Sweet fish
|
||||
{
|
||||
enemyActive[i] = false;
|
||||
enemyType[i] = GetRandomValue(0, 3);
|
||||
enemyRail[i] = GetRandomValue(0, 4);
|
||||
|
||||
// Make sure not two consecutive enemies in the same row
|
||||
if (i > 0) while (enemyRail[i] == enemyRail[i - 1]) enemyRail[i] = GetRandomValue(0, 4);
|
||||
|
||||
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
|
||||
|
||||
if (!gameraMode) foodBar += 80;
|
||||
else foodBar += 25;
|
||||
|
||||
score += 10;
|
||||
|
||||
if (foodBar == 400)
|
||||
{
|
||||
gameraMode = true;
|
||||
|
||||
PlaySound(growl);
|
||||
}
|
||||
|
||||
PlaySound(eat);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Gamera mode logic
|
||||
if (gameraMode)
|
||||
{
|
||||
foodBar--;
|
||||
|
||||
if (foodBar <= 0)
|
||||
{
|
||||
gameraMode = false;
|
||||
enemySpeed -= 2;
|
||||
if (enemySpeed < 10) enemySpeed = 10;
|
||||
}
|
||||
}
|
||||
|
||||
// Update distance counter
|
||||
distance += 0.5f;
|
||||
|
||||
} break;
|
||||
case ENDING:
|
||||
{
|
||||
// Press enter to play again
|
||||
if (IsKeyPressed(KEY_ENTER))
|
||||
{
|
||||
currentScreen = GAMEPLAY;
|
||||
|
||||
// Reset player
|
||||
playerRail = 1;
|
||||
playerBounds = (Rectangle){ 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
|
||||
gameraMode = false;
|
||||
|
||||
// Reset enemies data
|
||||
for (int i = 0; i < MAX_ENEMIES; i++)
|
||||
{
|
||||
int enemyProb = GetRandomValue(0, 100);
|
||||
|
||||
if (enemyProb < 30) enemyType[i] = 0;
|
||||
else if (enemyProb < 60) enemyType[i] = 1;
|
||||
else if (enemyProb < 90) enemyType[i] = 2;
|
||||
else enemyType[i] = 3;
|
||||
|
||||
//enemyType[i] = GetRandomValue(0, 3);
|
||||
enemyRail[i] = GetRandomValue(0, 4);
|
||||
|
||||
// Make sure not two consecutive enemies in the same row
|
||||
if (i > 0) while (enemyRail[i] == enemyRail[i - 1]) enemyRail[i] = GetRandomValue(0, 4);
|
||||
|
||||
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
|
||||
enemyActive[i] = false;
|
||||
}
|
||||
|
||||
enemySpeed = 10;
|
||||
|
||||
// Reset game variables
|
||||
score = 0;
|
||||
distance = 0.0;
|
||||
foodBar = 0;
|
||||
framesCounter = 0;
|
||||
}
|
||||
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
// Draw background (common to all screens)
|
||||
DrawTexture(sky, 0, 0, WHITE);
|
||||
|
||||
DrawTexture(mountains, backScrolling, 0, WHITE);
|
||||
DrawTexture(mountains, screenWidth + backScrolling, 0, WHITE);
|
||||
|
||||
if (!gameraMode)
|
||||
{
|
||||
DrawTexture(sea, seaScrolling, 0, (Color){ 16, 189, blue, 255});
|
||||
DrawTexture(sea, screenWidth + seaScrolling, 0, (Color){ 16, 189, blue, 255});
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawTexture(sea, seaScrolling, 0, (Color){ 255, 113, 66, 255});
|
||||
DrawTexture(sea, screenWidth + seaScrolling, 0, (Color){ 255, 113, 66, 255});
|
||||
}
|
||||
|
||||
switch (currentScreen)
|
||||
{
|
||||
case TITLE:
|
||||
{
|
||||
// Draw title
|
||||
DrawTexture(title, screenWidth/2 - title.width/2, screenHeight/2 - title.height/2 - 80, WHITE);
|
||||
|
||||
// Draw blinking text
|
||||
if ((framesCounter/30) % 2) DrawTextEx(font, "PRESS ENTER", (Vector2){ screenWidth/2 - 150, 480 }, font.size, 1, WHITE);
|
||||
|
||||
} break;
|
||||
case GAMEPLAY:
|
||||
{
|
||||
// Draw water lines
|
||||
for (int i = 0; i < 5; i++) DrawRectangle(0, i*120 + 120, screenWidth, 110, Fade(SKYBLUE, 0.1f));
|
||||
|
||||
// Draw player
|
||||
if (!gameraMode) DrawTexture(turtle, playerBounds.x - 14, playerBounds.y - 14, WHITE);
|
||||
else DrawTexture(gamera, playerBounds.x - 64, playerBounds.y - 64, WHITE);
|
||||
|
||||
// Draw player bounding box
|
||||
//if (!gameraMode) DrawRectangleRec(playerBounds, Fade(GREEN, 0.4f));
|
||||
//else DrawRectangleRec(playerBounds, Fade(ORANGE, 0.4f));
|
||||
|
||||
// Draw enemies
|
||||
for (int i = 0; i < MAX_ENEMIES; i++)
|
||||
{
|
||||
if (enemyActive[i])
|
||||
{
|
||||
// Draw enemies
|
||||
switch(enemyType[i])
|
||||
{
|
||||
case 0: DrawTexture(shark, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
|
||||
case 1: DrawTexture(orca, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
|
||||
case 2: DrawTexture(swhale, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
|
||||
case 3: DrawTexture(fish, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
// Draw enemies bounding boxes
|
||||
/*
|
||||
switch(enemyType[i])
|
||||
{
|
||||
case 0: DrawRectangleRec(enemyBounds[i], Fade(RED, 0.5f)); break;
|
||||
case 1: DrawRectangleRec(enemyBounds[i], Fade(RED, 0.5f)); break;
|
||||
case 2: DrawRectangleRec(enemyBounds[i], Fade(RED, 0.5f)); break;
|
||||
case 3: DrawRectangleRec(enemyBounds[i], Fade(GREEN, 0.5f)); break;
|
||||
default: break;
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
// Draw gameplay interface
|
||||
DrawRectangle(20, 20, 400, 40, Fade(GRAY, 0.4f));
|
||||
DrawRectangle(20, 20, foodBar, 40, ORANGE);
|
||||
DrawRectangleLines(20, 20, 400, 40, BLACK);
|
||||
|
||||
DrawTextEx(font, FormatText("SCORE: %04i", score), (Vector2){ screenWidth - 300, 20 }, font.size, -2, ORANGE);
|
||||
DrawTextEx(font, FormatText("DISTANCE: %04i", (int)distance), (Vector2){ 550, 20 }, font.size, -2, ORANGE);
|
||||
|
||||
if (gameraMode)
|
||||
{
|
||||
DrawText("GAMERA MODE", 60, 22, 40, GRAY);
|
||||
DrawTexture(gframe, 0, 0, Fade(WHITE, 0.5f));
|
||||
}
|
||||
|
||||
} break;
|
||||
case ENDING:
|
||||
{
|
||||
// Draw a transparent black rectangle that covers all screen
|
||||
DrawRectangle(0, 0, screenWidth, screenHeight, Fade(BLACK, 0.4f));
|
||||
|
||||
DrawTextEx(font, "GAME OVER", (Vector2){ 300, 160 }, font.size*3, -2, MAROON);
|
||||
|
||||
DrawTextEx(font, FormatText("SCORE: %04i", score), (Vector2){ 680, 350 }, font.size, -2, GOLD);
|
||||
DrawTextEx(font, FormatText("DISTANCE: %04i", (int)distance), (Vector2){ 290, 350 }, font.size, -2, GOLD);
|
||||
DrawTextEx(font, FormatText("HISCORE: %04i", hiscore), (Vector2){ 665, 400 }, font.size, -2, ORANGE);
|
||||
DrawTextEx(font, FormatText("HIDISTANCE: %04i", (int)hidistance), (Vector2){ 270, 400 }, font.size, -2, ORANGE);
|
||||
|
||||
// Draw blinking text
|
||||
if ((framesCounter/30) % 2) DrawTextEx(font, "PRESS ENTER to REPLAY", (Vector2){ screenWidth/2 - 250, 520 }, font.size, -2, LIGHTGRAY);
|
||||
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
186
games/drturtle/makefile
Normal file
|
@ -0,0 +1,186 @@
|
|||
#**************************************************************************************************
|
||||
#
|
||||
# raylib - makefile to compile Dr.Turtle game
|
||||
#
|
||||
# Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#**************************************************************************************************
|
||||
|
||||
# define raylib platform if not defined (by default, compile for RPI)
|
||||
# Other possible platform: PLATFORM_DESKTOP
|
||||
PLATFORM ?= PLATFORM_DESKTOP
|
||||
|
||||
# determine PLATFORM_OS in case PLATFORM_DESKTOP selected
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
# No uname.exe on MinGW!, but OS=Windows_NT on Windows! ifeq ($(UNAME),Msys) -> Windows
|
||||
ifeq ($(OS),Windows_NT)
|
||||
PLATFORM_OS=WINDOWS
|
||||
LIBPATH=win32
|
||||
else
|
||||
UNAMEOS:=$(shell uname)
|
||||
ifeq ($(UNAMEOS),Linux)
|
||||
PLATFORM_OS=LINUX
|
||||
LIBPATH=linux
|
||||
else
|
||||
ifeq ($(UNAMEOS),Darwin)
|
||||
PLATFORM_OS=OSX
|
||||
LIBPATH=osx
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# define compiler: gcc for C program, define as g++ for C++
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
# define emscripten compiler
|
||||
CC = emcc
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
# define llvm compiler for mac
|
||||
CC = clang
|
||||
else
|
||||
# define default gcc compiler
|
||||
CC = gcc
|
||||
endif
|
||||
endif
|
||||
|
||||
# define compiler flags:
|
||||
# -O2 defines optimization level
|
||||
# -Wall turns on most, but not all, compiler warnings
|
||||
# -std=c99 use standard C from 1999 revision
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
CFLAGS = -O2 -Wall -std=gnu99 -fgnu89-inline
|
||||
else
|
||||
CFLAGS = -O2 -Wall -std=c99
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
CFLAGS = -O1 -Wall -std=c99 -s USE_GLFW=3 --preload-file resources -s ALLOW_MEMORY_GROWTH=1 --shell-file ../../templates/web_shell/shell.html
|
||||
#-s ASSERTIONS=1 --preload-file resources
|
||||
#-s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing
|
||||
#-s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB)
|
||||
endif
|
||||
|
||||
# define any directories containing required header files
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
INCLUDES = -I. -I../../src -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads
|
||||
else
|
||||
INCLUDES = -I. -I../../src
|
||||
# external libraries headers
|
||||
# GLFW3
|
||||
INCLUDES += -I../../external/glfw3/include
|
||||
# GLEW
|
||||
INCLUDES += -I../../external/glew/include
|
||||
# OpenAL Soft
|
||||
INCLUDES += -I../../external/openal_soft/include
|
||||
endif
|
||||
|
||||
# define library paths containing required libs
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
LFLAGS = -L. -L../../src -L/opt/vc/lib
|
||||
else
|
||||
LFLAGS = -L. -L../../src
|
||||
# external libraries to link with
|
||||
# GLFW3
|
||||
LFLAGS += -L../../external/glfw3/lib/$(LIBPATH)
|
||||
ifneq ($(PLATFORM_OS),OSX)
|
||||
# OpenAL Soft
|
||||
LFLAGS += -L../../external/openal_soft/lib/$(LIBPATH)
|
||||
# GLEW
|
||||
LFLAGS += -L../../external/glew/lib/$(LIBPATH)
|
||||
endif
|
||||
endif
|
||||
|
||||
# define any libraries to link into executable
|
||||
# if you want to link libraries (libname.so or libname.a), use the -lname
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
# libraries for Debian GNU/Linux desktop compiling
|
||||
# requires the following packages:
|
||||
# libglfw3-dev libopenal-dev libglew-dev libegl1-mesa-dev
|
||||
LIBS = -lraylib -lglfw -lGLEW -lGL -lopenal
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
# libraries for OS X 10.9 desktop compiling
|
||||
# requires the following packages:
|
||||
# libglfw3-dev libopenal-dev libglew-dev libegl1-mesa-dev
|
||||
LIBS = -lraylib -lglfw -framework OpenGL -framework OpenAl -framework Cocoa
|
||||
else
|
||||
# libraries for Windows desktop compiling
|
||||
# NOTE: GLFW3 and OpenAL Soft libraries should be installed
|
||||
LIBS = -lraylib -lglfw3 -lglew32 -lopengl32 -lopenal32 -lgdi32
|
||||
endif
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
# libraries for Raspberry Pi compiling
|
||||
# NOTE: OpenAL Soft library should be installed (libopenal1 package)
|
||||
LIBS = -lraylib -lGLESv2 -lEGL -lpthread -lrt -lm -lbcm_host -lopenal
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
LIBS = ../../src/libraylib.bc
|
||||
endif
|
||||
|
||||
# define additional parameters and flags for windows
|
||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||
# resources file contains windows exe icon
|
||||
# -Wl,--subsystem,windows hides the console window
|
||||
WINFLAGS = ../../src/resources -Wl,--subsystem,windows
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
EXT = .html
|
||||
endif
|
||||
|
||||
# define all screen object files required
|
||||
SCREENS = \
|
||||
|
||||
# typing 'make' will invoke the first target entry in the file,
|
||||
# in this case, the 'default' target entry is advance_game
|
||||
default: drturtle
|
||||
|
||||
# compile template - advance_game
|
||||
drturtle: drturtle_final_web.c $(SCREENS)
|
||||
$(CC) -o $@$(EXT) $< $(SCREENS) $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# clean everything
|
||||
clean:
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
find . -type f -perm +ugo+x -delete
|
||||
rm -f *.o
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
find . -type f -executable -delete
|
||||
rm -f *.o
|
||||
else
|
||||
del *.o *.exe
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
find . -type f -executable -delete
|
||||
rm -f *.o
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
del *.o *.html *.js
|
||||
endif
|
||||
@echo Cleaning done
|
||||
|
||||
# instead of defining every module one by one, we can define a pattern
|
||||
# this pattern below will automatically compile every module defined on $(OBJS)
|
||||
#%.exe : %.c
|
||||
# $(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM)
|
246
games/floppy.c
Normal file
|
@ -0,0 +1,246 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib - sample game: floppy
|
||||
*
|
||||
* Sample game developed by Ian Eito, Albert Martos and Ramon Santamaria
|
||||
*
|
||||
* This game has been created using raylib v1.3 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
#include <emscripten/emscripten.h>
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Some Defines
|
||||
//----------------------------------------------------------------------------------
|
||||
#define MAX_TUBES 100
|
||||
#define FLOPPY_RADIUS 24
|
||||
#define TUBES_WIDTH 80
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
typedef struct Floppy {
|
||||
Vector2 position;
|
||||
int radius;
|
||||
Color color;
|
||||
} Floppy;
|
||||
|
||||
typedef struct Tubes {
|
||||
Rectangle rec;
|
||||
Color color;
|
||||
bool active;
|
||||
} Tubes;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Global Variables Declaration
|
||||
//------------------------------------------------------------------------------------
|
||||
static int screenWidth = 800;
|
||||
static int screenHeight = 450;
|
||||
|
||||
static int framesCounter;
|
||||
static bool gameOver;
|
||||
static bool pause;
|
||||
static int score;
|
||||
static int hiScore = 0;
|
||||
|
||||
static Floppy floppy;
|
||||
static Tubes tubes[MAX_TUBES*2];
|
||||
static Vector2 tubesPos[MAX_TUBES];
|
||||
static int tubesSpeedX;
|
||||
static bool superfx;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module Functions Declaration (local)
|
||||
//------------------------------------------------------------------------------------
|
||||
static void InitGame(void); // Initialize game
|
||||
static void UpdateGame(void); // Update game (one frame)
|
||||
static void DrawGame(void); // Draw game (one frame)
|
||||
static void UnloadGame(void); // Unload game
|
||||
static void UpdateDrawFrame(void); // Update and Draw (one frame)
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "sample game: floppy");
|
||||
|
||||
InitGame();
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
emscripten_set_main_loop(UpdateDrawFrame, 0, 1);
|
||||
#else
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateGame();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
DrawGame();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
#endif
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadGame(); // Unload loaded data (textures, sounds, models...)
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module Functions Definitions (local)
|
||||
//------------------------------------------------------------------------------------
|
||||
|
||||
// Initialize game variables
|
||||
void InitGame(void)
|
||||
{
|
||||
floppy.radius = FLOPPY_RADIUS;
|
||||
floppy.position = (Vector2){80, screenHeight/2 - floppy.radius};
|
||||
tubesSpeedX = 2;
|
||||
|
||||
for (int i = 0; i < MAX_TUBES; i++)
|
||||
{
|
||||
tubesPos[i].x = 400 + 280*i;
|
||||
tubesPos[i].y = -GetRandomValue(0, 120);
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_TUBES*2; i += 2)
|
||||
{
|
||||
tubes[i].rec.x = tubesPos[i/2].x;
|
||||
tubes[i].rec.y = tubesPos[i/2].y;
|
||||
tubes[i].rec.width = TUBES_WIDTH;
|
||||
tubes[i].rec.height = 255;
|
||||
|
||||
tubes[i+1].rec.x = tubesPos[i/2].x;
|
||||
tubes[i+1].rec.y = 600 + tubesPos[i/2].y - 255;
|
||||
tubes[i+1].rec.width = TUBES_WIDTH;
|
||||
tubes[i+1].rec.height = 255;
|
||||
|
||||
tubes[i/2].active = true;
|
||||
}
|
||||
|
||||
score = 0;
|
||||
|
||||
gameOver = false;
|
||||
superfx = false;
|
||||
pause = false;
|
||||
}
|
||||
|
||||
// Update game (one frame)
|
||||
void UpdateGame(void)
|
||||
{
|
||||
if (!gameOver)
|
||||
{
|
||||
if (IsKeyPressed('P')) pause = !pause;
|
||||
|
||||
if (!pause)
|
||||
{
|
||||
for (int i = 0; i < MAX_TUBES; i++) tubesPos[i].x -= tubesSpeedX;
|
||||
|
||||
for (int i = 0; i < MAX_TUBES*2; i += 2)
|
||||
{
|
||||
tubes[i].rec.x = tubesPos[i/2].x;
|
||||
tubes[i+1].rec.x = tubesPos[i/2].x;
|
||||
}
|
||||
|
||||
if (IsKeyDown(KEY_SPACE) && !gameOver) floppy.position.y -= 3;
|
||||
else floppy.position.y += 1;
|
||||
|
||||
// Check Collisions
|
||||
for (int i = 0; i < MAX_TUBES*2; i++)
|
||||
{
|
||||
if (CheckCollisionCircleRec(floppy.position, floppy.radius, tubes[i].rec))
|
||||
{
|
||||
gameOver = true;
|
||||
pause = false;
|
||||
}
|
||||
else if ((tubesPos[i/2].x < floppy.position.x) && tubes[i/2].active && !gameOver)
|
||||
{
|
||||
score += 100;
|
||||
tubes[i/2].active = false;
|
||||
|
||||
superfx = true;
|
||||
|
||||
if (score > hiScore) hiScore = score;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsKeyPressed(KEY_ENTER))
|
||||
{
|
||||
InitGame();
|
||||
gameOver = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw game (one frame)
|
||||
void DrawGame(void)
|
||||
{
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
if (!gameOver)
|
||||
{
|
||||
DrawCircle(floppy.position.x, floppy.position.y, floppy.radius, DARKGRAY);
|
||||
|
||||
// Draw tubes
|
||||
for (int i = 0; i < MAX_TUBES; i++)
|
||||
{
|
||||
DrawRectangle(tubes[i*2].rec.x, tubes[i*2].rec.y, tubes[i*2].rec.width, tubes[i*2].rec.height, GRAY);
|
||||
DrawRectangle(tubes[i*2 + 1].rec.x, tubes[i*2 + 1].rec.y, tubes[i*2 + 1].rec.width, tubes[i*2 + 1].rec.height, GRAY);
|
||||
}
|
||||
|
||||
// Draw flashing fx (one frame only)
|
||||
if (superfx)
|
||||
{
|
||||
DrawRectangle(0, 0, screenWidth, screenHeight, WHITE);
|
||||
superfx = false;
|
||||
}
|
||||
|
||||
DrawText(FormatText("%04i", score), 20, 20, 40, GRAY);
|
||||
DrawText(FormatText("HI-SCORE: %04i", hiScore), 20, 70, 20, LIGHTGRAY);
|
||||
|
||||
if (pause) DrawText("GAME PAUSED", screenWidth/2 - MeasureText("GAME PAUSED", 40)/2, screenHeight/2 - 40, 40, GRAY);
|
||||
}
|
||||
else DrawText("PRESS [ENTER] TO PLAY AGAIN", GetScreenWidth()/2 - MeasureText("PRESS [ENTER] TO PLAY AGAIN", 20)/2, GetScreenHeight()/2 - 50, 20, GRAY);
|
||||
|
||||
EndDrawing();
|
||||
}
|
||||
|
||||
// Unload game variables
|
||||
void UnloadGame(void)
|
||||
{
|
||||
// TODO: Unload all dynamic loaded data (textures, sounds, models...)
|
||||
}
|
||||
|
||||
// Update and Draw (one frame)
|
||||
void UpdateDrawFrame(void)
|
||||
{
|
||||
UpdateGame();
|
||||
DrawGame();
|
||||
}
|
|
@ -1,213 +0,0 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib game - Floppy Bird
|
||||
*
|
||||
* This game has been created using raylib 1.1 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#define MAX_TUBES 100
|
||||
|
||||
int main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
int screenWidth = 800;
|
||||
int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "Floppy Bird");
|
||||
|
||||
InitAudioDevice(); // Initialize audio device
|
||||
|
||||
Sound coin = LoadSound("resources/coin.wav");
|
||||
Sound jump = LoadSound("resources/jump.wav");
|
||||
|
||||
Texture2D background = LoadTexture("resources/background.png");
|
||||
Texture2D tubes = LoadTexture("resources/tubes.png");
|
||||
Texture2D floppy = LoadTexture("resources/floppy.png");
|
||||
|
||||
Vector2 floppyPos = { 80, screenHeight/2 - floppy.height/2 };
|
||||
|
||||
Vector2 tubesPos[MAX_TUBES];
|
||||
int tubesSpeedX = 2;
|
||||
|
||||
for (int i = 0; i < MAX_TUBES; i++)
|
||||
{
|
||||
tubesPos[i].x = 400 + 280*i;
|
||||
tubesPos[i].y = -GetRandomValue(0, 120);
|
||||
}
|
||||
|
||||
Rectangle tubesRecs[MAX_TUBES*2];
|
||||
bool tubesActive[MAX_TUBES];
|
||||
|
||||
for (int i = 0; i < MAX_TUBES*2; i += 2)
|
||||
{
|
||||
tubesRecs[i].x = tubesPos[i/2].x;
|
||||
tubesRecs[i].y = tubesPos[i/2].y;
|
||||
tubesRecs[i].width = tubes.width;
|
||||
tubesRecs[i].height = 255;
|
||||
|
||||
tubesRecs[i+1].x = tubesPos[i/2].x;
|
||||
tubesRecs[i+1].y = 600 + tubesPos[i/2].y - 255;
|
||||
tubesRecs[i+1].width = tubes.width;
|
||||
tubesRecs[i+1].height = 255;
|
||||
|
||||
tubesActive[i/2] = true;
|
||||
}
|
||||
|
||||
int backScroll = 0;
|
||||
|
||||
int score = 0;
|
||||
int hiscore = 0;
|
||||
|
||||
bool gameover = false;
|
||||
bool superfx = false;
|
||||
|
||||
SetTargetFPS(60);
|
||||
//---------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Background scroll logic
|
||||
backScroll--;
|
||||
if (backScroll <= -800) backScroll = 0;
|
||||
|
||||
// Player movement logic
|
||||
if (!gameover)
|
||||
{
|
||||
if (IsKeyDown(KEY_SPACE)) floppyPos.y -= 3;
|
||||
else floppyPos.y += 1;
|
||||
|
||||
if (IsKeyPressed(KEY_SPACE)) PlaySound(jump);
|
||||
}
|
||||
|
||||
// Tubes moving logic
|
||||
for (int i = 0; i < MAX_TUBES; i++) tubesPos[i].x -= tubesSpeedX;
|
||||
|
||||
for (int i = 0; i < MAX_TUBES*2; i += 2)
|
||||
{
|
||||
tubesRecs[i].x = tubesPos[i/2].x;
|
||||
tubesRecs[i+1].x = tubesPos[i/2].x;
|
||||
}
|
||||
|
||||
// Check collisions player-tubes
|
||||
for (int i = 0; i < MAX_TUBES*2; i++)
|
||||
{
|
||||
if (CheckCollisionCircleRec((Vector2){ floppyPos.x + floppy.width/2, floppyPos.y + floppy.height/2 }, floppy.width/2, tubesRecs[i]))
|
||||
{
|
||||
gameover = true;
|
||||
}
|
||||
else if ((tubesPos[i/2].x < floppyPos.x) && tubesActive[i/2] && !gameover)
|
||||
{
|
||||
score += 100;
|
||||
tubesActive[i/2] = false;
|
||||
PlaySound(coin);
|
||||
|
||||
superfx = true;
|
||||
|
||||
if (score > hiscore) hiscore = score;
|
||||
}
|
||||
}
|
||||
|
||||
// Gameover logic for reset
|
||||
if (gameover && IsKeyPressed(KEY_ENTER))
|
||||
{
|
||||
for (int i = 0; i < MAX_TUBES; i++)
|
||||
{
|
||||
tubesPos[i].x = 400 + 280*i;
|
||||
tubesPos[i].y = -GetRandomValue(0, 120);
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_TUBES*2; i += 2)
|
||||
{
|
||||
tubesRecs[i].x = tubesPos[i/2].x;
|
||||
tubesRecs[i].y = tubesPos[i/2].y;
|
||||
|
||||
tubesRecs[i+1].x = tubesPos[i/2].x;
|
||||
tubesRecs[i+1].y = 600 + tubesPos[i/2].y - 255;
|
||||
|
||||
tubesActive[i/2] = true;
|
||||
}
|
||||
|
||||
floppyPos.x = 80;
|
||||
floppyPos.y = screenHeight/2 - floppy.height/2;
|
||||
|
||||
gameover = false;
|
||||
score = 0;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
// Draw scrolling background
|
||||
DrawTexture(background, backScroll, 0, WHITE);
|
||||
DrawTexture(background, screenWidth + backScroll, 0, WHITE);
|
||||
|
||||
// Draw moving tubes
|
||||
for (int i = 0; i < MAX_TUBES; i++)
|
||||
{
|
||||
if (tubesPos[i].x <= 800) DrawTextureEx(tubes, tubesPos[i], 0, 1.0, WHITE);
|
||||
|
||||
// Draw collision recs
|
||||
//DrawRectangleLines(tubesRecs[i*2].x, tubesRecs[i*2].y, tubesRecs[i*2].width, tubesRecs[i*2].height, RED);
|
||||
//DrawRectangleLines(tubesRecs[i*2 + 1].x, tubesRecs[i*2 + 1].y, tubesRecs[i*2 + 1].width, tubesRecs[i*2 + 1].height, RED);
|
||||
}
|
||||
|
||||
// Draw scores
|
||||
DrawText(FormatText("%04i", score), 20, 20, 40, PINK);
|
||||
DrawText(FormatText("HI-SCORE: %04i", hiscore), 20, 70, 20, VIOLET);
|
||||
|
||||
// Draw player or game over messages
|
||||
if (!gameover)
|
||||
{
|
||||
DrawTextureEx(floppy, floppyPos, 0, 1.0, WHITE);
|
||||
|
||||
// Draw collision circle
|
||||
//DrawCircleLines(floppyPos.x + floppy.width/2, floppyPos.y + floppy.height/2, floppy.width/2, RED);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawText("GAME OVER", 100, 180, 100, MAROON);
|
||||
DrawText("PRESS ENTER to RETRY!", 280, 280, 20, RED);
|
||||
}
|
||||
|
||||
// Draw screen light flash when passing through a tube
|
||||
if (superfx)
|
||||
{
|
||||
DrawRectangle(0, 0, screenWidth, screenHeight, GOLD);
|
||||
superfx = false;
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadTexture(background); // Texture unloading
|
||||
UnloadTexture(tubes); // Texture unloading
|
||||
UnloadTexture(floppy); // Texture unloading
|
||||
|
||||
UnloadSound(coin); // Unload sound data
|
||||
UnloadSound(jump); // Unload sound data
|
||||
|
||||
CloseAudioDevice(); // Close audio device
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
Before Width: | Height: | Size: 224 KiB |
Before Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 19 KiB |
288
games/gold_fever.c
Normal file
|
@ -0,0 +1,288 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib - sample game: gold fever
|
||||
*
|
||||
* Sample game developed by Ian Eito, Albert Martos and Ramon Santamaria
|
||||
*
|
||||
* This game has been created using raylib v1.3 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
#include <emscripten/emscripten.h>
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
typedef struct Player {
|
||||
Vector2 position;
|
||||
Vector2 speed;
|
||||
int radius;
|
||||
} Player;
|
||||
|
||||
typedef struct Enemy {
|
||||
Vector2 position;
|
||||
Vector2 speed;
|
||||
int radius;
|
||||
int radiusBounds;
|
||||
bool moveRight; // RAY: o__O
|
||||
} Enemy;
|
||||
|
||||
typedef struct Points {
|
||||
Vector2 position;
|
||||
int radius;
|
||||
int value;
|
||||
bool active;
|
||||
} Points;
|
||||
|
||||
typedef struct Home {
|
||||
Rectangle rec;
|
||||
bool active;
|
||||
bool save;
|
||||
Color color;
|
||||
} Home;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Global Variables Declaration
|
||||
//------------------------------------------------------------------------------------
|
||||
static int screenWidth = 800;
|
||||
static int screenHeight = 450;
|
||||
|
||||
static int framesCounter;
|
||||
static bool gameOver;
|
||||
static bool pause;
|
||||
static int score;
|
||||
static int hiScore = 0;
|
||||
|
||||
static Player player;
|
||||
static Enemy enemy;
|
||||
static Points points;
|
||||
static Home home;
|
||||
static bool follow;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module Functions Declaration (local)
|
||||
//------------------------------------------------------------------------------------
|
||||
static void InitGame(void); // Initialize game
|
||||
static void UpdateGame(void); // Update game (one frame)
|
||||
static void DrawGame(void); // Draw game (one frame)
|
||||
static void UnloadGame(void); // Unload game
|
||||
static void UpdateDrawFrame(void); // Update and Draw (one frame)
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "sample game: gold fever");
|
||||
|
||||
InitGame();
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
emscripten_set_main_loop(UpdateDrawFrame, 0, 1);
|
||||
#else
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateGame();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
DrawGame();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
#endif
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadGame(); // Unload loaded data (textures, sounds, models...)
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module Functions Definitions (local)
|
||||
//------------------------------------------------------------------------------------
|
||||
|
||||
// Initialize game variables
|
||||
void InitGame(void)
|
||||
{
|
||||
pause = false;
|
||||
score = 0;
|
||||
|
||||
player.position = (Vector2){50, 50};
|
||||
player.radius = 20;
|
||||
player.speed = (Vector2){5, 5};
|
||||
|
||||
enemy.position = (Vector2){screenWidth - 50, screenHeight/2};
|
||||
enemy.radius = 20;
|
||||
enemy.radiusBounds = 150;
|
||||
enemy.speed = (Vector2){3, 3};
|
||||
enemy.moveRight = true;
|
||||
follow = false;
|
||||
|
||||
points.radius = 10;
|
||||
points.position = (Vector2){GetRandomValue(points.radius, screenWidth - points.radius), GetRandomValue(points.radius, screenHeight - points.radius)};
|
||||
points.value = 100;
|
||||
points.active = true;
|
||||
|
||||
home.rec.width = 50;
|
||||
home.rec.height = 50;
|
||||
home.rec.x = GetRandomValue(0, screenWidth - home.rec.width);
|
||||
home.rec.y = GetRandomValue(0, screenHeight - home.rec.height);
|
||||
home.active = false;
|
||||
home.save = false;
|
||||
}
|
||||
|
||||
// Update game (one frame)
|
||||
void UpdateGame(void)
|
||||
{
|
||||
if (!gameOver)
|
||||
{
|
||||
if (IsKeyPressed('P')) pause = !pause;
|
||||
|
||||
if (!pause)
|
||||
{
|
||||
//Control player
|
||||
if (IsKeyDown(KEY_RIGHT)) player.position.x += player.speed.x;
|
||||
if (IsKeyDown(KEY_LEFT)) player.position.x -= player.speed.x;
|
||||
if (IsKeyDown(KEY_UP)) player.position.y -= player.speed.y;
|
||||
if (IsKeyDown(KEY_DOWN)) player.position.y += player.speed.y;
|
||||
|
||||
//wall behaviour player
|
||||
if (player.position.x - player.radius <= 0) player.position.x = player.radius;
|
||||
if (player.position.x + player.radius >= screenWidth) player.position.x = screenWidth - player.radius;
|
||||
if (player.position.y - player.radius <= 0) player.position.y = player.radius;
|
||||
if (player.position.y + player.radius >= screenHeight) player.position.y = screenHeight - player.radius;
|
||||
|
||||
//IA Enemy
|
||||
if ( (follow || CheckCollisionCircles(player.position, player.radius, enemy.position, enemy.radiusBounds)) && !home.save)
|
||||
{
|
||||
if (player.position.x > enemy.position.x) enemy.position.x += enemy.speed.x;
|
||||
if (player.position.x < enemy.position.x) enemy.position.x -= enemy.speed.x;
|
||||
|
||||
if (player.position.y > enemy.position.y) enemy.position.y += enemy.speed.y;
|
||||
if (player.position.y < enemy.position.y) enemy.position.y -= enemy.speed.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (enemy.moveRight) enemy.position.x += enemy.speed.x;
|
||||
else enemy.position.x -= enemy.speed.x;
|
||||
}
|
||||
|
||||
//wall behaviour enemy
|
||||
if (enemy.position.x - enemy.radius <= 0) enemy.moveRight = true;
|
||||
if (enemy.position.x + enemy.radius >= screenWidth) enemy.moveRight = false;
|
||||
|
||||
if (enemy.position.x - enemy.radius <= 0) enemy.position.x = enemy.radius;
|
||||
if (enemy.position.x + enemy.radius >= screenWidth) enemy.position.x = screenWidth - enemy.radius;
|
||||
if (enemy.position.y - enemy.radius <= 0) enemy.position.y = enemy.radius;
|
||||
if (enemy.position.y + enemy.radius >= screenHeight) enemy.position.y = screenHeight - enemy.radius;
|
||||
|
||||
//Collisions
|
||||
if (CheckCollisionCircles(player.position, player.radius, points.position, points.radius) && points.active)
|
||||
{
|
||||
follow = true;
|
||||
points.active = false;
|
||||
home.active = true;
|
||||
}
|
||||
|
||||
if (CheckCollisionCircles(player.position, player.radius, enemy.position, enemy.radius) && !home.save)
|
||||
{
|
||||
gameOver = true;
|
||||
|
||||
if (hiScore < score) hiScore = score;
|
||||
}
|
||||
|
||||
if (CheckCollisionCircleRec(player.position, player.radius, home.rec))
|
||||
{
|
||||
follow = false;
|
||||
|
||||
if (!points.active)
|
||||
{
|
||||
score += points.value;
|
||||
points.active = true;
|
||||
enemy.speed.x += 0.5;
|
||||
enemy.speed.y += 0.5;
|
||||
points.position = (Vector2){GetRandomValue(points.radius, screenWidth - points.radius), GetRandomValue(points.radius, screenHeight - points.radius)};
|
||||
}
|
||||
|
||||
home.save = true;
|
||||
}
|
||||
else home.save = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsKeyPressed(KEY_ENTER))
|
||||
{
|
||||
InitGame();
|
||||
gameOver = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw game (one frame)
|
||||
void DrawGame(void)
|
||||
{
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
if (!gameOver)
|
||||
{
|
||||
if (follow)
|
||||
{
|
||||
DrawRectangle(0, 0, screenWidth, screenHeight, RED);
|
||||
DrawRectangle(10, 10, screenWidth - 20, screenHeight - 20, RAYWHITE);
|
||||
}
|
||||
|
||||
DrawRectangleLines(home.rec.x, home.rec.y, home.rec.width, home.rec.height, BLUE);
|
||||
|
||||
DrawCircleLines(enemy.position.x, enemy.position.y, enemy.radiusBounds, RED);
|
||||
DrawCircleV(enemy.position, enemy.radius, MAROON);
|
||||
|
||||
DrawCircleV(player.position, player.radius, GRAY);
|
||||
if (points.active) DrawCircleV(points.position, points.radius, GOLD);
|
||||
|
||||
DrawText(FormatText("SCORE: %04i", score), 20, 15, 20, GRAY);
|
||||
DrawText(FormatText("HI-SCORE: %04i", hiScore), 300, 15, 20, GRAY);
|
||||
|
||||
if (pause) DrawText("GAME PAUSED", screenWidth/2 - MeasureText("GAME PAUSED", 40)/2, screenHeight/2 - 40, 40, GRAY);
|
||||
}
|
||||
else DrawText("PRESS [ENTER] TO PLAY AGAIN", GetScreenWidth()/2 - MeasureText("PRESS [ENTER] TO PLAY AGAIN", 20)/2, GetScreenHeight()/2 - 50, 20, GRAY);
|
||||
|
||||
EndDrawing();
|
||||
}
|
||||
|
||||
// Unload game variables
|
||||
void UnloadGame(void)
|
||||
{
|
||||
// TODO: Unload all dynamic loaded data (textures, sounds, models...)
|
||||
}
|
||||
|
||||
// Update and Draw (one frame)
|
||||
void UpdateDrawFrame(void)
|
||||
{
|
||||
UpdateGame();
|
||||
DrawGame();
|
||||
}
|
571
games/gorilas.c
Normal file
|
@ -0,0 +1,571 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib - sample game: gorilas
|
||||
*
|
||||
* Sample game Marc Palau and Ramon Santamaria
|
||||
*
|
||||
* This game has been created using raylib v1.3 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
#include <emscripten/emscripten.h>
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Some Defines
|
||||
//----------------------------------------------------------------------------------
|
||||
#define MAX_BUILDINGS 15
|
||||
#define MAX_EXPLOSIONS 200
|
||||
#define MAX_PLAYERS 2
|
||||
|
||||
#define BUILDING_RELATIVE_ERROR 30 // Building size random range %
|
||||
#define BUILDING_MIN_RELATIVE_HEIGHT 20 // Minimum height in % of the screenHeight
|
||||
#define BUILDING_MAX_RELATIVE_HEIGHT 60 // Maximum height in % of the screenHeight
|
||||
#define BUILDING_MIN_GRAYSCALE_COLOR 120 // Minimum gray color for the buildings
|
||||
#define BUILDING_MAX_GRAYSCALE_COLOR 200 // Maximum gray color for the buildings
|
||||
|
||||
#define MIN_PLAYER_POSITION 5 // Minimum x position %
|
||||
#define MAX_PLAYER_POSITION 20 // Maximum x position %
|
||||
|
||||
#define GRAVITY 9.81f
|
||||
#define DELTA_FPS 60
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
typedef struct Player {
|
||||
Vector2 position;
|
||||
Vector2 size;
|
||||
|
||||
Vector2 aimingPoint;
|
||||
int aimingAngle;
|
||||
int aimingPower;
|
||||
|
||||
Vector2 previousPoint;
|
||||
int previousAngle;
|
||||
int previousPower;
|
||||
|
||||
Vector2 impactPoint;
|
||||
|
||||
bool isLeftTeam; // This player belongs to the left or to the right team
|
||||
bool isPlayer; // If is a player or an AI
|
||||
bool isAlive;
|
||||
} Player;
|
||||
|
||||
typedef struct Building {
|
||||
Rectangle rectangle;
|
||||
Color color;
|
||||
} Building;
|
||||
|
||||
typedef struct Explosion {
|
||||
Vector2 position;
|
||||
int radius;
|
||||
bool active;
|
||||
} Explosion;
|
||||
|
||||
typedef struct Ball {
|
||||
Vector2 position;
|
||||
Vector2 speed;
|
||||
int radius;
|
||||
bool active;
|
||||
} Ball;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Global Variables Declaration
|
||||
//------------------------------------------------------------------------------------
|
||||
static int screenWidth = 800;
|
||||
static int screenHeight = 450;
|
||||
|
||||
static bool gameOver = false;
|
||||
static bool pause = false;
|
||||
|
||||
static Player player[MAX_PLAYERS];
|
||||
static Building building[MAX_BUILDINGS];
|
||||
static Explosion explosion[MAX_EXPLOSIONS];
|
||||
static Ball ball;
|
||||
|
||||
static int playerTurn = 0;
|
||||
static bool ballOnAir = false;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module Functions Declaration (local)
|
||||
//------------------------------------------------------------------------------------
|
||||
static void InitGame(void); // Initialize game
|
||||
static void UpdateGame(void); // Update game (one frame)
|
||||
static void DrawGame(void); // Draw game (one frame)
|
||||
static void UnloadGame(void); // Unload game
|
||||
static void UpdateDrawFrame(void); // Update and Draw (one frame)
|
||||
|
||||
// Additional module functions
|
||||
static void InitBuildings(void);
|
||||
static void InitPlayers(void);
|
||||
static bool UpdatePlayer(int playerTurn);
|
||||
static bool UpdateBall(int playerTurn);
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "sample game: gorilas");
|
||||
|
||||
InitGame();
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
emscripten_set_main_loop(UpdateDrawFrame, 0, 1);
|
||||
#else
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateGame();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
DrawGame();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
#endif
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadGame(); // Unload loaded data (textures, sounds, models...)
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module Functions Definitions (local)
|
||||
//------------------------------------------------------------------------------------
|
||||
|
||||
// Initialize game variables
|
||||
void InitGame(void)
|
||||
{
|
||||
// Init shoot
|
||||
ball.radius = 10;
|
||||
ballOnAir = false;
|
||||
ball.active = false;
|
||||
|
||||
InitBuildings();
|
||||
InitPlayers();
|
||||
|
||||
// Init explosions
|
||||
for (int i = 0; i < MAX_EXPLOSIONS; i++)
|
||||
{
|
||||
explosion[i].position = (Vector2){ 0.0f, 0.0f };
|
||||
explosion[i].radius = 30;
|
||||
explosion[i].active = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Update game (one frame)
|
||||
void UpdateGame(void)
|
||||
{
|
||||
if (!gameOver)
|
||||
{
|
||||
if (IsKeyPressed('P')) pause = !pause;
|
||||
|
||||
if (!pause)
|
||||
{
|
||||
if (!ballOnAir) ballOnAir = UpdatePlayer(playerTurn); // If we are aiming
|
||||
else
|
||||
{
|
||||
if (UpdateBall(playerTurn)) // If collision
|
||||
{
|
||||
// Game over logic
|
||||
bool leftTeamAlive = false;
|
||||
bool rightTeamAlive = false;
|
||||
|
||||
for (int i = 0; i < MAX_PLAYERS; i++)
|
||||
{
|
||||
if (player[i].isAlive)
|
||||
{
|
||||
if (player[i].isLeftTeam) leftTeamAlive = true;
|
||||
if (!player[i].isLeftTeam) rightTeamAlive = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (leftTeamAlive && rightTeamAlive)
|
||||
{
|
||||
ballOnAir = false;
|
||||
ball.active = false;
|
||||
|
||||
playerTurn++;
|
||||
|
||||
if (playerTurn == MAX_PLAYERS) playerTurn = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
gameOver = true;
|
||||
|
||||
// if (leftTeamAlive) left team wins
|
||||
// if (rightTeamAlive) right team wins
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsKeyPressed(KEY_ENTER))
|
||||
{
|
||||
InitGame();
|
||||
gameOver = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw game (one frame)
|
||||
void DrawGame(void)
|
||||
{
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
if (!gameOver)
|
||||
{
|
||||
// Draw buildings
|
||||
for (int i = 0; i < MAX_BUILDINGS; i++) DrawRectangleRec(building[i].rectangle, building[i].color);
|
||||
|
||||
// Draw explosions
|
||||
for (int i = 0; i < MAX_EXPLOSIONS; i++)
|
||||
{
|
||||
if (explosion[i].active) DrawCircle(explosion[i].position.x, explosion[i].position.y, explosion[i].radius, RAYWHITE);
|
||||
}
|
||||
|
||||
// Draw players
|
||||
for (int i = 0; i < MAX_PLAYERS; i++)
|
||||
{
|
||||
if (player[i].isAlive)
|
||||
{
|
||||
if (player[i].isLeftTeam) DrawRectangle(player[i].position.x - player[i].size.x/2, player[i].position.y - player[i].size.y/2,
|
||||
player[i].size.x, player[i].size.y, BLUE);
|
||||
else DrawRectangle(player[i].position.x - player[i].size.x/2, player[i].position.y - player[i].size.y/2,
|
||||
player[i].size.x, player[i].size.y, RED);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw ball
|
||||
if (ball.active) DrawCircle(ball.position.x, ball.position.y, ball.radius, MAROON);
|
||||
|
||||
// Draw the angle and the power of the aim, and the previous ones
|
||||
if (!ballOnAir)
|
||||
{
|
||||
// Draw shot information
|
||||
/*
|
||||
if (player[playerTurn].isLeftTeam)
|
||||
{
|
||||
DrawText(FormatText("Previous Point %i, %i", (int)player[playerTurn].previousPoint.x, (int)player[playerTurn].previousPoint.y), 20, 20, 20, DARKBLUE);
|
||||
DrawText(FormatText("Previous Angle %i", player[playerTurn].previousAngle), 20, 50, 20, DARKBLUE);
|
||||
DrawText(FormatText("Previous Power %i", player[playerTurn].previousPower), 20, 80, 20, DARKBLUE);
|
||||
DrawText(FormatText("Aiming Point %i, %i", (int)player[playerTurn].aimingPoint.x, (int)player[playerTurn].aimingPoint.y), 20, 110, 20, DARKBLUE);
|
||||
DrawText(FormatText("Aiming Angle %i", player[playerTurn].aimingAngle), 20, 140, 20, DARKBLUE);
|
||||
DrawText(FormatText("Aiming Power %i", player[playerTurn].aimingPower), 20, 170, 20, DARKBLUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawText(FormatText("Previous Point %i, %i", (int)player[playerTurn].previousPoint.x, (int)player[playerTurn].previousPoint.y), screenWidth*3/4, 20, 20, DARKBLUE);
|
||||
DrawText(FormatText("Previous Angle %i", player[playerTurn].previousAngle), screenWidth*3/4, 50, 20, DARKBLUE);
|
||||
DrawText(FormatText("Previous Power %i", player[playerTurn].previousPower), screenWidth*3/4, 80, 20, DARKBLUE);
|
||||
DrawText(FormatText("Aiming Point %i, %i", (int)player[playerTurn].aimingPoint.x, (int)player[playerTurn].aimingPoint.y), screenWidth*3/4, 110, 20, DARKBLUE);
|
||||
DrawText(FormatText("Aiming Angle %i", player[playerTurn].aimingAngle), screenWidth*3/4, 140, 20, DARKBLUE);
|
||||
DrawText(FormatText("Aiming Power %i", player[playerTurn].aimingPower), screenWidth*3/4, 170, 20, DARKBLUE);
|
||||
}
|
||||
*/
|
||||
|
||||
// Draw aim
|
||||
if (player[playerTurn].isLeftTeam)
|
||||
{
|
||||
// Previous aiming
|
||||
DrawTriangle((Vector2){ player[playerTurn].position.x - player[playerTurn].size.x/4, player[playerTurn].position.y - player[playerTurn].size.y/4 },
|
||||
(Vector2){ player[playerTurn].position.x + player[playerTurn].size.x/4, player[playerTurn].position.y + player[playerTurn].size.y/4 },
|
||||
player[playerTurn].previousPoint, GRAY);
|
||||
|
||||
// Actual aiming
|
||||
DrawTriangle((Vector2){ player[playerTurn].position.x - player[playerTurn].size.x/4, player[playerTurn].position.y - player[playerTurn].size.y/4 },
|
||||
(Vector2){ player[playerTurn].position.x + player[playerTurn].size.x/4, player[playerTurn].position.y + player[playerTurn].size.y/4 },
|
||||
player[playerTurn].aimingPoint, DARKBLUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Previous aiming
|
||||
DrawTriangle((Vector2){ player[playerTurn].position.x - player[playerTurn].size.x/4, player[playerTurn].position.y + player[playerTurn].size.y/4 },
|
||||
(Vector2){ player[playerTurn].position.x + player[playerTurn].size.x/4, player[playerTurn].position.y - player[playerTurn].size.y/4 },
|
||||
player[playerTurn].previousPoint, GRAY);
|
||||
|
||||
// Actual aiming
|
||||
DrawTriangle((Vector2){ player[playerTurn].position.x - player[playerTurn].size.x/4, player[playerTurn].position.y + player[playerTurn].size.y/4 },
|
||||
(Vector2){ player[playerTurn].position.x + player[playerTurn].size.x/4, player[playerTurn].position.y - player[playerTurn].size.y/4 },
|
||||
player[playerTurn].aimingPoint, MAROON);
|
||||
}
|
||||
}
|
||||
|
||||
if (pause) DrawText("GAME PAUSED", screenWidth/2 - MeasureText("GAME PAUSED", 40)/2, screenHeight/2 - 40, 40, GRAY);
|
||||
}
|
||||
else DrawText("PRESS [ENTER] TO PLAY AGAIN", GetScreenWidth()/2 - MeasureText("PRESS [ENTER] TO PLAY AGAIN", 20)/2, GetScreenHeight()/2 - 50, 20, GRAY);
|
||||
|
||||
EndDrawing();
|
||||
}
|
||||
|
||||
// Unload game variables
|
||||
void UnloadGame(void)
|
||||
{
|
||||
// TODO: Unload all dynamic loaded data (textures, sounds, models...)
|
||||
}
|
||||
|
||||
// Update and Draw (one frame)
|
||||
void UpdateDrawFrame(void)
|
||||
{
|
||||
UpdateGame();
|
||||
DrawGame();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Additional module functions
|
||||
//--------------------------------------------------------------------------------------
|
||||
static void InitBuildings(void)
|
||||
{
|
||||
// Horizontal generation
|
||||
int currentWidth = 0;
|
||||
|
||||
// We make sure the absolute error randomly generated for each building, has as a minimum value the screenWidth.
|
||||
// This way all the screen will be filled with buildings. Each building will have a different, random width.
|
||||
|
||||
float relativeWidth = 100/(100 - BUILDING_RELATIVE_ERROR);
|
||||
float buildingWidthMean = (screenWidth*relativeWidth/MAX_BUILDINGS) + 1; // We add one to make sure we will cover the whole screen.
|
||||
|
||||
// Vertical generation
|
||||
int currentHeighth = 0;
|
||||
int grayLevel;
|
||||
|
||||
// Creation
|
||||
for (int i = 0; i < MAX_BUILDINGS; i++)
|
||||
{
|
||||
// Horizontal
|
||||
building[i].rectangle.x = currentWidth;
|
||||
building[i].rectangle.width = GetRandomValue(buildingWidthMean*(100 - BUILDING_RELATIVE_ERROR/2)/100 + 1, buildingWidthMean*(100 + BUILDING_RELATIVE_ERROR)/100);
|
||||
|
||||
currentWidth += building[i].rectangle.width;
|
||||
|
||||
// Vertical
|
||||
currentHeighth = GetRandomValue(BUILDING_MIN_RELATIVE_HEIGHT, BUILDING_MAX_RELATIVE_HEIGHT);
|
||||
building[i].rectangle.y = screenHeight - (screenHeight*currentHeighth/100);
|
||||
building[i].rectangle.height = screenHeight*currentHeighth/100 + 1;
|
||||
|
||||
// Color
|
||||
grayLevel = GetRandomValue(BUILDING_MIN_GRAYSCALE_COLOR, BUILDING_MAX_GRAYSCALE_COLOR);
|
||||
building[i].color = (Color){ grayLevel, grayLevel, grayLevel, 255 };
|
||||
}
|
||||
}
|
||||
|
||||
static void InitPlayers(void)
|
||||
{
|
||||
for (int i = 0; i < MAX_PLAYERS; i++)
|
||||
{
|
||||
player[i].isAlive = true;
|
||||
|
||||
// Decide the team of this player
|
||||
if (i % 2 == 0) player[i].isLeftTeam = true;
|
||||
else player[i].isLeftTeam = false;
|
||||
|
||||
// Now there is no AI
|
||||
player[i].isPlayer = true;
|
||||
|
||||
// Set size, by default by now
|
||||
player[i].size = (Vector2){ 40, 40 };
|
||||
|
||||
// Set position
|
||||
if (player[i].isLeftTeam) player[i].position.x = GetRandomValue(screenWidth*MIN_PLAYER_POSITION/100, screenWidth*MAX_PLAYER_POSITION/100);
|
||||
else player[i].position.x = screenWidth - GetRandomValue(screenWidth*MIN_PLAYER_POSITION/100, screenWidth*MAX_PLAYER_POSITION/100);
|
||||
|
||||
for (int j = 0; j < MAX_BUILDINGS; j++)
|
||||
{
|
||||
if (building[j].rectangle.x > player[i].position.x)
|
||||
{
|
||||
// Set the player in the center of the building
|
||||
player[i].position.x = building[j-1].rectangle.x + building[j-1].rectangle.width/2;
|
||||
// Set the player at the top of the building
|
||||
player[i].position.y = building[j-1].rectangle.y - player[i].size.y/2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Set statistics to 0
|
||||
player[i].aimingPoint = player[i].position;
|
||||
player[i].previousAngle = 0;
|
||||
player[i].previousPower = 0;
|
||||
player[i].previousPoint = player[i].position;
|
||||
player[i].aimingAngle = 0;
|
||||
player[i].aimingPower = 0;
|
||||
|
||||
player[i].impactPoint = (Vector2){ -100, -100 };
|
||||
}
|
||||
}
|
||||
|
||||
static bool UpdatePlayer(int playerTurn)
|
||||
{
|
||||
// If we are aiming at the firing quadrant, we calculate the angle
|
||||
if (GetMousePosition().y <= player[playerTurn].position.y)
|
||||
{
|
||||
// Left team
|
||||
if (player[playerTurn].isLeftTeam && GetMousePosition().x >= player[playerTurn].position.x)
|
||||
{
|
||||
// Distance (calculating the fire power)
|
||||
player[playerTurn].aimingPower = sqrt(pow(player[playerTurn].position.x - GetMousePosition().x, 2) + pow(player[playerTurn].position.y - GetMousePosition().y, 2));
|
||||
// Calculates the angle via arcsin
|
||||
player[playerTurn].aimingAngle = asin((player[playerTurn].position.y - GetMousePosition().y)/player[playerTurn].aimingPower)*RAD2DEG;
|
||||
// Point of the screen we are aiming at
|
||||
player[playerTurn].aimingPoint = GetMousePosition();
|
||||
|
||||
// Ball fired
|
||||
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
|
||||
{
|
||||
player[playerTurn].previousPoint = player[playerTurn].aimingPoint;
|
||||
player[playerTurn].previousPower = player[playerTurn].aimingPower;
|
||||
player[playerTurn].previousAngle = player[playerTurn].aimingAngle;
|
||||
ball.position = player[playerTurn].position;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Right team
|
||||
else if (!player[playerTurn].isLeftTeam && GetMousePosition().x <= player[playerTurn].position.x)
|
||||
{
|
||||
// Distance (calculating the fire power)
|
||||
player[playerTurn].aimingPower = sqrt(pow(player[playerTurn].position.x - GetMousePosition().x, 2) + pow(player[playerTurn].position.y - GetMousePosition().y, 2));
|
||||
// Calculates the angle via arcsin
|
||||
player[playerTurn].aimingAngle = asin((player[playerTurn].position.y - GetMousePosition().y)/player[playerTurn].aimingPower)*RAD2DEG;
|
||||
// Point of the screen we are aiming at
|
||||
player[playerTurn].aimingPoint = GetMousePosition();
|
||||
|
||||
// Ball fired
|
||||
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
|
||||
{
|
||||
player[playerTurn].previousPoint = player[playerTurn].aimingPoint;
|
||||
player[playerTurn].previousPower = player[playerTurn].aimingPower;
|
||||
player[playerTurn].previousAngle = player[playerTurn].aimingAngle;
|
||||
ball.position = player[playerTurn].position;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
player[playerTurn].aimingPoint = player[playerTurn].position;
|
||||
player[playerTurn].aimingPower = 0;
|
||||
player[playerTurn].aimingAngle = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
player[playerTurn].aimingPoint = player[playerTurn].position;
|
||||
player[playerTurn].aimingPower = 0;
|
||||
player[playerTurn].aimingAngle = 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool UpdateBall(int playerTurn)
|
||||
{
|
||||
static int explosionNumber = 0;
|
||||
|
||||
// Activate ball
|
||||
if (!ball.active)
|
||||
{
|
||||
if (player[playerTurn].isLeftTeam)
|
||||
{
|
||||
ball.speed.x = cos(player[playerTurn].previousAngle*DEG2RAD)*player[playerTurn].previousPower*3/DELTA_FPS;
|
||||
ball.speed.y = -sin(player[playerTurn].previousAngle*DEG2RAD)*player[playerTurn].previousPower*3/DELTA_FPS;
|
||||
ball.active = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ball.speed.x = -cos(player[playerTurn].previousAngle*DEG2RAD)*player[playerTurn].previousPower*3/DELTA_FPS;
|
||||
ball.speed.y = -sin(player[playerTurn].previousAngle*DEG2RAD)*player[playerTurn].previousPower*3/DELTA_FPS;
|
||||
ball.active = true;
|
||||
}
|
||||
}
|
||||
|
||||
ball.position.x += ball.speed.x;
|
||||
ball.position.y += ball.speed.y;
|
||||
ball.speed.y += GRAVITY/DELTA_FPS;
|
||||
|
||||
// Collision
|
||||
if (ball.position.x + ball.radius < 0) return true;
|
||||
else if (ball.position.x - ball.radius > screenWidth) return true;
|
||||
else
|
||||
{
|
||||
// Player collision
|
||||
for (int i = 0; i < MAX_PLAYERS; i++)
|
||||
{
|
||||
if (CheckCollisionCircleRec(ball.position, ball.radius, (Rectangle){ player[i].position.x - player[i].size.x/2, player[i].position.y - player[i].size.y/2,
|
||||
player[i].size.x, player[i].size.y }))
|
||||
{
|
||||
// We can't hit ourselves
|
||||
if (i == playerTurn) return false;
|
||||
else
|
||||
{
|
||||
// We set the impact point
|
||||
player[playerTurn].impactPoint.x = ball.position.x;
|
||||
player[playerTurn].impactPoint.y = ball.position.y + ball.radius;
|
||||
|
||||
// We destroy the player
|
||||
player[i].isAlive = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Building collision
|
||||
// NOTE: We only check building collision if we are not inside an explosion
|
||||
for (int i = 0; i < MAX_BUILDINGS; i++)
|
||||
{
|
||||
if (CheckCollisionCircles(ball.position, ball.radius, explosion[i].position, explosion[i].radius - ball.radius))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_BUILDINGS; i++)
|
||||
{
|
||||
if (CheckCollisionCircleRec(ball.position, ball.radius, building[i].rectangle))
|
||||
{
|
||||
// We set the impact point
|
||||
player[playerTurn].impactPoint.x = ball.position.x;
|
||||
player[playerTurn].impactPoint.y = ball.position.y + ball.radius;
|
||||
|
||||
// We create an explosion
|
||||
explosion[explosionNumber].position = player[playerTurn].impactPoint;
|
||||
explosion[explosionNumber].active = true;
|
||||
explosionNumber++;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
|
@ -72,7 +72,7 @@ else
|
|||
CFLAGS = -O2 -Wall -std=c99
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
CFLAGS = -O1 -Wall -std=c99 -s USE_GLFW=3
|
||||
CFLAGS = -O1 -Wall -std=c99 -s USE_GLFW=3 --shell-file ../../templates/web_shell/shell.html
|
||||
#-s ASSERTIONS=1 --preload-file resources
|
||||
#-s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing
|
||||
#-s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB)
|
||||
|
|
271
games/light_my_ritual/light_my_ritual.c
Normal file
|
@ -0,0 +1,271 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* GLOBAL GAME JAM 2016 - LIGHT MY RITUAL!
|
||||
*
|
||||
* Preparing a ritual session is not that easy.
|
||||
* You must light all the candles before the astral alignment finishes...
|
||||
* but dark creatures move in the shadows to put out all your lights!
|
||||
* Be fast! Be smart! Light my ritual!
|
||||
*
|
||||
* This game has been created using raylib (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2015 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "screens/screens.h" // NOTE: Defines global variable: currentScreen
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
#include <emscripten/emscripten.h>
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition (local to this module)
|
||||
//----------------------------------------------------------------------------------
|
||||
const int screenWidth = 1280;
|
||||
const int screenHeight = 720;
|
||||
|
||||
// Required variables to manage screen transitions (fade-in, fade-out)
|
||||
float transAlpha = 0;
|
||||
bool onTransition = false;
|
||||
bool transFadeOut = false;
|
||||
int transFromScreen = -1;
|
||||
int transToScreen = -1;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Local Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
void TransitionToScreen(int screen);
|
||||
void ChangeToScreen(int screen); // No transition effect
|
||||
void UpdateTransition(void);
|
||||
void DrawTransition(void);
|
||||
|
||||
void UpdateDrawFrame(void); // Update and Draw one frame
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Main entry point
|
||||
//----------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//---------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "GGJ16 - LIGHT MY RITUAL!");
|
||||
|
||||
// Global data loading (assets that must be available in all screens, i.e. fonts)
|
||||
InitAudioDevice();
|
||||
|
||||
Image image = LoadImage("resources/lights_map.png"); // Load image in CPU memory (RAM)
|
||||
|
||||
lightsMap = GetImageData(image); // Get image pixels data as an array of Color
|
||||
lightsMapWidth = image.width;
|
||||
lightsMapHeight = image.height;
|
||||
|
||||
UnloadImage(image); // Unload image from CPU memory (RAM)
|
||||
|
||||
//PlayMusicStream("resources/audio/come_play_with_me.ogg");
|
||||
|
||||
font = LoadSpriteFont("resources/font_arcadian.png");
|
||||
//doors = LoadTexture("resources/textures/doors.png");
|
||||
//sndDoor = LoadSound("resources/audio/door.ogg");
|
||||
|
||||
// Setup and Init first screen
|
||||
currentScreen = LOGO_RL;
|
||||
//InitTitleScreen();
|
||||
//InitGameplayScreen();
|
||||
rlInitLogoScreen();
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
emscripten_set_main_loop(UpdateDrawFrame, 0, 1);
|
||||
#else
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
UpdateDrawFrame();
|
||||
}
|
||||
#endif
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
switch (currentScreen)
|
||||
{
|
||||
case LOGO_RL: rlUnloadLogoScreen(); break;
|
||||
case TITLE: UnloadTitleScreen(); break;
|
||||
case GAMEPLAY: UnloadGameplayScreen(); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
// Unload all global loaded data (i.e. fonts) here!
|
||||
UnloadSpriteFont(font);
|
||||
//UnloadSound(sndDoor);
|
||||
|
||||
free(lightsMap);
|
||||
|
||||
CloseAudioDevice();
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TransitionToScreen(int screen)
|
||||
{
|
||||
onTransition = true;
|
||||
transFromScreen = currentScreen;
|
||||
transToScreen = screen;
|
||||
}
|
||||
|
||||
void ChangeToScreen(int screen)
|
||||
{
|
||||
switch (currentScreen)
|
||||
{
|
||||
case LOGO_RL: rlUnloadLogoScreen(); break;
|
||||
case TITLE: UnloadTitleScreen(); break;
|
||||
case GAMEPLAY: UnloadGameplayScreen(); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
switch (screen)
|
||||
{
|
||||
case LOGO_RL: rlInitLogoScreen(); break;
|
||||
case TITLE: InitTitleScreen(); break;
|
||||
case GAMEPLAY: InitGameplayScreen(); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
currentScreen = screen;
|
||||
}
|
||||
|
||||
void UpdateTransition(void)
|
||||
{
|
||||
if (!transFadeOut)
|
||||
{
|
||||
transAlpha += 0.05f;
|
||||
|
||||
if (transAlpha >= 1.0)
|
||||
{
|
||||
transAlpha = 1.0;
|
||||
|
||||
switch (transFromScreen)
|
||||
{
|
||||
case LOGO_RL: rlUnloadLogoScreen(); break;
|
||||
case TITLE: UnloadTitleScreen(); break;
|
||||
case GAMEPLAY: UnloadGameplayScreen(); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
switch (transToScreen)
|
||||
{
|
||||
case LOGO_RL:
|
||||
{
|
||||
rlInitLogoScreen();
|
||||
currentScreen = LOGO_RL;
|
||||
} break;
|
||||
case TITLE:
|
||||
{
|
||||
InitTitleScreen();
|
||||
currentScreen = TITLE;
|
||||
} break;
|
||||
case GAMEPLAY:
|
||||
{
|
||||
InitGameplayScreen();
|
||||
currentScreen = GAMEPLAY;
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
transFadeOut = true;
|
||||
}
|
||||
}
|
||||
else // Transition fade out logic
|
||||
{
|
||||
transAlpha -= 0.05f;
|
||||
|
||||
if (transAlpha <= 0)
|
||||
{
|
||||
transAlpha = 0;
|
||||
transFadeOut = false;
|
||||
onTransition = false;
|
||||
transFromScreen = -1;
|
||||
transToScreen = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawTransition(void)
|
||||
{
|
||||
DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), Fade(BLACK, transAlpha));
|
||||
}
|
||||
|
||||
// Update and draw game frame
|
||||
void UpdateDrawFrame(void)
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (!onTransition)
|
||||
{
|
||||
switch(currentScreen)
|
||||
{
|
||||
case LOGO_RL:
|
||||
{
|
||||
rlUpdateLogoScreen();
|
||||
|
||||
if (rlFinishLogoScreen()) TransitionToScreen(TITLE);
|
||||
|
||||
} break;
|
||||
case TITLE:
|
||||
{
|
||||
UpdateTitleScreen();
|
||||
|
||||
if (FinishTitleScreen() == 1) TransitionToScreen(GAMEPLAY);
|
||||
|
||||
} break;
|
||||
case GAMEPLAY:
|
||||
{
|
||||
UpdateGameplayScreen();
|
||||
|
||||
if (FinishGameplayScreen() == 1) ChangeToScreen(LOGO_RL);
|
||||
else if (FinishGameplayScreen() == 2) TransitionToScreen(TITLE);
|
||||
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Update transition (fade-in, fade-out)
|
||||
UpdateTransition();
|
||||
}
|
||||
|
||||
UpdateMusicStream();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
switch(currentScreen)
|
||||
{
|
||||
case LOGO_RL: rlDrawLogoScreen(); break;
|
||||
case TITLE: DrawTitleScreen(); break;
|
||||
case GAMEPLAY: DrawGameplayScreen(); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
if (onTransition) DrawTransition();
|
||||
|
||||
//DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
203
games/light_my_ritual/makefile
Normal file
|
@ -0,0 +1,203 @@
|
|||
#**************************************************************************************************
|
||||
#
|
||||
# raylib - Advance Game
|
||||
#
|
||||
# makefile to compile advance game for desktop platforms, Raspberry Pi and HTML5 (emscripten)
|
||||
#
|
||||
# Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#**************************************************************************************************
|
||||
|
||||
# define raylib platform if not defined (by default, compile for RPI)
|
||||
# Other possible platform: PLATFORM_DESKTOP
|
||||
PLATFORM ?= PLATFORM_DESKTOP
|
||||
|
||||
# determine PLATFORM_OS in case PLATFORM_DESKTOP selected
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
# No uname.exe on MinGW!, but OS=Windows_NT on Windows! ifeq ($(UNAME),Msys) -> Windows
|
||||
ifeq ($(OS),Windows_NT)
|
||||
PLATFORM_OS=WINDOWS
|
||||
LIBPATH=win32
|
||||
else
|
||||
UNAMEOS:=$(shell uname)
|
||||
ifeq ($(UNAMEOS),Linux)
|
||||
PLATFORM_OS=LINUX
|
||||
LIBPATH=linux
|
||||
else
|
||||
ifeq ($(UNAMEOS),Darwin)
|
||||
PLATFORM_OS=OSX
|
||||
LIBPATH=osx
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# define compiler: gcc for C program, define as g++ for C++
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
# define emscripten compiler
|
||||
CC = emcc
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
# define llvm compiler for mac
|
||||
CC = clang
|
||||
else
|
||||
# define default gcc compiler
|
||||
CC = gcc
|
||||
endif
|
||||
endif
|
||||
|
||||
# define compiler flags:
|
||||
# -O2 defines optimization level
|
||||
# -Wall turns on most, but not all, compiler warnings
|
||||
# -std=c99 use standard C from 1999 revision
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
CFLAGS = -O2 -Wall -std=gnu99 -fgnu89-inline
|
||||
else
|
||||
CFLAGS = -O2 -Wall -std=c99
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
CFLAGS = -O1 -Wall -std=c99 -s USE_GLFW=3 --preload-file resources -s ALLOW_MEMORY_GROWTH=1 --shell-file ../../templates/web_shell/shell.html
|
||||
#-s ASSERTIONS=1 --preload-file resources
|
||||
#-s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing
|
||||
#-s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB)
|
||||
endif
|
||||
|
||||
# define any directories containing required header files
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
INCLUDES = -I. -I../../src -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads
|
||||
else
|
||||
INCLUDES = -I. -I../../src
|
||||
# external libraries headers
|
||||
# GLFW3
|
||||
INCLUDES += -I../../external/glfw3/include
|
||||
# GLEW
|
||||
INCLUDES += -I../../external/glew/include
|
||||
# OpenAL Soft
|
||||
INCLUDES += -I../../external/openal_soft/include
|
||||
endif
|
||||
|
||||
# define library paths containing required libs
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
LFLAGS = -L. -L../../src -L/opt/vc/lib
|
||||
else
|
||||
LFLAGS = -L. -L../../src
|
||||
# external libraries to link with
|
||||
# GLFW3
|
||||
LFLAGS += -L../../external/glfw3/lib/$(LIBPATH)
|
||||
ifneq ($(PLATFORM_OS),OSX)
|
||||
# OpenAL Soft
|
||||
LFLAGS += -L../../external/openal_soft/lib/$(LIBPATH)
|
||||
# GLEW
|
||||
LFLAGS += -L../../external/glew/lib/$(LIBPATH)
|
||||
endif
|
||||
endif
|
||||
|
||||
# define any libraries to link into executable
|
||||
# if you want to link libraries (libname.so or libname.a), use the -lname
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
# libraries for Debian GNU/Linux desktop compiling
|
||||
# requires the following packages:
|
||||
# libglfw3-dev libopenal-dev libglew-dev libegl1-mesa-dev
|
||||
LIBS = -lraylib -lglfw -lGLEW -lGL -lopenal
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
# libraries for OS X 10.9 desktop compiling
|
||||
# requires the following packages:
|
||||
# libglfw3-dev libopenal-dev libglew-dev libegl1-mesa-dev
|
||||
LIBS = -lraylib -lglfw -framework OpenGL -framework OpenAl -framework Cocoa
|
||||
else
|
||||
# libraries for Windows desktop compiling
|
||||
# NOTE: GLFW3 and OpenAL Soft libraries should be installed
|
||||
LIBS = -lraylib -lglfw3 -lglew32 -lopengl32 -lopenal32 -lgdi32
|
||||
endif
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
# libraries for Raspberry Pi compiling
|
||||
# NOTE: OpenAL Soft library should be installed (libopenal1 package)
|
||||
LIBS = -lraylib -lGLESv2 -lEGL -lpthread -lrt -lm -lbcm_host -lopenal
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
LIBS = ../../src/libraylib.bc
|
||||
endif
|
||||
|
||||
# define additional parameters and flags for windows
|
||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||
# resources file contains windows exe icon
|
||||
# -Wl,--subsystem,windows hides the console window
|
||||
WINFLAGS = ../../src/resources -Wl,--subsystem,windows
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
EXT = .html
|
||||
endif
|
||||
|
||||
# define all screen object files required
|
||||
SCREENS = \
|
||||
screens/screen_logo_raylib.o \
|
||||
screens/screen_title.o \
|
||||
screens/screen_gameplay.o \
|
||||
|
||||
# typing 'make' will invoke the first target entry in the file,
|
||||
# in this case, the 'default' target entry is advance_game
|
||||
default: light_my_ritual
|
||||
|
||||
# compile template - advance_game
|
||||
light_my_ritual: light_my_ritual.c $(SCREENS)
|
||||
$(CC) -o $@$(EXT) $< $(SCREENS) $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile screen LOGO raylib
|
||||
screens/screen_logo_raylib.o: screens/screen_logo_raylib.c
|
||||
$(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
|
||||
# compile screen TITLE
|
||||
screens/screen_title.o: screens/screen_title.c
|
||||
$(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
|
||||
# compile screen ENDING
|
||||
screens/screen_gameplay.o: screens/screen_gameplay.c
|
||||
$(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
|
||||
# clean everything
|
||||
clean:
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
find . -type f -perm +ugo+x -delete
|
||||
rm -f *.o
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
find . -type f -executable -delete
|
||||
rm -f *.o
|
||||
else
|
||||
del *.o *.exe
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
find . -type f -executable -delete
|
||||
rm -f *.o
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
del *.o *.html *.js
|
||||
endif
|
||||
@echo Cleaning done
|
||||
|
||||
# instead of defining every module one by one, we can define a pattern
|
||||
# this pattern below will automatically compile every module defined on $(OBJS)
|
||||
#%.exe : %.c
|
||||
# $(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM)
|
BIN
games/light_my_ritual/resources/audio/ambient.ogg
Normal file
BIN
games/light_my_ritual/resources/audio/light_off.wav
Normal file
BIN
games/light_my_ritual/resources/audio/light_on.wav
Normal file
BIN
games/light_my_ritual/resources/audio/ritual.ogg
Normal file
BIN
games/light_my_ritual/resources/audio/start.wav
Normal file
BIN
games/light_my_ritual/resources/font_arcadian.png
Normal file
After Width: | Height: | Size: 95 KiB |
BIN
games/light_my_ritual/resources/lights_map.png
Normal file
After Width: | Height: | Size: 430 B |
BIN
games/light_my_ritual/resources/textures/back_title.png
Normal file
After Width: | Height: | Size: 179 KiB |
BIN
games/light_my_ritual/resources/textures/background.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
games/light_my_ritual/resources/textures/book.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
games/light_my_ritual/resources/textures/circle_level_i_off.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
games/light_my_ritual/resources/textures/circle_level_i_on.png
Normal file
After Width: | Height: | Size: 50 KiB |
BIN
games/light_my_ritual/resources/textures/circle_level_ii_off.png
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
games/light_my_ritual/resources/textures/circle_level_ii_on.png
Normal file
After Width: | Height: | Size: 104 KiB |
After Width: | Height: | Size: 37 KiB |
BIN
games/light_my_ritual/resources/textures/circle_level_iii_on.png
Normal file
After Width: | Height: | Size: 156 KiB |
BIN
games/light_my_ritual/resources/textures/enemy.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
games/light_my_ritual/resources/textures/foreground_level_i.png
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
games/light_my_ritual/resources/textures/foreground_level_ii.png
Normal file
After Width: | Height: | Size: 35 KiB |
After Width: | Height: | Size: 41 KiB |
BIN
games/light_my_ritual/resources/textures/light.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
games/light_my_ritual/resources/textures/light_glow.png
Normal file
After Width: | Height: | Size: 8.5 KiB |
BIN
games/light_my_ritual/resources/textures/light_ray.png
Normal file
After Width: | Height: | Size: 8.6 KiB |
BIN
games/light_my_ritual/resources/textures/msg_ritual.png
Normal file
After Width: | Height: | Size: 111 KiB |
BIN
games/light_my_ritual/resources/textures/player.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
games/light_my_ritual/resources/textures/time_over.png
Normal file
After Width: | Height: | Size: 113 KiB |
BIN
games/light_my_ritual/resources/textures/title.png
Normal file
After Width: | Height: | Size: 208 KiB |
842
games/light_my_ritual/screens/screen_gameplay.c
Normal file
|
@ -0,0 +1,842 @@
|
|||
/**********************************************************************************************
|
||||
*
|
||||
* raylib - Advance Game template
|
||||
*
|
||||
* Gameplay Screen Functions Definitions (Init, Update, Draw, Unload)
|
||||
*
|
||||
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "screens.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#define MAX_LIGHTS_I 8
|
||||
#define MAX_LIGHTS_II 12
|
||||
#define MAX_LIGHTS_III 20
|
||||
|
||||
#define MAX_ENEMIES 8
|
||||
|
||||
#define MAX_PLAYER_ENERGY 40.0f
|
||||
#define ENERGY_REFILL_RATIO 0.2f
|
||||
|
||||
#define GAMEPAD_SENSITIVITY 4.0f // More sensitivity, more speed :P
|
||||
|
||||
#define LIGHT_ANIM_FRAMES 7
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
typedef struct Player {
|
||||
Vector2 position;
|
||||
Vector2 speed;
|
||||
int radius;
|
||||
Color color;
|
||||
float lightEnergy;
|
||||
} Player;
|
||||
|
||||
typedef struct Enemy {
|
||||
Vector2 position;
|
||||
Vector2 targetPos; // light target position
|
||||
int targetNum; // light target number
|
||||
float speed; // scalar value
|
||||
int radius;
|
||||
int active;
|
||||
int awakeFramesDelay;
|
||||
int framesCounter;
|
||||
Color color;
|
||||
} Enemy;
|
||||
|
||||
typedef struct Light {
|
||||
Vector2 position;
|
||||
int radius;
|
||||
int requiredEnergy;
|
||||
bool active;
|
||||
Color color;
|
||||
|
||||
int framesCounter;
|
||||
int currentFrame;
|
||||
Rectangle frameRec;
|
||||
} Light;
|
||||
|
||||
typedef enum { LEVEL_I, LEVEL_II, LEVEL_III, LEVEL_FINISHED } LightedLevel;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition (local to this module)
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Gameplay screen global variables
|
||||
static int framesCounter;
|
||||
static int finishScreen;
|
||||
|
||||
//static Texture2D background;
|
||||
|
||||
static bool pause;
|
||||
|
||||
static Player player;
|
||||
|
||||
static Light lightsI[MAX_LIGHTS_I];
|
||||
static Light lightsII[MAX_LIGHTS_II];
|
||||
static Light lightsIII[MAX_LIGHTS_III];
|
||||
|
||||
static Enemy enemies[MAX_ENEMIES];
|
||||
|
||||
static int ritualLevel;
|
||||
static int previousLightedLevel;
|
||||
static int currentLightedLevel;
|
||||
|
||||
static Vector2 lighterPosition;
|
||||
|
||||
static int maxLightEnergy;
|
||||
static int currentLightEnergy;
|
||||
|
||||
static float ritualTime;
|
||||
static bool startRitual;
|
||||
static float alphaRitual;
|
||||
|
||||
static bool timeOver;
|
||||
static int nextStarsAlignment;
|
||||
|
||||
static Texture2D background;
|
||||
static Texture2D foregroundI;
|
||||
static Texture2D foregroundII;
|
||||
static Texture2D foregroundIII;
|
||||
static Texture2D texPlayer;
|
||||
static Texture2D texEnemy;
|
||||
static Texture2D texLight;
|
||||
static Texture2D lightGlow;
|
||||
static Texture2D lightRay;
|
||||
static Texture2D book;
|
||||
static Texture2D texRitual;
|
||||
static Texture2D texTimeOver;
|
||||
static Texture2D circleIoff, circleIIoff, circleIIIoff;
|
||||
static Texture2D circleIon, circleIIon, circleIIIon;
|
||||
|
||||
static Rectangle lightOff, lightOn;
|
||||
|
||||
static Sound fxLightOn, fxLightOff;
|
||||
|
||||
// Debug variables
|
||||
static bool enemiesStopped;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module Functions Declaration (local)
|
||||
//------------------------------------------------------------------------------------
|
||||
static bool ColorEqual(Color col1, Color col2); // Check if two colors are equal
|
||||
static Vector2 Vector2Subtract(Vector2 v1, Vector2 v2);
|
||||
static void Vector2Normalize(Vector2 *v);
|
||||
static void EnemyReset(Enemy *enemy);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Gameplay Screen Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Gameplay Screen Initialization logic
|
||||
void InitGameplayScreen(void)
|
||||
{
|
||||
framesCounter = 0;
|
||||
finishScreen = 0;
|
||||
pause = false;
|
||||
|
||||
// Textures loading
|
||||
background = LoadTexture("resources/textures/background.png");
|
||||
foregroundI = LoadTexture("resources/textures/foreground_level_i.png");
|
||||
foregroundII = LoadTexture("resources/textures/foreground_level_ii.png");
|
||||
foregroundIII = LoadTexture("resources/textures/foreground_level_iii.png");
|
||||
texPlayer = LoadTexture("resources/textures/player.png");
|
||||
texEnemy = LoadTexture("resources/textures/enemy.png");
|
||||
texLight = LoadTexture("resources/textures/light.png");
|
||||
lightGlow = LoadTexture("resources/textures/light_glow.png");
|
||||
lightRay = LoadTexture("resources/textures/light_ray.png");
|
||||
book = LoadTexture("resources/textures/book.png");
|
||||
texRitual = LoadTexture("resources/textures/msg_ritual.png");
|
||||
texTimeOver = LoadTexture("resources/textures/time_over.png");
|
||||
|
||||
circleIoff = LoadTexture("resources/textures/circle_level_i_off.png");
|
||||
circleIIoff = LoadTexture("resources/textures/circle_level_ii_off.png");
|
||||
circleIIIoff = LoadTexture("resources/textures/circle_level_iii_off.png");
|
||||
circleIon = LoadTexture("resources/textures/circle_level_i_on.png");
|
||||
circleIIon = LoadTexture("resources/textures/circle_level_ii_on.png");
|
||||
circleIIIon = LoadTexture("resources/textures/circle_level_iii_on.png");
|
||||
|
||||
lightOff = (Rectangle){ 0, 0, 64, 64 };
|
||||
lightOn = (Rectangle){ 64, 0, 64, 64 };
|
||||
|
||||
fxLightOn = LoadSound("resources/audio/light_on.wav");
|
||||
fxLightOff = LoadSound("resources/audio/light_off.wav");
|
||||
|
||||
// Initialize player
|
||||
player.position = (Vector2){ GetScreenWidth()/2, GetScreenHeight()/2 - 40 };
|
||||
player.radius = 20;
|
||||
player.speed = (Vector2){5, 5};
|
||||
player.color = WHITE;
|
||||
|
||||
// Initialize lights positions based on lights map image data
|
||||
int kI = 0, kII = 0, kIII = 0;
|
||||
for (int y = 0; y < lightsMapHeight; y++)
|
||||
{
|
||||
for (int x = 0; x < lightsMapWidth; x++)
|
||||
{
|
||||
if (ColorEqual(lightsMap[y*lightsMapWidth + x], (Color){ 255, 0, 0, 255 }))
|
||||
{
|
||||
// Store light position I
|
||||
lightsI[kI].position.x = (float)x*10;
|
||||
lightsI[kI].position.y = (float)y*10;
|
||||
kI++;
|
||||
|
||||
//printf("Light %02i position: %i, %i\n", kI, (int)lightsI[kI - 1].position.x, (int)lightsI[kI - 1].position.y);
|
||||
}
|
||||
else if (ColorEqual(lightsMap[y*lightsMapWidth + x], (Color){ 0, 255, 0, 255 }))
|
||||
{
|
||||
// Store light position II
|
||||
lightsII[kII].position.x = (float)x*10;
|
||||
lightsII[kII].position.y = (float)y*10;
|
||||
kII++;
|
||||
}
|
||||
else if (ColorEqual(lightsMap[y*lightsMapWidth + x], (Color){ 0, 0, 255, 255 }))
|
||||
{
|
||||
// Store light position III
|
||||
lightsIII[kIII].position.x = (float)x*10;
|
||||
lightsIII[kIII].position.y = (float)y*10;
|
||||
kIII++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize lights I
|
||||
for (int i = 0; i < MAX_LIGHTS_I; i++)
|
||||
{
|
||||
lightsI[i].radius = 12;
|
||||
lightsI[i].requiredEnergy = GetRandomValue(3, 9);
|
||||
lightsI[i].active = false;
|
||||
lightsI[i].color = GOLD;
|
||||
|
||||
lightsI[i].framesCounter = 0;
|
||||
lightsI[i].currentFrame = 0;
|
||||
lightsI[i].frameRec = (Rectangle){ 0, 0, 64, 64 };
|
||||
}
|
||||
|
||||
// Initialize lights II
|
||||
for (int i = 0; i < MAX_LIGHTS_II; i++)
|
||||
{
|
||||
lightsII[i].radius = 8;
|
||||
lightsII[i].requiredEnergy = GetRandomValue(3, 8);
|
||||
lightsII[i].active = false;
|
||||
lightsII[i].color = GOLD;
|
||||
|
||||
lightsII[i].framesCounter = 0;
|
||||
lightsII[i].currentFrame = 0;
|
||||
lightsII[i].frameRec = (Rectangle){ 0, 0, 64, 64 };
|
||||
}
|
||||
|
||||
// Initialize lights III
|
||||
for (int i = 0; i < MAX_LIGHTS_III; i++)
|
||||
{
|
||||
lightsIII[i].radius = 8;
|
||||
lightsIII[i].requiredEnergy = GetRandomValue(4, 10);
|
||||
lightsIII[i].active = false;
|
||||
lightsIII[i].color = GOLD;
|
||||
|
||||
lightsIII[i].framesCounter = 0;
|
||||
lightsIII[i].currentFrame = 0;
|
||||
lightsIII[i].frameRec = (Rectangle){ 0, 0, 64, 64 };
|
||||
}
|
||||
|
||||
// Initialize ritual level
|
||||
ritualLevel = 0;
|
||||
currentLightedLevel = LEVEL_I;
|
||||
lighterPosition = (Vector2){ GetScreenWidth()/2, GetScreenHeight()/2 };
|
||||
|
||||
// Initialize enemies
|
||||
for (int i = 0; i < MAX_ENEMIES; i++) EnemyReset(&enemies[i]);
|
||||
|
||||
// Initialize max light energy (depends on lights randomness)
|
||||
maxLightEnergy = 0;
|
||||
|
||||
for (int i = 0; i < MAX_LIGHTS_I; i++) maxLightEnergy += lightsI[i].requiredEnergy;
|
||||
for (int i = 0; i < MAX_LIGHTS_II; i++) maxLightEnergy += lightsII[i].requiredEnergy;
|
||||
for (int i = 0; i < MAX_LIGHTS_III; i++) maxLightEnergy += lightsIII[i].requiredEnergy;
|
||||
|
||||
//printf("Max light energy: %i\n", maxLightEnergy);
|
||||
|
||||
// Initialize ritual variables
|
||||
ritualTime = 0.0f;
|
||||
startRitual = false;;
|
||||
alphaRitual = 0.0f;
|
||||
|
||||
timeOver = false;
|
||||
nextStarsAlignment = GetRandomValue(500, 1000);
|
||||
|
||||
enemiesStopped = false;
|
||||
|
||||
PlayMusicStream("resources/audio/ritual.ogg");
|
||||
}
|
||||
|
||||
// Gameplay Screen Update logic
|
||||
void UpdateGameplayScreen(void)
|
||||
{
|
||||
if (IsKeyPressed('P')) pause = !pause;
|
||||
|
||||
if (!pause && (currentLightedLevel != LEVEL_FINISHED) && !timeOver)
|
||||
{
|
||||
framesCounter++; // Time starts counting to awake enemies
|
||||
|
||||
// Player movement logic
|
||||
if (IsKeyDown(KEY_RIGHT)) player.position.x += player.speed.x;
|
||||
else if (IsKeyDown(KEY_LEFT)) player.position.x -= player.speed.x;
|
||||
|
||||
if (IsKeyDown(KEY_UP)) player.position.y -= player.speed.y;
|
||||
else if (IsKeyDown(KEY_DOWN)) player.position.y += player.speed.y;
|
||||
|
||||
// Debug key to stop enemies
|
||||
if (IsKeyPressed(KEY_S)) enemiesStopped = !enemiesStopped;
|
||||
|
||||
/*
|
||||
if (IsGamepadAvailable(GAMEPAD_PLAYER1))
|
||||
{
|
||||
Vector2 movement = GetGamepadMovement(GAMEPAD_PLAYER1);
|
||||
|
||||
player.position.x += movement.x*GAMEPAD_SENSITIVITY;
|
||||
player.position.y += movement.y*GAMEPAD_SENSITIVITY;
|
||||
}
|
||||
*/
|
||||
|
||||
// Player light energy filling logic
|
||||
if (CheckCollisionCircles(player.position, player.radius, lighterPosition, 50))
|
||||
{
|
||||
player.lightEnergy += ENERGY_REFILL_RATIO;
|
||||
player.color = (Color){ 255, 255, 100, 255 };
|
||||
}
|
||||
else player.color = WHITE;
|
||||
|
||||
if (player.lightEnergy > MAX_PLAYER_ENERGY) player.lightEnergy = MAX_PLAYER_ENERGY;
|
||||
|
||||
// Player vs lights collision detection (depends on lighted level)
|
||||
if (currentLightedLevel == LEVEL_I)
|
||||
{
|
||||
for (int i = 0; i < MAX_LIGHTS_I; i++)
|
||||
{
|
||||
// Check player vs lightI collision
|
||||
if (CheckCollisionCircles(player.position, player.radius, lightsI[i].position, lightsI[i].radius))
|
||||
{
|
||||
if (!lightsI[i].active && (player.lightEnergy >= lightsI[i].requiredEnergy))
|
||||
{
|
||||
lightsI[i].active = true;
|
||||
lightsI[i].currentFrame = 1;
|
||||
player.lightEnergy -= lightsI[i].requiredEnergy;
|
||||
|
||||
PlaySound(fxLightOn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (currentLightedLevel == LEVEL_II)
|
||||
{
|
||||
for (int i = 0; i < MAX_LIGHTS_II; i++)
|
||||
{
|
||||
if (CheckCollisionCircles(player.position, player.radius, lightsII[i].position, lightsII[i].radius))
|
||||
{
|
||||
if (!lightsII[i].active && (player.lightEnergy >= lightsII[i].requiredEnergy))
|
||||
{
|
||||
lightsII[i].active = true;
|
||||
player.lightEnergy -= lightsII[i].requiredEnergy;
|
||||
|
||||
PlaySound(fxLightOn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (currentLightedLevel == LEVEL_III)
|
||||
{
|
||||
for (int i = 0; i < MAX_LIGHTS_III; i++)
|
||||
{
|
||||
if (CheckCollisionCircles(player.position, player.radius, lightsIII[i].position, lightsIII[i].radius))
|
||||
{
|
||||
if (!lightsIII[i].active && (player.lightEnergy >= lightsIII[i].requiredEnergy))
|
||||
{
|
||||
lightsIII[i].active = true;
|
||||
player.lightEnergy -= lightsIII[i].requiredEnergy;
|
||||
|
||||
PlaySound(fxLightOn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Lights animation (it doesn't depend on currentLightedLevel)
|
||||
for (int i = 0; i < MAX_LIGHTS_I; i++)
|
||||
{
|
||||
// Light animation
|
||||
if (lightsI[i].active)
|
||||
{
|
||||
lightsI[i].framesCounter++;
|
||||
|
||||
if (lightsI[i].framesCounter > 10)
|
||||
{
|
||||
lightsI[i].currentFrame++;
|
||||
|
||||
if (lightsI[i].currentFrame > LIGHT_ANIM_FRAMES - 1) lightsI[i].currentFrame = 1;
|
||||
|
||||
lightsI[i].framesCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
lightsI[i].frameRec.x = lightsI[i].currentFrame*texLight.width/LIGHT_ANIM_FRAMES;
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_LIGHTS_II; i++)
|
||||
{
|
||||
// Light animation
|
||||
if (lightsII[i].active)
|
||||
{
|
||||
lightsII[i].framesCounter++;
|
||||
|
||||
if (lightsII[i].framesCounter > 10)
|
||||
{
|
||||
lightsII[i].currentFrame++;
|
||||
|
||||
if (lightsII[i].currentFrame > LIGHT_ANIM_FRAMES - 1) lightsII[i].currentFrame = 1;
|
||||
|
||||
lightsII[i].framesCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
lightsII[i].frameRec.x = lightsII[i].currentFrame*texLight.width/LIGHT_ANIM_FRAMES;
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_LIGHTS_III; i++)
|
||||
{
|
||||
// Light animation
|
||||
if (lightsIII[i].active)
|
||||
{
|
||||
lightsIII[i].framesCounter++;
|
||||
|
||||
if (lightsIII[i].framesCounter > 10)
|
||||
{
|
||||
lightsIII[i].currentFrame++;
|
||||
|
||||
if (lightsIII[i].currentFrame > LIGHT_ANIM_FRAMES - 1) lightsIII[i].currentFrame = 1;
|
||||
|
||||
lightsIII[i].framesCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
lightsIII[i].frameRec.x = lightsIII[i].currentFrame*texLight.width/LIGHT_ANIM_FRAMES;
|
||||
}
|
||||
|
||||
// Enemies logic
|
||||
if (!enemiesStopped)
|
||||
{
|
||||
for (int i = 0; i < MAX_ENEMIES; i++)
|
||||
{
|
||||
if (!enemies[i].active) enemies[i].framesCounter++;
|
||||
|
||||
if (enemies[i].framesCounter > enemies[i].awakeFramesDelay) enemies[i].active = true;
|
||||
|
||||
if (enemies[i].active)
|
||||
{
|
||||
// Move to the target
|
||||
Vector2 dir = Vector2Subtract(enemies[i].targetPos, enemies[i].position);
|
||||
Vector2Normalize(&dir);
|
||||
|
||||
enemies[i].position.x += dir.x*enemies[i].speed;
|
||||
enemies[i].position.y += dir.y*enemies[i].speed;
|
||||
|
||||
if (currentLightedLevel == LEVEL_I)
|
||||
{
|
||||
if (CheckCollisionCircles(enemies[i].position, enemies[i].radius, enemies[i].targetPos, lightsI[enemies[i].targetNum].radius))
|
||||
{
|
||||
lightsI[enemies[i].targetNum].active = false;
|
||||
lightsI[enemies[i].targetNum].framesCounter = 0;
|
||||
lightsI[enemies[i].targetNum].currentFrame = 0;
|
||||
lightsI[enemies[i].targetNum].frameRec = (Rectangle){ 0, 0, 64, 64 };
|
||||
|
||||
EnemyReset(&enemies[i]);
|
||||
|
||||
PlaySound(fxLightOff);
|
||||
}
|
||||
}
|
||||
else if (currentLightedLevel == LEVEL_II)
|
||||
{
|
||||
if (CheckCollisionCircles(enemies[i].position, enemies[i].radius, enemies[i].targetPos, lightsII[enemies[i].targetNum].radius))
|
||||
{
|
||||
lightsII[enemies[i].targetNum].active = false;
|
||||
lightsII[enemies[i].targetNum].framesCounter = 0;
|
||||
lightsII[enemies[i].targetNum].currentFrame = 0;
|
||||
lightsII[enemies[i].targetNum].frameRec = (Rectangle){ 0, 0, 64, 64 };
|
||||
|
||||
EnemyReset(&enemies[i]);
|
||||
|
||||
PlaySound(fxLightOff);
|
||||
}
|
||||
}
|
||||
else if (currentLightedLevel == LEVEL_III)
|
||||
{
|
||||
if (CheckCollisionCircles(enemies[i].position, enemies[i].radius, enemies[i].targetPos, lightsIII[enemies[i].targetNum].radius))
|
||||
{
|
||||
lightsIII[enemies[i].targetNum].active = false;
|
||||
lightsIII[enemies[i].targetNum].framesCounter = 0;
|
||||
lightsIII[enemies[i].targetNum].currentFrame = 0;
|
||||
lightsIII[enemies[i].targetNum].frameRec = (Rectangle){ 0, 0, 64, 64 };
|
||||
|
||||
EnemyReset(&enemies[i]);
|
||||
|
||||
PlaySound(fxLightOff);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check current light energy (for right bar)
|
||||
currentLightEnergy = 0;
|
||||
|
||||
for (int i = 0; i < MAX_LIGHTS_I; i++) if (lightsI[i].active) currentLightEnergy += lightsI[i].requiredEnergy;
|
||||
for (int i = 0; i < MAX_LIGHTS_II; i++) if (lightsII[i].active) currentLightEnergy += lightsII[i].requiredEnergy;
|
||||
for (int i = 0; i < MAX_LIGHTS_III; i++) if (lightsIII[i].active) currentLightEnergy += lightsIII[i].requiredEnergy;
|
||||
|
||||
// Check current lighted level
|
||||
// Check ending conditions: all lights off, ritual level reached
|
||||
previousLightedLevel = currentLightedLevel;
|
||||
|
||||
currentLightedLevel = LEVEL_I;
|
||||
|
||||
bool lightedLevel = true;
|
||||
for (int i = 0; i < MAX_LIGHTS_I; i++) if (!lightsI[i].active) lightedLevel = false;
|
||||
if (lightedLevel) currentLightedLevel = LEVEL_II;
|
||||
|
||||
for (int i = 0; i < MAX_LIGHTS_II; i++) if (!lightsII[i].active) lightedLevel = false;
|
||||
if (lightedLevel) currentLightedLevel = LEVEL_III;
|
||||
|
||||
for (int i = 0; i < MAX_LIGHTS_III; i++) if (!lightsIII[i].active) lightedLevel = false;
|
||||
if (lightedLevel)
|
||||
{
|
||||
currentLightedLevel = LEVEL_FINISHED;
|
||||
|
||||
for (int i = 0; i < MAX_ENEMIES; i++) enemies[i].active = false;
|
||||
}
|
||||
|
||||
if (currentLightedLevel != previousLightedLevel) for (int i = 0; i < MAX_ENEMIES; i++) EnemyReset(&enemies[i]);
|
||||
|
||||
ritualTime = (float)framesCounter/60;
|
||||
|
||||
// Check game over condition (time run out)
|
||||
if ((99.0f - ritualTime) <= 0.0f)
|
||||
{
|
||||
ritualTime = 99.0f;
|
||||
timeOver = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (startRitual)
|
||||
{
|
||||
alphaRitual += 0.02f;
|
||||
|
||||
SetMusicVolume(1.0f - alphaRitual);
|
||||
|
||||
if (alphaRitual > 1.0f) finishScreen = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Gameplay Screen Draw logic
|
||||
void DrawGameplayScreen(void)
|
||||
{
|
||||
DrawTexture(background, 0, 0, WHITE);
|
||||
|
||||
// DrawText("STARS ARE ALIGNED! NO TIME TO LOOSE! LIGHT MY RITUAL!",
|
||||
|
||||
// Draw foreground and circles
|
||||
if ((currentLightedLevel == LEVEL_FINISHED) || (currentLightedLevel == LEVEL_III)) DrawTexture(foregroundIII, 0, 0, WHITE);
|
||||
else if (currentLightedLevel == LEVEL_II) DrawTexture(foregroundII, 0, 0, WHITE);
|
||||
else if (currentLightedLevel == LEVEL_I) DrawTexture(foregroundI, 0, 0, WHITE);
|
||||
|
||||
// Draw lighted circles (depends on current lighted level)
|
||||
switch (currentLightedLevel)
|
||||
{
|
||||
case LEVEL_FINISHED:
|
||||
{
|
||||
DrawTexture(circleIIIon, GetScreenWidth()/2 - circleIIIon.width/2, GetScreenHeight()/2 - circleIIIon.height/2, WHITE);
|
||||
DrawTexture(circleIIon, GetScreenWidth()/2 - circleIIon.width/2, GetScreenHeight()/2 - circleIIon.height/2, WHITE);
|
||||
DrawTexture(circleIon, GetScreenWidth()/2 - circleIon.width/2, GetScreenHeight()/2 - circleIon.height/2, WHITE);
|
||||
} break;
|
||||
case LEVEL_III:
|
||||
{
|
||||
DrawTexture(circleIIIoff, GetScreenWidth()/2 - circleIIIoff.width/2, GetScreenHeight()/2 - circleIIIoff.height/2, WHITE);
|
||||
DrawTexture(circleIIon, GetScreenWidth()/2 - circleIIon.width/2, GetScreenHeight()/2 - circleIIon.height/2, WHITE);
|
||||
DrawTexture(circleIon, GetScreenWidth()/2 - circleIon.width/2, GetScreenHeight()/2 - circleIon.height/2, WHITE);
|
||||
} break;
|
||||
case LEVEL_II:
|
||||
{
|
||||
DrawTexture(circleIIoff, GetScreenWidth()/2 - circleIIoff.width/2, GetScreenHeight()/2 - circleIIoff.height/2, WHITE);
|
||||
DrawTexture(circleIon, GetScreenWidth()/2 - circleIon.width/2, GetScreenHeight()/2 - circleIon.height/2, WHITE);
|
||||
} break;
|
||||
case LEVEL_I:
|
||||
{
|
||||
DrawTexture(circleIoff, GetScreenWidth()/2 - circleIoff.width/2, GetScreenHeight()/2 - circleIoff.height/2, WHITE);
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
// Draw lights (depends on current lighted level)
|
||||
switch (currentLightedLevel)
|
||||
{
|
||||
case LEVEL_FINISHED:
|
||||
case LEVEL_III:
|
||||
{
|
||||
for (int i = 0; i < MAX_LIGHTS_III; i++)
|
||||
{
|
||||
//if (lightsIII[i].active) DrawCircleV(lightsIII[i].position, lightsIII[i].radius, GOLD);
|
||||
//else DrawCircleLines(lightsIII[i].position.x, lightsIII[i].position.y, lightsIII[i].radius, GRAY);
|
||||
|
||||
if (lightsIII[i].active)
|
||||
{
|
||||
DrawTextureRec(texLight, lightsIII[i].frameRec, (Vector2){ lightsIII[i].position.x - 32, lightsIII[i].position.y - 32 }, WHITE);
|
||||
DrawTexture(lightGlow, lightsIII[i].position.x - lightGlow.width/2, lightsIII[i].position.y - lightGlow.height/2, Fade(WHITE, 0.3f));
|
||||
DrawText(FormatText("%02i", lightsIII[i].requiredEnergy), lightsIII[i].position.x - 10, lightsIII[i].position.y + 14, 20, GRAY);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawTextureRec(texLight, lightsIII[i].frameRec, (Vector2){ lightsIII[i].position.x - 32, lightsIII[i].position.y - 32 }, WHITE);
|
||||
DrawText(FormatText("%02i", lightsIII[i].requiredEnergy), lightsIII[i].position.x - 10, lightsIII[i].position.y + 14, 20, YELLOW);
|
||||
}
|
||||
}
|
||||
}
|
||||
case LEVEL_II:
|
||||
{
|
||||
for (int i = 0; i < MAX_LIGHTS_II; i++)
|
||||
{
|
||||
//if (lightsII[i].active) DrawCircleV(lightsII[i].position, lightsII[i].radius, GOLD);
|
||||
//else DrawCircleLines(lightsI[i].position.x, lightsI[i].position.y, lightsI[i].radius, GRAY);
|
||||
|
||||
if (lightsII[i].active)
|
||||
{
|
||||
DrawTextureRec(texLight, lightsII[i].frameRec, (Vector2){ lightsII[i].position.x - 32, lightsII[i].position.y - 32 }, WHITE);
|
||||
DrawTexture(lightGlow, lightsII[i].position.x - lightGlow.width/2, lightsII[i].position.y - lightGlow.height/2, Fade(WHITE, 0.3f));
|
||||
DrawText(FormatText("%02i", lightsII[i].requiredEnergy), lightsII[i].position.x - 10, lightsII[i].position.y + 14, 20, GRAY);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawTextureRec(texLight, lightsII[i].frameRec, (Vector2){ lightsII[i].position.x - 32, lightsII[i].position.y - 32 }, WHITE);
|
||||
DrawText(FormatText("%02i", lightsII[i].requiredEnergy), lightsII[i].position.x - 10, lightsII[i].position.y + 14, 20, YELLOW);
|
||||
}
|
||||
}
|
||||
}
|
||||
case LEVEL_I:
|
||||
{
|
||||
for (int i = 0; i < MAX_LIGHTS_I; i++)
|
||||
{
|
||||
//if (lightsI[i].active) DrawCircleV(lightsI[i].position, lightsI[i].radius, GOLD);
|
||||
//else DrawCircleLines(lightsI[i].position.x, lightsI[i].position.y, lightsI[i].radius, GRAY);
|
||||
|
||||
if (lightsI[i].active)
|
||||
{
|
||||
DrawTextureRec(texLight, lightsI[i].frameRec, (Vector2){ lightsI[i].position.x - 32, lightsI[i].position.y - 32 }, WHITE);
|
||||
DrawTexture(lightGlow, lightsI[i].position.x - lightGlow.width/2, lightsI[i].position.y - lightGlow.height/2, Fade(WHITE, 0.3f));
|
||||
DrawText(FormatText("%02i", lightsI[i].requiredEnergy), lightsI[i].position.x - 10, lightsI[i].position.y + 14, 20, GRAY);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawTextureRec(texLight, lightsI[i].frameRec, (Vector2){ lightsI[i].position.x - 32, lightsI[i].position.y - 32 }, WHITE);
|
||||
DrawText(FormatText("%02i", lightsI[i].requiredEnergy), lightsI[i].position.x - 10, lightsI[i].position.y + 14, 20, YELLOW);
|
||||
}
|
||||
}
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
|
||||
// Draw main lighter
|
||||
DrawTexture(book, GetScreenWidth()/2 - book.width/2, GetScreenHeight()/2, WHITE);
|
||||
DrawTexture(lightRay, GetScreenWidth()/2 - lightRay.width/2, 0, Fade(WHITE, 0.5f));
|
||||
|
||||
// Draw player
|
||||
//DrawCircleV(player.position, player.radius, player.color);
|
||||
DrawTexture(texPlayer, player.position.x - 32, player.position.y - 32, player.color);
|
||||
|
||||
if (currentLightedLevel != LEVEL_FINISHED)
|
||||
{
|
||||
// Draw enemies (depends on current lighted level)
|
||||
for (int i = 0; i < MAX_ENEMIES; i++)
|
||||
{
|
||||
if (enemies[i].active)
|
||||
{
|
||||
//DrawCircleV(enemies[i].position, enemies[i].radius, enemies[i].color);
|
||||
DrawTextureRec(texEnemy, (Rectangle){ 0, 0, 64, 64 }, (Vector2){ enemies[i].position.x - 32, enemies[i].position.y - 32 }, WHITE);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw time left for ritual
|
||||
DrawTextEx(font, FormatText("%02.2f", (99.0f - ritualTime)), (Vector2){ 560, 20 }, font.size, 0, WHITE);
|
||||
|
||||
// Draw light energy bar
|
||||
DrawRectangle(20, 30, 400, 20, GRAY);
|
||||
DrawRectangle(20, 30, (400*player.lightEnergy)/MAX_PLAYER_ENERGY, 20, GOLD);
|
||||
DrawRectangleLines(20, 30, 400, 20, LIGHTGRAY);
|
||||
DrawText(FormatText("%03.0f", player.lightEnergy), 430, 30, 20, WHITE);
|
||||
|
||||
// Draw level lighted bar (for completion)
|
||||
DrawRectangle(GetScreenWidth() - 40, 30, 20, 660, GRAY);
|
||||
DrawRectangle(GetScreenWidth() - 40, 30 + 660 - 660*currentLightEnergy/maxLightEnergy, 20, 660*currentLightEnergy/maxLightEnergy, YELLOW);
|
||||
DrawRectangleLines(GetScreenWidth() - 40, 30, 20, 660, LIGHTGRAY);
|
||||
|
||||
// Show message: "You run out of light!!!" if player.lightEnergy <= 0
|
||||
if (player.lightEnergy < 2)
|
||||
{
|
||||
if ((framesCounter/20)%2) DrawTextEx(font, "YOU'RE RUNNING OUT OF LIGHT!", (Vector2){ 20, 60 }, font.size/2, 0, WHITE);
|
||||
}
|
||||
}
|
||||
else if (!timeOver) // LEVEL_FINISHED
|
||||
{
|
||||
DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), Fade(BLACK, 0.4f));
|
||||
|
||||
// Wait some time before jumping to ending: raylib
|
||||
DrawTexture(texRitual, GetScreenWidth()/2 - texRitual.width/2, 100, WHITE);
|
||||
DrawTextEx(font, FormatText("BEST LIGHTING TIME: %02.2f", ritualTime), (Vector2){ 320, 340 }, 50, 0, WHITE);
|
||||
DrawTextEx(font, "PRESS ENTER to START the RITUAL", (Vector2){ 160, 480 }, 60, 0, WHITE);
|
||||
|
||||
if (IsKeyPressed(KEY_ENTER)) startRitual = true;
|
||||
}
|
||||
|
||||
if (timeOver)
|
||||
{
|
||||
DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), Fade(BLACK, 0.4f));
|
||||
|
||||
DrawTexture(texTimeOver, GetScreenWidth()/2 - texTimeOver.width/2, 140, WHITE);
|
||||
DrawTextEx(font, FormatText("NEXT STARS ALIGNMENT IN %i YEARS", nextStarsAlignment), (Vector2){ 200, 360 }, 50, 0, WHITE);
|
||||
DrawTextEx(font, "PRESS ENTER to GO HOME...", (Vector2){ 260, 480 }, 60, 0, WHITE);
|
||||
|
||||
if (IsKeyPressed(KEY_ENTER)) finishScreen = 2;
|
||||
}
|
||||
|
||||
if (startRitual) DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), Fade(RAYWHITE, alphaRitual));
|
||||
|
||||
if (pause) DrawTextEx(font, "RITUAL PAUSED", (Vector2){ GetScreenWidth()/2 - MeasureText("RITUAL PAUSED", 40)/2, 110 }, 50, 0, WHITE);
|
||||
}
|
||||
|
||||
// Gameplay Screen Unload logic
|
||||
void UnloadGameplayScreen(void)
|
||||
{
|
||||
// Unload GAMEPLAY screen variables here!
|
||||
UnloadTexture(background);
|
||||
UnloadTexture(foregroundI);
|
||||
UnloadTexture(foregroundII);
|
||||
UnloadTexture(foregroundIII);
|
||||
UnloadTexture(texPlayer);
|
||||
UnloadTexture(texEnemy);
|
||||
UnloadTexture(texLight);
|
||||
UnloadTexture(lightGlow);
|
||||
UnloadTexture(lightRay);
|
||||
UnloadTexture(book);
|
||||
UnloadTexture(texRitual);
|
||||
UnloadTexture(texTimeOver);
|
||||
|
||||
// Unload circles
|
||||
UnloadTexture(circleIoff);
|
||||
UnloadTexture(circleIIoff);
|
||||
UnloadTexture(circleIIIoff);
|
||||
UnloadTexture(circleIon);
|
||||
UnloadTexture(circleIIon);
|
||||
UnloadTexture(circleIIIon);
|
||||
|
||||
// Unload sounds
|
||||
UnloadSound(fxLightOn);
|
||||
UnloadSound(fxLightOff);
|
||||
}
|
||||
|
||||
// Gameplay Screen should finish?
|
||||
int FinishGameplayScreen(void)
|
||||
{
|
||||
return finishScreen;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module Functions Definitions (local)
|
||||
//------------------------------------------------------------------------------------
|
||||
|
||||
// Check two colors if equal
|
||||
static bool ColorEqual(Color col1, Color col2)
|
||||
{
|
||||
return ((col1.r == col2.r) && (col1.g == col2.g) && (col1.b == col2.b) && (col1.a == col2.a));
|
||||
}
|
||||
|
||||
// Substract two vectors
|
||||
static Vector2 Vector2Subtract(Vector2 v1, Vector2 v2)
|
||||
{
|
||||
Vector2 result;
|
||||
|
||||
result.x = v1.x - v2.x;
|
||||
result.y = v1.y - v2.y;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Normalize provided vector
|
||||
static void Vector2Normalize(Vector2 *v)
|
||||
{
|
||||
float length, ilength;
|
||||
|
||||
length = sqrt(v->x*v->x + v->y*v->y);
|
||||
|
||||
if (length == 0) length = 1.0f;
|
||||
|
||||
ilength = 1.0f/length;
|
||||
|
||||
v->x *= ilength;
|
||||
v->y *= ilength;
|
||||
}
|
||||
|
||||
// Reset enemy parameters
|
||||
// NOTE: Depends on currentLightedLevel
|
||||
static void EnemyReset(Enemy *enemy)
|
||||
{
|
||||
enemy->active = false;
|
||||
enemy->framesCounter = 0;
|
||||
enemy->color = RED;
|
||||
enemy->radius = 10;
|
||||
|
||||
int side = GetRandomValue(0, 1);
|
||||
|
||||
if (side) enemy->position = (Vector2){ GetRandomValue(50, 150), GetRandomValue(50, GetScreenHeight() - 50) };
|
||||
else enemy->position = (Vector2){ GetRandomValue(GetScreenWidth() - 150, GetScreenWidth() - 50), GetRandomValue(50, GetScreenHeight() - 50) };
|
||||
|
||||
// TODO: Choose only active lights
|
||||
// TODO: if currentLightedLevel has no active lights, choose light from a lower level!
|
||||
|
||||
if (currentLightedLevel == LEVEL_I)
|
||||
{
|
||||
enemy->targetNum = GetRandomValue(0, MAX_LIGHTS_I - 1); // LEVEL_I
|
||||
enemy->targetPos = lightsI[enemy->targetNum].position;
|
||||
enemy->speed = (float)GetRandomValue(15, 20)/10.0f;
|
||||
enemy->awakeFramesDelay = GetRandomValue(90, 400);
|
||||
}
|
||||
else if (currentLightedLevel == LEVEL_II)
|
||||
{
|
||||
enemy->targetNum = GetRandomValue(0, MAX_LIGHTS_II - 1); // LEVEL_II
|
||||
enemy->targetPos = lightsII[enemy->targetNum].position;
|
||||
enemy->speed = (float)GetRandomValue(10, 20)/10.0f;
|
||||
enemy->awakeFramesDelay = GetRandomValue(240, 800);
|
||||
}
|
||||
else if (currentLightedLevel == LEVEL_III)
|
||||
{
|
||||
enemy->targetNum = GetRandomValue(0, MAX_LIGHTS_III - 1); // LEVEL_III
|
||||
enemy->targetPos = lightsIII[enemy->targetNum].position;
|
||||
enemy->speed = (float)GetRandomValue(8, 18)/10.0f;
|
||||
enemy->awakeFramesDelay = GetRandomValue(180, 1200);
|
||||
}
|
||||
}
|
214
games/light_my_ritual/screens/screen_logo_raylib.c
Normal file
|
@ -0,0 +1,214 @@
|
|||
/**********************************************************************************************
|
||||
*
|
||||
* raylib - Advance Game template
|
||||
*
|
||||
* Logo Screen Functions Definitions (Init, Update, Draw, Unload)
|
||||
*
|
||||
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "screens.h"
|
||||
|
||||
#define LOGO_RECS_SIDE 16
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition (local to this module)
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Logo screen global variables
|
||||
static int framesCounter;
|
||||
static int finishScreen;
|
||||
|
||||
static int logoPositionX;
|
||||
static int logoPositionY;
|
||||
|
||||
static int lettersCount;
|
||||
|
||||
static int topSideRecWidth;
|
||||
static int leftSideRecHeight;
|
||||
|
||||
static int bottomSideRecWidth;
|
||||
static int rightSideRecHeight;
|
||||
|
||||
static char raylib[8]; // raylib text array, max 8 letters
|
||||
static int state; // Tracking animation states (State Machine)
|
||||
static float alpha = 1.0f; // Useful for fading
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Logo Screen Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Logo Screen Initialization logic
|
||||
void rlInitLogoScreen(void)
|
||||
{
|
||||
// Initialize LOGO screen variables here!
|
||||
finishScreen = 0;
|
||||
framesCounter = 0;
|
||||
lettersCount = 0;
|
||||
|
||||
logoPositionX = GetScreenWidth()/2 - 128;
|
||||
logoPositionY = GetScreenHeight()/2 - 128;
|
||||
|
||||
topSideRecWidth = LOGO_RECS_SIDE;
|
||||
leftSideRecHeight = LOGO_RECS_SIDE;
|
||||
bottomSideRecWidth = LOGO_RECS_SIDE;
|
||||
rightSideRecHeight = LOGO_RECS_SIDE;
|
||||
|
||||
for (int i = 0; i < 8; i++) raylib[i] = '\0';
|
||||
|
||||
state = 0;
|
||||
alpha = 1.0f;
|
||||
|
||||
PlayMusicStream("resources/audio/ambient.ogg");
|
||||
SetMusicVolume(1.0f);
|
||||
}
|
||||
|
||||
// Logo Screen Update logic
|
||||
void rlUpdateLogoScreen(void)
|
||||
{
|
||||
// Update LOGO screen variables here!
|
||||
if (state == 0) // State 0: Small box blinking
|
||||
{
|
||||
framesCounter++;
|
||||
|
||||
if (framesCounter == 80)
|
||||
{
|
||||
state = 1;
|
||||
framesCounter = 0; // Reset counter... will be used later...
|
||||
}
|
||||
}
|
||||
else if (state == 1) // State 1: Top and left bars growing
|
||||
{
|
||||
topSideRecWidth += 8;
|
||||
leftSideRecHeight += 8;
|
||||
|
||||
if (topSideRecWidth == 256) state = 2;
|
||||
}
|
||||
else if (state == 2) // State 2: Bottom and right bars growing
|
||||
{
|
||||
bottomSideRecWidth += 8;
|
||||
rightSideRecHeight += 8;
|
||||
|
||||
if (bottomSideRecWidth == 256) state = 3;
|
||||
}
|
||||
else if (state == 3) // State 3: Letters appearing (one by one)
|
||||
{
|
||||
framesCounter++;
|
||||
|
||||
if (framesCounter/10) // Every 12 frames, one more letter!
|
||||
{
|
||||
lettersCount++;
|
||||
framesCounter = 0;
|
||||
}
|
||||
|
||||
switch (lettersCount)
|
||||
{
|
||||
case 1: raylib[0] = 'r'; break;
|
||||
case 2: raylib[1] = 'a'; break;
|
||||
case 3: raylib[2] = 'y'; break;
|
||||
case 4: raylib[3] = 'l'; break;
|
||||
case 5: raylib[4] = 'i'; break;
|
||||
case 6: raylib[5] = 'b'; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
// When all letters have appeared...
|
||||
if (lettersCount >= 10)
|
||||
{
|
||||
state = 4;
|
||||
framesCounter = 0;
|
||||
}
|
||||
}
|
||||
else if (state == 4)
|
||||
{
|
||||
framesCounter++;
|
||||
|
||||
if (framesCounter > 100)
|
||||
{
|
||||
alpha -= 0.02f;
|
||||
|
||||
if (alpha <= 0.0f)
|
||||
{
|
||||
alpha = 0.0f;
|
||||
finishScreen = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Logo Screen Draw logic
|
||||
void rlDrawLogoScreen(void)
|
||||
{
|
||||
if (state == 0)
|
||||
{
|
||||
if ((framesCounter/10)%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(raylib, GetScreenWidth()/2 - 44, GetScreenHeight()/2 + 48, 50, Fade(BLACK, alpha));
|
||||
}
|
||||
else if (state == 4)
|
||||
{
|
||||
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(raylib, GetScreenWidth()/2 - 44, GetScreenHeight()/2 + 48, 50, Fade(BLACK, alpha));
|
||||
|
||||
if (framesCounter > 20) DrawText("powered by", logoPositionX, logoPositionY - 27, 20, Fade(DARKGRAY, alpha));
|
||||
}
|
||||
}
|
||||
|
||||
// Logo Screen Unload logic
|
||||
void rlUnloadLogoScreen(void)
|
||||
{
|
||||
// TODO: Unload LOGO screen variables here!
|
||||
}
|
||||
|
||||
// Logo Screen should finish?
|
||||
int rlFinishLogoScreen(void)
|
||||
{
|
||||
return finishScreen;
|
||||
}
|
105
games/light_my_ritual/screens/screen_title.c
Normal file
|
@ -0,0 +1,105 @@
|
|||
/**********************************************************************************************
|
||||
*
|
||||
* raylib - Advance Game template
|
||||
*
|
||||
* Title Screen Functions Definitions (Init, Update, Draw, Unload)
|
||||
*
|
||||
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "screens.h"
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition (local to this module)
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Title screen global variables
|
||||
static int framesCounter;
|
||||
static int finishScreen;
|
||||
|
||||
static Texture2D background;
|
||||
static Texture2D title;
|
||||
static float titleAlpha = 0.0f;
|
||||
|
||||
static Sound fxStart;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Title Screen Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Title Screen Initialization logic
|
||||
void InitTitleScreen(void)
|
||||
{
|
||||
// Initialize TITLE screen variables here!
|
||||
framesCounter = 0;
|
||||
finishScreen = 0;
|
||||
|
||||
background = LoadTexture("resources/textures/back_title.png");
|
||||
title = LoadTexture("resources/textures/title.png");
|
||||
|
||||
fxStart = LoadSound("resources/audio/start.wav");
|
||||
}
|
||||
|
||||
// Title Screen Update logic
|
||||
void UpdateTitleScreen(void)
|
||||
{
|
||||
// Update TITLE screen variables here!
|
||||
framesCounter++;
|
||||
|
||||
titleAlpha += 0.005f;
|
||||
|
||||
if (titleAlpha >= 1.0f) titleAlpha = 1.0f;
|
||||
|
||||
// Press enter to change to ATTIC screen
|
||||
if ((IsKeyPressed(KEY_ENTER)) || (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)))
|
||||
{
|
||||
PlaySound(fxStart);
|
||||
finishScreen = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Title Screen Draw logic
|
||||
void DrawTitleScreen(void)
|
||||
{
|
||||
DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), (Color){ 26, 26, 26, 255 });
|
||||
|
||||
DrawTexture(background, GetScreenWidth()/2 - background.width/2, 0, WHITE);
|
||||
DrawTexture(title, GetScreenWidth()/2 - title.width/2, 30, Fade(WHITE, titleAlpha));
|
||||
|
||||
DrawText("(c) Developed by Ramon Santamaria (@raysan5)", 20, GetScreenHeight() - 40, 20, LIGHTGRAY);
|
||||
|
||||
if ((framesCounter > 180) && ((framesCounter/40)%2)) DrawTextEx(font, "PRESS ENTER to START LIGHTING", (Vector2){ 230, 450 }, font.size, -2, WHITE);
|
||||
}
|
||||
|
||||
// Title Screen Unload logic
|
||||
void UnloadTitleScreen(void)
|
||||
{
|
||||
// Unload TITLE screen variables here!
|
||||
UnloadTexture(background);
|
||||
UnloadTexture(title);
|
||||
|
||||
UnloadSound(fxStart);
|
||||
}
|
||||
|
||||
// Title Screen should finish?
|
||||
int FinishTitleScreen(void)
|
||||
{
|
||||
return finishScreen;
|
||||
}
|
78
games/light_my_ritual/screens/screens.h
Normal file
|
@ -0,0 +1,78 @@
|
|||
/**********************************************************************************************
|
||||
*
|
||||
* raylib - Advance Game template
|
||||
*
|
||||
* Screens Functions Declarations (Init, Update, Draw, Unload)
|
||||
*
|
||||
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
*
|
||||
* 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 SCREENS_H
|
||||
#define SCREENS_H
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
typedef enum GameScreen { LOGO_RL = 0, TITLE, GAMEPLAY } GameScreen;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
GameScreen currentScreen;
|
||||
SpriteFont font;
|
||||
|
||||
Color *lightsMap;
|
||||
int lightsMapWidth, lightsMapHeight;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { // Prevents name mangling of functions
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// raylib Logo Screen Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
void rlInitLogoScreen(void);
|
||||
void rlUpdateLogoScreen(void);
|
||||
void rlDrawLogoScreen(void);
|
||||
void rlUnloadLogoScreen(void);
|
||||
int rlFinishLogoScreen(void);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Title Screen Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
void InitTitleScreen(void);
|
||||
void UpdateTitleScreen(void);
|
||||
void DrawTitleScreen(void);
|
||||
void UnloadTitleScreen(void);
|
||||
int FinishTitleScreen(void);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Gameplay Screen Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
void InitGameplayScreen(void);
|
||||
void UpdateGameplayScreen(void);
|
||||
void DrawGameplayScreen(void);
|
||||
void UnloadGameplayScreen(void);
|
||||
int FinishGameplayScreen(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SCREENS_H
|
254
games/makefile
Normal file
|
@ -0,0 +1,254 @@
|
|||
#**************************************************************************************************
|
||||
#
|
||||
# raylib makefile for desktop platforms, Raspberry Pi and HTML5 (emscripten)
|
||||
#
|
||||
# Copyright (c) 2015 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.
|
||||
#
|
||||
#**************************************************************************************************
|
||||
|
||||
# define raylib platform to compile for
|
||||
# possible platforms: PLATFORM_DESKTOP PLATFORM_RPI PLATFORM_WEB
|
||||
# WARNING: To compile to HTML5, code must be redesigned to use emscripten.h and emscripten_set_main_loop()
|
||||
PLATFORM ?= PLATFORM_DESKTOP
|
||||
|
||||
# determine PLATFORM_OS in case PLATFORM_DESKTOP selected
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
# No uname.exe on MinGW!, but OS=Windows_NT on Windows! ifeq ($(UNAME),Msys) -> Windows
|
||||
ifeq ($(OS),Windows_NT)
|
||||
PLATFORM_OS=WINDOWS
|
||||
LIBPATH=win32
|
||||
else
|
||||
UNAMEOS:=$(shell uname)
|
||||
ifeq ($(UNAMEOS),Linux)
|
||||
PLATFORM_OS=LINUX
|
||||
LIBPATH=linux
|
||||
else
|
||||
ifeq ($(UNAMEOS),Darwin)
|
||||
PLATFORM_OS=OSX
|
||||
LIBPATH=osx
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# define compiler: gcc for C program, define as g++ for C++
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
# define emscripten compiler
|
||||
CC = emcc
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
# define llvm compiler for mac
|
||||
CC = clang
|
||||
else
|
||||
# define default gcc compiler
|
||||
CC = gcc
|
||||
endif
|
||||
endif
|
||||
|
||||
# define compiler flags:
|
||||
# -O2 defines optimization level
|
||||
# -Wall turns on most, but not all, compiler warnings
|
||||
# -std=c99 use standard C from 1999 revision
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
CFLAGS = -O2 -Wall -std=gnu99 -fgnu89-inline
|
||||
else
|
||||
CFLAGS = -O2 -Wall -std=c99
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
CFLAGS = -O1 -Wall -std=c99 -s USE_GLFW=3 --shell-file ../../templates/web_shell/shell.html
|
||||
#-s ASSERTIONS=1 # to check for memory allocation errors (-O1 disables it)
|
||||
#-s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing
|
||||
#-s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB)
|
||||
endif
|
||||
|
||||
#CFLAGSEXTRA = -Wextra -Wmissing-prototypes -Wstrict-prototypes
|
||||
|
||||
# define any directories containing required header files
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
INCLUDES = -I. -I../src -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads
|
||||
else
|
||||
INCLUDES = -I. -I../src
|
||||
# external libraries headers
|
||||
# GLFW3
|
||||
INCLUDES += -I../external/glfw3/include
|
||||
# GLEW - Not required any more, replaced by GLAD
|
||||
#INCLUDES += -I../external/glew/include
|
||||
# OpenAL Soft
|
||||
INCLUDES += -I../external/openal_soft/include
|
||||
endif
|
||||
|
||||
# define library paths containing required libs
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
LFLAGS = -L. -L../src -L/opt/vc/lib
|
||||
else
|
||||
LFLAGS = -L. -L../src
|
||||
# external libraries to link with
|
||||
# GLFW3
|
||||
LFLAGS += -L../external/glfw3/lib/$(LIBPATH)
|
||||
ifneq ($(PLATFORM_OS),OSX)
|
||||
# OpenAL Soft
|
||||
LFLAGS += -L../external/openal_soft/lib/$(LIBPATH)
|
||||
# GLEW: Not used, replaced by GLAD
|
||||
#LFLAGS += -L../../external/glew/lib/$(LIBPATH)
|
||||
endif
|
||||
endif
|
||||
|
||||
# define any libraries to link into executable
|
||||
# if you want to link libraries (libname.so or libname.a), use the -lname
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
# libraries for Debian GNU/Linux desktop compiling
|
||||
# requires the following packages:
|
||||
# libglfw3-dev libopenal-dev libglew-dev libegl1-mesa-dev
|
||||
LIBS = -lraylib -lglfw3 -lGLEW -lGL -lopenal -lm -pthread
|
||||
# on XWindow could require also below libraries, just uncomment
|
||||
#LIBS += -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
# libraries for OS X 10.9 desktop compiling
|
||||
# requires the following packages:
|
||||
# libglfw3-dev libopenal-dev libglew-dev libegl1-mesa-dev
|
||||
LIBS = -lraylib -lglfw -framework OpenGL -framework OpenAl -framework Cocoa
|
||||
else
|
||||
# libraries for Windows desktop compiling
|
||||
# NOTE: GLFW3 and OpenAL Soft libraries should be installed
|
||||
LIBS = -lraylib -lglfw3 -lopengl32 -lopenal32 -lgdi32
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
# libraries for Raspberry Pi compiling
|
||||
# NOTE: OpenAL Soft library should be installed (libopenal1 package)
|
||||
LIBS = -lraylib -lGLESv2 -lEGL -lpthread -lrt -lm -lbcm_host -lopenal
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
# NOTE: Set the correct path to libraylib.bc
|
||||
LIBS = ../src/libraylib.bc
|
||||
endif
|
||||
|
||||
# define additional parameters and flags for windows
|
||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||
# resources file contains windows exe icon
|
||||
# -Wl,--subsystem,windows hides the console window
|
||||
WINFLAGS = ../src/resources -Wl,--subsystem,windows
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
EXT = .html
|
||||
endif
|
||||
|
||||
# define all object files required
|
||||
SAMPLES = \
|
||||
arkanoid \
|
||||
asteroids \
|
||||
asteroids_survival \
|
||||
floppy \
|
||||
gold_fever \
|
||||
gorilas \
|
||||
missile_commander \
|
||||
pang \
|
||||
snake \
|
||||
space_invaders \
|
||||
tetris \
|
||||
fix_dylib \
|
||||
|
||||
|
||||
# typing 'make' will invoke the first target entry in the file,
|
||||
# in this case, the 'default' target entry is raylib
|
||||
default: samples
|
||||
|
||||
# compile all game samples
|
||||
samples: $(SAMPLES)
|
||||
|
||||
# compile game sample - arkanoid
|
||||
arkanoid: arkanoid.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile game sample - steroids
|
||||
asteroids: asteroids.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile game sample - asteroids_survival
|
||||
asteroids_survival: asteroids_survival.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile game sample - floppy
|
||||
floppy: floppy.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile game sample - gold_fever
|
||||
gold_fever: gold_fever.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile game sample - gorilas
|
||||
gorilas: gorilas.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile game sample - missile_commander
|
||||
missile_commander: missile_commander.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile game sample - pang
|
||||
pang: pang.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile game sample - snake
|
||||
snake: snake.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile game sample - space_invaders
|
||||
space_invaders: space_invaders.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile game sample - tetris
|
||||
tetris: tetris.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# fix dylib install path name for each executable (MAC)
|
||||
fix_dylib:
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
find . -type f -perm +ugo+x -print0 | xargs -t -0 -R 1 -I file install_name_tool -change libglfw.3.0.dylib ../external/glfw3/lib/osx/libglfw.3.0.dylib file
|
||||
endif
|
||||
|
||||
# clean everything
|
||||
clean:
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
find . -type f -perm +ugo+x -delete
|
||||
rm -f *.o
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
find -type f -executable | xargs file -i | grep -E 'x-object|x-archive|x-sharedlib|x-executable' | rev | cut -d ':' -f 2- | rev | xargs rm -f
|
||||
else
|
||||
del *.o *.exe
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
find . -type f -executable -delete
|
||||
rm -f *.o
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
del *.o *.html *.js
|
||||
endif
|
||||
@echo Cleaning done
|
||||
|
||||
# instead of defining every module one by one, we can define a pattern
|
||||
# this pattern below will automatically compile every module defined on $(OBJS)
|
||||
#%.exe : %.c
|
||||
# $(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM)
|
539
games/missile_commander.c
Normal file
|
@ -0,0 +1,539 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib - sample game: missile commander
|
||||
*
|
||||
* Sample game Marc Palau and Ramon Santamaria
|
||||
*
|
||||
* This game has been created using raylib v1.3 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
#include <emscripten/emscripten.h>
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Some Defines
|
||||
//----------------------------------------------------------------------------------
|
||||
#define MAX_MISSILES 100
|
||||
#define MAX_INTERCEPTORS 30
|
||||
#define MAX_EXPLOSIONS 100
|
||||
#define LAUNCHERS_AMOUNT 3 // Not a variable, should not be changed
|
||||
#define BUILDINGS_AMOUNT 6 // Not a variable, should not be changed
|
||||
|
||||
#define LAUNCHER_SIZE 80
|
||||
#define BUILDING_SIZE 60
|
||||
#define EXPLOSION_RADIUS 40
|
||||
|
||||
#define MISSILE_SPEED 1
|
||||
#define MISSILE_LAUNCH_FRAMES 80
|
||||
#define INTERCEPTOR_SPEED 10
|
||||
#define EXPLOSION_INCREASE_TIME 90 // In frames
|
||||
#define EXPLOSION_TOTAL_TIME 210 // In frames
|
||||
|
||||
#define EXPLOSION_COLOR (Color){ 125, 125, 125, 125 }
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
typedef struct Missile {
|
||||
Vector2 origin;
|
||||
Vector2 position;
|
||||
Vector2 objective;
|
||||
Vector2 speed;
|
||||
|
||||
bool active;
|
||||
} Missile;
|
||||
|
||||
typedef struct Interceptor {
|
||||
Vector2 origin;
|
||||
Vector2 position;
|
||||
Vector2 objective;
|
||||
Vector2 speed;
|
||||
|
||||
bool active;
|
||||
} Interceptor;
|
||||
|
||||
typedef struct Explosion {
|
||||
Vector2 position;
|
||||
float radiusMultiplier;
|
||||
int frame;
|
||||
bool active;
|
||||
} Explosion;
|
||||
|
||||
typedef struct Launcher {
|
||||
Vector2 position;
|
||||
bool active;
|
||||
} Launcher;
|
||||
|
||||
typedef struct Building {
|
||||
Vector2 position;
|
||||
bool active;
|
||||
} Building;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Global Variables Declaration
|
||||
//------------------------------------------------------------------------------------
|
||||
static int screenWidth = 800;
|
||||
static int screenHeight = 450;
|
||||
|
||||
static int framesCounter = 0;
|
||||
static bool gameOver = false;
|
||||
static bool pause = false;
|
||||
static int score = 0;
|
||||
|
||||
static Missile missile[MAX_MISSILES];
|
||||
static Interceptor interceptor[MAX_INTERCEPTORS];
|
||||
static Explosion explosion[MAX_EXPLOSIONS];
|
||||
static Launcher launcher[LAUNCHERS_AMOUNT];
|
||||
static Building building[BUILDINGS_AMOUNT];
|
||||
static int explosionIndex = 0;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module Functions Declaration (local)
|
||||
//------------------------------------------------------------------------------------
|
||||
static void InitGame(void); // Initialize game
|
||||
static void UpdateGame(void); // Update game (one frame)
|
||||
static void DrawGame(void); // Draw game (one frame)
|
||||
static void UnloadGame(void); // Unload game
|
||||
static void UpdateDrawFrame(void); // Update and Draw (one frame)
|
||||
|
||||
// Additional module functions
|
||||
static void UpdateOutgoingFire();
|
||||
static void UpdateIncomingFire();
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "sample game: missile commander");
|
||||
|
||||
InitGame();
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
emscripten_set_main_loop(UpdateDrawFrame, 0, 1);
|
||||
#else
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateGame();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
DrawGame();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
#endif
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadGame(); // Unload loaded data (textures, sounds, models...)
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Game Module Functions Definition
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Initialize game variables
|
||||
void InitGame(void)
|
||||
{
|
||||
// Initialize missiles
|
||||
for (int i = 0; i < MAX_MISSILES; i++)
|
||||
{
|
||||
missile[i].origin = (Vector2){ 0, 0 };
|
||||
missile[i].speed = (Vector2){ 0, 0 };
|
||||
missile[i].position = (Vector2){ 0, 0 };
|
||||
|
||||
missile[i].active = false;
|
||||
}
|
||||
|
||||
// Initialize interceptors
|
||||
for (int i = 0; i < MAX_INTERCEPTORS; i++)
|
||||
{
|
||||
interceptor[i].origin = (Vector2){ 0, 0 };
|
||||
interceptor[i].speed = (Vector2){ 0, 0 };
|
||||
interceptor[i].position = (Vector2){ 0, 0 };
|
||||
|
||||
interceptor[i].active = false;
|
||||
}
|
||||
|
||||
// Initialize explosions
|
||||
for (int i = 0; i < MAX_EXPLOSIONS; i++)
|
||||
{
|
||||
explosion[i].position = (Vector2){ 0, 0 };
|
||||
explosion[i].frame = 0;
|
||||
explosion[i].active = false;
|
||||
}
|
||||
|
||||
// Initialize buildings and launchers
|
||||
int sparcing = screenWidth/(LAUNCHERS_AMOUNT + BUILDINGS_AMOUNT + 1);
|
||||
|
||||
// Buildings and launchers placing
|
||||
launcher[0].position = (Vector2){ 1*sparcing, screenHeight - LAUNCHER_SIZE/2 };
|
||||
building[0].position = (Vector2){ 2*sparcing, screenHeight - BUILDING_SIZE/2 };
|
||||
building[1].position = (Vector2){ 3*sparcing, screenHeight - BUILDING_SIZE/2 };
|
||||
building[2].position = (Vector2){ 4*sparcing, screenHeight - BUILDING_SIZE/2 };
|
||||
launcher[1].position = (Vector2){ 5*sparcing, screenHeight - LAUNCHER_SIZE/2 };
|
||||
building[3].position = (Vector2){ 6*sparcing, screenHeight - BUILDING_SIZE/2 };
|
||||
building[4].position = (Vector2){ 7*sparcing, screenHeight - BUILDING_SIZE/2 };
|
||||
building[5].position = (Vector2){ 8*sparcing, screenHeight - BUILDING_SIZE/2 };
|
||||
launcher[2].position = (Vector2){ 9*sparcing, screenHeight - LAUNCHER_SIZE/2 };
|
||||
|
||||
// Buildings and launchers activation
|
||||
for (int i = 0; i < LAUNCHERS_AMOUNT; i++) launcher[i].active = true;
|
||||
for (int i = 0; i < BUILDINGS_AMOUNT; i++) building[i].active = true;
|
||||
|
||||
// Initialize game variables
|
||||
score = 0;
|
||||
}
|
||||
|
||||
// Update game (one frame)
|
||||
void UpdateGame(void)
|
||||
{
|
||||
if (!gameOver)
|
||||
{
|
||||
if (IsKeyPressed('P')) pause = !pause;
|
||||
|
||||
if (!pause)
|
||||
{
|
||||
framesCounter++;
|
||||
|
||||
static
|
||||
float distance;
|
||||
|
||||
// Interceptors update
|
||||
for (int i = 0; i < MAX_INTERCEPTORS; i++)
|
||||
{
|
||||
if (interceptor[i].active)
|
||||
{
|
||||
// Update position
|
||||
interceptor[i].position.x += interceptor[i].speed.x;
|
||||
interceptor[i].position.y += interceptor[i].speed.y;
|
||||
|
||||
// Distance to objective
|
||||
distance = sqrt( pow(interceptor[i].position.x - interceptor[i].objective.x, 2) +
|
||||
pow(interceptor[i].position.y - interceptor[i].objective.y, 2));
|
||||
|
||||
if (distance < INTERCEPTOR_SPEED)
|
||||
{
|
||||
// Interceptor dissapears
|
||||
interceptor[i].active = false;
|
||||
|
||||
// Explosion
|
||||
explosion[explosionIndex].position = interceptor[i].position;
|
||||
explosion[explosionIndex].active = true;
|
||||
explosion[explosionIndex].frame = 0;
|
||||
explosionIndex++;
|
||||
if (explosionIndex == MAX_EXPLOSIONS) explosionIndex = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Missiles update
|
||||
for (int i = 0; i < MAX_MISSILES; i++)
|
||||
{
|
||||
if (missile[i].active)
|
||||
{
|
||||
// Update position
|
||||
missile[i].position.x += missile[i].speed.x;
|
||||
missile[i].position.y += missile[i].speed.y;
|
||||
|
||||
// Collision and missile out of bounds
|
||||
if (missile[i].position.y > screenHeight) missile[i].active = false;
|
||||
else
|
||||
{
|
||||
// CHeck collision with launchers
|
||||
for (int j = 0; j < LAUNCHERS_AMOUNT; j++)
|
||||
{
|
||||
if (launcher[j].active)
|
||||
{
|
||||
if (CheckCollisionPointRec(missile[i].position, (Rectangle){ launcher[j].position.x - LAUNCHER_SIZE/2, launcher[j].position.y - LAUNCHER_SIZE/2,
|
||||
LAUNCHER_SIZE, LAUNCHER_SIZE }))
|
||||
{
|
||||
// Missile dissapears
|
||||
missile[i].active = false;
|
||||
|
||||
// Explosion and destroy building
|
||||
launcher[j].active = false;
|
||||
|
||||
explosion[explosionIndex].position = missile[i].position;
|
||||
explosion[explosionIndex].active = true;
|
||||
explosion[explosionIndex].frame = 0;
|
||||
explosionIndex++;
|
||||
if (explosionIndex == MAX_EXPLOSIONS) explosionIndex = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CHeck collision with buildings
|
||||
for (int j = 0; j < BUILDINGS_AMOUNT; j++)
|
||||
{
|
||||
if (building[j].active)
|
||||
{
|
||||
if (CheckCollisionPointRec(missile[i].position, (Rectangle){ building[j].position.x - BUILDING_SIZE/2, building[j].position.y - BUILDING_SIZE/2,
|
||||
BUILDING_SIZE, BUILDING_SIZE }))
|
||||
{
|
||||
// Missile dissapears
|
||||
missile[i].active = false;
|
||||
|
||||
// Explosion and destroy building
|
||||
building[j].active = false;
|
||||
|
||||
explosion[explosionIndex].position = missile[i].position;
|
||||
explosion[explosionIndex].active = true;
|
||||
explosion[explosionIndex].frame = 0;
|
||||
explosionIndex++;
|
||||
if (explosionIndex == MAX_EXPLOSIONS) explosionIndex = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CHeck collision with explosions
|
||||
for (int j = 0; j < MAX_EXPLOSIONS; j++)
|
||||
{
|
||||
if (explosion[j].active)
|
||||
{
|
||||
if (CheckCollisionPointCircle(missile[i].position, explosion[j].position, EXPLOSION_RADIUS*explosion[j].radiusMultiplier))
|
||||
{
|
||||
// Missile dissapears and we earn 100 points
|
||||
missile[i].active = false;
|
||||
score += 100;
|
||||
|
||||
explosion[explosionIndex].position = missile[i].position;
|
||||
explosion[explosionIndex].active = true;
|
||||
explosion[explosionIndex].frame = 0;
|
||||
explosionIndex++;
|
||||
if (explosionIndex == MAX_EXPLOSIONS) explosionIndex = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Explosions update
|
||||
for (int i = 0; i < MAX_EXPLOSIONS; i++)
|
||||
{
|
||||
if (explosion[i].active)
|
||||
{
|
||||
explosion[i].frame++;
|
||||
|
||||
if (explosion[i].frame <= EXPLOSION_INCREASE_TIME) explosion[i].radiusMultiplier = explosion[i].frame/(float)EXPLOSION_INCREASE_TIME;
|
||||
else if (explosion[i].frame <= EXPLOSION_TOTAL_TIME) explosion[i].radiusMultiplier = 1 - (explosion[i].frame - (float)EXPLOSION_INCREASE_TIME)/(float)EXPLOSION_TOTAL_TIME;
|
||||
else
|
||||
{
|
||||
explosion[i].frame = 0;
|
||||
explosion[i].active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fire logic
|
||||
UpdateOutgoingFire();
|
||||
UpdateIncomingFire();
|
||||
|
||||
// Game over logic
|
||||
int checker = 0;
|
||||
|
||||
for (int i = 0; i < LAUNCHERS_AMOUNT; i++)
|
||||
{
|
||||
if (!launcher[i].active) checker++;
|
||||
if (checker == LAUNCHERS_AMOUNT) gameOver = true;
|
||||
}
|
||||
|
||||
checker = 0;
|
||||
for (int i = 0; i < BUILDINGS_AMOUNT; i++)
|
||||
{
|
||||
if (!building[i].active) checker++;
|
||||
if (checker == BUILDINGS_AMOUNT) gameOver = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsKeyPressed(KEY_ENTER))
|
||||
{
|
||||
InitGame();
|
||||
gameOver = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw game (one frame)
|
||||
void DrawGame(void)
|
||||
{
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
if (!gameOver)
|
||||
{
|
||||
// Draw missiles
|
||||
for (int i = 0; i < MAX_MISSILES; i++)
|
||||
{
|
||||
if (missile[i].active)
|
||||
{
|
||||
DrawLine(missile[i].origin.x, missile[i].origin.y, missile[i].position.x, missile[i].position.y, RED);
|
||||
|
||||
if (framesCounter % 16 < 8) DrawCircle(missile[i].position.x, missile[i].position.y, 3, YELLOW);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw interceptors
|
||||
for (int i = 0; i < MAX_INTERCEPTORS; i++)
|
||||
{
|
||||
if (interceptor[i].active)
|
||||
{
|
||||
DrawLine(interceptor[i].origin.x, interceptor[i].origin.y, interceptor[i].position.x, interceptor[i].position.y, GREEN);
|
||||
|
||||
if (framesCounter % 16 < 8) DrawCircle(interceptor[i].position.x, interceptor[i].position.y, 3, BLUE);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw explosions
|
||||
for (int i = 0; i < MAX_EXPLOSIONS; i++)
|
||||
{
|
||||
if (explosion[i].active) DrawCircle(explosion[i].position.x, explosion[i].position.y, EXPLOSION_RADIUS*explosion[i].radiusMultiplier, EXPLOSION_COLOR);
|
||||
}
|
||||
|
||||
// Draw buildings and launchers
|
||||
for (int i = 0; i < LAUNCHERS_AMOUNT; i++)
|
||||
{
|
||||
if (launcher[i].active) DrawRectangle(launcher[i].position.x - LAUNCHER_SIZE/2, launcher[i].position.y - LAUNCHER_SIZE/2, LAUNCHER_SIZE, LAUNCHER_SIZE, GRAY);
|
||||
}
|
||||
|
||||
for (int i = 0; i < BUILDINGS_AMOUNT; i++)
|
||||
{
|
||||
if (building[i].active) DrawRectangle(building[i].position.x - BUILDING_SIZE/2, building[i].position.y - BUILDING_SIZE/2, BUILDING_SIZE, BUILDING_SIZE, LIGHTGRAY);
|
||||
}
|
||||
|
||||
// Draw score
|
||||
DrawText(FormatText("SCORE %4i", score), 20, 20, 40, LIGHTGRAY);
|
||||
|
||||
if (pause) DrawText("GAME PAUSED", screenWidth/2 - MeasureText("GAME PAUSED", 40)/2, screenHeight/2 - 40, 40, GRAY);
|
||||
}
|
||||
else DrawText("PRESS [ENTER] TO PLAY AGAIN", GetScreenWidth()/2 - MeasureText("PRESS [ENTER] TO PLAY AGAIN", 20)/2, GetScreenHeight()/2 - 50, 20, GRAY);
|
||||
|
||||
EndDrawing();
|
||||
}
|
||||
|
||||
// Unload game variables
|
||||
void UnloadGame(void)
|
||||
{
|
||||
// TODO: Unload all dynamic loaded data (textures, sounds, models...)
|
||||
}
|
||||
|
||||
// Update and Draw (one frame)
|
||||
void UpdateDrawFrame(void)
|
||||
{
|
||||
UpdateGame();
|
||||
DrawGame();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Additional module functions
|
||||
//--------------------------------------------------------------------------------------
|
||||
static void UpdateOutgoingFire()
|
||||
{
|
||||
static int interceptorNumber = 0;
|
||||
int launcherShooting = 0;
|
||||
|
||||
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) launcherShooting = 1;
|
||||
if (IsMouseButtonPressed(MOUSE_MIDDLE_BUTTON)) launcherShooting = 2;
|
||||
if (IsMouseButtonPressed(MOUSE_RIGHT_BUTTON)) launcherShooting = 3;
|
||||
|
||||
if (launcherShooting > 0 && launcher[launcherShooting - 1].active)
|
||||
{
|
||||
float module;
|
||||
float sideX;
|
||||
float sideY;
|
||||
|
||||
// Activate the interceptor
|
||||
interceptor[interceptorNumber].active = true;
|
||||
|
||||
// Assign start position
|
||||
interceptor[interceptorNumber].origin = launcher[launcherShooting - 1].position;
|
||||
interceptor[interceptorNumber].position = interceptor[interceptorNumber].origin;
|
||||
interceptor[interceptorNumber].objective = GetMousePosition();
|
||||
|
||||
// Calculate speed
|
||||
module = sqrt( pow(interceptor[interceptorNumber].objective.x - interceptor[interceptorNumber].origin.x, 2) +
|
||||
pow(interceptor[interceptorNumber].objective.y - interceptor[interceptorNumber].origin.y, 2));
|
||||
|
||||
sideX = (interceptor[interceptorNumber].objective.x - interceptor[interceptorNumber].origin.x)*INTERCEPTOR_SPEED/module;
|
||||
sideY = (interceptor[interceptorNumber].objective.y - interceptor[interceptorNumber].origin.y)*INTERCEPTOR_SPEED/module;
|
||||
|
||||
interceptor[interceptorNumber].speed = (Vector2){ sideX, sideY };
|
||||
|
||||
// Update
|
||||
interceptorNumber++;
|
||||
if (interceptorNumber == MAX_INTERCEPTORS) interceptorNumber = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void UpdateIncomingFire()
|
||||
{
|
||||
static int missileIndex = 0;
|
||||
|
||||
// Launch missile
|
||||
if (framesCounter % MISSILE_LAUNCH_FRAMES == 0)
|
||||
{
|
||||
float module;
|
||||
float sideX;
|
||||
float sideY;
|
||||
|
||||
// Activate the missile
|
||||
missile[missileIndex].active = true;
|
||||
|
||||
// Assign start position
|
||||
missile[missileIndex].origin = (Vector2){ GetRandomValue(20, screenWidth - 20), -10 };
|
||||
missile[missileIndex].position = missile[missileIndex].origin;
|
||||
missile[missileIndex].objective = (Vector2){ GetRandomValue(20, screenWidth - 20), screenHeight + 10 };
|
||||
|
||||
// Calculate speed
|
||||
module = sqrt( pow(missile[missileIndex].objective.x - missile[missileIndex].origin.x, 2) +
|
||||
pow(missile[missileIndex].objective.y - missile[missileIndex].origin.y, 2));
|
||||
|
||||
sideX = (missile[missileIndex].objective.x - missile[missileIndex].origin.x)*MISSILE_SPEED/module;
|
||||
sideY = (missile[missileIndex].objective.y - missile[missileIndex].origin.y)*MISSILE_SPEED/module;
|
||||
|
||||
missile[missileIndex].speed = (Vector2){ sideX, sideY };
|
||||
|
||||
// Update
|
||||
missileIndex++;
|
||||
if (missileIndex == MAX_MISSILES) missileIndex = 0;
|
||||
}
|
||||
}
|
630
games/pang.c
Normal file
|
@ -0,0 +1,630 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib - sample game: pang
|
||||
*
|
||||
* Sample game developed by Ian Eito and Albert Martos and Ramon Santamaria
|
||||
*
|
||||
* This game has been created using raylib v1.3 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
#include <emscripten/emscripten.h>
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Some Defines
|
||||
//----------------------------------------------------------------------------------
|
||||
#define PLAYER_BASE_SIZE 20.0f
|
||||
#define PLAYER_SPEED 5.0f
|
||||
#define PLAYER_MAX_SHOOTS 1
|
||||
|
||||
#define MAX_BIG_BALLS 2
|
||||
#define BALLS_SPEED 2.0f
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
typedef struct Player {
|
||||
Vector2 position;
|
||||
Vector2 speed;
|
||||
Vector3 collider;
|
||||
float rotation;
|
||||
} Player;
|
||||
|
||||
typedef struct Shoot {
|
||||
Vector2 position;
|
||||
Vector2 speed;
|
||||
float radius;
|
||||
float rotation;
|
||||
int lifeSpawn;
|
||||
bool active;
|
||||
} Shoot;
|
||||
|
||||
typedef struct Ball {
|
||||
Vector2 position;
|
||||
Vector2 speed;
|
||||
float radius;
|
||||
int points;
|
||||
bool active;
|
||||
} Ball;
|
||||
|
||||
typedef struct Points {
|
||||
Vector2 position;
|
||||
int value;
|
||||
float alpha;
|
||||
} Points;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Global Variables Declaration
|
||||
//------------------------------------------------------------------------------------
|
||||
static int screenWidth = 800;
|
||||
static int screenHeight = 450;
|
||||
|
||||
static int framesCounter;
|
||||
static bool gameOver;
|
||||
static bool pause;
|
||||
static int score;
|
||||
|
||||
static Player player;
|
||||
static Shoot shoot[PLAYER_MAX_SHOOTS];
|
||||
static Ball bigBalls[MAX_BIG_BALLS];
|
||||
static Ball mediumBalls[MAX_BIG_BALLS*2];
|
||||
static Ball smallBalls[MAX_BIG_BALLS*4];
|
||||
static Points points[5];
|
||||
|
||||
// NOTE: Defined triangle is isosceles with common angles of 70 degrees.
|
||||
static float shipHeight;
|
||||
static float gravity;
|
||||
|
||||
static int countmediumBallss;
|
||||
static int countsmallBallss;
|
||||
static int meteorsDestroyed;
|
||||
static Vector2 linePosition;
|
||||
|
||||
static bool victory;
|
||||
static bool lose;
|
||||
static bool awake;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module Functions Declaration (local)
|
||||
//------------------------------------------------------------------------------------
|
||||
static void InitGame(void); // Initialize game
|
||||
static void UpdateGame(void); // Update game (one frame)
|
||||
static void DrawGame(void); // Draw game (one frame)
|
||||
static void UnloadGame(void); // Unload game
|
||||
static void UpdateDrawFrame(void); // Update and Draw (one frame)
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main()
|
||||
{
|
||||
InitWindow(screenWidth, screenHeight, "sample game: pang");
|
||||
|
||||
InitGame();
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
emscripten_set_main_loop(UpdateDrawFrame, 0, 1);
|
||||
#else
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateGame();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
DrawGame();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
#endif
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadGame(); // Unload loaded data (textures, sounds, models...)
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module Functions Definitions (local)
|
||||
//------------------------------------------------------------------------------------
|
||||
|
||||
// Initialize game variables
|
||||
static void InitGame(void)
|
||||
{
|
||||
int posx, posy;
|
||||
int velx = 0;
|
||||
int vely = 0;
|
||||
|
||||
framesCounter = 0;
|
||||
gameOver = false;
|
||||
pause = false;
|
||||
score = 0;
|
||||
|
||||
victory = false;
|
||||
lose = false;
|
||||
awake = true;
|
||||
gravity = 0.25f;
|
||||
|
||||
linePosition = (Vector2){ 0.0f , 0.0f };
|
||||
shipHeight = (PLAYER_BASE_SIZE/2)/tanf(20*DEG2RAD);
|
||||
|
||||
// Initialization player
|
||||
player.position = (Vector2){ screenWidth/2, screenHeight };
|
||||
player.speed = (Vector2){ PLAYER_SPEED, PLAYER_SPEED };
|
||||
player.rotation = 0;
|
||||
player.collider = (Vector3){ player.position.x, player.position.y - shipHeight/2.0f, 12.0f };
|
||||
|
||||
meteorsDestroyed = 0;
|
||||
|
||||
// Initialize shoots
|
||||
for (int i = 0; i < PLAYER_MAX_SHOOTS; i++)
|
||||
{
|
||||
shoot[i].position = (Vector2){ 0, 0 };
|
||||
shoot[i].speed = (Vector2){ 0, 0 };
|
||||
shoot[i].radius = 2;
|
||||
shoot[i].active = false;
|
||||
shoot[i].lifeSpawn = 0;
|
||||
}
|
||||
|
||||
// Initialize big meteors
|
||||
for (int i = 0; i < MAX_BIG_BALLS; i++)
|
||||
{
|
||||
bigBalls[i].radius = 40.0f;
|
||||
posx = GetRandomValue(0 + bigBalls[i].radius, screenWidth - bigBalls[i].radius);
|
||||
posy = GetRandomValue(0 + bigBalls[i].radius, screenHeight/2);
|
||||
|
||||
bigBalls[i].position = (Vector2){ posx, posy };
|
||||
|
||||
while ((velx == 0) || (vely == 0))
|
||||
{
|
||||
velx = GetRandomValue(-BALLS_SPEED, BALLS_SPEED);
|
||||
vely = GetRandomValue(-BALLS_SPEED, BALLS_SPEED);
|
||||
}
|
||||
|
||||
bigBalls[i].speed = (Vector2){ velx, vely };
|
||||
bigBalls[i].points = 200;
|
||||
bigBalls[i].active = true;
|
||||
}
|
||||
|
||||
// Initialize medium meteors
|
||||
for (int i = 0; i < MAX_BIG_BALLS*2; i++)
|
||||
{
|
||||
mediumBalls[i].position = (Vector2){-100, -100};
|
||||
mediumBalls[i].speed = (Vector2){0,0};
|
||||
mediumBalls[i].radius = 20.0f;
|
||||
mediumBalls[i].points = 100;
|
||||
mediumBalls[i].active = false;
|
||||
}
|
||||
|
||||
// Initialize small meteors
|
||||
for (int i = 0; i < MAX_BIG_BALLS*4; i++)
|
||||
{
|
||||
smallBalls[i].position = (Vector2){ -100, -100 };
|
||||
smallBalls[i].speed = (Vector2){ 0, 0 };
|
||||
smallBalls[i].radius = 10.0f;
|
||||
smallBalls[i].points = 50;
|
||||
smallBalls[i].active = false;
|
||||
}
|
||||
|
||||
// Initialize animated points
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
points[i].position = (Vector2){ 0, 0 };
|
||||
points[i].value = 0;
|
||||
points[i].alpha = 0.0f;
|
||||
}
|
||||
|
||||
countmediumBallss = 0;
|
||||
countsmallBallss = 0;
|
||||
}
|
||||
|
||||
// Update game (one frame)
|
||||
void UpdateGame(void)
|
||||
{
|
||||
if (!gameOver && !victory)
|
||||
{
|
||||
if (IsKeyPressed('P')) pause = !pause;
|
||||
|
||||
if (!pause)
|
||||
{
|
||||
// Player logic
|
||||
if (IsKeyDown(KEY_LEFT)) player.position.x -= player.speed.x;
|
||||
if (IsKeyDown(KEY_RIGHT)) player.position.x += player.speed.x;
|
||||
|
||||
// Player vs wall collision logic
|
||||
if (player.position.x + PLAYER_BASE_SIZE/2 > screenWidth) player.position.x = screenWidth - PLAYER_BASE_SIZE/2;
|
||||
else if (player.position.x - PLAYER_BASE_SIZE/2 < 0) player.position.x = 0 + PLAYER_BASE_SIZE/2;
|
||||
|
||||
// Player shot logic
|
||||
if (IsKeyPressed(KEY_SPACE))
|
||||
{
|
||||
for (int i = 0; i < PLAYER_MAX_SHOOTS; i++)
|
||||
{
|
||||
if (!shoot[i].active)
|
||||
{
|
||||
shoot[i].position = (Vector2){ player.position.x, player.position.y - shipHeight };
|
||||
shoot[i].speed.y = PLAYER_SPEED;
|
||||
shoot[i].active = true;
|
||||
|
||||
linePosition = (Vector2){ player.position.x, player.position.y};
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Shoot life timer
|
||||
for (int i = 0; i < PLAYER_MAX_SHOOTS; i++)
|
||||
{
|
||||
if (shoot[i].active) shoot[i].lifeSpawn++;
|
||||
}
|
||||
|
||||
// Shot logic
|
||||
for (int i = 0; i < PLAYER_MAX_SHOOTS; i++)
|
||||
{
|
||||
if (shoot[i].active)
|
||||
{
|
||||
shoot[i].position.y -= shoot[i].speed.y;
|
||||
|
||||
// Shot vs walls collision logic
|
||||
if ((shoot[i].position.x > screenWidth + shoot[i].radius) || (shoot[i].position.x < 0 - shoot[i].radius) ||
|
||||
(shoot[i].position.y > screenHeight + shoot[i].radius) || (shoot[i].position.y < 0 - shoot[i].radius))
|
||||
{
|
||||
shoot[i].active = false;
|
||||
shoot[i].lifeSpawn = 0;
|
||||
}
|
||||
|
||||
// Player shot life spawn
|
||||
if (shoot[i].lifeSpawn >= 120)
|
||||
{
|
||||
shoot[i].position = (Vector2){ 0.0f, 0.0f };
|
||||
shoot[i].speed = (Vector2){ 0.0f, 0.0f };
|
||||
shoot[i].lifeSpawn = 0;
|
||||
shoot[i].active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Player vs meteors collision logic
|
||||
player.collider = (Vector3){player.position.x, player.position.y - shipHeight/2, 12};
|
||||
|
||||
for (int i = 0; i < MAX_BIG_BALLS; i++)
|
||||
{
|
||||
if (CheckCollisionCircles((Vector2){ player.collider.x, player.collider.y }, player.collider.z, bigBalls[i].position, bigBalls[i].radius) && bigBalls[i].active)
|
||||
{
|
||||
gameOver = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_BIG_BALLS*2; i++)
|
||||
{
|
||||
if (CheckCollisionCircles((Vector2){ player.collider.x, player.collider.y }, player.collider.z, mediumBalls[i].position, mediumBalls[i].radius) && mediumBalls[i].active)
|
||||
{
|
||||
gameOver = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_BIG_BALLS*4; i++)
|
||||
{
|
||||
if (CheckCollisionCircles((Vector2){ player.collider.x, player.collider.y }, player.collider.z, smallBalls[i].position, smallBalls[i].radius) && smallBalls[i].active)
|
||||
{
|
||||
gameOver = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Meteors logic (big)
|
||||
for (int i = 0; i < MAX_BIG_BALLS; i++)
|
||||
{
|
||||
if (bigBalls[i].active)
|
||||
{
|
||||
// Meteor movement logic
|
||||
bigBalls[i].position.x += bigBalls[i].speed.x;
|
||||
bigBalls[i].position.y += bigBalls[i].speed.y;
|
||||
|
||||
// Meteor vs wall collision logic
|
||||
if (((bigBalls[i].position.x + bigBalls[i].radius) >= screenWidth) || ((bigBalls[i].position.x - bigBalls[i].radius) <= 0)) bigBalls[i].speed.x *= -1;
|
||||
if ((bigBalls[i].position.y - bigBalls[i].radius) <= 0) bigBalls[i].speed.y *= -1.5;
|
||||
|
||||
if ((bigBalls[i].position.y + bigBalls[i].radius) >= screenHeight)
|
||||
{
|
||||
bigBalls[i].speed.y *= -1;
|
||||
bigBalls[i].position.y = screenHeight - bigBalls[i].radius;
|
||||
}
|
||||
|
||||
bigBalls[i].speed.y += gravity;
|
||||
}
|
||||
}
|
||||
|
||||
// Meteors logic (medium)
|
||||
for (int i = 0; i < MAX_BIG_BALLS*2; i++)
|
||||
{
|
||||
if (mediumBalls[i].active)
|
||||
{
|
||||
// Meteor movement logic
|
||||
mediumBalls[i].position.x += mediumBalls[i].speed.x;
|
||||
mediumBalls[i].position.y += mediumBalls[i].speed.y;
|
||||
|
||||
// Meteor vs wall collision logic
|
||||
if (mediumBalls[i].position.x + mediumBalls[i].radius >= screenWidth || mediumBalls[i].position.x - mediumBalls[i].radius <= 0) mediumBalls[i].speed.x *= -1;
|
||||
if (mediumBalls[i].position.y - mediumBalls[i].radius <= 0) mediumBalls[i].speed.y *= -1;
|
||||
if (mediumBalls[i].position.y + mediumBalls[i].radius >= screenHeight)
|
||||
{
|
||||
mediumBalls[i].speed.y *= -1;
|
||||
mediumBalls[i].position.y = screenHeight - mediumBalls[i].radius;
|
||||
}
|
||||
|
||||
mediumBalls[i].speed.y += gravity + 0.12f;
|
||||
}
|
||||
}
|
||||
|
||||
// Meteors logic (small)
|
||||
for (int i = 0; i < MAX_BIG_BALLS*4; i++)
|
||||
{
|
||||
if (smallBalls[i].active)
|
||||
{
|
||||
// Meteor movement logic
|
||||
smallBalls[i].position.x += smallBalls[i].speed.x;
|
||||
smallBalls[i].position.y += smallBalls[i].speed.y;
|
||||
|
||||
// Meteor vs wall collision logic
|
||||
if (smallBalls[i].position.x + smallBalls[i].radius >= screenWidth || smallBalls[i].position.x - smallBalls[i].radius <= 0) smallBalls[i].speed.x *= -1;
|
||||
if (smallBalls[i].position.y - smallBalls[i].radius <= 0) smallBalls[i].speed.y *= -1;
|
||||
if (smallBalls[i].position.y + smallBalls[i].radius >= screenHeight)
|
||||
{
|
||||
smallBalls[i].speed.y *= -1;
|
||||
smallBalls[i].position.y = screenHeight - smallBalls[i].radius;
|
||||
}
|
||||
|
||||
smallBalls[i].speed.y += gravity + 0.25f;
|
||||
}
|
||||
}
|
||||
|
||||
// Player-shot vs meteors logic
|
||||
for (int i = 0; i < PLAYER_MAX_SHOOTS; i++)
|
||||
{
|
||||
if ((shoot[i].active))
|
||||
{
|
||||
for (int a = 0; a < MAX_BIG_BALLS; a++)
|
||||
{
|
||||
if (bigBalls[a].active && (bigBalls[a].position.x - bigBalls[a].radius <= linePosition.x && bigBalls[a].position.x + bigBalls[a].radius >= linePosition.x)
|
||||
&& (bigBalls[a].position.y + bigBalls[a].radius >= shoot[i].position.y))
|
||||
{
|
||||
shoot[i].active = false;
|
||||
shoot[i].lifeSpawn = 0;
|
||||
bigBalls[a].active = false;
|
||||
meteorsDestroyed++;
|
||||
score += bigBalls[a].points;
|
||||
|
||||
for (int z = 0; z < 5; z++)
|
||||
{
|
||||
if (points[z].alpha == 0.0f)
|
||||
{
|
||||
points[z].position = bigBalls[a].position;
|
||||
points[z].value = bigBalls[a].points;
|
||||
points[z].alpha = 1.0f;
|
||||
z = 5;
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j < 2; j ++)
|
||||
{
|
||||
if ((countmediumBallss%2) == 0)
|
||||
{
|
||||
mediumBalls[countmediumBallss].position = (Vector2){bigBalls[a].position.x, bigBalls[a].position.y};
|
||||
mediumBalls[countmediumBallss].speed = (Vector2){ -1*BALLS_SPEED, BALLS_SPEED };
|
||||
}
|
||||
else
|
||||
{
|
||||
mediumBalls[countmediumBallss].position = (Vector2){bigBalls[a].position.x, bigBalls[a].position.y};
|
||||
mediumBalls[countmediumBallss].speed = (Vector2){ BALLS_SPEED, BALLS_SPEED };
|
||||
}
|
||||
|
||||
mediumBalls[countmediumBallss].active = true;
|
||||
countmediumBallss ++;
|
||||
}
|
||||
|
||||
a = MAX_BIG_BALLS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((shoot[i].active))
|
||||
{
|
||||
for (int b = 0; b < MAX_BIG_BALLS*2; b++)
|
||||
{
|
||||
if (mediumBalls[b].active && (mediumBalls[b].position.x - mediumBalls[b].radius <= linePosition.x && mediumBalls[b].position.x + mediumBalls[b].radius >= linePosition.x)
|
||||
&& (mediumBalls[b].position.y + mediumBalls[b].radius >= shoot[i].position.y))
|
||||
{
|
||||
shoot[i].active = false;
|
||||
shoot[i].lifeSpawn = 0;
|
||||
mediumBalls[b].active = false;
|
||||
meteorsDestroyed++;
|
||||
score += mediumBalls[b].points;
|
||||
|
||||
for (int z = 0; z < 5; z++)
|
||||
{
|
||||
if (points[z].alpha == 0.0f)
|
||||
{
|
||||
points[z].position = mediumBalls[b].position;
|
||||
points[z].value = mediumBalls[b].points;
|
||||
points[z].alpha = 1.0f;
|
||||
z = 5;
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j < 2; j ++)
|
||||
{
|
||||
if (countsmallBallss%2 == 0)
|
||||
{
|
||||
smallBalls[countsmallBallss].position = (Vector2){mediumBalls[b].position.x, mediumBalls[b].position.y};
|
||||
smallBalls[countsmallBallss].speed = (Vector2){ BALLS_SPEED*-1, BALLS_SPEED*-1};
|
||||
}
|
||||
else
|
||||
{
|
||||
smallBalls[countsmallBallss].position = (Vector2){mediumBalls[b].position.x, mediumBalls[b].position.y};
|
||||
smallBalls[countsmallBallss].speed = (Vector2){ BALLS_SPEED, BALLS_SPEED*-1};
|
||||
}
|
||||
|
||||
smallBalls[countsmallBallss].active = true;
|
||||
countsmallBallss ++;
|
||||
}
|
||||
|
||||
b = MAX_BIG_BALLS*2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((shoot[i].active))
|
||||
{
|
||||
for (int c = 0; c < MAX_BIG_BALLS*4; c++)
|
||||
{
|
||||
if (smallBalls[c].active && (smallBalls[c].position.x - smallBalls[c].radius <= linePosition.x && smallBalls[c].position.x + smallBalls[c].radius >= linePosition.x)
|
||||
&& (smallBalls[c].position.y + smallBalls[c].radius >= shoot[i].position.y))
|
||||
{
|
||||
shoot[i].active = false;
|
||||
shoot[i].lifeSpawn = 0;
|
||||
smallBalls[c].active = false;
|
||||
meteorsDestroyed++;
|
||||
score += smallBalls[c].points;
|
||||
|
||||
for (int z = 0; z < 5; z++)
|
||||
{
|
||||
if (points[z].alpha == 0.0f)
|
||||
{
|
||||
points[z].position = smallBalls[c].position;
|
||||
points[z].value = smallBalls[c].points;
|
||||
points[z].alpha = 1.0f;
|
||||
z = 5;
|
||||
}
|
||||
}
|
||||
|
||||
c = MAX_BIG_BALLS*4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (meteorsDestroyed == (MAX_BIG_BALLS + MAX_BIG_BALLS*2 + MAX_BIG_BALLS*4)) victory = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsKeyPressed(KEY_ENTER))
|
||||
{
|
||||
InitGame();
|
||||
gameOver = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Points move-up and fade logic
|
||||
for (int z = 0; z < 5; z++)
|
||||
{
|
||||
if (points[z].alpha > 0.0f)
|
||||
{
|
||||
points[z].position.y -= 2;
|
||||
points[z].alpha -= 0.02f;
|
||||
}
|
||||
|
||||
if (points[z].alpha < 0.0f) points[z].alpha = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw game (one frame)
|
||||
void DrawGame(void)
|
||||
{
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
if (!gameOver)
|
||||
{
|
||||
// Draw player
|
||||
Vector2 v1 = { player.position.x + sinf(player.rotation*DEG2RAD)*(shipHeight), player.position.y - cosf(player.rotation*DEG2RAD)*(shipHeight) };
|
||||
Vector2 v2 = { player.position.x - cosf(player.rotation*DEG2RAD)*(PLAYER_BASE_SIZE/2), player.position.y - sinf(player.rotation*DEG2RAD)*(PLAYER_BASE_SIZE/2) };
|
||||
Vector2 v3 = { player.position.x + cosf(player.rotation*DEG2RAD)*(PLAYER_BASE_SIZE/2), player.position.y + sinf(player.rotation*DEG2RAD)*(PLAYER_BASE_SIZE/2) };
|
||||
DrawTriangle(v1, v2, v3, MAROON);
|
||||
|
||||
// Draw meteors (big)
|
||||
for (int i = 0;i < MAX_BIG_BALLS; i++)
|
||||
{
|
||||
if (bigBalls[i].active) DrawCircleV(bigBalls[i].position, bigBalls[i].radius, DARKGRAY);
|
||||
else DrawCircleV(bigBalls[i].position, bigBalls[i].radius, Fade(LIGHTGRAY, 0.3f));
|
||||
}
|
||||
|
||||
// Draw meteors (medium)
|
||||
for (int i = 0;i < MAX_BIG_BALLS*2; i++)
|
||||
{
|
||||
if (mediumBalls[i].active) DrawCircleV(mediumBalls[i].position, mediumBalls[i].radius, GRAY);
|
||||
else DrawCircleV(mediumBalls[i].position, mediumBalls[i].radius, Fade(LIGHTGRAY, 0.3f));
|
||||
}
|
||||
|
||||
// Draw meteors (small)
|
||||
for (int i = 0;i < MAX_BIG_BALLS*4; i++)
|
||||
{
|
||||
if (smallBalls[i].active) DrawCircleV(smallBalls[i].position, smallBalls[i].radius, GRAY);
|
||||
else DrawCircleV(smallBalls[i].position, smallBalls[i].radius, Fade(LIGHTGRAY, 0.3f));
|
||||
}
|
||||
|
||||
// Draw shoot
|
||||
for (int i = 0; i < PLAYER_MAX_SHOOTS; i++)
|
||||
{
|
||||
if (shoot[i].active) DrawLine(linePosition.x, linePosition.y, shoot[i].position.x, shoot[i].position.y, RED);
|
||||
}
|
||||
|
||||
// Draw score points
|
||||
for (int z = 0; z < 5; z++)
|
||||
{
|
||||
if (points[z].alpha > 0.0f)
|
||||
{
|
||||
DrawText(FormatText("+%02i", points[z].value), points[z].position.x, points[z].position.y, 20, Fade(BLUE, points[z].alpha));
|
||||
}
|
||||
}
|
||||
|
||||
// Draw score (UI)
|
||||
DrawText(FormatText("SCORE: %i", score), 10, 10, 20, LIGHTGRAY);
|
||||
|
||||
if (victory)
|
||||
{
|
||||
DrawText("YOU WIN!", screenWidth/2 - MeasureText("YOU WIN!", 60)/2, 100, 60, LIGHTGRAY);
|
||||
DrawText("PRESS [ENTER] TO PLAY AGAIN", GetScreenWidth()/2 - MeasureText("PRESS [ENTER] TO PLAY AGAIN", 20)/2, GetScreenHeight()/2 - 50, 20, LIGHTGRAY);
|
||||
}
|
||||
|
||||
if (pause) DrawText("GAME PAUSED", screenWidth/2 - MeasureText("GAME PAUSED", 40)/2, screenHeight/2 - 40, 40, LIGHTGRAY);
|
||||
}
|
||||
else DrawText("PRESS [ENTER] TO PLAY AGAIN", GetScreenWidth()/2 - MeasureText("PRESS [ENTER] TO PLAY AGAIN", 20)/2, GetScreenHeight()/2 - 50, 20, LIGHTGRAY);
|
||||
|
||||
EndDrawing();
|
||||
}
|
||||
|
||||
// Unload game variables
|
||||
void UnloadGame(void)
|
||||
{
|
||||
// TODO: Unload all dynamic loaded data (textures, sounds, models...)
|
||||
}
|
||||
|
||||
// Update and Draw (one frame)
|
||||
void UpdateDrawFrame(void)
|
||||
{
|
||||
UpdateGame();
|
||||
DrawGame();
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
#
|
||||
# raylib - Basic Game
|
||||
#
|
||||
# makefile to compile basic game
|
||||
# makefile to compile advance game for desktop platforms, Raspberry Pi and HTML5 (emscripten)
|
||||
#
|
||||
# Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
#
|
||||
|
@ -23,31 +23,57 @@
|
|||
#
|
||||
#**************************************************************************************************
|
||||
|
||||
# define raylib platform (by default, compile for RPI)
|
||||
# Other possible platform: PLATFORM_DESKTOP, PLATFORM_WEB, PLATFORM_RPI
|
||||
PLATFORM ?= PLATFORM_WEB
|
||||
# define raylib platform to compile for
|
||||
# possible platforms: PLATFORM_DESKTOP PLATFORM_RPI PLATFORM_WEB
|
||||
# WARNING: To compile to HTML5, code must be redesigned to use emscripten.h and emscripten_set_main_loop()
|
||||
PLATFORM ?= PLATFORM_DESKTOP
|
||||
|
||||
# determine PLATFORM_OS in case PLATFORM_DESKTOP selected
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
# No uname.exe on MinGW!, but OS=Windows_NT on Windows! ifeq ($(UNAME),Msys) -> Windows
|
||||
ifeq ($(OS),Windows_NT)
|
||||
PLATFORM_OS=WINDOWS
|
||||
LIBPATH=win32
|
||||
else
|
||||
UNAMEOS:=$(shell uname)
|
||||
ifeq ($(UNAMEOS),Linux)
|
||||
PLATFORM_OS=LINUX
|
||||
LIBPATH=linux
|
||||
else
|
||||
ifeq ($(UNAMEOS),Darwin)
|
||||
PLATFORM_OS=OSX
|
||||
LIBPATH=osx
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# define compiler: gcc for C program, define as g++ for C++
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
# define emscripten compiler
|
||||
CC = emcc
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
# define llvm compiler for mac
|
||||
CC = clang
|
||||
else
|
||||
# define default gcc compiler
|
||||
CC = gcc
|
||||
endif
|
||||
endif
|
||||
|
||||
# define compiler flags:
|
||||
# -O2 defines optimization level
|
||||
# -Wall turns on most, but not all, compiler warnings
|
||||
# -std=c99 use standard C from 1999 revision
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
CFLAGS = -O1 -Wall -std=gnu99 -fgnu89-inline
|
||||
CFLAGS = -O2 -Wall -std=gnu99 -fgnu89-inline
|
||||
else
|
||||
CFLAGS = -O1 -Wall -std=c99
|
||||
CFLAGS = -O2 -Wall -std=c99
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
CFLAGS = -O1 -Wall -std=c99 -s USE_GLFW=3 -s ASSERTIONS=1 --preload-file resources
|
||||
CFLAGS = -O1 -Wall -std=c99 -s USE_GLFW=3 --preload-file resources --shell-file ../../templates/web_shell/shell.html
|
||||
#-s ASSERTIONS=1 # to check for memory allocation errors (-O1 disables it)
|
||||
#-s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing
|
||||
#-s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB)
|
||||
endif
|
||||
|
@ -59,33 +85,66 @@ ifeq ($(PLATFORM),PLATFORM_RPI)
|
|||
INCLUDES = -I. -I../../src -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads
|
||||
else
|
||||
INCLUDES = -I. -I../../src
|
||||
# external libraries headers
|
||||
# GLFW3
|
||||
INCLUDES += -I../../external/glfw3/include
|
||||
# GLEW - Not required any more, replaced by GLAD
|
||||
#INCLUDES += -I../external/glew/include
|
||||
# OpenAL Soft
|
||||
INCLUDES += -I../../external/openal_soft/include
|
||||
endif
|
||||
|
||||
# define library paths containing required libs
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
LFLAGS = -L.
|
||||
else
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
LFLAGS = -L. -L../../src -L/opt/vc/lib
|
||||
else
|
||||
LFLAGS = -L. -L../../src -LC:/raylib/raylib/src
|
||||
# external libraries to link with
|
||||
# GLFW3
|
||||
LFLAGS += -L../../external/glfw3/lib/$(LIBPATH)
|
||||
ifneq ($(PLATFORM_OS),OSX)
|
||||
# OpenAL Soft
|
||||
LFLAGS += -L../../external/openal_soft/lib/$(LIBPATH)
|
||||
# GLEW: Not used, replaced by GLAD
|
||||
#LFLAGS += -L../../external/glew/lib/$(LIBPATH)
|
||||
endif
|
||||
endif
|
||||
|
||||
# define any libraries to link into executable
|
||||
# if you want to link libraries (libname.so or libname.a), use the -lname
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
# libraries for Debian GNU/Linux desktop compiling
|
||||
# requires the following packages:
|
||||
# libglfw3-dev libopenal-dev libglew-dev libegl1-mesa-dev
|
||||
LIBS = -lraylib -lglfw3 -lGLEW -lGL -lopenal -lm -pthread
|
||||
# on XWindow could require also below libraries, just uncomment
|
||||
#LIBS += -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
# libraries for OS X 10.9 desktop compiling
|
||||
# requires the following packages:
|
||||
# libglfw3-dev libopenal-dev libglew-dev libegl1-mesa-dev
|
||||
LIBS = -lraylib -lglfw -framework OpenGL -framework OpenAl -framework Cocoa
|
||||
else
|
||||
# libraries for Windows desktop compiling
|
||||
# NOTE: GLFW3 and OpenAL Soft libraries should be installed
|
||||
LIBS = -lraylib -lglfw3 -lopengl32 -lopenal32 -lgdi32
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
# libraries for Raspberry Pi compiling
|
||||
# NOTE: OpenAL Soft library should be installed (libopenal1 package)
|
||||
LIBS = -lraylib -lGLESv2 -lEGL -lpthread -lrt -lm -lbcm_host -lopenal
|
||||
else
|
||||
# libraries for Windows desktop compiling
|
||||
# NOTE: GLFW3 and OpenAL Soft libraries should be installed
|
||||
LIBS = -lraylib -lglfw3 -lglew32 -lopengl32 -lopenal32 -lgdi32
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
# NOTE: Set the correct path to libraylib.bc
|
||||
LIBS = ../../src/libraylib.bc
|
||||
endif
|
||||
|
||||
# define additional parameters and flags for windows
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||
# resources file contains windows exe icon
|
||||
# -Wl,--subsystem,windows hides the console window
|
||||
WINFLAGS = ../../src/resources -Wl,--subsystem,windows
|
||||
|
@ -99,21 +158,30 @@ endif
|
|||
# in this case, the 'default' target entry is qidv_raylib
|
||||
default: raylib_demo
|
||||
|
||||
# compile qidv_raylib
|
||||
# compile raylib demo
|
||||
raylib_demo: raylib_demo.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# clean everything
|
||||
clean:
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
rm -f *.o
|
||||
# find . -executable -delete
|
||||
else
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
del *.html *.js
|
||||
else
|
||||
del *.o *.exe
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
find . -type f -perm +ugo+x -delete
|
||||
rm -f *.o
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
find -type f -executable | xargs file -i | grep -E 'x-object|x-archive|x-sharedlib|x-executable' | rev | cut -d ':' -f 2- | rev | xargs rm -f
|
||||
else
|
||||
del *.o *.exe
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
find . -type f -executable -delete
|
||||
rm -f *.o
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
del *.o *.html *.js
|
||||
endif
|
||||
@echo Cleaning done
|
||||
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib - Talk: QIDV raylib (Learn Videogames Programming)
|
||||
* raylib - Features demo 01 (Learn Videogames Programming)
|
||||
*
|
||||
* Aprende a Programar Videojuegos con raylib
|
||||
*
|
||||
* This talk has been created using raylib v1.2 (www.raylib.com)
|
||||
* This show has been created using raylib v1.4 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
|
@ -703,11 +701,11 @@ void UpdateDrawOneFrame(void)
|
|||
{
|
||||
DrawText("This module give you functions to:", 48, 200, 10, GetColor(0x5c5a5aff));
|
||||
|
||||
DrawTextEx(fontRomulus, "Open-Close Window", (Vector2){ 48, 230 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0x5c5a5aff));
|
||||
DrawTextEx(fontRomulus, "Manage Drawing Area", (Vector2){ 48, 260 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0x5c5a5aff));
|
||||
DrawTextEx(fontRomulus, "Manage Inputs", (Vector2){ 48, 290 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0x5c5a5aff));
|
||||
DrawTextEx(fontRomulus, "Manage Timming", (Vector2){ 48, 320 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0x5c5a5aff));
|
||||
DrawTextEx(fontRomulus, "Auxiliar Functions", (Vector2){ 48, 350 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0x5c5a5aff));
|
||||
DrawTextEx(fontRomulus, "Open-Close Window", (Vector2){ 48, 230 }, fontRomulus.size*2, 4, GetColor(0x5c5a5aff));
|
||||
DrawTextEx(fontRomulus, "Manage Drawing Area", (Vector2){ 48, 260 }, fontRomulus.size*2, 4, GetColor(0x5c5a5aff));
|
||||
DrawTextEx(fontRomulus, "Manage Inputs", (Vector2){ 48, 290 }, fontRomulus.size*2, 4, GetColor(0x5c5a5aff));
|
||||
DrawTextEx(fontRomulus, "Manage Timming", (Vector2){ 48, 320 }, fontRomulus.size*2, 4, GetColor(0x5c5a5aff));
|
||||
DrawTextEx(fontRomulus, "Auxiliar Functions", (Vector2){ 48, 350 }, fontRomulus.size*2, 4, GetColor(0x5c5a5aff));
|
||||
|
||||
switch (coreWindow)
|
||||
{
|
||||
|
@ -733,16 +731,16 @@ void UpdateDrawOneFrame(void)
|
|||
|
||||
if (framesCounter > 140)
|
||||
{
|
||||
DrawTextEx(fontMecha, "MOVE ME", (Vector2){ ballPosition.x - 26, ballPosition.y - 20 }, GetFontBaseSize(fontMecha), 2, BLACK);
|
||||
DrawTextEx(fontMecha, "[ W A S D ]", (Vector2){ ballPosition.x - 36, ballPosition.y }, GetFontBaseSize(fontMecha), 2, BLACK);
|
||||
DrawTextEx(fontMecha, "MOVE ME", (Vector2){ ballPosition.x - 26, ballPosition.y - 20 }, fontMecha.size, 2, BLACK);
|
||||
DrawTextEx(fontMecha, "[ W A S D ]", (Vector2){ ballPosition.x - 36, ballPosition.y }, fontMecha.size, 2, BLACK);
|
||||
}
|
||||
} break;
|
||||
case SHAPES:
|
||||
{
|
||||
DrawText("This module give you functions to:", 48, 200, 10, GetColor(0xcd5757ff));
|
||||
|
||||
DrawTextEx(fontRomulus, "Draw Basic Shapes", (Vector2){ 48, 230 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0xcd5757ff));
|
||||
DrawTextEx(fontRomulus, "Basic Collision Detection", (Vector2){ 48, 260 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0xcd5757ff));
|
||||
DrawTextEx(fontRomulus, "Draw Basic Shapes", (Vector2){ 48, 230 }, fontRomulus.size*2, 4, GetColor(0xcd5757ff));
|
||||
DrawTextEx(fontRomulus, "Basic Collision Detection", (Vector2){ 48, 260 }, fontRomulus.size*2, 4, GetColor(0xcd5757ff));
|
||||
|
||||
DrawCircle(screenWidth/4, 120 + 240, 35, DARKBLUE);
|
||||
DrawCircleGradient(screenWidth/4, 220 + 240, 60, GREEN, SKYBLUE);
|
||||
|
@ -763,8 +761,8 @@ void UpdateDrawOneFrame(void)
|
|||
{
|
||||
DrawText("This module give you functions to:", 48, 200, 10, GetColor(0x60815aff));
|
||||
|
||||
DrawTextEx(fontRomulus, "Load Images and Textures", (Vector2){ 48, 230 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0x60815aff));
|
||||
DrawTextEx(fontRomulus, "Draw Textures", (Vector2){ 48, 260 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0x60815aff));
|
||||
DrawTextEx(fontRomulus, "Load Images and Textures", (Vector2){ 48, 230 }, fontRomulus.size*2, 4, GetColor(0x60815aff));
|
||||
DrawTextEx(fontRomulus, "Draw Textures", (Vector2){ 48, 260 }, fontRomulus.size*2, 4, GetColor(0x60815aff));
|
||||
|
||||
DrawRectangle(138, 348, 260, 260, GRAY);
|
||||
DrawTexturePro(lena, (Rectangle){ 0, 0, lena.width, lena.height }, (Rectangle){ 140 + 128, 350 + 128, lena.width/2*scaleFactor, lena.height/2*scaleFactor }, (Vector2){ lena.width/4*scaleFactor, lena.height/4*scaleFactor }, 0.0f, WHITE);
|
||||
|
@ -780,21 +778,21 @@ void UpdateDrawOneFrame(void)
|
|||
{
|
||||
DrawText("This module give you functions to:", 48, 200, 10, GetColor(0x377764ff));
|
||||
|
||||
DrawTextEx(fontRomulus, "Load SpriteFonts", (Vector2){ 48, 230 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0x377764ff));
|
||||
DrawTextEx(fontRomulus, "Draw Text", (Vector2){ 48, 260 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0x377764ff));
|
||||
DrawTextEx(fontRomulus, "Text Formatting", (Vector2){ 48, 290 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0x377764ff));
|
||||
DrawTextEx(fontRomulus, "Load SpriteFonts", (Vector2){ 48, 230 }, fontRomulus.size*2, 4, GetColor(0x377764ff));
|
||||
DrawTextEx(fontRomulus, "Draw Text", (Vector2){ 48, 260 }, fontRomulus.size*2, 4, GetColor(0x377764ff));
|
||||
DrawTextEx(fontRomulus, "Text Formatting", (Vector2){ 48, 290 }, fontRomulus.size*2, 4, GetColor(0x377764ff));
|
||||
|
||||
DrawTexture(texAlagard, 60, 360, WHITE);
|
||||
|
||||
DrawTextEx(fontMechaC, msg1, (Vector2){ 540 + 168, 210 }, GetFontBaseSize(fontMechaC), -3, WHITE);
|
||||
DrawTextEx(fontAlagardC, msg2, (Vector2){ 460 + 140, 260 }, GetFontBaseSize(fontAlagardC), -2, WHITE);
|
||||
DrawTextEx(fontJupiterC, msg3, (Vector2){ 640 + 70, 300 }, GetFontBaseSize(fontJupiterC), 2, WHITE);
|
||||
DrawTextEx(fontMechaC, msg1, (Vector2){ 540 + 168, 210 }, fontMechaC.size, -3, WHITE);
|
||||
DrawTextEx(fontAlagardC, msg2, (Vector2){ 460 + 140, 260 }, fontAlagardC.size, -2, WHITE);
|
||||
DrawTextEx(fontJupiterC, msg3, (Vector2){ 640 + 70, 300 }, fontJupiterC.size, 2, WHITE);
|
||||
|
||||
DrawTextEx(fontAlagard, "It also includes some...", (Vector2){ 650 + 70, 400 }, GetFontBaseSize(fontAlagard)*2, 2, MAROON);
|
||||
DrawTextEx(fontPixelplay, "...free fonts in rBMF format...", (Vector2){ 705 - 26, 450 }, GetFontBaseSize(fontPixelplay)*2, 4, ORANGE);
|
||||
DrawTextEx(fontMecha, "...to be used even in...", (Vector2){ 700 + 40, 500 }, GetFontBaseSize(fontMecha)*2, 4, DARKGREEN);
|
||||
DrawTextEx(fontSetback, "...comercial projects...", (Vector2){ 710, 550 }, GetFontBaseSize(fontSetback)*2, 4, DARKBLUE);
|
||||
DrawTextEx(fontRomulus, "...completely for free!", (Vector2){ 710 + 17, 600 }, GetFontBaseSize(fontRomulus)*2, 3, DARKPURPLE);
|
||||
DrawTextEx(fontAlagard, "It also includes some...", (Vector2){ 650 + 70, 400 }, fontAlagard.size*2, 2, MAROON);
|
||||
DrawTextEx(fontPixelplay, "...free fonts in rBMF format...", (Vector2){ 705 - 26, 450 }, fontPixelplay.size*2, 4, ORANGE);
|
||||
DrawTextEx(fontMecha, "...to be used even in...", (Vector2){ 700 + 40, 500 }, fontMecha.size*2, 4, DARKGREEN);
|
||||
DrawTextEx(fontSetback, "...comercial projects...", (Vector2){ 710, 550 }, fontSetback.size*2, 4, DARKBLUE);
|
||||
DrawTextEx(fontRomulus, "...completely for free!", (Vector2){ 710 + 17, 600 }, fontRomulus.size*2, 3, DARKPURPLE);
|
||||
|
||||
DrawText("This is a custom font spritesheet, raylib can load it automatically!", 228, 360 + 295, 10, GRAY);
|
||||
|
||||
|
@ -803,9 +801,9 @@ void UpdateDrawOneFrame(void)
|
|||
{
|
||||
DrawText("This module give you functions to:", 48, 200, 10, GetColor(0x417794ff));
|
||||
|
||||
DrawTextEx(fontRomulus, "Draw Geometric Models", (Vector2){ 48, 230 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0x417794ff));
|
||||
DrawTextEx(fontRomulus, "Load 3D Models", (Vector2){ 48, 260 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0x417794ff));
|
||||
DrawTextEx(fontRomulus, "Draw 3D Models", (Vector2){ 48, 290 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0x417794ff));
|
||||
DrawTextEx(fontRomulus, "Draw Geometric Models", (Vector2){ 48, 230 }, fontRomulus.size*2, 4, GetColor(0x417794ff));
|
||||
DrawTextEx(fontRomulus, "Load 3D Models", (Vector2){ 48, 260 }, fontRomulus.size*2, 4, GetColor(0x417794ff));
|
||||
DrawTextEx(fontRomulus, "Draw 3D Models", (Vector2){ 48, 290 }, fontRomulus.size*2, 4, GetColor(0x417794ff));
|
||||
|
||||
Begin3dMode(camera);
|
||||
|
||||
|
@ -823,7 +821,7 @@ void UpdateDrawOneFrame(void)
|
|||
DrawCylinder((Vector3){1, 0, -4}, 0, 1.5, 3, 8, GOLD);
|
||||
DrawCylinderWires((Vector3){1, 0, -4}, 0, 1.5, 3, 8, PINK);
|
||||
|
||||
DrawModelEx(cat, (Vector3){ 8.0f, 0.0f, 2.0f }, (Vector3){ 0.0f, 0.5f*framesCounter, 0.0f }, (Vector3){ 0.1f, 0.1f, 0.1f }, WHITE);
|
||||
DrawModelEx(cat, (Vector3){ 8.0f, 0.0f, 2.0f }, (Vector3){ 0.0f, 1.0f, 0.0f }, 0.5f*framesCounter, (Vector3){ 0.1f, 0.1f, 0.1f }, WHITE);
|
||||
DrawGizmo((Vector3){ 8.0f, 0.0f, 2.0f });
|
||||
|
||||
DrawGrid(10.0, 1.0); // Draw a grid
|
||||
|
@ -837,8 +835,8 @@ void UpdateDrawOneFrame(void)
|
|||
{
|
||||
DrawText("This module give you functions to:", 48, 200, 10, GetColor(0x8c7539ff));
|
||||
|
||||
DrawTextEx(fontRomulus, "Load and Play Sounds", (Vector2){ 48, 230 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0x8c7539ff));
|
||||
DrawTextEx(fontRomulus, "Play Music (streaming)", (Vector2){ 48, 260 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0x8c7539ff));
|
||||
DrawTextEx(fontRomulus, "Load and Play Sounds", (Vector2){ 48, 230 }, fontRomulus.size*2, 4, GetColor(0x8c7539ff));
|
||||
DrawTextEx(fontRomulus, "Play Music (streaming)", (Vector2){ 48, 260 }, fontRomulus.size*2, 4, GetColor(0x8c7539ff));
|
||||
|
||||
DrawText("PRESS SPACE to START PLAYING MUSIC", 135, 350, 20, GRAY);
|
||||
DrawRectangle(150, 390, 400, 12, LIGHTGRAY);
|
||||
|
@ -891,7 +889,7 @@ void UpdateDrawOneFrame(void)
|
|||
case ENDING:
|
||||
{
|
||||
// Draw ENDING screen
|
||||
DrawTextEx(fontAlagard, "LEARN VIDEOGAMES PROGRAMMING", (Vector2){ screenWidth/2 - MeasureTextEx(fontAlagard, "LEARN VIDEOGAMES PROGRAMMING", GetFontBaseSize(fontAlagard)*4, 4).x/2, 80 }, GetFontBaseSize(fontAlagard)*4, 4, MAROON);
|
||||
DrawTextEx(fontAlagard, "LEARN VIDEOGAMES PROGRAMMING", (Vector2){ screenWidth/2 - MeasureTextEx(fontAlagard, "LEARN VIDEOGAMES PROGRAMMING", fontAlagard.size*4, 4).x/2, 80 }, fontAlagard.size*4, 4, MAROON);
|
||||
|
||||
DrawTexture(raylibLogoA, logoPositionX, logoPositionY - 40, WHITE);
|
||||
|
||||
|
|
254
games/skully_escape/makefile
Normal file
|
@ -0,0 +1,254 @@
|
|||
#**************************************************************************************************
|
||||
#
|
||||
# raylib - Advance Game
|
||||
#
|
||||
# makefile to compile advance game
|
||||
#
|
||||
# Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#**************************************************************************************************
|
||||
|
||||
# define raylib platform if not defined (by default, compile for RPI)
|
||||
# Other possible platform: PLATFORM_DESKTOP
|
||||
PLATFORM ?= PLATFORM_DESKTOP
|
||||
|
||||
# determine PLATFORM_OS in case PLATFORM_DESKTOP selected
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
# No uname.exe on MinGW!, but OS=Windows_NT on Windows! ifeq ($(UNAME),Msys) -> Windows
|
||||
ifeq ($(OS),Windows_NT)
|
||||
PLATFORM_OS=WINDOWS
|
||||
LIBPATH=win32
|
||||
else
|
||||
UNAMEOS:=$(shell uname)
|
||||
ifeq ($(UNAMEOS),Linux)
|
||||
PLATFORM_OS=LINUX
|
||||
LIBPATH=linux
|
||||
else
|
||||
ifeq ($(UNAMEOS),Darwin)
|
||||
PLATFORM_OS=OSX
|
||||
LIBPATH=osx
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# define compiler: gcc for C program, define as g++ for C++
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
# define emscripten compiler
|
||||
CC = emcc
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
# define llvm compiler for mac
|
||||
CC = clang
|
||||
else
|
||||
# define default gcc compiler
|
||||
CC = gcc
|
||||
endif
|
||||
endif
|
||||
|
||||
# define compiler flags:
|
||||
# -O2 defines optimization level
|
||||
# -Wall turns on most, but not all, compiler warnings
|
||||
# -std=c99 use standard C from 1999 revision
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
CFLAGS = -O2 -Wall -std=gnu99 -fgnu89-inline
|
||||
else
|
||||
CFLAGS = -O2 -Wall -std=c99
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
CFLAGS = -O1 -Wall -std=c99 -s USE_GLFW=3 --preload-file resources -s ALLOW_MEMORY_GROWTH=1 --shell-file ../../templates/web_shell/shell.html
|
||||
#-s ASSERTIONS=1 --preload-file resources
|
||||
#-s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing
|
||||
#-s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB)
|
||||
endif
|
||||
|
||||
# define any directories containing required header files
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
INCLUDES = -I. -I../../src -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads
|
||||
else
|
||||
INCLUDES = -I. -I../../src
|
||||
# external libraries headers
|
||||
# GLFW3
|
||||
INCLUDES += -I../../external/glfw3/include
|
||||
# GLEW
|
||||
INCLUDES += -I../../external/glew/include
|
||||
# OpenAL Soft
|
||||
INCLUDES += -I../../external/openal_soft/include
|
||||
endif
|
||||
|
||||
# define library paths containing required libs
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
LFLAGS = -L. -L../../src -L/opt/vc/lib
|
||||
else
|
||||
LFLAGS = -L. -L../../src -L../../../src
|
||||
# external libraries to link with
|
||||
# GLFW3
|
||||
LFLAGS += -L../../external/glfw3/lib/$(LIBPATH)
|
||||
ifneq ($(PLATFORM_OS),OSX)
|
||||
# OpenAL Soft
|
||||
LFLAGS += -L../../external/openal_soft/lib/$(LIBPATH)
|
||||
# GLEW
|
||||
LFLAGS += -L../../external/glew/lib/$(LIBPATH)
|
||||
endif
|
||||
endif
|
||||
|
||||
# define any libraries to link into executable
|
||||
# if you want to link libraries (libname.so or libname.a), use the -lname
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
# libraries for Debian GNU/Linux desktop compiling
|
||||
# requires the following packages:
|
||||
# libglfw3-dev libopenal-dev libglew-dev libegl1-mesa-dev
|
||||
LIBS = -lraylib -lglfw -lGLEW -lGL -lopenal
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
# libraries for OS X 10.9 desktop compiling
|
||||
# requires the following packages:
|
||||
# libglfw3-dev libopenal-dev libglew-dev libegl1-mesa-dev
|
||||
LIBS = -lraylib -lglfw -framework OpenGL -framework OpenAl -framework Cocoa
|
||||
else
|
||||
# libraries for Windows desktop compiling
|
||||
# NOTE: GLFW3 and OpenAL Soft libraries should be installed
|
||||
LIBS = -lraylib -lglfw3 -lglew32 -lopengl32 -lopenal32 -lgdi32
|
||||
endif
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
# libraries for Raspberry Pi compiling
|
||||
# NOTE: OpenAL Soft library should be installed (libopenal1 package)
|
||||
LIBS = -lraylib -lGLESv2 -lEGL -lpthread -lrt -lm -lbcm_host -lopenal
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
LIBS = ../../src/libraylib.bc
|
||||
endif
|
||||
|
||||
# define additional parameters and flags for windows
|
||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||
# resources file contains windows exe icon
|
||||
# -Wl,--subsystem,windows hides the console window
|
||||
WINFLAGS = ../../src/resources
|
||||
#-Wl,--subsystem,windows
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
EXT = .html
|
||||
endif
|
||||
|
||||
# define all screen object files required
|
||||
SCREENS = \
|
||||
screens/screen_logo.o \
|
||||
screens/screen_logo_raylib.o \
|
||||
screens/screen_title.o \
|
||||
screens/screen_attic.o \
|
||||
screens/screen_aisle01.o \
|
||||
screens/screen_aisle02.o \
|
||||
screens/screen_armory.o \
|
||||
screens/screen_livingroom.o \
|
||||
screens/screen_kitchen.o \
|
||||
screens/screen_bathroom.o \
|
||||
screens/screen_ending.o \
|
||||
player.o \
|
||||
monster.o \
|
||||
|
||||
# typing 'make' will invoke the first target entry in the file,
|
||||
# in this case, the 'default' target entry is advance_game
|
||||
default: skully_escape
|
||||
|
||||
# compile template - advance_game
|
||||
skully_escape: skully_escape.c $(SCREENS)
|
||||
$(CC) -o $@$(EXT) $< $(SCREENS) $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile screen LOGO
|
||||
screens/screen_logo.o: screens/screen_logo.c
|
||||
$(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
|
||||
# compile screen LOGO raylib
|
||||
screens/screen_logo_raylib.o: screens/screen_logo_raylib.c
|
||||
$(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
|
||||
# compile screen TITLE
|
||||
screens/screen_title.o: screens/screen_title.c
|
||||
$(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
|
||||
# compile screen ATTIC
|
||||
screens/screen_attic.o: screens/screen_attic.c
|
||||
$(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
|
||||
# compile screen AISLE01
|
||||
screens/screen_aisle01.o: screens/screen_aisle01.c
|
||||
$(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
|
||||
# compile screen AISLE02
|
||||
screens/screen_aisle02.o: screens/screen_aisle02.c
|
||||
$(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
|
||||
# compile screen BATHROOM
|
||||
screens/screen_bathroom.o: screens/screen_bathroom.c
|
||||
$(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
|
||||
# compile screen LIVINGROOM
|
||||
screens/screen_livingroom.o: screens/screen_livingroom.c
|
||||
$(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
|
||||
# compile screen KITCHEN
|
||||
screens/screen_kitchen.o: screens/screen_kitchen.c
|
||||
$(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
|
||||
# compile screen ARMORY
|
||||
screens/screen_armory.o: screens/screen_armory.c
|
||||
$(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
|
||||
# compile screen ENDING
|
||||
screens/screen_ending.o: screens/screen_ending.c
|
||||
$(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
|
||||
# compile screen LOGO
|
||||
player.o: player.c
|
||||
$(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
|
||||
# compile screen LOGO
|
||||
monster.o: monster.c
|
||||
$(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
|
||||
# clean everything
|
||||
clean:
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
find . -type f -perm +ugo+x -delete
|
||||
rm -f *.o
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
find . -type f -executable -delete
|
||||
rm -f *.o
|
||||
else
|
||||
del *.o *.exe
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
find . -type f -executable -delete
|
||||
rm -f *.o
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
del *.o *.html *.js
|
||||
endif
|
||||
@echo Cleaning done
|
||||
|
||||
# instead of defining every module one by one, we can define a pattern
|
||||
# this pattern below will automatically compile every module defined on $(OBJS)
|
||||
#%.exe : %.c
|
||||
# $(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM)
|
54
games/skully_escape/monster.c
Normal file
|
@ -0,0 +1,54 @@
|
|||
/***********************************************************************************
|
||||
*
|
||||
* KING GAME JAM - GRAY TEAM
|
||||
*
|
||||
* <Game title>
|
||||
* <Game description>
|
||||
*
|
||||
* This game has been created using raylib (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "monster.h"
|
||||
|
||||
void UpdateMonster(Monster *monster)
|
||||
{
|
||||
if (!monster->active)
|
||||
{
|
||||
if (CheckCollisionPointRec(GetMousePosition(), monster->bounds)) monster->selected = true;
|
||||
else monster->selected = false;
|
||||
}
|
||||
else if (monster->spooky)
|
||||
{
|
||||
monster->framesCounter++;
|
||||
monster->currentSeq = 0;
|
||||
|
||||
if (monster->framesCounter > 7)
|
||||
{
|
||||
monster->currentFrame++;
|
||||
monster->framesCounter = 0;
|
||||
|
||||
if (monster->currentFrame > monster->numFrames - 1) monster->currentFrame = 1;
|
||||
}
|
||||
}
|
||||
|
||||
monster->frameRec.x = monster->currentFrame*monster->texture.width/monster->numFrames;
|
||||
monster->frameRec.y = monster->currentSeq*monster->texture.height;
|
||||
}
|
||||
|
||||
void DrawMonster(Monster monster, int scroll)
|
||||
{
|
||||
Vector2 scrollPos = { monster.position.x - scroll, monster.position.y };
|
||||
|
||||
if (monster.selected) DrawTextureRec(monster.texture, monster.frameRec, scrollPos, RED);
|
||||
else DrawTextureRec(monster.texture, monster.frameRec, scrollPos, WHITE);
|
||||
}
|
||||
|
||||
void UnloadMonster(Monster monster)
|
||||
{
|
||||
UnloadTexture(monster.texture);
|
||||
}
|
73
games/skully_escape/monster.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
/**********************************************************************************************
|
||||
*
|
||||
* raylib - Advance Game template
|
||||
*
|
||||
* Screens Functions Declarations (Init, Update, Draw, Unload)
|
||||
*
|
||||
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
*
|
||||
* 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 MONSTER_H
|
||||
#define MONSTER_H
|
||||
|
||||
#define MONSTER_ANIM_FRAMES 7
|
||||
#define MONSTER_ANIM_SEQ 2
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//---------------------------------------------------------------------------------
|
||||
typedef struct Monster {
|
||||
Vector2 position;
|
||||
Texture2D texture;
|
||||
Rectangle bounds;
|
||||
Rectangle frameRec;
|
||||
Color color;
|
||||
int framesCounter;
|
||||
int currentFrame;
|
||||
int currentSeq;
|
||||
int numFrames;
|
||||
bool active;
|
||||
bool selected;
|
||||
bool spooky;
|
||||
} Monster;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { // Prevents name mangling of functions
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Monster Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
void UpdateMonster(Monster *monster);
|
||||
void DrawMonster(Monster monster, int scroll);
|
||||
void UnloadMonster(Monster monster);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SCREENS_H
|
281
games/skully_escape/player.c
Normal file
|
@ -0,0 +1,281 @@
|
|||
/***********************************************************************************
|
||||
*
|
||||
* KING GAME JAM - GRAY TEAM
|
||||
*
|
||||
* <Game title>
|
||||
* <Game description>
|
||||
*
|
||||
* This game has been created using raylib (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "player.h"
|
||||
|
||||
#define PLAYER_ANIM_FRAMES 4
|
||||
#define PLAYER_ANIM_SEQ 6
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Player mouse moving variables
|
||||
static bool movingAnim;
|
||||
static int moveDirection;
|
||||
static int nextMovePoint;
|
||||
|
||||
// Mouse pointer variables
|
||||
static Vector2 pointerPosition;
|
||||
static bool pointerAnim;
|
||||
static float pointerAlpha;
|
||||
|
||||
static int framesCounter;
|
||||
static bool outControl = false;
|
||||
|
||||
static int animTimer = 0;
|
||||
|
||||
static Texture2D texLife;
|
||||
|
||||
static void DrawLifes(void);
|
||||
|
||||
// player initialitaction definition
|
||||
void InitPlayer(void)
|
||||
{
|
||||
// NOTE: Some player variables are only initialized once
|
||||
player.texture = LoadTexture("resources/textures/skully.png");
|
||||
player.position = (Vector2){ 350, 400 };
|
||||
player.numLifes = 4;
|
||||
|
||||
ResetPlayer();
|
||||
|
||||
framesCounter = 0;
|
||||
|
||||
texLife = LoadTexture("resources/textures/skully_icon.png");
|
||||
}
|
||||
|
||||
// player update definition
|
||||
void UpdatePlayer(void)
|
||||
{
|
||||
if (!outControl)
|
||||
{
|
||||
if ((IsKeyDown(KEY_LEFT)) || (IsKeyDown(KEY_RIGHT)))
|
||||
{
|
||||
moveDirection = -1;
|
||||
movingAnim = false;
|
||||
}
|
||||
|
||||
if ((IsKeyDown(KEY_RIGHT)) || (moveDirection == 0))
|
||||
{
|
||||
player.currentSeq = WALK_RIGHT;
|
||||
framesCounter++;
|
||||
|
||||
if (framesCounter > 15)
|
||||
{
|
||||
player.currentFrame++;
|
||||
framesCounter = 0;
|
||||
|
||||
if (player.currentFrame > PLAYER_ANIM_FRAMES - 1) player.currentFrame = 0;
|
||||
}
|
||||
|
||||
player.position.x += 4;
|
||||
}
|
||||
else if ((IsKeyDown(KEY_LEFT)) || (moveDirection == 1))
|
||||
{
|
||||
player.currentSeq = WALK_LEFT;
|
||||
framesCounter++;
|
||||
|
||||
if (framesCounter > 15)
|
||||
{
|
||||
player.currentFrame++;
|
||||
framesCounter = 0;
|
||||
|
||||
if (player.currentFrame > PLAYER_ANIM_FRAMES - 1) player.currentFrame = 0;
|
||||
}
|
||||
|
||||
player.position.x -= 4;
|
||||
}
|
||||
else player.currentFrame = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
framesCounter++;
|
||||
animTimer++;
|
||||
|
||||
if (framesCounter > 10)
|
||||
{
|
||||
player.currentFrame++;
|
||||
framesCounter = 0;
|
||||
|
||||
if (player.currentFrame > PLAYER_ANIM_FRAMES - 1) player.currentFrame = 0;
|
||||
|
||||
// We can adjust animation playing time depending on sequence
|
||||
switch (player.currentSeq)
|
||||
{
|
||||
case SCARE_RIGHT:
|
||||
{
|
||||
if (animTimer > 180)
|
||||
{
|
||||
animTimer = 0;
|
||||
outControl = false;
|
||||
player.currentSeq = WALK_LEFT;
|
||||
}
|
||||
} break;
|
||||
case SCARE_LEFT:
|
||||
{
|
||||
if (animTimer > 240)
|
||||
{
|
||||
animTimer = 0;
|
||||
outControl = false;
|
||||
player.currentSeq = WALK_RIGHT;
|
||||
}
|
||||
} break;
|
||||
case SEARCH:
|
||||
case FIND_KEY:
|
||||
{
|
||||
if (animTimer > 240)
|
||||
{
|
||||
animTimer = 0;
|
||||
outControl = false;
|
||||
player.currentSeq = WALK_RIGHT;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (player.position.x < 30) player.position.x = 30;
|
||||
else if (player.position.x > (GetScreenWidth() - 200)) player.position.x = GetScreenWidth() - 200;
|
||||
|
||||
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
|
||||
{
|
||||
pointerPosition = GetMousePosition();
|
||||
pointerAnim = true;
|
||||
pointerAlpha = 1.0f;
|
||||
|
||||
nextMovePoint = (int)pointerPosition.x;
|
||||
movingAnim = true;
|
||||
}
|
||||
|
||||
if (movingAnim)
|
||||
{
|
||||
if (nextMovePoint > (player.position.x + (player.frameRec.width/2) + 5)) moveDirection = 0; // Move Left
|
||||
else if (nextMovePoint < (player.position.x + (player.frameRec.width/2) - 5)) moveDirection = 1; // Move Right
|
||||
else
|
||||
{
|
||||
moveDirection = -1;
|
||||
movingAnim = 0;
|
||||
}
|
||||
}
|
||||
|
||||
player.frameRec.x = player.currentFrame*player.texture.width/PLAYER_ANIM_FRAMES;
|
||||
player.frameRec.y = (player.currentSeq - 1)*player.texture.height/PLAYER_ANIM_SEQ;
|
||||
|
||||
// Update player bounds
|
||||
player.bounds = (Rectangle){ player.position.x + 50, player.position.y - 60, 100, 300 };
|
||||
|
||||
// Mouse pointer alpha animation
|
||||
if (pointerAnim)
|
||||
{
|
||||
pointerAlpha -= 0.1f;
|
||||
|
||||
if (pointerAlpha <= 0.0f)
|
||||
{
|
||||
pointerAlpha = 0.0f;
|
||||
pointerAnim = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
void DrawPlayer(void)
|
||||
{
|
||||
DrawTextureRec(player.texture, player.frameRec, player.position, WHITE);
|
||||
|
||||
// Draw mouse pointer on click
|
||||
if (pointerAnim) DrawCircleV(pointerPosition, 20, Fade(RED, pointerAlpha));
|
||||
|
||||
DrawLifes();
|
||||
}
|
||||
|
||||
void UnloadPlayer(void)
|
||||
{
|
||||
UnloadTexture(player.texture);
|
||||
UnloadTexture(texLife);
|
||||
}
|
||||
|
||||
void ResetPlayer(void)
|
||||
{
|
||||
// Reset player variables
|
||||
player.frameRec = (Rectangle){ 0, 0, player.texture.width/PLAYER_ANIM_FRAMES, player.texture.height/PLAYER_ANIM_SEQ };
|
||||
player.currentFrame = 0;
|
||||
player.currentSeq = WALK_RIGHT;
|
||||
|
||||
player.key = false;
|
||||
player.dead = false;
|
||||
|
||||
// Reset player position
|
||||
if (player.position.x < 400) player.position.x = GetScreenWidth() - 350;
|
||||
if (player.position.x > (GetScreenWidth() - 400)) player.position.x = 350;
|
||||
|
||||
// Reset moving variables
|
||||
movingAnim = false;
|
||||
moveDirection = -1;
|
||||
nextMovePoint = 0;
|
||||
framesCounter = 0;
|
||||
outControl = false;
|
||||
animTimer = 0;
|
||||
|
||||
// Reset pointer
|
||||
pointerAlpha = 0.0f;
|
||||
pointerAnim = false;
|
||||
}
|
||||
|
||||
void ScarePlayer(void)
|
||||
{
|
||||
player.currentFrame = 0;
|
||||
|
||||
if (moveDirection == 0) player.currentSeq = SCARE_RIGHT;
|
||||
else if (moveDirection == 1) player.currentSeq = SCARE_LEFT;
|
||||
else player.currentSeq = SCARE_RIGHT;
|
||||
|
||||
player.numLifes--;
|
||||
|
||||
if (player.numLifes <= 0) player.dead = true;
|
||||
|
||||
outControl = true;
|
||||
}
|
||||
|
||||
void SearchKeyPlayer(void)
|
||||
{
|
||||
moveDirection = -1;
|
||||
movingAnim = 0;
|
||||
|
||||
player.currentFrame = 0;
|
||||
player.currentSeq = SEARCH;
|
||||
|
||||
outControl = true;
|
||||
}
|
||||
|
||||
void FindKeyPlayer(void)
|
||||
{
|
||||
player.currentFrame = 0;
|
||||
player.currentSeq = FIND_KEY;
|
||||
player.key = true;
|
||||
|
||||
outControl = true;
|
||||
}
|
||||
|
||||
static void DrawLifes(void)
|
||||
{
|
||||
if (player.numLifes != 0)
|
||||
{
|
||||
Vector2 position = { 20, GetScreenHeight() - texLife.height - 20 };
|
||||
|
||||
for(int i = 0; i < player.numLifes; i++)
|
||||
{
|
||||
DrawTexture(texLife, position.x + i*texLife.width, position.y, Fade(RAYWHITE, 0.7f));
|
||||
}
|
||||
}
|
||||
}
|