package 贪吃蛇;
import java.awt.Color;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.font.TextAttribute;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.AttributedString;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
import javax.swing.JSlider;
import javax.swing.border.LineBorder;
public class Snake extends JFrame implements KeyListener, Runnable {
/**
*
*/
public Snake(int rows, int cols) {
super("XnakeS");
load = new loadframe();
setROWS(rows);
setCOLS(cols);
setUndecorated(true);
setIconImage(logo);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setAlwaysOnTop(true);
setResizable(false);
initXnakes();
addKeyListener(this);
setSize(ROWS * BLOCK, COLS * BLOCK);
setLocationRelativeTo(rootPane);
}
@Override
public void paint(Graphics g) {
int nake = eggcnt % xnake.length;
bImage = createImage(ROWS * BLOCK, COLS * BLOCK);
bGraphics = (Graphics2D) bImage.getGraphics();
bGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// 画背景图片
bGraphics.setPaint(new GradientPaint(new Point2D.Float(0, 0),
snakeColor[nake], new Point2D.Float(getWidth(), getHeight()),
Color.black));
bGraphics.fillRect(0, 0, getWidth(), getHeight());
// 画蛇图片800*600区域
bGraphics.drawImage(xnake[nake],
(getWidth() - xnake[nake].getWidth()) / 2,
(getHeight() - xnake[nake].getHeight()) / 2, null);
String scoresStrin = new String("Score: " + eggcnt);// 画当前分数
AttributedString scoreString = new AttributedString(scoresStrin);
scoreString.addAttribute(TextAttribute.FONT, scoreFont);
scoreString.addAttribute(TextAttribute.FONT, numberfont, 7,
scoresStrin.length());
scoreString.addAttribute(TextAttribute.UNDERLINE,
TextAttribute.UNDERLINE_ON, 7, scoresStrin.length());
scoreString.addAttribute(TextAttribute.FOREGROUND, Color.red, 7,
scoresStrin.length());
scoreString.addAttribute(TextAttribute.FOREGROUND, Color.gray, 0, 7);
bGraphics.drawString(scoreString.getIterator(), 750, 100);
bGraphics.drawImage(egg, eggPoint.x * BLOCK, eggPoint.y * BLOCK, BLOCK,
BLOCK, null);
int naks = xnakes.size() - 1;// 画蛇身
bGraphics.drawImage(head, xnakes.get(naks).x * BLOCK,
xnakes.get(naks).y * BLOCK, BLOCK, BLOCK, null);
while (0 < (naks--)) {
bGraphics.drawImage(egg, xnakes.get(naks).x * BLOCK,
xnakes.get(naks).y * BLOCK, BLOCK, BLOCK, null);
}
g.drawImage(bImage, 0, 0, rootPane);
};
static Snake snake = new Snake(64, 36);
public static void main(String[] args) {
mainThreak = new Thread(snake);
}
static Thread mainThreak;
@Override
public void run() {
try {
while (true) {
Thread.sleep(difficulty);
creep();
repaint();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void initXnakes() {
xnakes = new ArrayList<Point>(20);
moveDirection = Right;
setEgg();
setEggcnt(0);
xnakes.add(new Point(5, COLS / 3));
xnakes.add(new Point(6, COLS / 3));
xnakes.add(new Point(7, COLS / 3));
}
public void setEgg() {
Point eggPoint = new Point((int) Math.ceil(Math.random() * ROWS - 1),
(int) Math.ceil(Math.random() * COLS - 1));
while (xnakes.contains(eggPoint)) {
eggPoint = new Point((int) Math.ceil(Math.random() * ROWS - 1),
(int) Math.ceil(Math.random() * COLS - 1));
}
setEggPoint(eggPoint);
}
private void creep() {
switch (moveDirection) {// 根据移动方向添加一个点
case Left:
xnakes.add(new Point(
(xnakes.get(xnakes.size() - 1).x - 1) < 0 ? ROWS - 1
: (xnakes.get(xnakes.size() - 1).x - 1), xnakes
.get(xnakes.size() - 1).y));// 添加一个蛇头左边的点
break;
case Right:
xnakes.add(new Point((xnakes.get(xnakes.size() - 1).x + 1) % ROWS,
xnakes.get(xnakes.size() - 1).y));// 添加一个蛇头右边的点
break;
case Up:
xnakes.add(new Point(xnakes.get(xnakes.size() - 1).x, (xnakes
.get(xnakes.size() - 1).y - 1) < 0 ? COLS - 1 : (xnakes
.get(xnakes.size() - 1).y - 1)));// 添加一个蛇头上边的点
break;
case Down:
xnakes.add(new Point(xnakes.get(xnakes.size() - 1).x, (xnakes
.get(xnakes.size() - 1).y + 1) % COLS));// 添加一个蛇头下边的点
break;
default:
break;
}
if (xnakes.contains(eggPoint)) {
setEgg();
eggcnt++;
repaint();
return;
}
if (xnakes.subList(0, xnakes.size() - 2).contains(
xnakes.get(xnakes.size() - 1))) {
if (0 == JOptionPane.showConfirmDialog(rootPane,
" Try again?", "You eat yourself~",
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE)) {
initXnakes();
return;
} else {
System.exit(0);
}
}
xnakes.remove(0);// 删除尾部的点
repaint();
}
class loadframe extends JFrame implements Runnable, ActionListener {
/**
*
*/
private static final long serialVersionUID = 1L;
public loadframe() {
super("Loading......");
setSize(500, 450);
setResizable(false);
setLocationRelativeTo(null);
setLayout(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
imgJLabel = new JLabel(new ImageIcon("img/贪吃蛇/loading.gif"));
imgJLabel.setBounds(0, 0, 500, 400);
loadBar.setBounds(0, 399, 500, 40);
loadBar.setForeground(Color.black);
loadBar.setBorder(new LineBorder(Color.black, 1, true));
getContentPane().add(imgJLabel);
getContentPane().add(loadBar);
setVisible(true);
run();
}
JLabel imgJLabel;
JSlider diffSlider;
public void stopLoad() {
setTitle("选择游戏难度");
getContentPane().remove(loadBar);
getContentPane().remove(imgJLabel);
repaint();
diffSlider = new JSlider(1, 8, 4);
diffSlider.setBounds(100, 200, 300, 50);
diffSlider.setName("设置难度");
diffSlider.setPaintLabels(true);
diffSlider.setMajorTickSpacing(1);
diffSlider.setPaintTicks(true);
diffSlider.setSnapToTicks(true);
getContentPane().add(diffSlider);
JButton setButton = new JButton("开始游戏");
setButton.setFocusPainted(false);
setButton.setBounds(150, 270, 200, 90);
setButton.addActionListener(this);
getContentPane().add(setButton);
repaint();
}
int imgcnt = 0;
JProgressBar loadBar = new JProgressBar(0, xnake.length);
@Override
public void run() {
try {
int red = 0, blue = 0, green = 0;
for (int i = 1; i <= xnake.length; i++) {
File snaFile = new File("img/贪吃蛇/xnak (" + i + ").jpg");
xnake[i - 1] = ImageIO.read(snaFile);
// 获取蛇的图像
// _______________________________________________________________
// System.out.print((i) + "Read over");
int width = 800, heigh = 600;
if (xnake[i - 1].getWidth() > xnake[i - 1].getHeight()) {
if (xnake[i - 1].getWidth() >= 800) {
width = 800;
heigh = xnake[i - 1].getHeight() * 800
/ xnake[i - 1].getWidth();
} else {
width = xnake[i - 1].getWidth();
heigh = xnake[i - 1].getHeight();
}
} else {
if (xnake[i - 1].getHeight() > 600) {
heigh = 600;
width = xnake[i - 1].getWidth() * 600
/ xnake[i - 1].getHeight();
} else {
width = xnake[i - 1].getWidth();
heigh = xnake[i - 1].getHeight();
}
}
BufferedImage tBufferedImage = new BufferedImage(width,
heigh, BufferedImage.TYPE_INT_RGB);
Graphics aGraphics = tBufferedImage.getGraphics();
aGraphics.drawImage(xnake[i - 1], 0, 0, width, heigh, null);
xnake[i - 1] = tBufferedImage;
// _______________________________________________________________
// System.out.print(" convert over");
int scansize = 200;
int[] data = new int[width * (heigh - scansize)];
xnake[i - 1].getRGB(0, 0, width, heigh, data, 0, scansize);
for (int j = 0; j < data.length; j++) {
red += (data[j] & 0x00ff0000) >> 16;
green += (data[j] & 0x0000ff00) >> 8;
blue += (data[j] & 0x000000ff);
}
int n = data.length;
red = (red / n);
green = (green / n);
blue = (blue / n);
snakeColor[i - 1] = new Color(red, green, blue);
snakeColor[i - 1] = snakeColor[i - 1].brighter();
loadBar.setValue(i);
}
stopLoad();
} catch (IOException e) {
e.printStackTrace();
}
}
@SuppressWarnings("deprecation")
@Override
public void actionPerformed(ActionEvent e) {
setDifficulty(diffSlider.getValue() * 50);
setVisible(false);
snake.setVisible(true);
if (!mainThreak.isAlive())
mainThreak.start();
mainThreak.resume();
}
}
int times = 0;
@Override
public void keyPressed(KeyEvent e) {
int Direction = 0;
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
Direction = Up;
break;
case KeyEvent.VK_DOWN:
Direction = Down;
break;
case KeyEvent.VK_LEFT:
Direction = Left;
break;
case KeyEvent.VK_RIGHT:
Direction = Right;
break;
default:
break;
}
switch (Direction) {// 根据移动方向添加一个点
case Left:
if (xnakes.get(xnakes.size() - 2).x + 1 == xnakes
.get(xnakes.size() - 1).x
|| xnakes.get(xnakes.size() - 2).x == ROWS - 1
&& xnakes.get(xnakes.size() - 1).x == 0) {// 如果蛇头跟蛇脖子挡住了移动方向,返回
return;
} else {
setMoveDirection(Left);
break;
}
case Right:
if (xnakes.get(xnakes.size() - 2).x - 1 == xnakes
.get(xnakes.size() - 1).x
|| xnakes.get(xnakes.size() - 2).x == 0
&& xnakes.get(xnakes.size() - 1).x == ROWS - 1) {// 如果蛇头跟蛇脖子挡住了移动方向,返回
return;
} else {
setMoveDirection(Right);
break;
}
case Up:
if (xnakes.get(xnakes.size() - 2).y + 1 == xnakes
.get(xnakes.size() - 1).y
|| xnakes.get(xnakes.size() - 2).y == COLS - 1
&& xnakes.get(xnakes.size() - 1).y == 0) {// 如果蛇头跟蛇脖子挡住了移动方向,返回
return;
} else {
setMoveDirection(Up);
break;
}
case Down:
if (xnakes.get(xnakes.size() - 2).y - 1 == xnakes
.get(xnakes.size() - 1).y
|| xnakes.get(xnakes.size() - 2).y == 0
&& xnakes.get(xnakes.size() - 1).y == COLS - 1) {// 如果蛇头跟蛇脖子挡住了移动方向,返回
return;
} else {
setMoveDirection(Down);
break;
}
default:
break;
}
times++;
if (times > 10) {
difficulty = 40;
}
}
@SuppressWarnings("deprecation")
@Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == 32) {
mainThreak.suspend();
} else if (e.getKeyCode() == 27) {
mainThreak.suspend();
snake.setVisible(false);
load.setVisible(true);
}
else {
mainThreak.resume();
}
difficulty = oridifficulty;
times = 0;
}
int oridifficulty;
@Override
public void keyTyped(KeyEvent e) {
}
public static void setbGraphics(Graphics2D bGraphics) {
Snake.bGraphics = bGraphics;
}
public static Graphics2D getbGraphics() {
return bGraphics;
}
public static void setbImage(Image bImage) {
Snake.bImage = bImage;
}
public static Image getbImage() {
return bImage;
}
public static int getROWS() {
return ROWS;
}
public static void setROWS(int rOWS) {
ROWS = rOWS;
}
public static int getCOLS() {
return COLS;
}
public static void setCOLS(int cOLS) {
COLS = cOLS;
}
public static int getBLOCK() {
return BLOCK;
}
public static void setBLOCK(int bLOCK) {
BLOCK = bLOCK;
}
public int getMoveDirection() {
return moveDirection;
}
public void setMoveDirection(int moveDirection) {
this.moveDirection = moveDirection;
}
public int getDifficulty() {
return difficulty;
}
public void setDifficulty(int difficulty) {
this.difficulty = difficulty;
this.oridifficulty = difficulty;
}
public static void setXnakes(ArrayList<Point> xnakes) {
Snake.xnakes = xnakes;
}
public static ArrayList<Point> getXnakes() {
return xnakes;
}
public static Point getEggPoint() {
return eggPoint;
}
public static void setEggPoint(Point eggPoint) {
Snake.eggPoint = eggPoint;
}
public static void setEggcnt(int eggcnt) {
Snake.eggcnt = eggcnt;
}
public static int getEggcnt() {
return eggcnt;
}
private static final long serialVersionUID = 1L;
private static int ROWS;
private static int COLS;
private static int BLOCK = 20;
private static Image bImage;
private static Graphics2D bGraphics;
private final static int Up = 1, Down = 3, Left = 2, Right = 4;
private static ArrayList<Point> xnakes;
private static Point eggPoint;
private static int eggcnt;
static Toolkit tkToolkit = Toolkit.getDefaultToolkit();
Image background = tkToolkit.getImage("img/贪吃蛇/background.png");
Image head = tkToolkit.getImage("img/贪吃蛇/head.png");
Image egg = tkToolkit.getImage("img/贪吃蛇/egg.png");
Image logo = tkToolkit.getImage("img/贪吃蛇/logo_small.png");
BufferedImage[] xnake = new BufferedImage[23];
Color[] snakeColor = new Color[23];
int moveDirection = Down;
int difficulty = 100;
Font scoreFont = new Font("Jokerman", Font.BOLD, 80);
Font numberfont = new Font("微软雅黑", Font.PLAIN, 60);
JFrame loadFrame;
loadframe load;
}