欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java 实现贪吃蛇小游戏

程序员文章站 2024-03-19 08:12:34
...

在贪吃蛇游戏中,贪吃蛇的移动可以看作是一个先进先出的队列(从蛇尾的角度看),因此我们在C语言实现贪吃蛇小游戏一文中使用了循环链接表作为队来存储蛇身节点,在 python实现贪吃蛇小游戏一文中,使用列表来存储蛇身节点,在 java 语言里,也可以使用向量来实现和 链表、列表类似的功能。游戏效果如下(gif):

java 实现贪吃蛇小游戏

 完整实现代码:

package lee;

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.Timer;

public class Snakey extends JFrame{
	
	private JFrame jf = new JFrame("Snakey");
	private MyCanvas drawArea = new MyCanvas();
	private int Side=30;//方形网格边长
	private int Row;//行数
	private int Column;//列数
	private int[][] RoadBlock;
	private Timer timer;//定时器
	private int fps=300;//定时器周期
	private int pos_x=0;
	private int pos_y=0;
	private int direct=0;
	private Vector V=new Vector(2,1);
	private Vector F=new Vector(1);
	private int score=0;
	
	Random rd=new Random();
	//Image bird =Toolkit.getDefaultToolkit().getImage("C:\\Users\\Kansa\\Pictures\\Saved Pictures\\red_bird.jpg");
	public Snakey() {
		super("Snakey");
		this.Row=15;
		this.Column=20;
		this.RoadBlock=new int[Column][Row];
		init();
	}
	public Snakey(int Row,int Column) {
		super("Snakey");
		this.Row=Row;
		this.Column=Column;
		this.RoadBlock=new int[Column][Row];
		init();
	}
	private class WindowCloser extends WindowAdapter{
		public void windowClosing(WindowEvent we) {
			timer.stop();
			System.exit(0);
		}
	}
	public void init() {
		Move move;
		int Wide=Side*Column;
		int High=Side*Row;
		int[] point=new int[2];
		point[0]=rd.nextInt(Column);
		point[1]=rd.nextInt(Row);
		RoadBlock[point[0]][point[1]]=1;
		V.add(point);//随机一个蛇身
		move=new Move();
		int[] food=new int[2];
		food[0]=rd.nextInt(Column);
		food[1]=rd.nextInt(Row);
		if(V.size()<Row*Column-1) {
			while(RoadBlock[food[0]][food[1]]==1) {
				food[0]=rd.nextInt(Column);
				food[1]=rd.nextInt(Row);
			}
			F.add(food);
			RoadBlock[food[0]][food[1]]=-1;
		}
		else {
			System.out.println("Game Over");
			return;
		}
		//获得屏幕分辨率
		Toolkit toolkit=Toolkit.getDefaultToolkit();
		Dimension scrnsize=toolkit.getScreenSize();
		
		jf.add(drawArea,"Center");
		jf.setSize(Wide+Side/4,High+Side*7/5);
		jf.setLocation((scrnsize.width-Wide)/2, (scrnsize.height-High)/2);
		jf.setResizable(false);
		jf.setVisible(true);
		
		drawArea.setSize(Wide,High);
		drawArea.setBackground(new Color(222,224,250));
		drawArea.setBounds(0,0, Wide,High);
		
		jf.addKeyListener(new KeyAdapter() {
					
			public void keyPressed(KeyEvent ke) {
				
				switch(ke.getKeyCode()) {
					case KeyEvent.VK_UP:
						if(direct!=2)
							//move.move_up();
							direct=1;
						break;
					case KeyEvent.VK_DOWN:
						if(direct!=1)
							//move.move_down();
							direct=2;
						break;
					case KeyEvent.VK_LEFT:
						if(direct!=4)
							//move.move_left();
							direct=3;
						break;
					case KeyEvent.VK_RIGHT:
						if(direct!=3)
							//move.move_right();
							direct=4;
						break;
				}
			}
		});
		jf.addWindowListener(new WindowCloser());
		ActionListener taskPerformer=evt->
		{
			switch(direct)
			{
				case 1:pos_y--;move.move_up();break;
				case 2:pos_y++;move.move_down();break;
				case 3:pos_x--;move.move_left();break;
				case 4:pos_x++;move.move_right();break;
			}
			if(pos_x>=0 && pos_x<Column && pos_y>=0 && pos_y<Row) {
				int[] p=new int[] {pos_x,pos_y};
				if(RoadBlock[pos_x][pos_y]==0) {
					RoadBlock[pos_x][pos_y]=1;
					V.add(p);
					p=(int[]) V.remove(0);
					RoadBlock[p[0]][p[1]]=0;
				}
				else if(RoadBlock[pos_x][pos_y]==-1) {
					score++;
					RoadBlock[pos_x][pos_y]=1;
					V.add(p);
					food[0]=rd.nextInt(Column);
					food[1]=rd.nextInt(Row);
					if(V.size()<Row*Column-1) {
						while(RoadBlock[food[0]][food[1]]==1) {
							food[0]=rd.nextInt(Column);
							food[1]=rd.nextInt(Row);
						}
						F.set(0,food);
						RoadBlock[food[0]][food[1]]=-1;
					}
					else {
						JOptionPane.showMessageDialog(jf, "恭喜达到人生巅峰");
						System.exit(0);
					}
				}
				else {
					if(direct!=0) {
						timer.stop();
						int select=JOptionPane.showConfirmDialog(jf, "SCORE:"+score+"\n是否重新游戏?","Game Over!",0);
						switch (select) {
						case 0:jf.setVisible(false);new Snakey(15,20);break;
						default:System.exit(0);break;
						}
						return;
					}
				}
				drawArea.repaint();
			}
			else {
				timer.stop();
				int select=JOptionPane.showConfirmDialog(jf, "SCORE:"+score+"\n是否重新游戏?","Game Over!",0);
				switch (select) {
				case 0:jf.setVisible(false);new Snakey(15,20);break;
				default:System.exit(0);break;
				}
				return;
			}
			
		};
		timer = new Timer(fps, taskPerformer);
		timer.start();
	}
	
	public class MyCanvas extends Canvas {
		public void paint(Graphics graphics) {
			Graphics2D g=(Graphics2D)graphics;
			int[] pos=new int[2];
			g.setColor(Color.BLACK);
			
			for(int i=0;i<=Row;i++) {
				g.drawLine(0, i*Side, Column*Side, i*Side);
				
			}
			for(int i=0;i<=Column;i++) {
				g.drawLine(i*Side, 0 , i*Side, Row*Side);
				
			}
			
			for(int i=0;i<V.size();i++) {
				pos=(int[]) V.get(i);
				g.fillRect(pos[0]*Side, pos[1]*Side, Side, Side);
			}
			pos=(int[]) F.get(0);
			g.setColor(Color.RED);
			g.fillOval(pos[0]*Side, pos[1]*Side, Side, Side);
		}
	}
	public class Move {
		private int[] point=new int[2];
		public Move() {
			point=(int[]) V.get(V.size()-1);
			pos_x=point[0];
			pos_y=point[1];
		}
		public void move_up() {
			//pos_y--;
			direct=1;
		}
		public void move_down() {
			//pos_y++;
			direct=2;
		}
		public void move_left() {
			//pos_x--;
			direct=3;
		}
		public void move_right() {
			//pos_x++;
			direct=4;
		}
	}
	public static void main(String[] args) {
		
		Snakey snakey=new Snakey(15,20);
		
	}
}