基于贪吃蛇游戏的设计与实现

整体架构图

 Test类

package snake;

import java.applet.Applet;  
import java.applet.AudioClip;  
import java.io.File;  
import java.net.MalformedURLException;  
import java.util.Scanner;

public class Test {
	
    public static void main(String[] args) {
        Snake snake = new Snake();
        int zz=snake.music;
        
        
        	Music audioPlayWave = new Music("1rjsrl-hytdo.wav");
        	
        	audioPlayWave.start();

        	@SuppressWarnings("unused")

        	int musicOpenLab = 1;
           
         
         
      //背景音乐启动
      /*  Music audioPlayWave = new Music("rjsrl-hytdo.wav");
        
        audioPlayWave.start();
        
        @SuppressWarnings("unused")
        
        int musicOpenLab = 1; */
        
        
        //GamePanel game = new GamePanel(0,0);
        
       // Scanner s = new Scanner (System.in);
        
        //snake.nandu=s.nextInt();
        	
        System.out.println(zz);
        
        snake.myJFrame();
        
    }
    
}

package snake;
 
import java.io.File;
import java.io.IOException;
 
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;
 
public class Music extends Thread
{
	private String fileName;
	
	private final int EXTERNAL_BUFFER_SIZE = 524288;
 
	public Music(String wavFile) 
	{
		this.fileName = wavFile;
	}
 
	@SuppressWarnings("unused")
	
	public void run() 
	{
		File soundFile = new File(fileName); // 播放音乐的文件名
		if (!soundFile.exists()) 
		{
			System.err.println("Wave file not found:" + fileName);
			
			return;
		}
		
		while (true)
		{ // 设置循环播放
			AudioInputStream audioInputStream = null; // 创建音频输入流对象
			
			try
			{
				audioInputStream = AudioSystem.getAudioInputStream(soundFile); // 创建音频对象
			}
			catch (UnsupportedAudioFileException e1)
			{
				e1.printStackTrace();
				return;
			} 
			catch (IOException e1) 
			{
				e1.printStackTrace();
				return;
			}
			
			
			AudioFormat format = audioInputStream.getFormat(); // 音频格式
			
			SourceDataLine auline = null; // 源数据线
			
			DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
			
			try
			{
				auline = (SourceDataLine) AudioSystem.getLine(info);
				auline.open(format);
			} 
			catch (LineUnavailableException e)
			{
				e.printStackTrace();
				return;
			}
			catch (Exception e) 
			{
				e.printStackTrace();
				return;
			}
			
			if (auline.isControlSupported(FloatControl.Type.PAN))
			{
				FloatControl pan = (FloatControl) auline.getControl(FloatControl.Type.PAN);
			}
			
			auline.start();
			
			int nBytesRead = 0;
			
			byte[] abData = new byte[EXTERNAL_BUFFER_SIZE];
			
			try 
			{
				while (nBytesRead != -1)
				{
					nBytesRead = audioInputStream.read(abData, 0, abData.length);
					
					
					if (nBytesRead >= 0)
						
						auline.write(abData, 0, nBytesRead);
					
				}
			} 
			catch (IOException e)
			
			{
				e.printStackTrace();
				
				return;
				
			} 
			finally 
			{
				auline.drain();
				
				
// auline.close();
			}
		}
	}
}

Snake类

package snake;

import javax.swing.*;

import java.awt.*;

import java.awt.event.*;

import java.io.File;

import java.io.IOException;

import java.io.InputStream;

import java.util.Random;


import javax.sound.sampled.*;

import java.net.MalformedURLException;

 import java.net.URI;
 
 import java.net.URL;

import java.awt.Toolkit;

import java.awt.event.*;

public class Snake extends JFrame implements KeyListener, ActionListener, MouseListener  
{
	//图片双缓冲防闪烁
	
	Image offScreenImage = null;
	
	int score=1;//分数
	
    int slong = 2;//蛇当前长度
    //蛇坐标
    
