Win check not working in TicTacToe game? - java

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
class Tix extends JFrame {
private static final int WIDTH = 500;
private static final int HEIGHT = 500;
private boolean xTurn = true;
private Font style;
private static JButton[][] btns = new JButton[3][3];
public Tix() {
setTitle("Tix");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(WIDTH, HEIGHT);
createContents();
setVisible(true);
}
public void createContents() {
style = new Font("Comic Sans", 1, 100);
Listener listener = new Listener();
setLayout(new GridLayout(3,3));
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
btns[i][j] = new JButton();
btns[i][j].setFont(style);
btns[i][j].addActionListener(listener);
add(btns[i][j]);
}
}
}
private class Listener implements ActionListener {
public void actionPerformed(ActionEvent e) {
JButton btn = (JButton) e.getSource();
if (xTurn)
btn.setForeground(Color.RED);
else
btn.setForeground(Color.BLUE);
if (btn.getText().isEmpty()) {
btn.setText(xTurn ? "X" : "O");
if (win()) {
JOptionPane.showMessageDialog(null, "Congratulations! Player " + (xTurn ? "X" : "O") + " wins!");
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
btns[i][j].setText(null);
}
}
xTurn = true;
}
else {
xTurn = !xTurn;
}
}
else {
JOptionPane.showMessageDialog(null,"Cell already clicked!");
}
}
}
public static boolean win() {
for (int i = 0; i < 3; i++)
if (btns[i][0].equals("X") && btns[i][1].equals("X") && btns[i][2].equals("X"))
return true;
for (int j = 0; j < 3; j++)
if (btns[0][j].equals("X") && btns[1][j].equals("X") && btns[2][j].equals("X"))
return true;
if (btns[0][0].equals("X") && btns[1][1].equals("X") && btns[2][2].equals("X"))
return true;
if (btns[0][2].equals("X") && btns[1][1].equals("X") && btns[2][0].equals("X"))
return true;
return false;
}
public static void main(String[] args) {
new Tix();
}
}
A for loop to check for the rows.
A for loop to check for the columns.
Two if statements to check for diagonals.
The win method does not return true at all. Is there something wrong with the && operators?

btns[i][j] is a JButton so it will never be equal to a String.
You should replace each method call of the form btns[i][0].equals("X") with something like btns[i][0].getText().equals("X").
Beside that, your win method only checks if the "X" player won. What about the "O" player?

Related

Jbutton Is Disappearing Even Though I call .setVisible(true)

I am making a basic platformer game and I need to make it so that every time you jump all the platforms that are below where you jumped disappear and every platform above moves down. It is still in development so just ignore some of the things that are commented out and the messy mode.
Basically, my problem is that when I try to clear all the platforms below the one that you clicked it works fine using this code:
for(int i = 0; i < platforms.length; i++) {
if(platforms[i] == null) {
continue;
}
if(parameters[i][1] > y) {
platforms[i].setVisible(false);
}
}
However later when I try to use .setvisible(true) on the platform that you clicked it doesn't work. Here is the full code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.math.*;
import java.util.*;
public class Main implements ActionListener {
static JFrame frame;
static JPanel panel;
//static JLabel title;
//static JLabel expl;
static JButton[] platforms;
static Random random;
static boolean playing;
static int[][] parameters;
static int platformsMade;
static int clicked;
static int preClicked;
static int score;
static int lives;
static int standing;
static int speed;
static double gravity;
static int jump;
static String action;
public Main(int seed) throws Exception {
frame = new JFrame("Snakes 'n' Adders");
panel = new JPanel(null);
//title = new JLabel("Snakes 'n' Adders", SwingConstants.CENTER);
//expl = new JLabel("");
platforms = new JButton[100000];
random = new Random();
parameters = new int[100000][5];
lives = 3;
speed = 10;
gravity = 9.81;
jump = 5;
action = "";
//panel.add(title);
//panel.add(expl);
frame.add(panel);
panel.setVisible(true);
frame.setVisible(true);
frame.setSize(500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
random.setSeed(seed);
panel.setBackground(Color.CYAN);
//title.setFont(new Font("Arial", Font.PLAIN, 50));
}
public void drawPlatform(int x, int y, int w, int h, int colour) {
platforms[platformsMade] = new JButton();
platforms[platformsMade].addActionListener(this);
platforms[platformsMade].setBounds(x, y, w, h);
switch(colour) {
case 0:
platforms[platformsMade].setBackground(Color.BLUE);
break;
case 1:
platforms[platformsMade].setBackground(Color.GREEN);
break;
case 2:
platforms[platformsMade].setBackground(Color.RED);
break;
case 3:
platforms[platformsMade].setBackground(Color.ORANGE);
break;
case 4:
platforms[platformsMade].setBackground(Color.GRAY);
break;
}
parameters[platformsMade][0] = x;
parameters[platformsMade][1] = y;
parameters[platformsMade][2] = w;
parameters[platformsMade][3] = h;
parameters[platformsMade][4] = colour;
panel.add(platforms[platformsMade]);
platforms[platformsMade].setVisible(true);
panel.repaint();
platformsMade++;
}
public void movePlatforms(int distance, int i) {
if(platforms[i] == null) {
NullPointerException end = new NullPointerException();
throw end;
}
//this.drawPlatform(parameters[i][0], parameters[i][1] + distance, parameters[i][2], parameters[i][3], parameters[i][4]);
//platforms[i].setVisible(false);
platforms[i].setBounds(parameters[i][0], parameters[i][1] + distance, parameters[i][2], parameters[i][3]);
parameters[i][1] = parameters[i][1] + distance;
}
#Override
public void actionPerformed(ActionEvent event) {
preClicked = clicked;
for(int i = 0; i < platforms.length; i++) {
if(event.getSource() == platforms[i]) {
clicked = i;
break;
}
}
int y = parameters[clicked][1];
for(int i = 0; i < platforms.length; i++) {
if(platforms[i] == null) {
continue;
}
if(parameters[i][1] > y) {
platforms[i].setVisible(false);
}
else {
this.movePlatforms(150, i);
}
this.movePlatforms(150, clicked);
}
for(int i = 0; i <= random.nextInt(2); i++) {
this.drawPlatform(random.nextInt(500), random.nextInt(500), 50, 50, random.nextInt(4));
}
/*for(int i = 0; i < platforms.length; i++) {
if(platforms[i] == null) {
continue;
}
if(platforms[i].getY() > frame.getY() - platforms[i].getHeight()) {
platforms[i].setVisible(false);
}
}*/
platforms[clicked].addActionListener(this);
platforms[clicked].setVisible(true);
standing = clicked;
for(int i = 0; i < platforms.length; i++) {
if(platforms[i] == null) {
continue;
}
if(clicked == i) {
platforms[i].setText("|");
}
else {
platforms[i].setText("");
}
}
}
public static void main(String[] args) throws Exception {
Main sna = new Main(7845);
//title.setVisible(true);
//expl.setVisible(false);
//Thread.sleep(5000);
//title.setVisible(false);
//expl.setVisible(true);
//Thread.sleep(40000);
for(int i = 0; i < 3; i++) {
sna.drawPlatform(random.nextInt(500), random.nextInt(500), 50, 50, random.nextInt(4));
}
int ticks = 0;
platforms[standing].setText("|");
}
}

The Tic Tac Toe game does not show the winner at the right time

my code is tic tac toe and i have problem with show winner.
i get winner but not when X or O in correct direction.
and show winner after click on button.
code :
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.border.EtchedBorder;
public class TicTocToe extends JFrame implements ActionListener {
private static final long serialVersionUID = -7730552764304282715L;
private static final Font BT_FONT = new Font("Segoe UI", 0, 30);
private static final Font LB_FONT = new Font("Consolas", 0, 20);
private JButton[][] board;
private JLabel statusBar;
private JPanel centerPanel, southPanel;
private int turn = 0, count = 0;
private String name;
public static void main(String[] args) {
EventQueue.invokeLater(() -> new TicTocToe().setVisible(true));
}
public TicTocToe() {
super("Tic Toc Toe");
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
initUI();
} catch (Exception e) {
e.printStackTrace();
}
}
private void initUI() {
initCenterPanel();
initSouthPanel();
add(centerPanel);
add(southPanel, BorderLayout.SOUTH);
pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setLocationRelativeTo(null);
}
private void initCenterPanel() {
centerPanel = new JPanel();
board = new JButton[3][3];
for (int i = 0; i < board[0].length; i++) {
for (int j = 0; j < board[i].length; j++) {
board[i][j] = new JButton("-");
board[i][j].setFont(BT_FONT);
board[i][j].setFocusPainted(false);
board[i][j].setPreferredSize(new Dimension(80, 80));
board[i][j].addActionListener(this);
centerPanel.add(board[i][j]);
}
}
}
private void initSouthPanel() {
southPanel = new JPanel();
southPanel.setLayout(new BorderLayout());
statusBar = new JLabel();
statusBar.setFont(LB_FONT);
statusBar.setText("Click On Button To Start");
statusBar.setHorizontalAlignment(JLabel.CENTER);
statusBar.setBorder(new EtchedBorder());
southPanel.add(statusBar);
}
private void play(JButton button) {
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[i].length; j++) {
if (button.equals(board[i][j])) {
count++;
if (turn < 1) {
statusBar.setText("Player " + "O" + " Turn");
button.setText("X");
button.setEnabled(false);
turn++;
} else {
statusBar.setText("Player " + "X" + " Turn");
button.setText("O");
button.setEnabled(false);
turn--;
}
}
}
}
}
private String getPlayerName() {
return (turn < 1) ? "X" : "O";
}
private boolean findWinner() {
name = getPlayerName();
for (int i = 0; i < board.length; i++) {
if (board[i][0].getText().equals(name) && board[i][1].getText().equals(name)
&& board[i][2].getText().equals(name))
return true;
for (int j = 0; j < board[i].length; j++) {
if (board[0][j].getText().equals(name) && board[1][j].getText().equals(name)
&& board[2][j].getText().equals(name))
return true;
if (board[0][0].getText().equals(name) && board[1][1].getText().equals(name)
&& board[2][2].getText().equals(name))
return true;
if (board[0][2].getText().equals(name) && board[1][1].getText().equals(name)
&& board[2][0].getText().equals(name))
return true;
}
}
return false;
}
private void showWinner() {
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board.length; j++) {
if (findWinner()) {
if (getPlayerName().equalsIgnoreCase("x")) {
statusBar.setText("Winner is Player X");
board[i][j].removeActionListener(this);
}
else if (getPlayerName().equalsIgnoreCase("o")) {
statusBar.setText("Winner is Player O");
board[i][j].removeActionListener(this);
}
} else if (!findWinner() && count == 9) {
statusBar.setText("It was a draw, no wone.");
board[i][j].removeActionListener(this);
}
}
}
}
public void actionPerformed(ActionEvent event) {
JButton button = (JButton) event.getSource();
play(button);
showWinner();
}
public Dimension getPreferredSize() {
return new Dimension(300, 320);
}
public Dimension getMinimumSize() {
return getPreferredSize();
}
}
in this image Winner is X but wait for Player O
and after click on other button show Winner.
i need show winner when X or O in correct Direction
and no wait for click on other button
I think I see it.
When a button is pressed, you do stuff in this order:
change the status bar to say it's the next player's turn
set the relevant button text to show the player who just picked that button
disable the button
change the turn value to reflect the next player
check for a winner, based on the current player's name but you have already changed this to the next player, not the player who just made the move.
When X makes a winning move, the current player name is changed to O before the game checks for a winner, so it checks to see if O has won. You need to reorder stuff:
change the button text
disable the button
check for a winner based on the current player name, end the game if the current player has won or if there is a draw
if the game is still going, now is the time to change the turn value and update the status bar to show that it's the next player's turn.

Problems with repaint() method in java

I'm new to Java and trying to make a simple Player vs. Computer "Tic-Tac-Toe" game using Swing. In the code I use paintComponent() method to paint certain components and call the repaint() method after the player or computer plays. The problem is that, the game freezes after the third (sometimes the second) time I click the mouse. In GameWindow class I create the instance of Map class.
public class GameWindow extends JFrame{
private final int sizeX = 3;
private final int sizeY = 3;
public GameWindow(){
setLocation(400,150);
setSize(406, 452);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setResizable(false);
Map map = new Map(sizeX, sizeY);
add(map, BorderLayout.CENTER);
JPanel bottomPanel = new JPanel();
bottomPanel.setLayout(new GridLayout(1, 2));
add(bottomPanel, BorderLayout.SOUTH);
Button newGame = new Button("Новая игра");
newGame.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Начинаем новую игру");
}
});
Button exit = new Button("Выход");
exit.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
bottomPanel.add(newGame);
bottomPanel.add(exit);
setVisible(true);
}
}
Here is the listener for the mouse click in the Map class:
public class Map extends JPanel {
private final int sizeX;
private final int sizeY;
private int cellWidth;
private int cellHeight;
private int cellX = -1;
private int cellY = -1;
private String lastPlayer = "nobody";
private String[][] table = new String[3][3];
public Map(int sizeX, int sizeY) {
this.sizeX = sizeX;
this.sizeY = sizeY;
setBackground(Color.WHITE);
for (int i = 0; i < table.length; i++) {
for (int j = 0; j < table.length; j++) {
table[i][j] = "empty";
}
}
addMouseListener(new MouseAdapter() {
#Override
public void mouseReleased(MouseEvent e) {
super.mouseReleased(e);
cellX = e.getX() / cellWidth;
cellY = e.getY() / cellHeight;
if (!winOrDraw()) {
boolean playerProgress = playerProgress();
if(playerProgress) {
botProgress();
}
}
}
});
}
Both in playerProgress() and botProgress() methods I call repaint() method to add new components to the screen. I can't really find out what is the problem in this code and why the program freezes after actually 6th call of repaint() method?
Here are winOrDraw(), playerProgress() and botProgress() methods:
private boolean winOrDraw(){
for (int i = 0; i < table.length; i++) {
if(table[i][0] == table[i][1] && table[i][1] == table[i][2] && !table[i][0].equals("empty")) return true;
else if(table[0][i] == table[1][i] && table[1][i] == table[2][i] && !table[0][i].equals("empty")) return true;
else if(table[0][0] == table[1][1] && table[1][1] == table[2][2] && !table[0][0].equals("empty")) return true;
else if(table[2][0] == table[1][1] && table[1][1] == table[0][2] && !table[2][0].equals("empty")) return true;
}
int i, j = 0;
for (i = 0; i < table.length; i++) {
for (j = 0; j < table.length; j++) {
if(table[i][j].equals("empty")) break;
}
}
if(i == table.length && j == table.length) { lastPlayer = "nobody"; return true; }
else return false;
}
private boolean playerProgress(){
if(!table[cellY][cellX].equals("empty")){
System.out.println("This cell is not empty");
return false;
} else {
lastPlayer = table[cellY][cellX] = "player";
repaint();
return true;
}
}
private void botProgress(){
do{
if(winOrDraw()){
switch (lastPlayer) {
case "player":
System.out.println("You won!");
System.exit(0);
case "bot":
System.out.println("Bot won");
System.exit(0);
default:
System.out.println("Draw");
System.exit(0);
}
}
Random random = new Random();
cellX = random.nextInt(2);
cellY = random.nextInt(2);
if(table[cellY][cellX].equals("empty")) {
lastPlayer = table[cellY][cellX] = "bot";
break;
}
}while (!table[cellY][cellX].equals("empty"));
System.out.println("Bot's turn");
repaint();
}
You are adding your Swing components directly to the JFrame-AWT-container. You should not do that. Instead you should do this:
JPanel panel = new JPanel();
myFrame.setContentPane(panel);
panel.setLayout(...)
panel.add(...);
panel.validate();
This should solve your problem.

Problems with a game similar to Tic Tac Toe using graphics and java OOP

I am working on a game that my friends invented - a little variation on tic tac toe: using a 4x4 board, one player (x) need to get 3 x's in a particular manner while the other can place one 'z' and one 'o' every turn and needs to fill the entire board. My problem is not with the rules and algoritems, but with the graphics: I don't have a lot of experience with graphics, and just can't get my board to work (even without any rules - just show up as needed).
I have a Board class that represents a board. A board has a two dimensional array of Cells. Each Cell (Cell = another class of mine) is also a JButton, and I would like that every time a button is clicked his image will change - so I decided to use ImageIcon. I also have a GameMain class to control the game and a Tools class to add two buttons - 'Exit' and 'Reset'.
If you could please help me by suggesting ways to get my board to load properly, I would appreciate that. Currently the board doesn't show up at all, and if I tweak the code a bit it shows up but the buttons won't show at all.
Here's the code: GameMain.java:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class GameMain extends JPanel {
private Turn _turn;
Board _board;
private Tools _buttons;
private boolean isOver = false;
public enum GameState {PLAYING, xWON, oWON};
private GameState _currentState;
// Name-constants for the various dimensions used for graphics drawing
public static final int CELL_SIZE = 100; // cell width and height (square)
public static final int CANVAS_WIDTH = CELL_SIZE * 4; // the drawing canvas
public static final int CANVAS_HEIGHT = CELL_SIZE * 4;
public static final int GRID_WIDTH = 8; // Grid-line's width
public static final int GRID_WIDTH_HALF = GRID_WIDTH / 2; // Grid-line's half-width
public GameMain() {
this.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (_currentState == GameState.PLAYING) {
updateGame();
} else {
initGame(); //game over, restart
}
repaint();
}
});
setLayout(new BorderLayout());
setPreferredSize(new Dimension(CANVAS_WIDTH, CANVAS_HEIGHT + 30));
_board = new Board();
_buttons = new Tools();
initGame();
_buttons.SetObject(_board);
add(_board, BorderLayout.CENTER);
add(_buttons, BorderLayout.SOUTH);
}
public void initGame() {
_turn = Turn.X;
_board.init();
_currentState = GameState.PLAYING;
}
public void updateGame() {
if (_board.hasWonX()) {
_currentState = GameState.xWON;
} else if (_board.hasWonO()) {
_currentState = GameState.oWON;
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
setBackground(Color.WHITE);
_board.paint(g);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame("xBlock");
frame.setSize(500, 500);
// Set the content-pane of the JFrame to an instance of main JPanel
frame.setContentPane(new GameMain());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null); // center the application window
frame.setVisible(true); // show it
}
});
}
}
Board:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Board extends JPanel implements ActionListener {
private Cell[][] _cells;
private Turn _turn;
public Board() {
setLayout(new GridLayout(4, 4));
_cells = new Cell[4][4];
_turn = Turn.X;
for (int i = 0; i < _cells.length; i++) {
for (int j = 0; j < _cells[0].length; j++) {
_cells[i][j] = new Cell(i, j);
_cells[i][j].addActionListener(this);
add(_cells[i][j]);
}
}
}
//initiate board
public void init() {
_turn = Turn.X;
for (int i = 0; i < _cells.length; i++) {
for (int j = 0; j < _cells[0].length; j++) {
_cells[i][j].setState(State.EMPTY);
}
}
}
public void fillCell(Cell c) {
if (c.getState() == State.EMPTY) {
c.setState(_turn.ordinal());
c.setEnabled(false);
c.draw();
_turn = _turn.getNext();
}
}
public void checkCellsAround(Cell c) {
State state = c.getState();
State right, left, up, down;
if (c.getJ() < 3 && c.getJ() > 0) {
right = _cells[c.getI()][c.getJ() + 1].getState();
left = _cells[c.getI()][c.getJ() - 1].getState();
} else if (c.getJ() == 0) {
right = _cells[c.getI()][c.getJ() + 1].getState();
left = State.EMPTY;
} else {
right = State.EMPTY;
left = _cells[c.getI()][c.getJ() - 1].getState();
}
if (c.getI() < 3 && c.getI() > 0) {
up = _cells[c.getI() - 1][c.getJ()].getState();
down = _cells[c.getI() + 1][c.getJ()].getState();
} else if (c.getI() == 0) {
up = State.EMPTY;
down = _cells[c.getI() + 1][c.getJ()].getState();
} else {
up = _cells[c.getI() - 1][c.getJ()].getState();
down = State.EMPTY;
}
switch (state) {
case EMPTY:
break;
case X:
if ((left == State.O && right == State.O) || (up == State.O && down == State.O) || (left == State.Z && right == State.Z) || (up == State.Z && down == State.Z)) {
c.setState(State.HOURGLASS);
}
break;
case O:
if ((left == State.X && right == State.X) || (up == State.X && down == State.X)) {
c.setState(State.EMPTY);
}
break;
case Z:
if ((left == State.X && right == State.X) || (up == State.X && down == State.X)) {
c.setState(State.HOURGLASS);
}
break;
case HOURGLASS:
break;
case SCRIBBLE:
break;
}
}
public void actionPerformed(ActionEvent E) {
Cell c = (Cell) E.getSource();
fillCell(_cells[c.getI()][c.getJ()]);
}
public boolean hasWonO() {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (_cells[i][j].getState() == State.EMPTY) {
return false;
}
}
}
return true;
}
public boolean hasWonX() {
return false;
}
public void paint(Graphics g) {
g.setColor(Color.GRAY);
for (int i = 1; i < 4; i++) {
g.fillRoundRect(0, GameMain.CELL_SIZE * i - GameMain.GRID_WIDTH_HALF,
GameMain.CANVAS_WIDTH - 1, GameMain.GRID_WIDTH,
GameMain.GRID_WIDTH, GameMain.GRID_WIDTH);
}
for (int j = 1; j < 4; j++) {
g.fillRoundRect(GameMain.CELL_SIZE * j - GameMain.GRID_WIDTH_HALF, 0,
GameMain.GRID_WIDTH, GameMain.CANVAS_HEIGHT - 1,
GameMain.GRID_WIDTH, GameMain.GRID_WIDTH);
}
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
_cells[i][j].draw();
}
}
}
}
Cell.java:
import javax.swing.ImageIcon;
import javax.swing.JButton;
public class Cell extends JButton {
private int _i, _j;
private State _state;
ImageIcon X = new ImageIcon(this.getClass().getResource("x-icon.png"));
ImageIcon O = new ImageIcon(this.getClass().getResource("o-icon.png"));
ImageIcon Z = new ImageIcon(this.getClass().getResource("z-icon.png"));
ImageIcon Hourglass = new ImageIcon(this.getClass().getResource("hourglass-icon.png"));
ImageIcon Scribble = new ImageIcon(this.getClass().getResource("scribble-icon.png"));
public Cell() {
this.setEnabled(true);
_i = 0;
_j = 0;
_state = State.EMPTY;
}
public Cell(int i, int j) {
this.setEnabled(true);
_i = i;
_j = j;
_state = State.EMPTY;
}
public int getI() {
return _i;
}
public int getJ() {
return _j;
}
public void setState(State state) {
_state = state;
if (state == State.EMPTY) {
this.setEnabled(true);
}
}
public void setState(int index) {
_state = State.values()[index];
}
public State getState() {
return _state;
}
public void draw() {
switch (_state) {
case EMPTY:
this.setIcon(null);
break;
case X:
this.setIcon(X);
break;
case O:
this.setIcon(X);
break;
case Z:
this.setIcon(X);
break;
case HOURGLASS:
this.setIcon(X);
break;
case SCRIBBLE:
this.setIcon(X);
break;
}
}
public void highlight() {
}
}
Tools.java:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Tools extends JPanel {
private JButton _exit, _reset;
private Board _board;
Tools() {
setLayout(new FlowLayout());
_exit = new JButton("Exit");
_reset = new JButton("Reset");
_exit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
System.exit(0);
}
});
_reset.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
_board.init();
}
});
add(_exit);
add(_reset);
}
public void SetObject(Board b) {
_board = b;
}
}
State.java:
public enum State {
EMPTY, X, O, Z, HOURGLASS, SCRIBBLE;
public State getNext() {
return State.values()[(this.ordinal() + 1) % State.values().length];
}
}
Turn.java:
public enum Turn {
X, O, Z;
public Turn getNext() {
return Turn.values()[(this.ordinal() + 1) % Turn.values().length];
}
}
Thanks in advance!
So after running it, you are getting an ArrayIndexOutOfBoundsException at this line in the paint method of the Board class:
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
_cells[i][j].draw(); <==========
}
}
Not sure how your game works, but by looking at the loops previous to this one, you are accessing only up to index 3 ( for (int j = 1; j < 4; j++) { ). So if you change the loop max to 4, it gets the game up and running.
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
_cells[i][j].draw();
}
}
Learning to read exceptions and stack traces is very important. It will save you a lot of future headaches. Take some time to read What is a stack trace, and how can I use it to debug my application errors?
And like I said in my comments,
It doesn't look like you're doing anything with the paintComponent in the GameMain. You should just get rid of the paintComponent method altogether in that class. Instead of trying to call board.paint(g);, try to just call board.repaint() in the mouse listener, instead of trying to repaint the main game panel. And just set the background in the constructor of the GameMain instead of in the paintComponent method.
Also in the Board class use paintComponent rather than paint. and don't forget to call super.paintComponent in the paintComponent method
Fixing all the things above, get it work (I guess).
UPDATE
As the MadMan pointed out in the comment below, it would be better to use the _cells.length to avoid having to rely magic numbers. This way you will be sure not to access an inexistant index
for (int i = 0; i < cells.length; i++) {
for (int j = 0; j < cells[i].length; j++) {
_cells[i][j].draw();
}
}

Repaint() method causes UI to flash and flicker

So I have been coding this little UI for a while and for some reason the repaint() method seems to cause the image generated on the screen to flicker and flash. Is there a way to prevent this?
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
import java.util.Timer;
public class userInterfaceSimple extends JFrame implements ActionListener
{
static ArrayList<Creature> list = new ArrayList<Creature>();
static JButton next = new JButton("Begin");
static Timer timer = new Timer();
static JFrame frame = new JFrame();
final static JPanel pane = new JPanel();
public static void main(String[] args)
{
new userInterfaceSimple();
}
public userInterfaceSimple()
{
super("Toy Planet: Life, a Simulation");
setSize(1000,1000);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new BorderLayout());
add(pane, BorderLayout.CENTER);
next.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
if(next.getText().equals("Begin"))
{
next.setText("Stop");
timer.scheduleAtFixedRate(new TimerTask()
{
#Override
public void run()
{
checkRules();
repaint();
}
}, 250, 250);
}
else
{
next.setText("Begin");
timer.cancel();
timer = new Timer();
}
}
});
add(next, BorderLayout.SOUTH);
for(int j = 0; j < 3; j ++)
{
Creature orgArc = new Creature();
for(int i = 0; i < 20; i++)
{
list.add(new Creature(orgArc.gene));
}
}
sortList();
}
public void paint(Graphics g)
{
super.paint(g);
for(int i = 0; i < list.size(); i++)
{
g.setColor(list.get(i).getColor());
int size = list.get(i).getSize();
g.fillOval(list.get(i).getX() - size/2, list.get(i).getY() - size/2,size,size);
}
}
public static void checkRules()
{
int size = list.size();
for(int i = 0; i < size; i++)
{
try
{
for(int j = 0; j < size; j++)
{
boolean alreadyMoved = false;
if(!(list.get(i)).equals(list.get(j)))
{
int x = list.get(j).getX() - (list.get(i)).getX();
int y = list.get(j).getY() - (list.get(i)).getY();
double z = Math.sqrt(x*x + y*y);
//Passive Interaction Rules
//Sight Check
if(list.get(j).getSense() > z)
{
list.get(j).moveTo(list.get(i));
alreadyMoved = true;
}
if(z <= 1.5)
{
//Active Interaction Rules
//Breeding Check
if(list.get(j).isCompatible(list.get(i)))
{
list.add(list.get(j).breed(list.get(i)));
sortList();
}
//Eating Check
else if(list.get(j).getAggro() > 15 || list.get(j).getDiet() > 3)
{
list.get(j).eat(list.get(i));
}
}
}
//If no checks fire then move randomly
if(alreadyMoved == false)
{
Organism temp = new Organism();
list.get(j).moveTo(temp);
}
}
//Hunger Check
list.get(i).hungerCheck();
}
catch(Exception e)
{
}
list.get(i).validate();
size = size - validateList();
}
/*for(int i = 0; i < list.size(); i ++) //for debugging.
{
System.out.println(list.get(i).getInfo());
}
System.out.println("----");*/
}
public static int getClosestCreature(Organism org)
{
int x,y;
double z;
double tempZ = 100000;
int closest = 0;
for(int i = 0; i < list.size(); i++)
{
if(!(list.get(i)).equals(org))
{
x = org.getX() - (list.get(i)).getX();
y = org.getY() - (list.get(i)).getY();
z = Math.sqrt(x*x + y*y);
if(z < tempZ)
{
closest = i;
tempZ = z;
}
}
}
return (closest);
}
public static int validateList()
{
int netLoss = 0;
for(int i = 0; i < list.size(); i++)
{
if((list.get(i)).getAlive() == false)
{
list.remove(i);
netLoss = netLoss + 1;
}
}
return netLoss;
}
public static void sortList()
{
Creature temp;
for(int i = 0; i < list.size(); i ++)
{
for(int j = 1; j < list.size() - i; j++)
{
if(list.get(j - 1).getSpeed() > list.get(j).getSpeed())
{
temp = list.get(j - 1);
list.set(j - 1, list.get(j));
list.set(j, temp);
}
}
}
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
}
Thanks for you help!
Yes, it is simple: Double Buffering should fix it. For more reference, visit http://docs.oracle.com/javase/tutorial/extra/fullscreen/doublebuf.html
First you should create private BufferedImage bufferImage;
In your public void paint(Graphics g) you should paint stuff into this bufferImage, and then, when bufferImage is filled, paint it g.drawImage(bufferImage, 0, 0, null);
public void paint(Graphics g) {
Graphics2D gr = bufferImage.createGraphics();
for(int i = 0; i < list.size(); i++)
{
gr.setColor(list.get(i).getColor());
int size = list.get(i).getSize();
gr.fillOval(list.get(i).getX() - size/2, list.get(i).getY() - size/2,size,size);
}
super(g);
g.drawImage(bufferImage, 0, 0, null);
}
Not compiled, but something like this should work.

Categories

Resources