一、系统介绍
贪吃蛇作为一款经典游戏,其整体功能是这样的:一条蛇被封闭在围墙里,围墙里随机出现一个事物,通过按键盘上的四个光标键控制蛇向上下左右四个方向移动,若一直按着某个方向键,则会一直加速移动。蛇头撞到食物,则食物被吃掉,蛇身体长一节,同时记100分,接着又随机出现食物,等待蛇来吃,如果蛇在移动中撞到了墙或是身体交叉蛇头撞到自己的身体游戏结束。
功能分析:
贪吃蛇游戏的设计与实现,主要分为以下三个模块:游戏主界面模块、游戏控制模块和查看游戏基本信息模块。
游戏主界面模块
游戏的主界面是进入游戏后,能够给玩家第一感官的部分,主要包括游戏图形区域界面以及玩游戏所得的分数。
游戏控制模块
这个模块是游戏的中心环节,主要完成控制游戏,包括开始游戏、退出游戏、选择游戏的难易程度、加快蛇的爬行速度、计算当前分数。以及蛇吃的食物的个数。
查看游戏基本信息模块
有查看游戏的最高纪录以及游戏版本和作者等信息。
运行环境:eclipse、idea
二、功能展示
1.游戏展示
三、系统实现
package snake;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
import javax.swing.JPanel;
import javax.swing.Timer;
public class GamePanel extends JPanel implements KeyListener,ActionListener{
//蛇的数据结构
static int i=0;
int length;
int[] snakex=new int[600];
int[] snakey=new int[600];
String fx;
boolean isStart=false;
boolean isfail=false;
int lx,ly;//吃食物后多出来一个的坐标
//目标的数据结构
int foodx,foody;
//随机数
Random random =new Random();
//计时器
Timer timer=new Timer(100, this);
int score;
public GamePanel(){
init();
//添加键盘监听器
this.addKeyListener(this);
//必须设置可以获得焦点才能监听到键盘事件
this.setFocusable(true);
timer.start();
}
public void init(){
score=0;
length=3;
snakex[0]=100;snakey[0]=100;
snakex[1]=75;snakey[1]=100;
snakex[2]=50;snakey[2]=100;
fx="R";
foodx=25+25*random.nextInt(850/25);
foody=75+25*random.nextInt(600/25);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);//清屏,这样不会闪烁
this.setBackground(Color.white);
Data.headicno.paintIcon(this, g, 25, 11);
g.setColor(new Color(104,197,107));
g.fillRect(25, 75, 850, 600);
//蛇头的绘制
if(fx.equals("U")){
Data.upicno.paintIcon(this, g, snakex[0], snakey[0]);
}else if(fx.equals("D")){
Data.downicno.paintIcon(this, g, snakex[0], snakey[0]);
}else if(fx.equals("L")){
Data.lefticno.paintIcon(this, g, snakex[0], snakey[0]);
}else if(fx.equals("R")){
Data.righticno.paintIcon(this, g, snakex[0], snakey[0]);
}
//蛇身体绘制
for(int i=1;i<length;++i){
Data.bodyicno.paintIcon(this, g, snakex[i], snakey[i]);
}
//食物的绘制
Data.foodicon.paintIcon(this, g, foodx, foody);
//暂停开始状态的绘制
if(isStart==false){
g.setFont(new Font("微软雅黑",Font.BOLD,40));
g.setColor(Color.WHITE);
g.drawString("按空格开始/暂停游戏", 275, 350);
}
//失败情况的绘制
if(isfail==true){
g.setFont(new Font("微软雅黑",Font.BOLD,40));
g.setColor(Color.red);
g.drawString("失败!按空格重新开始", 275, 350);
}
//积分的绘制
g.setColor(Color.PINK);
g.setFont(new Font("微软雅黑", Font.ITALIC, 15));
g.drawString("长度: "+length, 800, 30);
g.drawString("积分: "+score, 800, 55);
}
//实现键盘监听的接口方法
@Override
public void keyPressed(KeyEvent e) {
int keycode=e.getKeyCode();
//空格键暂停或者重开
if(keycode==KeyEvent.VK_SPACE){
if(isfail==true){
System.out.println(1);
init();
isfail=false;
}
else{
System.out.println(2);
isStart=!isStart;
repaint();
}
}
//上下左右
if(keycode==KeyEvent.VK_UP){
fx="U";
}else if(keycode==KeyEvent.VK_DOWN){
fx="D";
//System.out.println("down");
}else if(keycode==KeyEvent.VK_LEFT){
fx="L";
}else if(keycode==KeyEvent.VK_RIGHT){
fx="R";
}
}
@Override
public void keyReleased(KeyEvent e) {}
@Override
public void keyTyped(KeyEvent e){}
@Override
public void actionPerformed(ActionEvent e) {
if(isStart==true&&isfail==false){
//身体移动
lx=snakex[length-1];
ly=snakey[length-1];
for(int i=length-1;i>0;--i){
snakex[i]=snakex[i-1];
snakey[i]=snakey[i-1];
}
//头移动
if(fx=="U"){
snakey[0]-=25;
if(snakey[0]<75)snakey[0]=650;
}else if(fx=="D"){
snakey[0]+=25;
if(snakey[0]>650)snakey[0]=75;
}else if(fx=="L"){
snakex[0]-=25;
if(snakex[0]<25)snakex[0]=850;
}else if(fx=="R"){
snakex[0]+=25;
if(snakex[0]>850)snakex[0]=25;
}
//失败判定
for(int i=1;i<length;++i){
if(snakex[i]==snakex[0]&&snakey[i]==snakey[0]){
isfail=true;
}
}
//吃食物
if(snakex[0]==foodx&&snakey[0]==foody){
length++;
score+=10;
snakex[length-1]=lx;
snakey[length-1]=ly;
foodx=25+25*random.nextInt(850/25);
foody=75+25*random.nextInt(600/25);
}
repaint();
}
}
}