0

I have a maze that I need to get a ball to move through, but I don't know what code I need to use to move the image of the ball around the maze. I have been given a hint that I need to swap images round.

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

public class CBallMaze extends JFrame implements ActionListener 
{
//Below is where I have declared all the different objects I have used throughout my program

private JButton buttonRight, buttonLeft, buttonUp, buttonDown, buttonTL, buttonTR, buttonBL, buttonBR, buttonCenter, optionOne, optionTwo, optionThree, optionExit, scenarioAct, scenarioRun, scenarioReset, compassPH;
private JButton [] game = new JButton [208];
private JPanel panelCentre, panelRight, panelBottom, buttonPanel, compassPanel, optionsPanel, selectionPanel, panelAct, panelRun, panelReset, panelSlider;
private JTextField optionTF, squareTF, directionTF;
private JLabel option, square, direction, compassDirection;
private JSlider speedSlider;
private String firstOption = "1", secondOption = "2", thirdOption = "3", upDirection = "North", rightDirection = "East", downDirection = "South", leftDirection = "West";
private int i;
private int[] map = new int[]
        {
        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,
        3,1,3,3,3,1,3,3,3,1,3,3,3,3,3,3,
        3,1,3,3,3,1,3,3,3,1,3,3,3,3,3,3,
        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
        3,3,1,3,3,3,1,3,3,3,3,1,3,3,3,3,
        3,3,1,3,3,3,1,3,3,3,3,1,3,3,3,3,
        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
        3,1,3,3,3,1,3,3,3,1,3,3,3,3,3,3,
        3,1,3,3,3,1,3,3,3,1,3,3,3,3,3,3,
        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
        3,3,1,3,3,3,1,3,3,3,3,1,3,3,3,3,
        3,3,1,3,3,3,1,3,3,3,3,1,3,3,3,3,
        4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
        };

final ImageIcon iconCompassNorth = new ImageIcon("north.jpg"); 
final ImageIcon iconCompassWest = new ImageIcon("west.jpg");
final ImageIcon iconCompassSouth = new ImageIcon("south.jpg");
final ImageIcon iconCompassEast = new ImageIcon("east.jpg");
ImageIcon iconReset = new ImageIcon("Reset.jpg");
ImageIcon iconRun = new ImageIcon("Run.jpg");
ImageIcon iconAct = new ImageIcon("Act.jpg");
ImageIcon iconSand, iconWhite, iconBall, iconEnd;

public CBallMaze(String title) {
    super(title);
}
public static void main(String[] args)
{
    CBallMaze cBallMaze = new CBallMaze("CBallMaze Ball Maze Application");
    cBallMaze.setSize(775, 650);
    cBallMaze.createGUI();
    cBallMaze.setVisible(true);
}
private void createGUI()
{   
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    Container window = getContentPane();
    window.setLayout(new BorderLayout() );

    //Panels

    panelCentre = new JPanel();
    panelCentre.setPreferredSize(new Dimension(625, 450));
    panelCentre.setBackground(Color.BLACK);
    window.add(panelCentre);
    panelCentre.setLayout(new GridLayout(13, 16));

    panelRight = new JPanel();
    panelRight.setPreferredSize(new Dimension(180, 450));
    panelRight.setBackground(Color.WHITE);
    window.add(panelRight, BorderLayout.EAST);

    optionsPanel = new JPanel();
    optionsPanel.setPreferredSize(new Dimension(150, 100));
    optionsPanel.setBackground(Color.WHITE);
    panelRight.add(optionsPanel, BorderLayout.EAST);

    buttonPanel = new JPanel();
    buttonPanel.setPreferredSize(new Dimension(175, 100));
    buttonPanel.setBackground(Color.WHITE);
    panelRight.add(buttonPanel, BorderLayout.EAST);

    selectionPanel = new JPanel();
    selectionPanel.setPreferredSize(new Dimension(175, 150));
    selectionPanel.setBackground(Color.WHITE);
    panelRight.add(selectionPanel, BorderLayout.EAST);

    ImageIcon cw = new ImageIcon("west.jpg");

    compassPanel = new JPanel();
    compassPanel.setPreferredSize(new Dimension(175, 300));
    compassPanel.setBackground(Color.WHITE);
    panelRight.add(compassPanel, BorderLayout.EAST);

    panelBottom = new JPanel();
    panelBottom.setPreferredSize(new Dimension(875, 50));
    panelBottom.setBackground(Color.WHITE);
    window.add(panelBottom, BorderLayout.SOUTH);

    panelAct = new JPanel();
    panelAct.setPreferredSize(new Dimension(125, 40));
    panelAct.setBackground(Color.WHITE);
    panelBottom.add(panelAct, BorderLayout.SOUTH);

    panelRun = new JPanel();
    panelRun.setPreferredSize(new Dimension(125, 40));
    panelRun.setBackground(Color.WHITE);
    panelBottom.add(panelRun, BorderLayout.SOUTH);

    panelReset = new JPanel();
    panelReset.setPreferredSize(new Dimension(125, 40));
    panelReset.setBackground(Color.WHITE);
    panelBottom.add(panelReset, BorderLayout.SOUTH);

    panelSlider = new JPanel();
    panelSlider.setPreferredSize(new Dimension(200, 40));
    panelSlider.setBackground(Color.WHITE);
    panelBottom.add(panelSlider, BorderLayout.SOUTH);

    //Displays

    option = new JLabel("Option: ");
    optionsPanel.add(option, BorderLayout.LINE_START);
    option.setEnabled(true);
    option.setForeground(Color.BLACK);
    option.setHorizontalAlignment(JLabel.LEFT);

    optionTF = new JTextField("1");
    optionsPanel.add(optionTF, BorderLayout.LINE_END);
    optionTF.setEnabled(true);
    optionTF.setPreferredSize(new Dimension(50, 25));
    optionTF.setHorizontalAlignment(JTextField.CENTER);

    square = new JLabel("Square:   ");
    optionsPanel.add(square, BorderLayout.LINE_START);
    square.setEnabled(true);
    square.setForeground(Color.BLACK);
    square.setHorizontalAlignment(JLabel.LEFT);

    squareTF = new JTextField("");
    optionsPanel.add(squareTF, BorderLayout.LINE_END);
    squareTF.setEnabled(true);
    squareTF.setPreferredSize(new Dimension(50, 25));
    squareTF.setHorizontalAlignment(JTextField.CENTER);

    direction = new JLabel("Direction:  ");
    optionsPanel.add(direction, BorderLayout.LINE_START);
    direction.setEnabled(true);
    direction.setForeground(Color.BLACK);
    direction.setHorizontalAlignment(JLabel.LEFT);

    directionTF = new JTextField("Still");
    optionsPanel.add(directionTF, BorderLayout.LINE_END);
    directionTF.setEnabled(true);
    directionTF.setPreferredSize(new Dimension(50, 25));
    directionTF.setHorizontalAlignment(JTextField.CENTER);

    //buttons

    buttonTL = new JButton("");
    buttonPanel.add(buttonTL);
    buttonTL.setPreferredSize(new Dimension(45, 25));
    buttonTL.setEnabled(false);

    buttonUp = new JButton("^");
    buttonPanel.add(buttonUp);
    buttonUp.setPreferredSize(new Dimension(45, 25));
    buttonUp.addActionListener(this);
    buttonUp.addActionListener(new ActionListener() 
    {
        public void actionPerformed(ActionEvent e) 
        {
            directionTF.setText(upDirection);
            compassDirection.setIcon(iconCompassNorth);
        }
    });

    buttonTR = new JButton("");
    buttonPanel.add(buttonTR); 
    buttonTR.setPreferredSize(new Dimension(45, 25));
    buttonTR.setEnabled(false);

    buttonLeft = new JButton("<");
    buttonPanel.add(buttonLeft);
    buttonLeft.setPreferredSize(new Dimension(45, 25));
    buttonLeft.addActionListener(new ActionListener() 
    {
        public void actionPerformed(ActionEvent e) 
        {
            directionTF.setText(leftDirection);
            compassDirection.setIcon(iconCompassWest);
        }
    });

    buttonCenter = new JButton("");
    buttonPanel.add(buttonCenter);
    buttonCenter.setPreferredSize(new Dimension(45, 25));
    buttonCenter.setEnabled(false);

    buttonRight = new JButton(">");
    buttonPanel.add(buttonRight);
    buttonRight.setPreferredSize(new Dimension(45, 25));
    buttonRight.addActionListener(new ActionListener() 
    {
        public void actionPerformed(ActionEvent e) 
        {
            directionTF.setText(rightDirection);
            compassDirection.setIcon(iconCompassEast);
        }
    });

    buttonBL = new JButton("");
    buttonPanel.add(buttonBL);
    buttonBL.setPreferredSize(new Dimension(45, 25));
    buttonBL.setEnabled(false);

    buttonDown = new JButton("v");
    buttonPanel.add(buttonDown);
    buttonDown.setPreferredSize(new Dimension(45, 25));
    buttonDown.addActionListener(new ActionListener() 
    {
        public void actionPerformed(ActionEvent e) 
        {
            directionTF.setText(downDirection);
            compassDirection.setIcon(iconCompassSouth);
        }
    });

    buttonBR = new JButton("");
    buttonPanel.add(buttonBR);
    buttonBR.setPreferredSize(new Dimension(45, 25));
    buttonBR.setEnabled(false);

    optionOne = new JButton("Option One");
    selectionPanel.add(optionOne);
    optionOne.setPreferredSize(new Dimension(125, 25));
    optionOne.addActionListener(new ActionListener() 
    {
        public void actionPerformed(ActionEvent e) 
        {
            optionTF.setText(firstOption);
        }
    });

    optionTwo = new JButton("Option Two");
    selectionPanel.add(optionTwo);
    optionTwo.setPreferredSize(new Dimension(125, 25));
    optionTwo.addActionListener(new ActionListener() 
    {
        public void actionPerformed(ActionEvent e) 
        {
            optionTF.setText(secondOption);
        }
    });

    optionThree = new JButton("Option Three");
    selectionPanel.add(optionThree);
    optionThree.setPreferredSize(new Dimension(125, 25));
    optionThree.addActionListener(new ActionListener() 
    {
        public void actionPerformed(ActionEvent e) 
        {
            optionTF.setText(thirdOption);
        }
    });

    optionExit = new JButton("Exit");
    selectionPanel.add(optionExit);
    optionExit.setPreferredSize(new Dimension(125, 25));

    scenarioAct = new JButton("Act");
    scenarioAct.setIcon(iconAct);
    panelAct.add(scenarioAct);
    scenarioAct.addActionListener(this);

    scenarioRun = new JButton("Run");
    scenarioRun.setIcon(iconRun);
    panelRun.add(scenarioRun);
    scenarioRun.addActionListener(this);

    scenarioReset = new JButton("Reset");
    scenarioReset.setIcon(iconReset);
    panelReset.add(scenarioReset);
    scenarioReset.addActionListener(this);

    JSlider speedSlider = new JSlider(JSlider.HORIZONTAL, 0, 50, 25);
    speedSlider.setMajorTickSpacing(10);
    speedSlider.setMinorTickSpacing(5);
    speedSlider.setPaintTicks(true);
    speedSlider.setBackground(Color.WHITE);
    speedSlider.setLabelTable(speedSlider.createStandardLabels(10));
    panelSlider.add(speedSlider);

    compassDirection = new JLabel();
    compassPanel.add(compassDirection);

    try
    {
        iconSand = new ImageIcon("sand.jpg");
    }
    catch (Exception e)
    {
        System.err.println("Sand Icon "+e);
    }

    try
    {
        iconBall = new ImageIcon("sand60x60.png");
    }
    catch (Exception e)
    {
        System.err.println("Ball Icon "+e);
    }

    try
    {
        iconWhite = new ImageIcon("white32x32.jpg");
    }
    catch (Exception e)
    {
        System.err.println("White Icon "+e);
    }

    try
    {
        iconEnd = new ImageIcon("sandstone.jpg");
    }
    catch (Exception e)
    {
        System.err.println("End Icon"+e);
    }

    for (i=0;i<208;i++)
    {
        game[i] = new JButton ();

        if(map[i]==1)
        {
            game[i].setIcon(iconSand);
        }
        if(map[i]==2)
        {
            game[i].setIcon(iconBall);
        }
        if(map[i]==3)
        {
            game[i].setIcon(iconWhite);
        }
        if(map[i]==4)
        {
            game[i].setIcon(iconEnd);
        }

        game[i].setBorder(null);
        game[i].setPreferredSize(new Dimension(32, 32));
        game[i].addActionListener(this);
        panelCentre.add(game[i]);

    }
}
public void actionPerformed(ActionEvent arg0) 
{

}
}

sand60x60 sand white32x32

  • 1
    This is not very much information. Do you got any code we can discuss about? – chris Jul 14 '15 at 11:28
  • sorry @chris I have updated the post with my code for this program, it produces a maze that I need to get a ball to move around, just any code to make the ball movements correspond with keyboard presses will be fine –  Jul 14 '15 at 11:39
  • Ok, it's running. Could you please post your images (sand.jpg,...)? I assume it looks much clearer using these. – chris Jul 14 '15 at 11:54
  • I think the OP has already implemented everything he will indeed need to work with. He creates anonymous ActionListeners... Making them instances he could just assign them to the maze and query for the keyEvents, then call the matching handler... :) – mambax Jul 14 '15 at 11:56

2 Answers2

0

Try this (works for me):

After this line panelCentre.add(game[i]); enter this:

    game[i].addKeyListener(new KeyListener() {

        @Override
        public void keyTyped(KeyEvent e) {
        }

        @Override
        public void keyPressed(KeyEvent e) {
        }

        @Override
        public void keyReleased(KeyEvent e) {
            System.out.println(e.getKeyCode());
            switch (e.getKeyCode()) {
                case KeyEvent.VK_RIGHT:
                    System.out.println("right..."); 
                    break;
                case KeyEvent.VK_LEFT:
                    System.out.println("left..."); 
                    break;
                case KeyEvent.VK_DOWN:
                    System.out.println("down..."); 
                    break;
                case KeyEvent.VK_UP:
                    System.out.println("up..."); 
            }
        }
    });

This should print out the direction you typed with the arrow keys.

chris
  • 1,685
  • 3
  • 18
  • 28
  • The @Override gives me an error, but when I remove them and attempt to run the code, pressing the arrow keys do not actually move the ball. –  Jul 14 '15 at 12:19
  • Of course it does not move the ball :) It is just a Print :) If you already have the move-methods, call them at the matching point (after the Print, before the break) – mambax Jul 14 '15 at 12:22
  • Please post the images here to help us understand whats going on with the graphics. – chris Jul 14 '15 at 12:25
  • I don't have the move-methods, that's all I need at this point, I don't know how to move the ball with code. @m4mbax –  Jul 14 '15 at 12:26
  • 1
    It's some kind of strange to use buttons for painting. I would recommend using a JPanel, override paint() and do some `graphics2d.drawImage()` to have much more control over the graphical appearance. Also use a ball object which knows his own position, speed and so on. This would be a much better concept to blow the possibilities. – chris Jul 14 '15 at 12:44
  • You know it is somehow difficult to help because when I run your code I dont see any images, no ball no nothing... Maybe consider sharing the project on github or something alike? – mambax Jul 14 '15 at 12:59
  • @m4mbax: you could use the images posted with the question. but it still looks strange. And i am not satisfied in general with the concept (using buttons). They must be updated and you always have to calculate the position and what not... – chris Jul 14 '15 at 13:03
  • CBallMaze somehow looks like a exercise given from a school or like this, I think OP has to use this approach. If not, I would consider switching to other approaches like @chris suggested, either JPanel and override paint() or even switch technology to FX and use translations... :) More info on your scope op? – mambax Jul 14 '15 at 13:16
  • @m4mbax yep, uni assignment and I just can't figure out how to get the ball to move. I've made it so the directional arrows in the GUI change the direction displayed in the JTextFields and the direction displayed on the compass. As far as I can tell when I click an arrow I have to make the image where the ball was turn into a standard sand block and the image where the ball has been told to go to turn into the ball image. –  Jul 14 '15 at 14:39
  • I think you just have to set the icon with `.setIcon()`. And you have to remember the current position which is updated every time a arrow key is pressed. Maybe you have to call `.update UI()` on the button object to update the graphics. I would store the current position in two variables - x and y. When the position is on the right and the right arrow is pressed you have to ignore that action. Similar stuff for the other edges... – chris Jul 14 '15 at 15:23
  • @wolfiejoe Ill look into that to help you tomorrow, can you in the meantime post your project somewhere? Github maybe? :) – mambax Jul 14 '15 at 20:56
0

Here is the answer to the question

How to move the ball in the maze https://gist.github.com/ad78d37918de6320733b

Note that you should use an own KeyEventDispatcher because otherwise you would have to attach the KeyListener to ALL components in your WHOLE GUI (see this post)

Anyway, as @chris pointed out, a ball object and another data structure than array would make your assignment easier :)

Community
  • 1
  • 1
mambax
  • 1,079
  • 8
  • 17