I have everything else correct, but for some reason this is giving me problems. I want to implement a method called populate(). i want to be called in the constructor. I want it to the method to create a random number of objects of each type of object. This is my code.
my error is "*strong text*constructor yellowish in class yellowish cannot be a apllied to given types. required: int found: not argument reason: actual and form argument list differ in length.
public class FishWorld extends World
{
/**
* Constructor for objects of class FishWorld.
*
*/
public FishWorld()
{
super(600, 400, 1);
populate();
populate2();
populate3();
}
public void populate()
{
int randX;
int randY;
for(int i = 0; i < 5; i++)
{
YellowFish yf = new YellowFish();
randX = Greenfoot.getRandomNumber ( getWidth() );
randY = Greenfoot.getRandomNumber( getHeight() );
addObject(yf, randX, randY);
}
}
public void populate2()
{
int randX;
int randY;
for(int i = 0; i < 5; i++)
{
GreenFish gf = new GreenFish();
randX = Greenfoot.getRandomNumber ( getWidth() );
randY = Greenfoot.getRandomNumber( getHeight() );
addObject(yf, randX, randY);
}
}
public void populate3()
{
int randX;
int randY;
for(int i = 0; i < 5; i++)
{
StripeFish sf = new StripeFish();
randX = Greenfoot.getRandomNumber ( getWidth() );
randY = Greenfoot.getRandomNumber( getHeight() );
addObject(yf, randX, randY);
}
}
}
It seems you don't have empty parameter constructor in class YellowFish. You might want to add:
public YellowFish() {
// ... your code here
}
in the YellowFish class.
Related
public class ChutesAndLadders2d {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[][] numbersOnBoard = new int [6][6];
boardSetUpA (numbersOnBoard);
printTwoD(numbersOnBoard);
}
public static void boardSetUpA (int[][]twoD) {
//Square with even size
//even rows
for (int row = 0;row<twoD.length; row ++) {
if (row %2 ==0) {
int num = twoD.length*(twoD.length-row);
for (int col = 0; col<twoD[row].length; col ++ ) {
twoD[row][col] = num;
num--;
}
}//
else {
int num = twoD.length*(twoD.length-(row + 1))+ 1;
for (int col = 0; col<twoD[row].length; col ++ ) {
twoD[row][col] = num;
num++;
}
}
}//for row
}//
public static void printTwoD(int [][] array){
for (int row = 0; row < array.length; row++){
for (int column = 0; column < array[row].length; column++){
System.out.print(array[row][column] + "\t");
}
System.out.println();
}
}
public static void boardDetails(String[][]board) {
for (int row = 0;row<board.length; row++){
for (int col = 0;col<board[row].length; col++){
if( col+2 == row||col+1 == row*2 ){
board[row][col] = "Lad"; // Append value
}
else if (col*2 == row|| row*2 == col){
board[row][col] = "Cht";// Append value
}
else {
board[row][col] = " ";
}
}
board[board.length-1][0] = "Start";
if (board.length%2 ==0) {
board[0][0] = "End";}
else {
board[0][board.length-1]="End";
}
}
}
public static void printBoard (int[][]twoD, String[][]strTwoD) {
//Printing
for (int row = 0;row<twoD.length;row++) {
for (int col = 0;col<twoD[row].length;col++) {
System.out.print(twoD[row][col] + " "+strTwoD[row][col]+"\t\t");
}
System.out.println("\n");
}
}
}
This is the starter code I have for setting up the snakes and ladders game. I also tried to set the chutes/snakes and ladders on the board but it is not printing. How should I fix it and how do I develop this code to have three methods: update the moves of a player once he reaches a snake, a ladder, and once he rolls his die, from one place to another?
Is it possible to implement a Shutes & Ladders game using a 2D Array? For sure! Does that make sense in an object-oriented language such as Java? I dont know ....
What do you need for that?
A square board with e.g. 36 playing fields.
Connections between two playing fields. (shutes and ladders)
Pawns and a dice.
A renderer that outputs the playing field (as text or graphics).
A program that allows input and connects everything to a functioning game.
Here is an example that works with a List instead of an Array. That can certainly be changed if it is necessary for your purposes.
I hope this is of some help to you.
P.S .: After the start, the board is displayed with field numbers. Shutes are shown as red lines. Ladders as green lines. Keys 1-6 on the keyboard simulate rolling the dice..
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyAdapter;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import javax.swing.*;
public class ChutesAndLadders2d {
public static void main(String[] args) {
JFrame frame = new JFrame("Chutes and Ladders 2D");
Game game = new ChutesAndLadders2d().new Game();
game.setPreferredSize(new Dimension(400, 400));
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setContentPane(game);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
#SuppressWarnings("serial")
class Game extends JPanel{
private final Font defaultFont = new Font("Arial", Font.PLAIN, 16);
private final BasicStroke stroke = new BasicStroke(4f);
private static final int SCALE = 64;
// board and pawns
private final Board board = new Board(6);
private final List<Pawn> pawns = new ArrayList<>();
public Game(){
setFocusable(true); // receive Keyboard-Events
addKeyListener(new KeyAdapter(){
#Override
public void keyTyped(KeyEvent e) {
char c = e.getKeyChar();
if(c >= '1' && c <= '6'){
int steps = Integer.parseInt(Character.toString(c));
Pawn pawn = pawns.get(0);
pawn.move(steps);
Field field = board.get(pawn.fieldIndex);
if(field.targetKind() != Kind.NONE){
pawn.move(field.getTarget().index - field.index);
}
repaint();
}
}
});
board.connect(5, 12); // Ladder 5 -> 12
board.connect(8, 4); // Shute 8 -> 4
board.connect(15, 32); // Ladder 15 -> 32
board.connect(35, 17); // Shute 35 -> 17
board.connect(23, 30); // Ladder 23 -> 30
pawns.add(new Pawn(Color.BLUE, board.size() - 1));
}
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
setFont(defaultFont);
for(Field field : board){
Point p = field.getLocation();
g2d.drawRect(p.x * SCALE, p.y * SCALE, SCALE, SCALE);
g2d.drawString(field.text, p.x * SCALE + 24, p.y * SCALE + 40);
}
for(Field field : board){
if(field.targetKind() != Kind.NONE){
g2d.setColor(field.targetKind() == Kind.LADDER ? Color.GREEN : Color.RED);
g2d.setStroke(stroke);
Point source = field.getLocation();
Point target = field.getTarget().getLocation();
g2d.drawLine(source.x * SCALE + 40, source.y * SCALE + 24, target.x * SCALE + 40, target.y * SCALE + 24);
}
}
for(Pawn pawn : pawns){
Point loc = board.get(pawn.fieldIndex).getLocation();
g2d.setColor(pawn.color);
g2d.fillOval(loc.x * SCALE + 32, loc.y * SCALE + 32, 16, 16);
}
}
}
class Board implements Iterable<Field>{
private final List<Field> fields = new ArrayList<>();
public Board(int size){
for(int index = 0; index < size * size; index++)
fields.add(new Field(index, size));
}
public Field get(int index){
return fields.get(index);
}
public void connect(int startFieldnumber, int targetFieldnumber){
get(startFieldnumber - 1).setTarget(get(targetFieldnumber - 1));
}
#Override
public Iterator<Field> iterator() {
return fields.iterator();
}
public int size(){
return fields.size();
}
}
class Field{
final int index;
final String text;
final int size;
private Field target;
public Field(int index, int size){
this.index = index;
this.size = size;
text = "" + (index + 1);
}
public void setTarget(Field target){
if(target == this) return;
this.target = target;
}
public Field getTarget(){
return target;
}
public Kind targetKind(){
if(target == null) return Kind.NONE;
return index < target.index ? Kind.LADDER : Kind.SHUTE;
}
public Point getLocation(){
int x = index % size;
int y = index / size;
if(y % 2 != 0) x = size - x - 1;
return new Point(x, size - y - 1);
}
}
class Pawn{
int fieldIndex = 0;
int maxIndex;
Color color;
public Pawn(Color color, int maxIndex){
this.color = color;
this.maxIndex = maxIndex;
}
public void move(int steps){
fieldIndex += steps;
if(fieldIndex < 0) fieldIndex = 0;
if(fieldIndex > maxIndex) fieldIndex = maxIndex;
}
}
enum Kind{
NONE, SHUTE, LADDER
}
}
public class Triangle {
double area;
int height;
int length;
public static void main(String [] args) {
int x = 0;
Triangle [ ] ta = new Triangle[4];
while ( x < 4 ) {
ta[x] = new Triangle();
ta[x].height = (x + 1) * 2;
ta[x].length = x + 4;
ta[x].setArea();
System.out.print("triangle "+x+", area");
System.out.println(" = " + ta[x].area);
x = x + 1;
}
int y = x;
x = 27;
Triangle t5 = ta[2];
ta[2].area = 343;
System.out.print("y = " + y);
System.out.println(", t5 area = "+ t5.area);
}
void setArea() {
ta[x].area = (height * length) / 2;
}
}
$javac Triangle.java
Triangle.java:25: error: cannot find symbol
ta[x].area = (height * length) / 2;
^
symbol: variable ta
location: class Triangle
Triangle.java:25: error: cannot find symbol
ta[x].area = (height * length) / 2;
^
symbol: variable x
location: class Triangle
2 errors
Of course I soon find that I need to take "ta[x]." thing off the setArea method, that's clear, but now I'm wondering why I cannot put a previously-declared Triangle array before that area function.
Is it because within the method, all things are local and you can't use variables which aren't declared in that method even if you've already declared them in other parts of code? Thank you guys.
x ta are local variable their scope are limited their respective function outside the scope you can not reference it.
Just pass the reference.
public class Triangle {
double area;
int height;
int length;
public static void main(String [] args) {
int x = 0;
Triangle [ ] ta = new Triangle[4];
while ( x < 4 ) {
ta[x] = new Triangle();
ta[x].height = (x + 1) * 2;
ta[x].length = x + 4;
ta[x].setArea(ta[x]);
System.out.print("triangle "+x+", area");
System.out.println(" = " + ta[x].area);
x = x + 1;
}
int y = x;
x = 27;
Triangle t5 = ta[2];
ta[2].area = 343;
System.out.print("y = " + y);
System.out.println(", t5 area = "+ t5.area);
}
void setArea(Triangle t) {
t.area = (height * length) / 2;
}
}
ta,x variable scope limited to Main() funtion
The question you have asked is related to the concept of scope of a variable in java.
Any variable declared inside {}, can be accessible inside those{} only. Outside the {},variables are not accessible.
In your code area is instance variable of class Triangle having length and height as instance variables.
So to calculate area you can directly use length and height. like
area=length*height
To calculate the area of perticular object call it through that object or you can pass triangle object as mentioned in previous post posted by user207421
You have couple of the problems in the snippet. Let me show you:
It's better to use immutable objects whenever it's possible. Imagine if someone will use your Triangle and forget to invoke setArea();
One of OOP's principles is encapsulation, so you should avoid access to the class's variables directly (only with getters);
In general, you should store minimum information. E.g. setArea() should be moved directly to the Triangle class. Moreover, it's pretty simple to calculate and it's better to do it
And finally look at division operation; before doing / you have to cast the result to the double. If you do (int + int) / int - the result will always be an integer.
Please check my solution:
// class is final (this is not mandatory)
public final class Triangle {
// variables are final (in general this is good approach)
// variables are private (access only via getters)
private final int width;
private final int height;
public Triangle(int width, int height) {
this.width = width;
this.height = height;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
// 2.0 is very important, here we cast (width * height) to double before division
public double getArea() {
return (width * height) / 2.0;
}
}
public class Main {
public static void main(String... args) {
Triangle[] triangles = createTriangles(4);
print(triangles);
}
private static Triangle[] createTriangles(int total) {
Triangle[] triangles = new Triangle[total];
// for loops letters like i,j,k are more common (x is mostly to 2D)
for (int i = 0; i < triangles.length; i++) {
int width = i + 4;
int height = (i + 1) * 2;
triangles[i] = new Triangle(width, height);
}
return triangles;
}
private static void print(Triangle... triangles) {
if (triangles != null)
for (int i = 0; i < triangles.length; i++)
System.out.format(Locale.ENGLISH, "triangle %d, area = %.2f",
i, triangles[i].getArea());
}
}
The setArea() mehtod is part of the class triangle,so there is no issue in calculating area of a trisngle.
public class Triangle {
double area;
int height;
int length;
public double setArea(){
return area=(length*height)/2;
}
public static void main(String[] args) {
int x=0;
Triangle [ ] ta = new Triangle[4];
while ( x < 4 ) {
ta[x] = new Triangle();
ta[x].height = (x + 1) * 2;
ta[x].length = x + 4;
ta[x].setArea();
System.out.print("triangle "+x+", area");
System.out.println(" = " + ta[x].area);
x = x + 1;
}
int y = x;
x = 27;
Triangle t5 = ta[2];
ta[2].area = 343;
System.out.print("y = " + y);
System.out.println(", t5 area = "+ t5.area);
}
}
//Generator class
public class Generator {
double jump;
double sizeModifier;
int iterationRate,range;
ComplexNumber c;
public Generator(double jump) {
this.jump=jump;
this.sizeModifier=40;
this.iterationRate=10;
this.range=100;
c=new ComplexNumber();
}
public void generateSet(){
DrawSet ds = new DrawSet();
int ticker=0;
for(double i=-2*range;i<=range;i+=jump){
for(double j=-2*range;j<=range;j+=jump){
c= new ComplexNumber((i/range),(j/range));
double fz=c.square().mod()+c.mod();
//System.out.println("c mod is: "+c.mod());
//System.out.println("fz is: "+fz);
if (fz < 2) {
for(int k=0;k<=iterationRate;k++) {
//System.out.println("nc:"+nc);
ticker++;
//System.out.println("ticker:"+ticker);
if(ticker==iterationRate) {
ds.addPoint(i + 450, j + 450);
}
if(fz>=2){
break;
}
else {
fz = Math.pow(fz, 2) + 1;
}
}
}
ticker=0;
}
}
}
//Drawset class
public class DrawSet extends JPanel {
private ArrayList<Point> Points;
private ArrayList<Point> nPoints;
GraphicWindow gw;
public DrawSet(){
this.Points=new ArrayList<>();
this.nPoints=new ArrayList<>();
gw = new GraphicWindow(1000,1000);
gw.add(this);
}
public void addPoint(double x,double y){
int ix=(int)x;
int iy=(int)y;
//int iwidth=(int)width*sizeModifier;
//int iheight=(int)height*sizeModifier;
Point a=new Point(ix,iy);
Points.add(a);
//System.out.println(Points.size());
}
public void paintComponent(Graphics g) {
int pointSize = 1;
super.paintComponents(g);
System.out.println(Points.size());
for (int i = 0; i < Points.size(); i++) {
g.setColor(Color.BLACK);
g.drawOval((int) Points.get(i).getX(), (int) Points.get(i).getY(), pointSize, pointSize);
}
}
The basic problem is that fz is never <2 after just 10 iterations, so no points are drawn. Why is this? What equation should I be implementing?
I am using a complex number to generate the value. The class which I use can be seen here:
https://github.com/abdulfatir/jcomplexnumber/
(or on the stack overflow forum Does Java have a class for complex numbers? by Mr Abdul Fatir)
Okay, observationally
Generator should not be creating a new instance of DrawSet
DrawSet should not be creating a new instance of GraphicWindow
These are the responsibilities of these classes or methods. This is highly coupling your code and generating side effects.
Instead, generate should pass back the points it creates and these should then be applied in what ever way you want, Generator shouldn't care.
Because I don't have access to your full code, I've just hacked together a random series of points instead to illustrate the point.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
DrawSet drawSet = new DrawSet();
Generator generator = new Generator(100);
drawSet.setPoints(generator.generateSet());
JFrame frame = new JFrame();
frame.add(drawSet);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class DrawSet extends JPanel {
private ArrayList<Point> points;
private ArrayList<Point> nPoints;
public DrawSet() {
this.points = new ArrayList<>();
this.nPoints = new ArrayList<>();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
public void setPoints(ArrayList<Point> points) {
this.points = points;
repaint();
}
// public void addPoint(double x, double y) {
// int ix = (int) x;
// int iy = (int) y;
// //int iwidth=(int)width*sizeModifier;
// //int iheight=(int)height*sizeModifier;
// Point a = new Point(ix, iy);
// Points.add(a);
// //System.out.println(Points.size());
// }
#Override
protected void paintComponent(Graphics g) {
int pointSize = 5;
super.paintComponents(g);
for (int i = 0; i < points.size(); i++) {
g.setColor(Color.BLACK);
g.drawOval((int) points.get(i).getX(), (int) points.get(i).getY(), pointSize, pointSize);
}
}
}
public class Generator {
double jump;
double sizeModifier;
int iterationRate, range;
//ComplexNumber c;
public Generator(double jump) {
this.jump = jump;
this.sizeModifier = 40;
this.iterationRate = 10;
this.range = 100;
//c = new ComplexNumber();
}
public ArrayList<Point> generateSet() {
Random rnd = new Random();
ArrayList<Point> points = new ArrayList<>(range);
for (int index = 0; index < range; index++) {
int x = (int)(490 * rnd.nextDouble());
int y = (int)(490 * rnd.nextDouble());
points.add(new Point(x, y));
}
return points;
// DrawSet ds = new DrawSet();
// int ticker = 0;
// for (double i = -2 * range; i <= range; i += jump) {
// for (double j = -2 * range; j <= range; j += jump) {
// c = new ComplexNumber((i / range), (j / range));
// double fz = c.square().mod() + c.mod();
// //System.out.println("c mod is: "+c.mod());
// //System.out.println("fz is: "+fz);
// if (fz < 2) {
// for (int k = 0; k <= iterationRate; k++) {
// //System.out.println("nc:"+nc);
// ticker++;
// //System.out.println("ticker:"+ticker);
// if (ticker == iterationRate) {
// ds.addPoint(i + 450, j + 450);
//
// }
// if (fz >= 2) {
// break;
// } else {
// fz = Math.pow(fz, 2) + 1;
// }
// }
// }
// ticker = 0;
// }
// }
}
}
}
I've also made the pointSize bigger, so you can actually see the results, although I'd consider filling the points.
If the Generator is takes a long time to perform its calculations, you might consider using a SwingWorker to perform the operation. This will allow to offload the operation to seperate thread and not block the main UI thread. You can then use the SwingWorker to either feed back each individual point as it's calculated or all the points when the whole generation is done, back to the main UI thread in a safe manner.
See Worker Threads and SwingWorker for more details
Why is this?
Swing is lazy. It won't make repaints or updates to the UI unless it thinks it needs to. So, if you change some state the UI is depending on, you need to nudge Swing to encourage it to make a new paint pass. In the simplest terms, this means calling repaint on the component which is has changed
I'm trying to scan though an AraayList created in the main class, in the turtle class to check various criteria. I simplified the code as much as possible for you.
The main class:
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.awt.event.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
class TurtleProgram
{
public ArrayList<DynamicTurtle> turtles;
public static void main(String[] args)
{
new TurtleProgram();
}
public TurtleProgram()
{
//INSTANTIATED JFRAME WITH BUTTONS/SLIDER AND CREATED LISTENER METHODS
turtles = new ArrayList<DynamicTurtle>(); //THE ARRAYLIST I AM WANTING TO USE IN ANOTHER CLASS
turtles.add(new RandomTurtleB(canvas, 400, 300, 100, 0)); //THIS ARRAYLIST BECOMES LARGER WHEN BUTTONS ON JFRAME TO ADD NEW TURTLES
gameLoop(); //LOOP FOREVER
}
private void gameLoop()
{
int deltaTime = 20;
while(true)
{
for (int i = 0; i < turtles.size(); i++)
{
(turtles.get(i)).unDrawTurtle(); //REMOVE FROM CANVAS
(turtles.get(i)).wrapPosition((turtles.get(i)).getPositionX(), (turtles.get(i)).getPositionY()); //MAKE SURE TURTLES NOT OFF SCREEN
}
for (int i = 0; i < turtles.size(); i++)
{
(turtles.get(i)).update(1000); //MAKE THE TURTLES MOVE WITH A CHANCE OF TURNING
}
for (int i = 0; i < turtles.size(); i++)
{
(turtles.get(i)).drawTurtle(); //DRAW TO CANVAS
}
for(int i = 0; i < turtles.size(); i++)
{
(turtles.get(i)).cohesian(); //THIS IS HOW I WOULD LIKE TO ADDRESS THE COHESIAN METHOD
}
Utils.pause(deltaTime/2);
}
}
}
Then I would like to check the current turtle against other turtles to see if it's close in the cohesion() method to perform actions:
class Turtle
{
protected Canvas canvas; // private field reference to a canvas private
private CartesianCoordinate myLocation, oldLocation;
private boolean penDown = true;
private double angle, maxX, maxY, nowPosX, nowPosY, maximumX, maximumY, x, y;
public double d, e, first, second;
private int speed;
public Turtle(Canvas canvas, CartesianCoordinate initLocation)
{
this.canvas = canvas;
this.myLocation = new CartesianCoordinate(0,0);
penDown = true;
myLocation = initLocation.copy();
}
public void cohesian()
{
double flockingDistanceLimit = 200;
double numberOfFlockers = 0;
double combinedX = 0;
double combinedY = 0;
double averageCombinedX, averageCombinedY, averageCombinedY, moveToFlock, turnToFlock, distanceToPotentialFlock;
for (DynamicTurtle t : turtles) //CANNOT USE THE ARRAYLIST TO SCAN THROUGH ITS ELEMENTS
{
if(this.getPositionX() != t.getPositionX() && this.getPositionY() != t.getPositionY()) //MAKE SURE TURTLE ISNT SCANNING ITS SELF
{
distanceToPotentialFlock = Math.sqrt(Math.pow((this.getPositionX()-t.getPositionX()),2 ) + Math.pow((this.getPositionY()-this.getPositionY()),2)); //FIND DISTANCE BETWEEN CURRENT AND SCANNED TURTLE
if(distanceToPotentialFlock < flockingDistanceLimit) //MAKE SURE THE FOUND TURTLE IS WITHIN RANGE USING THE DISTANCE BETWEEN POINTS METHOD
{
combinedX = combinedX + t.getPositionX(); //FIND SUMMATION OF X POSITIONS
combinedY = combinedY + t.getPositionY(); //FIND SUMMATION OF Y POSITIONS
numberOfFlockers++; //AS A FLOCKER HAS BEEN FOUND INCREMENT THE NUMBER OF FLOCKERS
}
}
if(numberOfFlockers > 0)
{
averageCombinedX = (combinedX / numberOfFlockers); //FIND AVERAGE X POSITION
averageCombinedY = (combinedY / numberOfFlockers); //FIND AVERAGE Y POSITION
moveToFlock = Math.sqrt(Math.pow(averageCombinedX,2 ) + Math.pow(averageCombinedY, 2)); //CALCULATE DISTANCE TO CENTER OF FLOCKING
turnToFlock = Math.atan(averageCombinedY / averageCombinedX);
if(turnToFlock < 0)
{
turnToFlock = 360 - (-turnToFlock); //ADJUSTING FOR NEGATIVES
}
}
}
}
public void wrapPosition(double x, double y)
{
this.maxX = x;
this.maxY = y;
if(maxX < 0)
{
this.setPositionX(800);
}
else if(maxX > 800)
{
this.setPositionX(0);
}
if(maxY < 0)
{
this.setPositionY(600);
}
else if(maxY > 600)
{
this.setPositionY(0);
}
}
}
If I could have any help with using the ArrayList in the Turtle Class, in the cohesian() method, it would be greatly appreciated. Thank you in advance.
Either pass the arrayList as parameter to cohesian, or declare it as a static field
I am creating a brick breaker game for school using ArrayLists, abstraction, and polymorphism. I have created an abstract class DrawableBrick that includes a draw method. I have already successfully created the other subclasses that fill my ArrayList and the game works beautifully, but I need to create a new subclass called ShavedBrick that is a polygon that can be easily added to my ArrayList.
I am a little stuck as to how to create the parameterized constructor for this class and to set the class data to the arguments passed in by the user. Here is what I have so far. It needs to be an octagon.
import java.awt.*;
import java.util.*;
public class ShavedBrick extends DrawableBrick {
//data
private int [] xArray = new int [8];
private int [] yArray = new int [8];
private int numberOfSides;
//private Color color;
//constructor
public ShavedBrick(int[] x {}, int [] y {}, int numberOfPoints)
{
Random ranGen = new Random();
xArray[0] = x;
yArray[0] = y;
this.numberOfSides = numberOfPoints;
//this.width = width;
//this.height = height;
this.color = new Color(0,(ranGen.nextInt(156)+100),0);
}
//draw - tells the ShavedBrick to draw itself, using the Graphics object received
public void draw(Graphics g)
{
Color prevColor = g.getColor(); //save previous color associated with g
g.setColor(this.color);
g.fillPolygon(xArray, yArray, numberOfSides);
g.setColor(prevColor); //restore previous color
}
Here is an example of creating the object in the ArrayList
//some constants created in the main data
private final int WALLWIDTH = 5; //Walls' width
private final int BRICKSTARTX = WALLWIDTH;
private final int BRICKSTARTY = 100 + WALLWIDTH;
private final int BRICKWIDTH = 150;
private final int BRICKHEIGHT = 75;
//Fill the ArrayList with random DrawableBricks
for (int i = 0; i<10; i++){
Random random = new Random();
int randomBrick = random.nextInt(3);
if (randomBrick == 0){
myBricks.add(i, new RedBrick((BRICKSTARTX + i*BRICKWIDTH),(BRICKSTARTY + BRICKHEIGHT),BRICKWIDTH,BRICKHEIGHT));
myBricks.add(i, new RedBrick((BRICKSTARTX + i*BRICKWIDTH),((BRICKSTARTY+75) + BRICKHEIGHT),BRICKWIDTH,BRICKHEIGHT));
}
else if (randomBrick == 1) {
myBricks.add(i, new BlueBrick((BRICKSTARTX + i*BRICKWIDTH),(BRICKSTARTY + BRICKHEIGHT),BRICKWIDTH, BRICKHEIGHT));
myBricks.add(i, new BlueBrick((BRICKSTARTX + i*BRICKWIDTH),((BRICKSTARTY+75) + BRICKHEIGHT),BRICKWIDTH,BRICKHEIGHT));
}
//else if (randomBrick == 3){
//myBricks.add(new ShavedBrick(0,0,2,6));
//}
else if (randomBrick == 2){
for (int i = 0; i<8; i++){
xValues[] array = new xArray[8];
myBricks.add(new ShavedBrick(int [i] x {BRICKSTARTX,});
}
}
}
i would suggest something like this...
public ShavedBrick(int[] x, int[] y, int numberOfPoints)
{
Random ranGen = new Random();
for(int i = 0; i < 8; i ++) {
xArray[i] = x[i];
yArray[i] = y[i];
}
this.numberOfSides = numberOfPoints;
this.color = new Color(0,(ranGen.nextInt(156)+100),0);
}
Basically, remove the braces ({ }) from the constructor signature. And add each of the 8 elements in the input arrays to the private arrays of the class using a for loop. You could point the private arrays of the class directly to the input arrays, but i would personally avoid that and simply copy the values to a newly created pair of arrays.
You could also use the Array.copyOf(int[], int) http://docs.oracle.com/javase/6/docs/api/java/util/Arrays.html#copyOf(int[], int) as well.
In your client code just run a loop to compute your co-ordinates and then pass those co-ordinates along to the constructor like this ...
int[] xArray = new int[8];
int[] yArray = new int[8];
for (int i = 0; i < 8; i ++) {
xArray[i] = //some value for the x co-ordinate of the ith point
yArray[i] = //some value for the y co-ordinate of the ith point
}
ShavedBrick b = new ShavedBrick(xArray, yArray, 8);
myBricks.add(b); //finally add the new shaved brick
You can directly assign the argument arrays as follows:
public ShavedBrick(int[] xArray, int[] yArray, int numberOfPoints)
this.xArray = xArray;
this.yArray = yArray;
//...
int[] x {} actually creates a new empty array which of course is not a valid parameter declaration. Parameter declaration should look as int[] xArray.
I'm not sure what your problem is, but if you have an octagon then you don't need a numberOfPoints argument:
public ShavedBrick(int[] x, int [] y)
{
Random ranGen = new Random();
this.numberOfSides = 8; //it's always 8
xArray = Arrays.copyOf(x,numberOfSides); //note, this method will pad array with zeros if x.length is less than 8
yArray = Arrays.copyOf(y,numberOfSides);
this.color = new Color(0,(ranGen.nextInt(156)+100),0);
}