I'm trying to initialize a bi-dimensional array of an object that I've created that has a some parameters (x,y,width,height) but doesn't work... The object is just a g.fillOval and when I do the initializing only prints the last object of the array.
Ovals = new Oval[4][4];
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
Ovals[x][y] = new Oval(x*100, y, 30,30);
}
}
...
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
Ovals[x][y].paint(g);
}
}
The Oval class:
package objectes;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;
public class Oval extends Canvas{
private static Random random;
private static int r1 = 0;
private static int r2 = 0;
private static int x = 0;
private static int y = 0;
private static int randomN = 5;
public static int color; //0 = red(#FF5C5C), 1 = blue(#4097ED), 2 = green(#65EB8F), 3 = yellow(#F5F267), 4 = orange(#FFAD42)
public Oval(int x, int y, int r1, int r2) {
//Constructor
this.x = x;
this.y = y;
this.r1 = r1;
this.r2 = r2;
random = new Random();
randomN = random.nextInt();
if (randomN < 0 ) {
randomN = randomN*-1;
}
randomN = randomN % 5;
}
public void paint(Graphics g) {
switch (randomN) {
case 0:
g.setColor(Color.decode("#ff5C5C"));
break;
case 1:
g.setColor(Color.decode("#4097ed"));
break;
case 2:
g.setColor(Color.decode("#65eb8f"));
break;
case 3:
g.setColor(Color.decode("#f5f267"));
break;
case 4:
g.setColor(Color.decode("#ffad42"));
break;
}
g.fillOval(x, y, r1, r2);
}
}
All of your classes variables are static
private static int r1 = 0;
private static int r2 = 0;
private static int x = 0;
private static int y = 0;
This means they are associated with the class Oval.. not a single instance of Oval.
Because there is only one copy of each variable, every time you make a new Oval you will overwrite the last value set. When you finally go to draw the Ovals, all of them will be drawn in the exact same spot!
Make them instance variables instead:
private int r1 = 0;
private int r2 = 0;
private int x = 0;
private int y = 0;
Related
I created a console snake game and some basics work pretty well. However, I couldn't add the tail feature. Here is my code:
Game.java(Main class)
import java.util.Scanner;
class Game{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
World world = new World(10, 5);
world.init();
world.draw();
while(true){
//get input
char direction = input.next().charAt(0);
//apply input
world.getSnake().direction = direction;
//simulate
world.tick();
//rendering
world.draw();
}
}}
World.java
public class World{
private char[][] field;
private int width;
private int height;
private Snake snake;
public World(int width, int height){
//+2 for borders
this.width = width + 2;
this.height = height + 2;
}
public void init(){
this.field = new char[height][width];
//background
for(int x = 0; x < width; x++){
for(int y = 0; y < height; y++){
field[y][x] = '.';
}
}
//walls
for(int x = 0; x < width; x++){
field[0][x] = '#';
field[height - 1][x] = '#';
}
for(int y = 0; y < height; y++){
field[y][0] = '#';
field[y][width - 1] = '#';
}
//snake
snake = new Snake();
snake.init(this.width / 2, this.height / 2);
field[snake.head.y][snake.head.x] = 'o';
//food
generateFood();
}
public void tick(){
field[snake.head.y][snake.head.x] = '.';
//movement
switch(snake.direction){
case 'w':
snake.head.y--;
break;
case 's':
snake.head.y++;
break;
case 'a':
snake.head.x--;
break;
case 'd':
snake.head.x++;
break;
}
//logic(rules)
switch(field[snake.head.y][snake.head.x]){
case '#':
case 'o':
//game over
init();
break;
case '*':
//eating
generateFood();
break;
}
field[snake.head.y][snake.head.x] = 'o';
}
public void generateFood(){
Point food = new Point();
food.x = (int)(Math.random() * (width - 3)) + 1;
food.y = (int)(Math.random() * (height - 3)) + 1;
if(food.x == snake.head.x && food.y == snake.head.y){
generateFood();
}
else{
field[food.y][food.x] = '*';
}
}
public void draw(){
for(int y = 0; y < height; y++){
for(int x = 0; x < width; x++){
System.out.print(field[y][x]);
}
System.out.println();
}
}
public Snake getSnake(){
return snake;
}}
Snake.java
public class Snake{
public Point head;
public char direction;
public void init(int x, int y){
this.head = new Point();
this.head.x = x;
this.head.y = y;
this.direction = 'w';
}
}
Point.java
public class Point{
int x;
int y; }
You should make a List in your Snake class, where you will be storing it's length,
something like that
public class Snake{
public Point head;
public ArrayList array = new ArrayList(); // added ArrayList
public char direction;
public void init(int x, int y){
array.add(3); // it will work if you want to count points or just simply add anything and count it's size with array.size()
this.head = new Point();
this.head.x = x;
this.head.y = y;
this.direction = 'w';
}
}
I want to make bubble shooter game and I have problem with generate bubbles at start. When trying to compile program, I have error: Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException.
public class MyPanel extends JPanel {
Init init;
public MyPanel(){
super();
init = new Init();
}
public void paint(Graphics g){
Dimension size = getSize();
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.GRAY);
g2d.fillRect(0, 0, size.width, size.height - 70);
for(int j = 0; j < 10; j++)
for(int i = 0; i < 20; i++){
init.fields[i][j].b.paint(g); //here compiler shows error
}
}
}
public class Field {
private int x;
private int y;
private int r = 30;
public Baloon b;
public Field(int x, int y){
this.x = x*r;
this.y = y*r;
}
public void addBaloon(int n){
b = new Baloon(this.x, this.y, r, n);
}
}
public class Init {
Parser pr = new Parser();
private int r = pr.getRadius();
private int x = pr.getXDimension();
private int y = pr.getYDimension();
private int ni = pr.getColorRange();
Field[][] fields = new Field[x][y];
private int startX = 20;
private int startY = 10;
public Init(){
for(int yi = 1; yi<y; yi++){
for (int xi = 1; xi<x; xi++){
fields[xi][yi] = new Field(xi*r, yi*r);
}
}
for(int yi = 1; yi < startY; yi ++){
for(int xi = 1 ; xi < startX; xi++){
Random rand = new Random();
int n = rand.nextInt(ni);
fields[xi][yi].addBaloon(n);
}
}
}
}
You are initializing array from index 1:
for(int yi = 1; yi<y; yi++){
for (int xi = 1; xi<x; xi++){
fields[xi][yi] = new Field(xi*r, yi*r);
}
}
While accessing it from 0 like:
for(int j = 0; j < 10; j++)
for(int i = 0; i < 20; i++){
init.fields[i][j].b.paint(g); //here compiler shows error
}
Array index starts from 0 and goes upto n-1. So you need to initialize like:
for(int yi = 0; yi<y; yi++){
for (int xi = 0; xi<x; xi++){
fields[xi][yi] = new Field(xi*r, yi*r);
}
}
I cant seem to figure it out is it possible that someone can tell me why?
public class Display {
private int width,height;
public int [] pixels;
public int [] tiles = new int[64 * 64];
private Random random = new Random();
public Display(int width, int height) {
this.width = width;
this.height = height;
pixels = new int [width*height]; // 50400
for (int i = 0; i < 64 * 64; i++) {
tiles[i] = random.nextInt (0xffffff);
}
}
public void clear() {
for (int i = 0; i < pixels.length; i++) {
tiles[i] = random.nextInt (0xffffff);
}
}
public void render() {
for (int y = 0; y <height; y++) {
if (y < 0 || y >= height) break;
for (int x = 0; x < width; x++) {
if (x < 0 || x >=width) break;
int tileIndex = (x / 16) + (y / 16) * 64;
pixels[x+y*width] = tiles[tileIndex];
}
}
}
}
The ArrayIndexOutOfBoundsException is likely to occur at the assignment in the clear() method.
You are iterating from 0 to pixels.length. pixels.length is variable-sized (according to what is passed to the constructor). While iterating you assign values to tiles[i]. Tiles is a fixed sized array (64*64 = 4.096 entries). If width*height > 4096, the clear() method will fail if it tries to access tiles[4096] or above.
Maybe you wanted to iterate up to tiles.length only?
constants
public final int DIMENSIONS = 4;
public final int MOVE_RIGHT = 1;
public final int MOVE_LEFT = 2;
public final int MOVE_UP = 3;
public final int MOVE_DOWN = 4;
main
PuzzleFrame board;
void setup(){
size(401,401);
board = new PuzzleFrame();
background(100);
}
void draw(){
background(100);
board.draw();
}
void keyPressed()
{
if(key == CODED)
{
if(keyCode == RIGHT) board.moveTile(MOVE_RIGHT);
if(keyCode == LEFT) board.moveTile(MOVE_LEFT);
if(keyCode == UP) board.moveTile(MOVE_UP);
if(keyCode == DOWN) board.moveTile(MOVE_DOWN);
}
}
class that creates puzzle frame
class PuzzleFrame{
private Tile[][] puzzleFrame;
private Tile[][] solvedPuzzleFrame;
public PuzzleFrame()
{
puzzleFrame = new Tile[DIMENSIONS][DIMENSIONS];
solvedPuzzleFrame = new Tile[DIMENSIONS][DIMENSIONS];
int tileNumber = 1;
for(int i = 0; i < DIMENSIONS; i++)
{
for(int j = 0; j < DIMENSIONS; j++)
{
puzzleFrame[i][j] = new Tile(tileNumber, j*100, i*100);
solvedPuzzleFrame[i][j] = new Tile(tileNumber, j*100, i*100);
tileNumber++;
}
}
}
public void draw()
{
for(int i = 0; i < DIMENSIONS; i++)
{
for(int j = 0; j < DIMENSIONS; j++)
{
puzzleFrame[i][j].draw();
}
}
}
public void moveTile(int side)
{
if(isMoveAllowed(side))
{
switch(side)
{
case MOVE_RIGHT:
{
for(int i = 0; i < DIMENSIONS; i++)
{
for(int j = 0; j < DIMENSIONS; j++)
{
if(puzzleFrame[i][j].getTileNumber() == DIMENSIONS*DIMENSIONS)
{
Tile tempTile = puzzleFrame[i][j];
puzzleFrame[i][j] = puzzleFrame[i][j-1];
puzzleFrame[i][j-1] = tempTile;
System.out.println("right");
break;
}
}
}
break;
}
}
}
}
private boolean isMoveAllowed(int side)
{
switch(side)
{
case MOVE_RIGHT:
{
for(int i = 0; i < DIMENSIONS; i++)
{
for(int j = 0; j < DIMENSIONS; j++)
{
if(puzzleFrame[i][j].getTileNumber() == DIMENSIONS*DIMENSIONS)
{
if(j > 0) return true;
}
}
}
break;
}
}
return false;
}
}
tile class which is used for to create puzzle Frame
class Tile{
private final int mTileNumber;
private final int width = 100;
private final int height = 100;
private String number = "";
private int xpos;
private int ypos;
private int xOffSet;
private int yOffSet;
public Tile(int tileNumber, int xpos, int ypos)
{
mTileNumber = tileNumber;
number += tileNumber;
textSize(64);
this.xpos = xpos; this.ypos = ypos;
xOffSet = 30;
yOffSet = 70;
if(mTileNumber >= 10)
{
xOffSet = 10;
}
}
public void draw()
{
if(mTileNumber == DIMENSIONS*DIMENSIONS)
{
}
else
{
strokeWeight(2);
fill(255);
rect(xpos, ypos, width, height);
fill(0);
text(number, xpos+xOffSet, ypos+yOffSet);
}
}
public int getTileNumber()
{
return mTileNumber;
}
}
I'm trying to make 15 puzzle game but the problem that I came across is that when I press arrow key RIGHT, contents of the puzzleFrame array change (I checked it in Eclipse via debugger) but in processing the image drawn remains the same. For now my code only consists of a function that allows to slide tile to the right. I honestly don't understand why the image remains the same even though the contents of the array have changed.
I know this doesn't answer your question but how are you avoiding a compiler error in your Tile class during the assignment: mTileNumber = tileNumber
You declared mTileNumber as a final variable so you shouldn't be able to reassign it to anything.
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);
}