0

I'm trying to make the game snake and have run into an issue. What I have is a class called Segment which is used to create the objects that hold the x- and y-positions and also the direction of the snake. The class extends JPanel and overrides the method paintComponent(). I then add an object of type Segment to a JFrame in a different class. The methods I have for moving/changing directions of the snake (actually just a square at the moment) work perfectly but my problem is this:

When the square gets to about half of the width of the frame or half of the height of the frame it stops being drawn. I have made the background of the JPanel light grey so I know that the square hasn't reached the end of the JPanel when it stops. Below is my simple paintComponent() method and the section in the class that extends JFrame where I add the object.

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    this.setBackground(Color.LIGHT_GRAY);
    g.setColor(Color.black);
    g.fillRect(xpos, ypos, width, height);
}

public Snake() {
        setLayout(new BorderLayout());
        addKeyListener(l);
        segment = new Segment(100, 100, Segment.Dir.RIGHT);
        segment.setPreferredSize(new Dimension(500,500));
        add(segment, BorderLayout.CENTER);
        timer.start();
        setVisible(true);
        pack();
        setTitle("Snake");
        setResizable(false);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }

I also know that the objects position doesn't stop being updated so it's just the drawing of the square in the entire panel/frame that's the issue. Appreciate any help!

Here's an MCVE:

import java.awt.*;
import javax.swing.*;

public class Segment extends JPanel {

private int width = 10;
private int height = 10;
private int xpos, ypos;
private Dir dir;

public enum Dir {
    LEFT, RIGHT, UP, DOWN;
}

public Segment() {
    xpos = 0;
    ypos = 0;
    dir = Dir.RIGHT;
}

public Segment(int x, int y, Dir d) {
    xpos = x;
    ypos = y;
    dir = d;
}

public Dir getDir() {
    return dir;
}
public void setDir(Dir d) {
    dir = d;
}
public void setX(int x) {
    xpos = x;
    repaint();
}
public void setY(int y) {
    ypos = y;
    repaint();
}
public int getX() {
    return xpos;
}
public int getY() {
    return ypos;
}

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    this.setBackground(Color.LIGHT_GRAY);
    g.setColor(Color.black);
    g.fillRect(xpos, ypos, width, height);
}
}

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Snake extends JFrame implements ActionListener {

Segment segment;
Timer timer = new Timer(50, this);

public Snake() {
    setLayout(new BorderLayout());
    setSize(500,500);
    segment = new Segment(100, 100, Segment.Dir.RIGHT);
    segment.setPreferredSize(new Dimension(getWidth(),getHeight()));
    add(segment, BorderLayout.CENTER);
    timer.start();
    setVisible(true);
    setTitle("Snake");
    setResizable(false);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setLocationRelativeTo(null);
}

    public void actionPerformed(ActionEvent e) {
    if (e.getSource() == timer) {
            segment.setX((segment.getX() + 4 + getWidth())%getWidth());
    }
}

public static void main(String[] arg) {
    new Snake();
}

}
4
  • try using paint instead of paint component and use getWidth() and getHeight()
    – Locke
    Commented Feb 15, 2018 at 20:30
  • Can you post a MCVE?
    – phflack
    Commented Feb 15, 2018 at 20:33
  • @Locke Overriding paintComponent should work here, especially if it works for other sizes being drawn
    – phflack
    Commented Feb 15, 2018 at 20:34
  • @phflack I've added a MCVE at the end of the question. Commented Feb 15, 2018 at 20:53

1 Answer 1

3

Don't override getX() and getY() of the Segment class.

Those are methods of all Swing components. They get the current location of the component within the parent container.

Use different method names to control the location of the painting of your snake. Since your variable names are xPos and yPos maybe use getXPos() and getYPos().

So what happens is that the snake is drawn at xPos/yPos relative to the Segment panel and the Segment panel is also drawn at xPos/yPos relative to its parent container.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.