@ -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(); | |||
//---------------------------------------------------------------------------------- | |||
} | |||
@ -0,0 +1,203 @@ | |||
#************************************************************************************************** | |||
# | |||
# 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 | |||
#-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. -IC:/raylib/raylib/src -IC:/raylib/raylib/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. -LC:/raylib/raylib/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 = C:/raylib/raylib/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 = C:/raylib/raylib/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) |
@ -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); | |||
} | |||
} |
@ -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; | |||
} |
@ -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; | |||
} |
@ -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 |