My snake game keeps glitching, and it is going wayy too fast. how do i control t
ID: 666310 • Letter: M
Question
My snake game keeps glitching, and it is going wayy too fast. how do i control the speed, and how do i get it to stop glitching?
Snake.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Snake extends javax.swing.JFrame implements KeyListener, Runnable {
final static int BLOCK_SIZE = 20;
final static int screenX = 700;
final static int screenY = 400;
final static int length = 2;
int hiScore;
//Thread to repaint
Thread t = new Thread(this);
boolean stopped = false;
//Instance of logic class
SnakeLogic snake = new SnakeLogic(length);
public Snake() {
super("Snake");
t.start();
JPanel p = new JPanel();
p.setFocusable(true);
p.addKeyListener(this);
add(p);
setIgnoreRepaint(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(screenX, screenY);
setBackground(Color.WHITE);
setIconImage(new ImageIcon("icon.png").getImage());
setResizable(false);
setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Snake();
}
});
}
public void paint(Graphics g) {
Point2 food = snake.getFoodLocation();
g.clearRect(0, 0, screenX, screenY);
//draw snake
if (snake.lightsOut() == false) {
normalPaint(g);
} else {
lightsOffPaint(g);
}
//food drawn
g.setColor(new Color(34, 139, 34));
g.fillRect(BLOCK_SIZE * food.getX() + 10, BLOCK_SIZE * food.getY() + 10, BLOCK_SIZE, BLOCK_SIZE);
g.setColor(Color.BLACK);
//powerup drawn
if (snake.getPowerUpOnScreen() == true) {
Point2 powerUp = snake.getPowerUpLocation();
g.setColor(Color.RED);
g.fillRect(BLOCK_SIZE * powerUp.getX() + 10, BLOCK_SIZE * powerUp.getY() + 10, BLOCK_SIZE, BLOCK_SIZE);
g.setColor(Color.BLACK);
}
//score drawn
g.setFont(new Font("LucidaSans", Font.PLAIN, 16));
g.drawString("Score: " + snake.getScore(), 20, 50);
g.drawString("Hi-Score: " + hiScore, 20, 70);
}
public void normalPaint(Graphics g) {
Point2[] snakeLocation = snake.getLocation();
for (int j = 0; j < snake.getLength(); j++) {
//each block drawn individually, 20 is size of snake, -10 is to match window borders
g.fillRect(BLOCK_SIZE * snakeLocation[j].getX() + 10, BLOCK_SIZE * snakeLocation[j].getY() + 10, BLOCK_SIZE, BLOCK_SIZE);
}
}
public void lightsOffPaint(Graphics g) {
Point2[] snakeLocation = snake.getLocation();
g.setColor(Color.BLACK);
g.fillRect(0, 0, screenX, screenY);
g.setColor(Color.WHITE);
g.fillRect(BLOCK_SIZE * snakeLocation[0].getX() + 10, BLOCK_SIZE * snakeLocation[0].getY() + 10, BLOCK_SIZE, BLOCK_SIZE);
}
//KeyListener functions
public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
snake.setDirection(Direction.UP);
break;
case KeyEvent.VK_RIGHT:
snake.setDirection(Direction.RIGHT);
break;
case KeyEvent.VK_DOWN:
snake.setDirection(Direction.DOWN);
break;
case KeyEvent.VK_LEFT:
snake.setDirection(Direction.LEFT);
break;
}
}
public void keyReleased(KeyEvent e) {
}
public void run() {
long tick = System.currentTimeMillis();
while (!stopped) {
try {
t.sleep(snake.period);
} catch (InterruptedException e) {
}
snake.updateSnake();
if (snake.endGame()) {
try {
t.sleep(2000);
} catch (InterruptedException e) {
}
if (snake.getScore() > hiScore) {
hiScore = snake.getScore();
}
snake.init(length);
}
tick = System.currentTimeMillis();
repaint();
}
}
}
Point2.java
class Point2 {
private int x;
private int y;
public Point2() {
}
public Point2(int X, int Y) {
x = X;
y = Y;
}
public void setX(int X) {
x = X;
}
public void setY(int Y) {
y = Y;
}
public void setLocation(int X, int Y) {
x = X;
y = Y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
SnakeLogic.java
import java.util.Random;
enum Direction {
UP, DOWN, LEFT, RIGHT
};
public class SnakeLogic {
public static int period = 300;
int snakeLength;
int score;
int startLength;
final static int powerUpTime = 60;
boolean lightsOut;
int activePowerUpTime;
Point2[] snakeLocation;
Direction snakeDirection;
Direction soughtDirection;
Point2 food;
Random rand;
Point2 powerUp;
boolean powerUpOnScreen;
int powerUpCounter;
boolean fastSpeed;
public SnakeLogic(int startLength) {
init(startLength);
}
public void init(int length) {
rand = new Random();
food = new Point2();
powerUp = new Point2();
snakeLocation = new Point2[128];
snakeLength = length;
powerUpCounter = powerUpTime;
startLength = length;
score = 0;
powerUpOnScreen = false;
lightsOut = false;
snakeDirection = soughtDirection = Direction.RIGHT;
setStartLocation(10, 10);
setPointLocation(food);
powerUp = new Point2();
}
//By knowing where head of snake is we set the rest of its coordinates
private void setStartLocation(int x, int y) {
//Make sure not out of bounds
if (x > snakeLength) {
for (int j = 0; j < snakeLength; j++) {
snakeLocation[j] = new Point2((x - j), y);
}
} else {
System.out.print("ERROR: snakeLength too long.");
System.exit(0);
}
}
public Point2[] getLocation() {
return snakeLocation;
}
public boolean getPowerUpOnScreen() {
return powerUpOnScreen;
}
public int getLength() {
return snakeLength;
}
private void setPointLocation(Point2 item) {
int Xrand;
int Yrand;
do {
Xrand = rand.nextInt(33);
Yrand = rand.nextInt(17) + 1;
} while (checkCollisions(Xrand, Yrand, snakeLocation, 0) || checkPointCollision(Xrand, Yrand, food));
item.setLocation(Xrand, Yrand);
}
private boolean checkPointCollision(int x, int y, Point2 p) {
if (x == p.getX() && y == p.getY()) {
return true;
}
return false;
}
public Point2 getFoodLocation() {
return food;
}
public Point2 getPowerUpLocation() {
return powerUp;
}
public void moveSnake() {
//increase each point
for (int j = snakeLength - 1; j > 0; j--) {
snakeLocation[j].setX(snakeLocation[j - 1].getX());
snakeLocation[j].setY(snakeLocation[j - 1].getY());
}
}
public void updateSnake() {
Point2 nextPoint = getNextPoint(new Point2(snakeLocation[0].getX(), snakeLocation[0].getY()));
if (checkPowerUp(nextPoint)) {
nextPoint = getNextPoint(new Point2(snakeLocation[0].getX(), snakeLocation[0].getY()));
}
checkFood(nextPoint);
checkPowerUpTimeLeft();
finalDirectionCheck();
moveSnake();
snakeLocation[0].setX(nextPoint.getX());
snakeLocation[0].setY(nextPoint.getY());
}
private Point2 getNextPoint(Point2 point) {
switch (snakeDirection) {
case RIGHT:
point.setX(point.getX() + 1);
break;
case UP:
point.setY(point.getY() - 1);
break;
case DOWN:
point.setY(point.getY() + 1);
break;
case LEFT:
point.setX(point.getX() - 1);
break;
}
//check borders
if (point.getX() < 0) {
point.setX(33);
}
if (point.getX() > 33) {
point.setX(0);
}
if (point.getY() < 1) {
point.setY(18);
}
if (point.getY() > 18) {
point.setY(1);
}
return point;
}
//loop through array too see if coordinate (x, y) is there start is the starting point of checking (0 is head, 1 is else)
private boolean checkCollisions(int x, int y, Point2[] array, int start) {
for (int j = start; j < snakeLength; j++) {
if (array[j].getX() == x && array[j].getY() == y) {
return true;
}
}
return false;
}
private void checkFood(Point2 point) {
if (food.getX() == point.getX() && food.getY() == point.getY()) {
score++;
setPointLocation(food);
snakeLength += 1;
snakeLocation[snakeLength - 1] = new Point2();
if (score % 10 == 0) {
powerUpOnScreen = true;
powerUp = new Point2();
setPointLocation(powerUp);
}
}
}
public boolean checkPowerUp(Point2 point) {
if (getPowerUpOnScreen()) {
if (powerUp.getX() == point.getX() && powerUp.getY() == point.getY()) {
activatePowerUp();
score += 5;
powerUpCounter = powerUpTime;
powerUpOnScreen = false;
powerUp = null;
return true;
}
//make counter
if (powerUpCounter-- == 0) {
powerUpOnScreen = false;
powerUp = null;
powerUpCounter = powerUpTime;
}
}
return false;
}
private void activatePowerUp() {
int randNum = rand.nextInt(3);
switch (randNum) {
case 0:
activateReverse();
break;
case 1:
activateLightsOut();
break;
case 2:
activateFastSpeed();
break;
default:
break;
}
}
private void activateLightsOut() {
lightsOut = true;
activePowerUpTime = 100;
}
private void activateReverse() {
int tempX;
int tempY;
for (int h = 0; h < snakeLength / 2; h++) {
tempX = snakeLocation[h].getX();
snakeLocation[h].setX(snakeLocation[snakeLength - h - 1].getX());
snakeLocation[snakeLength - h - 1].setX(tempX);
tempY = snakeLocation[h].getY();
snakeLocation[h].setY(snakeLocation[snakeLength - h - 1].getY());
snakeLocation[snakeLength - h - 1].setY(tempY);
}
reverseDirection();
}
private void activateFastSpeed() {
activePowerUpTime = 125;
period = 30;
}
private void activateSlowSpeed() {
activePowerUpTime = 25;
period = 120;
}
private void reverseDirection() {
if (snakeLocation[0].getX() + 1 == snakeLocation[1].getX()) {
snakeDirection = Direction.LEFT;
}
if (snakeLocation[0].getX() - 1 == snakeLocation[1].getX()) {
snakeDirection = Direction.RIGHT;
}
if (snakeLocation[0].getY() + 1 == snakeLocation[1].getY()) {
snakeDirection = Direction.UP;
}
if (snakeLocation[0].getY() - 1 == snakeLocation[1].getY()) {
snakeDirection = Direction.DOWN;
}
}
public boolean lightsOut() {
return lightsOut;
}
public void checkPowerUpTimeLeft() {
if (activePowerUpTime-- < 1) {
lightsOut = false;
period = 60;
}
}
public boolean endGame() {
if (checkCollisions(snakeLocation[0].getX(), snakeLocation[0].getY(), snakeLocation, 1)) {
return true;
}
return false;
}
public int getScore() {
return score;
}
public void setDirection(Direction d) {
boolean allow = true;
switch (snakeDirection) {
case RIGHT:
if (d == Direction.LEFT) {
allow = false;
}
break;
case UP:
if (d == Direction.DOWN) {
allow = false;
}
break;
case DOWN:
if (d == Direction.UP) {
allow = false;
}
break;
case LEFT:
if (d == Direction.RIGHT) {
allow = false;
}
break;
}
if (allow) {
soughtDirection = d;
}
}
private void finalDirectionCheck() {
boolean allow = true;
switch (snakeDirection) {
case RIGHT:
if (soughtDirection == Direction.LEFT) {
allow = false;
}
break;
case UP:
if (soughtDirection == Direction.DOWN) {
allow = false;
}
break;
case DOWN:
if (soughtDirection == Direction.UP) {
allow = false;
}
break;
case LEFT:
if (soughtDirection == Direction.RIGHT) {
allow = false;
}
break;
}
if (allow) {
snakeDirection = soughtDirection;
}
}
//deprecated method for testing
/*
private void printSnake(Point2[] array) {
for (int j = 0; j < snakeLength; j++) {
System.out.println("Ar: " + j + " [" + array[j].getX() + "]" + "[" + array[j].getY() + "]");
}
}
*/
}
Explanation / Answer
Snake.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Snake extends javax.swing.JFrame implements KeyListener, Runnable {
final static int BLOCK_SIZE = 20;
final static int screenX = 700;
final static int screenY = 400;
final static int length = 2;
int hiScore;
//Thread to repaint
Thread t = new Thread(this);
boolean stopped = false;
//Instance of logic class
SnakeLogic snake = new SnakeLogic(length);
public Snake() {
super("Snake");
t.start();
JPanel p = new JPanel();
p.setFocusable(true);
p.addKeyListener(this);
add(p);
setIgnoreRepaint(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(screenX, screenY);
setBackground(Color.WHITE);
setIconImage(new ImageIcon("icon.png").getImage());
setResizable(false);
setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Snake();
}
});
}
public void paint(Graphics g) {
Point2 food = snake.getFoodLocation();
g.clearRect(0, 0, screenX, screenY);
//draw snake
if (snake.lightsOut() == false) {
normalPaint(g);
} else {
lightsOffPaint(g);
}
//food drawn
g.setColor(new Color(34, 139, 34));
g.fillRect(BLOCK_SIZE * food.getX() + 10, BLOCK_SIZE * food.getY() + 10, BLOCK_SIZE, BLOCK_SIZE);
g.setColor(Color.BLACK);
//powerup drawn
if (snake.getPowerUpOnScreen() == true) {
Point2 powerUp = snake.getPowerUpLocation();
g.setColor(Color.RED);
g.fillRect(BLOCK_SIZE * powerUp.getX() + 10, BLOCK_SIZE * powerUp.getY() + 10, BLOCK_SIZE, BLOCK_SIZE);
g.setColor(Color.BLACK);
}
//score drawn
g.setFont(new Font("LucidaSans", Font.PLAIN, 16));
g.drawString("Score: " + snake.getScore(), 20, 50);
g.drawString("Hi-Score: " + hiScore, 20, 70);
}
public void normalPaint(Graphics g) {
Point2[] snakeLocation = snake.getLocation();
for (int j = 0; j < snake.getLength(); j++) {
//each block drawn individually, 20 is size of snake, -10 is to match window borders
g.fillRect(BLOCK_SIZE * snakeLocation[j].getX() + 10, BLOCK_SIZE * snakeLocation[j].getY() + 10, BLOCK_SIZE, BLOCK_SIZE);
}
}
public void lightsOffPaint(Graphics g) {
Point2[] snakeLocation = snake.getLocation();
g.setColor(Color.BLACK);
g.fillRect(0, 0, screenX, screenY);
g.setColor(Color.WHITE);
g.fillRect(BLOCK_SIZE * snakeLocation[0].getX() + 10, BLOCK_SIZE * snakeLocation[0].getY() + 10, BLOCK_SIZE, BLOCK_SIZE);
}
//KeyListener functions
public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
snake.setDirection(Direction.UP);
break;
case KeyEvent.VK_RIGHT:
snake.setDirection(Direction.RIGHT);
break;
case KeyEvent.VK_DOWN:
snake.setDirection(Direction.DOWN);
break;
case KeyEvent.VK_LEFT:
snake.setDirection(Direction.LEFT);
break;
}
}
public void keyReleased(KeyEvent e) {
}
public void run() {
long tick = System.currentTimeMillis();
while (!stopped) {
try {
t.sleep(snake.period);
} catch (InterruptedException e) {
}
snake.updateSnake();
if (snake.endGame()) {
try {
t.sleep(2000);
} catch (InterruptedException e) {
}
if (snake.getScore() > hiScore) {
hiScore = snake.getScore();
}
snake.init(length);
}
tick = System.currentTimeMillis();
repaint();
}
}
}
Point2.java
class Point2 {
private int x;
private int y;
public Point2() {
}
public Point2(int X, int Y) {
x = X;
y = Y;
}
public void setX(int X) {
x = X;
}
public void setY(int Y) {
y = Y;
}
public void setLocation(int X, int Y) {
x = X;
y = Y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
SnakeLogic.java
import java.util.Random;
enum Direction {
UP, DOWN, LEFT, RIGHT
};
public class SnakeLogic {
public static int period = 300;
int snakeLength;
int score;
int startLength;
final static int powerUpTime = 60;
boolean lightsOut;
int activePowerUpTime;
Point2[] snakeLocation;
Direction snakeDirection;
Direction soughtDirection;
Point2 food;
Random rand;
Point2 powerUp;
boolean powerUpOnScreen;
int powerUpCounter;
boolean fastSpeed;
public SnakeLogic(int startLength) {
init(startLength);
}
public void init(int length) {
rand = new Random();
food = new Point2();
powerUp = new Point2();
snakeLocation = new Point2[128];
snakeLength = length;
powerUpCounter = powerUpTime;
startLength = length;
score = 0;
powerUpOnScreen = false;
lightsOut = false;
snakeDirection = soughtDirection = Direction.RIGHT;
setStartLocation(10, 10);
setPointLocation(food);
powerUp = new Point2();
}
//By knowing where head of snake is we set the rest of its coordinates
private void setStartLocation(int x, int y) {
//Make sure not out of bounds
if (x > snakeLength) {
for (int j = 0; j < snakeLength; j++) {
snakeLocation[j] = new Point2((x - j), y);
}
} else {
System.out.print("ERROR: snakeLength too long.");
System.exit(0);
}
}
public Point2[] getLocation() {
return snakeLocation;
}
public boolean getPowerUpOnScreen() {
return powerUpOnScreen;
}
public int getLength() {
return snakeLength;
}
private void setPointLocation(Point2 item) {
int Xrand;
int Yrand;
do {
Xrand = rand.nextInt(33);
Yrand = rand.nextInt(17) + 1;
} while (checkCollisions(Xrand, Yrand, snakeLocation, 0) || checkPointCollision(Xrand, Yrand, food));
item.setLocation(Xrand, Yrand);
}
private boolean checkPointCollision(int x, int y, Point2 p) {
if (x == p.getX() && y == p.getY()) {
return true;
}
return false;
}
public Point2 getFoodLocation() {
return food;
}
public Point2 getPowerUpLocation() {
return powerUp;
}
public void moveSnake() {
//increase each point
for (int j = snakeLength - 1; j > 0; j--) {
snakeLocation[j].setX(snakeLocation[j - 1].getX());
snakeLocation[j].setY(snakeLocation[j - 1].getY());
}
}
public void updateSnake() {
Point2 nextPoint = getNextPoint(new Point2(snakeLocation[0].getX(), snakeLocation[0].getY()));
if (checkPowerUp(nextPoint)) {
nextPoint = getNextPoint(new Point2(snakeLocation[0].getX(), snakeLocation[0].getY()));
}
checkFood(nextPoint);
checkPowerUpTimeLeft();
finalDirectionCheck();
moveSnake();
snakeLocation[0].setX(nextPoint.getX());
snakeLocation[0].setY(nextPoint.getY());
}
private Point2 getNextPoint(Point2 point) {
switch (snakeDirection) {
case RIGHT:
point.setX(point.getX() + 1);
break;
case UP:
point.setY(point.getY() - 1);
break;
case DOWN:
point.setY(point.getY() + 1);
break;
case LEFT:
point.setX(point.getX() - 1);
break;
}
//check borders
if (point.getX() < 0) {
point.setX(33);
}
if (point.getX() > 33) {
point.setX(0);
}
if (point.getY() < 1) {
point.setY(18);
}
if (point.getY() > 18) {
point.setY(1);
}
return point;
}
//loop through array too see if coordinate (x, y) is there start is the starting point of checking (0 is head, 1 is else)
private boolean checkCollisions(int x, int y, Point2[] array, int start) {
for (int j = start; j < snakeLength; j++) {
if (array[j].getX() == x && array[j].getY() == y) {
return true;
}
}
return false;
}
private void checkFood(Point2 point) {
if (food.getX() == point.getX() && food.getY() == point.getY()) {
score++;
setPointLocation(food);
snakeLength += 1;
snakeLocation[snakeLength - 1] = new Point2();
if (score % 10 == 0) {
powerUpOnScreen = true;
powerUp = new Point2();
setPointLocation(powerUp);
}
}
}
public boolean checkPowerUp(Point2 point) {
if (getPowerUpOnScreen()) {
if (powerUp.getX() == point.getX() && powerUp.getY() == point.getY()) {
activatePowerUp();
score += 5;
powerUpCounter = powerUpTime;
powerUpOnScreen = false;
powerUp = null;
return true;
}
//make counter
if (powerUpCounter-- == 0) {
powerUpOnScreen = false;
powerUp = null;
powerUpCounter = powerUpTime;
}
}
return false;
}
private void activatePowerUp() {
int randNum = rand.nextInt(3);
switch (randNum) {
case 0:
activateReverse();
break;
case 1:
activateLightsOut();
break;
case 2:
activateFastSpeed();
break;
default:
break;
}
}
private void activateLightsOut() {
lightsOut = true;
activePowerUpTime = 100;
}
private void activateReverse() {
int tempX;
int tempY;
for (int h = 0; h < snakeLength / 2; h++) {
tempX = snakeLocation[h].getX();
snakeLocation[h].setX(snakeLocation[snakeLength - h - 1].getX());
snakeLocation[snakeLength - h - 1].setX(tempX);
tempY = snakeLocation[h].getY();
snakeLocation[h].setY(snakeLocation[snakeLength - h - 1].getY());
snakeLocation[snakeLength - h - 1].setY(tempY);
}
reverseDirection();
}
private void activateFastSpeed() {
activePowerUpTime = 125;
period = 30;
}
private void activateSlowSpeed() {
activePowerUpTime = 25;
period = 120;
}
private void reverseDirection() {
if (snakeLocation[0].getX() + 1 == snakeLocation[1].getX()) {
snakeDirection = Direction.LEFT;
}
if (snakeLocation[0].getX() - 1 == snakeLocation[1].getX()) {
snakeDirection = Direction.RIGHT;
}
if (snakeLocation[0].getY() + 1 == snakeLocation[1].getY()) {
snakeDirection = Direction.UP;
}
if (snakeLocation[0].getY() - 1 == snakeLocation[1].getY()) {
snakeDirection = Direction.DOWN;
}
}
public boolean lightsOut() {
return lightsOut;
}
public void checkPowerUpTimeLeft() {
if (activePowerUpTime-- < 1) {
lightsOut = false;
period = 60;
}
}
public boolean endGame() {
if (checkCollisions(snakeLocation[0].getX(), snakeLocation[0].getY(), snakeLocation, 1)) {
return true;
}
return false;
}
public int getScore() {
return score;
}
public void setDirection(Direction d) {
boolean allow = true;
switch (snakeDirection) {
case RIGHT:
if (d == Direction.LEFT) {
allow = false;
}
break;
case UP:
if (d == Direction.DOWN) {
allow = false;
}
break;
case DOWN:
if (d == Direction.UP) {
allow = false;
}
break;
case LEFT:
if (d == Direction.RIGHT) {
allow = false;
}
break;
}
if (allow) {
soughtDirection = d;
}
}
private void finalDirectionCheck() {
boolean allow = true;
switch (snakeDirection) {
case RIGHT:
if (soughtDirection == Direction.LEFT) {
allow = false;
}
break;
case UP:
if (soughtDirection == Direction.DOWN) {
allow = false;
}
break;
case DOWN:
if (soughtDirection == Direction.UP) {
allow = false;
}
break;
case LEFT:
if (soughtDirection == Direction.RIGHT) {
allow = false;
}
break;
}
if (allow) {
snakeDirection = soughtDirection;
}
}
private void printSnake(Point2[] array) {
for (int j = 0; j < snakeLength; j++) {
System.out.println("Ar: " + j + " [" + array[j].getX() + "]" + "[" + array[j].getY() + "]");
}
}
*/
}
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.