[WIP][LGE] SkyBerron Cool Invaders

This is my first game for Little Game Engine.

Press C to toggle experimental horizontal scaling.

  • No scaling

SkyBerron Cool Invaders.bin.1

SkyBerron Cool Invaders.bin.2s

  • Scaling 3:2

SkyBerron Cool Invaders.bin.3

SkyBerron Cool Invaders.bin.4s

  • Scaling 3:2 with interpolation

SkyBerron Cool Invaders.bin.5

SkyBerron Cool Invaders.bin.6s

SkyBerron Cool Invaders.bin (71.0 KB)

4 Likes

That is a nice particle effect.

LGE runs on Pokitto?

LGE does it for you through its builtin particle system.
I suppose it’s just points with position and speed updated using simple explicit forward integration: x += vx; y += vy; vy += gravity

You caught me! :wink: It’s running the same C code… but compiled and linked to SBDL, API calls going through a wrapper API pretty similar to LGE’s. So no VM nor interpreter nor anything fancy going under the hood. Just the bare minimum to get the code running and be able to debug using good old Codeblocks and my own tools on an old PC. It’s much faster and uses less RAM. I could lift some annoying restrictions on sprites and code size screen resolution… but breaking compatability isn’t on my mind :grin:

2 Likes

I’m sorry, I forgot to include the game source code for LGE:

/*settings*{"name":"coolinvaders","author":"skyberron"}*/

// Cool Invaders by SkyBerron, 2020

#define MAX_BULLET_DOWN 48
#define MAX_BULLET_UP 16
#define SPEED_BULLET_DOWN 1
#define SPEED_BULLET_UP 2
#define MAX_DEF 4
#define WDEF 20
#define HDEF 10
#define MIN_XSHIP 1
#define MAX_XSHIP 110
#define MIN_YSHIP 116
#define MAX_YSHIP 119

