Skip to content

Instantly share code, notes, and snippets.

@smvd
Created May 3, 2021 13:18
Show Gist options
  • Save smvd/a8a83e724549a22d1a078f06ef33b87a to your computer and use it in GitHub Desktop.
Save smvd/a8a83e724549a22d1a078f06ef33b87a to your computer and use it in GitHub Desktop.
/*
____ _____ _ ____ __ __ _____
| _ \| ____| / \ | _ \ | \/ | ____|
| |_) | _| / _ \ | | | | | |\/| | _|
| _ <| |___ / ___ \| |_| | | | | | |___
|_| \_\_____/_/ \_\____/ |_| |_|_____|
<--[ GENERAL ]-->
This is a simple game meant to be fun yet simple.
It uses ANSI codes to make it run without flicker compared to most small terminal games.
These codes currently need to be activated on windows 10 so lookup a guide.
The command i used to compile the game was:
GCC source.c resource.o -o SS.exe -Wall -Werror -W -lpthread
GCC : MinGw compiler
source.c : Source code
resource.o : ICON and version info (not required)
-o SS.exe : Set output file to SS.exe
-Wall : All warning about questionable code
-Werror : Make all warnings into errors
-W : Inhibit all warning messages
-lpthread : Link the pthread library
It was built on windows for windows.
But if you are on linux or OS X some google foo should get you some suitable replacements.
Under the spaceships section you will find my simple ship designs.
Under the controls section you will find the controls for the game
Under the info section you will find some basic info about the game build
The whole game falls under unlicense, but please plug my channel and leave this readme.
I cant force you but i can kindly ask.
<--[ SPACESHIPS ]-->
PLAYER:
/]\
<]()]]C>
\]/
ENEMY:
/-|
<( [>C>
\-|
<--[ CONTROLS ]-->
W : UP
S : DOWN
Q : QUIT
SPACE : FIRE
<--[ INFO ]-->
Font : Cascadia Code (Its suggested not needed)
Reddit : No_War3219
Editor : Sublime text 3
Discord : smvd#4197
Version : 2.0
License : www.unlicense.org
Youtube : www.rebrand.ly/eclips-coding
Compiler : GCC
Platform : WINDOWS
Terminal : Windows Terminal CMD (Default, not previeuw)
StackOverflow : smvd
*/
#include <pthread.h> // Header for multithreading
#include <windows.h> // Header for working with windows
#include <string.h> // Header for string manipulation
#include <conio.h> // Header for general use
#include <stdio.h> // Header for input & output
#include <time.h> // Header for time
#define NC "\e[0m" // NC = ANSI code for white text
#define RED "\e[31m" // RED = ANSI code for red text
#define GREEN "\e[32m" // GREEN = ANSI code for green text
#define YELLOW "\e[33m" // YELLOW = ANSI code for yellow text
#define BLUE "\e[34m" // BLUE = ANSI code for blue text
typedef struct // Defining custom variable
{
int x; // Variable for the X position
int y; // Variable for the Y position
}PIX; // Variable name = PIX
PIX bullets[100]; // Variable array for the bullets
PIX enemy; // Variable for the enemy
int bulletCount = 0; // Variable for the bullet count
int fire = 0; // Variable for the frames since last shot
int playerY = 8; // Variable for the player Y position
int FIRERATE = 500; // Variable for the fire rate
int SPEED = 75; // Variable for the delay between frames
pthread_t inputThread; // Varialbe for the input thread
char input = '\0'; // Variable for the user input
void *In(); // Function to get user input
void Move(); // Function to move elements
void Draw(); // Function to draw the game
void Start(); // Function to prepare the game
void HitTest(); // Function to test for hits
void SpawnEnemy(); // Function to spawn a new enemy
void SpawnBullet(); // Function to spawn a new bullet
void DespawnBullet(int idx); // Function to despawn bullet
int InPlayer(); // Function to test if in player
int IsBullet(int x, int y); // Function to test if there is a bullet at X,Y
void *In() // Function for getting user input
{
while (1) // Loop for ever
{
input = getch(); // Store the pressed key in input
}
}
void Move() // Function to move elements
{
enemy.x--; // Remove 1 from the enemy x
HitTest(); // Test for hits
for ( // For
int i = 0; // Variable to hold the loop count
i < bulletCount; // While i is less then bullet count
i++ // Add 1 to i
)
{
if (bullets[i].x >= 33) // If bullet x is greater then or equal to 33
{
DespawnBullet(i); // Despawn the bullet
}
bullets[i].x += 2; // Add 2 to the bullet x
}
switch (input) // Test if input
{
case 'w': // Equals W
if (playerY > 1) // If player y is larger then 1
{
playerY--; // Remove 1 from the player y
}
break; // End test
case 's': // Equals S
if (playerY < 15) // If player y is less then 15
{
playerY++; // Add 1 to player y
}
break; // End test
case ' ': // Equals SPACE
if (fire == 0) // If fire equals 0
{
SpawnBullet(); // Spawn a new bullet
}
break; // End test
case 'q': // Equals Q
exit(0); // Exit game
break; // End test
}
input = '\0'; // Set input to 0x00
}
void Draw() // Function to draw the game
{
char buff[5000]; // Buffer variable
strcpy(buff, "\e[20A"); // Copy "move up 20 lines" into the buffer
strcat(buff, "\e[34D"); // Append "move back 34 characters" to the buffer
strcat(buff, NC "Press Q to quit, W & S to move, SPACE to shoot\n"); // Append "Press Q to quit, W & S to move, SPACE to shoot\n" to the buffer in white
for ( // For
int y = 0; // Variable to hold the loop count
y < 19; // While y is less then 19
y++ // Add 1 to y each loop
)
{
for ( // For
int x = 0; // Variable to hold the loop count
x < 34; // While x is less then 34
x++ // Add 1 to x each loop
)
{
if ( // If
x == 0 || // X == 0
x == 33 || // Or X == 3
y == 0 || // Or Y == 0
y == 18 // Or Y == 18
)
{
strcat(buff, NC "[]"); // Append "[]" to the buffer in white
}
else if ( // Else if
y == playerY && // Y equals player y
(
x == 2 || // And x equals 2
x == 3 // Or x equals 3
)
)
{
if (x == 2) // If x equals 2
{
strcat(buff, GREEN " /"); // Append " /" to the buffer in green
}
else if (x == 3) // Else if x equals 3
{
strcat(buff, GREEN "]\\"); // Append "]\" to the buffer in green
}
}
else if ( // Else if
y == playerY + 1 && // Y equals player y + 1
x >= 2 && // And x is greater then or equal to 2
x <= 5 // And x is less then or equal to 5
)
{
switch(x) // Test x
{
case 2: // If 2
strcat(buff, GREEN "<]"); // Append "<]" to the buffer in green
break; // End test
case 3: // If 3
strcat(buff, GREEN "()"); // Append ()"" to the buffer in green
break; // End test
case 4: // If 4
strcat(buff, GREEN "]]"); // Append "]]" to the buffer in green
break; // End test
case 5: // If 5
strcat(buff, GREEN "C>"); // Append "C>" to the buffer in green
break; // End test
}
}
else if ( // Else if
y == playerY + 2 && // Y equals player y + 2
(
x == 2 || // And x equals 2
x == 3 // Or x equals 3
)
)
{
if (x == 2) // If x equals 2
{
strcat(buff, GREEN " \\"); // Append " \" to the buffer in green
}
else if (x == 3) // Else if x equals 3
{
strcat(buff, GREEN "]/"); // Append "]/" to the buffer in green
}
}
else if (IsBullet(x, y)) // Else if X,Y in bullet
{
strcat(buff, RED "()"); // Append "()" to the buffer in red
}
else if ( // Else if
x >= enemy.x && // X is greater then or equal to enemy x
x <= enemy.x + 3 && // And x is less then or equal to enemy x + 3
y == enemy.y // And y equals enemy y
)
{
if (x == enemy.x) // If x equals enemy x
{
strcat(buff, BLUE " <"); // Append " <" to the buffer in blue
}
else if (x == enemy.x + 1) // Else if x equals enemy x + 1
{
strcat(buff, BLUE "( "); // Append "( " to the buffer in blue
}
else if (x == enemy.x + 2) // Else if x equals enemy x + 2
{
strcat(buff, BLUE "[>"); // Append "[>" to the buffer in blue
}
else if (x == enemy.x + 3) // Else if x equals enemy x + 3
{
strcat(buff, YELLOW "C>"); // Append "C>" to the buffer in yellow
}
}
else if ( // Else if
(
x == enemy.x + 1 || // X equals enemy x + 1
x == enemy.x + 2 // Or X equals enemy x + 2
) && // And
y == enemy.y - 1 // Y equals enemy y - 1
)
{
if (x == enemy.x + 1) // If x equals enemy x + 1
{
strcat(buff, BLUE " /"); // Append " /" to the buffer in blue
}
else if (x == enemy.x + 2) // Else if x equals enemy x + 2
{
strcat(buff, BLUE "-|"); // Append "-|" to the buffer in blue
}
}
else if ( // Else if
(
x == enemy.x + 1 || // X equals enemy x + 1
x == enemy.x + 2 // Or X equals enemy x + 2
) && // And
y == enemy.y + 1 // Y equals enemy y + 1
)
{
if (x == enemy.x + 1) // If x equals enemy x + 1
{
strcat(buff, BLUE " \\"); // Append " \" to the buffer in blue
}
else if (x == enemy.x + 2) // Else if x equals enemy x + 2
{
strcat(buff, BLUE "-|"); // Append "-|" to the buffer in blue
}
}
else // Else
{
strcat(buff, NC " "); // Append " " to the buffer in white
}
}
strcat(buff, "\n"); // Append a new line to the buffer
}
printf(buff); // Display the buffer
}
void Start() // Function to setup for the game
{
for (int i = 0; i < 20; i++) // Loop 20 times
{
printf("\n"); // Write a new line
}
pthread_create(&inputThread, NULL, In, NULL); // Make a new thread from the function In
srand(time(0)); // Set the seed for the random number generator to the current UNIX time stamp
SpawnEnemy(); // Spawn a enemy
}
void HitTest() // Function to test for hits
{
if (enemy.x == -1) // If enemy x equals -1
{
exit(0); // End game
}
if (InPlayer()) // If in player
{
exit(0); // End game
}
for (
int i = 0; // Variable to hold the loop count
i < bulletCount; // While i is less then bullet count
i++ // Add 1 to i each loop
)
{
if ( // If
bullets[i].y >= enemy.y - 1 && // Bullet y is greater then or equal to enemy y - 1
bullets[i].y <= enemy.y + 1 && // And bullet y is less then or equal to enemy y + 1
bullets[i].x >= enemy.x && // And bullet x is greater then or equal to enemy x
bullets[i].x <= enemy.x + 2 // And bullet x is less then or equal to enemy x + 2
)
{
SpawnEnemy(); // Spawn enemy
DespawnBullet(i); // Despawn bullet
}
}
}
void SpawnEnemy() // Function to spawn a enemy
{
enemy.y = ((rand() % (16 - 2 + 1)) + 2); // Set enemy y to a random number between 16 and 1
enemy.x = 32; // Set enemy x to 32
}
void SpawnBullet() // Function to spawn a bullet
{
fire = FIRERATE / SPEED; // Set fire to the fire rate devided by the speed = the ammount of frames untill we have passed FIRERATE milliseconds
bullets[bulletCount].x = 6; // Set bullet x to 6
bullets[bulletCount].y = playerY + 1; // Set bullet y to player y + 1
bulletCount++; // Add 1 to bullet count
}
void DespawnBullet(int idx) // Function to despawn bullet at IDX
{
for ( // For
int i = idx; // Variable to hold loop value
i < bulletCount; // While i is less then bullet count
++i // Add 1 to i each loop
)
{
bullets[i] = bullets[i + 1]; // Replace the value of bullet with the value of the next bullet
}
bulletCount--; // Remove 1 from the bullet count
}
int InPlayer() // Function to test if in player
{
if ( // If
enemy.x == 4 && // Enemy x equals 4
enemy.y == playerY + 1 // And enemy y equals player y + 1
)
{
return 1; // Return TRUE
}
if ( // If
enemy.x == 3 && // enemy x equals 3
(
enemy.y == playerY || // And enemy y equals player y
enemy.y == playerY + 2 // Or enemy y equals player y + 2
)
)
{
return 1; // Return TRUE
}
if ( // If
enemy.x == 1 && // Enemy x equals 1
(
enemy.y == playerY + 3 || // And enemy y equals player y + 3
enemy.y == playerY - 1 // Or enemy y equals player y - 1
)
)
{
return 1; // Return TRUE
}
return 0; // Return FALSE
}
int IsBullet(int x, int y) // Function to test if there is a bullet at X,Y
{
for ( // For
int i = 0; // Variable to hold loop count
i < bulletCount; // While i is less then bullet count
i++ // Add 1 to i ever loop
)
{
if ( // If
bullets[i].x == x && // Bullet x equals x
bullets[i].y == y // And bullet y equals y
)
{
return 1; // Return TRUE
}
}
return 0; // Return FALSE
}
int main() // Main entry point
{
Start(); // Setup for the game
while (1) // Loop for ever
{
Move(); // Make any moves
Draw(); // Draw the game
if (fire != 0) // If fire isnt equal to 0
{
fire--; // Remove 1 from fire
}
Sleep(SPEED); // Wait SLEEP milliseconds
}
Draw(); // Draw the game
return 0; // Exit normaly
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment