Sunday 26 July 2015

Invaders with Processing


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--;}
}


No comments:

Post a Comment