Java贪吃蛇

游戏逻辑实现思路源自BV1QZ4y157rK
用java可视化,加上了消息队列机制优化手感

import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.Dimension;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingDeque;

class View extends JPanel{
	private static final long serialVersionUID = 01111111111L;
	private int width;
	private int height;
	private int cellSize;
	public int[][] grid;

	View(int width, int height, int cellSize, int[][] grid){
		this.width = width;
		this.height = height;
		this.cellSize = cellSize;
		this.grid = grid;
	}

	@Override
	public void paint(Graphics g){
		super.paint(g);
		int max_value = 0;
		for ( int row = 0; row<height; row++ ) {
			for ( int col = 0; col<width; col++ ) {
				max_value = grid[row][col] > max_value ? grid[row][col] : max_value;
			}
		}
		for ( int row = 0; row<height; row++ ) {
			for ( int col = 0; col<width; col++ ) {
				if ( grid[row][col] != 0 ) {
					if ( grid[row][col] > 0 ){
						int v = (int)(255 - ((double)grid[row][col]/max_value*200+55));
						g.setColor(new Color(v,v,v));
					} else if ( grid[row][col] == -1 ) {
						g.setColor(Color.red);
					}
					g.fillRect(col*cellSize, row*cellSize, cellSize, cellSize);
					// g.setColor(Color.white);
					// g.drawString(""+(grid[row][col]), col*cellSize+cellSize/2-5, row*cellSize+cellSize/2+5);
				}
				g.setColor(Color.gray);
				g.drawRect(col*cellSize, row*cellSize, cellSize, cellSize);
			}
		}
	}

	@Override
	public Dimension getPreferredSize() {
		return new Dimension(width*cellSize+1, height*cellSize+1);
	}
}

enum Direction{
	UP, DOWN, LEFT, RIGHT;
}
public class Snake{
	public static void main(String[] args) {
		final int size = 40;
		final int width = 1920/size;
		final int height = 1080/size;
		int[][] grid = new int[height][width];
		System.out.println(grid[0].length);
		System.out.println(grid.length);
		grid[0][0] = 3; // initial length // -1 food 0 empty >0 : snake
		// grid[3][3] = -1; // the first food in (3,3)
		for ( int col = 0; col < 10; col++ ) {
			grid[0][col+1] = -1;
		}
		int[][] directions = {
			{-1,0}, // up
			{1,0}, // down
			{0,-1}, // left
			{0,1} // right
		};
		boolean[] isPause = {false};
		int[] snakeHeadPos = {0,0};
		Direction currDirectionIdx = Direction.RIGHT;
		Queue<Direction> q = new LinkedBlockingDeque<Direction>();
		View view = new View(width, height, size, grid);

		JFrame frame = new JFrame();
		frame.setUndecorated(true);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setResizable(false);
		// frame.setTitle("Snake");
		frame.add(view);
		frame.pack();
		frame.setVisible(true);

		
		frame.addKeyListener(new KeyAdapter(){
			Hashtable<Integer, Direction> keyCode_to_Direction = new Hashtable<Integer, Direction>()
			{{
	            put(KeyEvent.VK_W, Direction.UP);
	            put(KeyEvent.VK_A, Direction.LEFT);
	            put(KeyEvent.VK_S, Direction.DOWN);
	            put(KeyEvent.VK_D, Direction.RIGHT);
	            put(KeyEvent.VK_UP, Direction.UP);
	            put(KeyEvent.VK_LEFT, Direction.LEFT);
	            put(KeyEvent.VK_DOWN, Direction.DOWN);
	            put(KeyEvent.VK_RIGHT, Direction.RIGHT);
	        }};
			@Override
			public void keyPressed(KeyEvent e){
				// System.out.println("key code is " + e.getKeyCode());
				if ( e.getKeyCode() == KeyEvent.VK_P ) {
					isPause[0] = !isPause[0];
					System.out.println("isPause : " + isPause[0]);

				}
				if ( keyCode_to_Direction.get(e.getKeyCode()) != null ) {
					q.add( keyCode_to_Direction.get(e.getKeyCode()) );
				}

			}
			
		});

		boolean x = true;
		while ( true ) {
			System.out.println(isPause[0]);
			if ( isPause[0] ) {
				continue;
			}
			while (q.size() > 0 && q.element()==currDirectionIdx ) {
				q.poll();
			}
			if (q.size() > 0 ) {
				Direction nextDir = q.poll();
				if ( (nextDir.ordinal() ^ 1) != currDirectionIdx.ordinal() ) {
					currDirectionIdx = nextDir;
				}
			}
			// System.out.println("turn to " + currDirectionIdx);
			int headValue = grid[snakeHeadPos[0]][snakeHeadPos[1]];
			snakeHeadPos[0] += directions[currDirectionIdx.ordinal()][0] + height;
			snakeHeadPos[1] += directions[currDirectionIdx.ordinal()][1] + width;
			snakeHeadPos[0] %= height;
			snakeHeadPos[1] %= width;
			int frontValue = grid[snakeHeadPos[0]][snakeHeadPos[1]];
			grid[snakeHeadPos[0]][snakeHeadPos[1]] = headValue + 1;

			if ( frontValue > 0 ) {
				break;
			}

			for ( int i=0; i<width; i++ ) {
				for ( int j=0; j<height; j++ ) {
					// System.out.printf("%d %d\n", i, j);
					if ( grid[j][i] > 0 ) {

						grid[j][i] -= (frontValue + 1);
						// grid[j][i]--;

						if ( grid[j][i] < 0 ) {
							grid[j][i] = 0;
						}
					}
				}
			}

			if(frontValue == -1){ // get the food
				int foodx;
				int foody;
				do{
					foodx = (int)(Math.random()*height);
					foody = (int)(Math.random()*width);
				} while ( grid[foodx][foody] != 0 );
				grid[foodx][foody] = -1;
			}

			// if ( snakeHeadPos[1] == width-1 || snakeHeadPos[1] == 0 ) {
			// 	if (x){
			// 		q.add(Direction.DOWN);
			// 		boolean _ = (snakeHeadPos[1] == 0) ? q.add(Direction.RIGHT) : q.add(Direction.LEFT);
			// 	}
			// 	x = !x;
			// }

			frame.repaint();
			try{
				Thread.sleep(200);
			} catch ( Exception e ) {
				e.printStackTrace();
			}
		}
	}
}

运行效果
↑↓← →或者wasd控制方向,p暂停
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值