1/*******************************************************************************************
2*
3* raylib - sample game: floppy
4*
5* Sample game developed by Ian Eito, Albert Martos and Ramon Santamaria
6*
7* This game has been created using raylib v1.3 (www.raylib.com)
8* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
9*
10* Copyright (c) 2015 Ramon Santamaria (@raysan5)
11*
12********************************************************************************************/
13
14#include "raylib.h"
15
16#if defined(PLATFORM_WEB)
17 #include <emscripten/emscripten.h>
18#endif
19
20//----------------------------------------------------------------------------------
21// Some Defines
22//----------------------------------------------------------------------------------
23#define MAX_TUBES 100
24#define FLOPPY_RADIUS 24
25#define TUBES_WIDTH 80
26
27//----------------------------------------------------------------------------------
28// Types and Structures Definition
29//----------------------------------------------------------------------------------
30typedef struct Floppy {
31 Vector2 position;
32 int radius;
33 Color color;
34} Floppy;
35
36typedef struct Tubes {
37 Rectangle rec;
38 Color color;
39 bool active;
40} Tubes;
41
42//------------------------------------------------------------------------------------
43// Global Variables Declaration
44//------------------------------------------------------------------------------------
45static const int screenWidth = 800;
46static const int screenHeight = 450;
47
48static bool gameOver = false;
49static bool pause = false;
50static int score = 0;
51static int hiScore = 0;
52
53static Floppy floppy = { 0 };
54static Tubes tubes[MAX_TUBES*2] = { 0 };
55static Vector2 tubesPos[MAX_TUBES] = { 0 };
56static int tubesSpeedX = 0;
57static bool superfx = false;
58
59//------------------------------------------------------------------------------------
60// Module Functions Declaration (local)
61//------------------------------------------------------------------------------------
62static void InitGame(void); // Initialize game
63static void UpdateGame(void); // Update game (one frame)
64static void DrawGame(void); // Draw game (one frame)
65static void UnloadGame(void); // Unload game
66static void UpdateDrawFrame(void); // Update and Draw (one frame)
67
68//------------------------------------------------------------------------------------
69// Program main entry point
70//------------------------------------------------------------------------------------
71int main(void)
72{
73 // Initialization
74 //---------------------------------------------------------
75 InitWindow(screenWidth, screenHeight, "sample game: floppy");
76
77 InitGame();
78
79#if defined(PLATFORM_WEB)
80 emscripten_set_main_loop(UpdateDrawFrame, 0, 1);
81#else
82 SetTargetFPS(60);
83 //--------------------------------------------------------------------------------------
84
85 // Main game loop
86 while (!WindowShouldClose()) // Detect window close button or ESC key
87 {
88 // Update and Draw
89 //----------------------------------------------------------------------------------
90 UpdateDrawFrame();
91 //----------------------------------------------------------------------------------
92 }
93#endif
94 // De-Initialization
95 //--------------------------------------------------------------------------------------
96 UnloadGame(); // Unload loaded data (textures, sounds, models...)
97
98 CloseWindow(); // Close window and OpenGL context
99 //--------------------------------------------------------------------------------------
100
101 return 0;
102}
103//------------------------------------------------------------------------------------
104// Module Functions Definitions (local)
105//------------------------------------------------------------------------------------
106
107// Initialize game variables
108void InitGame(void)
109{
110 floppy.radius = FLOPPY_RADIUS;
111 floppy.position = (Vector2){80, screenHeight/2 - floppy.radius};
112 tubesSpeedX = 2;
113
114 for (int i = 0; i < MAX_TUBES; i++)
115 {
116 tubesPos[i].x = 400 + 280*i;
117 tubesPos[i].y = -GetRandomValue(0, 120);
118 }
119
120 for (int i = 0; i < MAX_TUBES*2; i += 2)
121 {
122 tubes[i].rec.x = tubesPos[i/2].x;
123 tubes[i].rec.y = tubesPos[i/2].y;
124 tubes[i].rec.width = TUBES_WIDTH;
125 tubes[i].rec.height = 255;
126
127 tubes[i+1].rec.x = tubesPos[i/2].x;
128 tubes[i+1].rec.y = 600 + tubesPos[i/2].y - 255;
129 tubes[i+1].rec.width = TUBES_WIDTH;
130 tubes[i+1].rec.height = 255;
131
132 tubes[i/2].active = true;
133 }
134
135 score = 0;
136
137 gameOver = false;
138 superfx = false;
139 pause = false;
140}
141
142// Update game (one frame)
143void UpdateGame(void)
144{
145 if (!gameOver)
146 {
147 if (IsKeyPressed('P')) pause = !pause;
148
149 if (!pause)
150 {
151 for (int i = 0; i < MAX_TUBES; i++) tubesPos[i].x -= tubesSpeedX;
152
153 for (int i = 0; i < MAX_TUBES*2; i += 2)
154 {
155 tubes[i].rec.x = tubesPos[i/2].x;
156 tubes[i+1].rec.x = tubesPos[i/2].x;
157 }
158
159 if (IsKeyDown(KEY_SPACE) && !gameOver) floppy.position.y -= 3;
160 else floppy.position.y += 1;
161
162 // Check Collisions
163 for (int i = 0; i < MAX_TUBES*2; i++)
164 {
165 if (CheckCollisionCircleRec(floppy.position, floppy.radius, tubes[i].rec))
166 {
167 gameOver = true;
168 pause = false;
169 }
170 else if ((tubesPos[i/2].x < floppy.position.x) && tubes[i/2].active && !gameOver)
171 {
172 score += 100;
173 tubes[i/2].active = false;
174
175 superfx = true;
176
177 if (score > hiScore) hiScore = score;
178 }
179 }
180 }
181 }
182 else
183 {
184 if (IsKeyPressed(KEY_ENTER))
185 {
186 InitGame();
187 gameOver = false;
188 }
189 }
190}
191
192// Draw game (one frame)
193void DrawGame(void)
194{
195 BeginDrawing();
196
197 ClearBackground(RAYWHITE);
198
199 if (!gameOver)
200 {
201 DrawCircle(floppy.position.x, floppy.position.y, floppy.radius, DARKGRAY);
202
203 // Draw tubes
204 for (int i = 0; i < MAX_TUBES; i++)
205 {
206 DrawRectangle(tubes[i*2].rec.x, tubes[i*2].rec.y, tubes[i*2].rec.width, tubes[i*2].rec.height, GRAY);
207 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);
208 }
209
210 // Draw flashing fx (one frame only)
211 if (superfx)
212 {
213 DrawRectangle(0, 0, screenWidth, screenHeight, WHITE);
214 superfx = false;
215 }
216
217 DrawText(TextFormat("%04i", score), 20, 20, 40, GRAY);
218 DrawText(TextFormat("HI-SCORE: %04i", hiScore), 20, 70, 20, LIGHTGRAY);
219
220 if (pause) DrawText("GAME PAUSED", screenWidth/2 - MeasureText("GAME PAUSED", 40)/2, screenHeight/2 - 40, 40, GRAY);
221 }
222 else DrawText("PRESS [ENTER] TO PLAY AGAIN", GetScreenWidth()/2 - MeasureText("PRESS [ENTER] TO PLAY AGAIN", 20)/2, GetScreenHeight()/2 - 50, 20, GRAY);
223
224 EndDrawing();
225}
226
227// Unload game variables
228void UnloadGame(void)
229{
230 // TODO: Unload all dynamic loaded data (textures, sounds, models...)
231}
232
233// Update and Draw (one frame)
234void UpdateDrawFrame(void)
235{
236 UpdateGame();
237 DrawGame();
238}
239