Skip to content

Instantly share code, notes, and snippets.

@smvd
Created May 11, 2021 13:39
Show Gist options
  • Save smvd/c779af8d3bf0e1dd02bb33117a79e4cc to your computer and use it in GitHub Desktop.
Save smvd/c779af8d3bf0e1dd02bb33117a79e4cc to your computer and use it in GitHub Desktop.
This is just a quick demo for the game i'm working on its not meant to be a full game yet, nor look good
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000040000000000000
0000000000000000000000011111111000000000
0000000000000000000000000000001000000000
0000000000000000000000000000001000000000
0000000000000000001100000000001000000000
0000000000000040000000000000001000000000
0000000111111111100000000000001000000000
0000000000000000000000000000001000000000
0000000000000000000000000000001000000000
0000000000000000001111110000001000003000
0000000000000000001000000000001111111111
0000200000000000001000000000000000000000
0000000000000000111000000000000000000000
0000000000000000001000000000000000000000
1111111111111111111000000000000000000000
#include <windows.h>
#include <stdio.h>
#include <time.h>
#define xSize 40
#define ySize 20
#define RED "\e[31m"
#define GREEN "\e[32m"
#define YELLOW "\e[33m"
#define BLUE "\e[34m"
#define PURPLE "\e[35m"
#define AQUA "\e[36m"
#define NC "\e[37m"
#define RIGHT_KEY 0x27
#define LEFT_KEY 0x25
#define UP_KEY 0x26
#define Q_KEY 0x51
#define R_KEY 0x52
typedef struct
{
int x;
int y;
int s; // For special info
}PIX;
PIX player; // Variable to hold the player date
PIX ghost; // Variable to hold the previos position of the player
PIX spawn; // Variable to hold the spawn location
PIX level[1000]; // Variable to hold all the walls
PIX enemy[50]; // Variable to hold all the enemys
PIX end; // Variable to hold the end block
int enemySize = 0; // Variable to hold the ammount of enemys
int lvlSize = 0; // Variable to hold the ammount of blocks
int IsFloor(int x, int y); // Prototype
void Setup()
{
srand(time(NULL)); // RNG seeding
for (int i = -1; i < ySize +1; i++) // Making space for the game
{
printf("\n");
}
}
void ReadLevel(int lvl) // Function to read level based on index
{
char ch; // Variable to hold the read character
char temp[20]; // Temp variable
int x = 0;
int y = 0;
int i = 0; // Variable to hold the read ammount of blocks
int a = 0; // Variable to hold the read ammount of enemys
sprintf(temp, "levels\\%d.LVL", lvl); // Generating the path based on the lvl number
FILE *fp = fopen(temp, "r"); // Reading the file
while((ch = fgetc(fp)) != EOF) // Loop over each character in the file
{
if (ch == '1')
{
level[i].x = x;
level[i].y = y;
lvlSize++;
i++;
}
else if (ch == '4')
{
enemy[a].x = x;
enemy[a].y = y;
enemy[a].s = rand() % 2; // For enemys we store their walking direction in s wich is a 0 or 1
enemySize++;
a++;
}
else if (ch == '3')
{
end.x = x;
end.y = y;
}
else if (ch == '2')
{
player.x = x;
player.y = y;
ghost = player; // Saving the first ghost
spawn = player; // Saving the respawn location
}
if (ch == 10) // 10 is the end of a line
{
y++;
x = 0;
}
else
{
x++;
}
}
}
int IsEnemy(int x, int y)
{
for (int i = 0; i < enemySize; i++) // Loop over each enemy and match their location against x and y
{
if (enemy[i].x == x && enemy[i].y == y)
{
return 1;
}
}
return 0;
}
void Draw()
{
char buff[5000]; // The buffer that will be used to draw
strcpy(buff, ""); // Clearing the buffer
for (int i = -1; i <= ySize; i++) // Moving up the correct ammount of lines to overwrite the current frame
{
strcat(buff, "\e[1A");
}
// Loop over each x, y position
for (int y = -1; y <= ySize; y++)
{
for (int x = -1; x <= xSize; x++)
{
if (y == -1 || x == -1 || x == xSize || y == ySize) // If its a window edge
{
strcat(buff, NC "[]");
}
else if (IsEnemy(x, y)) // If its a enemy
{
strcat(buff, PURPLE "[]");
}
else if (y == end.y && x == end.x) // If its the end block
{
strcat(buff, GREEN "[]");
}
else if (y == player.y && x == player.x) // If its the player
{
strcat(buff, RED "()");
}
else if (IsFloor(x, y)) // If its a floor block
{
strcat(buff, BLUE "[]");
}
else // If there was no object on this x, y
{
strcat(buff, " ");
}
}
strcat(buff, "\n"); // Start building the next line
}
printf(buff); // Overwrite the frame with the new one stored in the buffer
}
int IsFloor(int x, int y)
{
for (int i = 0; i < lvlSize; i++) // Loop over each floor block and test it against x, y
{
if (x == level[i].x && y == level[i].y)
{
return 1;
}
}
return 0;
}
void HitTest()
{
if (player.x == end.x && player.y == end.y) // If the player is on the end block
{
exit(0);
}
// If the player is touching the enemy
if (IsEnemy(player.x, player.y) || IsEnemy(player.x +1, player.y) || IsEnemy(player.x -1, player.y))
{
exit(0);
}
// If the player is walking of the map
if (player.x == -1 || player.x == xSize +1 || player.y == ySize +1)
{
exit(0);
}
}
int main()
{
Setup(); // Prepare the program
ReadLevel(1); // Load the first level
int jump = 0; // Variable to spread jumps accross frames
while (1) // Inf loop
{
Draw(); // Draw the game
HitTest(); // Test for collisions
if (GetAsyncKeyState(Q_KEY)) // If the user presses q
{
break;
}
if (GetAsyncKeyState(R_KEY)) // If the user presses r
{
player = spawn;
}
if (GetAsyncKeyState(LEFT_KEY) && !IsFloor(player.x -1, player.y)) // If the user pressed left and there is no wall in the way
{
player.x--;
}
if (GetAsyncKeyState(RIGHT_KEY) && !IsFloor(player.x +1, player.y)) // If the user pressed right and there is no wall in the way
{
player.x++;
}
for (int i = 0; i < enemySize; i++) // Loop over each enemy
{
if (enemy[i].s == 0) // If its walking left
{
if (IsFloor(enemy[i].x -1, enemy[i].y +1)) // If there is a floor to the left
{
enemy[i].x--;
}
else
{
enemy[i].s = 1; // Flip the direction
}
}
if (enemy[i].s == 1) // If its walking right
{
if (IsFloor(enemy[i].x +1, enemy[i].y +1)) // If there is a floor on the right
{
enemy[i].x++;
}
else
{
enemy[i].s = 0; // Flip
}
}
}
// If the player presses up and there is a floor bellow him or his ghost(this is done as it greatly improves the feel of the game)
if (GetAsyncKeyState(UP_KEY) && (IsFloor(player.x, player.y +1) || IsFloor(ghost.x, ghost.y +1)))
{
jump = 3;
}
if (jump)
{
if (!IsFloor(player.x, player.y -1)) // If there is no roof above the player
{
player.y--;
}
if (!IsFloor(player.x, player.y -1)) // If there is no roof above the player
{
player.y--;
}
jump--;
}
if (!IsFloor(player.x, player.y +1) && !jump) // If there is no floor bellow the player
{
player.y++;
}
if (!IsFloor(player.x, player.y +1) && !jump) // If there is no floor bellow the player
{
player.y++;
}
ghost = player; // Update the ghost
Sleep(100); // Wait 0.1 seconds
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment