Number grid using arrays or classes in processing (java) coding - java

Using processing I am trying to recreate snakes and ladders games. The grid is done and so is a "dice".
i would like to number the grid like the actual snakes and ladders games. And also add a way that when I move the pawn there will be a link between the "dice" (number that is shown at the bottom of the screen) and the number of boxes the pawn will move.
// Class that displays a single cell of a checker board
class GameBoard {
/*-----------------------properties------------------*/
float x;
float y;
int rVal;
int gVal;
int bVal;
color squareColor; //color of cell fill
int ccSize; //size of cell
/*-----------------------methods---------------------*/
// constructor method
public GameBoard(int tempX, int tempY, color tempColor, int tempSize) {
x = tempX;
y = tempY;
squareColor = tempColor;
ccSize = tempSize;
}
// draws ccColor = tempColor; the cell. This is public because other objects will need to
// be able to tell the object to draw itself.
public void display() {
fill(squareColor);
noStroke();
rectMode(CORNER);
rect(x, y, ccSize, ccSize);
}
}
class Dice {
float xDice;
float yDice;
float diceSize;
String randomNumber = "";
public Dice (float xNewDice, float yNewDice, float newDiceSize) {
xDice = xNewDice;
yDice = yNewDice;
diceSize = newDiceSize;
randomNumber = "4";
}
public void displayDice() {
stroke(0);
fill(255);
rectMode(CENTER);
rect(xDice, yDice, diceSize, diceSize);
}
public void displayNumber() {
textSize(50);
fill(0);
textAlign(CENTER, CENTER);
text(randomNumber, xDice, yDice);
}
public void getRandomNumber() {
float referenceNumber = int(random(1, 7));
if (referenceNumber == 1) {
randomNumber = "1";
}
if (referenceNumber == 2) {
randomNumber = "2";
}
if (referenceNumber == 3) {
randomNumber = "3";
}
if (referenceNumber == 4) {
randomNumber = "4";
}
if (referenceNumber == 5) {
randomNumber = "5";
}
if (referenceNumber == 6) {
randomNumber = "6";
}
}
public void generateRandom() {
textSize(50);
fill(0);
textAlign(CENTER, CENTER);
text(randomNumber, xDice, yDice);
float referenceNumber = int(random(1, 7));
if (referenceNumber == 1) {
randomNumber = "1";
}
if (referenceNumber == 2) {
randomNumber = "2";
}
if (referenceNumber == 3) {
randomNumber = "3";
}
if (referenceNumber == 4) {
randomNumber = "4";
}
if (referenceNumber == 5) {
randomNumber = "5";
}
if (referenceNumber == 6) {
randomNumber = "6";
}
}
}
boolean rollingDice = false;
//create an array of GameBoard objects
GameBoard[] [] squareBoard;
Dice randomDice;
//number of GameBoards
int cellSize = 100;
// set things up
void setup() {
noStroke();
size(700, 800);
background(0);
//initialize the array of GameBoard objects
//base it on the size of the canvas and the size of the individual cells
squareBoard = new GameBoard[width/cellSize][height/cellSize];
randomDice = new Dice (width/2, 750, 80);
//initialize checker board
initCheckerboard();
}
// main drawing loop
void draw() {
background(44, 44, 44);
drawCheckerboard();
randomDice.displayDice();
randomDice.displayNumber();
if(rollingDice) {
randomDice.generateRandom();
}
}
void mouseClicked() {
rollingDice = !rollingDice;
}
// draws a checkerboard pattern
void initCheckerboard() {
// flag to indicate whether to fill with white or black
boolean white = true;
GameBoard cCell;
// flag to indicate whether we are starting an odd or even column
// this is used to ensure that column n + 1 always starts with a different fill
// than column n.
boolean oddColumn = true;
// walk across the x-axis
for (int x=0; x < width; x = x+cellSize) {
// walk down the y-axis
for (int y=0; y < height-100; y = y+cellSize) {
// create the GameBoard
if (white) {
cCell = new GameBoard(x, y, color(64, 64, 64), cellSize);
}
else {
cCell = new GameBoard(x, y, color(44, 44, 44), cellSize);
}
squareBoard[x/cellSize][y/cellSize] = cCell;
//invert the fill color for next cell
white = !white;
}
// make sure that each successive column starts with a different fill
white = !oddColumn;
// flip the flag that tells us whether we're starting an even or odd column
oddColumn = !oddColumn;
}
}
// draws a checkerboard pattern
void drawCheckerboard() {
noStroke();
// walk across the x-axis
for (int x=0; x < width; x = x+cellSize) {
// walk down the y-axis
for (int y=0; y < height-100; y = y+cellSize) {
// draw the GameBoard
squareBoard[x/cellSize][y/cellSize].display();
}
}
}

I tried to change your code as little as possible. As for the movement and the dice, that is a different subject and you have no code in there to do it... I would suggest trying a few things first and if you can't get it ask another question!
As for the numbers as in the snake game you need to fill the rows first, start from below, and every row switch the x of the check rectangles:
// Class that displays a single cell of a checker board
class GameBoard {
/*-----------------------properties------------------*/
float x;
float y;
int rVal;
int gVal;
int bVal;
color squareColor; //color of cell fill
int ccSize; //size of cell
int index;
/*-----------------------methods---------------------*/
// constructor method
public GameBoard(int tempX, int tempY, color tempColor, int tempSize, int i) {
x = tempX;
y = tempY;
squareColor = tempColor;
ccSize = tempSize;
index = i;
}
// draws ccColor = tempColor; the cell. This is public because other objects will need to
// be able to tell the object to draw itself.
public void display() {
fill(squareColor);
noStroke();
rectMode(CORNER);
rect(x, y, ccSize, ccSize);
fill(255);
text(String.valueOf(index), x-ccSize*0.5, y-ccSize*0.5, 200, 200);
}
}
class Dice {
float xDice;
float yDice;
float diceSize;
String randomNumber = "";
public Dice (float xNewDice, float yNewDice, float newDiceSize) {
xDice = xNewDice;
yDice = yNewDice;
diceSize = newDiceSize;
randomNumber = "4";
}
public void displayDice() {
stroke(0);
fill(255);
rectMode(CENTER);
rect(xDice, yDice, diceSize, diceSize);
}
public void displayNumber() {
textSize(50);
fill(0);
textAlign(CENTER, CENTER);
text(randomNumber, xDice, yDice);
}
public void getRandomNumber() {
float referenceNumber = int(random(1, 7));
if (referenceNumber == 1) {
randomNumber = "1";
}
if (referenceNumber == 2) {
randomNumber = "2";
}
if (referenceNumber == 3) {
randomNumber = "3";
}
if (referenceNumber == 4) {
randomNumber = "4";
}
if (referenceNumber == 5) {
randomNumber = "5";
}
if (referenceNumber == 6) {
randomNumber = "6";
}
}
public void generateRandom() {
textSize(50);
fill(0);
textAlign(CENTER, CENTER);
text(randomNumber, xDice, yDice);
float referenceNumber = int(random(1, 7));
if (referenceNumber == 1) {
randomNumber = "1";
}
if (referenceNumber == 2) {
randomNumber = "2";
}
if (referenceNumber == 3) {
randomNumber = "3";
}
if (referenceNumber == 4) {
randomNumber = "4";
}
if (referenceNumber == 5) {
randomNumber = "5";
}
if (referenceNumber == 6) {
randomNumber = "6";
}
}
}
boolean rollingDice = false;
//create an array of GameBoard objects
GameBoard[] [] squareBoard;
Dice randomDice;
//number of GameBoards
int cellSize = 100;
// set things up
void setup() {
noStroke();
size(700, 800);
background(0);
//initialize the array of GameBoard objects
//base it on the size of the canvas and the size of the individual cells
squareBoard = new GameBoard[width/cellSize][height/cellSize];
randomDice = new Dice (width/2, 750, 80);
//initialize checker board
initCheckerboard();
}
// main drawing loop
void draw() {
background(44, 44, 44);
drawCheckerboard();
randomDice.displayDice();
randomDice.displayNumber();
if (rollingDice) {
randomDice.generateRandom();
}
}
void mouseClicked() {
rollingDice = !rollingDice;
}
// draws a checkerboard pattern
void initCheckerboard() {
// flag to indicate whether to fill with white or black
boolean white = true;
GameBoard cCell;
// flag to indicate whether we are starting an odd or even column
// this is used to ensure that column n + 1 always starts with a different fill
// than column n.
boolean oddColumn = true;
int index = 0;
boolean switcher = false;
// walk down the y-axis
for (int y=height-100-cellSize; y >= 0 ; y = y-cellSize) {
// walk across the x-axis
for (int x=0; x < width; x = x+cellSize) {
// create the GameBoard
int nx = x;
if(switcher) nx = width - cellSize - x;
if (white) {
cCell = new GameBoard(nx, y, color(64, 64, 64), cellSize, index);
}
else {
cCell = new GameBoard(nx, y, color(44, 44, 44), cellSize, index);
}
println(y);
squareBoard[x/cellSize][y/cellSize] = cCell;
//invert the fill color for next cell
white = !white;
index++;
}
switcher = !switcher;
// make sure that each successive column starts with a different fill
white = !oddColumn;
// flip the flag that tells us whether we're starting an even or odd column
oddColumn = !oddColumn;
}
}
// draws a checkerboard pattern
void drawCheckerboard() {
noStroke();
// walk across the x-axis
for (int x=0; x < width; x = x+cellSize) {
// walk down the y-axis
for (int y=0; y < height-100; y = y+cellSize) {
// draw the GameBoard
squareBoard[x/cellSize][y/cellSize].display();
}
}
}

Related

How to change color automatically in processing.exe?

I currently learned about processing.exe. I've made a snake game in processing and I want to modify it. What I want is every time the snake eats food, the food that is moving randomly also gets given random colors.
here's my code:
snake s;
int grid = 15;
PVector food;
int r;
int g;
int b;
int warna;
void setup() {
size(600, 600);
s = new snake();
food = new PVector();
r = (int)random(255);
g = (int)random(255);
b = (int)random(255);
frameRate(15);
newFood();
}
void draw() {
background(0);
s.showScore();
s.display();
if (s.gameOver()) {
background(0);
textAlign(LEFT);
textSize(25);
fill(255);
text("Game Over", 10, 10, width - 20, 50);
noLoop();
}
if (s.eat(food)) {
newFood();
}
s.move();
fill (r, g, b);
rect (food.x, food.y, grid, grid);
}
void newFood() {
food.x = floor(random(width));
food.y = floor(random(height));
food.x = floor(food.x/grid) * grid;
food.y = floor(food.y/grid) * grid;
if (food.x == floor(random(width)) && food.y == floor(random(height))){
fill (r = (int)random(255), g = (int)random(255), b = (int)random(255));
rect( food.x, food.y, grid, grid);
}
}
void keyPressed() {
if (keyCode == UP) {
s.arah(0, -1);
} else if (keyCode == DOWN) {
s.arah(0, 1);
} else if (keyCode == RIGHT) {
s.arah(1, 0);
} else if (keyCode == LEFT) {
s.arah(-1, 0);
}
}
And this are the snake :
class snake {
float x = 0;
float y = 0;
float xspd = 1;
float yspd = 0;
int panjang = 0;
ArrayList<PVector> body = new ArrayList<PVector>();
snake() {
}
boolean eat(PVector pos) {
float d = dist(x, y, pos.x, pos.y);
if (d < 1) {
panjang++;
return true;
} else {
return false;
}
}
void arah(float x, float y) {
xspd = x;
yspd = y;
}
boolean gameOver() {
for (int i = 0; i < body.size(); i++) {
PVector pos = body.get(i);
float d = dist(x, y, pos.x, pos.y);
if (d < 1) {
panjang = 0;
body.clear();
return true;
}
}
return false;
}
void move() {
if (panjang > 0) {
if (panjang == body.size() && !body.isEmpty()) {
body.remove(0);
}
body.add(new PVector(x, y));
}
x = x + xspd*grid;
y = y + yspd*grid;
x = (x + width) % width;
y = (y + height) % height;
}
void display() {
noStroke();
fill(255);
for (PVector bagi : body) {
rect(bagi.x, bagi.y, grid, grid);
}
rect(x, y, grid, grid);
}
void showScore() {
textAlign(LEFT);
textSize(25);
fill(255);
text("Score: " + body.size(), 10, 10, width - 20, 50);
}
}
I've tried to change the color with declare r, g, b and assign a random color to it. But the food color doesn't seem to change every time the snake eats the food. Any suggestions on what I should do?
You're doing good so far. The only part you missed is that you want to change the food's color when you create some new food. So... you just have to take this part of the setup() method:
r = (int)random(255);
g = (int)random(255);
b = (int)random(255);
and move it in the newFood() method.
Hope this helps. Have fun!

Collisions in processing

My game is a shooting game for school. I need help on the collision between my bullet and my enemy. I have placed the bullet class with my player but for some reason it keeps on passing through it and not disappearing. The first example below shows the weapon class which is for the bullet and the one underneath that is the main.
class Weapons{
PImage bullet;
int speed;
int imageSize = 20;
float x = 20;
float y = 20;
float m;
int damage = 5;
int[] src = new int[2];
float[] dest = new float[2];
Weapons(int x, int y){
speed = 12;
dest[0] = mouseX;
dest[1] = mouseY;
src[0] = x;
src[1] = y;
m = (dest[1]-src[1]) / (dest[0]-src[0]);
this.x = x;
this.y = y;
bullet = loadImage("bullet.png");
bullet.resize(imageSize,imageSize);
}
boolean shooting(){
image(bullet, x, y); // if attack is true then renfer the image
x += speed;
y = (m * (x - dest[0])) + dest[1];
return (x > width || y > height);
}
boolean crash(Enemy enemies) {
//// return the result of checking if the plane has crashed into the bird
return abs(this.x-enemies.x) < bullet.width && abs(this.y - enemies.y) < bullet.height;
}
}
Maincharacter MC;
Goal G;
ArrayList<Enemy> enemies = new ArrayList<>();
ArrayList<Weapons> bullets = new ArrayList<>();
final int Playing = 0;
final int Finish = 1;
int gameMode = Playing;
//Enemy[] enemies = new Enemy[10];
PImage background; // creating background
int bgX = 0;
void setup(){
size(800,500);
MC = new Maincharacter(100,3);
//E1 = new Enemy();
G = new Goal(100,20);
background = loadImage("Battleground1.png");
background.resize(width*2,height); //set image to be same size as the canvas
for(int i = 0; i<2; i++){ // i represent how many enemy I want.
enemies.add(new Enemy((int)random(200,850), (int)random(0, height- 150) ) );
}
//for(int i=0 ; i < enemies.length ; i++){
//enemies[i] = new Enemy(); }
}
void draw(){
if(gameMode == Playing){
background();
MC.display();
G.display();
for(Enemy E : enemies){
E.update();
if (MC.crash(E)){
gameMode = Finish;
}
}
for(Weapons W: bullets){
W.update();
if(enemies.crash(W)){ // doesnt exist
gameMode = Finish;
}
}
// for(int i=0 ; i < enemies.length ; i++){
//enemies[i].update(); }
}}
void keyPressed(){
// creating the movemnt for my main charcter
MC.move();
if (keyCode == RIGHT || keyCode == 68 ){
MC.x += 10;
} else if (keyCode == UP || keyCode == 87) {
MC.y -=10;
} else if (keyCode == LEFT || keyCode == 65){
MC.x -= 10;
} else if(keyCode == DOWN || keyCode == 83 ){
MC.y += 10;
} else if (keyCode == 32) { // space bar
MC.attack_function(); // call attack function to create bullet object
}// make an attack
}
void mousePressed(){ // when mouse is pressed call attack function to create bullet object
MC.attack_function();
}
void background(){
//scrolling background image
image(background, bgX, height/2); //draw image to fill the canvas
//draw image again off the right of the canvas
image(background, bgX+background.width, height/2);
bgX -= 4;
if(bgX == -background.width ) //if first image completely off the canvas
{
bgX=0; //reset back to initial value background
}
}
What I want is to have bullet colliding with the enemies and then disappearing.
You are trying to call the method enemies.crash(W) but enemies is some collection of Enemy instances. Enemy does not provide the method crash as well.
You have to loop for each of your enemies all of your weapons and call the method crash on the Weapon instance giving the current enemy, something like:
for (Enemy enemy: enemies){
enemy.update();
if (mainCharacter.crash(enemy)) {
gameMode = Finish;
}
for (Weapons weapon: bullets) {
weapon.update();
if (weapon.crash(enemy)) {
gameMode = Finish;
// TODO: are you sure that killing an enemy finishes the game?
}
}
}
(Please note that I used mainCharacter instead of MC here for better readability.)

How can I fix my crash method/collision detection between my player and other objects?

Currently, I'm making a 2d java game that includes a tank at the top of the screen shooting the oncoming cars from below, I have made a crash method and collision detection which determines to stop the game when the tank crashes or enters the radius of the cars. However, sometimes it works early, sometimes late and other times it doesn't. My question is how can I fix it so that when the tank enters the radius of the car it stops the game with simple code that excludes vectors.
Below are my classes and code.
I'm using Java in Processing.
PImage bg; //loads bakground
PFont f; //loads font
Car[] cars = new Car[3];
//Bullet[] bullets = new Bullet[100];
int x = 0;
int y = 0;
int game = 0;
int running = 0;
int over = 1;
int score = 0;
int move = 20;
int cX, cY;
//int carRadius = 20;
Tank tank;
void setup()
{
size(500,1000);
textSize(40);
bg = loadImage("bg.jpeg"); //loads background
bg.resize(width,height); //the background will fill the height and width of the screen size
tank = new Tank(tankX, tankY, 3, 2); //X pos, Y pos, speedY
for (int i=0; i<cars.length; i++)
{
int cX = (int)random(width-100); //car xpos
int cY = (int)random(900); //car ypos
int speedY = 3; //car speedY
cars[i] = new Car(cX, cY, speedY);
}
cars[0] = new Car((int)random(5, width-100), (int)random(5, height), 2); //X pos, Y pos, speedY
cars[1] = new Car((int)random(5, width-100), (int)random(5, height), 2); //X pos, Y pos, speedY
cars[2] = new Car((int)random(5, width-100), (int)random(5, height), 2); //X pos, Y pos, speedY
f = createFont("Arial", 36, true);
}
void draw()
{
if (game == running)
{
drawBackground(); //background
for (Car c : cars) {
c.draw();
c.move();
}
tank.draw(); //tank
drawScore(); //draw score
//if (bullet.crash(cars[0]) == true) {
// cars.remove(c);
// score++;
//}
if (game == over)
{
tank.speedX = 0;
tank.speedY = 0;
move = 0;
gameOver();
}
//if tank crashes into cars
if(tank.crash(cars[0]))
{
game = over;
gameOver();
}
if(tank.crash(cars[1]))
{
game = over;
gameOver();
}
if(tank.crash(cars[2]))
{
game = over;
gameOver();
}
/*
if(bullet.shoot(cars[0]))
{
cars[0].remove(c);
score++;
}
if(bullet.shoot(cars[1]))
{
cars[1].remove(c);
score++;
}
if(bullet.shoot(cars[2]))
{
cars[2].remove(c);
score++;
}
*/
}
}
void keyReleased() {
tankXD = 0;
tankYD = 0;
}
void keyPressed() //controls for the tank using the arrow keys
{
if(keyCode == LEFT) {
tankXD =- 10;
}
if(keyCode == RIGHT) {
tankXD = 10;
}
if(keyCode == DOWN) {
tankYD = 10;
}
if(keyCode == UP) {
tankYD =- 10;
}
if(keyCode == ' ') {
bulletSPD = 30;
//bullets.add(new Bullet(tank.x+30, tank.y+140, 3));
}
}
//void carFill()
// {
// fill(255,0,0);
// }
void drawBackground()
{
image(bg, y, 0);
}
void drawScore() {
fill(255);
textFont(f);
text("Score: " + String.valueOf(score), 200, 50);
}
void gameOver() {
clear();
textFont(f);
text("Game Over! ", 150, 400);
}
class Car
{
//members
int cX, cY;
int speedY = 2;
int speedX = 0;
int animationCounter = 0;
int carRadius = 30;
PImage image1,image2,image3;
//constructor
Car(int cX, int cY, int speedY)
{
this.cX = cX;
this.cY = cY;
this.speedY = speedY;
image1 = loadImage("c1.png");
image2 = loadImage("c2.png");
image3 = loadImage("c3.png");
}
void update() {
draw();
move();
}
void move()
{
this.cY = this.cY - speedY; //move upwards
if(this.cY < 0 - image1.height)
this.cY = height + image1.height;
if(this.cY > height + image1.height +30)
this.cY = -image1.height;
}
void draw()
{
if (animationCounter >=0 & animationCounter <=8)
{ image(image1,this.cX,this.cY); }
else if (animationCounter >8 & animationCounter <=16)
{ image(image2,this.cX,this.cY); }
else
{ image(image3,this.cX,this.cY); }
animationCounter = animationCounter + 1;
if(animationCounter>20)
animationCounter = 0;
}
}
int tankX = 215; //tank xpos
int tankY = 60; //tank ypos
int tankXD = 0; //tank x dir
int tankYD = 0; //tank y dir
int bulletX = tankX; //bullet xpos
int bulletY = tankY; //bullet ypos
int bulletW = 8; //bullet xpos
int bulletH = 20; //bullet ypos
int bulletSPD = 0; //bullet speed
int bulletRadius = 4;
float bulletDistance = 5;
PImage image1;
class Tank
{
//members
int tankX;
int tankY;
int speedX;
int speedY;
//constructor
Tank (int tankX, int tankY, int speedX, int speedY)
{
this.tankX = tankX;
this.tankY = tankY;
this.speedX = speedX;
this.speedY = speedY;
image1 = loadImage("tank.png");
}
void draw() {
image(image1,tankX, tankY);
tankX+=tankXD;
tankY+=tankYD;
bulletX=tankX;
bulletY+=bulletSPD;
if(bulletY>800) {
bulletX=tankX;
bulletY=tankY;
bulletSPD=0;
}
//draw bullet
fill(255,0,0);
stroke(255,0,0);
rect(bulletX+30, bulletY+140, bulletW, bulletH);
}
//tank crash method
boolean crash(Car other)
{
return (abs(this.tankY-other.cY) <20) && abs(this.tankX-other.cX) <10;
}
/*
boolean shoot (Bullet b, Car c) {
float d = dist(bulletX, bulletY, cX, cY);
if ((d < 5) == true) {
// we have a collision
return true;
} else {
return false;
}
}
*/
/*
boolean shoot(Car c) {
float d = dist(bulletX, bulletY, cX, cY);
if (d < 5) {
// we have a collision
return true;
} else {
return false;
}
}
*/
}
So I believe you want to fix the collision. If you have two circles and you want to see if they collide, you need to see if the radii collide. You can do this by seeing if the distance between the centers is greater than or less than the total of the two radii. Like this:
//returns whether or not two circles collide
//x1, y1, and r1 are for circle 1
boolean colliding(int x1, int y1, int x2, int y2, int r1, int r2) {
return sqrt(pow(x1-x2, 2) + pow(y1-y2, 2)); <= r1 + r2
}
If you wish to use rectangular hitboxes instead, check this link.
I hope this helped, have a good day.

Cannot get sprite to collide with map images (java)

I am creating a 2D game which the zombie moves with WASD keys and is supposed to collide with the walls and not enter them, as well as collide with the brains and removes them. Every type of code I have used does not create collision. I am using a zombie sprite sheet i found on google as well as 2 backgroundless images for walls and brains.
After I figure out collision, I then then to implement a autorun sequence to where it bounces around like a screensaver and does the same thing just automatically until all brains are collected.
The EZ is just a library that is utilized by UH Manoa, that can be found here: EZ Graphics
Main
import java.awt.Color;
import java.io.FileReader;
import java.util.Scanner;
public class ZombieMain {
static EZImage[] walls = new EZImage[500];
static EZImage[] sideWalls = new EZImage[500];
static EZImage[] brains = new EZImage[50];
static int wallsCount = 0;
static int sideWallsCount = 0;
static int brainsCount = 0;
/*public static void addWall(EZImage wall) {
walls[wallsCount] = wall;
wallsCount++;
}
public static void addCoin(EZImage brain) {
brains[brainsCount] = brain;
brainsCount++;
}*/
/*public static void CollisingCoin(EZImage me) {
int x = me.getXCenter();
int y = me.getYCenter();
for (int i = 0; i < brainsCount; i++) {
if ((brains[i].isPointInElement(me.getXCenter() - 30, me.getYCenter() - 30))
|| (brains[i].isPointInElement(me.getXCenter() + 30, me.getYCenter() - 30))
|| (brains[i].isPointInElement(me.getXCenter() - 30, me.getYCenter() + 30))
|| (brains[i].isPointInElement(me.getXCenter() + 30, me.getYCenter() + 30))) {
brains[i].translateTo(-20, -20);
System.out.println("You ate a brain!");
}
}
}*/
public static void main(String[] args) throws java.io.IOException {
//initialize scanner
Scanner fScanner = new Scanner(new FileReader("boundaries.txt"));
int w = fScanner.nextInt();
int h = fScanner.nextInt();
String inputText = fScanner.nextLine();
//create backdrop
EZ.initialize(w*33,h*32);
EZ.setBackgroundColor(new Color(0, 0,0));
Zombie me = new Zombie("zombieSheet.png", 650, 450, 65, 63, 10);
//set reading parameters and establish results of case readings
int row = 0;
while(fScanner.hasNext()) {
inputText = fScanner.nextLine();
for (int column = 0; column < inputText.length(); column++){
char ch = inputText.charAt(column);
switch(ch){
case 'W':
walls[wallsCount] = EZ.addImage("barbwire.jpg", column*32, row*32);
wallsCount++;
break;
case 'M':
sideWalls[wallsCount] = EZ.addImage("barb.jpg", column*32, row*32);
wallsCount++;
break;
case 'B':
brains[brainsCount] = EZ.addImage("brains.png", column*32, row*32);
brainsCount++;
break;
default:
// Do nothing
break;
}
//printed count of walls, side walls, and brains
System.out.println("W = " + wallsCount);
System.out.println("M = " + sideWallsCount);
System.out.println("B = " + brainsCount);
}
row++;
}
fScanner.close();
while (true) {
// check if going to collide with wall
// we want to check this before we actually move
// otherwise, we get "stuck" in a situation where we can't move
// if no collision, we can move
/*if (EZInteraction.isKeyDown('a')) {
if (!isCollisingWall(me, -2, 0)) {
me.translateBy(-2, 0);
}
} else if (EZInteraction.isKeyDown('d')) {
if (!isCollisingWall(me, 2, 0)) {
me.translateBy(2, 0);
}
} else if (EZInteraction.isKeyDown('w')) {
if (!isCollisingWall(me, 0, -2)) {
me.translateBy(0, -2);
}
} else if (EZInteraction.isKeyDown('s')) {
if (!isCollisingWall(me, 0, 2)) {
me.translateBy(0, 2);
}
}*/
me.go();
EZ.refreshScreen();
}
}
}
Sprite
public class Zombie {
EZImage zombieSheet;
int x = 0; // Position of Sprite
int y = 0;
int zombieWidth; // Width of each sprite
int zombieHeight; // Height of each sprite
int direction = 0; // Direction character is walking in
int walkSequence = 0; // Walk sequence counter
int cycleSteps; // Number of steps before cycling to next animation step
int counter = 0; // Cycle counter
Zombie(String imgFile, int startX, int startY, int width, int height, int steps) {
x = startX; // position of the sprite character on the screen
y = startY;
zombieWidth = width; // Width of the sprite character
zombieHeight = height; // Height of the sprite character
cycleSteps = steps; // How many pixel movement steps to move before changing the sprite graphic
zombieSheet = EZ.addImage(imgFile, x, y);
setImagePosition();
}
private void setImagePosition() {
// Move the entire sprite sheet
zombieSheet.translateTo(x, y);
// Show only a portion of the sprite sheet.
// Portion is determined by setFocus which takes 4 parameters:
// The 1st two numbers is the top left hand corner of the focus region.
// The 2nd two numbers is the bottom right hand corner of the focus region.
zombieSheet.setFocus(walkSequence * zombieWidth, direction, walkSequence * zombieWidth + zombieWidth, direction + zombieHeight);
}
public void moveDown(int stepSize) {
y = y + stepSize;
direction = 0;
if ((counter % cycleSteps) == 0) {
walkSequence++;
if (walkSequence > 6)
walkSequence = 0;
}
counter++;
setImagePosition();
}
public void moveLeft(int stepSize) {
x = x - stepSize;
direction = zombieHeight * 2;
if ((counter % cycleSteps) == 0) {
walkSequence--;
if (walkSequence < 0)
walkSequence = 6;
}
counter++;
setImagePosition();
}
public void moveRight(int stepSize) {
x = x + stepSize;
direction = zombieHeight;
if ((counter % cycleSteps) == 0) {
walkSequence++;
if (walkSequence > 6)
walkSequence = 0;
}
counter++;
setImagePosition();
}
public void moveUp(int stepSize) {
y = y - stepSize;
direction = zombieHeight * 3;
if ((counter % cycleSteps) == 0) {
walkSequence--;
if (walkSequence < 0)
walkSequence = 6;
}
setImagePosition();
counter++;
}
// Keyboard controls for moving the character.
public void go() {
if (EZInteraction.isKeyDown('w')) {
moveUp(2);
} else if (EZInteraction.isKeyDown('a')) {
moveLeft(2);
} else if (EZInteraction.isKeyDown('s')) {
moveDown(2);
} else if (EZInteraction.isKeyDown('d')) {
moveRight(2);
}
}
public void translateBy(int i, int j) {
// TODO Auto-generated method stub
}
public int getXCenter() {
// TODO Auto-generated method stub
return x;
}
public int getYCenter() {
// TODO Auto-generated method stub
return y;
}
public int getWidth() {
// TODO Auto-generated method stub
return 0;
}
public int getHeight() {
// TODO Auto-generated method stub
return 0;
}
}
EZElement provides a getBounds property, which returns a java.awt.Shape object; why is this important? Because the Java 2D Graphics API already provides some hit detection.
From this, we then need to determine the player shape's intersection with any other shapes. To do this, we need to wrap both shapes in a Area and use it to make the final determinations.
Area meArea = new Area(me.getBounds());
Area checkArea = new Area(elementToCheck.getBounds());
checkArea(meArea);
if (!checkArea.isEmpty()) {
//... We have collision
}
Obviously, this should all be wrapped up in some kind of method to handle the core functionality, but you could have a helper method which simply took two EZElements and return true/false if the collide
For brevity and testing, I stripped back your example, but the basic idea should continue to work
import java.awt.Color;
import java.awt.Shape;
import java.awt.geom.Area;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Test {
private List<EZImage> brains = new ArrayList<>(25);
private Zombie me;
public static void main(String[] args) throws java.io.IOException {
new Test();
}
public Test() {
int w = 10;
int h = 10;
//create backdrop
EZ.initialize(w * 33, h * 32);
EZ.setBackgroundColor(new Color(0, 0, 0));
me = new Zombie("Zombie.png", 0, 0);
brains.add(EZ.addImage("Brains.png", (w * 33) / 2, (h * 32 / 2)));
while (true) {
detectCollision();
// check if going to collide with wall
// we want to check this before we actually move
// otherwise, we get "stuck" in a situation where we can't move
// if no collision, we can move
/*if (EZInteraction.isKeyDown('a')) {
if (!isCollisingWall(me, -2, 0)) {
me.translateBy(-2, 0);
}
} else if (EZInteraction.isKeyDown('d')) {
if (!isCollisingWall(me, 2, 0)) {
me.translateBy(2, 0);
}
} else if (EZInteraction.isKeyDown('w')) {
if (!isCollisingWall(me, 0, -2)) {
me.translateBy(0, -2);
}
} else if (EZInteraction.isKeyDown('s')) {
if (!isCollisingWall(me, 0, 2)) {
me.translateBy(0, 2);
}
}*/
me.go();
EZ.refreshScreen();
}
}
public boolean doesCollide(EZElement element, EZElement with) {
Area a = new Area(element.getBounds());
Area b = new Area(with.getBounds());
a.intersect(b);
return !a.isEmpty();
}
public void detectCollision() {
Iterator<EZImage> obstacles = brains.iterator();
while (obstacles.hasNext()) {
EZElement next = obstacles.next();
if (doesCollide(me.zombieSheet, next)) {
System.out.println("Me = " + me.getBounds().getBounds());
System.out.println("next = " + next.getBounds().getBounds());
EZ.removeEZElement(next);
obstacles.remove();
}
}
}
public class Zombie {
EZImage zombieSheet;
int x = 0; // Position of Sprite
int y = 0;
Zombie(String imgFile, int startX, int startY) {
x = startX; // position of the sprite character on the screen
y = startY;
zombieSheet = EZ.addImage(imgFile, x, y);
setImagePosition();
}
public Shape getBounds() {
return zombieSheet.getBounds();
}
private void setImagePosition() {
// Move the entire sprite sheet
zombieSheet.translateTo(x, y);
}
public void moveDown(int stepSize) {
y = y + stepSize;
setImagePosition();
}
public void moveLeft(int stepSize) {
x = x - stepSize;
setImagePosition();
}
public void moveRight(int stepSize) {
x = x + stepSize;
setImagePosition();
}
public void moveUp(int stepSize) {
y = y - stepSize;
setImagePosition();
}
// Keyboard controls for moving the character.
public void go() {
if (EZInteraction.isKeyDown('w')) {
moveUp(2);
} else if (EZInteraction.isKeyDown('a')) {
moveLeft(2);
} else if (EZInteraction.isKeyDown('s')) {
moveDown(2);
} else if (EZInteraction.isKeyDown('d')) {
moveRight(2);
}
}
}
}
I would recommend that you give each entity (and block/tile) a collision box, then test if a specific entity's bounding box collided with another entity's bounding box, then make it so that the entities can't move in that direction until there isn't a bounding box in a direction, if that made any since.
Do the same for testing for the brains, though I recommend making an ArrayList of brains, and removing specific ones if that brain had been touched.

Brick breaker brick color

I am trying to have each brick in my game have a random color, however when I try to do this the whole set of bricks become the same color. How do I make each individual brick a random color? Any help is appreciated.
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class Game extends JoeApplet implements KeyListener
{
String status;
int ballx = 294; // ball spawn x coordinate
int bally = 640; // ball spawn y coordinate
int batx = 294;
int baty = 654;
int brickx = 32;
int bricky = 50;
double movex = -16; // x speed of ball
double movey = -16; //y speed of ball
int count = 0;
int currentLevel=0;
int score=0; //starts score at 0
int lives=3; //lives start at 3
static boolean right = false;
static boolean left = false;
boolean ballFallDown = false;
boolean bricksOver = false;
Rectangle Ball = new Rectangle(ballx, bally, 14, 14); //creates ball
Rectangle Bat = new Rectangle(batx, baty, 100, 12); //creates bat(paddle)
Rectangle[] Brick = new Rectangle[49]; //creates desired number of bricks
public void paint(Graphics art)
{
switch(currentLevel)
{
case 0:
menuScreen(art);
break;
case 1:
game(art);
break;
}
}
public void menuScreen(Graphics art)
{
setSize(700, 700);
art.setColor(Color.BLACK);
art.fillRect(0, 0, 698, 698);
Color ballcolor=new Color(0,0,66);
art.setColor(ballcolor);
art.fillOval(Ball.x, Ball.y, Ball.width, Ball.height);
Color batcolor=new Color(0,0,66);
art.setColor(batcolor);
art.fill3DRect(Bat.x, Bat.y, Bat.width, Bat.height, true);
art.setColor(Color.green);
art.drawRect(0, 0, 698, 698);
art.setColor(Color.yellow);
Font menu = new Font("Arial", Font.BOLD, 20);
art.setFont(menu);
art.drawString("Brick Breaker", 100,400);
art.drawString("Press P to Play", 100,425);
art.drawString("Press Q to Quit game", 100,450);
for (int i = 0; i < Brick.length; i++)
{
if (Brick[i] != null)
{
Color mycolor=new Color(100,0,0);
art.setColor(mycolor);
art.fill3DRect(Brick[i].x, Brick[i].y, Brick[i].width,
Brick[i].height, true);
}
}
art.setColor(Color.YELLOW);
if (ballFallDown || bricksOver)
{
Font f = new Font("Arial", Font.BOLD, 20);
art.setFont(f);
art.drawString(status, 294, 349);
ballFallDown = false;
bricksOver = false;
}
}
public void game(Graphics art)
{
setSize(700, 700);
art.setColor(Color.BLACK);
art.fillRect(0, 0, 698, 698);
Color ballcolor=new Color(0,0,225);
art.setColor(ballcolor);
art.fillOval(Ball.x, Ball.y, Ball.width, Ball.height);
Color batcolor=new Color(0,0,139);
art.setColor(batcolor);
art.fill3DRect(Bat.x, Bat.y, Bat.width, Bat.height, true);
art.setColor(Color.green);
art.drawRect(0, 0, 698, 698);
for (int i = 0; i < Brick.length; i++)
{
if (Brick[i] != null)
{
Color mycolor=new Color(200,0,0);
art.setColor(mycolor);
art.fill3DRect(Brick[i].x, Brick[i].y, Brick[i].width,
Brick[i].height, true);
}
}
if (ballFallDown || bricksOver)
{
Font f = new Font("Arial", Font.BOLD, 20);
art.setFont(f);
art.drawString(status, 100,425);
ballFallDown = false;
bricksOver = false;
}
for (int i = 0; i < Brick.length; i++)
{
if (Brick[i] != null)
{
if (Brick[i].intersects(Ball))
{
score=score+10;
Brick[i] = null;
movey = -movey;
count++;
}
}
}
if (count == Brick.length)
{
bricksOver = true;
movex=0;
movey=0;
art.setColor(Color.green);
status = "YOU BEAT THE LEVEL!!";
art.drawString("Press E to Exit", 100,450);
art.drawString("Press N for Next Level", 100,475);
repaint();
}
repaint();
Font f = new Font("Arial", Font.BOLD, 20);
art.setFont(f);
art.setColor(Color.white);
art.drawString("Score:"+score, 600, 684);
Ball.x += movex;
Ball.y += movey;
if (left == true)
{
Bat.x -= 18;
right = false;
}
if (right == true)
{
Bat.x += 18;
left = false;
}
if (Bat.x <= 4)
{
Bat.x = 4;
}
else if (Bat.x >= 586)
{
Bat.x = 596;
}
if (Ball.intersects(Bat))
{
movey = -movey-.1;
}
if (Ball.x <= 0 || Ball.x + Ball.height >= 698)
{
movex = -movex;
}
if (Ball.y <= 0)
{
movey = -movey;
}
Font f1 = new Font("Arial", Font.BOLD, 20);
art.setFont(f1);
art.setColor(Color.white);
art.drawString("Lives:"+ lives, 5, 684);
if (Ball.y >= 698 && (bricksOver==false) && lives>0)
{
ballFallDown = true;
art.setColor(Color.red);
status = "";
art.drawString("", 100,450);
lives=lives-1;
ballx = 294;
bally = 640;
Ball = new Rectangle(ballx, bally, 14, 14);
movex = -16;
movey = -16;
repaint();
}
if(lives==0 && Ball.y >= 698)
{
art.setColor(Color.red);
art.drawString("You lost!!", 100,425);
art.drawString("Press E to Exit", 100,450);
}
}
public void init()
{
addKeyListener(this);
for (int i = 0; i < Brick.length; i++) //creates bricks
{
Brick[i] = new Rectangle(brickx, bricky, 40, 20);
if (i == 12) //1st row of bricks
{
brickx = 32;
bricky = 84;
}
if (i == 23) //2nd row of bricks
{
brickx = 82;
bricky = 118;
}
if (i == 32) //3rd row of bricks
{
brickx = 132;
bricky = 152;
}
if (i == 39) //4th row of bricks
{
brickx = 182;
bricky = 186;
}
if (i == 44) //5th row of bricks
{
brickx = 232;
bricky = 220;
}
if (i == 47) //6th row of bricks
{
brickx = 282;
bricky = 254;
}
if (i == 48) //7th row of bricks
{
brickx = 144;
bricky = 132;
}
brickx += 50; //spacing between each brick
}
}
public void restart()
{
ballx = 294;
bally = 640;
batx = 294;
baty = 654;
brickx = 32;
bricky = 50;
Ball = new Rectangle(ballx, bally, 14, 14);
Bat = new Rectangle(batx, baty, 100, 12);
movex = -16;
movey = -16;
ballFallDown = false;
bricksOver = false;
count = 0;
status = null;
for (int i = 0; i < Brick.length; i++) //recreates bricks
{
Brick[i] = new Rectangle(brickx, bricky, 40, 20);
if (i == 12)
{
brickx = 32;
bricky = 84;
}
if (i == 23)
{
brickx = 82;
bricky = 118;
}
if (i == 32)
{
brickx = 132;
bricky = 152;
}
if (i == 39)
{
brickx = 182;
bricky = 186;
}
if (i == 44)
{
brickx = 232;
bricky = 220;
}
if (i == 47)
{
brickx = 282;
bricky = 254;
}
if (i == 48)
{
brickx = 144;
bricky = 132;
}
brickx += 50;
}
repaint();
}
#Override
public void keyPressed(KeyEvent e) //allows each key to do desired action
{
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_LEFT)
{
left = true;
}
if (keyCode == KeyEvent.VK_RIGHT)
{
right = true;
}
if (keyCode == e.VK_P && currentLevel == 0)
{
currentLevel = 1;
}
else if (keyCode == e.VK_E && currentLevel == 1)
{
currentLevel = 0;
score=0;
lives=3;
restart();
}
else if(keyCode == e.VK_Q)
{
System.exit(0);
}
}
#Override
public void keyReleased(KeyEvent e)
{
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_LEFT)
{
left = false;
}
if (keyCode == KeyEvent.VK_RIGHT)
{
right = false;
}
}
#Override
public void keyTyped(KeyEvent e)
{
}
public static void main(String[] args)
{
Game prog = new Game();
prog.init();
}
}
I'd throw that code out and start over as you've got both program logic and repaints within your painting methods, neither of which will help you, and your code appears to be one big huge "God" class, all of which will leave you with code that's a horrific nightmare to debug. Recommendations:
Create at least two separate JPanels to display your program with, a GamePanel and a MenuPanel.
Swap these JPanels using a CardLayout.
Do all graphics within a JPanel's paintComponent method and not within a JFrame's or JApplet's paint method.
Don't forget to call the super's painting method, the same method as your override within your override. This is to clean up any dirty pixels.
Separate your program logic from your GUI
This means that you should have a logical non-GUI representation of a single Brick class as well as a collection of these non-GUI bricks.
You can always give your Brick class a Color field, one that the view or gui uses to paint it with.
Create a game-loop, one that you can control, one that doesn't involve calling repaint() within a painting method, since this leads to a completely uncontrollable loop.
Favor use of Key Bindings over KeyListeners.
Try to avoid use of "magic" numbers, such as hard-coding your brick width and spacing in the class itself. Better to use constants as this too makes debugging and enhancing much easier.
For example, some code that's just to demonstrate showing random colors:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import javax.swing.*;
public class BrickBreak {
private static void createAndShowGui() {
GamePanel gamePanel = new GamePanel();
JFrame frame = new JFrame("Brick Break");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(gamePanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
// JPanel that draws the game
class GamePanel extends JPanel {
private static final long serialVersionUID = 1L;
private static final Color BACK_GRND = Color.BLACK;
private int prefW;
private int prefH;
private Bricks bricks = new Bricks();
public GamePanel() {
// wide enough to hold the complete top-row of Bricks
// using constants, so GUI automatically resizes if any sizes change
prefW = (Brick.WIDTH + Bricks.X_SPACING) * Bricks.ROW_COUNTS[0] + Bricks.X_SPACING;
prefH = prefW;
setBackground(BACK_GRND);
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(prefW, prefH);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
for (Brick brick : bricks) {
brick.draw(g2);
}
}
}
// non-GUI class that represents a logical Brick
class Brick {
public static final int WIDTH = 40;
public static final int HEIGHT = 20;
private int x;
private int y;
private Color color;
private Rectangle boundingRectangle;
public Brick(int x, int y, Color color) {
this.x = x;
this.y = y;
this.color = color;
boundingRectangle = new Rectangle(x, y, WIDTH, HEIGHT);
}
// yeah, I'm mixing some view with model here.
public void draw(Graphics2D g2) {
g2.setColor(color);
g2.fill3DRect(x, y, WIDTH, HEIGHT, true);
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public Color getColor() {
return color;
}
// use this to test for collisions
public boolean contains(Point p) {
return boundingRectangle.contains(p);
}
#Override
public String toString() {
return "Brick [x=" + x + ", y=" + y + ", color=" + color + "]";
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Brick other = (Brick) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
}
// logical class that holds all Bricks
// Have class implement Iterable<Brick> so we can easily iterate through its containing
// Brick objects in a for-each loop
class Bricks implements Iterable<Brick> {
public static final int X_SPACING = 10;
public static final int Y_SPACING = X_SPACING;
public static final int[] ROW_COUNTS = {13, 11, 9, 7, 5, 3, 1};
private static final float MIN_SAT = 0.8f;
private List<Brick> brickList;
private Random random = new Random();
public Bricks() {
init(); // safe to call since it's final
}
public final void init() {
// recreate the brickList ArrayList
brickList = new ArrayList<>();
int y = Y_SPACING;
// for each row of bricks
for (int row = 0; row < ROW_COUNTS.length; row++) {
int x = X_SPACING + ((ROW_COUNTS[0] - ROW_COUNTS[row]) / 2) * (X_SPACING + Brick.WIDTH);
// for each column
for (int j = 0; j < ROW_COUNTS[row]; j++) {
// create a random color
float hue = random.nextFloat();
float saturation = MIN_SAT + random.nextFloat() * (1f - MIN_SAT);
float brightness = MIN_SAT + random.nextFloat() * (1f - MIN_SAT);
Color color = Color.getHSBColor(hue, saturation, brightness);
Brick brick = new Brick(x, y, color); // create a new Brick with this Color
brickList.add(brick);
x += X_SPACING + Brick.WIDTH;
}
y += Y_SPACING + Brick.HEIGHT;
}
}
// returns null if no collision
public Brick collision(Point p) {
for (Brick brick : brickList) {
if (brick.contains(p)) {
return brick;
}
}
return null;
}
#Override
public Iterator<Brick> iterator() {
return brickList.iterator();
}
public boolean remove(Brick brick) {
// because Brick implements equals and hashCode, we can do this
return brickList.remove(brick);
}
}
Note that I like using Color's static getHSBColor(float h, float s, float b) method for creating random Colors as this helps me to avoid creating dull Colors, since I can guarantee that the saturation and brightness are above minimum values. All three parameters must be float values between 0f and 1.0f
float hue = random.nextFloat();
float saturation = MIN_SAT + random.nextFloat() * (1f - MIN_SAT);
float brightness = MIN_SAT + random.nextFloat() * (1f - MIN_SAT);
Color color = Color.getHSBColor(hue, saturation, brightness);
Your code has quite a lot of issues, which #HovercaftFullOfEels answer already points out.
As for why your code doesn't work:
for (int i = 0; i < Brick.length; i++)
{
if (Brick[i] != null)
{
Color mycolor=new Color(100,0,0);
art.setColor(mycolor);
art.fill3DRect(Brick[i].x, Brick[i].y, Brick[i].width,
Brick[i].height, true);
}
}
This is the part that renders the bricks. You never create a random-number, but use the same Color for each brick (new Color(100, 0, 0);). Instead introduce a new variable into Brick that specifies the color of each brick and is initialized once with a random color.
The Brick-class would afterwards look like this:
public class Brick{
public int x;
public int y;
...
public Color color;
...
}
The ... are just placeholders for other code that may be content of the class. Regarding public access of Class-variables: Encapsulation is a fundamental concept of OOP and should be used (on encapsulation). E.g. instead of giving direct access to Brick.x consider introducing a method Brick#getX().

Categories