/* built with Studio Sketchpad:
* https://sketchpad.cc
*
* observe the evolution of this sketch:
* https://studio.sketchpad.cc/sp/pad/view/ro.ZZ$PxobyAxg/rev.1128
*
* authors:
*
* Tanya Tasheva
*
* license (unless otherwise specified):
* creative commons attribution-share alike 3.0 license.
* https://creativecommons.org/licenses/by-sa/3.0/
*/
/* @pjs preload="/static/uploaded_resources/p.22229/Ship.png"; */
/* @pjs preload="/static/uploaded_resources/p.22229/Green0.png"; */
/* @pjs preload="/static/uploaded_resources/p.22229/Green1.png"; */
/* @pjs preload="/static/uploaded_resources/p.22229/Green2.png"; */
/* @pjs preload="/static/uploaded_resources/p.22229/BGstart.png"; */
/* @pjs preload="/static/uploaded_resources/p.22229/BGOver.png"; */
/* @pjs preload="/static/uploaded_resources/p.22229/BG.png"; */
/* @pjs preload="/static/uploaded_resources/p.22229/Transition.png"; */
/* @pjs preload="/static/uploaded_resources/p.22229/Bullet.png"; */
/* @pjs preload="/static/uploaded_resources/p.22229/Purple.png"; */
/* @pjs preload="/static/uploaded_resources/p.22229/Purple1.png"; */
/* @pjs preload="/static/uploaded_resources/p.22229/Purple2.png"; */
PImage bgstart;
PImage bgtrans;
PImage bgover;
Ship ship;
boolean upPressed = false;//CHANGE LEFT AND RIGHT TO UP AND DOWN( IN SHIP TOO)
boolean downPressed = false;
boolean aPressed = false;
boolean dPressed = false;
int score;
int highscore = 0;
float shipSpeed = 2;
float rotationAngle = .2;
float bulletSpeed = 10;
int numAsteroids = 1;
int numPurple = 1;
int startingRadius = 50;
PImage[] asteroidPics = new PImage[3];
PImage[] purplePics = new PImage[3];
float bgColor = 0;
PImage rocket;
ArrayList<Exhaust> exhaust;
ArrayList<Exhaust> fire;
ArrayList<Bullet> bullets;
ArrayList<Asteroid> asteroids;
ArrayList<Purple> purple;
PFont font;
int darkCounter;
int darkCounterLimit = 24*2;
int MAX_LIVES = 3;
int lives;
int stage = -1;
int diffCurve = 2;
void setup(){
size(800,500);
bgstart = loadImage("/static/uploaded_resources/p.22229/BGstart.png");
bgover = loadImage("/static/uploaded_resources/p.22229/BGOver.png");
bgtrans = loadImage("/static/uploaded_resources/p.22229/Transition.png");
BG = loadImage("/static/uploaded_resources/p.22229/BG.png");
font = createFont("Montserrat-ExtraBold", 32);
asteroidPics[0] = loadImage("/static/uploaded_resources/p.22229/Green0.png");
asteroidPics[1] = loadImage("/static/uploaded_resources/p.22229/Green1.png");
asteroidPics[2] = loadImage("/static/uploaded_resources/p.22229/Green2.png");
purplePics[0] = loadImage("/static/uploaded_resources/p.22229/Purple.png");
purplePics[1] = loadImage("/static/uploaded_resources/p.22229/Purple1.png");
purplePics[2] = loadImage("/static/uploaded_resources/p.22229/Purple2.png");
rocket = loadImage("/static/uploaded_resources/p.22229/Ship.png");
frameRate(24);
lives = 3;
score=0;
asteroids = new ArrayList<Asteroid>(0);
purple = new ArrayList<Purple>(0);
}
void draw(){
if( (lives >= 0 && asteroids.size()>0) && (lives >= 0 && purple.size()>0) ){
float theta = heading2D(ship.rotation)+PI/2;
background(BG);
fill(255)
textFont(font, 15);
text("Score: " + score, 700,40);
ship.update(exhaust, fire);
ship.edges();
ship.render();
if(ship.checkCollision(asteroids)){
lives--;
ship = new Ship();
}
if(ship.checkCollision(purple)){
lives--;
ship = new Ship();
}
if(aPressed){
rotate2D(ship.rotation,-rotationAngle);
//ellipse(1000,800,400,800);
}
if(dPressed){
rotate2D(ship.rotation, rotationAngle);
}
if(upPressed){
ship.acceleration = new PVector(0,shipSpeed);
rotate2D(ship.acceleration, theta);
}
for(Exhaust e: exhaust){
e.update();
e.render();
}
for(Exhaust e: fire){
e.update();
e.render();
}
for(int i = 0; i < bullets.size(); i++){
bullets.get(i).edges();
if(bullets.get(i).update()){
bullets.remove(i);
i--;
}
if(i < 0){
break;
}
bullets.get(i).render();
if(bullets.get(i).checkCollision(asteroids) ){
bullets.remove(i);
i--;
}
}
for(int i = 0; i < bullets.size(); i++){
bullets.get(i).edges();
if(bullets.get(i).update()){
bullets.remove(i);
i--;
}
if(i < 0){
break;
}
bullets.get(i).render();
if(bullets.get(i).checkCollision(purple) ){
bullets.remove(i);
i--;
}
}
while(exhaust.size() >50){
exhaust.remove(0);
}
while(fire.size()>10){
fire.remove(0);
}
while(bullets.size() > 100){
bullets.remove(0);
}
for(Asteroid a : asteroids){
a.update();
a.edges();
a.render();
}
for(Purple p : purple){
p.update();
p.edges();
p.render();
}
for(int i = 0; i < lives; i++){
image(ship,40*i + 10,ship.r*1.5,2*ship.r,3*ship.r);
}
} else if(lives < 0){
if(darkCounter < darkCounterLimit){
background(0);
darkCounter++;
for(Asteroid a : asteroids){
a.update();
a.edges();
a.render();
}
for(Purple p : purple){
p.update();
p.edges();
p.render();
}
fill(0, 255-(darkCounterLimit-darkCounter)*3);
rect(0,0,width,height);
} else {
background(0);
for(Asteroid a : asteroids){
a.update();
a.edges();
a.render();
}
for(Purple p : purple){
p.update();
p.edges();
p.render();
}
background(bgover);
if(score>highscore){highscore = score;}
textFont("Montserrat-ExtraBold", 20);
fill(255);
text("SCORE: " + score,600,70);
text("HIGH SCORE: " +highscore, 600, 50);
}
} else {
background(bgtrans);
ship = new Ship();
if(stage > -1){
stage++;
} else {
background(bgstart);
}
}
}
void mousePressed(){
if(lives < 0){
stage = -1;
lives = 3;
asteroids = new ArrayList<Asteroid>(0);
purple = new ArrayList<Purple>(0);
score = 0;
} else if ((asteroids.size()==0) && (purple.size()==0)){
stage++;
reset();
}
}
void reset(){
ship = new Ship();
exhaust = new ArrayList<Exhaust>();
fire = new ArrayList<Exhaust>();
bullets = new ArrayList<Bullet>();
asteroids = new ArrayList<Asteroid>();
purple = new ArrayList<Purple>();
for(int i = 0; i <numAsteroids + diffCurve*stage; i++){
PVector position = new PVector((int)(random()*width), (int)(height/1.5));
asteroids.add(new Asteroid(position, startingRadius, asteroidPics, stage));
}
for(int i = 0; i <numPurple + diffCurve*stage; i++){
PVector position = new PVector((int)(random()*width), (int)(height/1.5));
purple.add(new Purple(position, startingRadius, purplePics, stage));
}
darkCounter = 0;
}
void fireBullet(){
PVector pos = new PVector(0, ship.r*4);
rotate2D(pos,heading2D(ship.rotation) + PI/2);
pos.add(ship.position);
PVector vel = new PVector(0, bulletSpeed);
rotate2D(vel, heading2D(ship.rotation) + PI/2);
bullets.add(new Bullet(pos, vel));
}
void keyPressed(){
if(key==CODED){
if(keyCode==UP){
upPressed=true;
} else if(keyCode==DOWN){
downPressed=true;
} else if(keyCode == LEFT){
aPressed = true;
}else if(keyCode==RIGHT){
dPressed = true;
}
}
if(key == 'a'){
aPressed = true;
}
if(key=='d'){
dPressed = true;
}
if(key=='w'){
upPressed=true;
}
if(key=='s'){
downPressed=true;
}
}
void keyReleased(){
if(key==CODED){
if(keyCode==UP){
upPressed=false;
ship.acceleration = new PVector(0,0);
} else if(keyCode==DOWN){
downPressed=false;
ship.acceleration = new PVector(0,0);
} else if(keyCode==LEFT){
aPressed = false;
} else if(keyCode==RIGHT){
dPressed = false;
}
}
if(key=='a'){
aPressed = false;
}
if(key=='d'){
dPressed = false;
}
if(key=='w'){
upPressed=false;
ship.acceleration = new PVector(0,0);
}
if(key=='s'){
downPressed=false;
ship.acceleration = new PVector(0,0);
}
if(key == ' '){
fireBullet();
}
}
float heading2D(PVector pvect){
return (float)(Math.atan2(pvect.y, pvect.x));
}
void rotate2D(PVector v, float theta) { // https://processing.org/tutorials/trig/
float xTemp = v.x;
v.x = v.x*cos(theta) - v.y*sin(theta);
v.y = xTemp*sin(theta) + v.y*cos(theta);
}
class Asteroid{
float radius;
float omegaLimit = .05;
PVector position;
PVector velocity;
PVector rotation;
float spin;
int col = 50;
PImage pics[];
PImage pic;
int stage;
float dampening = 1;
public Asteroid(PVector pos, float radius_, PImage[] pics_, int stage_){
radius = radius_;
stage = stage_;
position = pos;
float angle = random(2 * PI);
velocity = new PVector(sin(angle), cos(angle));
velocity.mult((50*50)/(radius*radius));
velocity.mult(sqrt(stage + 2));
velocity.mult(dampening);
angle = random(2 * PI);
rotation = new PVector(cos(angle), sin(angle));
spin = (float)(Math.random()*omegaLimit-omegaLimit/2);
int rnd = (int)(Math.random()*3);
pics = pics_;
pic = pics[rnd];
}
void breakUp(ArrayList<Asteroid> asteroids){
if(radius <= 30){
asteroids.remove(this);
} else if (radius < 33){
for(int i = 0; i < 2; i++){
float angle = random(2*PI);
PVector rand = new PVector(radius*sin(angle), radius*cos(angle));
rand.add(position);
asteroids.add(new Asteroid(rand, radius*.8, pics, stage));
}
asteroids.remove(this);
} else {
for(int i = 0; i < 3; i++){
float angle = random(2*PI);
PVector rand = new PVector(radius*sin(angle), radius*cos(angle));
rand.add(position);
asteroids.add(new Asteroid(rand, radius*.8, pics, stage));
}
asteroids.remove(this);
}
}
void update(){
position.add(velocity);
rotate2D(rotation, spin);
}
void render(){
fill(col);
circ(position.x, position.y);
if (position.x < radius){
circ(position.x + width, position.y);
} else if (position.x > width+radius) {
circ( position.x+width, position.y);
}
if (position.y < radius) {
circ(position.x, position.y + height);
} else if (position.y > height-radius){
circ(position.x, position.y-height);
}
}
void edges(){
if (position.x < 0){
position.x = width;
}
if (position.y < 0) {
position.y = height;
}
if (position.x > width) {
position.x = 0;
}
if (position.y > height){
position.y = 0;
}
}
void circ(float x, float y){
pushMatrix();
translate(x,y);
rotate(heading2D(rotation)+PI/2);
// ellipse(0,0,2.1*radius, 1.9*radius);
image(pic, -radius,-radius,radius*2, radius*2);
popMatrix();
}
float heading2D(PVector pvect){
return (float)(Math.atan2(pvect.y, pvect.x));
}
void rotate2D(PVector v, float theta) {
float xTemp = v.x;
v.x = v.x*cos(theta) - v.y*sin(theta);
v.y = xTemp*sin(theta) + v.y*cos(theta);
}
}
class Purple{
float radius;
float omegaLimit = .05;
PVector position;
PVector velocity;
PVector rotation;
float spin;
int col = 100;
PImage pics[];
PImage pic;
int stage;
float dampening = 1;
public Purple(PVector pos, float radius_, PImage[] pics_, int stage_){
radius = radius_;
stage = stage_;
position = pos;
float angle = random(2 * PI);
velocity = new PVector(sin(angle), cos(angle));
velocity.mult((50*50)/(radius*radius));
velocity.mult(sqrt(stage + 2));
velocity.mult(dampening);
angle = random(2 * PI);
rotation = new PVector(cos(angle), sin(angle));
spin = (float)(Math.random()*omegaLimit-omegaLimit/2);
int rnd = (int)(Math.random()*3);
pics = pics_;
pic = pics[rnd];
}
void breakUp(ArrayList<Purple> purple){
if(radius <= 30){
purple.remove(this);
} else if (radius < 33){
for(int i = 0; i < 2; i++){
float angle = random(2*PI);
PVector rand = new PVector(radius*sin(angle), radius*cos(angle));
rand.add(position);
purple.add(new Purple(rand, radius*.8, pics, stage));
}
purple.remove(this);
} else {
for(int i = 0; i < 3; i++){
float angle = random(2*PI);
PVector rand = new PVector(radius*sin(angle), radius*cos(angle));
rand.add(position);
purple.add(new Purple(rand, radius*.8, pics, stage));
}
purple.remove(this);
}
}
void update(){
position.add(velocity);
rotate2D(rotation, spin);
}
void render(){
fill(col);
circ(position.x, position.y);
if (position.x < radius){
circ(position.x + width, position.y);
} else if (position.x > width+radius) {
circ( position.x+width, position.y);
}
if (position.y < radius) {
circ(position.x, position.y + height);
} else if (position.y > height-radius){
circ(position.x, position.y-height);
}
}
void edges(){
if (position.x < 0){
position.x = width;
}
if (position.y < 0) {
position.y = height;
}
if (position.x > width) {
position.x = 0;
}
if (position.y > height){
position.y = 0;
}
}
void circ(float x, float y){
pushMatrix();
translate(x,y);
rotate(heading2D(rotation)+PI/2);
image(pic, -radius,-radius,radius*2, radius*2); // purple radius
popMatrix();
}
float heading2D(PVector pvect){
return (float)(Math.atan2(pvect.y, pvect.x));
}
void rotate2D(PVector v, float theta) {
float xTemp = v.x;
v.x = v.x*cos(theta) - v.y*sin(theta);
// v.y = xTemp*sin(theta) + v.y*cos(theta);
}
}
class Bullet{
PVector position;
PVector velocity;
int radius = 5;
int counter = 0;
int timeOut = 24 * 2;
float alpha;
PImage img = loadImage("/static/uploaded_resources/p.22229/Bullet.png");
public Bullet(PVector pos, PVector vel){
position = pos;
velocity = vel;
alpha = 255;
}
void edges(){
if (position.x < 0){
position.x = width;
}
if (position.y < 0) {
position.y = height;
}
if (position.x > width) {
position.x = 0;
}
if (position.y > height){
position.y = 0;
}
}
boolean checkCollision(ArrayList<Asteroid> asteroids){
for(Asteroid a : asteroids){
PVector dist = PVector.sub(position, a.position);
if(dist.mag() < a.radius){
a.breakUp(asteroids);
score++; // when asteroid hit , score 1 point
return true;}
}
return false;
}
boolean checkCollision(ArrayList<Purple> purple){
for(Purple p : purple){
PVector dist = PVector.sub(position, p.position);
if(dist.mag() < p.radius){
p.breakUp(purple);
score++; // when purple hit , score 1 point
return true;
}
}
return false;
}
boolean update(){
alpha *= .9;
counter++;
if(counter>=timeOut){
return true;
}
position.add(velocity);
return false;
}
void render(){
fill(255);
pushMatrix();
translate(position.x, position.y);
rotate(heading2D(velocity)+PI/2);
//ellipse(0,0, radius, radius*5);
image(img, -radius/2, -2*radius, radius, radius*5);
popMatrix();
}
float heading2D(PVector pvect){
return (float)(Math.atan2(pvect.y, pvect.x));
}
}
class Exhaust{
PVector position;
PVector velocity;
float diameter;
color hugh;
public Exhaust(PVector pos, PVector vel, color col, int rad){
position = pos;
velocity = vel;
diameter = (float)(Math.random()*rad);
hugh = col;
}
void render(){
noStroke();
fill(2);
ellipse(position.x, position.y, diameter, diameter);
}
void update(){
position.add(velocity);
velocity.mult(.9);
}
}
/* @pjs preload="/static/uploaded_resources/p.22229/Ship.png"; */
class Ship{
PVector position;
PVector velocity;
PVector acceleration;
PVector rotation;
float drag = .9;
float r = 20;
PImage img = loadImage("/static/uploaded_resources/p.22229/Ship.png");
public Ship(){
position = new PVector(width/2, height-50);
acceleration = new PVector(0,0);
velocity = new PVector(0,0);
rotation = new PVector(0,1);
}
void update(ArrayList<Exhaust> exhaust, ArrayList<Exhaust> fire){
PVector below = new PVector(0, -2*r);
rotate2D(below, heading2D(rotation)+PI/2);
below.add(position);
color grey = color(255);
int exhaustVolume = (int)(velocity.mag())+1;
for(int i = 0; i <exhaustVolume; i++){
float angle = (float)(Math.random()*.5-.25);
angle += heading2D(rotation);
PVector outDir = new PVector(cos(angle), sin(angle));
exhaust.add(new Exhaust(below, outDir, grey, 8));
}
for(int i = 0; i <1; i++){
float angle = (float)(Math.random()*.5-.9);
angle += heading2D(rotation);
PVector outDir = new PVector(cos(angle), sin(angle));
outDir.y = 0; // tale lenght
below.add(outDir);
below.y-=.10;
color red = color((int)(200 + Math.random()*55),(int)( 150+Math.random()*105), 30, 25);
fire.add(new Exhaust(below,outDir, red, 3)); //tale wight
}
velocity.add(acceleration);
velocity.mult(drag);
velocity.limit(10);
position.add(velocity);
}
void edges(){
if (position.x < r){
position.x = width-r;
}
if (position.y < r) {
position.y = height-r;
}
if (position.x > width-r) {
position.x = r;
}
if (position.y > height-r){
position.y = r;
}
}
boolean checkCollision(ArrayList<Asteroid> asteroids){
for(Asteroid a : asteroids){
PVector dist = PVector.sub(a.position, position);
if(dist.mag() < a.radius + r/2){
a.breakUp(asteroids);
return true;
}
}
return false;
}
boolean checkCollision(ArrayList<Purple> purple){
for(Purple p : purple){
PVector dist = PVector.sub(p.position, position);
if(dist.mag() < p.radius + r/2){
p.breakUp(purple);
return true;
}
}
return false;
}
void render(){
float theta = heading2D(rotation) + PI/2;
theta += PI;
pushMatrix();
translate(position.x, position.y);
rotate(theta);
fill(0);
image(img,-r,-r*1.5,2*r,3*r); // how the could rotates- like a pivot
popMatrix();
}
float heading2D(PVector pvect){
return (float)(Math.atan2(pvect.y, pvect.x));
}
void rotate2D(PVector v, float theta) {
float xTemp = v.x;
v.x = v.x*cos(theta) - v.y*sin(theta);
v.y = xTemp*sin(theta) + v.y*cos(theta);
}
}