Version 1.1
// Engine
Nodes engine, jeu, aliens, lasers, gui;
// Player
PImage playerImage;
Player player;
// Aliens
PImage alienImage;
float alienRadius;
int topA, nowA, intervalA;
// Lasers
PImage laserImage;
Tirs tirs;
// Explosions
Explosion explosion;
// GUI
int score=0;
PImage fond;
StartGame startgame;
boolean pauseInDraw=true;
void setup() {
size(1200, 800);
// Engine
engine = new Nodes();
jeu = new Nodes();
aliens = new Nodes();
lasers = new Nodes();
gui = new Nodes();
engine.add(jeu);
jeu.add(aliens);
jeu.add(lasers);
engine.add(gui);
jeu.pause=true;
// Player
playerImage=loadImage("playerShip.png");
player = new Player(0, height-50, 20, playerImage);
player.scale=0.5;
jeu.add(player);
//Aliens
alienRadius = 20;
alienImage=loadImage("spaceShip.png");
topA=0;
intervalA=500;
nowA=0;
// Lasers
laserImage=loadImage("laser.png");
tirs = new Tirs();
jeu.add(tirs);
jeu.add(new AlienBoum(aliens, lasers));
// Explosions
explosion=new Explosion(300, 100, 20, laserImage);
for (int i=0; i<16; i++) {
explosion.addImage(loadImage("explode"+(i+1)+".png"));
}
gui.add(explosion);
// GUI
pglobal.font=createFont("ZeroCool.ttf", 32);
textFont(pglobal.font);
fond=loadImage("fond.png");
fond.resize(width, height);
gui.add(new boutonCollisions(10, 20, 220, 30, "Formes de collisions"));
startgame = new StartGame(width/2, height/3, 100, 30, "Démarrer");
gui.add(startgame);
// Tests
//pglobal.debug=true;
//player.vy=-2;
//novAlien();
}
void draw() {
background(fond);
// 2. Aliens
if (pauseInDraw==false) {
nowA=millis();
if (nowA-topA>intervalA) {
topA = nowA;
aliens.add(new Alien(random(width), -50, 20, alienImage, player));
}
}
// 3. class PGlobal { // singleton : pglobal
boolean debug=false;
PFont font;
int theTextSize=18;
}
//---------------- DEBUT DU MOTEUR DE JEU -------------------------------------------------
PGlobal pglobal = new PGlobal();
class Events { // singleton : events
//ArrayList clicNodes = new ArrayList();
Node[] clicEvents= new Node[0];
void listeningClicEvents(Node node) {
clicEvents=(Node[]) append(clicEvents, node);
}
void clicEvent(float mx, float my) {
if (pglobal.debug) {
println("clicEvent !");
}
if (clicEvents.length!=0) {
//for (Node node : clicNodes) node.runClic(mx, my);
for (int i=0; i<clicEvents.length; i++) {
clicEvents[i].clicEvent(mx, my);
}
}
}
}
Events events = new Events();
void mousePressed() {
events.clicEvent(mouseX, mouseY);
}
class Node {
boolean toRemove=false;
boolean pause=false;
void run() {
if (pglobal.debug) {
println("Méthode run() appelée sur Node : non redéfinie !");
exit();
}
}
void clicEvent(float mx, float my) {
if (pglobal.debug) {
println("Méthode runClic("+mx+","+my+") appelée sur Node : non redéfinie !");
exit();
}
}
}
class Nodes extends Node {
//ArrayList nodes = new ArrayList();
Node[] nodes= new Node[0];
void add(Node node) {
//nodes.add(node);
nodes=(Node[]) append(nodes, node);
}
void run() {
// if (nodes.size()!=0) {
// //for (Node node : nodes) node.run();
// for (int i=0;i<nodes.size();i++) {
// if (nodes.get(i).toRemove) {
// nodes.remove(i);
// }
// else {
// nodes.get(i).run();
// }
// }
// }
//}
if (pause==false) {
if (nodes.length>10) {
Node[] nodes2=nodes;
nodes=new Node[0];
for (int i=0; i<nodes2.length; i++) {
if (nodes2[i].toRemove==false) {
nodes=(Node[]) append(nodes, nodes2[i]);
}
}
}
if (nodes.length!=0) {
for (int i=0; i<nodes.length; i++) {
if (nodes[i].toRemove==false) {
nodes[i].run();
}
}
}
}
}
}
class Node2D extends Node {
float x, y;
Node2D(float x, float y) {
this.x=x;
this.y=y;
}
}
class Area2D extends Node2D {
float shapeRadius;
Area2D(float x, float y) {
super(x, y);
shapeRadius=20;
}
Area2D(float x, float y, float radius) {
super(x, y);
this.shapeRadius=radius;
}
boolean collide(Area2D a) {
if (dist(x, y, a.x, a.y)<=shapeRadius+a.shapeRadius) {
return true;
} else {
return false;
}
}
void run() {
if (pause==false) {
display();
if (pglobal.debug) {
noFill();
stroke(255);
circle(x, y, 2*shapeRadius);
}
}
}
void display() {
}
}
class Sprite2D extends Area2D {
float vx, vy;
Sprite2D(float x, float y) {
super(x, y);
this.vx=0;
this.vy=0;
}
Sprite2D(float x, float y, float radius) {
super(x, y, radius);
this.vx=0;
this.vy=0;
}
void run() {
x+=vx;
y+=vy;
super.run();
}
}
class Button extends Node2D {
float dx, dy;
color baseColor=color(57, 99, 170); // un bleu
color overColor=color(174, 90, 193); // un violet
String textButton;
//int MARGE=10;
boolean toInit=true; // Inscription à Events lors du premier passage dans run()
Button(float x, float y, float dx, float dy, String t) {
super(x, y);
this.dx=dx;
this.dy=dy;
this.textButton=t;
}
boolean mOver(float mx, float my) {
return ((mx >= x) && (mx <= x + dx) &&
(my >= y) && (my <= y + dy));
}
void display() {
rectMode(CORNER);
if (mOver(mouseX, mouseY)) fill(overColor);
else fill(baseColor);
noStroke();
rect(x, y, dx, dy);
textAlign(CENTER, CENTER);
fill(0);
textSize(pglobal.theTextSize);
text(textButton, x+dx/2, y+dy/2);
}
void run() {
// l'ajout doit se faire quand l'objet est complètement construit donc pas dans le constructeur
if (toInit) {
events.listeningClicEvents(this);
toInit=false;
}
if (pause==false)
display();
}
void clicEvent(float mx, float my) {
if (mOver(mx, my)) {
action();
}
}
void action() {
println("Méthode action() dans Button non redéfinie !");
exit();
}
}
class SpriteImage extends Sprite2D {
PImage image;
float scale;
SpriteImage(float x, float y, float radius, PImage image) {
super(x, y, radius);
this.image=image;
this.scale=1;
}
void display() {
imageMode(CENTER);
image(image, x, y, image.width*scale, image.height*scale);
}
}
class Collisions extends Node {
Nodes nodes1, nodes2;
Collisions(Nodes nodes1, Nodes nodes2) {
this.nodes1=nodes1;
this.nodes2=nodes2;
}
void run() {
Area2D n1, n2;
for (int i=0; i<nodes1.nodes.length; i++) {
n1 = (Area2D) nodes1.nodes[i];
for (int j=0; j<nodes2.nodes.length; j++) {
n2 = (Area2D) nodes2.nodes[j];
if (n1.toRemove==false && n2.toRemove==false) {
if (n1.collide(n2)) {
action(n1, n2);
}
}
}
}
}
void action(Area2D a1, Area2D a2) {
println("action() dans Collisions non redéfinie i !");
exit();
}
}engine
engine.run();
println(aliens.nodes.length);
// GUI
fill(255);
textSize(30);
text("Score : "+score, width-180, 30);
}
//------------------ FIN DU MOTEUR DE JEU -------------------------------------
//------------------ CLASSES PROPRES A CE JEU ---------------------------------
class Player extends SpriteImage {
Player(float x, float y, float radius, PImage image) {
super(x, y, radius, image);
}
void run() {
x=mouseX;
// Limitation du mouvement à droite et à gauche
if (xwidth-image.width * scale /2) {
x = width-image.width * scale /2;
}
super.run();
}
}
class Tirs extends Node {
boolean toInit=true; // Inscription à Events lors du premier passage dans run()
boolean goTir=true;
void run() {
// l'ajout doit se faire quand l'objet est complètement construit donc pas dans le constructeur
if (toInit) {
events.listeningClicEvents(this);
toInit=false;
}
}
void clicEvent(float mx, float my) {
if (goTir) {
SpriteImage laser = new SpriteImage(player.x, player.y, 10, laserImage);
laser.vy=-10;
lasers.add(laser);
} else goTir=true; // Après n'avoir pas tiré de laser selon le clicEvent de l'appui sur le
// bouton starGame les lasers sont de nouveau autorisés ! Ils sont interdits
// lors du reset du jeu : goTir = false !
}
}
class Alien extends SpriteImage {
SpriteImage player;
Alien (float x, float y, float radius, PImage image, SpriteImage player) {
super(x, y, radius, image);
vy=10;
scale=0.5;
this.player=player;
}
void run() {
if (y>height+100) {
toRemove=true;
}
if (collide(player)) {
player.pause=true;
this.toRemove=true;
/// Reset du Jeu
pauseInDraw=true;
jeu.pause=true;
startgame.pause=false;
aliens.nodes=new Node[0];
lasers.pause=true;
lasers.nodes=new Node[0];
tirs.goTir=false;
}
super.run();
}
}
class AlienBoum extends Collisions {
AlienBoum(Nodes a, Nodes b) {
super(a, b) ;
}
void action(Area2D a1, Area2D a2) {
a1.toRemove=true;
a2.toRemove=true;
score+=10;
}
}
class boutonCollisions extends Button {
boutonCollisions(float x, float y, float dx, float dy, String t) {
super(x, y, dx, dy, t);
}
void action() {
if (pglobal.debug) pglobal.debug=false;
else pglobal.debug=true;
}
}
class StartGame extends Button {
StartGame(float x, float y, float dx, float dy, String t) {
super(x, y, dx, dy, t);
}
void action() {
jeu.pause=false;
this.pause=true;
topA=millis();
pauseInDraw=false;
lasers.pause=false;
score=0;
player.pause=false;
}
}
class Explosion extends SpriteImage {
PImage[] images= new PImage[0];
int index=0;
Explosion(float x, float y, float radius, PImage image) {
super(x, y, radius, image);
}
void addImage(PImage image) {
//nodes.add(node);
images=(PImage[]) append(images, image);
}
void run() {
if (index>=images.length) index=0;
else image=images[index];
super.run();
index++;
}
}