mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Added the game snake.
This commit is contained in:
parent
86351d9274
commit
8a085f6fa0
2 changed files with 180 additions and 0 deletions
|
@ -6,6 +6,7 @@ INITRDDIR:=../initrd
|
|||
LOCALBINARIES:=\
|
||||
pong \
|
||||
conway \
|
||||
snake \
|
||||
|
||||
BINARIES:=$(addprefix $(INITRDDIR)/,$(LOCALBINARIES))
|
||||
|
||||
|
|
179
games/snake.cpp
Normal file
179
games/snake.cpp
Normal file
|
@ -0,0 +1,179 @@
|
|||
#include <libmaxsi/platform.h>
|
||||
#include <libmaxsi/io.h>
|
||||
#include <libmaxsi/thread.h>
|
||||
#include <libmaxsi/keyboard.h>
|
||||
#include <libmaxsi/sortix-vga.h>
|
||||
#include <libmaxsi/sortix-keyboard.h>
|
||||
|
||||
using namespace Maxsi;
|
||||
using namespace Maxsi::Keyboard;
|
||||
|
||||
const int width = 80;
|
||||
const int height = 25;
|
||||
|
||||
const int buffersize = height * width;
|
||||
|
||||
System::VGA::Frame* frame;
|
||||
|
||||
int posx;
|
||||
int posy;
|
||||
int velx;
|
||||
int vely;
|
||||
int tailx;
|
||||
int taily;
|
||||
int taillen;
|
||||
int tailmax;
|
||||
int animalx;
|
||||
int animaly;
|
||||
|
||||
char direction[buffersize];
|
||||
|
||||
uint16_t animal = '%' | (COLOR8_RED<<8);
|
||||
uint16_t snake = ' ' | (COLOR8_GREEN<<12);
|
||||
|
||||
// HACK: Sortix has no random number generator yet!
|
||||
int random_seed=1337;
|
||||
int rand(int max)
|
||||
{
|
||||
int tmpmax=max;
|
||||
random_seed = random_seed + 37 * 1103515245 + 12345;
|
||||
return (unsigned int) (random_seed / 65536) % tmpmax;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
// Reset the game data.
|
||||
for ( int i = 0; i < buffersize; i++ ) { frame->text[i] = 0; direction[i] = -1; }
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
Clear();
|
||||
tailx = posx = width/2;
|
||||
taily = posy = height/2;
|
||||
switch ( rand(4) )
|
||||
{
|
||||
case 0: velx = -1; vely = 0; break;
|
||||
case 1: velx = 1; vely = 0; break;
|
||||
case 2: velx = 0; vely = -1; break;
|
||||
case 3: velx = 0; vely = -1; break;
|
||||
}
|
||||
|
||||
animalx = 2 + rand(width-4);
|
||||
animaly = 2 + rand(height-4);
|
||||
|
||||
taillen = 0;
|
||||
tailmax = 3;
|
||||
|
||||
frame->text[animaly * width + animalx] = animal;
|
||||
}
|
||||
|
||||
int Init()
|
||||
{
|
||||
// Create a VGA frame we can render onto.
|
||||
frame = System::VGA::CreateFrame();
|
||||
if ( frame == NULL )
|
||||
{
|
||||
Print("Could not create VGA frame\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
System::VGA::ChangeFrame(frame->fd);
|
||||
|
||||
Reset();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
int newvelx = velx;
|
||||
int newvely = vely;
|
||||
|
||||
// Read the keyboard input from the user.
|
||||
unsigned method = System::Keyboard::POLL;
|
||||
uint32_t codepoint;
|
||||
while ( (codepoint = System::Keyboard::ReceieveKeystroke(method) ) != 0 )
|
||||
{
|
||||
bool keyup = codepoint & DEPRESSED;
|
||||
if ( keyup ) { continue; }
|
||||
codepoint &= ~DEPRESSED;
|
||||
|
||||
if ( codepoint == '\n' ) { Reset(); return; }
|
||||
if ( codepoint == 'w' || codepoint == 'W' ) { newvelx = 0; newvely = -1; }
|
||||
if ( codepoint == 'a' || codepoint == 'A' ) { newvelx = -1; newvely = 0; }
|
||||
if ( codepoint == 's' || codepoint == 'S' ) { newvelx = 0; newvely = 1; }
|
||||
if ( codepoint == 'd' || codepoint == 'D' ) { newvelx = 1; newvely = 0; }
|
||||
}
|
||||
|
||||
// Make sure we don't do a 180.
|
||||
if ( !(velx == -1 && newvelx == 1) &&
|
||||
!(velx == 1 && newvelx == -1) &&
|
||||
!(vely == -1 && newvely == 1) &&
|
||||
!(vely == 1 && newvely == -1) )
|
||||
{
|
||||
velx = newvelx; vely = newvely;
|
||||
}
|
||||
|
||||
// Don't collide with the border!
|
||||
if ( posx + velx < 0 || width <= posx + velx ||
|
||||
posy + vely < 0 || height <= posy + vely ) { Reset(); return; }
|
||||
|
||||
int newx = posx + velx;
|
||||
int newy = posy + vely;
|
||||
|
||||
// Move the tail, if needed.
|
||||
if ( taillen == tailmax )
|
||||
{
|
||||
frame->text[taily * width + tailx] = 0; taillen--;
|
||||
switch ( direction[taily * width + tailx] )
|
||||
{
|
||||
case 0: tailx--; break;
|
||||
case 1: tailx++; break;
|
||||
case 2: taily--; break;
|
||||
case 3: taily++; break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for collision.
|
||||
if ( frame->text[newy * width + newx] == snake ) { Reset(); return; }
|
||||
|
||||
// Check for food.
|
||||
if ( newx == animalx && newy == animaly )
|
||||
{
|
||||
tailmax++;
|
||||
animalx = 2 + rand(width-4);
|
||||
animaly = 2 + rand(height-4);
|
||||
}
|
||||
|
||||
frame->text[animaly * width + animalx] = animal;
|
||||
|
||||
// Remember where we are going.
|
||||
int dir = 0;
|
||||
if ( velx < 0 ) { dir = 0; }
|
||||
if ( velx > 0 ) { dir = 1; }
|
||||
if ( vely < 0 ) { dir = 2; }
|
||||
if ( vely > 0 ) { dir = 3; }
|
||||
direction[posy * width + posx] = dir;
|
||||
|
||||
// Move the head.
|
||||
posx = newx;
|
||||
posy = newy;
|
||||
frame->text[posy * width + posx] = snake; taillen++;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int result = Init();
|
||||
if ( result != 0 ) { return result; }
|
||||
|
||||
// Update the game every 300th milisecond.
|
||||
while ( true )
|
||||
{
|
||||
const int sleepms = 75;
|
||||
Thread::USleep(sleepms * 1000);
|
||||
Update();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Reference in a new issue