//16x16
char invader11[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 
0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 
0x00, 0x00, 0x77, 0x77, 0x77, 0x77, 0x00, 0x00, 
0x00, 0x77, 0x76, 0x67, 0x76, 0x67, 0x77, 0x00, 
0x07, 0x77, 0x76, 0x67, 0x76, 0x67, 0x77, 0x70, 
0x07, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 
0x07, 0x76, 0x77, 0x77, 0x77, 0x77, 0x76, 0x70, 
0x07, 0x76, 0x77, 0x77, 0x77, 0x77, 0x76, 0x70, 
0x07, 0x77, 0x66, 0x66, 0x66, 0x66, 0x67, 0x70, 
0x00, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x00, 
0x00, 0x07, 0x77, 0x77, 0x77, 0x77, 0x70, 0x00, 
0x00, 0x00, 0x07, 0x00, 0x00, 0x70, 0x00, 0x00, 
0x00, 0x77, 0x70, 0x00, 0x00, 0x07, 0x77, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

//16x16
char invader12[] = {
0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 
0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 
0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 
0x00, 0x00, 0x77, 0x77, 0x77, 0x77, 0x00, 0x00, 
0x00, 0x77, 0x76, 0x67, 0x76, 0x67, 0x77, 0x00, 
0x07, 0x77, 0x76, 0x67, 0x76, 0x67, 0x77, 0x70, 
0x07, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 
0x07, 0x76, 0x77, 0x77, 0x77, 0x77, 0x76, 0x70, 
0x07, 0x76, 0x77, 0x77, 0x77, 0x77, 0x76, 0x70, 
0x07, 0x77, 0x66, 0x66, 0x66, 0x66, 0x67, 0x70, 
0x00, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x00, 
0x00, 0x07, 0x77, 0x77, 0x77, 0x77, 0x70, 0x00, 
0x00, 0x00, 0x07, 0x00, 0x00, 0x70, 0x00, 0x00, 
0x00, 0x00, 0x70, 0x00, 0x00, 0x07, 0x00, 0x00, 
0x00, 0x77, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};


//16x16
char invader21[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 
0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 
0x00, 0x00, 0xee, 0xee, 0xee, 0xee, 0x00, 0x00, 
0x00, 0xee, 0xe6, 0x6e, 0xe6, 0x6e, 0xee, 0x00, 
0x0e, 0xee, 0xe6, 0x6e, 0xe6, 0x6e, 0xee, 0xe0, 
0x0e, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe0, 
0x0e, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe0, 
0x0e, 0xe6, 0xee, 0xee, 0xee, 0xee, 0xe6, 0xe0, 
0x0e, 0xee, 0x66, 0x66, 0x66, 0x66, 0x6e, 0xe0, 
0x00, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x00, 
0x00, 0x0e, 0xee, 0xee, 0xee, 0xee, 0xe0, 0x00, 
0x00, 0x00, 0x0e, 0x00, 0x00, 0xe0, 0x00, 0x00, 
0x00, 0xee, 0xe0, 0x00, 0x00, 0x0e, 0xee, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

//16x16
char invader22[] = {
0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 
0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 
0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 
0x00, 0x00, 0xee, 0xee, 0xee, 0xee, 0x00, 0x00, 
0x00, 0xee, 0xe6, 0x6e, 0xe6, 0x6e, 0xee, 0x00, 
0x0e, 0xee, 0xe6, 0x6e, 0xe6, 0x6e, 0xee, 0xe0, 
0x0e, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe0, 
0x0e, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe0, 
0x0e, 0xe6, 0xee, 0xee, 0xee, 0xee, 0xe6, 0xe0, 
0x0e, 0xee, 0x66, 0x66, 0x66, 0x66, 0x6e, 0xe0, 
0x00, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x00, 
0x00, 0x0e, 0xee, 0xee, 0xee, 0xee, 0xe0, 0x00, 
0x00, 0x00, 0x0e, 0x00, 0x00, 0xe0, 0x00, 0x00, 
0x00, 0x00, 0xe0, 0x00, 0x00, 0x0e, 0x00, 0x00, 
0x00, 0xee, 0x00, 0x00, 0x00, 0x00, 0xee, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};


//16x16
char invader31[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 
0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 
0x00, 0x00, 0x88, 0x88, 0x88, 0x88, 0x00, 0x00, 
0x00, 0x88, 0x86, 0x68, 0x86, 0x68, 0x88, 0x00, 
0x08, 0x88, 0x86, 0x68, 0x86, 0x68, 0x88, 0x80, 
0x08, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x80, 
0x08, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x80, 
0x08, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x80, 
0x08, 0x88, 0x66, 0x66, 0x66, 0x66, 0x68, 0x80, 
0x00, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x00, 
0x00, 0x08, 0x88, 0x88, 0x88, 0x88, 0x80, 0x00, 
0x00, 0x00, 0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 
0x00, 0x88, 0x80, 0x00, 0x00, 0x08, 0x88, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

//16x16
char invader32[] = {
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 
0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 
0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 
0x00, 0x00, 0x88, 0x88, 0x88, 0x88, 0x00, 0x00, 
0x00, 0x88, 0x86, 0x68, 0x86, 0x68, 0x88, 0x00, 
0x08, 0x88, 0x86, 0x68, 0x86, 0x68, 0x88, 0x80, 
0x08, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x80, 
0x08, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x80, 
0x08, 0x88, 0x88, 0x88, 0x88, 0x88, 0x86, 0x80, 
0x08, 0x88, 0x66, 0x66, 0x66, 0x66, 0x68, 0x80, 
0x00, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x00, 
0x00, 0x08, 0x88, 0x88, 0x88, 0x88, 0x80, 0x00, 
0x00, 0x00, 0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 
0x00, 0x00, 0x80, 0x00, 0x00, 0x08, 0x00, 0x00, 
0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};


//16x16
char invader41[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 
0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 
0x00, 0xff, 0xf6, 0x66, 0xf6, 0x66, 0xff, 0x00, 
0x0f, 0xff, 0xff, 0x66, 0xff, 0x66, 0xff, 0xf0, 
0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 
0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xf0, 
0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xf0, 
0x0f, 0xff, 0x66, 0x66, 0x66, 0x66, 0x6f, 0xf0, 
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 
0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 
0x00, 0x00, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x00, 
0x00, 0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

//16x16
char invader42[] = {
0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 
0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 
0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 
0x00, 0xff, 0xf6, 0x66, 0xf6, 0x66, 0xff, 0x00, 
0x0f, 0xff, 0xff, 0x66, 0xff, 0x66, 0xff, 0xf0, 
0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 
0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xf0, 
0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xf0, 
0x0f, 0xff, 0x66, 0x66, 0x66, 0x66, 0x6f, 0xf0, 
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 
0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 
0x00, 0x00, 0x0f, 0x00, 0x00, 0xf0, 0x00, 0x00, 
0x00, 0x00, 0xf0, 0x00, 0x00, 0x0f, 0x00, 0x00, 
0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};


//16x16
char invader51[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 
0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 
0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 
0x00, 0xaa, 0xa6, 0x6a, 0xa6, 0x6a, 0xaa, 0x00, 
0x0a, 0xaa, 0xa6, 0x6a, 0xa6, 0x6a, 0xaa, 0xa0, 
0x0a, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa0, 
0x0a, 0xa6, 0xaa, 0xaa, 0xaa, 0xaa, 0xa6, 0xa0, 
0x0a, 0xa6, 0xaa, 0xaa, 0xaa, 0xaa, 0xa6, 0xa0, 
0x0a, 0xaa, 0x66, 0x66, 0x66, 0x66, 0x6a, 0xa0, 
0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 
0x00, 0x0a, 0xaa, 0xaa, 0xaa, 0xaa, 0xa0, 0x00, 
0x00, 0x00, 0x0a, 0x00, 0x00, 0xa0, 0x00, 0x00, 
0x00, 0xaa, 0xa0, 0x00, 0x00, 0x0a, 0xaa, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

//16x16
char invader52[] = {
0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 
0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 
0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 
0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 
0x00, 0xaa, 0xa6, 0x6a, 0xa6, 0x6a, 0xaa, 0x00, 
0x0a, 0xaa, 0xa6, 0x6a, 0xa6, 0x6a, 0xaa, 0xa0, 
0x0a, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa0, 
0x0a, 0xa6, 0xaa, 0xaa, 0xaa, 0xaa, 0xa6, 0xa0, 
0x0a, 0xa6, 0xaa, 0xaa, 0xaa, 0xaa, 0xa6, 0xa0, 
0x0a, 0xaa, 0x66, 0x66, 0x66, 0x66, 0x6a, 0xa0, 
0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 
0x00, 0x0a, 0xaa, 0xaa, 0xaa, 0xaa, 0xa0, 0x00, 
0x00, 0x00, 0x0a, 0x00, 0x00, 0xa0, 0x00, 0x00, 
0x00, 0x00, 0xa0, 0x00, 0x00, 0x0a, 0x00, 0x00, 
0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};



int tinvader[] = {
	invader11, invader12,
	invader21, invader22,
	invader31, invader32,
	invader41, invader42,
	invader51, invader52,
	invader11, invader12,
	invader21, invader22,
	invader31, invader32
};


//16x8
char ship[] = {
0x00, 0x00, 0x00, 0x0d, 0xd0, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0xd5, 0x5d, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x0d, 0x55, 0x55, 0xd0, 0x00, 0x00, 
0x0d, 0xdd, 0xd5, 0x55, 0x55, 0x5d, 0xdd, 0xd0, 
0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x5d, 
0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x5d, 
0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x5d, 
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd
};

//16x8
char dead_ship[] = {
0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x70, 0xa0, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x07, 0xa0, 0xaa, 0x70, 0x00, 0x00, 
0x07, 0x07, 0x0a, 0xaa, 0x0a, 0xa7, 0x07, 0x00, 
0x7a, 0x0a, 0xa0, 0xaa, 0x0a, 0xaa, 0x0a, 0xa0, 
0x70, 0xaa, 0xa0, 0xa0, 0xa0, 0x0a, 0xa0, 0xa7, 
0x70, 0xaa, 0xaa, 0x0a, 0xaa, 0xa0, 0xa0, 0xa7, 
0x07, 0x77, 0x77, 0x07, 0x77, 0x70, 0x77, 0x07
};


//20x10
char barrier[] = {
0x00, 0x03, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x30, 0x00, 
0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x00, 
0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x30, 
0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x30, 
0x3f, 0xff, 0xff, 0x33, 0x33, 0x33, 0x33, 0xff, 0xff, 0xf3, 
0x3f, 0xff, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xf3, 
0x3f, 0xff, 0x30, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf3, 
0x3f, 0xff, 0x30, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf3, 
0x3f, 0xff, 0x30, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf3, 
0x33, 0x33, 0x30, 0x00, 0x00, 0x00, 0x00, 0x03, 0x33, 0x33
};

//32x32
char saturn[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xbb, 0xb0, 0x00, 0x00, 0x00, 0x99, 0x99, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xbb, 0xbb, 0xbb, 0xb0, 0x00, 0x09, 0x99, 0x99, 0x90, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb0, 0x00, 0x09, 0x99, 0x99, 
0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x00, 0x00, 0x99, 0x99, 
0x00, 0x00, 0x00, 0x00, 0x0b, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb0, 0x00, 0x99, 0x99, 
0x00, 0x00, 0x00, 0x00, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x09, 0x99, 0x99, 
0x00, 0x00, 0x00, 0x00, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x99, 0x99, 0x90, 
0x00, 0x00, 0x00, 0x0b, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb9, 0x99, 0x99, 0x90, 
0x00, 0x00, 0x00, 0x0b, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x99, 0x99, 0x99, 0x00, 
0x00, 0x00, 0x00, 0x0b, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb9, 0x99, 0x99, 0x90, 0x00, 
0x00, 0x00, 0x00, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb9, 0x99, 0x99, 0x99, 0x00, 0x00, 
0x00, 0x00, 0x00, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x99, 0x99, 0x99, 0x9b, 0x00, 0x00, 
0x00, 0x00, 0x00, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x99, 0x99, 0x99, 0x99, 0xbb, 0x00, 0x00, 
0x00, 0x00, 0x00, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x99, 0x99, 0x99, 0x99, 0x9b, 0xbb, 0x00, 0x00, 
0x00, 0x09, 0x90, 0x0b, 0xbb, 0xbb, 0xbb, 0xb9, 0x99, 0x99, 0x99, 0x9b, 0xbb, 0xbb, 0x00, 0x00, 
0x00, 0x99, 0x90, 0x0b, 0xbb, 0xbb, 0xb9, 0x99, 0x99, 0x99, 0x99, 0xbb, 0xbb, 0xb0, 0x00, 0x00, 
0x09, 0x99, 0x00, 0x00, 0xbb, 0x99, 0x99, 0x99, 0x99, 0x99, 0xbb, 0xbb, 0xbb, 0xb0, 0x00, 0x00, 
0x09, 0x99, 0x90, 0x00, 0x99, 0x99, 0x99, 0x99, 0x99, 0xbb, 0xbb, 0xbb, 0xbb, 0x00, 0x00, 0x00, 
0x09, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9b, 0xbb, 0xbb, 0xbb, 0xb0, 0x00, 0x00, 0x00, 
0x09, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x99, 0x99, 0x99, 0x99, 0x9b, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb0, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x99, 0x99, 0x90, 0x00, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xbb, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

//64x16
char game_over[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x06, 0x66, 0x60, 0x00, 0x00, 0x66, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x66, 0x66, 0x66, 0x00, 0x00, 0x06, 0x66, 0x00, 0x60, 0x00, 0x60, 0x66, 0x66, 0x66, 0x60, 0x66, 0x66, 0x00, 0x00, 
0x00, 0x67, 0x77, 0x76, 0x00, 0x06, 0x77, 0x60, 0x00, 0x67, 0x60, 0x67, 0x66, 0x77, 0x77, 0x77, 0x60, 0x00, 0x67, 0x77, 0x60, 0x76, 0x06, 0x76, 0x77, 0x77, 0x77, 0x76, 0x77, 0x77, 0x60, 0x00, 
0x06, 0x77, 0x66, 0x67, 0x60, 0x67, 0x77, 0x76, 0x00, 0x67, 0x76, 0x77, 0x60, 0x67, 0x66, 0x77, 0x60, 0x06, 0x76, 0x67, 0x76, 0x77, 0x66, 0x76, 0x67, 0x66, 0x67, 0x76, 0x76, 0x66, 0x76, 0x00, 
0x67, 0x66, 0x00, 0x06, 0x00, 0x67, 0x66, 0x76, 0x00, 0x67, 0x76, 0x77, 0x60, 0x67, 0x66, 0x66, 0x00, 0x06, 0x76, 0x06, 0x76, 0x67, 0x66, 0x76, 0x67, 0x66, 0x66, 0x66, 0x76, 0x66, 0x76, 0x00, 
0x67, 0x60, 0x06, 0x66, 0x06, 0x77, 0x66, 0x76, 0x00, 0x67, 0x77, 0x77, 0x60, 0x67, 0x77, 0x76, 0x00, 0x06, 0x76, 0x06, 0x76, 0x67, 0x66, 0x76, 0x67, 0x77, 0x76, 0x06, 0x76, 0x77, 0x60, 0x00, 
0x67, 0x60, 0x67, 0x77, 0x66, 0x77, 0x66, 0x77, 0x60, 0x67, 0x67, 0x67, 0x60, 0x67, 0x76, 0x60, 0x00, 0x67, 0x76, 0x06, 0x76, 0x06, 0x77, 0x60, 0x67, 0x76, 0x60, 0x06, 0x77, 0x76, 0x00, 0x00, 
0x67, 0x76, 0x66, 0x77, 0x66, 0x77, 0x77, 0x77, 0x66, 0x77, 0x66, 0x67, 0x76, 0x67, 0x76, 0x06, 0x00, 0x67, 0x60, 0x06, 0x76, 0x06, 0x77, 0x60, 0x67, 0x76, 0x06, 0x66, 0x77, 0x77, 0x60, 0x00, 
0x06, 0x77, 0x66, 0x77, 0x67, 0x77, 0x66, 0x77, 0x76, 0x76, 0x00, 0x06, 0x76, 0x67, 0x76, 0x67, 0x60, 0x67, 0x76, 0x67, 0x76, 0x06, 0x76, 0x60, 0x67, 0x76, 0x67, 0x76, 0x76, 0x67, 0x76, 0x00, 
0x00, 0x67, 0x77, 0x76, 0x67, 0x77, 0x66, 0x77, 0x76, 0x76, 0x00, 0x06, 0x76, 0x77, 0x77, 0x77, 0x60, 0x06, 0x77, 0x77, 0x60, 0x06, 0x76, 0x06, 0x77, 0x77, 0x77, 0x76, 0x76, 0x06, 0x77, 0x60, 
0x00, 0x06, 0x66, 0x60, 0x06, 0x66, 0x00, 0x66, 0x60, 0x60, 0x00, 0x00, 0x60, 0x66, 0x66, 0x66, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x60, 0x00, 0x66, 0x66, 0x66, 0x60, 0x60, 0x00, 0x66, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

int level = 0;
int score = 0;
int xship;
int yship;
char game, count, key, dead;
int inv_cols;
int inv_rows;
int inv_xsep;
int inv_ysep;
int xinv;
int yinv;
int ixinv;
int iyinv;
int timer_move;
int timer_shoot;
int timer_cooldown;
int ydef;

// x, y
char tbulletdown[MAX_BULLET_DOWN][2];
char tbulletup[MAX_BULLET_UP][2];
int cbulletdown = 0;
int cbulletup = 0;


void init(){
	
	dead = 0;
	xship = 64;
	yship = 118;
	xinv = 0;
	yinv = 0;
	ixinv = 1;
	iyinv = 0;

	timer_move = 200 - 10 * level;
	timer_shoot = 1000 - 50 * level;
	timer_cooldown = 800 - 10 * level;
	
	inv_cols = 6;
	inv_rows = 5;
	inv_xsep = 112;
	inv_ysep = 80;

	if( timer_move < 100 )
		timer_move = 100;
	if( timer_shoot < 100 )
		timer_shoot = 100;
	if( timer_cooldown < 100 )
		timer_cooldown = 100;
	
	setframerate(30);
	clearscreen();	
	game = 1;
	count = inv_rows * inv_cols;
	setparticle(2, 10, 500);
	setemitter(100, 220, 320, 6 );

	int i = 0;
	for( int irow = 0; irow < inv_rows; irow++ ){
		for( int icol = 0; icol < inv_cols; icol++ ){
			int x = xinv + icol * inv_xsep / inv_cols;
			int y = irow * inv_ysep / inv_rows;
			getsprite(i, invader11);
			spritesetvalue(i, S_WIDTH, 16);
			spritesetvalue(i, S_HEIGHT, 16);
			spritesetvalue(i,S_LIVES,1);
			putsprite(i, x, y);
			i++;
		}
	}
	count = i;
	getsprite(31, ship);
	spritesetvalue(31, S_WIDTH, 16);
	spritesetvalue(31, S_HEIGHT, 8);
	putsprite( 31, xship, yship );
	
	cbulletdown = 0;
	cbulletup = 0;
	
	for( int idef = 0; idef < MAX_DEF; idef++ ) {
		int x = ( WDEF >> 1 ) + idef * ( 128 - ( WDEF << 1 ) ) / ( MAX_DEF - 1 );
		int y = 128 - 14 - HDEF;
		putimage( barrier, x, y, 20, 10 );
	}
	ydef = 128 - 14 - HDEF - 16;

	settimer( 0, timer_move );
	settimer( 1, timer_shoot );
	settimer( 2, timer_cooldown );
}


void update_bullet() {
	int remove;
	for( int ibullet = 0; ibullet < cbulletdown; ) {
		int xbullet = tbulletdown[ibullet][0];
		int ybullet = tbulletdown[ibullet][1];
		ybullet += SPEED_BULLET_DOWN;
		tbulletdown[ibullet][1] = ybullet;
		remove = 0;
		if( ybullet >= 128 ) {
			remove = 1;
		} else if( ybullet > ydef && ybullet < 120 ) {
			if( getpixel( xbullet, ybullet + 3 ) > 0 ) {
				fillrect( xbullet, ybullet, xbullet, ybullet + 4 );
				remove = 1;
			}
		}
		if( ( xbullet >= xship ) && ( xbullet < xship + 16 ) && ( ybullet >= yship - 1 ) && ( ybullet < yship + 8 ) ) {
			dead = 1;
			remove = 1;
		}
		
		if( remove ) {
			for( int k = ibullet + 1; k < cbulletdown; k++ ) {
				tbulletdown[k-1][0] = tbulletdown[k][0];
				tbulletdown[k-1][1] = tbulletdown[k][1];
			}
			cbulletdown--;
		} else {
			ibullet++;
		}
	}
	for( int ibullet = 0; ibullet < cbulletup; ) {
		int xbullet = tbulletup[ibullet][0];
		int ybullet = tbulletup[ibullet][1];
		ybullet -= SPEED_BULLET_UP;
		tbulletup[ibullet][1] = ybullet;
		
		remove = 0;
		if( ybullet < 0 ) {
			remove = 1;
		} else if( ybullet > ydef && ybullet < 120 ) {
			if( getpixel( xbullet, ybullet - 1 ) > 0 ) {
				fillrect( xbullet, ybullet - 1, xbullet, ybullet );
				remove = 1;
			}
		}
		
		if( remove ) {
			for( int k = ibullet + 1; k < cbulletup; k++ ) {
				tbulletup[k-1][0] = tbulletup[k][0];
				tbulletup[k-1][1] = tbulletup[k][1];
			}
			cbulletup--;
		} else {
			ibullet++;
		}
	}
}

void draw_bullet_down() {
	for( int ibullet = 0; ibullet < cbulletdown; ibullet++ ) {
		int xbullet = tbulletdown[ibullet][0];
		int ybullet = tbulletdown[ibullet][1];
		fillrect( xbullet, ybullet, xbullet, ybullet + 3 );
	}
}

void draw_bullet_up() {
	for( int ibullet = 0; ibullet < cbulletup; ibullet++ ) {
		int xbullet = tbulletup[ibullet][0];
		int ybullet = tbulletup[ibullet][1];
		fillrect( xbullet, ybullet, xbullet, ybullet + 3 );
	}
}

void add_bullet_down( int xbullet, int ybullet ) {
	if( cbulletdown < MAX_BULLET_DOWN ) {
		int ibullet = cbulletdown;
		tbulletdown[ibullet][0] = xbullet;
		tbulletdown[ibullet][1] = ybullet;
		cbulletdown++;
	}
}

void add_bullet_up( int xbullet, int ybullet ) {
	if( cbulletup < MAX_BULLET_UP ) {
		int ibullet = cbulletup;
		tbulletup[ibullet][0] = xbullet;
		tbulletup[ibullet][1] = ybullet;
		cbulletup++;
	}
}


void update_invader() {
	int i = 0;
	int xmin = 128;
	int xmax = 0;
	int ymin = 128;
	int ymax = 0;
	int r;
	int a = 0;
	int xshoot = 0;
	int yshoot = 0;
	int xbullet;
	int ybullet;
	int xinvmin;
	int xinvmax;
	
	r = random( count - 1 );
	
	for( int irow = 0; irow < inv_rows; irow++ ){
		for( int icol = 0; icol < inv_cols; icol++ ){
			int lives = spritegetvalue( i, S_LIVES );
			if( lives > 0 ) {
				int x = xinv + icol * inv_xsep / inv_cols;
				int y = yinv + irow * inv_ysep / inv_rows;
				if( xmin > x ) {
					xmin = x;
				}
				if( xmax < x ) {
					xmax = x;
				}
				if( ymin > y ) {
					ymin = y;
				}
				if( ymax < y ) {
					ymax = y;
				}
				int s = 2 * irow + ( x & 1 );
				getsprite(i, tinvader[ s ] );
				putsprite(i, x, y);
				if( a == r ) {
					xshoot = x + 8;
					yshoot = y + 8;
				}
				a++;
				
				for( int ibullet = 0; ibullet < cbulletup; ) {
					xbullet = tbulletup[ibullet][0];
					ybullet = tbulletup[ibullet][1];
					if( ( xbullet >= x + 1 ) && ( xbullet < x + 15 ) && ( ybullet >= y ) && ( ybullet < y + 12 ) ) {
						spritesetvalue( i, S_LIVES, 0 );
						count--;
						drawparticle( x + 8, y + 8, 7 );
						score++;
						for( int k = ibullet + 1; k < cbulletup; k++ ) {
							tbulletup[k-1][0] = tbulletup[k][0];
							tbulletup[k-1][1] = tbulletup[k][1];
						}
						cbulletup--;		
					} else {
						ibullet++;
					}
				}
			}
				
			i++;
		}
	}
	if( gettimer( 0 ) <= 0 ) {
		xinvmin = 0 - ( xmin - xinv );
		xinvmax = 128 - 16 - ( xmax - xinv );

		xinv += ixinv;
		if( ixinv > 0 ) {
			if( xinv > xinvmax ) {
				xinv = xinvmax;
				yinv += 3;
				ixinv = -1;
				timer_move -= 1;
			}
		}
		else {
			if( xinv < xinvmin ) {
				xinv = xinvmin;
				yinv += 3;
				ixinv = 1;
				timer_move -= 1;
			}
		}
		if( timer_move < 100 )
			timer_move = 100;		
		settimer( 0, timer_move );
	}
	if( gettimer( 1 ) <= 0 ) {
		settimer( 1, timer_shoot );
		add_bullet_down( xshoot, yshoot );
	}
	if( ymax >= ydef ) {
		fillrect( 0, 128 - 14 - HDEF, 127, 127 );
		ydef = 1000;
	}
	if( ymax >= 128 - 24 ) {
		dead = 1;
	}
}

void gameover(){
	gotoxy(4, 7);
	if(count == 0) {
		puts("Level Cleared!!!");
		level++;
	} else {
		//puts("game over");
		drawparticle( xship + 8, yship + 4, 7 );
		getsprite(31, dead_ship);
		getsprite( 30, game_over );
		spritesetvalue( 30, S_WIDTH, 64 );
		spritesetvalue( 30, S_HEIGHT, 16 );
		spritesetvalue( 30, S_LIVES, 1 );
		putsprite( 30, 32, 48 );
		level = 0;
		score = 0;
	}
	settimer(1,1000);
	while(gettimer(1)){}
	while(getkey() != 0){}
	while(getkey() == 0){}
	spritesetvalue( 30, S_LIVES, 0 );
	init();
}


void main(){
	while(1){
		init();
		while(game){
			key = getkey();
			int x = xship;
			int y = yship;
			if( key & KEY_LEFT ) {
				x -= 3;
				spritesetvalue(31, S_FLIP_HORIZONTAL, 0 );
			}
			if( key & KEY_RIGHT ) {
				x += 3;
				spritesetvalue(31, S_FLIP_HORIZONTAL, 1 );
			}
			if( key & KEY_UP ) {
				y -= 3;
			}
			if( key & KEY_DOWN ) {
				y += 3;
			}
			if( key & KEY_A ) {
				if( gettimer( 2 ) <= 0 ) {
					settimer( 2, timer_cooldown );
					add_bullet_up( xship + 8, yship );
				}
			}

			if( x < MIN_XSHIP ) {
				x = MIN_XSHIP;
			}
			if( x > MAX_XSHIP ) {
				x = MAX_XSHIP;
			}
			if( y < MIN_YSHIP ) {
				y = MIN_YSHIP;
			}
			if( y > MAX_YSHIP ) {
				y = MAX_YSHIP;
			}
			
			xship = x;
			yship = y;

			putsprite(31, xship, yship);

			setcolor( 0 );
			draw_bullet_down();
			draw_bullet_up();

			update_invader();
			update_bullet();
			
			putimage( saturn, 8, 8, 32, 32 );
			
			setcolor( 1 );
			draw_bullet_down();
			setcolor( 8 );
			draw_bullet_up();

			setcolor( 3 );
			gotoxy( 0, 0 );
			printf( "S: %i", score );
			gotoxy( 16, 0 );
			printf( "L: %i", level+1 );
			setcolor( 1 );
			
			if( ( count == 0 ) || ( dead > 0 ) )
				gameover();
					
			delayredraw();
		}
	}
}

Just copy/paste into the code editor, it’s easy :wink:: https://corax89.github.io/esp8266Game/index.html

2 Likes

Works in the Pokitto HW too. I could not get to scale. Also, the binary is in dev mode, which means that you cannot any more launch a loader for loading other games.

Thanks, I can’t tell if something works on hw. I know there are reports about emulation speed being different than real hw speed, specially with alt system clock settings. And I wasn’t aware MinLib was using higher osc multiplier till recently (I don’t RTFM, sorry). I haven’t come to implement timers nor audio output so there’s no frame rate cap. I’m working only with (emulated) MCU and (emulated) display controller. Tbh, SBDL lower layer abstracts me from hw so I don’t have to go low level any more: if it works in my recent Codeblocks SDL2 Windows frontend, then it compiles fine on Femtoide and also works in the emulator. I’m still deciding on going further with timers and audio, but I’m not sure if it’s worth the effort for many reasons.
About the binary being in dev mode, I have read somewhere that keeping pressed one button (which?) at power up launches bootloader. I can’t check that on emulator, but I haven’t altered MinLib in any ways, so if the code is there, it should work. If not, I’m open to include it, as long as someone provides the magic source code lines for that functionality and doesn’t interfere with my coding.
Running binaries on the emulator is just ok for me, I’m not here for the games (which I don’t play) nor the hw, just for the fun of coding a MCU with limited resources and learning, which it’s what I’m doing. I’d like to have a better and more accurate emulator (and support for my XBox One game controller, which does not work), but it suits my needs as it is now. If I’ve ever complained about the hw (I did!), I’m deeply sorry… that’s a byproduct of coding frustration, I suppose.
I have ordered a new nice looking little device: CircuitMess Nibble, which is arriving today. I bought it at discount for my son. So a new adventure starts now. Wish me luck!
If anyone is interested: https://www.circuitmess.com/nibble/
https://community.circuitmess.com/t/new-game-console-nibble/3575

2 Likes

Oh, I did not remember you are using MinLib. There can be a different way to start the launcher. I have not used it myself.

Otherwise the demo works well in HW. It is always fun to see what you have implemented :slight_smile: