说明:这个游戏没有很好的体现出面向对象的编程思想,代码比较凌乱,不是很规范,一个面板类就解决了所有问题。图片做的比较粗糙,但不影响使用。
面板类有各种属性,其中最核心的是由贪吃蛇数组。面板类实现Runnable接口,可以实现重绘,重绘过程中,身体的移动看上去是从前往后的,因此后一个身体的坐标会变成前一个身体的坐标。
//这个逻辑很关键
for(int i=len;i>0;i--){
snakex[i]=snakex[i-1];
snakey[i]=snakey[i-1];
}
//当i=1时
//snakex[1]=snakex[0]就体现出身体跟着头走的,牵一发动全身。
初始化有一个头,两个身体,身体的移动最终都是尾随着头部的,头部当然会根据当前方向,在画板刷新时移动一个单位。根据以下坐标的变换可以体会出来。
0 0
50 100
75 100头
50 100
75 100
100 100头
75 100
100 100
125 100头
100 100
125 100
150 100头
125 100
150 100
175 100头
150 100
175 100
200 100头
package com.xing.snake;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Snake {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
JFrame frame=new JFrame();
frame.setBounds(400, 200, 900, 720);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
SnakePanel snakePanel=new SnakePanel();
frame.add(snakePanel);
frame.setVisible(true);
}
}
class SnakePanel extends JPanel implements KeyListener,Runnable{
ImageIcon up =new ImageIcon("images/up.png");
ImageIcon down = new ImageIcon("images/down.png");
ImageIcon left = new ImageIcon("images/left.png");
ImageIcon right = new ImageIcon("images/right.png");
ImageIcon title = new ImageIcon("images/title.png");
ImageIcon food = new ImageIcon("images/food.png");
ImageIcon body = new ImageIcon("images/body.png");
int [] snakex=new int[750];
int [] snakey=new int[750];
Random r=new Random();
int foodx=r.nextInt(34)*25+25;
int foody=r.nextInt(24)*25+75;
int len=3;
char direction='R';
boolean isStart=false;
boolean isGameOver =false;
public SnakePanel(){
this.setFocusable(true);
initSnake();
this.addKeyListener(this);
Thread t=new Thread(this);
t.start();
}
public void initSnake(){
isStart=false;
isGameOver=false;
len=3;
direction='R';
snakex[0]=100;
snakey[0]=100;
snakex[1]=75;
snakey[1]=100;
snakex[2]=50;
snakey[2]=100;
}
public void paint(Graphics g){
this.setBackground(Color.BLACK);
g.fillRect(25, 75, 850, 600);
title.paintIcon(this, g, 25, 11);
if(direction=='U'){
up.paintIcon(this, g, snakex[0], snakey[0]);
}else if(direction=='D'){
down.paintIcon(this, g, snakex[0], snakey[0]);
}else if(direction=='L'){
left.paintIcon(this, g, snakex[0], snakey[0]);
}else if(direction=='R'){
right.paintIcon(this, g, snakex[0], snakey[0]);
}
for(int i=1;i<len;i++){
body.paintIcon(this, g, snakex[i], snakey[i]);
}
if(!isStart){
g.setColor(Color.WHITE);
g.setFont(new Font("华文仿宋",Font.BOLD,30));
g.drawString("请按空格开始游戏", 300, 300);
}
if(isGameOver){
g.setColor(Color.ORANGE);
g.setFont(new Font("华文仿宋",Font.BOLD,30));
g.drawString("游戏结束", 300, 300);
}
food.paintIcon(this, g, foodx, foody);
}
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
}
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
int keyCode = e.getKeyCode();
if(keyCode == KeyEvent.VK_SPACE){
if(isGameOver){
initSnake();
}else{
isStart=!isStart;
}
//repaint();
}else if(keyCode == KeyEvent.VK_UP && direction!='D'){
direction = 'U';
}else if(keyCode == KeyEvent.VK_DOWN && direction!='U'){
direction = 'D';
}else if(keyCode == KeyEvent.VK_LEFT && direction!='R'){
direction = 'L';
}else if(keyCode == KeyEvent.VK_RIGHT && direction!='L'){
direction = 'R';
}
}
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
public void run(){
while(true){
if(isStart && !isGameOver){
//身体的移动
for(int i=len;i>0;i--){
snakex[i]=snakex[i-1];
snakey[i]=snakey[i-1];
}
if(direction=='U'){
snakey[0]-=25;
if(snakey[0]<75){snakey[0]=650;}
}else if(direction=='D'){
snakey[0]+=25;
if(snakey[0]>650){snakey[0]=75;}
}else if(direction=='L'){
snakex[0]-=25;
if(snakex[0]<25){snakex[0]=850;}
}else if(direction=='R'){
snakex[0]+=25;
if(snakex[0]>850){snakex[0]=25;}
}
}
try {
Thread.sleep(100);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
if(snakex[0]==foodx && snakey[0]==foody){
len++;
foodx=r.nextInt(34)*25+25;
foody=r.nextInt(24)*25+75;
}
for(int i=1;i<len;i++){
if(snakex[0]==snakex[i] && snakey[0]==snakey[i]){
isGameOver=true;
}
}
repaint();
}
}
}