08.
25 11:06 PM
import [Link].*;
import [Link].*;
import [Link];
import [Link];
import [Link].*;
public class SnakeGame extends JPanel implements ActionListener, KeyListener {
private class Tile {
int x;
int y;
Tile(int x, int y) {
this.x = x;
this.y = y;
}
}
int boardWidth;
int boardHeight;
int tileSize = 25;
//snake
Tile snakeHead;
ArrayList<Tile> snakeBody;
//food
Tile food;
Random random;
//game logic
int velocityX;
int velocityY;
Timer gameLoop;
boolean gameOver = false;
SnakeGame(int boardWidth, int boardHeight) {
[Link] = boardWidth;
[Link] = boardHeight;
setPreferredSize(new Dimension([Link], [Link]));
setBackground([Link]);
addKeyListener(this);
setFocusable(true);
snakeHead = new Tile(5, 5);
snakeBody = new ArrayList<Tile>();
food = new Tile(10, 10);
random = new Random();
placeFood();
velocityX = 1;
velocityY = 0;
//game timer
gameLoop = new Timer(100, this); //how long it takes to start timer,
milliseconds gone between frames
[Link]();
}
public void paintComponent(Graphics g) {
[Link](g);
draw(g);
}
public void draw(Graphics g) {
//Grid Lines
for(int i = 0; i < boardWidth/tileSize; i++) {
//(x1, y1, x2, y2)
[Link](i*tileSize, 0, i*tileSize, boardHeight);
[Link](0, i*tileSize, boardWidth, i*tileSize);
}
//Food
[Link]([Link]);
// [Link](food.x*tileSize, food.y*tileSize, tileSize, tileSize);
g.fill3DRect(food.x*tileSize, food.y*tileSize, tileSize, tileSize, true);
//Snake Head
[Link]([Link]);
// [Link](snakeHead.x, snakeHead.y, tileSize, tileSize);
// [Link](snakeHead.x*tileSize, snakeHead.y*tileSize, tileSize,
tileSize);
g.fill3DRect(snakeHead.x*tileSize, snakeHead.y*tileSize, tileSize,
tileSize, true);
//Snake Body
for (int i = 0; i < [Link](); i++) {
Tile snakePart = [Link](i);
// [Link](snakePart.x*tileSize, snakePart.y*tileSize, tileSize,
tileSize);
g.fill3DRect(snakePart.x*tileSize, snakePart.y*tileSize, tileSize,
tileSize, true);
}
//Score
[Link](new Font("Arial", [Link], 16));
if (gameOver) {
[Link]([Link]);
[Link]("Game Over: " + [Link]([Link]()), tileSize
- 16, tileSize);
}
else {
[Link]("Score: " + [Link]([Link]()), tileSize -
16, tileSize);
}
}
public void placeFood(){
food.x = [Link](boardWidth/tileSize);
food.y = [Link](boardHeight/tileSize);
}
public void move() {
//eat food
if (collision(snakeHead, food)) {
[Link](new Tile(food.x, food.y));
placeFood();
}
//move snake body
for (int i = [Link]()-1; i >= 0; i--) {
Tile snakePart = [Link](i);
if (i == 0) { //right before the head
snakePart.x = snakeHead.x;
snakePart.y = snakeHead.y;
}
else {
Tile prevSnakePart = [Link](i-1);
snakePart.x = prevSnakePart.x;
snakePart.y = prevSnakePart.y;
}
}
//move snake head
snakeHead.x += velocityX;
snakeHead.y += velocityY;
//game over conditions
for (int i = 0; i < [Link](); i++) {
Tile snakePart = [Link](i);
//collide with snake head
if (collision(snakeHead, snakePart)) {
gameOver = true;
}
}
if (snakeHead.x*tileSize < 0 || snakeHead.x*tileSize > boardWidth ||
//passed left border or right border
snakeHead.y*tileSize < 0 || snakeHead.y*tileSize > boardHeight ) {
//passed top border or bottom border
gameOver = true;
}
}
public boolean collision(Tile tile1, Tile tile2) {
return tile1.x == tile2.x && tile1.y == tile2.y;
}
@Override
public void actionPerformed(ActionEvent e) { //called every x milliseconds by
gameLoop timer
move();
repaint();
if (gameOver) {
[Link]();
}
}
@Override
public void keyPressed(KeyEvent e) {
// [Link]("KeyEvent: " + [Link]());
if ([Link]() == KeyEvent.VK_UP && velocityY != 1) {
velocityX = 0;
velocityY = -1;
}
else if ([Link]() == KeyEvent.VK_DOWN && velocityY != -1) {
velocityX = 0;
velocityY = 1;
}
else if ([Link]() == KeyEvent.VK_LEFT && velocityX != 1) {
velocityX = -1;
velocityY = 0;
}
else if ([Link]() == KeyEvent.VK_RIGHT && velocityX != -1) {
velocityX = 1;
velocityY = 0;
}
}
//not needed
@Override
public void keyTyped(KeyEvent e) {}
@Override
public void keyReleased(KeyEvent e) {}
}