java贪吃蛇

不那么low的贪吃蛇...以及贪吃蛇寻路算法....算法这里暂时不提,只提贪吃蛇小游戏的制作

整体内容来说比扫雷简单...但是因为了有了图片,所以看起来肯定要比上一篇的扫雷高级很多......

然后我在代码中增加了寻路ai以及更高一层的UI界面....依然很丑的UI界面....

github:https://github.com/jnxxhzz/java-snake

———————————————————————————————————————————

因为贪吃蛇跟扫雷不同,扫雷是全局静态只需要修改每个按钮的状态,而贪吃蛇需要每次重画整个界面,所以将游戏整体与画布分开写在两个类里

Snake.java

设置基础窗口格式,并且添加画布到frame里

public class Snake {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		new Snake();
	}
	public Snake() {
		JFrame frame = new JFrame();
		//基本窗口设置
		frame.setBounds(10,10,1000,720);
		frame.setResizable(false);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setTitle("Snake");
		
		Snakebackground panel = new Snakebackground();
		
		frame.add(panel);
		
		
		frame.setVisible(true);
	}

}

Snakebackground类这里需要监听键盘输入keylistener和动作actionlistener

全局变量设置,这里的坐标跨度全部为25,因为蛇身蛇头的像素为25*25

ImageIcon upIcon = new ImageIcon("up.png");
	ImageIcon downIcon = new ImageIcon("down.png");
	ImageIcon leftIcon = new ImageIcon("left.png");
	ImageIcon rightIcon = new ImageIcon("right.png");
	ImageIcon[] headIcon = new ImageIcon[5];
	ImageIcon title = new ImageIcon("title.png");
	ImageIcon food = new ImageIcon("food.png");
	ImageIcon body = new ImageIcon("body.png");
	int dirright = 0;
	int dirleft = 1;
	int dirup = 2;
	int dirdown = 3;
	Timer timer = new Timer(100,this);
	
	//蛇的属性
	int[] snake_x = new int[750];
	int[] snake_y = new int[750];
	int len = 3;
	int direction = 1;
	int dirx[] = {25,-25, 0,  0};
	int diry[] = {0 ,  0,-25, 25};
	//0 1 2 3
	//R L U D
	
	//食物属性
	Random rand = new Random();
	int foodx = (rand.nextInt(36))*25 + 25;
	int foody = (rand.nextInt(24))*25 + 75;
	
	
	boolean gamestart = false;
	boolean gameover = false;
	

首先初始化初始蛇头以及gameover和gamestart

public void setup() {
		headIcon[0] = rightIcon;
		headIcon[1] = leftIcon;
		headIcon[2] = upIcon;
		headIcon[3] = downIcon;
		gamestart = false;
		gameover = false;
		
		len = 3;
		direction = dirright;
		snake_x[0] = 100;
		snake_y[0] = 100;
		snake_x[1] = 75;
		snake_y[1] = 100;
		snake_x[2] = 50;
		snake_y[2] = 100;
	}

增加监听以及增加timer计时器,也可以理解成隔多久刷新画布,也就是蛇的移动速度

public Snakebackground() {
		this.setFocusable(true); //获得焦点
		this.addKeyListener(this);
		//初始化snake
		setup();
		timer.start();
		
	}

然后在画布上画出整体框架,并且按照gameover和gamestart标记判断是否需要写出开始/暂停游戏的提示

public void paint(Graphics x) {
		super.paint(x);
		this.setBackground(Color.white);
		
		title.paintIcon(this, x, 25, 11);
		//背景色
		x.fillRect(25, 75, 900, 600);

		//蛇头
		headIcon[direction].paintIcon(this, x, snake_x[0], snake_y[0]);
		//蛇身
		for (int i=1;i<len;i++) body.paintIcon(this,x,snake_x[i],snake_y[i]);
	
		if (gameover == true) {
			x.setColor(Color.white);
			x.setFont(new Font("arial",Font.BOLD,30));
			x.drawString("Game over", 300, 300);
			x.drawString("Press space to Start again", 300, 400);
		}
		
		if (gamestart == false) {
			x.setColor(Color.white);
			x.setFont(new Font("arial",Font.BOLD,30));
			x.drawString("Press space to Start/Pause", 300, 300);
		}
		
		//食物
		food.paintIcon(this, x, foodx, foody);
		
		x.setColor(Color.white);
		x.setFont(new Font("arial",Font.PLAIN,20));
		x.drawString("Score: " + (len-3), 750, 30);
	}

计时器结束后,需要重启计时器,然后蛇整体移动一步,并且判断吃到食物或撞到自己的情况

public void actionPerformed(ActionEvent arg0) {
		// TODO Auto-generated method stub
		
		timer.start(); //重启timer
		//移动身体
		if (gamestart && !gameover) {
			for (int i = len; i > 0 ;i--) {
				snake_x[i] = snake_x[i-1];
				snake_y[i] = snake_y[i-1];
			}
			snake_x[0]+=dirx[direction];
			snake_y[0]+=diry[direction];
			if (snake_x[0] > 900) snake_x[0] = 25;
			if (snake_x[0] < 25)  snake_x[0] = 900;
			if (snake_y[0] > 650) snake_y[0] = 75;
			if (snake_y[0] < 75)  snake_y[0] = 650;
			
		}
		
		//吃到食物
		if (snake_x[0] == foodx && snake_y[0] == foody) {
			len++;
			foodx = (rand.nextInt(36))*25 + 25;
			foody = (rand.nextInt(24))*25 + 75;
		}
		
		//撞到障碍物
		for (int i=1;i<len;i++)
			if (snake_x[i] == snake_x[0] && snake_y[i] == snake_y[0]) {
				gameover = true;
			}

		repaint();
	}

最后通过键盘监听keylistener,控制蛇的方向,以及空格的作用,开始/暂停游戏,或在失败后重新开始游戏

public void keyPressed(KeyEvent e) {
		// TODO Auto-generated method stub
		int keycode = e.getKeyCode();
		
		if (keycode == KeyEvent.VK_SPACE) {
			if (gameover) {
				setup();
				
			}else {
				gamestart = !gamestart;
			}
		}
		if (direction!=dirdown && (keycode == KeyEvent.VK_UP || keycode == KeyEvent.VK_W)) {
			direction = dirup;
		}else if (direction!=dirup && (keycode == KeyEvent.VK_DOWN || keycode == KeyEvent.VK_S)) {
			direction = dirdown;
		}else if (direction!=dirleft && (keycode == KeyEvent.VK_RIGHT || keycode == KeyEvent.VK_D)) {
			direction = dirright;
		}else if (direction!=dirright && (keycode == KeyEvent.VK_LEFT ||  keycode == KeyEvent.VK_A)) {
			direction = dirleft;
		}
	}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值