java 实现贪吃蛇小游戏

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

 完整实现代码:

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);
		
	}
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值