This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I have fixed the errors but I am still unable to get the game to start
This is a snake game and I can not get it to start. When I try to run it on Eclipse it keeps giving me
Exception in thread "main" java.lang.NullPointerException
at Snake.createSnake(Snake.java:110)
at Snake.<init>(Snake.java:95)
at Driver.main(Driver.java:6)
I just need someone to please explain and help me fix this. I have asked numerous friends and no one that I know can help me fix it.
public class Driver {
public static void main(String[] args) {
Snake game = new Snake();
}
}
Below is this Snake class.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
#SuppressWarnings("serial")
class Snake extends JFrame implements KeyListener, Runnable{
JPanel gamePanel, scorePanel;
JButton extraFood;
JTextArea textAreaScore;
int x = 500;
int y = 250;
int minSnake = 3;
int directionx = 1;
int directiony = 0;
int speed = 50;
int difference = 0;
int oldx = 0;
int oldy = 0;
int score = 0;
boolean food = false;
boolean runLeft = false;
boolean runRight = true;
boolean runUp = true;
boolean runDown = true;
boolean bonusFlag = true;
Random ran = new Random();
JButton[] bc = new JButton[200];
int[] bx = new int[300];
int[] by = new int[300];
Thread myThread;
Point[] bp = new Point[300];
Point bonusp = new Point();
//initializing values
public void Values() {
minSnake = 3;
directionx = 10;
directiony = 0;
difference = 0;
score = 0;
food = false;
runLeft = false;
runRight = true;
runUp = true;
runDown = true;
bonusFlag = true;
}
//sets layout of game
public Snake() {
getContentPane().setBackground(Color.GRAY);
getContentPane().setLayout(null);
gamePanel = new JPanel();
gamePanel.setBackground(Color.LIGHT_GRAY);
gamePanel.setBounds(6, 6, 438, 223);
getContentPane().add(gamePanel);
gamePanel.setLayout(new GridLayout(1, 0, 0, 0));
scorePanel = new JPanel();
scorePanel.setBackground(Color.GRAY);
scorePanel.setBounds(6, 241, 438, 31);
getContentPane().add(scorePanel);
scorePanel.setLayout(null);
textAreaScore = new JTextArea("Your score is:" + score);
textAreaScore.setBackground(Color.LIGHT_GRAY);
textAreaScore.setBounds(0, 0, 303, 31);
scorePanel.add(textAreaScore);
//Exit Game button
JButton btnExitGame = new JButton("Exit Game");
btnExitGame.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
}
});
btnExitGame.setBounds(315, 0, 117, 29);
scorePanel.add(btnExitGame);
btnExitGame.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
setVisible(true);
createSnake();
extraFood = new JButton();
extraFood.setEnabled(false);
addKeyListener(this);
//This starts the game
myThread = new Thread(this);
myThread.start();
}
//Creates snake
public void createSnake() {
for (int i = 0; i < 3; i++){
bc[i] = new JButton("b" + i);
bc[i].setEnabled(false);
gamePanel.add(bc[i]);
bc[i].setBounds(bx[0], by[0], 10, 10);
bx[i + 1] = bx[i] - 10;
by[i + 1] = by[i];
}
}
#SuppressWarnings("deprecation")
void reset(){
Values();
gamePanel.removeAll();
myThread.stop();
createSnake();
textAreaScore.setText("Your score is: " + score);
myThread = new Thread(this);
myThread.start();
}
//As snake eats food, it grows
void snakeGrow(){
bc[minSnake] = new JButton();
bc[minSnake].setEnabled(false);
gamePanel.add(bc[minSnake]);
int a = 10 + (10 * ran.nextInt(48));
int b = 10 + (10 * ran.nextInt(23));
bx[minSnake] = a;
by[minSnake] = b;
bc[minSnake].setBounds(a, b, 10, 10);
minSnake++;
}
//Snake moving logic
void moveForward() {
for (int i = 0; i < minSnake; i++) {
bp[i] = bc[i].getLocation();
}
bx[0] += directionx;
by[0] += directiony;
bc[0].setBounds(bx[0], by[0], 10, 10);
for (int i = 1; i < minSnake; i++) {
bc[i].setLocation(bp[i - 1]);
}
if (bx[0] == x) {
bx[0] = 10;
} else if (bx[0] == 0) {
bx[0] = x - 10;
} else if (by[0] == y) {
by[0] = 10;
} else if (by[0] == 0) {
by[0] = y - 10;
}
if (bx[0] == bx[minSnake - 1] && by[0] == by[minSnake - 1]) {
food = false;
score += 1;
textAreaScore.setText("Your score is: " + score);
if (score % 50 == 0 && bonusFlag == true) {
gamePanel.add(extraFood);
extraFood.setBounds((10 * ran.nextInt(50)), (10 * ran.nextInt(25)), 15, 15);
bonusp = extraFood.getLocation();
bonusFlag = false;
}
}
if (bonusFlag == false) {
if (bonusp.x <= bx[0] && bonusp.y <= by[0] && bonusp.x + 10 >= bx[0] && bonusp.y +
10 >= by[0]) {
gamePanel.remove(extraFood);
score += 100;
textAreaScore.setText("Your score is: " + score);
bonusFlag = true;
}
}
if (food == false) {
snakeGrow();
food = true;
} else {
bc[minSnake - 1].setBounds(bx[minSnake - 1], by[minSnake - 1], 10, 10);
}
gamePanel.repaint();
extracted();
}
#SuppressWarnings("deprecation")
private void extracted() {
show();
}
public void keyPressed(KeyEvent e) {
//Move to the left when player presses the left arrow key
if (runLeft == true && e.getKeyCode() == 37) {
directionx = -10; //Moves to the left by 10 pixels
directiony = 0;
runRight = false;
runUp = true;
runDown = true;
}
//Move up when player presses the up arrow key
if (runUp == true && e.getKeyCode() == 38) {
directionx = 0;
directiony = -10; //Moves up by 10 pixels
runDown = false;
runRight = true;
runLeft = true;
}
//Move to the right when the player presses the right arrow key
if (runRight == true && e.getKeyCode() == 39) {
directionx = +10; //Moves right by 10 pixels
directiony = 0;
runLeft = false;
runUp = true;
runDown = true;
}
//Move down when the player presses the down arrow key
if (runDown == true && e.getKeyCode() == 40) {
directionx = 0;
directiony = +10; //Moves down by 10 pixels
runUp = false;
runRight = true;
runLeft = true;
}
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
public void run() {
for (;;) {
//Moves the snake forward
moveForward();
try {
Thread.sleep(speed);
} catch (InterruptedException ie) {
}
}
}
}
The problem is that you're not setting the global gamePanel variable in your constructor just a local version of it. Remove the JPanel in front of the variable initialization and it should work.
Same applies to your scorePanel and textAreaScore variables.
You declared view objects (i.e. gamePanel, scorePanel, extraFood, textAreaScore) as member variables of your class Snake, but then declared local variables of the same name in your constructor.
Member variables:
JPanel gamePanel, scorePanel;
JButton extraFood;
JTextArea textAreaScore;
Local variables:
public Snake() {
...
JPanel gamePanel = new JPanel();
...
JPanel scorePanel = new JPanel();
...
JTextArea textAreaScore = new JTextArea("Your score is:" + score);
...
Change the constructor to instantiate your member variables like so:
public Snake() {
...
this.gamePanel = new JPanel();
...
this.scorePanel = new JPanel();
...
this.textAreaScore = new JTextArea("Your score is:" + score);
...
The problem is here:
You defined the global variable:
JPanel gamePanel, scorePanel;
JTextArea textAreaScore;
But you defined dupplicate in:
public Snake() {
JPanel gamePanel = new JPanel();
...
JPanel scorePanel = new JPanel();
...
JTextArea textAreaScore = new JTextArea("Your score is:" + score);
...
}
So, change them to:
public Snake() {
gamePanel = new JPanel();
...
scorePanel = new JPanel();
...
textAreaScore = new JTextArea("Your score is:" + score);
...
}
That's it.
You are shadowing gamePanel in the constructor of Snake. Replace
JPanel gamePanel = new JPanel();
with
gamePanel = new JPanel();
The variables scorePanel and textAreaScore have the same issue.
Side issues:
Don't use KeyListeners in Swing applications. They were not designed to be used with Swing applications. Use Key Bindings instead.
Similarly don't use raw Threads for Swing applications, use a Swing Timer instead
Related
I need help to improve my simple game of Tron. I first created Snake for a project and then decided to create this since I thought it would be somewhat similar. However, even though I used pretty much the same code for the key adapters in both, Snake's works but Tron's doesn't. If it makes any difference Snake was coded in JGrasp and Tron in Eclipse. Based on what I can tell from debugging the key adapter is not responding at all which made me think it was a focus problem but Tron's codes requests focus at all the same times Snake does and as I said Snake works fine. If someone could help me with that it would be great.
Also since I am relatively new to coding I would love suggestions afterwards on how I could improve the program in speed, or taking less memory. Also, any suggestions you have on features I should add to the game or ways I can make the game just look better, I would be very grateful to hear them. I might need help making these features especially if they introduce new concepts so I might contact you afterwards looking for help on how to do somethings.
Anyway here is the code:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class Tron_Board extends JPanel{
public int directionleft = 4;
public int directionright = 3;
static JLabel instr, Lwins, Rwins;
public int numL, numR = 0;
static int[][] array;
static JLabel[][] board;
Timer timer;
public final int rows = 100;
public final int columns = 200;
JButton resetButton, quitButton, startButton;
public Tron_Board()
{
setLayout(new BorderLayout());
array = new int[rows][columns];
board = new JLabel[rows][columns];
JPanel north = new JPanel();
north.setLayout(new BorderLayout());
Lwins = new JLabel("" + numL);
north.add(Lwins, BorderLayout.WEST);
Rwins = new JLabel("" + numR);
north.add(Rwins, BorderLayout.EAST);
instr = new JLabel("Best of 5! Good Luck!");
instr.setHorizontalAlignment(SwingConstants.CENTER);
north.add(instr, BorderLayout.CENTER);
Lwins.setFont(new Font("Serif", Font.BOLD, 30));
Rwins.setFont(new Font("Serif", Font.BOLD, 30));
instr.setFont(new Font("Serif", Font.BOLD, 25));
add(north, BorderLayout.NORTH);
JPanel center = new JPanel();
center.setLayout(new GridLayout(rows, columns));
for(int r = 0; r < array.length; r++)
for(int c = 0; c < array[0].length; c++)
{
array[r][c] = 0;
board[r][c] = new JLabel();
board[r][c].setOpaque(true);
center.add(board[r][c]);
}
add(center, BorderLayout.CENTER);
JPanel south = new JPanel();
south.setLayout(new FlowLayout());
add(south, BorderLayout.SOUTH);
resetButton = new JButton("Reset");
resetButton.addActionListener(new ResetListener());
resetButton.setEnabled(false);
startButton = new JButton("Start Round");
startButton.addActionListener(new StartListener());
startButton.setEnabled(false);
south.add(resetButton);
south.add(startButton);
quitButton = new JButton("Quit");
quitButton.addActionListener(new QuitListener());
south.add(quitButton);
addKeyListener(new Key());
setFocusable(true);
requestFocus();
timer = new Timer(75, new Listener());
reset();
}
private void start()
{
timer.start();
startButton.setEnabled(false);
}
private static void update()
{
for(int r = 0; r < array.length; r++)
for(int c = 0; c < array[r].length; c++)
{
switch(array[r][c]){
case 0: board[r][c].setBackground(Color.BLACK);
break;
case 1: board[r][c].setBackground(Color.RED);
break;
case 2: board[r][c].setBackground(Color.ORANGE);
break;
case 3: board[r][c].setBackground(new Color(13, 182, 233));
break;
case 4: board[r][c].setBackground(Color.YELLOW);
break;
case 5: board[r][c].setBackground(new Color(169, 212, 144));
break;
}
}
}
private void move()
{
int oldR = 0;
int oldC = 0;
int newR = 0;
int newC = 0;
int oldR2 = 0;
int oldC2 = 0;
int newR2 = 0;
int newC2 = 0;
for(int r = 0; r < array.length; r++)
{
for(int c = 0; c < array[r].length; c++)
{
if(array[r][c] == 1)
{
oldR = r;
oldC = c;
switch(directionleft){
case 1: newR = oldR - 1; //up
newC = oldC;
break;
case 2: newR = oldR + 1; //down
newC = oldC;
break;
case 3: newR = oldR; //left
newC = oldC - 1;
break;
case 4: newR = oldR; //right
newC = oldC + 1;
break;
}
}
}
}
for(int r = 0; r < array.length; r++)
{
for(int c = 0; c < array[r].length; c++)
{
if(array[r][c] == 3)
{
oldR2 = r;
oldC2 = c;
switch(directionright)
{
case 1: newR2 = oldR2 - 1; //up
newC2 = oldC2;
break;
case 2: newR2 = oldR2 + 1; //down
newC2 = oldC2;
break;
case 3: newR2 = oldR2; //left
newC2 = oldC2 - 1;
break;
case 4: newR2 = oldR2; //right
newC2 = oldC2 + 1;
break;
}
}
}
}
if((array[newR2][newC2] == 0) && (array[newR][newC] == 0)){
array[oldR][oldC] = 2;
array[newR][newC] = 1;
array[oldR2][oldC2] = 4;
array[newR2][newC2] = 3;
}
else if((array[newR2][newC2] > 0) && (array[newR][newC] > 0)){
roundLose("draw");
}
else if(array[newR2][newC2] > 0){
roundLose("right");
}
else if(array[newR][newC] > 0){
roundLose("left");
}
}
private void gameWin(String player)
{
timer.stop();
instr.setText("Congratulations, " + player + " player won!");
resetButton.setEnabled(true);
}
public void roundLose(String player){
timer.stop();
if(player.equals("left"))
{
if(numR + 1 == 3)
{
gameWin("right");
}
else
{
numR += 1;
}
}
if(player.equals("right"))
{
if(numL + 1 == 3)
{
gameWin("left");
}
else
{
numL += 1;
}
}
if(player.equals("draw"))
{
instr.setText("DRAW!!!");
}
reset();
}
private void reset()
{
timer.stop();
directionleft = 4;
directionright = 3;
Lwins.setText("" + numL);
Rwins.setText("" + numR);
instr.setText("Best of 5! Good Luck!");
for(int r = 0; r < array.length; r++)
for(int c = 0; c < array[0].length; c++)
{
if(r == 0 || r == (array.length - 1) || c == 0 || c == (array[0].length - 1))
array[r][c] = 5; //wall
else
array[r][c] = 0; //background
}
array[rows / 2][7] = 1;
array[rows / 2][columns - 8] = 3;
update();
startButton.setEnabled(true);
resetButton.setEnabled(false);
requestFocus();
}
private class Listener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
move();
update();
}
}
private class ResetListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
reset();
numL = 0;
numR = 0;
}
}
private class QuitListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
}
private class StartListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
start();
}
}
private class Key extends KeyAdapter
{
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode() == KeyEvent.VK_W){
directionleft = 1;
System.out.println("I'm here");//up
}
if(e.getKeyCode() == KeyEvent.VK_S) //down
directionleft = 2;
if(e.getKeyCode() == KeyEvent.VK_A) //left
directionleft = 3;
if(e.getKeyCode() == KeyEvent.VK_D) //right
directionleft = 4;
if(e.getKeyCode() == KeyEvent.VK_UP)
directionright = 1;
if(e.getKeyCode() == KeyEvent.VK_DOWN)
directionright = 2;
if(e.getKeyCode() == KeyEvent.VK_LEFT)
directionright = 3;
if(e.getKeyCode() == KeyEvent.VK_RIGHT)
directionright = 4;
}
}
}
I put it in a JFrame under Java 8u91 on Windows 7 and the key listener works for me.
How are you using the panel and have you tried running from outside Eclipse?
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().
i am creating a maze generation application. what i want to happen is that, when i run my program, it will show the animation on how the maze was created (it will show how it knocks the wall to create a path).
i tried to put delay on some of its parts but it won't run.thank you for the HUGE HELP!
here's the code:
public class Maze extends JPanel {
private Room[][] rooms;// m x n matrix of rooms
private ArrayList<Wall> walls; // List of walls
private Random rand;// for random wall
private int height;// height of matrix
private int width;// width of matrix
private int num;// incrementor
private JoinRoom ds;// union paths
// paint methods //
private int x_cord; // x-axis rep
private int y_cord;// y-axis rep
private int roomSize;
private int randomWall;
private int create;
int mazectr;
public static int m;// these are variables for the size of maze (m x n)
public static int n;
public Maze(int m, int n) {
JPanel j = new JPanel();
final JFrame f = new JFrame();
this.height = m;
this.width = n;
rooms = new Room[m][n];
walls = new ArrayList<Wall>((m - 1) * (n - 1));
long startTime = System.currentTimeMillis();
generateRandomMaze();
long endTime = System.currentTimeMillis();
final JLabel jl = new JLabel("Time Taken: " + (endTime-startTime) + "ms");
final JButton y = new JButton("OK");
j.add(jl);
j.add(y);
f.add(j);
y.addActionListener(new ActionListener(){
public void actionPerformed (ActionEvent e)
{
f.setVisible(false);
}
});
f.setVisible(true);
f.setSize(100, 100);
//jl.setLocation(1000, 1500);
//jl.setBounds(0, 0, 110, 130);
setPreferredSize(new Dimension(800, 700));
}
private void generateRandomMaze() {
generateInitialRooms();// see next method
ds = new JoinRoom(width * height);
rand = new Random(); // here is the random room generator
num = width * height;
while (num > 1) {
// when we pick a random wall we want to avoid the borders getting eliminated
randomWall = rand.nextInt(walls.size());
Wall temp = walls.get(randomWall);
// we will pick two rooms randomly
int roomA = temp.currentRoom.y + temp.currentRoom.x * width;
int roomB = temp.nextRoom.y + temp.nextRoom.x * width;
// check roomA and roomB to see if they are already members
if (ds.find(roomA) != ds.find(roomB)) {
walls.remove(randomWall);
ds.unionRooms(ds.find(roomA), ds.find(roomB));
temp.isGone = true;
temp.currentRoom.adj.add(temp.nextRoom);
temp.nextRoom.adj.add(temp.currentRoom);
num--;
}// end of if
}// end of while
}
// name the room to display
private int roomNumber = 0;
private static Label input;
private static Label input2;
/**
* Sets the grid of rooms to be initially boxes
* This is self explanitory, we are only creating an reverse L for all
* The rooms and there is an L for the border
*/
private void generateInitialRooms() {
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
// create north walls
rooms[i][j] = new Room(i, j);
if (i == 0) {
rooms[i][j].north = new Wall(rooms[i][j]);
} else {
rooms[i][j].north = new Wall(rooms[i - 1][j], rooms[i][j]);
walls.add(rooms[i][j].north);
}
if (i == height - 1) {
rooms[i][j].south = new Wall(rooms[i][j]);
}
if (j == 0) {
rooms[i][j].west = new Wall(rooms[i][j]);
} else {
rooms[i][j].west = new Wall(rooms[i][j - 1], rooms[i][j]);
walls.add(rooms[i][j].west);
}
if (j == width - 1) {
rooms[i][j].east = new Wall(rooms[i][j]);
}
rooms[i][j].roomName = roomNumber++;// we will name the rooms
}
}
// initalize entrance and exit
rooms[0][0].west.isGone = true;// you can replace .west.isGone with .north.isGone
// this is just saying the roomName for top left is 0
rooms[0][0].roomName = 0;
// we will remove the south wall of the last room
rooms[height - 1][width - 1].south.isGone = true;
// this is just saying the roomName for bottom right is the last element in the mxn room matrix
rooms[height - 1][width - 1].roomName = (height * width);
}
public void paintComponent(Graphics g) {
x_cord = 40;
y_cord = 40;
Thread t = new Thread();
// could have taken height as well as width
// just need something to base the roomsize
roomSize = (width - x_cord) / width + 20;
// temp variables used for painting
int x = x_cord;
int y = y_cord;
for (int i = 0; i <= height - 1; i++) {
for (int j = 0; j <= width - 1; j++) {
if (!(rooms[i][j].north.isGone)) {
g.drawLine(x, y, x + roomSize, y);
}//end of north if
// west wall not there draw the line
if (rooms[i][j].west.isGone == false) {
g.drawLine(x, y, x, y + roomSize);
}// end of west if
if ((i == height - 1) && rooms[i][j].south.isGone == false) {
g.drawLine(x, y + roomSize, x + roomSize,
y + roomSize);
}// end of south if
if ((j == width - 1) && rooms[i][j].east.isGone == false) {
g.drawLine(x + roomSize, y, x + roomSize,
y + roomSize);
}// end of east if
x += roomSize;// change the horizontal
try
{
Thread.sleep(50);
} catch (Exception e) {};
t.start();
}// end of inner for loop
x = x_cord;
y += roomSize;
}// end of outer for loop
}
public static void main(String[] args) throws IOException {
// use JFrame to put the created panel on
String path = "E:\\Iskul\\trys\\tryy\\bin\\GUI.jpg";
File file = new File("E:\\Iskul\\trys\\tryy\\bin\\GUI.jpg");
BufferedImage image = ImageIO.read(file);
File fileRec = new File("E:\\Iskul\\trys\\tryy\\bin\\re.jpg");
BufferedImage imageRec = ImageIO.read(fileRec);
File fileHex = new File("E:\\Iskul\\trys\\tryy\\bin\\hexx.jpg");
BufferedImage imageHex = ImageIO.read(fileHex);
final JFrame frame = new JFrame("Prim's Algorithm");
final JPanel jp = new JPanel();
final JTextField input = new JTextField(10);
final JTextField input2 = new JTextField(10);
final JButton jb = new JButton(new ImageIcon(imageRec));
jb.setBorder(BorderFactory.createEmptyBorder());
final JButton jb1 = new JButton(new ImageIcon(imageHex));
jb1.setBorder(BorderFactory.createEmptyBorder());
final JLabel label = new JLabel(new ImageIcon(image));
jb.setLocation(100, 10);
frame.getContentPane().add(label);
frame.pack();
frame.setVisible(true);
frame.setSize(400, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(new Dimension(795, 501));
jp.add(input);
jp.add(input2);
frame.add(jp);
jp.add(jb);
jp.add(jb1);
//jb.setImage(image);
jb.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
//int mazectr = 1;
int m = Integer.valueOf(input.getText());
int n = Integer.valueOf(input2.getText());
frame.remove(label);
frame.remove(jp);
//frame.add(new Maze(m,n));
frame.getContentPane().add(new Maze(m, n));
frame.pack();
}});
jb1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
//int m = Integer.valueOf(input.getText());
//int n = Integer.valueOf(input2.getText());
Hexa1 hexa = new Hexa1();
hexa.main();
//hexa.run();
}
});
}}// end of main
Your code wont work, you cant do an sleep in the Paint method, because if you do so, he wont draw, he just waits and at the end he'll draw your whole image.
If you want to do a nice effect, you should draw one step after the other but you should be aware that this is a lot of work to realize...
I have a problem, I have a game, tic tac toe, and i can't figure out how to make it so when someone wins or someone moves it blocks the certain spot, and when someone wins it will not let you do anything, it is inside a JFrame, I can always keep changing the O and X
Here is the code
package project;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.swing.Timer;
import java.util.Random;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Project extends JFrame
{
static JButton startButton = new JButton();
static ImageIcon image = new ImageIcon("src/project/imagesX1.jpg");
static ImageIcon imageX = new ImageIcon("src/project/images1.jpg");
static JButton restart = new JButton();
static JLabel label0 = new JLabel();
static JLabel label1 = new JLabel();
static JLabel label2 = new JLabel();
static JLabel label3 = new JLabel();
static JLabel label4 = new JLabel();
static JLabel label5 = new JLabel();
static JLabel label6 = new JLabel();
static JLabel label7 = new JLabel();
static JLabel label8 = new JLabel();
static JLabel vert1 = new JLabel();
static JLabel vert2 = new JLabel();
static JLabel horiz1 = new JLabel();
static JLabel horiz2 = new JLabel();
static JLabel showWinner = new JLabel();
static int[] gridMark = new int[9];
static boolean xTurn = true;
static int numberClicks = 0;
static Timer drawTimer;
static JLabel[] choiceLabel = new JLabel[9];
static int[] labelValue = new int[9];
static int screen = 0;
static int whosTurn = 0;
static int counter = 0;
public static void main(String[] args)
{
new Project().show();
}
public Project()
{
setTitle("Tic Tac Toe");
setVisible(true);
setResizable(true);
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
getContentPane().setLayout(new GridBagLayout());
GridBagConstraints myGrid = new GridBagConstraints();
getContentPane().setBackground(Color.white);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
setBounds((int) (0.5 * (screenSize.width - getWidth())), (int) (0.5 * (screenSize.height - getHeight())), getWidth(), getHeight());
for (int i = 0; i < 9; i++)
{
gridMark[i] = 0;
}
for (int i = 0; i < 9; i++)
{
labelValue[i] = 0;
}
choiceLabel[0] = label0;
choiceLabel[1] = label1;
choiceLabel[2] = label2;
choiceLabel[3] = label3;
choiceLabel[4] = label4;
choiceLabel[5] = label5;
choiceLabel[6] = label6;
choiceLabel[7] = label7;
choiceLabel[8] = label8;
//ROW 1
int x = 0;
for (int i = 0; i < 3; i++)
{
myGrid = new GridBagConstraints();
choiceLabel[i].setBackground(Color.white);
choiceLabel[i].setPreferredSize(new Dimension(image.getIconWidth(), image.getIconHeight()));
choiceLabel[i].setHorizontalAlignment(SwingConstants.CENTER);
choiceLabel[i].setOpaque(true);
choiceLabel[i].setForeground(Color.black);
myGrid.gridx = x;
x+=2;
myGrid.gridy = 0;
//gridConstraints.insets = new Insets(10, 10, 10, 10);
myGrid.ipadx = 40;
myGrid.ipady = 40;
getContentPane().add(choiceLabel[i], myGrid);
choiceLabel[i].addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
labelMouseClicked(e);
}
});
}
//ROW 2
x = 0;
for (int i = 3; i < 6; i++)
{
myGrid = new GridBagConstraints();
choiceLabel[i].setBackground(Color.white);
choiceLabel[i].setPreferredSize(new Dimension(image.getIconWidth(), image.getIconHeight()));
choiceLabel[i].setHorizontalAlignment(SwingConstants.CENTER);
choiceLabel[i].setOpaque(true);
choiceLabel[i].setForeground(Color.black);
myGrid.gridx = x;
x+=2;
myGrid.gridy = 3;
myGrid.ipadx = 40;
myGrid.ipady = 40;
getContentPane().add(choiceLabel[i], myGrid);
choiceLabel[i].addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
labelMouseClicked(e);
}
});
}
//ROW 3
x = 0;
for (int i = 6; i < 9; i++)
{
myGrid = new GridBagConstraints();
choiceLabel[i].setBackground(Color.white);
choiceLabel[i].setPreferredSize(new Dimension(image.getIconWidth(), image.getIconHeight()));
choiceLabel[i].setHorizontalAlignment(SwingConstants.CENTER);
choiceLabel[i].setOpaque(true);
choiceLabel[i].setForeground(Color.black);
myGrid.gridx = x;
x+=2;
myGrid.gridy = 5;
myGrid.ipadx = 40;
myGrid.ipady = 40;
getContentPane().add(choiceLabel[i], myGrid);
choiceLabel[i].addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
labelMouseClicked(e);
}
});
}
myGrid = new GridBagConstraints();
horiz1.setOpaque(true);
horiz1.setBackground(Color.blue);
myGrid.gridx = 0;
myGrid.gridy = 1;
myGrid.gridwidth = 5;
myGrid.ipadx = 500;
myGrid.ipady = 2;
getContentPane().add(horiz1, myGrid);
myGrid = new GridBagConstraints();
horiz2.setOpaque(true);
horiz2.setBackground(Color.blue);
myGrid.gridx = 0;
myGrid.gridy = 4;
myGrid.gridwidth = 5;
myGrid.ipadx = 500;
myGrid.ipady = 2;
getContentPane().add(horiz2, myGrid);
myGrid = new GridBagConstraints();
vert1.setOpaque(true);
vert1.setBackground(Color.blue);
vert1.setVerticalAlignment(SwingConstants.CENTER);
myGrid.gridx = 1;
myGrid.gridy = 0;
myGrid.gridheight = 6;
myGrid.ipadx = 2;
myGrid.ipady = 500;
//gridConstraints.insets = new Insets(10, 0, 10, 0);
getContentPane().add(vert1, myGrid);
myGrid = new GridBagConstraints();
vert2.setOpaque(true);
vert2.setBackground(Color.blue);
myGrid.gridx = 3;
myGrid.gridy = 0;
myGrid.gridheight = 6;
myGrid.ipadx = 2;
myGrid.ipady = 500;
//gridConstraints.insets = new Insets(10, 0, 10, 0);
getContentPane().add(vert2, myGrid);
myGrid = new GridBagConstraints();
showWinner.setBackground(Color.white);
showWinner.setOpaque(true);
myGrid.gridx = 0;
myGrid.gridy = 6;
myGrid.gridwidth = 5;
myGrid.gridheight = 6;
getContentPane().add(showWinner, myGrid);
restart.setText("Restart");
myGrid.gridx = 1;
myGrid.gridy = 7;
getContentPane().add(restart, myGrid);
restart.setVisible(false);
restart.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
restartActionPerformed(e);
}
});
pack();
}
private void labelMouseClicked(MouseEvent e)
{
Component clickedComponent = e.getComponent();
int choice;
for (choice = 0; choice < 9; choice++)
{
if (clickedComponent == choiceLabel[choice])
{
break;
}
}
choiceLabel[choice].setBackground(Color.WHITE);
if (whosTurn == 0)
{
choiceLabel[choice].setIcon(image);
labelValue[choice] = 1;
whosTurn = 1;
}
else if (whosTurn == 1)
{
choiceLabel[choice].setIcon(imageX);
labelValue[choice] = 5;
whosTurn = 0;
}
counter += 1;
checkWinner();
}
public static void checkWinner()
{
if (labelValue[0] + labelValue[1] + labelValue[2] == 3 || labelValue[3] + labelValue[4] + labelValue[5] == 3 || labelValue[6] + labelValue[7] + labelValue[8] == 3 ||
labelValue[0] + labelValue[3] + labelValue[6] == 3 || labelValue[1] + labelValue[4] + labelValue[7] == 3 || labelValue[2] + labelValue[5] + labelValue[8] == 3 ||
labelValue[0] + labelValue[4] + labelValue[8] == 3 || labelValue[2] + labelValue[4] + labelValue[6] == 3)
{
showWinner.setFont(new Font("Arial" , Font.BOLD, 30));
showWinner.setText("X wins!");
restart.setVisible(true);
}
else if (labelValue[0] + labelValue[1] + labelValue[2] == 15 || labelValue[3] + labelValue[4] + labelValue[5] == 15 || labelValue[6] + labelValue[7] + labelValue[8] == 15 ||
labelValue[0] + labelValue[3] + labelValue[6] == 15 || labelValue[1] + labelValue[4] + labelValue[7] == 15 || labelValue[2] + labelValue[5] + labelValue[8] == 15 ||
labelValue[0] + labelValue[4] + labelValue[8] == 15 || labelValue[2] + labelValue[4] + labelValue[6] == 15)
{
showWinner.setFont(new Font("Arial" , Font.BOLD, 30));
showWinner.setText("O wins!");
restart.setVisible(true);
}
else if (counter == 9)
{
showWinner.setFont(new Font("Arial" , Font.BOLD, 30));
showWinner.setText("It's a draw");
restart.setVisible(true);
}
}
public static int getGridSelected (int a, int b, int c, int d)
{
if(gridMark[a] + gridMark[b] + gridMark[c] == d)
{
if(gridMark[a] == 0) return a;
else if(gridMark[b] == 0) return b;
else if(gridMark[c] == 0) return c;
}
return -1;
}
public void restartActionPerformed(ActionEvent e)
{
}
}
AI FOR FRAME:
public static void makeMove()
{
myFrame.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
int gridSelected;
int y;
Random r = new Random();
Graphics myGraphics = myFrame.getGraphics();
//find gridSelected for "can win"
if (getGridSelected(0,1,2,10) != -1) gridSelected = getGridSelected(0,1,2,10);
else if (getGridSelected(3,4,5,10) != -1) gridSelected = getGridSelected(3,4,5,10);
else if (getGridSelected(6,7,8,10) != -1) gridSelected = getGridSelected(6,7,8,10);
else if (getGridSelected(0,3,6,10) != -1) gridSelected = getGridSelected(0,3,6,10);
else if (getGridSelected(1,4,7,10) != -1) gridSelected = getGridSelected(1,4,7,10);
else if (getGridSelected(2,5,8,10) != -1) gridSelected = getGridSelected(2,5,8,10);
else if (getGridSelected(0,4,8,10) != -1) gridSelected = getGridSelected(0,4,8,10);
else if (getGridSelected(2,4,6,10) != -1) gridSelected = getGridSelected(2,4,6,10);
//find gridSelected for "block win"
else if (getGridSelected(0,1,2,2) != -1) gridSelected = getGridSelected(0,1,2,2);
else if (getGridSelected(3,4,5,2) != -1) gridSelected = getGridSelected(3,4,5,2);
else if (getGridSelected(6,7,8,2) != -1) gridSelected = getGridSelected(6,7,8,2);
else if (getGridSelected(0,3,6,2) != -1) gridSelected = getGridSelected(0,3,6,2);
else if (getGridSelected(1,4,7,2) != -1) gridSelected = getGridSelected(1,4,7,2);
else if (getGridSelected(2,5,8,2) != -1) gridSelected = getGridSelected(2,5,8,2);
else if (getGridSelected(0,4,8,2) != -1) gridSelected = getGridSelected(0,4,8,2);
else if (getGridSelected(2,4,6,2) != -1) gridSelected = getGridSelected(2,4,6,2);
//is the center available?
else if (gridMark[4] == 0)gridSelected = 4;
//if all else fail pick a random blank square
else
{
while(true)
{
gridSelected = r.nextInt(9);
if (gridMark[gridSelected] == 0)break;
}
}
int x = 40 + (gridSelected % 3) * 80;
if (gridSelected <= 2) y = 50;
else if (gridSelected <= 5) y = 130;
else y = 210;
// draw O
gridMark[gridSelected] = 5;
myGraphics.setColor(Color.red);
myGraphics.drawOval(x, y, 60, 60);
checkWinner();
xTurn = true;
if (numberClicks != 10)
{
numberClicks++;
}
}
In labelMouseClicked() you have to check if the field is already clicked. For example check choiceLabel[choice].getBackground():
if (choiceLabel[choice].getBackground().equal(Color.WHITE))
{
// already clicked
return;
}
To check if the game is over you may return a boolean value in checkWinner() or better make a new function for it: isGameEnd(). You could use it in labelMouseClicked() and checkWinner().
public class Project extends JFrame
{
static boolean gameHasEnded;
...
public Project()
{
...
gameHasEnded = false;
}
...
private void labelMouseClicked(MouseEvent e)
{
// If any player has already won, abort. Label will not be changed.
// Players turn will not be switched.
if (gameHasEnded) return;
...
// If the label has already been clicked, abort.
if (labelValue[choice] != 0) return;
choiceLabel[choice].setBackground(Color.WHITE);
...
}
public static void checkWinner()
{
...
restart.setVisible(true);
gameHasEnded = true;
...
restart.setVisible(true);
gameHasEnded = true;
...
restart.setVisible(true);
gameHasEnded = true;
...
}
public void restartActionPerformed(ActionEvent e)
{
for (int i = 0; i < 9; i++)
{
labelValue[i] = 0;
choiceLabel[i].setIcon(null);
choiceLabel[i].setBackground(Color.white);
}
showWinner.setText("");
restart.setVisible(false);
counter = 0;
whosTurn = 0;
gameHasEnded = false;
}
}
Edit: You seem to have two "grids". The JFrame version uses labelValue and the Fame version gridMark.
Remove the declarations of the fields gridMark, numberClicks and xTurn, since they should not be used.
Replace all references to gridMark with labelValue.
Replace all references to numberClicks with counter.
Change xTurn = true; to whosTurn = 0;.
Replace the drawing commands. (E.g. myGraphics.drawOval(x, y, 60, 60);) with choiceLabel[gridSelected].setIcon(imageX);
After the call to checkWinner() in labelMouseClicked, insert this:
if (!gameHasEnded)
{
makeMove();
}
One tip: Remove all fields you are not using in the JFrame-version. This will make all references to Frame-version variables to be highlighted as errors.
I am currently developing a booking system as a task for my degree. I need the seating plan to be "saved/stored" for each showing time (radio buttons), so that e.g. If I book 2 tickets at 13:00, I can also book 2 tickets on the same spot for 15:00. What is the best way of doing this?
PS: I'm not making use of a database and I would prefer not to; due to task's requirements.
Here's my code, please run it if you can.
// CM1203 Fundamentals of Computing with Java; Second Assignement.
// Walter Carvalho - C1001984; 2012.
// Cardiff University
// Load Libraries
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.text.*;
public class cinemaSystem extends JFrame implements ActionListener {
// Global Variables
boolean lselected, rselected, mselected;
double chargeDue;
int a, b, c;
static Ticket oapticket, childticket, adultticket;
JFrame frame = new JFrame(); // Creates JFrame
JLabel title, lchild, ladult, loap, ltotalprice, time;
JTextField child, adult, oap, totalprice;
JButton submit;
JRadioButton time1, time2, time3, time4, time5; // Radio Butons
JToggleButton l[][], m[][], r[][]; // Names grid of JButtons
JPanel panel1, panel2, panel3, panel4, panel5, panel6;
ArrayList<String> seatsAvailable = new ArrayList<String>();
ArrayList<String> coupon = new ArrayList<String>();
// Constructor
public cinemaSystem(){
title = new JLabel("Cinema Booking System");
title.setFont(new Font("Helvetica", Font.BOLD, 30));
title.setLocation(12,5);
title.setSize(600, 60);
frame.setLayout(null); // Setting Grid Layout
// panel1.setLayout(new GridLayout(seat,row));
l = new JToggleButton[4][4]; // Allocating Size of Grid
panel1 = new JPanel(new GridLayout(4,4));
panel1.setBounds(20, 95, 220, 140);
for(int y = 0; y <4 ; y++){
for(int x = 0; x < 4; x++){
l[x][y] = new JToggleButton("L" + y + x); // Creates New JButton
l[x][y].addActionListener(this);
seatsAvailable.add("L" + y + x);
panel1.add(l[x][y]); //adds button to grid
}
}
m = new JToggleButton[4][2]; // Allocating Size of Grid
panel2 = new JPanel(new GridLayout(2,4));
panel2.setBounds(240, 165, 220, 70);
for(int y = 0; y <2 ; y++){
for(int x = 0; x < 4; x++){
m[x][y] = new JToggleButton("M" + y + x); // Creates New JButton
m[x][y].addActionListener(this);
seatsAvailable.add("M" + y + x);
panel2.add(m[x][y]); //adds button to grid
}
}
r = new JToggleButton[4][4]; // Allocating Size of Grid
panel3 = new JPanel(new GridLayout(4,4));
panel3.setBounds(460, 95, 220, 140);
for(int y = 0; y <4 ; y++){
for(int x = 0; x < 4; x++){
r[x][y] = new JToggleButton("R" + y + x); // Creates New JButton
r[x][y].addActionListener(this);
seatsAvailable.add("R" + y + x);
panel3.add(r[x][y]); //adds button to grid
}
}
panel4 = new JPanel(new FlowLayout());
panel4.setBounds(0, 250, 300, 70);
lchild = new JLabel("Child");
child = new JTextField("0", 2);
child.addActionListener(this);
ladult = new JLabel("Adult");
adult = new JTextField("0", 2);
adult.addActionListener(this);
loap = new JLabel("OAP");
oap = new JTextField("0", 2);
oap.addActionListener(this);
submit = new JButton("Submit");
submit.addActionListener(this);
oapticket = new Ticket(4.70);
childticket = new Ticket(3.50);
adultticket = new Ticket(6.10);
child.addKeyListener(new MyKeyAdapter());
oap.addKeyListener(new MyKeyAdapter());
adult.addKeyListener(new MyKeyAdapter());
panel4.add(lchild);
panel4.add(child);
panel4.add(ladult);
panel4.add(adult);
panel4.add(loap);
panel4.add(oap);
panel4.add(submit);
panel5 = new JPanel(new FlowLayout());
panel5.setBounds(240, 250, 300, 70);
ltotalprice = new JLabel("Charge Due (£): ");
totalprice = new JTextField("£0.00", 5);
totalprice.setEnabled(false);
panel5.add(ltotalprice);
panel5.add(totalprice);
panel6 = new JPanel(new FlowLayout());
panel6.setBounds(0, 55, 560, 30);
time = new JLabel("Please select a film time: ");
time1 = new JRadioButton("13:00", true);
time2 = new JRadioButton("15:00", false);
time3 = new JRadioButton("17:00", false);
time4 = new JRadioButton("19:00", false);
time5 = new JRadioButton("21:00", false);
ButtonGroup group = new ButtonGroup();
group.add(time1);
group.add(time2);
group.add(time3);
group.add(time4);
group.add(time5);
panel6.add(time);
panel6.add(time1);
panel6.add(time2);
panel6.add(time3);
panel6.add(time4);
panel6.add(time5);
time1.addActionListener(this);
time2.addActionListener(this);
time3.addActionListener(this);
time4.addActionListener(this);
time5.addActionListener(this);
frame.add(title);
frame.add(panel1);
frame.add(panel2);
frame.add(panel3);
frame.add(panel4);
frame.add(panel5);
frame.add(panel6);
frame.setPreferredSize(new Dimension(700, 350));
frame.setTitle("Cinema Booking");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack(); //sets appropriate size for frame
frame.setVisible(true); //makes frame visible
}
// Calculates Charge Due for current transaction.
public double calcChargeDue(){
DecimalFormat df = new DecimalFormat("#.##");
double chargeDue = 0.0;
chargeDue = (a*childticket.price) + (b*oapticket.price) + (c*adultticket.price);
totalprice.setText("£"+df.format(chargeDue));
return chargeDue;
}
// Method to check if the number of people matches the number of seats selected.
public void check(){
int check = coupon.size();
int noTickets = a + b + c;
if (check != noTickets){
submit.setEnabled(false);
}
else {
submit.setEnabled(true);
}
}
// Ticket Object
public class Ticket {
double price;
// Constructor
public Ticket(double cost) {
price = cost;
}
public double getTicketPrice() {
return price;
}
}
public void actionPerformed(ActionEvent e)
{
a = Integer.parseInt(child.getText());
b = Integer.parseInt(oap.getText());
c = Integer.parseInt(adult.getText());
for(int y = 0; y < 4; y++){
for(int x = 0; x < 4; x++){
lselected = l[x][y].isSelected();
rselected = r[x][y].isSelected();
if (e.getSource() == l[x][y]) {
if(lselected == true){
coupon.add(e.getActionCommand());
calcChargeDue();
check();
}
else {
coupon.remove(e.getActionCommand());
check();
}
}
if (e.getSource() == r[x][y]) {
if(rselected == true){
coupon.add(e.getActionCommand());
calcChargeDue();
check();
}
else {
coupon.remove(e.getActionCommand());
check();
}
}
if (e.getSource() == oap){
calcChargeDue();
check();
}
if (e.getSource() == adult){
calcChargeDue();
check();
}
if (e.getSource() == child){
calcChargeDue();
check();
}
}
}
for(int y = 0; y < 2; y++){
for(int x = 0; x < 4; x++){
mselected = m[x][y].isSelected();
if (e.getSource() == m[x][y]) {
if(mselected == true){
coupon.add(e.getActionCommand());
calcChargeDue();
check();
}
else {
coupon.remove(e.getActionCommand());
check();
}
}
}
}
if(time1 == e.getSource()){
}
if(time2 == e.getSource()){
}
if(time3 == e.getSource()){
}
if(time4 == e.getSource()){
}
if(time5 == e.getSource()){
}
if(submit == e.getSource()) {
for(int y = 0; y < 4; y++){
for(int x = 0; x < 4; x++){
lselected = l[x][y].isSelected();
rselected = r[x][y].isSelected();
if (lselected == true) {
l[x][y].setEnabled(false);
}
if (rselected == true) {
r[x][y].setEnabled(false);
}
}
}
for(int y = 0; y < 2; y++){
for(int x = 0; x < 4; x++){
mselected = m[x][y].isSelected();
if (mselected == true) {
m[x][y].setEnabled(false);
}
}
}
Collections.sort(coupon);
System.out.println("Here's your ticket:");
System.out.println(coupon);
System.out.println("Child: " + child.getText());
System.out.println("Adult: " + adult.getText());
System.out.println("OAP: " + oap.getText());
System.out.println("Total Price: " + totalprice.getText());
System.out.println("Thank you. Enjoy your film.");
System.out.println(" ");
coupon.clear();
child.setText("0");
adult.setText("0");
oap.setText("0");
}
}
// Main Class
public static void main(String[] args) {
new cinemaSystem(); //makes new ButtonGrid with 2 parameters
}
}
Related: Java: Disable all JToggleButtons after Submission — setEnabled(false);
If you already have it working for one booking time, all you need to do is take all your data structures used for storing information about that booking time and double them up to support several independent booking times.
For instance, ArrayList<String> seatsAvailable = new ArrayList<String>(); will become:
Dictionary<Time, ArrayList<String> > seatsAvailable =
new Dictionary<Time, ArrayList<String> >();
Time firstBooking = new Time(13,0,0);
Time secondBooking = new Time(15,0,0);
seatsAvailable.put( firstBooking , new ArrayList<String>() );
seatsAvailable.put( secondBooking , new ArrayList<String>() );
Now you can keep track of two completely seperate ArrayLists of seatsAvailable.