    int[] Snakex = new int[100];
    
    int[] Snakey = new int[100];
    
    int fx = 1;//蛇的方向 0-左 1-右 2-上 3-下
    
    int nandu =0;//传递输入流
    
    //难度对应
    Timer timer = new Timer(160, this);//设置定时器,x毫秒一次,即蛇运动速度
    
    Timer timer1 = new Timer(140, this);
    
    Timer timer2 = new Timer(130, this);
    
    Timer timer3 = new Timer(120, this);
    
    Timer timer4 = new Timer(115, this);
    //食物位置
    int foodx;
    
    int foody;
    
    int bombx,bomby;
    
    Random random = new Random();//随机数,随机位置生成食物
    
  //游戏信息 -1-选择界面 0-未开始 1-开始 2-结束 3-暂停 4-通关 5-无尽模式
    int started = -1;
    
    int guan=1;//关卡
    
    int superfoodx,superfoody;//超级食物坐标
    
    int music=0;
    
    int doorx=0,doory=0;
    
    JMenuBar menubar = new JMenuBar();
	//JFrame a=new JFrame();
	
	JMenu menu1 = new JMenu("开始");
	
	JMenuItem item1 = new JMenuItem("游玩");
	
	JMenuItem item2 = new JMenuItem("暂停");
	
	JMenuItem item3 = new JMenuItem("保存");

    //---------------------------------------------------------------------------------------------------------------------
    //窗体
    public void myJFrame() {
    	
    	this.add(item1);
    	this.add(item2);
    	this.add(item3);
    	this.add(menu1);
    	
		item1.addActionListener(new kaishi()); //注册监听器
    	item2.addActionListener(new zanting()); //注册监听器
    	item3.addActionListener(new baocun()); //注册监听器.
    	
    	
        this.setTitle("贪吃蛇"); //标题
        this.setSize(800, 600); //窗口大小
        this.setResizable(false); //窗口是否可以改变大小=否
        this.setDefaultCloseOperation(Snake.EXIT_ON_CLOSE); //窗口关闭方式为关闭窗口同时结束程序

        int width = Toolkit.getDefaultToolkit().getScreenSize().width; //获取屏幕宽度
        int height = Toolkit.getDefaultToolkit().getScreenSize().height; //获取屏幕高度
//        System.out.println("宽度:"+width);//测试
//        System.out.println("高度:"+height);//测试

        this.setLocation((width - 800) / 2, (height - 600) / 2); //设置窗口默认位置以屏幕居中

        this.setFocusable(true);
        
        this.addKeyListener(this);


        this.setVisible(true); //窗口是否显示=是
       

//        蛇的初识位置
        Snakex[0] = 260;
        
        Snakey[0] = 300;
        
        Snakex[1] = 240;
        
        Snakey[1] = 300;

//        随机食物的初识位置
        foodx = random.nextInt(39);
        
        foody = random.nextInt(22);
        
        foodx = foodx * 20;
        
        foody = foody * 20 + 80;

        System.out.println(foodx + "," + foody);//输出每次食物坐标
    }
    
    class kaishi implements ActionListener
    {  
		  
        @Override  
        public void actionPerformed(ActionEvent e) 
        {  
        	// TODO Auto-generated method stub 
        	
        	JOptionPane.showMessageDialog(null,"开始游戏");
        }  
          
    }
	class zanting implements ActionListener
	{  
		  
        @Override  
        public void actionPerformed(ActionEvent e) 
        {  
            // TODO Auto-generated method stub  
        	MenuListener m=new MenuListener();
        	m.guan=100;
        	JOptionPane.showMessageDialog(null,"已暂停");
        	System.out.println(m.guan);
        }  
          
    }  
	class baocun implements ActionListener
	{  
		  
        @Override  
        public void actionPerformed(ActionEvent e)
        {  
            // TODO Auto-generated method stub  
        	JOptionPane.showMessageDialog(null,"已保存");
        }  
          
    }
	

    //---------------------------------------------------------------------------------------------------------------------
    //覆写paint方法,绘制界面
	
    public void paint(Graphics g) 
    {
    	
    	//初始化双缓存图片
    	if(offScreenImage==null)
    	{
    		offScreenImage=this.createImage(800, 600);	
    	}
    	
    	//获取图片对应的graphics对象
    	
    	Graphics gImage = offScreenImage.getGraphics();
   
    	
    	
	
    	
//        绘制背景
    	gImage.setColor(new Color(187,222,214));//文字背景
    	
    	gImage.fillRect(0, 0, 800, 600);
    	
        
        //绘制游戏区域
    	
    	switch(guan) 
    	{
    	case 1:gImage.setColor(new Color(250,227,217));//文字背景
    	
    	gImage.fillRect(0, 80, 800, 520);break;
    	
    	case 2:gImage.setColor(new Color(247,239,214));//文字背景
    	
    	gImage.fillRect(0, 80, 800, 520);break;
    	
    	case 3:gImage.setColor(new Color(255,240,245));//文字背景
    	
    	gImage.fillRect(0, 80, 800, 520);break;
    	
    	case 4:gImage.setColor(new Color(0,128,128));//文字背景
    	
    	gImage.fillRect(0, 80, 800, 520);break;
    	
    	case 5:gImage.setColor(new Color(255,255,255));//文字背景
    	
    	gImage.fillRect(0, 80, 800, 520);break;
    		
    	}
    	
    	
        //绘制蛇
        for (int i = 0; i < slong; i++) 
        {
        	gImage.setColor(new Color(255,182,185));
        	gImage.fillRect(Snakex[i], Snakey[i], 20, 20);
        	
        }
        


        //        绘制食物
        gImage.setColor(new Color(138,198,209));
        gImage.fillOval(foodx, foody, 20, 20);
        
        
        
        //	超级食物
        gImage.setColor(new Color(194,91,86));
        gImage.fillOval(superfoodx, superfoody, 20, 20);
        
        
        
        //炸弹食物
        gImage.setColor(new Color(0,0,0));
        gImage.fillOval(bombx, bomby, 20, 20);
        
        //传送门
        gImage.setColor(new Color(128,0,128));
        gImage.fillOval(doorx, doory, 20, 20);
        
        
        if (started == 0) 
        {
        	
        	gImage.setColor(Color.BLACK);//设置画笔颜色
        	gImage.setFont(new Font("微软雅黑",Font.BOLD,25)); //设置字体
        	gImage.drawString("按下“空格键”开始游戏", 240, 65); //绘制字符
        	
        } else if (started == 1) 
        {
        	
        	gImage.setColor(Color.BLACK);//设置画笔颜色
        	gImage.setFont(new Font("微软雅黑",Font.BOLD,25)); //设置字体
        	
        	gImage.drawString("分数", 320, 65); //绘制字符
        	gImage.drawString(String.valueOf(slong - 2), 380, 65); //绘制字符
        	
        	gImage.drawString("长度", 420, 65);
        	gImage.drawString(String.valueOf(slong), 480, 65);
        	
        	gImage.drawString("关卡", 220, 65);
        	gImage.drawString(String.valueOf(guan), 280, 65);
        	
        } 
        else if (started == 4) 
        {
        	
        	gImage.setColor(Color.BLACK);//设置画笔颜色
        	
        	gImage.setFont(new Font("微软雅黑",Font.BOLD,25)); //设置字体
        	
        	gImage.drawString("游戏结束 ——", 220, 65); //绘制字符
        	
        	gImage.drawString("最终分数为:", 400, 65); //绘制字符
        	
        	gImage.drawString(String.valueOf(slong - 2), 550, 65); //绘制字符
        	
        	
        	//死亡归零
            bombx=0;
            bomby=0;
            
            superfoodx = 0;
            superfoody = 0;
            
            slong=2;
            score=1;
            
        }
        
        else if (started ==3) 
        	
        {
        	
        	gImage.setColor(Color.BLACK);//设置画笔颜色
        	
        	gImage.setFont(new Font("微软雅黑",Font.BOLD,25)); //设置字体
        	
        	gImage.drawString("游戏已暂停,按下“空格键”开始游戏", 180, 65); //绘制字符
        	
        	//gImage.drawString("最终分数为:", 400, 65); //绘制字符
        }
        else if(started==2) 
        	
        {
        	
        	gImage.setColor(new Color(76,88,112));//设置画笔颜色
        	
        	gImage.setFont(new Font("微软雅黑",Font.BOLD,25)); //设置字体
        	
        	gImage.drawString("恭喜您已通关,按下“空格键”进入下一关", 150, 70); //绘制字符
        	
        	if(guan==5) 
        	{
        		gImage.drawString("接下来将是隐藏无尽模式,你的长度和分数都会一直持续下去", 45, 120); //绘制字符
        		
        		gImage.drawString("进入紫色传送门可直接进入下一关", 200, 150);
        	}
        	
        }
        if(started==-1) 
        	
        {
        	
        	gImage.setColor(new Color(255,255,255));
        	gImage.fillRect(0, 0, 800, 600);
        	
        	gImage.setColor(new Color(0,51,153));//设置画笔颜色
        	
        	gImage.setFont(new Font("微软雅黑",Font.BOLD,60));
        	gImage.drawString("贪吃蛇", 300, 140);
        	
        	gImage.setColor(new Color(51,153,255));
        	gImage.setFont(new Font("微软雅黑",Font.BOLD,25)); //设置字体
        	
        	gImage.drawString("关卡选择", 335, 320);
        	gImage.drawString("关卡1", 150, 370); //绘制字符
        	gImage.drawString("关卡2", 250, 370);
        	gImage.drawString("关卡3", 350, 370);
        	gImage.drawString("关卡4", 450, 370);
        	gImage.drawString("关卡5", 550, 370);
        	gImage.drawString("按下空格键开始游戏", 280, 500);
        	
        	
        	//对应选择
        	switch(nandu)
        	{
        	case 1:gImage.setColor(new Color(51,102,204));
        	
            gImage.fillOval(170, 390, 20, 20);break;
            
        	case 2:gImage.setColor(new Color(51,102,204));
        	
            gImage.fillOval(270, 390, 20, 20);break;
            
        	case 3:gImage.setColor(new Color(51,102,204));
        	
            gImage.fillOval(370, 390, 20, 20);break;
            
        	case 4:gImage.setColor(new Color(51,102,204));
        	
            gImage.fillOval(470, 390, 20, 20);break;
            
        	case 5:gImage.setColor(new Color(51,102,204));
        	
            gImage.fillOval(570, 390, 20, 20);break;
            
        	}
        	
        	gImage.drawString("歌曲选择", 335, 200);
        	
        	
        	//gImage.drawString("歌曲1", 250, 250);
        	
        	
        	gImage.drawString("歌曲1", 350, 250);
        	
        //	gImage.drawString("歌曲3", 450, 250);
        	
        	//对应选择
        	
        	switch(music)
        	{
        	case 1:gImage.setColor(new Color(51,102,204));
        	
            gImage.fillOval(270, 270, 20, 20);break;
            
        	case 2:gImage.setColor(new Color(51,102,204));
        	
            gImage.fillOval(370, 270, 20, 20);break;
            
        	case 3:gImage.setColor(new Color(51,102,204));
        	
            gImage.fillOval(470, 270, 20, 20);break;
            
        	}
        	
        	
        	//刷新
        	repaint();
        	
        }
        
        //双缓冲结尾
  
        g.drawImage(offScreenImage,0,0,null);
        
        
        }
        
    
    

    //    操作监听——控制蛇的不断移动
    @Override
    public void actionPerformed(ActionEvent e) 
    {
//        判断游戏是否开始
        if (started == 1) 
        {
//            通过循环控制蛇移动
            for (int i = slong - 1; i > 0; i--)
            {
                Snakex[i] = Snakex[i - 1];
                Snakey[i] = Snakey[i - 1];
            }

//            判断蛇移动的方向
            if (fx == 0)
            {
                Snakex[0] = Snakex[0] - 20;
            }
            else if (fx == 1) 
            {
                Snakex[0] = Snakex[0] + 20;
            } 
            else if (fx == 2) 
            {
                Snakey[0] = Snakey[0] - 20;
            } 
            else if (fx == 3) 
            {
                Snakey[0] = Snakey[0] + 20;
            }

            
//            判断蛇是否撞到墙外
            if (Snakex[0] < 0 || Snakex[0] > 780 || Snakey[0] < 80 || Snakey[0] > 580) 
            {
                started = 4;
            }

//            判断蛇是否吃到了普通食物
            if (Snakex[0] == foodx && Snakey[0] == foody) 
            {

                slong++;
                score++;
                
                //特判超级食物
                if(score%6==0&&guan>1) 
                {
                	superfoodx = random.nextInt(39);
                	superfoody = random.nextInt(22);
                	
                	superfoodx = superfoodx * 20;
                	superfoody = superfoody * 20 + 80;
                }
                
                
                //特判炸弹食物
                if(slong%6==0&&guan>2) 
                {
                	bombx=random.nextInt(39);
                	bomby = random.nextInt(22);
                	
                	bombx = bombx * 20;
                	bomby = bomby * 20 + 80;
                }
                
                if(guan==6&&slong>random.nextInt(40)) {
                	doorx=random.nextInt(39);
                	doory = random.nextInt(22);
                	
                	doorx = doorx * 20;
                	doory = doory * 20 + 80;
                }
                foodx = random.nextInt(39);
                foody = random.nextInt(22);
                
                foodx = foodx * 20;
                foody = foody * 20 + 80;
              
                System.out.println(foodx + "," + foody);//输出下个食物坐标
            }
            
//超级食物判断
            
            if (Snakex[0] == superfoodx && Snakey[0] == superfoody) 
            
            {

                slong+=4;
                score+=3;
                
                //超级食物清零
                superfoodx = 0;
                superfoody = 0;
                
                superfoodx = 0;
                superfoody = 0;
                
              
                //System.out.println(foodx + "," + foody);//输出下个食物坐标
            }
            
            
            //炸弹食物判断
            if (Snakex[0] == bombx && Snakey[0] == bomby)
            {
            	started=4;
                //System.out.println(foodx + "," + foody);//输出下个食物坐标
            }
            
            if (Snakex[0] == doorx && Snakey[0] == doory) 
                
            {
                score+=3;
                
                //传送门清零
                doorx = 0;
                doory = 0;
                
               started=2;
                
              
                //System.out.println(foodx + "," + foody);//输出下个食物坐标
            }
            
            
//            判断是否吃到了自己
            
            for (int i = 1; i < slong; i++) 
            {
            	
                if (Snakex[0] == Snakex[i] && Snakey[0] == Snakey[i]) {
                    started = 4;
                }
            }

//            判断食物是否随机在了蛇身上
            for (int i = 0; i < slong; i++) 
            {
                if (foodx == Snakex[i] && foody == Snakey[i]) 
                {

                	
                    //        随机食物的初识位置
                	
                    foodx = random.nextInt(39);
                    
                    foody = random.nextInt(22);
                    
                    foodx = foodx * 20;
                    
                    foody = foody * 20 + 80;
                    
                    
                    System.out.println(foodx + "," + foody);
                }
            }
            //刷新
            repaint();
           
           }
            
            
        //通关判断
        
        
        if(score>1) {
        	
        	started=2;
        	
        }
        
    }
   
    
    //    键盘输入
    
