/* built with Studio Sketchpad:
* https://sketchpad.cc
*
* observe the evolution of this sketch:
* https://studio.sketchpad.cc/sp/pad/view/ro.0oMiyMgK9QP/rev.107
*
* authors:
* kirk kirkjerk israel
* license (unless otherwise specified):
* creative commons attribution-share alike 3.0 license.
* https://creativecommons.org/licenses/by-sa/3.0/
*/
ArrayList invaders = new ArrayList();
ArrayList bullets = new ArrayList ();
Gunner g = new Gunner();
int level = 1;
int score = -1;
int highscore = 50;
boolean playing = false;
void setup(){
frameRate(30);
size(500,500);
noCursor();
textAlign(CENTER,CENTER);
textFont(loadFont("courier"));
}
void startGame(){
score = 0;
level = 1;
invaders = new ArrayList();
bullets = new ArrayList();
addInvaders();
playing = true;
}
void mouseReleased(){
if(!playing) startGame();
}
void addInvaders(){
for(int i = 0; i< level *5;i++){
invaders.add(new Invader());
}
}
void draw(){
background(100);
text("highscore:"+highscore,0,0,500,50);
if(!playing){
fill(200);
String txt = "manyinvaders\n\n";
if(score != -1) txt += "last score:"+score;
txt += "\n\nclick to play";
text(txt,0,0,500,500);
} else{
text("score:"+score,0,450,100,50);
text("level:"+level,400,450,100,50);
}
int invadersToAdd = 0;
ArrayList bulletsToKill = new ArrayList();
ArrayList invadersToKill = new ArrayList();
if(playing && frameCount % 2 == 0){
bullets.add(new Bullet());
}
for(Invader i : invaders){
i.move();
if(i.tooLow()) invadersToKill.add(i);
if(overlapBox(i,g)){
playing = false;
g.ys = 0;
}
i.draw();
}
for(Bullet b : bullets){
b.move();
if(b.tooHigh()){
bulletsToKill.add(b);
}
for(Invader i : invaders){
if(overlapBox(b,i)){
if(i.alive){
score++;
if(score > highscore) highscore = score;
i.alive = false;
invadersToAdd++;
}
i.hitByBullet();
bulletsToKill.add(b);
}
}
b.draw();
}
g.move();
g.draw();
removeAll(bullets,bulletsToKill);
removeAll(invaders,invadersToKill);
if(playing && invaders.size() <= 0){
level++;
addInvaders();
}
}
void removeAll(ArrayList big, ArrayList bad){
for(Object b : bad){
big.remove(b);
}
}
float IMOVE = .1;
class Invader extends boxish{
float xs,ys;
float cx,cy;
boolean alive = true;
Invader(){
w = random(5,20);
h = random(5,20);
cx = random(0,500);
cy = random(100,400);
x = random(0,500);
y = random(-h,-h-20);
xs = random(-IMOVE*60,IMOVE*60);
ys = random(-IMOVE*60,IMOVE*60);
/* c = color(
random(128,255),
random(128,255),
random(128,255)
);*/
c = color(255,128,0);
}
void hitByBullet(){
ys -= IMOVE* map(w*h,25,400,60,10);
}
boolean tooLow(){
return y > 500;
}
void move(){
if(alive){
if(x < cx) xs += IMOVE;
else xs -= IMOVE;
if(y < cy) ys += IMOVE;
else ys -= IMOVE;
} else ys += IMOVE;
if(x < 0) {
x = 0; xs = abs(xs);
}
if(x > 500-w) {
x = 500-w; xs = -abs(xs);
}
if(y < 0) {
y = 0; ys = abs(ys);
}
if(alive && y > 500-h) {
y = 500-h; ys = -abs(ys);
}
x += xs;
y += ys;
}
void draw(){
if(! alive){
c = color(128,64,0);
}
stroke(c);
strokeWeight(2);
fill(c);
rect(x,y,w,h);
int dir;
if(alive) {
line(x,y+h,x-w*.5,y+h*1.5);
line(x+w,y+h,x+w*1.5,y+h*1.5);
} else {
line(x,y,x-w*.5,y-h*.5);
line(x+w,y,x+w*1.5,y-h*.5);
}
}
}
class Gunner extends boxish{
Gunner(){
super();
w = 40;
h = 20;
c = color(200);
}
float ys;
void move(){
if(playing || score == -1){
y =constrain(mouseY, 300,500-h);
x = constrain(mouseX,0,500-w);
c = color(200);
} else {
y += ys;
ys += .1;
c = color(40);
}
}
}
float BULSPEED = 8;
class Bullet extends boxish{
Bullet(){
super();
w = 10;
h = 10;
x = g.x + g.w / 2 - w / 2;
y = g.y;
}
void move(){
c = color(random(150,250));
y -= BULSPEED;
}
boolean tooHigh(){
return y < -h;
}
}
void mousePressed(){
bullets.add(new Bullet());
}
class boxish{
float w,h,x,y;
color c;
boxish(){
}
void draw(){
noStroke();
fill(c);
rect(x,y,w,h);
}
}
boolean overlapBox(boxish b1, boxish b2){
if(overlapHoriz(b1,b2) && overlapVert(b1,b2)){
return true;
} else {
return false;
}
}
boolean overlapHoriz(boxish b1, boxish b2){
float b1left = b1.x;
float b1right = b1.x+b1.w;
float b2left = b2.x;
float b2right = b2.x+b2.w;
if(b1left < b2left && b1right < b2left) return false;
if(b1left > b2right && b1right > b2right)return false;
return true;
}
boolean overlapVert(boxish b1, boxish b2){
float b1top = b1.y;
float b1bot = b1.y+b1.h;
float b2top = b2.y;
float b2bot = b2.y+b2.h;
if(b1top < b2top && b1bot < b2top) return false;
if(b1top > b2bot && b1bot > b2bot) return false;
return true;
}