lundi 24 avril 2017

Java repaint() not updating images, poor design

I am having some problems with the repaint() method in my code, while everything runs normally (no exceptions) there is no change to the panel I am drawing to.

I know that the design of the classes/methods is not great and is probably contributing to the problem but I don't know how to clean it up without breaking my program.

You can see my code + some screenshot of the output here:

The Draw class is responsible for paint and repainting the game board

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Draw extends JPanel{
    Observer observer = new Observer();

    ArrayList<BufferedImage> Pieces = new ArrayList<BufferedImage>();

    int movedToX;
    int movedToY;
    BufferedImage pieceIcon;

    String square;
    String piece;

    public JPanel makeABoard(){
        JPanel board = null;
         try {
                final BufferedImage gboard = ImageIO.read(new File("cutsomGameBoard.jpg"));

                //load white game pieces
                Pieces.add(ImageIO.read(new File("rect-lightOrange.png")));
                Pieces.add(ImageIO.read(new File("rect-navy.png")));
                Pieces.add(ImageIO.read(new File("rect-maroon.png")));  
                Pieces.add(ImageIO.read(new File("rect-lilac.png")));
                Pieces.add(ImageIO.read(new File("rect-yellow.png")));
                Pieces.add(ImageIO.read(new File("rect-orange.png")));
                Pieces.add(ImageIO.read(new File("rect-green.png")));
                Pieces.add(ImageIO.read(new File("rect-brown.png")));

                //load black game pieces
                Pieces.add(ImageIO.read(new File("rev-brown.png")));
                Pieces.add(ImageIO.read(new File("rev-green.png")));
                Pieces.add(ImageIO.read(new File("rev-orange.png")));
                Pieces.add(ImageIO.read(new File("rev-yellow.png")));
                Pieces.add(ImageIO.read(new File("rev-lilac.png")));
                Pieces.add(ImageIO.read(new File("rev-maroon.png")));
                Pieces.add(ImageIO.read(new File("rev-navy.png")));
                Pieces.add(ImageIO.read(new File("rev-lighOrange.png")));

                //You can get the Piece class from the observer which you can then use to store that Piece's icon

                int i = 0;
                for(Piece p : observer.getCurrentState().getPieces().getPieces()){
                    p.setIcon(Pieces.get(i));
                    i++;
                }

                //draws the initial board
                board = new JPanel(){
                    protected void paintComponent(Graphics g) {
                        super.paintComponent(g);

                        g.drawImage(gboard, 0, 0, this);

                        starterPieces(g);  
                    }
                    @Override
                    public Dimension getPreferredSize() {
                        return new Dimension(480, 480);
                    }   
                };
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        return board;

    }

    public void paintComponent(Graphics g){
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.drawImage(pieceIcon, movedToX, movedToY, this);
    }

    public void starterPieces(Graphics g){
        int x = 5;
        int y = 5;
        for(int i = 0; i <8; i++){
            g.drawImage(Pieces.get(i), x, y, this);
            x += 60;
        }
        x = 5;
        y = 425;
        for(int i = 8; i <16; i++){
            g.drawImage(Pieces.get(i), x, y, this);
            x += 60;
        }

    }

    //Here is where my main problem lies: this method translates the users input (a string) to something which the GUI can use to repaint the board
    public void updateBoard(String pieceInput, String squareInput){
        Graphics g = this.getGraphics();
        //each square object know its own id (e.g. C4) which you can use to search a certain square as well as knowing its location in the form of a Point2D object
        Square sq = observer.getCurrentState().getBoard().getStringSquare(squareInput);
        movedToX = (int) sq.getSquareLocation().getX();
        movedToY = (int) sq.getSquareLocation().getY();
        pieceIcon = observer.getCurrentState().getPiece(pieceInput).getIcon();
        repaint();
    }

    public void clearOldPieces(){
        // to be added
    }

}

The GUI class is the main user interface which calls the Draw method once the user reaches the game screen

import java.util.ArrayList;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;

public class GUI extends Frame implements ActionListener {
    private static final long serialVersionUID = 1L;

Observer observer = new Observer();

String piece;
String square; 

JFrame screen;
JLabel updates; 


public GUI(){
    welcome();
}

//One method per screen
public void welcome(){  
    observer.createState();
    final JTextField accountName = new JTextField(20);
    updates = new JLabel();
    updates.setText("Watch this space for feedback through out your game!");
    updates.setForeground(Color.WHITE);
    screen = new JFrame("Welcome");

    JPanel welcome =  new JPanel();
    JPanel footer = new JPanel();

    JButton start = new JButton("Start");
    start.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            playerOneName = accountName.getText();
            CurrentState cs = observer.getCurrentState();
            cs.createPlayer();
            observer.getCurrentState().getPlayer(1).setName(playerOneName);
            welcome.setVisible(false);
            updates.setText("Player one created!");
            observer.getCurrentState().getPlayer(1).activatePlayer();
            //choose(playerOneName); --> usually there is a few more screens here before the board but for now we can directly go to it
            drawBoard();
        }
    });

    JLabel message = new JLabel();
    message.setText("Welcome to Kamisado, please enter your name");
    message.setForeground(Color.WHITE);

    welcome.add(message);
    welcome.add(accountName);
    welcome.add(start);
    welcome.setVisible(true);
    welcome.setBackground(Color.darkGray);

    footer.add(updates);
    footer.setVisible(true);
    footer.setBackground(Color.darkGray);

    screen.add(welcome);
    screen.add(footer, BorderLayout.PAGE_END);
    screen.setVisible(true);
    screen.pack();
    //screen.getContentPane().setBackground(Color.darkGray);
    screen.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

}

public void drawBoard(){
    JPanel gameScreen = new JPanel();
    JButton loadGame = new JButton("Load Game");
    JButton settings = new JButton("Settings");
    JButton reset = new JButton("Reset");
    JButton undo = new JButton("Undo");
    JButton save = new JButton("Save");
    JButton quit = new JButton("Quit");

    Draw boardImg = new Draw();

    JPanel keyInput = new JPanel();

    JLabel message = new JLabel();
    message.setText("Enter the piece to move and the square to move to, comma seperated: ");
    message.setForeground(Color.white);

    JTextField pieceSquare = new JTextField(10);

    JButton move = new JButton("Move");
    move.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e){
            piece = pieceSquare.getText().substring(0,2).toUpperCase();
            square = pieceSquare.getText().substring(3,5).toUpperCase();
            System.out.println("Piece from text field " + piece);
            System.out.println("Square from text field " + square);
            if(!gameMode.startsWith("A")){
                if(movePiece()){
                    updates.setText("Success!");
                    boardImg.updateBoard(piece,square);
                }

            }
            else{
                if(moveAIPiece()){
                    updates.setText("Success!");
                    boardImg.updateBoard(piece,square);
                }
            }

        }
    });

    keyInput.add(message);
    keyInput.add(pieceSquare);
    keyInput.add(move);
    keyInput.setBackground(Color.darkGray);
    keyInput.setVisible(true);
    gameScreen.add(boardImg.makeABoard(), BorderLayout.LINE_END);
    gameScreen.add(keyInput, BorderLayout.LINE_END);
    gameScreen.setVisible(true);
    gameScreen.setBackground(Color.DARK_GRAY);
    gameScreen.setMinimumSize(new Dimension(520,520));
    screen.add(gameScreen);
}

public boolean movePiece(){
    if(gameMode.equals("H")){
        if(gameInterface.play(piece, square, playerColour)){
            return true;
        }
    }
    else if(gameMode.equals("T")){
        if(gameInterface.playTimed(piece, square, playerColour, timeLength){
            return true;
        }
    }
    return false;
}

public boolean moveAIPiece(){
    if(gameMode.equals("A")){
        if(gameInterface.play(piece, square, playerColour)){
            if(aiDiff.equals("E")){
                 gameInterface.playAI(piece, square, playerColour);
                 return true;
            }
            else{
                gameInterface.playHardAI(piece, square, playerColour);
                return true;
            }
        }
    }
    else{
        if(gameInterface.playTimed(piece, square, playerColour, timeLength){
            if(aiDiff.equals("E")){
                gameInterface.playAI(piece, square, playerColour);
                switchPlayer();
                return true;
            }
            else{
                gameInterface.playHardAI(piece, square, playerColour);
                return true;
            }
        }
    }
    return false;
}

}

Output:

screenshot of board GUI

Aucun commentaire:

Enregistrer un commentaire