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?
Related
As a beginner in Java, I'm working on a project of Space Invaders. Looking to add more levels.
private void LevelInit() {
aliens = new ArrayList<>();
int currentLevel = 1;
if (currentLevel == 1) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
var alien = new Alien(Constants.ALIEN_INIT_X + 18 * j, Constants.ALIEN_INIT_Y + 18 * i);
aliens.add(alien);
//System.out.println(currentLevel);
}
}
}
else if (currentLevel == 2) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
var alien = new Alien(Constants.ALIEN_INIT_X + 18 * j, Constants.ALIEN_INIT_Y + 18 * i);
aliens.add(alien);
// System.out.println(currentLevel);
}
}
}
else if (currentLevel == 3) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 6; j++) {
var alien = new Alien(Constants.ALIEN_INIT_X + 18 * j, Constants.ALIEN_INIT_Y + 18 * i);
aliens.add(alien);
//System.out.println(currentLevel);
}
}
}
player = new Player();
bullet = new Bullet();
}
This function is the logic behind the code that initializes the game and gets called by the constructor. The simple way of adding levels is adding more Aliens.
This is how it looks after being updated from yesterday, levels are being added but the arraylists are being stuck together. Like the 12 - 16 - 24 aliens are together printed, some spaceships take 1 hit some 2 and some 3 and when they are all destroyed system give message of You passed level 1 and 2 and 3 together which is confusing me why are they bound together like that and not being passed.
And I can't figure it out. Also,
private void update() {
if (deaths == 12) {
inGame = false;
timer.stop();
message = "Next Level!";
}
// player
player.act();
// shot
if (bullet.isVisible()) {
int shotX = bullet.getX();
int shotY = bullet.getY();
for (Alien alien : aliens) {
int alienX = alien.getX();
int alienY = alien.getY();
if (alien.isVisible() && bullet.isVisible()) {
if (shotX >= (alienX)
&& shotX <= (alienX + Constants.ALIEN_WIDTH)
&& shotY >= (alienY)
&& shotY <= (alienY + Constants.ALIEN_HEIGHT)) {
var ii = new ImageIcon(explImg);
alien.setImage(ii.getImage());
alien.setDying(true);
deaths++;
bullet.die();
}
}
}
int y = bullet.getY();
y -= 4;
if (y < 0) {
bullet.die();
} else {
bullet.setY(y);
}
}
// aliens
for (Alien alien : aliens) {
int x = alien.getX();
if (x >= Constants.BOARD_WIDTH - Constants.BORDER_RIGHT && direction != -1) {
direction = -1;
for(Alien a2 : aliens) {
a2.setY(a2.getY() + Constants.GO_DOWN);
}
}
if (x <= Constants.BORDER_LEFT && direction != 1) {
direction = 1;
for(Alien a : aliens) {
a.setY(a.getY() + Constants.GO_DOWN);
}
}
}
for(Alien alien : aliens) {
if (alien.isVisible()) {
int y = alien.getY();
if (y > Constants.GROUND - Constants.ALIEN_HEIGHT) {
inGame = false;
message = "Invasion!";
}
alien.act(direction);
}
}
// bombs
var generator = new Random();
for (Alien alien : aliens) {
int shot = generator.nextInt(15);
Alien.Bomb bomb = alien.getBomb();
if (shot == Constants.CHANCE && alien.isVisible() && bomb.isDestroyed()) {
bomb.setDestroyed(false);
bomb.setX(alien.getX());
bomb.setY(alien.getY());
}
int bombX = bomb.getX();
int bombY = bomb.getY();
int playerX = player.getX();
int playerY = player.getY();
if (player.isVisible() && !bomb.isDestroyed()) {
if (bombX >= (playerX)
&& bombX <= (playerX + Constants.PLAYER_WIDTH)
&& bombY >= (playerY)
&& bombY <= (playerY + Constants.PLAYER_HEIGHT)) {
var ii = new ImageIcon(explImg);
player.setImage(ii.getImage());
player.setDying(true);
bomb.setDestroyed(true);
}
}
if (!bomb.isDestroyed()) {
bomb.setY(bomb.getY() + 1);
if (bomb.getY() >= Constants.GROUND - Constants.BOMB_HEIGHT) {
bomb.setDestroyed(true);
}
}
}
}
This function is to update the game whenever anything happens. The code is made from a bunch of YouTube videos and GitHubs, so excuse the copying if you see any.
I need to create new levels by simply adding more aliens, tried using a for loop but that resulted in either the aliens move faster or the bullet doesn't destroy an alien, it just hits.
Board class:
public class Board extends JPanel {
private Dimension d;
private List<Alien> aliens;
private Player player;
private Bullet bullet;
private int level;
private int direction = -1;
private int deaths = 0;
private boolean inGame = true;
private String explImg = "src/images/explosion.png";
private String message = "Game Over";
private Timer timer;
public Board() {
initBoard();
gameInit();
LevelInit();
}
private void initBoard() {
addKeyListener(new TAdapter());
setFocusable(true);
d = new Dimension(Constants.BOARD_WIDTH, Constants.BOARD_HEIGHT);
setBackground(Color.black);
timer = new Timer(Constants.DELAY, new GameCycle());
timer.start();
gameInit();
}
private void gameInit() {
aliens = new ArrayList<>();
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
var alien = new Alien(Constants.ALIEN_INIT_X + 18 * j,
Constants.ALIEN_INIT_Y + 18 * i);
aliens.add(alien);
}
}
player = new Player();
bullet = new Bullet();
}
private void LevelInit() {
inGame = true;
timer.start();
int level = 1;
if (aliens.isEmpty()) {
level++;
int AlienCount;if(level == 2) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 6; j++) {
var alien = new Alien(Constants.ALIEN_INIT_X + 18 * j, Constants.ALIEN_INIT_Y + 18 * i);
aliens.add(alien);
}
}
} else if (level == 3) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 6; j++) {
var alien = new Alien(Constants.ALIEN_INIT_X + 18 * j, Constants.ALIEN_INIT_Y + 18 * i);
aliens.add(alien);
}
}
}
}
player = new Player();
bullet = new Bullet();
}
private void drawAliens(Graphics g) {
for (Alien alien : aliens) {
if (alien.isVisible()) {
g.drawImage(alien.getImage(), alien.getX(), alien.getY(), this);
}
if (alien.isDying()) {
alien.die();
}
}
}
private void drawPlayer(Graphics g) {
if (player.isVisible()) {
g.drawImage(player.getImage(), player.getX(), player.getY(), this);
}
if (player.isDying()) {
player.die();
inGame = false;
}
}
private void drawShot(Graphics g) {
if (bullet.isVisible()) {
g.drawImage(bullet.getImage(), bullet.getX(), bullet.getY(), this);
}
}
private void drawBombing(Graphics g) {
for (Alien a : aliens) {
Alien.Bomb b = a.getBomb();
if (!b.isDestroyed()) {
g.drawImage(b.getImage(), b.getX(), b.getY(), this);
}
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
doDrawing(g);
}
private void doDrawing(Graphics g) {
g.setColor(Color.black);
g.fillRect(0, 0, d.width, d.height);
g.setColor(Color.green);
if (inGame) {
g.drawLine(0, Constants.GROUND,
Constants.BOARD_WIDTH, Constants.GROUND);
drawAliens(g);
drawPlayer(g);
drawShot(g);
drawBombing(g);
} else {
if (timer.isRunning()) {
timer.stop();
}
gameOver(g);
}
Toolkit.getDefaultToolkit().sync();
}
private void gameOver(Graphics g) {
g.setColor(Color.black);
g.fillRect(0, 0, Constants.BOARD_WIDTH, Constants.BOARD_HEIGHT);
g.setColor(new Color(0, 32, 48));
g.fillRect(50, Constants.BOARD_WIDTH / 2 - 30, Constants.BOARD_WIDTH - 100, 50);
g.setColor(Color.white);
g.drawRect(50, Constants.BOARD_WIDTH / 2 - 30, Constants.BOARD_WIDTH - 100, 50);
var small = new Font("Helvetica", Font.BOLD, 14);
var fontMetrics = this.getFontMetrics(small);
g.setColor(Color.white);
g.setFont(small);
g.drawString(message, (Constants.BOARD_WIDTH - fontMetrics.stringWidth(message)) / 2,
Constants.BOARD_WIDTH / 2);
}
private void update() {
if (deaths == aliens.size()) {
inGame = false;
timer.stop();
message = "Next Level!";
}
// player
player.act();
// shot
if (bullet.isVisible()) {
int shotX = bullet.getX();
int shotY = bullet.getY();
for (Alien alien : aliens) {
int alienX = alien.getX();
int alienY = alien.getY();
if (alien.isVisible() && bullet.isVisible()) {
if (shotX >= (alienX)
&& shotX <= (alienX + Constants.ALIEN_WIDTH)
&& shotY >= (alienY)
&& shotY <= (alienY + Constants.ALIEN_HEIGHT)) {
var ii = new ImageIcon(explImg);
alien.setImage(ii.getImage());
alien.setDying(true);
deaths++;
bullet.die();
}
}
}
int y = bullet.getY();
y -= 4;
if (y < 0) {
bullet.die();
} else {
bullet.setY(y);
}
}
// aliens
for (Alien alien : aliens) {
int x = alien.getX();
if (x >= Constants.BOARD_WIDTH - Constants.BORDER_RIGHT && direction != -1) {
direction = -1;
Iterator<Alien> i1 = aliens.iterator();
while (i1.hasNext()) {
Alien a2 = i1.next();
a2.setY(a2.getY() + Constants.GO_DOWN);
}
}
if (x <= Constants.BORDER_LEFT && direction != 1) {
direction = 1;
Iterator<Alien> i2 = aliens.iterator();
while (i2.hasNext()) {
Alien a = i2.next();
a.setY(a.getY() + Constants.GO_DOWN);
}
}
}
Iterator<Alien> it = aliens.iterator();
while (it.hasNext()) {
Alien alien = it.next();
if (alien.isVisible()) {
int y = alien.getY();
if (y > Constants.GROUND - Constants.ALIEN_HEIGHT) {
inGame = false;
message = "Invasion!";
}
alien.act(direction);
}
}
// bombs
var generator = new Random();
for (Alien alien : aliens) {
int shot = generator.nextInt(15);
Alien.Bomb bomb = alien.getBomb();
if (shot == Constants.CHANCE && alien.isVisible() && bomb.isDestroyed()) {
bomb.setDestroyed(false);
bomb.setX(alien.getX());
bomb.setY(alien.getY());
}
int bombX = bomb.getX();
int bombY = bomb.getY();
int playerX = player.getX();
int playerY = player.getY();
if (player.isVisible() && !bomb.isDestroyed()) {
if (bombX >= (playerX)
&& bombX <= (playerX + Constants.PLAYER_WIDTH)
&& bombY >= (playerY)
&& bombY <= (playerY + Constants.PLAYER_HEIGHT)) {
var ii = new ImageIcon(explImg);
player.setImage(ii.getImage());
player.setDying(true);
bomb.setDestroyed(true);
}
}
if (!bomb.isDestroyed()) {
bomb.setY(bomb.getY() + 1);
if (bomb.getY() >= Constants.GROUND - Constants.BOMB_HEIGHT) {
bomb.setDestroyed(true);
}
}
}
}
private void doGameCycle() {
update();
repaint();
}
private class GameCycle implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
doGameCycle();
}
}
private class TAdapter extends KeyAdapter {
#Override
public void keyReleased(KeyEvent e) {
player.keyReleased(e);
}
#Override
public void keyPressed(KeyEvent e) {
player.keyPressed(e);
int x = player.getX();
int y = player.getY();
int key = e.getKeyCode();
if (key == KeyEvent.VK_SPACE) {
if (inGame) {
if (!bullet.isVisible()) {
bullet = new Bullet(x, y);
}
}
}
}
}
}
As #JoachimSauer mentioned, your code needs refactoring. Here is one possible solution to your problem.
Additions
You will need two extra variables and one extra method.
Variables
1: int currentLevel - keeps track of the current level
2: boolean isLevelOver - keeps track if the current level is still active or not
Method
private void levelInit(int currentlevel)
{
aliens = new ArrayList<>();
int alienCount = //calculate alien count depending upon the current level
//Add aliens to aliens ArrayList
player = new Player();
bullet = new Bullet();
}
You have to provide implementation of how alienCount will be calculated depending upon currentLevel. The nested loop you used earlier to add aliens to aliens will also change. You have to make the loop dependent upon currentLevel.
Changes
Few of your methods will require some change.
public Board()
{
initBoard();
}
private void initBoard()
{
addKeyListener(new TAdapter());
setFocusable(true);
d = new Dimension(Constants.BOARD_WIDTH, Constants.BOARD_HEIGHT);
setBackground(Color.black);
levelInit(currentLevel);
timer = new Timer(Constants.DELAY, new GameCycle());
timer.start();
}
private void update()
{
if (deaths == aliens.size())
{
isLevelOver = true;
currentLevel++;
message = "Next Level!";
return;
}
...
}
private void doGameCycle()
{
if (isLevelOver)
{
levelInit(currentLevel);
isLevelOver = false;
}
update();
repaint();
}
Notes
This is one of the possible ways to achieve what you want. There
might be other ways, probably better, but this is what I came up
with.
I tried to find as many additions and updation required in your code. However, I do not know its structure, you do. So there might be more additions or changes required.
I noticed you are were calling gameInit() in initBoard() and then again in Board() constructor. I think that might be unnecessary, please look into it.
You made one call to timer.stop() after setting isGame = false. This again might be unnecessary since you are already doing so inside doDrawing(...). Please also check that.
You should probably set a limit to either the levelCount() or max alien that can be on the screen since if you just keep on adding more aliens in each new level, they might fill up the entire screen.
I have provided many hints which should help you in your problem. If you still face any more problems or someone finds anything wrong with the answer, please comment.
Here is my code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ChessBoardGUI extends JFrame {
private Container contents;
private JButton[][] squares = new JButton[8][8];
private Color colorBlack = Color.BLACK;
private int row = 7;
private int col = 1;
private ImageIcon knight = new ImageIcon("knight.jpg");
public ChessBoardGUI() {
super("GUI GridLayout Manager - (click a valid square to move knight)");
contents = getContentPane();
contents.setLayout(new GridLayout(8,8));
ButtonHandler buttonHandler = new ButtonHandler();
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
squares[i][j] = new JButton();
if ((i + j) % 2 != 0) {
squares[i][j].setBackground(colorBlack);
}
contents.add(squares[i][j]);
squares[i][j].addActionListener(buttonHandler);
}
}
squares[row][col].setIcon(knight);
setSize(500, 500);
setResizable(false);
setLocationRelativeTo(null);
setVisible(true);
}
private boolean isValidMove(int i, int j) {
int rowDelta = Math.abs(i - row);
int colDelta = Math.abs(j - col);
if ((rowDelta == 1) && (colDelta == 2)) {
return true;
}
if ((colDelta == 1) && (rowDelta == 2)) {
return true;
}
return false;
}
private void processClick(int i, int j) {
if (isValidMove(i, j) == false) {
return;
}
squares[row][col].setIcon(null);
squares[i][j].setIcon(knight);
row = i;
col = j;
}
private class ButtonHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
if (source == squares[i][j]) {
processClick(i, j);
return;
}
}
}
}
}
public static void main(String args[]) {
ChessBoardGUI gui = new ChessBoardGUI();
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
I have a program that creates a chess board GUI, but when I runs my code, the buttons are all white instead of black and white buttons (Just like chess board). Could anyone please tell me where am I doing wrong? Any help is appreciated!
When I runs my program, all I see is a window with white buttons, but there is no black color button.
In my code I added the setOpaque() method but the black color was only at border, so I added this line of code:
squares[i][j].setBorder(null);
Here is the code:
if ((i + j) % 2 != 0) {
squares[i][j].setBackground(colorBlack);
squares[i][j].setBorder(null);
squares[i][j].setOpaque(true);
}
I'm writing a code which generates a random maze, every time i run the program it looks diffrent, but i cant get my reset button working. Here is some of my code:
public class MakeFrame extends JPanel implements ActionListener {
JFrame frame;
JPanel buttonPanel;
JButton solve1;
JButton solve2;
JButton solve3;
JButton clear;
JButton reset;
Maze maze = new Maze();
void buildframe() {
frame = new JFrame("maze"); //makes a frame, names it maze
frame.add(this, BorderLayout.CENTER);
frame.add(maze);
buttonPanel = new JPanel();
frame.add(buttonPanel, BorderLayout.NORTH);
solve1 = new JButton("solve 1"); // create some buttons
solve2 = new JButton("solve 2");
solve3 = new JButton("solve 3");
clear = new JButton("clear");
reset = new JButton("reset");
buttonPanel.add(solve1); // add the buttons to a panel
buttonPanel.add(solve2);
buttonPanel.add(solve3);
buttonPanel.add(clear);
buttonPanel.add(reset);
solve1.addActionListener(this);// assigns action listeners to buttons
solve2.addActionListener(this);
solve3.addActionListener(this);
clear.addActionListener(this);
reset.addActionListener(this);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // makes the frame visable, grey and close on exit.
frame.setSize(455, 320);
frame.setVisible(true);
setBackground(Color.GRAY);
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == reset) {
frame.add(new Maze());
repaint();
}
}
}
I don't know what to put in the action performed method to make it work, can anybody help me?
here is my class maze:
public class Maze extends JPanel {
Cell[][] cells = new Cell[22][12];
String[][] route = new String[22][12];
Random random = new Random();
Maze() {
othersetroute();
createFloor();
createWalls();
setStartEnd();
}
void othersetroute() {
int x = 1;
int y = 1;
int downorright;
for (int i = 0; i < 50; i++) {
downorright = random.nextInt(3);
if (x == 20 && y == 10) {
break;
}
if (x > 20 || y > 10) {
break;
}
if (y == 10 || downorright == 0 || downorright == 1) {
x++;
} else {
y++;
}
route[x][y] = "floor";
}
for (int a = 0; a < 22; a++) {
for (int b = 0; b < 12; b++) {
if (route[a][b] == null) {
int floororwall;
floororwall = random.nextInt(4);
if (floororwall == 0 || floororwall == 1) {
route[a][b] = "walls";
} else {
route[a][b] = "floor";
}
if (a % 2 == 1 && b % 2 == 1) {
route[a][b] = "floor";
}
if (a % 2 == 0 && b % 2 == 0) {
route[a][b] = "walls";
}
}
}
}
}
void setRoute() {
int x = 1;
int y = 1;
int leftcounter = 0;
int rightcounter = 0;
int upcounter = 0;
int downcounter = 0;
for (int i = 0; i < 150; i++) {
String direction;
if (x > 20 || y > 10) {
break;
} else if (x == 20 && y == 10) {
break;
} else if (downcounter == 14 && upcounter == 5 && leftcounter == 10 && rightcounter == 29) {
break;
} else if (x == 20) {
int k = random.nextInt(3);
if (k == 0) {
direction = "left";
} else if (k == 1) {
direction = "up";
} else {
direction = "down";
}
} else if (y == 10) {
int k = random.nextInt(3);
if (k == 0) {
direction = "left";
} else if (k == 1) {
direction = "up";
} else {
direction = "right";
}
} else if (x == 1 || y == 1) {
int k = random.nextInt(3);
if (k == 0) {
direction = "down";
} else {
direction = "right";
}
} else {
int k = random.nextInt(4);
if (k == 0) {
direction = "left";
} else if (k == 1) {
direction = "up";
} else if (k == 2) {
direction = "right";
} else {
direction = "down";
}
}
if (direction.equals("right") && rightcounter < 30) {
x++;
rightcounter++;
} else if (direction.equals("down") && downcounter < 15) {
y++;
downcounter++;
} else if (direction.equals("left") && leftcounter < 11) {
x = x - 1;
leftcounter++;
} else if (direction.equals("up") && upcounter < 6) {
y = y - 1;
upcounter++;
}
System.out.println(x);
System.out.println(y);
route[x][y] = "floor";
}
for (int a = 0; a < 22; a++) {
for (int b = 0; b < 12; b++) {
if (route[a][b] == null) {
int floororwall;
floororwall = random.nextInt(4);
if (floororwall == 0 || floororwall == 1) {
route[a][b] = "walls";
} else {
route[a][b] = "floor";
}
if (a % 2 == 1 && b % 2 == 1) {
route[a][b] = "floor";
}
if (a % 2 == 0 && b % 2 == 0) {
route[a][b] = "walls";
}
}
}
}
}
void createFloor() {
for (int x = 0; x < 22; x++) {
for (int y = 0; y < 12; y++) {
if (route[x][y].equals("walls")) {
cells[x][y] = new Cell("walls");
}
if (route[x][y].equals("floor")) {
cells[x][y] = new Cell("floor");
}
}
}
}
void createWalls() {
for (int i = 0; i < 12; i++) {
cells[0][i] = new Cell("walls");
cells[21][i] = new Cell("walls");
}
for (int i = 0; i < 22; i++) {
cells[i][0] = new Cell("walls");
cells[i][11] = new Cell("walls");
}
for (int x = 0; x < 22; x++) {
for (int y = 0; y < 12; y++) {
if (cells[x][y] == null) {
cells[x][y] = new Cell("walls");
}
}
}
}
void setStartEnd() {
cells[1][1] = new Cell("start");
cells[20][10] = new Cell("end");
}
#Override
public void paintComponent(Graphics g) {
for (int x = 0; x < 22; x++) {
for (int y = 0; y < 12; y++) {
if (cells[x][y].getType().equals("#")) {
g.setColor(Color.GREEN);
g.fillRect(x * 20, y * 20, x * 20 + 20, y * 20 + 20);
}
if (cells[x][y].getType().equals(" ")) {
g.setColor(Color.WHITE);
g.fillRect(x * 20, y * 20, x * 20 + 20, y * 20 + 20);
}
if (cells[x][y].getType().equals("S") || cells[x][y].getType().equals("E")) {
g.setColor(Color.PINK);
g.fillRect(x * 20, y * 20, x * 20 + 20, y * 20 + 20);
}
}
}
}
void solutionOne(){ // least visited
int visits[][]= new int [20][10];
for (int i = 0; i<21; i++){
for (int j = 0; j<10; j++){
visits[i][j]=0;
}
}
for (int i = 0; i<100; i++){
}
}
}
and here is my class cell :p
public class Cell {
private String cell;
Cell(String type){
if (type.equals("walls")){
walls();
}
if (type.equals("floor")){
Floor();
}
if (type.equals("start")){
start();
}
if(type.equals("end")){
end();
}
}
void walls(){
cell = "#";
}
void start(){
cell = "S";
}
void end(){
cell = "E";
}
void Floor(){
cell = " ";
}
public String getType(){
return cell;
}
}
You had too much of this
MakeFrame extends JPanel
Which would make another JPanel but I could not find any main methods that ran the whole code, so here you go, enjoy xD
MakeFrame.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class MakeFrame extends JFrame implements ActionListener{
JPanel buttonPanel;
JButton solve1;
JButton solve2;
JButton solve3;
JButton clear;
JButton reset;
Maze maze;
public MakeFrame(){
super("Maze");
init();
}
public void init() {
//makes a frame, names it maze
maze = new Maze();
super.getContentPane().add(maze, BorderLayout.CENTER);
buttonPanel = new JPanel();
super.getContentPane().add(buttonPanel, BorderLayout.NORTH);
solve1 = new JButton("solve 1"); // create some buttons
solve2 = new JButton("solve 2");
solve3 = new JButton("solve 3");
clear = new JButton("clear");
reset = new JButton("reset");
buttonPanel.add(solve1); // add the buttons to a panel
buttonPanel.add(solve2);
buttonPanel.add(solve3);
buttonPanel.add(clear);
buttonPanel.add(reset);
solve1.addActionListener(this);// assigns action listeners to buttons
solve2.addActionListener(this);
solve3.addActionListener(this);
clear.addActionListener(this);
reset.addActionListener(this);
super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// makes the frame visable, grey and close on exit.
super.setSize(455, 320);
super.setVisible(true);
super.setBackground(Color.GRAY);
}
public void repaint(){
init();
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == reset) {
super.getContentPane().removeAll();
repaint();
}
}
}
TestMaze.java
public class TestMaze {
public static void main(String [] args){
new MakeFrame();
}
}
private void b2ActionPerformed(java.awt.event.ActionEvent evt) {
jTextField.getText(");
}
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
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.