Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 3 of 3
  1. #1
    New to the CF scene
    Join Date
    Oct 2012
    Location
    New Zealand
    Posts
    2
    Thanks
    1
    Thanked 0 Times in 0 Posts

    Question Issues with listeners in a snake game

    I'm very new to this, trying to make a snake game and I'm having a bit of difficulty getting the directional buttons to do what I want. At the moment I am just trying to get a square to move in the direction of the last arrow key by changing the dx and dy values that a move() method uses. It changes those values by the setMove(int i, int i) method until you press the start button which starts the timer which calls move() on the block, then for some reason the keystrokes don't even register.

    I suspect it might be an issue with multiple listeners (and different types) or something to do with the setFocusable(boolean b) method that perhaps needs to be called again at some stage?

    I realise this is a slightly convoluted way to set out the panels and JFrame but I have extended this from a class project. It's not a class project but it just uses some of the layout from one I have finished already.

    Any help would be appreciated even just tips for debugging or ideas why this might not be working.

    Anyway here's the code, sorry about the mess:

    In file SnakeHead.Java:

    Code:
    /* Snake head class to draw the snake head and move it
     * Scott van Heerden
     */
    
    package Snake;
    
    import java.awt.*;
    
    public class SnakeHead{
      private final int DIAM = 10;
      private int x, y;
      protected int dx, dy;
        
      
      /*-----CONSTRUCTOR for SnakeHead-------*/
      public SnakeHead(){
        // Sets the initial placement at the centre of the panel (bottom right corner of centre four)
        x = y = 200;
        // Sets the initial direction to be right horizontal
        dx = 10;
            
      } // end SnakeHead()
      
      /*------SETTER for SnakeHead movements---*/
      public void setMove(int dx, int dy){
        this.dx = dx;
        this.dy = dy;
        System.out.println("Got through setMove()");
      }
      
      //////////////////////////////////////////////////////////////////////
      /*-Makes the snake head move depending on the current direction set-*/
      public void move(){
        
        x+=dx;
        y+=dy;
        
      } // end move() method
      
      public void display(Graphics g){
        g.setColor (Color.yellow); // Sets the snake head to have a yellow fill
        g.fillRect(x, y, DIAM, DIAM);
        g.setColor (Color.black); // Sets the snake head to have a black outline
        g.drawRect(x, y, DIAM, DIAM);
      }
      
      ///////////////////////////////////////////////////////////////////////////
      /*---Checks that the snake hasn't run into a wall*/
      public boolean checkSafe(){
        boolean safe;
        if (x > -1 && x < 391 && y <391 && y > -1){
          safe = true;
        }else{
          safe = false;
        }
        return safe;
        
      } // end chackSafe() method
        
    } // end SnakeHead class
    And the file which runs that:

    SnakePanel.java

    Code:
    /* Snake attempt by Scott van Heerden
     * Direction class to create and display the panel
     * 
     */
    
    package Snake;
    
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    
    public class SnakePanel extends JPanel{
      private JPanel gamePanel = new GamePanel();
      // Creates buttons, labels, and text fields
      private JPanel controlPanel = new JPanel();
      private JButton speedUp = new JButton("Speed Up");
      private JButton slowDown = new JButton("Slow Down");
      private JLabel score = new JLabel("Score: ");
      private JButton start = new JButton("Start");
      private JButton pause = new JButton("Pause");
      private JButton restart = new JButton("Restart");
      Timer timer;
      private final int MEDIUM =200;
      private SnakeHead head = new SnakeHead();
     
      
      /*----------------------------MAIN-----------------------------*/
      public static void main(String[] args){
        JFrame frame = new JFrame(); // Creates a new JFrame
        frame.getContentPane().add(new SnakePanel());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
        frame.setTitle("Snake");
            
      } // end main
      
      /*-----------------CONSTRUCTOR for SnakePanel-------------------*/
      public SnakePanel(){
        
        // Creates and adds a listener for the buttons
        ButtonListener listener = new ButtonListener();
        speedUp.addActionListener(listener);
        speedUp.addActionListener(listener);
        start.addActionListener(listener);
        pause.addActionListener(listener);
        restart.addActionListener(listener);
        
        //Creates new timer object, sets the delay, sets the listener
        timer = new Timer(MEDIUM, listener);
        
        // Settings for controlPanel
        controlPanel.setPreferredSize(new Dimension(100,400));
        controlPanel.add(start);
        controlPanel.add(pause);
        controlPanel.add(speedUp);
        controlPanel.add(slowDown);
        controlPanel.add(score);
        controlPanel.add(restart);
        
        // Adds controlPanel and drawPanel to SnakePanel
        add(controlPanel);
        add(gamePanel);
        
        // Creates and adds a key listener
        addKeyListener(new DirectionListener());
        setFocusable(true);
        
      } // end SnakePanel() constructor
      
      /////////////////////////////////////////////////////////////////
      //---------------------INNER CLASSES-(each is commented with!!##)
      /////////////////////////////////////////////////////////////////
      
      //##############################################################//
      /*!!!!!!!!!!!!!!!!inner class DrawingPanel!!!!!!!!!!!!!!!!!!!!!!*/
      private class GamePanel extends JPanel{
        
        /*--CONSTRUCTOR for inner class GamePanel---*/
        public GamePanel(){
          setPreferredSize(new Dimension(400,400));
          setBackground(Color.red);  
          
        } // end GamePanel() constructor
        /*--PAINT_COMPONENT METHOD for GamePanel--*/ 
    //Trouble shoot here if there are issues##########################
        public void paintComponent(Graphics g){
          super.paintComponent(g);
          head.display(g);
          
        } // end paintComponent method
        
      } // end DrawingPanel class
      
      
      //#############################################################//
      /*!!!!!!!!!!!inner class BUTTON_LISTENER for buttons!!!!!!!!!!!*/
      private class ButtonListener implements ActionListener{
        public void actionPerformed(ActionEvent push) {
          
          //If source of event is timer calls move()
          if (push.getSource() ==timer){
            head.move();
            //System.out.println("Got to head.move()");
            if (!head.checkSafe()){
              timer.stop();
            }
            
          }else{
            JButton whichButton = (JButton) push.getSource();
            /* If start button has been pressed start the timer*/
            if((whichButton.getText()).equals("Start")){
              timer.start();
              
              /* If stop button has been pressed stop the timer*/
            }else if((whichButton.getText()).equals("Pause")){
              timer.stop();
              
            }else if((whichButton.getText()).equals("Speed up")){
              
              
            }else if((whichButton.getText()).equals("Slow Down")){
              
              
            }else if((whichButton.getText()).equals("Restart")){
              
              
            } // last button chain
          } // end if-else chain
          repaint();
          SnakePanel.setFocusable(true);
          
        } // end ActionListener method
      } // end ActionPerformed method
      
      /*!!!!!!!!!Inner Class Listener for key events!!!!!!!!!*/
      private class DirectionListener implements KeyListener{
        /* Responds to direction keys by changing the 
         * direction the snake head will move*/
        public void keyPressed (KeyEvent event){
          System.out.println("Registered a key event");
          switch (event.getKeyCode()){
            case KeyEvent.VK_UP:
              head.setMove(0, -10);          
              break;
            case KeyEvent.VK_DOWN:
              head.setMove(0, 10); 
              System.out.println("Registered the down arrow case");
              break;
            case KeyEvent.VK_RIGHT:
              head.setMove(10, 0); 
              break;
            case KeyEvent.VK_LEFT:
              head.setMove(-10, 0); 
              break;
          } // end switch statement
               
        } // end keyPressed 
        
        // Provide empty descriptions for unused methods
        public void keyTyped(KeyEvent event) {}
        public void keyReleased(KeyEvent event) {}
        
      } // end KeyListener
      
    } // end SnakePanel class

  • #2
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,978
    Thanks
    4
    Thanked 2,659 Times in 2,628 Posts
    Looks to me that its simply a problem with the focus.
    There are a few fixes, one would involve setting the keyListener on the frame itself, and another would simply be requesting it back. In the ButtonListener, simply add requestFocus(); as the final instruction in the actionPerformed. That will pass it back to the SnakePanel.

  • Users who have thanked Fou-Lu for this post:

    scottyavh (10-02-2012)

  • #3
    New to the CF scene
    Join Date
    Oct 2012
    Location
    New Zealand
    Posts
    2
    Thanks
    1
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by Fou-Lu View Post
    Looks to me that its simply a problem with the focus.
    There are a few fixes, one would involve setting the keyListener on the frame itself, and another would simply be requesting it back. In the ButtonListener, simply add requestFocus(); as the final instruction in the actionPerformed. That will pass it back to the SnakePanel.
    Thank you very much Fou-Lou, it works now! I had done a bit of looking around and thought it might be a simple fix but simply don't know enough about focus myself (first time I've come across it). Cheers!


  •  

    Tags for this Thread

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •