When clearing background, rect moves - java

So i've used a rect to divide the screen for two different background colours. The code im writing is for a minigame and its supposed to move a bubble up the screen, but when I click my mouse the rect I used to divide the screen moves as well. I probably did a very poor job at describing this so heres the code and you'll see what I mean.
PFont font1;
int dice = 100;
int num = 0;
float circlex = 300;
float circley = 830;
float xmove = 0;
float ymove = 0;
void setup ()
{
noLoop();
frameRate(10);
size (600, 900);
//background (#29C4FF);
//fill (#C4FFEC);
//strokeWeight(3);
//line(1, 225, 599, 225);
//noStroke ();
//rect (0, 0, 599, 225);
font1 = loadFont ("ArialMT-18.vlw");
ellipseMode(CENTER);
}
void draw ()
{
//OCEAN
background (#29C4FF);
fill (#C4FFEC);
strokeWeight(3);
line(1, 225, 599, 225);
noStroke ();
rect (0, 0, 599, 225);
textFont(font1, 18);
fill(0);
text("Click on the dice to help free Aang from the iceberg.", 100, 50);
//BUBBLE
fill(0, 0, 200);
ellipse(circlex, circley, 125, 125);
noStroke();
fill (210);
ellipse(circlex, circley, 118, 118);
//AANG
//BODY
fill(#FF8E03);
noStroke ();
triangle(255, 830, 345, 830, 300, 890);
//HEAD
fill(#027A9D);
ellipse(275, 820, 10, 15);
ellipse(325, 820, 10, 15);
ellipse(300, 820, 50, 55);
rectMode(CENTER);
fill(255);
rect(300, 800, 10, 15);
triangle(290, 805, 310, 805, 300, 820);
rect(288, 815, 8, 3);
rect(312, 815, 8, 3);
//DICE
fill(#027A9D);
rect(80, 130, 100, 100, 12);
fill(#8EC1EA);
rect(80, 130, 90, 90, 8);
//NUMBERS(DOTS)
fill(150, 0, 0);
int num = int(random(1, 7));
if (num == 1 || num == 3 || num == 5)
ellipse(80, 130, dice/5, dice/5);
if (num == 2 || num == 3 || num == 4 || num == 5 || num == 6) {
ellipse(80 - dice/4, 130 - dice/4, dice/5, dice/5);
ellipse(80 + dice/4, 130 + dice/4, dice/5, dice/5);
}
if (num == 4 || num == 5 || num == 6) {
ellipse(80 - dice/4, 130 + dice/4, dice/5, dice/5);
ellipse(80 + dice/4, 130 - dice/4, dice/5, dice/5);
}
if (num == 6) {
ellipse(80, 130 - dice/4, dice/5, dice/5);
ellipse(80, 130 + dice/4, dice/5, dice/5);
}
if (num == 1 || num == 2) {
circlex = circlex + xmove;
xmove = +20;
}
if (num == 3 || num == 4) {
circlex = circlex + xmove;
xmove = -20;
}
if (num == 5) {
circley = circley + ymove;
ymove = -25;
}
if (num == 6) {
circley = circley + ymove;
ymove = -50;
}
//ROLL
if (mousePressed && mouseButton == LEFT)
noLoop();
}
void mousePressed() {
loop();
}

rectMode(CENTER);
This line modifies how your rectangles are drawn. On the first run its still set to default (CORNER), but afterwards the rect get drawn from the center and thus moves to the top left.
Reference:
https://processing.org/reference/rectMode_.html
Solution 1:
Add rectMode(CORNER) before drawing the background.
Solution 2:
Move rectMode(CENTER) to the setup and draw all shapes a bit different.
In general I suggest you put the background into a function for a better readability and flexibility.
void setup () {
noLoop();
frameRate(10);
size (600, 900);
ellipseMode(CENTER);
rectMode(CENTER); // added rectMode here.
}
void draw () {
drawStage();
//BUBBLE
// ...
}
// Function to draw the background
void drawStage() {
//OCEAN
background (#29C4FF);
fill (#C4FFEC);
noStroke();
rect(width/2, 125, width, 250); // rect drawn with "width" scales if you choose to adjust your sketch size.
fill(0);
text("Click on the dice to help free Aang from the iceberg.", 100, 50);
}

Related

Creating sliders with arrow buttons

How can I create a slider with two arrow buttons from the side? The arrows/triangle should turn white when clicked. And the slider should move each time the arrow button is clicked.
here's the link to what it should look like
and here's what I've done so far
int x=75;
void setup() {
size(600,400);
}
void draw() {
background(100);
fill (200);
rect (75, 25, 400, 50);
stroke(0);
if(mousePressed) {
if (mouseX >75 && mouseX <= 475)
{x=mouseX;}
}
fill(127,0,0);
rect (x, 20, 9, 60);
fill (255);
fill (200);
rect (10, 25, 50, 50);
{
if (mousePressed == true) {
fill(255);
} else {
fill(0);
}
triangle (50, 60, 50, 40, 15, 50);
}
fill (200);
rect (490, 25, 50, 50);
{
if (mousePressed == true) {
fill(255);
} else {
fill(0);
}
triangle (500, 60, 500, 40, 535, 50);
}
println(x);
}
When I click anywhere on the screen, my problem is that both arrows turn white. I need it to individually function. And the slider is not moving every time I click the arrow buttons
The following approach to this problem uses 4 different classes: ForwardArrow, BackArrow, Slider, and ValueField. Arrow fill color is controlled by the press() method of its respective class.
color BLUE = color(64, 124, 188);
color LTGRAY = color(185, 180, 180);
color YELLOW = color(245, 250, 13);
color RED = color(255, 0, 0);
color BLACK = color(0, 0, 0);
color WHITE = color(255, 255, 255);
color GREEN = color(32, 175, 47);
ForwardArrow _fwdArrw;
BackArrow _backArrw;
ValueField _valueFld;
Slider _slider;
final int _sliderX = 90;
final int _sliderY = 40;
final int _sliderW = 200;
final int _sliderH = 30;
final int _txtSize = 22;
final int _initValue = 40;
final int _maxValue = 200;
final int _minValue = 0;
int value = _initValue;
class ValueField {
float x, y, w, h;
String title;
color fldColor;
color txtColor;
// Constructor
ValueField(int xpos, int ypos, float wt, float ht, String valueStr, color background, color foreground) {
x = xpos;
y = ypos;
w = wt;
h = ht;
title = valueStr;
fldColor = background;
txtColor = foreground;
}
void display(int val) {
// **** Value Field **** //
fill(fldColor); // erase old value
rect(x, y, w, h);
fill(txtColor); // text color
textSize(_txtSize);
textAlign(CENTER);
text(str(val), x, y, w, h);
// **** Slider bar **** //
fill(255);
rect(_sliderX, _sliderY, _sliderW*val/_maxValue, _sliderH);
}
}
class ForwardArrow {
float x, y, w, h;
color arrwColor;
// Constructor
ForwardArrow(int xpos, int ypos, float wt, float ht, color background) {
x = xpos;
y = ypos;
w = wt;
h = ht;
arrwColor = background;
}
void display() {
fill(arrwColor); // arrow color
noStroke();
triangle(x, y, x, y + h, x + w, y + h/2 );
}
void press() {
fill(255); // arrow color
noStroke();
triangle(x, y, x, y + h, x + w, y + h/2 );
}
}
class BackArrow {
float x, y, w, h;
color arrwColor;
// Constructor
BackArrow(int xpos, int ypos, float wt, float ht, color background) {
x = xpos;
y = ypos;
w = wt;
h = ht;
arrwColor = background;
}
void display() {
fill(arrwColor);
noStroke();
triangle(x, y + h/2, x + w, y, x + w, y + h );
}
void press() {
fill(255);
noStroke();
triangle(x, y + h/2, x + w, y, x + w, y + h );
}
}
class Slider {
float x, y, w, h;
color barColor;
color trimColor;
// Constructor
Slider(int xpos, int ypos, float wt, float ht, color background, color foreground) {
x = xpos;
y = ypos;
w = wt;
h = ht;
barColor = background;
trimColor = foreground;
}
void display() {
stroke(0);
strokeWeight(1);
noFill();
rect(x, y, w, h);
}
}
void setup() {
size(500, 250);
background(BLUE);
_slider = new Slider(_sliderX, _sliderY, _sliderW, _sliderH, WHITE, BLACK);
_backArrw = new BackArrow(50, 40, 30, 30, GREEN);
_fwdArrw = new ForwardArrow(300, 40, 30, 30, GREEN);
_valueFld = new ValueField(380, 40, 60, 30, str(_initValue), WHITE, BLACK);
}
void draw() {
background(BLUE);
_valueFld.display(value);
_fwdArrw.display();
_backArrw.display();
_slider.display();
// FwdArrw Long Press
if ((mouseX >= _fwdArrw.x) && (mouseX <= _fwdArrw.x + _fwdArrw.w) && (mouseY >= _fwdArrw.y) && (mouseY <= _fwdArrw.y + _fwdArrw.h)) {
if (mousePressed == true) {
_fwdArrw.press();
value++;
if (value > _maxValue) {
value = _maxValue;
}
_valueFld.display(value);
}
}
// BackArrw Long Press
if ((mouseX >= _backArrw.x) && (mouseX <= _backArrw.x + _backArrw.w) && (mouseY >= _backArrw.y) && (mouseY <= _backArrw.y + _backArrw.h)) {
if (mousePressed == true) {
_backArrw.press();
value--;
if (value < _minValue) {
value = _minValue;
}
_valueFld.display(value);
}
}
}
A revision of your code follows;
int x=75;
void setup() {
size(600, 400);
}
void draw() {
background(100);
fill (200);
rect (75, 25, 400, 50); // slider bar
stroke(0);
fill(127, 0, 0);
rect (x, 20, 9, 60); // slider thumb
fill (200);
rect (10, 25, 50, 50); // back arrow
fill(0);
triangle (50, 60, 50, 40, 15, 50);
if ((mouseX >= 10) && (mouseX <= 10 + 50) && (mouseY >= 25) && (mouseY <= 25 + 50) ) {
if (mousePressed == true) {
fill(255);
triangle (50, 60, 50, 40, 15, 50);
x--;
if (x<75) {
x = 75; // minValue
}
} else {
fill(0);
triangle (50, 60, 50, 40, 15, 50);
}
}
fill (200);
rect (490, 25, 50, 50); //forward arrow
fill(0);
triangle (500, 60, 500, 40, 535, 50);
if ((mouseX >= 490) && (mouseX <= 490 + 50) && (mouseY >= 25) && (mouseY <= 25 + 50) ) {
if (mousePressed == true) {
fill(255);
triangle (500, 60, 500, 40, 535, 50);
x++;
if (x>466) {
x = 466; // maxValue
}
} else {
fill(0);
triangle (500, 60, 500, 40, 535, 50);
}
}
}
You've got part of the logic right for the slider/trackbar so it changes x only within a range. This happens horizontally only at this stage, but you can use the same logic to check horizontal limits as well. Similarly, you can check if the cursor is within the bounds of any rectangle (be it the slider or either of the buttons):
int x=75;
void setup() {
size(600, 400);
}
void draw() {
background(100);
// slider
fill (200);
rect (75, 25, 400, 50);
stroke(0);
if (mousePressed) {
if (mouseX >75 && mouseX <= 475)
{
x=mouseX;
}
}
fill(127, 0, 0);
rect (x, 20, 9, 60);
fill (255);
// left arrow button
fill (200);
rect (10, 25, 50, 50);
fill(0);
if (mousePressed == true) {
if (mouseX > 10 && mouseX <= 10 + 50 && mouseY > 25 && mouseY <= 25 + 50){
fill(255);
}
}
triangle (50, 60, 50, 40, 15, 50);
// right arrow button
fill (200);
rect (490, 25, 50, 50);
fill(0);
if (mousePressed == true) {
if (mouseX > 490 && mouseX <= 490 + 50 && mouseY > 25 && mouseY <= 25 + 50){
fill(255);
}
}
triangle (500, 60, 500, 40, 535, 50);
println(x);
}
Wouldn't it be nice if you could take that logic and instead of copy/pasting the different x,y,width,height parameters for the same 4 statements you could group that functionality in a reusable block of code ?
That what functions are for. You're already using them already (defining setup()/draw(), calling background()/fill()/etc.
The Processing Button example already provides the boolean overRect(int x, int y, int width, int height) function which is perfect for you're trying to achieve: pass in the x,y,width,height or a button and get back boolean value.
Here's your code using the overRect():
int x=75;
void setup() {
size(600, 400);
}
void draw() {
background(100);
// slider
fill (200);
rect (75, 25, 400, 50);
stroke(0);
if (mousePressed) {
if (mouseX >75 && mouseX <= 475)
{
x=mouseX;
}
}
fill(127, 0, 0);
rect (x, 20, 9, 60);
fill (255);
// left arrow button
fill (200);
rect (10, 25, 50, 50);
fill(0);
if (mousePressed && overRect(10, 25, 50, 50)) {
fill(255);
x--;
}
triangle (50, 60, 50, 40, 15, 50);
// right arrow button
fill (200);
rect (490, 25, 50, 50);
fill(0);
if (mousePressed && overRect(490, 25, 50, 50)){
fill(255);
x++;
}
triangle (500, 60, 500, 40, 535, 50);
// ensure x remains within the slide limits
x = constrain(x, 75, 475);
println(x);
}
boolean overRect(int x, int y, int width, int height) {
if (mouseX >= x && mouseX <= x+width &&
mouseY >= y && mouseY <= y+height) {
return true;
} else {
return false;
}
}

How to do random generation of barriers for car collision game

How do I create a random car barrier for my game? I have this top-down car game that I need to make. This game aims to make the car move up and down (on the y-axis) to avoid the barriers, while the barriers are moving toward the car (on the x-axis). Is it possible to create a random generation of the barriers when they spawn, making the game enjoyable? Right now, I only have a set of barriers that last for 12 seconds before I get easily through them. Can I also keep the spacing of the barriers the same? So the car can fit.
code
color green = color(0,195,0);
color red = color(195,0,0);
color grey = color(100,100,100);
color yellow = color(200,200,0);
color white = color(255,255,255);
float roadx = 70, road1y = 130;
float road2y = 230, road3y = 330;
float carY = road2y;
float carX = roadx;
float carUPspeed = 1;
float laneX = 700;
float lanes;
void lane1(float x, float y){
fill(white);
rect(x + 100, y,30,100);
rect(x + 250, y + 100,30,100);
rect(x + 250, y + 200, 30, 100);
rect(x + 400, y + 100, 30, 100);
rect(x + 550, y + 100, 30, 100);
rect(x + 550, y, 30, 100);
rect(x + 700, y + 100, 30, 100);
rect(x + 700, y + 200, 30, 100);
}
void background(){
background(green);
}
void car(){
fill(red);
rect(carX, carY, 60, 40);
}
void setup(){
surface.setTitle("dodge");
size(900, 500);
}
void draw(){
background();
noStroke();
fill(grey);
rect(roadx - 400, road1y - 30, 1500, 100);
stroke(yellow);
strokeWeight(5);
rect(roadx - 400, road2y - 30, 1500, 100);
noStroke();
rect(roadx - 400, road3y - 27, 1500, 100);
car();
lane1(laneX, 100);
laneX -= 1;
lanes = 1;
}
void keyPressed(KeyEvent event){
if (key == 'w'){
if(carY != 130){
carY = carY - 100;
}
}
if (key == 's'){
if(carY != 330){
carY = carY + 100;
}
}
}
I've modified your lane rendering and added dynamic creation of barriers. Every 150 pixels moved, the barriers are updated (leftmost barriers are removed, new ones are added at the rightmost position and the cycle starts over).
The barriers are stored as an integer between 0 and 6, as there are 7 possibilities for the barrier positions:
int | 0 1 2 3 4 5 6
------+--------------------
lane0 | # # #
lane1 | # # #
lane2 | # # #
Hope this helps.
Modified code:
import java.util.*;
private static final int SCREEN_X = 900;
private static final int SCREEN_Y = 500;
private static final int LANE_HEIGHT = 100;
private static final int BARRIER_DISTANCE = 150;
private static final int BARRIER_HEIGHT = 100;
private static final int BARRIER_WIDTH = 30;
color green = color(0,195,0);
color red = color(195,0,0);
color grey = color(100,100,100);
color yellow = color(200,200,0);
color white = color(255,255,255);
float roadx = 70, road1y = 130;
float road2y = 230, road3y = 330;
float carY = road2y;
float carX = roadx;
float carUPspeed = 1;
float laneX = 50;
float lanes;
List<Integer> barriers;
void lane1(float x){
fill(white);
for (Integer b : barriers)
{
switch(b)
{
case 0: // ___
break;
case 1: // X__
rect(x, LANE_HEIGHT, BARRIER_WIDTH, BARRIER_HEIGHT);
break;
case 2: // _X_
rect(x, LANE_HEIGHT * 2, BARRIER_WIDTH, BARRIER_HEIGHT);
break;
case 3: // __X
rect(x, LANE_HEIGHT * 3, BARRIER_WIDTH, BARRIER_HEIGHT);
break;
case 4: // _XX
rect(x, LANE_HEIGHT * 2, BARRIER_WIDTH, BARRIER_HEIGHT);
rect(x, LANE_HEIGHT * 3, BARRIER_WIDTH, BARRIER_HEIGHT);
break;
case 5: // XX_
rect(x, LANE_HEIGHT * 1, BARRIER_WIDTH, BARRIER_HEIGHT);
rect(x, LANE_HEIGHT * 2, BARRIER_WIDTH, BARRIER_HEIGHT);
break;
case 6: // X_X
rect(x, LANE_HEIGHT * 1, BARRIER_WIDTH, BARRIER_HEIGHT);
rect(x, LANE_HEIGHT * 3, BARRIER_WIDTH, BARRIER_HEIGHT);
break;
}
x += BARRIER_DISTANCE;
}
}
void background(){
background(green);
}
void car(){
fill(red);
rect(carX, carY, 60, 40);
}
void setup(){
surface.setTitle("dodge");
size(900, 500);
// Initially generate 7 barriers (one more than the screen can fit)
barriers = new ArrayList<Integer>();
for (int i = 0; i <= (SCREEN_X / BARRIER_DISTANCE); i++)
{
barriers.add(int(random(0, 6)));
}
// Set the first to barriers to 'no barrier' to the player initially has some time
barriers.set(0, 0);
barriers.set(1, 0);
}
void draw(){
background();
noStroke();
fill(grey);
rect(roadx - 400, road1y - 30, 1500, LANE_HEIGHT);
stroke(yellow);
strokeWeight(5);
rect(roadx - 400, road2y - 30, 1500, LANE_HEIGHT);
noStroke();
rect(roadx - 400, road3y - 27, 1500, LANE_HEIGHT);
car();
lane1(laneX);
laneX -= 1;
// laneX cycles from 50 to -100 (because of draw position)
// So, every 150 pixels moved
if (laneX == -100)
{
// Reset laneX
laneX = 50;
// Remove leftmost barrier
barriers.remove(0);
// Add new barriers, incoming from the right
barriers.add(int(random(0, 6)));
}
lanes = 1;
}
void keyPressed(KeyEvent event){
if (key == 'w'){
if(carY != 130){
carY = carY - 100;
}
}
if (key == 's'){
if(carY != 330){
carY = carY + 100;
}
}
}

Why is one array value not being used? Processing 3 (java)

I am working on creating a random dungeon generator for a game I am going to make. I just barely did the basics. In order to avoid having to make 20 different variables for the 20 different rectangles I drew, I used two arrays called rx and ry. However, when I went to draw the rectangles using:
rect(rx[19], rx[19], 50, 50)
It didnt put the last rectangle in the correct spot. Rather than putting it at the value that is determined by my code, it always puts rectangle 19 at 0, 0. I am not entirely sure that it is in fact rectangle 19, but I'm assuming it is. I made my two arrays using:
int[] rx = new int[20];
and
int[] ry = new int[20];
Anything helps. Here is the rest of my code just in case it will be useful, however, if you would like me to only give the important bits, tell me. Thanks!
int gx = 400;
int gy = 400;
int gDir;
int gCheckX;
int gCheckY;
int[] rx = new int[20];
int[] ry = new int[20];
int i = 0;
void setup() {
size(700, 700);
}
void draw() {
fill(0);
rect(0, 0, width, height);
fill(#696969);
if(i < 19) {
i++;
gDir = int(random(1, 5));
if(gDir == 1) {
gCheckX = 25;
gCheckY = -25;
}
if(gDir == 2) {
gCheckX = 25;
gCheckY = 75;
}
if(gDir == 3) {
gCheckX = -25;
gCheckY = 25;
}
if(gDir == 4) {
gCheckX = 75;
gCheckY = 25;
}
while(get(gCheckX, gCheckY) == color(105, 105, 105)) {
gDir = int(random(1, 5));
if(gDir == 1) {
gCheckX = 25;
gCheckY = -25;
}
if(gDir == 2) {
gCheckX = 25;
gCheckY = 75;
}
if(gDir == 3) {
gCheckX = -25;
gCheckY = 25;
}
if(gDir == 4) {
gCheckX = 75;
gCheckY = 25;
}
}
if(gDir == 1) {gy -= 50;}
if(gDir == 2) {gy += 50;}
if(gDir == 3) {gx -= 50;}
if(gDir == 4) {gx += 50;}
rx[i] = gx;
ry[i] = gy;
println(rx[i] + " " + ry[i]);
}
else {
rect(rx[0], ry[0], 50, 50);
rect(rx[1], ry[1], 50, 50);
rect(rx[2], ry[2], 50, 50);
rect(rx[3], ry[3], 50, 50);
rect(rx[4], ry[4], 50, 50);
rect(rx[5], ry[5], 50, 50);
rect(rx[6], ry[6], 50, 50);
rect(rx[7], ry[7], 50, 50);
rect(rx[8], ry[8], 50, 50);
rect(rx[9], ry[9], 50, 50);
rect(rx[10], ry[10], 50, 50);
rect(rx[11], ry[11], 50, 50);
rect(rx[12], ry[12], 50, 50);
rect(rx[13], ry[13], 50, 50);
rect(rx[14], ry[14], 50, 50);
rect(rx[15], ry[15], 50, 50);
rect(rx[16], ry[16], 50, 50);
rect(rx[17], ry[17], 50, 50);
rect(rx[18], ry[18], 50, 50);
rect(rx[19], ry[19], 50, 50);
}
}
Got it answered by #Jeremy Kahan. I just had to set i to -1 and it fixed itself!
Since this was my answer, I'm writing it as an answer. The key was to initialize int i = -1; rather than int i = 0;
It works because since the first thing you do inside your if block is i++, you were working with 1, 2, 3, ..., 18, and 19, but never with index 0. Starting at -1 fixed that so you worked with all twenty entries (whose indices are 0 to 19).

Java - how to connect classes, methods, constructors?

I have a game in Processing and there are two classes - main and player. I'm thinking the main class should have the setup and menu, and the player class have the controls, collision, movement etc.
I need help figuring out how to connect the two classes so the game can run. In the main class some variables and methods are not defined so I know I'm not referencing or calling them right.
I'm fairly new to classes and methods so any help would be appreciated. Thanks!
Main class:
//used for setup
//makes program run
//diff currents? play/instr/dead/replay
PFont title, main, dead;
PImage candy, lollipop, cottonCandy;
PImage badApple, bananaPeel, pepper;
PImage panda, heart, bkgrd;
PImage [] goodCandy = new PImage [3];
PImage [] badFood = new PImage [3];
PrintWriter highScore;
String current="menu";
int menuBut1x, menuBut1y;
int menuBut2x, menuBut2y;
int menuBut3x, menuBut3y;
int backButx, backButy;
void setup() {
size(1200,700);
frameRate(30);
title = loadFont("Gabriola-150.vlw");
textFont(title);
main = loadFont("SegoeUI-Light-60.vlw");
textFont(main);
dead = loadFont("Stencil-200.vlw");
textFont(dead);
highScore = createWriter("HighScore.txt");
menuBut1x = width/3-70;
menuBut1y = height/2-100;
menuBut2x = width/3-70;
menuBut2y = height/2+40;
menuBut3x = width/3-70;
menuBut3y = height/2+180;
backButx = 1030;
backButy = 10;
candy = loadImage("goodCandy0.png");
cottonCandy = loadImage("goodCandy1.png");
lollipop = loadImage("goodCandy2.png");
badApple = loadImage("badFood0.png");
bananaPeel = loadImage("badFood1.png");
pepper = loadImage("badFood2.png");
panda = loadImage("panda.png");
heart = loadImage("heart.png");
bkgrd = loadImage("floatClouds.jpg");
for (int i=0; i<goodCandy.length; i++) {
goodCandy[i] = loadImage("goodCandy" + i + ".png"); //loading goodCandy imgs via array
}
for (int i=0; i<badFood.length; i++) {
badFood[i] = loadImage("badFood" + i + ".png"); //loading badFood imgs via array
}
}
public void menu (){
background(#bfefff);
fill(255);
rect(menuBut1x, menuBut1y, 520, 100); //first button
rect(menuBut2x, menuBut2y, 520, 100); //second button
rect(menuBut3x, menuBut3y, 520, 100); //third button
textSize(100);
fill(#000000);
textFont(title);
text("Candy Dash!", 300, 180);
textSize(200);
fill(#000000);
textFont(main);
text("PLAY", 530, 320);
textSize(65);
fill(#000000);
textFont(main);
text("INSTRUCTIONS", 400, 465);
textSize(65);
fill(#000000);
textFont(main);
text("HIGH SCORES", 415, 600);
if (current=="menu") {
//background(#F0D5E2); DON'T HAVE BACKGROUND COLOUR HERE OR WILL COVER EVERYTHING - BKGRD TOP OF VOID DRAW
if (mouseX >= menuBut1x && mouseX <= menuBut1x+520 && mouseY >= menuBut1y && mouseY <= menuBut1y+100 && mousePressed) {
current="play"; //clicked play button
}
if (mouseX >= menuBut2x && mouseX <= menuBut2x+520 && mouseY >= menuBut2y && mouseY <= menuBut2y+100 && mousePressed) {
current="instructions"; //clicked instructions button
}
if (mouseX >= menuBut3x && mouseX <= menuBut3x+520 && mouseY >= menuBut3y && mouseY <= menuBut3y+100 && mousePressed) {
current="high scores"; //clicked high scores button
}
pandaX = 550; //resets the panda to starting position
pandaY = 580; //RESET EVERYTHING WHEN EXIT
points = 0;
}
if (current=="instructions") {
background(#e8f0f7);
textSize(80);
text("INSTRUCTIONS", 360, 140);
textSize(35);
text("Use the arrow keys to move left and right.", 100,240);
text("Your goal is to collect all the yummy candies, and avoid the bad foods!", 100, 300);
text("Watch out! Touch a bad food and YOU ARE DEAD!", 100, 360);
fill(#F0FFF0); //back button
rect(backButx, backButy, 160, 100); //back button
textSize(50);
fill(#000000);
text("MENU", 1040, 75);
textSize(35);
fill(#000000);
text("COLLECT THESE:", 180, 450);
image(candy, 80, 480, 120, 80);
image(lollipop, 220, 480, 100, 170);
image(cottonCandy, 350, 480, 100, 180);
text("AVOID THESE:", 800, 450);
image(badApple, 720, 480, 100, 140);
image(bananaPeel, 830, 480, 180, 170);
image(pepper, 1030, 470, 100, 170);
if (mouseX >= backButx && mouseX <= backButx+160 && mouseY >= backButy && mouseY <= backButy+100 && mousePressed) {
current="menu"; //clicked menu button
}
}
if (current=="high scores") {
background(#e8f0f7);
fill(#F0FFF0);
rect(backButx, backButy, 160, 100); //back button
textSize(50);
fill(#000000);
text("MENU", 1040, 75);
textSize(100);
text("HIGH SCORE: " + points, 300, height/2);
if (mouseX >= backButx && mouseX <= backButx+160 && mouseY >= backButy && mouseY <= backButy+100 && mousePressed) {
current="menu"; //clicked menu button
}
}
if (current=="play") {
image(bkgrd, 0, 0, 1200, 700);
//background(#cfe1e1);
fill(#F0FFF0);
rect(backButx, backButy, 160, 100); //back button
textSize(50);
fill(#000000);
text("MENU", 1040, 75);
candyFall(); //calling methods
touchCandy();
newCandy();
badFoodFall();
if (mouseX >= backButx && mouseX <= backButx+160 && mouseY >= backButy && mouseY <= backButy+100 && mousePressed) {
current="menu"; //clicked menu button
}
}
if (current=="gameOver") {
background(#7B0B1F);
textFont(dead);
textSize(150);
text("YOU ARE DEAD", 70, height/2);
textFont(main);
fill(#fbfbfb);
rect(200, 500, 300, 150); //replay button
textSize(80);
fill(#000000);
noStroke();
text("REPLAY", 220, 600);
fill(#fbfbfb);
rect(700, 500, 300, 150); //menu button
textSize(80);
fill(#000000);
noStroke();
text("MENU", 745, 600);
highScore.println("High Score: " + points); // Write the points to the file
points=0; //reset points to 0 when dead
pandaX = 550; //resets pandaX when dead
pandaY = 580; //resets pandaY when dead
if (mouseX >= 200 && mouseX <= 200+300 && mouseY >= 500 && mouseY <= 500+150 && mousePressed) {
current="play"; //clicked replay
}
if (mouseX >= 700 && mouseX <= 700+300 && mouseY >= 500 && mouseY <= 500+150 && mousePressed) {
current="menu"; //clicked menu button
}
}
}
Player class:
//controls movement of panda, collision w/ falling objects, etc -- all in different methods
import java.io.Serializable;
public class Player implements Serializable {
public int pandaX, pandaY, pandaW, pandaH;
public int candyY, candyX, candyW, candyH;
public int randCandyW, randCandyH, badAppleX, randY, lolliY;
public int rand, randX, randX2, lolliX;
public int points;
public int candySpeed, foodSpeed;
public int yDirCandy, yDirFood;
//constructor of class, where default values are assigned (coordinates, points, etc)
public Player(){
//setting up default coordinates
pandaX = 550;
pandaY = 580;
pandaW = 80;
pandaH = 112;
points = 0;
candySpeed = 10;
foodSpeed = 5;
yDirCandy = 1;
yDirFood = 1;
candyY = 10;
candyX = 200;
candyW = 187;
candyH = 121;
randCandyW = 100;
randCandyH = 100;
badAppleX = 700;
randY = -200;
lolliY = -600;
rand = (int) (2*Math.random()) +1;
randX = (int) (1100*Math.random())+20;
randX2 = (int) (1100*Math.random())+20;
lolliX = (int) (1100*Math.random())+20;
}
public int GetPoints(){ //just test
return points;
}
public void candyFall() {
image(panda, pandaX, pandaY, pandaW, pandaH);
fill(#000000);
text("Points: " + points, 20, 70);
touchCandy();
newCandy();
image(candy, candyX, candyY, candyW, candyH); //original candy
candyY = candyY + (candySpeed * yDirCandy);
image(goodCandy[rand], randX, randY, randCandyW, randCandyH); //rand candy
randY = randY + (candySpeed * yDirCandy);
image(lollipop, lolliX, lolliY, randCandyW, randCandyH); //lolli candy
lolliY = lolliY + (candySpeed * yDirCandy);
highScore.println("High Score: " + points); // Write the points to the file
}
public void badFoodFall(){
image(badFood[rand], randX2, randY, randCandyW, randCandyH); //rand food
randY = randY + (candySpeed * yDirCandy);
image(badApple, badAppleX, randY, randCandyW, randCandyH); //rand food
randY = randY + (candySpeed * yDirFood);
}
public void keyPressed() {
if (key==CODED) {
if (keyCode==LEFT) {
pandaX = pandaX-20;
}
if (keyCode==RIGHT) {
pandaX = pandaX+20;
}
if (pandaX<=5) {
pandaX=5; //if hit into wall panda won't go off screen
}
if (pandaX>=1120) {
pandaX=1120;
}
highScore.flush(); // Writes the remaining data to the file
highScore.close(); // Finishes the file
}
}
public void touchCandy() {
if ( (pandaX + pandaW > candyX && //original candy
pandaX < candyX + candyW &&
pandaY + pandaH > candyY &&
pandaY < candyY + candyH) ||
(pandaX + pandaW > randX && //rand candy
pandaX < randX + randCandyW &&
pandaY + pandaH > randY &&
pandaY < randY + randCandyH) ||
(pandaX + pandaW > lolliX && //lollipop
pandaX < lolliX + randCandyW &&
pandaY + pandaH > lolliY &&
pandaY < lolliY + randCandyH)
)
{
textSize(60);
text("YUM! You get points!", 370, 300);
points = points + 1; //if panda touches candy, get points!
image(heart, pandaX+20, pandaY-50, 50, 50);
}
if ((pandaX + pandaW > randX2 && //rand food
pandaX < randX2 + randCandyW &&
pandaY + pandaH > randY &&
pandaY < randY + randCandyH) ||
(pandaX + pandaW > badAppleX && //apple
pandaX < badAppleX + randCandyW &&
pandaY + pandaH > randY &&
pandaY < randY + randCandyH))
{
current="gameOver";
}
}
public void newCandy() {
if (candyY>=850) {
candyY=0; //resetting the original candy to top
}
if (lolliY>=850) {
lolliY=0; //resetting lolli to top
}
if (randY>=850) {
randY=0;
}
}
}

"The nested type cannot hide an enclosing type" class - Java Processing

I'm getting this error: The nested type cannot hide an enclosing type. I have looked it up, and other people seem to be declaring their class twice, which I am not.
What's weird is if I copy and paste the code into a new processing document, it works with no error. But as I'm converting it to js i need it to work with no errors after saving and opening again.
MotorBike Bike1, Bike2, Bike3, Bike4, Bike5, Bike6, Bike7, Bike8, Bike9;
int Score_Bike1 = 0;
int Score_Bike2 = 0;
int Score_Bike3 = 0;
int Score_Bike4 = 0;
int Score_Bike5 = 0;
int Score_Bike6 = 0;
int Score_Bike7 = 0;
int Score_Bike8 = 0;
int Score_Bike9 = 0;
String Score_Spacing = " ";
int GameState = 0;
class MotorBike {
float Pos_X;
int Pos_Y;
float Speed;
int Size = 30;
float WheelSize = Size / 3;
color Color;
MotorBike(int Declare_X, int Declare_Y, int Declare_Speed, color Declare_Color)
{
this.Pos_X = Declare_X;
this.Pos_Y = Declare_Y;
Speed = Declare_Speed;
Color = Declare_Color;
}
void move()
{
if (GameState == 1) {
Speed = (random(0, 50) / 10);
Pos_X = Pos_X + Speed;
}
}
void render()
{
fill(Color);
triangle(Pos_X, Pos_Y, Pos_X + Size, Pos_Y, Pos_X + Size / 2, Pos_Y -Size / 2);
fill(255);
strokeWeight(1.5);
ellipse(Pos_X, Pos_Y, WheelSize, WheelSize);
ellipse(Pos_X + Size, Pos_Y, WheelSize, WheelSize);
}
}
void setup()
{
size(700, 600);
background(200);
SpawnBikes();
}
void draw()
{
background(200);
strokeWeight(3);
line(50, 10, 50, 590);
line(650, 10, 650, 590);
strokeWeight(1);
MoveBikes();
DetectWinner();
DisplayScore();
}
void MoveBikes()
{
Bike1.render();
Bike1.move();
Bike2.render();
Bike2.move();
Bike3.render();
Bike3.move();
Bike4.render();
Bike4.move();
Bike5.render();
Bike5.move();
Bike6.render();
Bike6.move();
Bike7.render();
Bike7.move();
Bike8.render();
Bike8.move();
Bike9.render();
Bike9.move();
}
void DetectWinner()
{
textSize(15);
fill(0);
if (Bike1.Pos_X >= 620) {
noLoop();
text("Bike 1 Wins", 310, 10, 350, 50);
Score_Bike1 += 1;
GameState = 2;
}
if (Bike2.Pos_X >= 620) {
noLoop();
text("Bike 2 Wins", 310, 10, 350, 50);
Score_Bike2 += 1;
GameState = 2;
}
if (Bike3.Pos_X >= 620) {
noLoop();
text("Bike 3 Wins", 310, 10, 350, 50);
Score_Bike3 += 1;
GameState = 2;
}
if (Bike4.Pos_X >= 620) {
noLoop();
text("Bike 4 Wins", 310, 10, 350, 50);
Score_Bike4 += 1;
GameState = 2;
}
if (Bike5.Pos_X >= 620) {
noLoop();
text("Bike 5 Wins", 310, 10, 350, 50);
Score_Bike5 += 1;
GameState = 2;
}
if (Bike6.Pos_X >= 620) {
noLoop();
text("Bike 6 Wins", 310, 10, 350, 50);
Score_Bike6 += 1;
GameState = 2;
}
if (Bike7.Pos_X >= 620) {
noLoop();
text("Bike 7 Wins", 310, 10, 350, 50);
Score_Bike7 += 1;
GameState = 2;
}
if (Bike8.Pos_X >= 620) {
noLoop();
text("Bike 8 Wins", 310, 10, 350, 50);
Score_Bike8 += 1;
GameState = 2;
}
if (Bike9.Pos_X >= 620) {
noLoop();
text("Bike 9 Wins", 310, 10, 350, 50);
Score_Bike9 += 1;
GameState = 2;
}
}
void DisplayScore()
{
textSize(15);
fill(0);
text("Bike 1: " + Score_Bike1 + Score_Spacing + "Bike 2: " + Score_Bike2 + Score_Spacing + "Bike 3: " +
Score_Bike3 + Score_Spacing + "Bike 4: " + Score_Bike4 + Score_Spacing + "Bike 5: " + Score_Bike5 + Score_Spacing +
"Bike 6: " + Score_Bike6 + Score_Spacing + "Bike 7: " + Score_Bike7 + Score_Spacing + "Bike 8: " + Score_Bike8 +
Score_Spacing + "Bike 9: " + Score_Bike9, 65, 530, 635, 700);
}
void keyPressed()
{
if (keyPressed) {
if (key == ' ')
{
if (GameState == 0) {
GameState = 1;
}
if (GameState == 2) {
loop();
background(200);
SpawnBikes();
GameState = 0;
}
}
}
}
void SpawnBikes()
{
Bike1 = new MotorBike(50, 100, 2, color(255, 0, 0));
Bike2 = new MotorBike(50, 150, 2, color(0, 255, 0));
Bike3 = new MotorBike(50, 200, 2, color(0, 0, 255));
Bike4 = new MotorBike(50, 250, 2, color(255, 255, 0));
Bike5 = new MotorBike(50, 300, 2, color(0, 255, 255));
Bike6 = new MotorBike(50, 350, 2, color(255, 0, 255));
Bike7 = new MotorBike(50, 400, 2, color(100, 255, 0));
Bike8 = new MotorBike(50, 450, 2, color(0, 100, 255));
Bike9 = new MotorBike(50, 500, 2, color(255, 0, 100));
}
Your problem is caused by the fact that you're naming your sketch the same thing as a class you're using inside your sketch. Your sketch can't be named MotorBike if you have a MotorBike class inside that sketch.
Either rename your sketch, or rename your class.
Behind the scenes, this is because Processing exports your sketch as a Java class, and any classes in your sketch become inner classes of that Java class. So your sketch becomes something like this:
class MotorBike{
void draw(){
//whatever
}
class MotorBike{
int x;
//whatever
}
}
This is illegal Java, which is what's causing your error. You can't have an inner class with the same name as a parent class. In other words, a nested type cannot hide an enclosing type.
This is also why it works okay when you copy it into a new sketch- Processing gives your sketch a random default name, so you don't have this name collision until you save your sketch as something else.

Categories