Created
December 25, 2020 21:04
-
-
Save flarn2006/f913a023d645c83b86f54f9c30b4b320 to your computer and use it in GitHub Desktop.
Simple game based on a SmileBASIC example program
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Requires raylib (compile with -lraylib) */ | |
#include <raylib.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#define WIDTH 400 | |
#define HEIGHT 240 | |
#define SAFE_AREA 50 | |
#define BASE_COUNT 500 | |
#define PER_LEVEL 100 | |
#define PIXEL_SCALE 3 | |
struct LevelState { | |
int tex_valid; | |
Image img; | |
Texture2D tex; | |
unsigned char bitmap[WIDTH/8][HEIGHT]; | |
int trail[WIDTH]; | |
int playerX, playerY; | |
}; | |
void bmp_set(struct LevelState* state, int x, int y, int bit) | |
{ | |
unsigned char* byte = &state->bitmap[x/8][y]; | |
unsigned char mask = 1 << (x % 8); | |
if (bit) | |
*byte |= mask; | |
else | |
*byte &= ~mask; | |
} | |
int bmp_read(struct LevelState* state, int x, int y) | |
{ | |
unsigned char byte = state->bitmap[x/8][y]; | |
unsigned char mask = 1 << (x % 8); | |
return !!(byte & mask); | |
} | |
void bmp_clear(struct LevelState* state) | |
{ | |
memset(&state->bitmap, 0, sizeof(state->bitmap)); | |
} | |
void init_level(struct LevelState* state, int lvlnum) | |
{ | |
if (state->tex_valid) { | |
UnloadTexture(state->tex); | |
} else { | |
state->tex_valid = 1; | |
} | |
bmp_clear(state); | |
int count = BASE_COUNT + PER_LEVEL * (lvlnum - 1); | |
ImageClearBackground(&state->img, BLACK); | |
for (int i=0; i<WIDTH; ++i) | |
state->trail[i] = -1; | |
state->playerX = 0; | |
if (lvlnum == 0) { | |
state->playerY = 40; | |
} else { | |
state->playerY = HEIGHT/2; | |
for (int i=0; i<count; ++i) { | |
int x = SAFE_AREA + rand() % (WIDTH - SAFE_AREA); | |
int y = 1 + rand() % (HEIGHT - 2); | |
ImageDrawPixel(&state->img, x, y, RED); | |
bmp_set(state, x, y, 1); | |
} | |
for (int i=0; i<WIDTH; ++i) { | |
ImageDrawPixel(&state->img, i, 0, YELLOW); | |
ImageDrawPixel(&state->img, i, HEIGHT-1, YELLOW); | |
bmp_set(state, i, 0, 1); | |
bmp_set(state, i, HEIGHT-1, 1); | |
} | |
} | |
state->tex = LoadTextureFromImage(state->img); | |
} | |
int main() | |
{ | |
InitWindow(WIDTH*PIXEL_SCALE, HEIGHT*PIXEL_SCALE, "Zigzag"); | |
SetTargetFPS(30); | |
int level = -1; /* negative = needs initialization */ | |
int score = 0; | |
int cheat = 0; | |
int was_level; | |
struct LevelState state; | |
state.tex_valid = 0; | |
state.img = GenImageColor(WIDTH, HEIGHT, BLACK); | |
while (!WindowShouldClose()) { | |
static int increment = 1; | |
if (level < 0) { | |
level = -level; | |
init_level(&state, level); | |
} else if (level == 0) { | |
cheat = IsMouseButtonDown(MOUSE_LEFT_BUTTON) && IsMouseButtonDown(MOUSE_MIDDLE_BUTTON) && IsMouseButtonDown(MOUSE_RIGHT_BUTTON); | |
} | |
BeginDrawing(); | |
DrawTextureEx(state.tex, (Vector2){0, 0}, 0.0f, PIXEL_SCALE, WHITE); | |
for (int i=0; i<WIDTH; ++i) { | |
if (state.trail[i] >= 0) | |
DrawRectangle(i*PIXEL_SCALE, state.trail[i]*PIXEL_SCALE, PIXEL_SCALE, PIXEL_SCALE, BLUE); | |
if (cheat && i > state.playerX) { | |
int y = state.playerY + increment * (i - state.playerX); | |
if (bmp_read(&state, i, y)) | |
break; | |
else if (i & 1) | |
DrawRectangle(i*PIXEL_SCALE, y*PIXEL_SCALE, PIXEL_SCALE, PIXEL_SCALE, DARKBLUE); | |
} | |
} | |
DrawRectangle(state.playerX * PIXEL_SCALE, state.playerY * PIXEL_SCALE, PIXEL_SCALE, PIXEL_SCALE, WHITE); | |
if (level == 0) { | |
DrawRectangle(0, 0, WIDTH * PIXEL_SCALE, PIXEL_SCALE, LIME); | |
DrawRectangle((WIDTH - 1) * PIXEL_SCALE, 0, PIXEL_SCALE, HEIGHT * PIXEL_SCALE, LIME); | |
DrawRectangle(0, (HEIGHT - 1) * PIXEL_SCALE, WIDTH * PIXEL_SCALE, PIXEL_SCALE, RED); | |
DrawText(TextFormat("You made it to level %d", was_level), 32, 32, 32, PINK); | |
DrawText(TextFormat("Your score was %d", score), 32, 64, 32, YELLOW); | |
DrawText("Try again?", 32, 128, 64, LIME); | |
} else { | |
DrawText(TextFormat("Level %d - Score %d", level, score), 8, 8, 24, LIME); | |
} | |
EndDrawing(); | |
state.trail[state.playerX] = state.playerY; | |
++state.playerX; | |
score += level; | |
increment = IsMouseButtonDown(MOUSE_LEFT_BUTTON) ? -1 : 1; | |
state.playerY += increment; | |
if (level == 0) { | |
if (state.playerY < 1 || state.playerX >= WIDTH) { | |
level = -1; | |
score = 0; | |
} else if (state.playerY >= HEIGHT-1) { | |
break; | |
} | |
} else if (state.playerX >= WIDTH) { | |
level = -(level + 1); | |
} else if (state.playerY < 1 || state.playerY >= HEIGHT-1 || bmp_read(&state, state.playerX, state.playerY)) { | |
was_level = level; | |
level = 0; | |
init_level(&state, 0); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment