Skip to content

Instantly share code, notes, and snippets.

Created September 17, 2015 16:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/a55e9ab57b7f231ae93c to your computer and use it in GitHub Desktop.
Save anonymous/a55e9ab57b7f231ae93c to your computer and use it in GitHub Desktop.
package snake;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Random;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import javax.swing.JFrame;
import javax.swing.Timer;
import javax.swing.JPanel;
public class Snake implements ActionListener, KeyListener {
public static int width = 500;
public static int height = width / 16 * 12;
public JFrame frame;
public RenderPanel renderPanel;
public static Snake snake;
public Timer timer = new Timer(20, this); // infinite loop & listener;
public Point head, apple;
public ArrayList<Point> snakeParts = new ArrayList<Point>();
public Random random;
public static final int SPEED = 1, SCALE = 10, LEFT = 0, UP = 1, RIGHT = 2, DOWN = 3;
public int tick, direction = DOWN;
public static int tailLength = 0; // or 1;
public int XBOUND, YBOUND;
public boolean over, pause, keyPressed;
public static void main(String[] args) {
snake = new Snake();
}
/*CONSTRUCTOR*/
public Snake() {
frame = new JFrame("Snake");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(width, height);
frame.setVisible(true);
frame.setResizable(false);
frame.setLocationRelativeTo(null); // centering the screen;
frame.getContentPane().add(renderPanel = new RenderPanel());
frame.addKeyListener(this);
startGame();
}
public void startGame() {
XBOUND = frame.getWidth() / SCALE - 1; // set a boundary;
YBOUND = frame.getHeight() / SCALE - 3;
random = new Random();
over = false;
pause = false;
tick = 0;
apple = new Point (random.nextInt(XBOUND), random.nextInt(YBOUND));
snakeParts.clear();
head = new Point(0, 0);
snakeParts.add(new Point(head.x, head.y));
timer.start(); // infinite loop of actionPerformed() method;
}
@Override
public void actionPerformed(ActionEvent event) {
renderPanel.repaint();
tick++;
if (tick % SPEED == 0 && !over && !pause) {
/************************
POINT
*************************/
keyPressed = false;
if (snakeParts.size() >= tailLength && !over) { // over just for display, so that last tail won't be deleted if game over;
snakeParts.remove(0);
}
snakeParts.add(new Point(head.x, head.y));
switch (direction) {
case DOWN :
if (head.y + 1 < YBOUND && noTailInFront(head.x, head.y + 1)) { // if there is tail == death;
head = new Point(head.x, head.y + 1);
} else {
over = true;
}
break;
case RIGHT :
if (head.x + 1 < XBOUND && noTailInFront(head.x + 1, head.y)) {
head = new Point(head.x + 1, head.y);
} else {
over = true;
}
break;
case UP :
if (head.y - 1 >= 0 && noTailInFront(head.x, head.y - 1)) {
head = new Point(head.x, head.y - 1);
} else {
over = true;
}
break;
case LEFT :
if (head.x - 1 >= 0 && noTailInFront(head.x - 1, head.y)) {
head = new Point(head.x - 1, head.y);
} else {
over = true;
}
break;
} // switch direction
if (head.equals(apple)) {
snakeParts.add(head);
tailLength++;
apple = new Point (random.nextInt(XBOUND), random.nextInt(YBOUND));
}
} // end of tick
} // actionPerformed
public boolean noTailInFront (int x, int y) {
for (Point point : snakeParts) {
if (point.equals(new Point(x, y) ) ) {
return false;
}
}
return true;
}
@Override
public void keyPressed (KeyEvent key) {
int i = key.getKeyCode();
/************************
POINT
*************************/
if (keyPressed) { // key can be pressed only once per loop;
return; // by returning immediately after key is pressed;
}
if (i == KeyEvent.VK_RIGHT && direction != LEFT) {
direction = RIGHT;
keyPressed = true;
}
if (i == KeyEvent.VK_LEFT && direction != RIGHT) {
direction = LEFT;
keyPressed = true;
}
if (i == KeyEvent.VK_UP && direction != DOWN) {
direction = UP;
keyPressed = true;
}
if (i == KeyEvent.VK_DOWN && direction != UP) {
direction = DOWN;
keyPressed = true;
}
if (i == KeyEvent.VK_SPACE) {
if (!over) {
pause = !pause;
} else {
startGame();
}
}
} // keyPressed
@Override
public void keyReleased (KeyEvent key) { }
@Override
public void keyTyped (KeyEvent key) { }
}
/**************************
RENDER CLASS
***************************/
public class RenderPanel extends JPanel {
public void paintComponent(Graphics g) {
Snake snake = Snake.snake; // ref to same object (snake) of class Snake; (if we create new obj, it will cause infinite loop)
int length = snake.snakeParts.size();
g.setColor(Color.BLUE);
g.fillRect(0, 0, this.getWidth(), this.getHeight()); // as panel (class RenderPanel) size;
for (Point point : snake.snakeParts) {
if (point == snake.snakeParts.get(length - 1)) { // set head color distinctly from body;
g.setColor(Color.YELLOW);
g.fillRect(point.x * Snake.SCALE, point.y * Snake.SCALE, Snake.SCALE, Snake.SCALE);
} else {
g.setColor(Color.BLACK);
g.fillRect(point.x * Snake.SCALE, point.y * Snake.SCALE, Snake.SCALE, Snake.SCALE);
}
}
g.setColor(Color.RED);
g.fillOval(snake.apple.x * Snake.SCALE, snake.apple.y * Snake.SCALE, Snake.SCALE, Snake.SCALE);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment