javaSwing制作贪吃蛇

javaSwing实现简单贪吃蛇游戏

效果展示

最外层的窗口是700500
蛇的运行区域是700
400
底部的按钮区域是700*100
在这里插入图片描述
属性配置Config
package snake5;

public class Config {

public final static int ROWS=20;//行
public final static int COLS=35;//列
public final static int SPAN=20;//间隔

public final static String U="U";
public final static String D="D";
public final static String L="L";
public final static String R="R";

public static boolean isLive=true;  // true:游戏运行    false:游戏结束
public static boolean isPause=true;  // true:游戏运行    false:游戏暂停

public static final String IMAGE_PATH="image/bg1.png"; 
public static final String BG_MUSIC_PATH="image/bg_music.wav"; 

}
主界面SnakeGame

package snake5;

import javax.swing.JFrame;

public class SnakeGame extends JFrame{
	
	SnakePanel snakePanel = new SnakePanel();
	ButtonPanel buttonPanel = new ButtonPanel(snakePanel);
	public SnakeGame(){
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setBounds(100, 50, Config.COLS*Config.SPAN, Config.ROWS*Config.SPAN+100);
		//不允许改变窗口大小
		this.setResizable(false);
		this.setLayout(null);
		this.setVisible(true);
		this.add(snakePanel);
		this.add(buttonPanel);
		//让 snakePanel获取焦点
		snakePanel.setFocusable(true);
		snakePanel.requestFocus();
		//创建背景音乐
		new Music();
	}
	public static void main(String[] args) {
		new SnakeGame();
	}

}

蛇运行区域界面 SnakePanel

package snake5;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class SnakePanel extends JPanel{
	
	//蛇
	Snake snake = new Snake();
	
	//食物
	Food food = new Food();
	
	//每间隔200毫秒重置执行一次paint()方法
	Snakethread snakethread = new Snakethread();
	
	ImageIcon image = new ImageIcon(Config.IMAGE_PATH);
	
	public SnakePanel(){
		this.setBounds(0, 0, Config.COLS*Config.SPAN, Config.ROWS*Config.SPAN);
		this.setBackground(Color.BLACK);
		snakethread.start();
		//添加键盘监听事件
		this.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				
				snake.keyPressed(e);
				
			}
		});
		
	}
	
	@Override
	public void paint(Graphics g) {
		super.paint(g);
		//先画背景,否则背景会把已经画的蛇给覆盖掉
		image.paintIcon(this, g, 0, 0);
		
		//蛇移动
		snake.move();
		//画蛇
		snake.draw(g);
		//画食物
		food.draw(g);
		
		//蛇每次走一步,都去判断一下蛇头是否和食物重叠
		snake.eat(food);
		//去除网格,美化界面
		//g.setColor(Color.darkGray);
		/*for(int i=0;i<Config.ROWS;i++){
			g.drawLine(0, i*Config.SPAN, Config.COLS*Config.SPAN, i*Config.SPAN);
		}
		for(int i=0;i<Config.COLS;i++){
			g.drawLine(i*Config.SPAN, 0, i*Config.SPAN, Config.ROWS*Config.SPAN);
		}*/
		
	}
	
	class Snakethread extends Thread{
		@Override
		public void run() {
			while(Config.isLive){
				try {
					Thread.sleep(200);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				if(Config.isPause){
					repaint();
				}
				
			}
			
			JOptionPane.showMessageDialog(SnakePanel.this, "游戏结束,再接再厉~~~");
		}
	}
}

蛇对象 Snake

package snake5;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;


public class Snake {
	
	Node head;//蛇头
	Node tail;//蛇尾
	
	Snake(){
		//                   x  y
		Node node = new Node(20,5,Config.L);
		Node node2 = new Node(21,5,Config.L);
		Node node3 = new Node(22,5,Config.L);
		node.next=node2;
		node2.pre=node;
		node2.next=node3;
		node3.pre=node2;
		
		head=node;
		tail=node3;
	}
	
	//蛇移动
	public void move(){
		
		//在蛇头前面添加一个节点
		addToHead();
		
		//把蛇尾的节点删除,同时让蛇尾前一个节点作为新的尾部
		deleteTail();
		
		//每次移动后检测一次是否撞墙
		isDied();
		
	}
	
	//判断蛇是否超出了四周的墙
	public void isDied(){
		
		if(head.x < 0 || head.x>Config.COLS-1 || head.y<0 || head.y>Config.ROWS-1){
			Config.isLive=false;
		}
		
	}
	
	//添加到头部
	public void addToHead(){
		Node node = null;
		switch(head.dir){
			case Config.L:
				node = new Node(head.x-1,head.y,head.dir);
				break;
			case Config.R:
				node = new Node(head.x+1,head.y,head.dir);
				break;
			case Config.D:
				node = new Node(head.x,head.y+1,head.dir);
				break;	
			case Config.U:
				node = new Node(head.x,head.y-1,head.dir);
				break;	
		}
		
		node.next=head;
		head.pre=node;
		head=node;
		
	}
	
	//删除尾部节点
	public void deleteTail(){
		tail.pre.next=null;
		tail = tail.pre;
	}
	
	
	public void keyPressed(KeyEvent e){
		int key = e.getKeyCode();
		
		switch(key){
			case KeyEvent.VK_UP:
				if(head.dir.equals(Config.D)){
					return;
				}
				head.dir=Config.U;
				break;
			case KeyEvent.VK_LEFT:
				if(head.dir.equals(Config.R)){
					return;
				}
				head.dir=Config.L;
				break;	
			case KeyEvent.VK_RIGHT:
				if(head.dir.equals(Config.L)){
					return;
				}
				head.dir=Config.R;
				break;	
			case KeyEvent.VK_DOWN:
				if(head.dir.equals(Config.U)){
					return;
				}
				head.dir=Config.D;
				break;	
		}
	} 
	
	//Rectangle(x,y,w,h) 
	//蛇头所在的区域
	public Rectangle getRec(){
		return new Rectangle(head.x*Config.SPAN,head.y*Config.SPAN,Config.SPAN,Config.SPAN);
	}
	
	//蛇吃食物的方法
	public void eat(Food food) {
		//判断2个区域是否相交
		if(this.getRec().intersects(food.getRec())){
			this.addToHead();
			food.appear();
		}

	}
	
	public void draw(Graphics g){
		for(Node n=head;n!=null;n=n.next){
			n.draw(g);
		}
	}
	
	class Node{
		int x;
		int y;
		Node next;
		Node pre;
		String dir;
		
		Node(int x,int y,String dir){
			this.x=x;
			this.y=y;
			this.dir=dir;
		}	
		public void draw(Graphics g){
			System.out.println(x +"   "+y);
			g.setColor(Color.yellow);
			g.fillOval(x*Config.SPAN,y*Config.SPAN,Config.SPAN, Config.SPAN);
		}
	}
}

食物对象 Food

package snake5;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;

public class Food {

int x;
int y;

Food(){
	x=10;
	y=8;		
}

public void draw(Graphics g){
	g.setColor(Color.red);
	g.fillRect(x*Config.SPAN, y*Config.SPAN, Config.SPAN, Config.SPAN);
}

//食物所在的区域
public Rectangle getRec(){
	return new Rectangle(x*Config.SPAN,y*Config.SPAN,Config.SPAN,Config.SPAN);
}

//让食物重新出现在一个位置
public void appear(){
	//  0<=r<1     0  34 
	x = (int)(Math.random()*Config.COLS) ;  
	y = (int)(Math.random()*Config.ROWS);
}

}
按钮面板 ButtonPanel

package snake5;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JPanel;

public class ButtonPanel extends JPanel{
	SnakePanel snakePanel;
	
	public ButtonPanel(SnakePanel snakePanel){
		this.snakePanel=snakePanel;
		
		this.setBounds(0, Config.ROWS*Config.SPAN, Config.COLS*Config.SPAN, 100);
		JButton pause = new JButton("暂停游戏");
		JButton con = new JButton("继续游戏");
		JButton restart = new JButton("重新游戏");
		this.add(pause);this.add(con);this.add(restart);
		
		pause.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				Config.isPause=false;
			}
		});
		
		con.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				Config.isPause=true;
				
				//让 snakePanel获取焦点
				snakePanel.setFocusable(true);
				snakePanel.requestFocus();
			}
		});
		
		restart.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				//让 snakePanel获取焦点
				snakePanel.setFocusable(true);
				snakePanel.requestFocus();
				
				//运行中不允许重新开始
				if(Config.isLive){
					return ;
				}
				
				//初始化蛇和食物对象
				snakePanel.snake=new Snake();
				snakePanel.food=new Food();
				
				Config.isLive = true;
				Config.isPause = true;
				
				
				//重新启动线程
				snakePanel.snakethread =  snakePanel.new Snakethread();
				snakePanel.snakethread.start();
				
			}
		});
	}
}

设置背景音乐Music
package snake5;

import java.applet.Applet;
import java.applet.AudioClip;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;

public class Music {
public Music(){
try {
//Java播放背景音乐需要无损音质,后缀名 .wav这之类的
File f= new File(Config.BG_MUSIC_PATH);
URI uri = f.toURI();
URL url = uri.toURL();//解析地址
AudioClip aau= Applet.newAudioClip(url);
aau.loop(); //循环播放
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值