import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class Snake extends JFrame {
private SnakePanel snakePanel = new SnakePanel();
private static final long serialVersionUID = 2L;
private JPanel controlPanel = new JPanel();
private JButton jbtNewGame = new JButton("New Game");
public Snake() {
// when window isn't not user's active window, pause the game. When window is activated again, restart the game again.
this.addWindowListener(new WindowAdapter() {
public void windowDeactivated(WindowEvent event) {
if (snakePanel.isGameRunning())
snakePanel.stopGame();
}
public void windowActivated(WindowEvent event) {
if(!snakePanel.isGameRunning())
snakePanel.startGame();
}
});
jbtNewGame.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
snakePanel.newGame();
snakePanel.setFocusable(true);
snakePanel.requestFocusInWindow();
}
});
controlPanel.add(jbtNewGame);
add(controlPanel, BorderLayout.NORTH);
add(snakePanel, BorderLayout.CENTER);
jbtNewGame.setFocusable(false);
snakePanel.setFocusable(true);
snakePanel.requestFocusInWindow();
snakePanel.newGame();
}
public static void main(String[] args) {
Snake frame = new Snake();
frame.setTitle("Snake Game");
frame.setSize(560, 600);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
class SnakePanel extends JPanel {
private static final long serialVersionUID = 1L;
private int row = 50;
private int column = 50;
private boolean gameStatue = true;
private boolean canType = true; // when pressed a keyboard, you must wait to fire a timer event to press next keyboard
private int[] spot = new int[2]; // record spot's coordinate
private int direct = 0; // 0 for down, 1 for right, 2 for left, 3 for up
private int snakeLength = 4;
private int[][] snakeCell = new int[snakeLength][2]; // record snake coordinate, snakeCell[i][0] for row number, snakeCell[i][1] for column number
private int[] endPoint = new int[2]; // record the end point's coordinate of snake
private int timeDelay = 150;
private Timer time = new Timer(timeDelay, new TimeListener());
public SnakePanel() {
addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (canType) {
switch (e.getKeyCode()) {
case KeyEvent.VK_DOWN:
if (direct == 0)
time.setDelay(timeDelay / 2);
else if (direct != 3)
direct = 0;
break;
case KeyEvent.VK_UP:
if (direct == 3)
time.setDelay(timeDelay / 2);
else if (direct != 0)
direct = 3;
break;
case KeyEvent.VK_RIGHT:
if (direct == 1)
time.setDelay(timeDelay / 2);
else if (direct != 2)
direct = 1;
break;
case KeyEvent.VK_LEFT:
if (direct == 2)
time.setDelay(timeDelay / 2);
else if (direct != 1)
direct = 2;
break;
}
}
canType = false;
}
public void keyReleased(KeyEvent e) {
time.setDelay(timeDelay);
}
});
setSpot();
}
private void setSpot() {
do {
spot[0] = (int)(Math.random() * row);
spot[1] = (int)(Math.random() * column);
} while (isSnake(spot[0], spot[1]));
}
private void inialSnake() {
snakeLength = 4;
snakeCell = new int[snakeLength][2];
endPoint = new int[2];
snakeCell[0][0] = row / 2;
snakeCell[0][1] = column / 2;
for (int i = 1; i < snakeLength; i++) {
snakeCell[i][0] = row / 2 - i;
snakeCell[i][1] = column / 2;
}
}
private boolean isInBound(int x, int y) {
return x >= 0 && x < row && y >= 0 && y < column;
}
private boolean isCrash() {
for (int i = 1; i < snakeCell.length; i++) {
if (snakeCell[0][0] == snakeCell[i][0] && snakeCell[0][1] == snakeCell[i][1])
return true;
}
return false;
}
private boolean isSnake(int x, int y) {
for (int i = 0; i < snakeCell.length; i++)
if (x == snakeCell[i][0] && y == snakeCell[i][1])
return true;
return false;
}
class TimeListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
if (gameStatue) {
switch (direct) {
case 0:
setNewSnake();
snakeCell[0][0]++;
if (snakeCell[0][0] == spot[0] && snakeCell[0][1] == spot[1])
eatSpot();
repaint();
if (!isInBound(snakeCell[0][0], snakeCell[0][1]) || isCrash()) {
gameStatue = false;
time.stop();
JOptionPane.showMessageDialog(null,"Game Over");
}
break;
case 1:
setNewSnake();
snakeCell[0][1]++;
if (snakeCell[0][0] == spot[0] && snakeCell[0][1] == spot[1])
eatSpot();
repaint();
if (!isInBound(snakeCell[0][0], snakeCell[0][1]) || isCrash()) {
gameStatue = false;
time.stop();
JOptionPane.showMessageDialog(null,"Game Over");
}
break;
case 2:
setNewSnake();
snakeCell[0][1]--;
if (snakeCell[0][0] == spot[0] && snakeCell[0][1] == spot[1])
eatSpot();
repaint();
if (!isInBound(snakeCell[0][0], snakeCell[0][1]) || isCrash()) {
gameStatue = false;
time.stop();
JOptionPane.showMessageDialog(null,"Game Over");
}
break;
case 3:
setNewSnake();
snakeCell[0][0]--;
if (snakeCell[0][0] == spot[0] && snakeCell[0][1] == spot[1])
eatSpot();
repaint();
if (!isInBound(snakeCell[0][0], snakeCell[0][1]) || isCrash()) {
gameStatue = false;
time.stop();
JOptionPane.showMessageDialog(null,"Game Over");
}
break;
}
if (!canType)
canType = true;
}
}
}
private void setNewSnake() {
endPoint[0] = snakeCell[snakeCell.length - 1][0];
endPoint[1] = snakeCell[snakeCell.length - 1][1];
for (int i = snakeLength - 1; i >= 1; i--) {
snakeCell[i][0] = snakeCell[i - 1][0];
snakeCell[i][1] = snakeCell[i - 1][1];
}
}
private void eatSpot() {
int[][] temp = new int[snakeCell.length][2];
System.arraycopy(snakeCell, 0, temp, 0, snakeCell.length);
snakeLength++;
snakeCell = new int[snakeLength][2];
System.arraycopy(temp, 0, snakeCell, 0, temp.length);
snakeCell[snakeCell.length - 1][0] = endPoint[0];
snakeCell[snakeCell.length - 1][1] = endPoint[1];
setSpot();
}
protected void paintComponent(Graphics g) {
super.paintComponents(g);
int xStart = (int)(getWidth() * 0.05);
int yStart = (int)(getHeight() * 0.05);
int xEnd = (int)(getWidth() * 0.95);
int yEnd = (int)(getHeight() * 0.95);
double width = getWidth() * 0.9;
double height = getHeight() * 0.9;
double cellWidth = width / column;
double cellHeight = height / row;
// draw background
g.setColor(Color.WHITE);
g.fillRect(0, 0, getWidth(), getHeight());
// draw bound line
g.setColor(Color.BLACK);
g.drawLine(xStart, yStart, xStart, yEnd);
g.drawLine(xStart, yStart, xEnd, yStart);
g.drawLine(xEnd, yStart, xEnd, yEnd);
g.drawLine(xStart, yEnd, xEnd, yEnd);
//draw snake and spot
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
if (isSnake(i, j)){
g.setColor(Color.BLUE);
g.drawLine((int)(xStart + j * cellWidth), (int)(yStart + i * cellHeight), (int)(xStart + (j + 1) * cellWidth), (int)(yStart + i * cellHeight));
g.drawLine((int)(xStart + j * cellWidth), (int)(yStart + i * cellHeight), (int)(xStart + j * cellWidth), (int)(yStart + (i + 1) * cellHeight));
g.drawLine((int)(xStart + (j + 1) * cellWidth), (int)(yStart + i * cellHeight), (int)(xStart + (j + 1) * cellWidth), (int)(yStart + (i + 1) * cellHeight));
g.drawLine((int)(xStart + j * cellWidth), (int)(yStart + (i + 1) * cellHeight), (int)(xStart + (j + 1) * cellWidth), (int)(yStart + (i + 1) * cellHeight));
}
else if (i == spot[0] && j == spot[1]) {
g.setColor(Color.GREEN);
g.drawLine((int)(xStart + j * cellWidth), (int)(yStart + i * cellHeight), (int)(xStart + (j + 1) * cellWidth), (int)(yStart + i * cellHeight));
g.drawLine((int)(xStart + j * cellWidth), (int)(yStart + i * cellHeight), (int)(xStart + j * cellWidth), (int)(yStart + (i + 1) * cellHeight));
g.drawLine((int)(xStart + (j + 1) * cellWidth), (int)(yStart + i * cellHeight), (int)(xStart + (j + 1) * cellWidth), (int)(yStart + (i + 1) * cellHeight));
g.drawLine((int)(xStart + j * cellWidth), (int)(yStart + (i + 1) * cellHeight), (int)(xStart + (j + 1) * cellWidth), (int)(yStart + (i + 1) * cellHeight));
}
}
}
}
public int getRow() {
return row;
}
public void setRow(int row) {
this.row = row;
}
public int getColumn() {
return column;
}
public void setColumn(int column) {
this.column = column;
}
public void newGame() {
gameStatue = true;
inialSnake();
setSpot();
direct = 0;
time.start();
}
public void startGame() {
time.start();
}
public boolean isGameRunning() {
return time.isRunning();
}
public void stopGame() {
time.stop();
}
public void setSpeed(int t) {
timeDelay = t;
time.setDelay(timeDelay);
}
public void setDirect(int direct) {
this.direct = direct;
}
}
贪吃蛇的java程序
最新推荐文章于 2024-05-10 07:47:00 发布