    @Override
    
    public void keyTyped(KeyEvent e) {

    }

    
    //    键盘按下——控制游戏的开始以及蛇的移动方向
    
    @Override
    
    public void keyPressed(KeyEvent e) {
//        获取从键盘输入的键
    	
        int key = e.getKeyCode();
//        判断是否为空格
        
        if (key == KeyEvent.VK_SPACE)
        {
            
        	if (started == 0) 
            {
            	guan=nandu;
            	
                started = 1;
            } 
            else if (started == 1)
            {
                started = 3;
            } 
            else if (started == 4)
            {
                started = 0;

                slong = 2;//蛇当前长度

                //        蛇的初识位置
                
                Snakex[0] = 260;
                
                Snakey[0] = 300;
                
                Snakex[1] = 240;
                
                Snakey[1] = 300;

                //        随机食物的初识位置
                
                foodx = random.nextInt(39);
                
                foody = random.nextInt(22);
                
                foodx = foodx * 20;
                
                foody = foody * 20 + 80;

                //                初始化方向
                fx = 1;
            }
            else if (started==3) 
            {
            	started=1;
            }
            else if(started==2)
            {
            	
            	started = 1;
            	
            	
            	if(guan<6) {
            		
            		guan++;
            		
            		score=1;
            		
            		 slong = 2;
            		 
            		  //        蛇的初识位置
                     
                     Snakex[0] = 260;
                     
                     Snakey[0] = 300;
                     
                     Snakex[1] = 240;
                     
                     Snakey[1] = 300;
                     
            	}else {
            		
            		guan++;
            		
            		slong+=2;
            		
            		
            	}
            	
            	

              

                //        随机食物的初识位置
                
                foodx = random.nextInt(39);
                
                foody = random.nextInt(22);
                
                foodx = foodx * 20;
                
                foody = foody * 20 + 80;
                
            }else if (started==-1) 
            {
            	started=0;
            }
            switch(guan) 
            {
            case 1: timer.start();break;
            
            case 2: timer1.start();break;
            
            case 3: timer2.start();break;
            
            case 4: timer3.start();break;
            
            default: timer4.start();break;
            	
            }
            
           //timer.start();
           
            repaint();
            

//            左
        } else if (key == KeyEvent.VK_LEFT||key == KeyEvent.VK_A)
        {
            if (fx != 1) 
            {
                fx = 0;
            }
//            右
        } else if (key == KeyEvent.VK_RIGHT||key == KeyEvent.VK_D) 
        {
            if (fx != 0) 
            {
                fx = 1;
            }
//            上
        } else if (key == KeyEvent.VK_UP||key == KeyEvent.VK_W) 
        {
            if (fx != 3) 
            {
                fx = 2;
            }
//下
        } else if (key == KeyEvent.VK_DOWN||key == KeyEvent.VK_S)
        {
            if (fx != 2)
            {
                fx = 3;
            }
        } 
        	else if (key == KeyEvent.VK_1) 
        {
           nandu=1;
        }
        	else if (key == KeyEvent.VK_2) 
        {
            nandu=2;
         }
        	else if (key == KeyEvent.VK_3) 
         {
             nandu=3;
         }
        	else if (key == KeyEvent.VK_4) 
         {
             nandu=4;
         }
        	else if (key == KeyEvent.VK_5) 
        {
             nandu=5;
         }
        	else if(key==KeyEvent.VK_6) {
        		music=1;
        	}else if(key==KeyEvent.VK_7) {
        		music=2;
        	}else if(key==KeyEvent.VK_8) {
        		music=3;
        	}

     
    	        }
    
    //    弹起
    @Override
    public void keyReleased(KeyEvent e) {

    }

    //    点击
    @Override
    public void mouseClicked(MouseEvent e) {

    }

    //    按下
    @Override
    public void mousePressed(MouseEvent e) {

    }

    //    抬起
    @Override
    public void mouseReleased(MouseEvent e) {

    }

    //    进入
    @Override
    public void mouseEntered(MouseEvent e) {

    }

    //    离开
    @Override
    public void mouseExited(MouseEvent e) {

    }
}

有较多未实现功能,代码冗余太多,改日重构。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值