Something I did on a boring Sunday afternoon. It's amazing how quickly these things can be done nowadays, as the programming can be extremely lazy. (Cough) I followed a "if it works don't look back" style of programming so obviously it could be a lot shorter and more efficient. I wanted to relax anyway.

I have no idea if it will work smoothly on different computers. The video shows roughly how it plays on my Linux Mint/Mate with 3GHz and a Radeon EAH5750 display adapter. Different Java implementations may result in different sync.

Install Processing, Copy/paste the following onto the sketch and off you go. The arrow keys control the ship. Up arrow is fire. Q resets the game anytime.

// Invaders game by Tero Heikkinen

// left/right arrows - Move

// up arrow - Fire

// q - restart game

// Made in one evening 26.7.2015

int MAXOBJECTS=100;

int []g_x=new int [MAXOBJECTS];

int []g_y=new int [MAXOBJECTS];

int []g_t=new int [MAXOBJECTS];

int []g_vx=new int [MAXOBJECTS];

int []g_vy=new int [MAXOBJECTS];

int []g_score=new int[10];

int g_pulse,g_level,g_aframe;

boolean g_joyr,g_joyl,g_joyf;

void setup()

{

size(600,400);noSmooth();noStroke();fill(255,255,255);

resetgame();

}

void create_wave()

{

int diffi,xon,flip;

float floi;

g_level++;

diffi=g_level;flip=0;

if(diffi>10){diffi=10;}

for(int j=0;j<=3;j++){

for(int i=0;i<=7;i++){

floi=0;

if(g_level==4||g_level==8||g_level==16){

floi=float(i);

}

xon=64*i;

if(g_level==6||g_level==10||g_level==14||g_level==20){xon=64*i+flip*32;}

addobject(xon,32+diffi*16+26*j+int(cos(floi)*16),1,0,2);

}

flip++;if(flip>1){flip=0;}

}

int mzip=-2;

if(random(100)<50){mzip=2;}

//add motherships

addobject(width*2,32,mzip,0,25);

addobject(width*4,32,mzip,0,25);

}

void resetgame()

{

for(int i=0;i<=9;i++){g_score[i]=0;}

clearobjects();g_level=0;

addobject(width/2-16,height-32,0,0,1);

}

void graphic(int x,int y,String gfx)

{

int xc,yc,xp,yp;

xc=0;yc=0;

for (int i=0;i<gfx.length();i++){

if(gfx.charAt(i)=='1'){

xp=x+xc*4;yp=y+yc*2;

if(xp>=0&&xp<=width-4&&yp>=0&&yp<=height-2){

pixels[xp+(yp)*width]=0xffffffff;

pixels[xp+(yp)*width+1]=0xffffffff;

pixels[xp+(yp)*width+2]=0xffffffff;

pixels[xp+(yp)*width+3]=0xffffffff;

}

//rect(x+xc*4,y+yc*2,4,2);

}

xc++;

if(gfx.charAt(i)==' '){xc=0;yc++;}

}

}

void addobject(int x,int y,int vx,int vy,int t)

{

int first;

first=0;

if(t!=1){first=1;}

//alien bullet check fit

if(t==4){

for(int i=0;i<MAXOBJECTS;i++){

if(g_t[i]==2){

if(x>g_x[i]&&x<g_x[i]+24&&y>g_y[i]-4&&y<g_y[i]+16){

return;

}

}

}

}

// add an object

for(int i=first;i<MAXOBJECTS;i++){

if(g_t[i]==0){

g_vx[i]=vx;g_vy[i]=vy;

g_x[i]=x;g_y[i]=y;g_t[i]=t;return;

}

}

}

void clearobjects()

{

for(int i=0;i<MAXOBJECTS;i++){

g_t[i]=0;g_vx[i]=0;g_vy[i]=0;g_x[i]=0;g_y[i]=0;

}

}

void command_fleet(int com)

{

for(int i=0;i<MAXOBJECTS;i++){

if(g_t[i]==2){

if(com<5){

g_vx[i]=com;

g_x[i]=g_x[i]+com;

}

if(com==16&&g_t[0]==1){

g_y[i]=g_y[i]+12;

}

}

}

}

void addscore(int ss)

{

int okay;

okay=0;

g_score[0]=g_score[0]+ss;

while(okay==0){

okay=1;

for(int i=0;i<=9;i++){

if(g_score[i]>9){g_score[i+1]++;g_score[i]=g_score[i]-10;okay=0;}

}

}

}

void drawobjects()

{

int aliens,multip,order;

loadPixels();

aliens=0;multip=1;order=0;

for(int i=0;i<MAXOBJECTS;i++){

if(g_t[i]==2){aliens++;}

}

if(aliens==0){create_wave();}

if(aliens<=9){multip=2;}

if(aliens<=3){multip=3;}

if(aliens==1){multip=4;}

g_aframe=g_aframe+multip;

if(g_aframe>31){g_aframe=g_aframe-32;}

for(int i=0;i<MAXOBJECTS;i++){

switch(g_t[i]){

case 1:

graphic(g_x[i],g_y[i],"00011000 00011000 01111110 00111100 11111111 11111111");

break;

case 2:

if(g_aframe<=15){

graphic(g_x[i],g_y[i],"00000000 11011011 00111100 11011011 11111111 00100100 01100110");

}

else

{

graphic(g_x[i],g_y[i],"10000001 01011010 00111100 11011011 11111111 01000010 11000011");

}

g_x[i]=g_x[i]+g_vx[i]*multip;

g_y[i]=g_y[i]+g_vy[i]*multip;

if(g_y[i]>g_y[0]-16&&g_t[0]==1){g_t[0]=8;}

if(g_x[i]>width-32){order=1;}

if(g_x[i]<=0){order=2;}

aliens++;

int frate;

frate=g_level*multip;

if(frate>200){frate=200;}

if(random(400)<frate){

int zzoo;

zzoo=2;

if(g_level>=4){zzoo=4;}

if(g_level>=8){zzoo=6;}

addobject(g_x[i]+12,g_y[i]+24,0,zzoo,4);

}

break;

case 3:

graphic(g_x[i],g_y[i],"11 11");

if(g_y[i]<0){g_t[i]=0;}

for(int j=0;j<MAXOBJECTS;j++){

if((g_t[j]==2||g_t[j]==25)&&g_x[i]>g_x[j]-8&&g_x[i]<g_x[j]+32&&g_y[i]>g_y[j]&&g_y[i]<g_y[j]+16){addscore(1*g_t[j]);g_t[j]=8;g_t[i]=0;}

}

g_x[i]=g_x[i]+g_vx[i];

g_y[i]=g_y[i]+g_vy[i];

break;

case 4:

graphic(g_x[i],g_y[i],"11 11 11");

if(g_y[i]>height){g_t[i]=0;}

int j=0;

if(g_t[j]==1&&g_x[i]>g_x[j]-6&&g_x[i]<g_x[j]+30&&g_y[i]>g_y[j]&&g_y[i]<g_y[j]+16){g_t[j]=8;g_t[i]=0;}

g_x[i]=g_x[i]+g_vx[i];

g_y[i]=g_y[i]+g_vy[i];

break;

case 8:

graphic(g_x[i],g_y[i],"10010011 01010110 00111100 11000011 0111100 01101010 11001001");

g_vy[i]++;if(g_vy[i]>3){g_vy[i]=0;g_t[i]=9;}

break;

case 9:

graphic(g_x[i],g_y[i],"00000000 01010010 00000000 10000001 0000000 01001010 0000000");

g_vy[i]++;if(g_vy[i]>3){g_vy[i]=0;g_t[i]=0;}

break;

case 25: //mothership

graphic(g_x[i],g_y[i],"00111110 01010101 01111111 00100010 00011100");

g_x[i]=g_x[i]+g_vx[i];

g_y[i]=g_y[i]+g_vy[i];

if(g_x[i]<-32){g_x[i]=width*6;}

if(g_x[i]>width*6){g_x[i]=-32;}

break;

}

}

if(order==1){command_fleet(16);command_fleet(-1);}

if(order==2){command_fleet(16);command_fleet(1);}

if(g_t[0]==0){

graphic(32,16,"00111100 01000010 01000010 01010010 01001010 00111100");

}

scoreboard();

updatePixels();

}

void scoreboard()

{

int s,x,y;

x=96+4*32;y=16;

s=1;

for(int i=0;i<=4;i++){

switch(g_score[i]){

case 0:graphic(x,y,"00111100 01000010 01000010 01000010 01000010 00111100");break;

case 1:graphic(x,y,"00001000 00011000 00101000 00001000 00001000 00111110");break;

case 2:graphic(x,y,"00111100 01000010 00000010 00111110 01000000 01111110");break;

case 3:graphic(x,y,"01111110 00000010 00011100 00000010 01000010 00111100");break;

case 4:graphic(x,y,"00011100 00100100 01000100 01111110 00000100 00000100");break;

case 5:graphic(x,y,"01111110 01000000 01111100 00000010 01000010 00111100");break;

case 6:graphic(x,y,"00111100 01000000 01111110 01000010 01000010 00111100");break;

case 7:graphic(x,y,"01111110 00000010 00011110 00000010 00000100 00001000");break;

case 8:graphic(x,y,"00111100 01000010 00111100 01000010 01000010 00111100");break;

case 9:graphic(x,y,"00111100 01000010 01111110 01000010 00000010 00111100");break;

}

x=x-32;

}

}

void keyPressed()

{

if(key=='q'){resetgame();}

if(key==CODED){

if(keyCode==RIGHT)g_joyr=true;

if(keyCode==LEFT)g_joyl=true;

if(keyCode==UP)g_joyf=true;

}

}

void keyReleased()

{

if(key==CODED){

if(keyCode==RIGHT){g_joyr=false;}

if(keyCode==LEFT){g_joyl=false;}

if(keyCode==UP){g_joyf=false;}

}

}

void draw()

{

background(0,0,0);

drawobjects();

if(g_joyr){if(g_x[0]<width-36){g_x[0]=g_x[0]+4;}}

if(g_joyl){if(g_x[0]>4){g_x[0]=g_x[0]-4;}}

if(g_joyf&&g_pulse==0){g_pulse=10;if(g_t[0]==1){addobject(g_x[0]+12,g_y[0],0,-8,3);}}

if(g_pulse>0){g_pulse--;}

}