Thank you for that!
I developed your idea further and I am grateful for your idea.
Development of a Sketch.
First version
It occured to me that only ONE of the 4 boolean vars can be true at one time. So this reminded me of states. So I changed this.
In draw() we can use switch() now, keyPressed is shorter.
Here is the whole code in one go:
//
final int HOME=0;
int state = HOME;
Rect r;
Circle c;
Triangle t;
// ------------------------------------------------------------------------------
void setup() {
fullScreen(P3D);
r = new Rect(100, 100, 400, 300);
c = new Circle(300, 300, 400);
t = new Triangle(300, 100, 100, 550, 550, 550);
}// func
void draw() {
switch (state) {
case HOME:
showHome();
break;
case 1:
showGame1();
break;
case 2:
showGame2();
break;
case 3:
showGame3();
break;
}//switch
//
}//func
// ------------------------------------------------------------------------------
void keyPressed() {
if (key >= '0' && key <= '3') {
state = int(key+"");
} else if (key==ESC) {
state=HOME; // MENU
key=0; // kill ESC
} else if (key=='X') {
exit();
}//else if
}// func
// ------------------------------------------------------------------------------
void showHome() {
background(209);
fill(255, 0, 0);
textSize(42);
textAlign(CENTER, CENTER);
text ("Welcome to Multi Game Generator \n Home = key '0' \n Game 1 = key '1' \n"
+ " Game 2 = key '2' \n Game 3 = key '3' \nX to Quit (shift-x)", width/2, height/2);//
}
void showGame1() {
r.display();
}
void showGame2() {
t.display();
}
void showGame3() {
c.display();
}
// ===============================================================================================
//classes in Tabs
class Circle {
int x, y, d;
Circle(int xpos, int ypos, int diameter) {
x = xpos;
y = ypos;
d = diameter;
}
void display() {
background(255);
translate(400, 200);
stroke(0);
strokeWeight(5);
fill(0, 0, 255);
circle(x, y, d);
}
}
// ===============================================================================================
//Tab
class Rect {
int x, y, w, h;
Rect(int xpos, int ypos, int wide, int ht) {
x = xpos;
y = ypos;
w = wide;
h = ht;
}
void display() {
background(255);
translate(400, 200);
strokeWeight(3);
stroke(0);
fill(255, 0, 0);
rect(x, y, w, h);
}
}
// ===============================================================================================
// Tab
class Triangle {
int x1, y1, x2, y2, x3, y3;
Triangle(int pt1x, int pt1y,
int pt2x, int pt2y,
int pt3x, int pt3y) {
x1 = pt1x;
y1 = pt1y;
x2 = pt2x;
y2 = pt2y;
x3 = pt3x;
y3 = pt3y;
}
void display() {
background(255);
translate(400, 200);
strokeWeight(3);
stroke(0);
fill(0, 255, 0);
triangle(x1, y1, x2, y2, x3, y3);
}
}
//
Second version
We can also use an enum clause for state so make it better readable.
Here is the whole code in one go:
// possible states of the program - enum !
enum State {
HOME, GAME1, GAME2, GAME3
}
State state = State.HOME;
Rect r;
Circle c;
Triangle t;
// ------------------------------------------------------------------------------
void setup() {
fullScreen(P3D);
r = new Rect(100, 100, 400, 300);
c = new Circle(300, 300, 400);
t = new Triangle(300, 100, 100, 550, 550, 550);
}//func
void draw() {
switch (state) {
case HOME:
showHome();
break;
case GAME1:
showGame1();
break;
case GAME2:
showGame2();
break;
case GAME3:
showGame3();
break;
}//switch
//
}//func
// ------------------------------------------------------------------------------
// Inputs
void keyPressed() {
if (key >= '0' && key <= '3') {
int keyAsInt = int(key+""); // convert to in
// println(keyAsInt); // test
state = State.values()[keyAsInt]; // convert int keyAsInt to the new state (using keyAsInt as a kind of index for State)
// println(state.toString()); // test
} else if (key==ESC) {
state=State.HOME; // MENU
key=0; // kill ESC
} else if (key=='X') {
exit();
}//else if
}//func
// ------------------------------------------------------------------------------
// Other funcs
void showHome() {
background(209);
fill(255, 0, 0);
textSize(42);
textAlign(CENTER, CENTER);
text ("Welcome to Multi Game Generator \n Home = key '0' \n Game 1 = key '1' \n"
+ " Game 2 = key '2' \n Game 3 = key '3' \nX to Quit (shift-x)", width/2, height/2);//
}
void showGame1() {
r.display();
}
void showGame2() {
t.display();
}
void showGame3() {
c.display();
}
// ===============================================================================================
//classes in Tabs
class Circle {
int x, y, d;
Circle(int xpos, int ypos, int diameter) {
x = xpos;
y = ypos;
d = diameter;
}
void display() {
background(255);
translate(400, 200);
stroke(0);
strokeWeight(5);
fill(0, 0, 255);
circle(x, y, d);
}
}
// ===============================================================================================
//Tab
class Rect {
int x, y, w, h;
Rect(int xpos, int ypos, int wide, int ht) {
x = xpos;
y = ypos;
w = wide;
h = ht;
}
void display() {
background(255);
translate(400, 200);
strokeWeight(3);
stroke(0);
fill(255, 0, 0);
rect(x, y, w, h);
}
}
// ===============================================================================================
// Tab
class Triangle {
int x1, y1, x2, y2, x3, y3;
Triangle(int pt1x, int pt1y,
int pt2x, int pt2y,
int pt3x, int pt3y) {
x1 = pt1x;
y1 = pt1y;
x2 = pt2x;
y2 = pt2y;
x3 = pt3x;
y3 = pt3y;
}
void display() {
background(255);
translate(400, 200);
strokeWeight(3);
stroke(0);
fill(0, 255, 0);
triangle(x1, y1, x2, y2, x3, y3);
}
}
//
Third version
Now it occured to me, that for each new game we need a new object variable.
Why not put them in an array?
It would be an array of classes. To make that possible, we need to make an interface first, that makes all classes compatible, so that we can have them together in one array:
interface GameInterface {
// Let's abstract
// Let's abstract funcs
void showState();
void keyPressedState();
void mousePressedState();
}
Each class must tell us that it belongs to this Interface:
class Circle implements StateInterface {
And each class must provide the functions the Interface promises,
display(), keyPressedState() and mousePressedState().
Therefore you can go back to MENU
- by key 0 OR by mouse in the three games.
Advantage: We can get rid of the switch()
in draw() (almost) and
get rid of these:
void showGame1() {
r.display();
}
void showGame2() {
t.display();
}
....
Nice Advantage here.
Full Code:
// different games/states in one Sketch, version 3
// see https://discourse.processing.org/t/multi-game-generator/45139
// This version features an Interface approach for the three Game classes. Similar approach: see https://discourse.processing.org/t/scenes-in-processing/40386
// possible states of the program that we use as an Index for the array of Game-classes.
enum State {
HOME, GAME1, GAME2, GAME3
}
State state = State.HOME;
// List of Game classes in array.
StateInterface[] games = new StateInterface[3];
// ------------------------------------------------------------------------------
void setup() {
fullScreen(P3D);
// Make List of Game classes
games[0] = new Rect(100, 100, 400, 300);
games[1] = new Circle(300, 300, 400);
games[2] = new Triangle(300, 100, 100, 550, 550, 550);
}//func
void draw() {
switch (state) {
case HOME:
showHome(); // show Menu
break;
default:
// show current game
int getIntFromState = state.ordinal()-1; // we must say -1 because 0 is Home and doesn't occur in the array (yet).
// see https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Enum.html
games[getIntFromState].display(); // show current game
break;
}//switch
//
}//func
// ------------------------------------------------------------------------------
// Inputs
void keyPressed() {
if (state==State.HOME) {
// run a keyPressed func for the Menu
keyPressedForMenu();
} else {
// ALL GAMES are told to run their respective keyPressedState() function here (which can be different)
int getIntFromState = state.ordinal()-1; // we must say -1 because 0 is Home and doesn't occur in the array (yet).
// see https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Enum.html
games[getIntFromState].keyPressedState();
}
}//func
void mousePressed() {
// The menu doesn't have mouse, only the games
if (state!=State.HOME) {
int getIntFromState = state.ordinal()-1; // we must say -1 because 0 is Home and doesn't occur in the array (yet).
// see https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Enum.html
// ALL GAMES are told to run their respective mousePressedState() function here (which can be different)
games[getIntFromState].mousePressedState();
}
}//func
void keyPressedForMenu() {
if (key >= '1' && key <= '3') {
// keys from 1 to 3 start a game
int keyAsInt = int(key+""); // convert to int
// println(keyAsInt); // test
state = State.values()[keyAsInt]; // convert int keyAsInt to the new state (using keyAsInt as a kind of index for State)
// println(state.toString()); // test
} else if (key==ESC) {
state=State.HOME; // MENU
key=0; // kill ESC
} else if (key=='X') {
exit();
}//else if
}//func
// ------------------------------------------------------------------------------
// Other funcs
void showHome() {
background(209);
fill(255, 0, 0);
textSize(42);
textAlign(CENTER, CENTER);
text ("Welcome to Multi Game Generator \n Home = key '0' \n Game 1 = key '1' \n"
+ " Game 2 = key '2' \n Game 3 = key '3' \nX to Quit (shift-x)", width/2, height/2);//
}//func
// ===============================================================================================
// Interface in Tab
interface StateInterface {
// Let's abstract
// Let's abstract funcs
void display();
void keyPressedState();
void mousePressedState();
}//interface
// ===============================================================================================
//classes in Tabs
class Circle implements StateInterface {
int x, y, d;
Circle(int xpos, int ypos, int diameter) {
x = xpos;
y = ypos;
d = diameter;
}
void display() {
background(255);
translate(400, 200);
stroke(0);
strokeWeight(5);
fill(0, 0, 255);
circle(x, y, d);
}
void keyPressedState() {
if (key == '0') {
state = State.values()[0]; // the new state (using 0 as a kind of index for State)
}
}//method
void mousePressedState() {
state = State.values()[0]; // the new state (using 0 as a kind of index for State)
}
}//class
// ===============================================================================================
//Tab
class Rect implements StateInterface {
int x, y, w, h;
Rect(int xpos, int ypos, int wide, int ht) {
x = xpos;
y = ypos;
w = wide;
h = ht;
}
void display() {
background(255);
translate(400, 200);
strokeWeight(3);
stroke(0);
fill(255, 0, 0);
rect(x, y, w, h);
}
void keyPressedState() {
if (key == '0') {
state = State.values()[0]; // the new state (using 0 as a kind of index for State)
}
}
void mousePressedState() {
state = State.values()[0]; // the new state (using 0 as a kind of index for State)
}
}//class
// ===============================================================================================
// Tab
class Triangle implements StateInterface {
int x1, y1, x2, y2, x3, y3;
Triangle(int pt1x, int pt1y,
int pt2x, int pt2y,
int pt3x, int pt3y) {
x1 = pt1x;
y1 = pt1y;
x2 = pt2x;
y2 = pt2y;
x3 = pt3x;
y3 = pt3y;
}
void display() {
background(255);
translate(400, 200);
strokeWeight(3);
stroke(0);
fill(0, 255, 0);
triangle(x1, y1, x2, y2, x3, y3);
}
void keyPressedState() {
if (key == '0') {
state = State.values()[0]; // the new state (using 0 as a kind of index for State)
}
}
void mousePressedState() {
state = State.values()[0]; // the new state (using 0 as a kind of index for State)
}
}//class
//
Thanks again!
Warm regards,
Chrisir