Java ,实现贪吃蛇小游戏

初学Java GUI编程。所以做个贪吃蛇游戏来练习一下学习的东西。

 

对于Java这种面向对象的编程语言来说,在编写程序之前一定要做相应的分析,要分析需要研究哪些对象,这些对象中会有哪些属性和方法。

 

对与贪吃蛇这个小游戏,会包含这几种对象: 蛇、食物、游戏控制器、游戏面板。

下面我们就要分析在这些对象中都包含哪些属性和方法。

首先,先分析蛇这个对象:

         蛇会具有的属性为: 蛇的身体,蛇身体的颜色,蛇身体的长度,蛇的生命,蛇的运动方向

         在贪吃蛇这个小游戏中,是通过蛇在各个方向的运动寻找食物吃然后增长身体来保证游戏的正常进行的。

         这时在蛇这个对象中就会存在这样几个方法:蛇移动的方法,蛇吃东西的方法

然后分析食物这个对象:

         食物会有颜色和位置这两个属性,和生成食物的方法

初步的代码规划会这这个样子:

//Snake.java
package org.sysit.game.snake;

import java.awt.Color;
import java.awt.Point;
import java.util.ArrayList;
import java.util.List;

public class Snake {
	private int length;
	private Color color;
	private List<Point> body = new ArrayList();
	private boolean life = true;	

	/**
	 * 蛇运动方向
	 * @author ZHANGBING
	 *
	 */
	enum dir{
		UP, RIGHT, DOWN, LEFT
	};
	private dir snakeDir;
	

	/**
	 * 初始化蛇
	 * @param length 蛇身长度
	 */
	public Snake(int length) {
	}
	
	
	public void move(){
	}
	/**
	 * 判断蛇是否吃到食物
	 * @param head	蛇头
	 * @return
	 */
	public boolean isSnakeEatFood(Point head){
		return true;
		
	}
}


//Food.java
package org.sysit.game.snake;

import java.awt.Color;
import java.awt.Point;

public class Food {

	private Color color;
	private Point location;

	/**
	 * 生成食物的位置
	 * @param snake
	 * @return	返回Point
	 */
	public Point setLocation(Snake snake) {
		return null;
	}

}

接下来就是向各个方法中添加实现的代码了:

在蛇这个对象中,首先应该先将把蛇初始化的代码完成,在这里,我是以点的形式将蛇的身体的每个一节存入到蛇身体的List中

	/**
	 * 初始化蛇
	 * @param length 蛇身长度
	 */
	public Snake(int length) {
		
		this.length = length;
		this.color = Color.YELLOW;
		for(int i = length ; i > 0 ; i--){
			body.add(new Point(0, i-1));
		}
		snakeDir = dir.RIGHT;
	
	}

接下来最核心的应该算是蛇移动的方法了,我的代码还有很大一部分还需改进,我的方法是将多个操作合并到一个方法中了,大家和自己进行修改

	public void move(){
		Point head = new Point(body.get(0).x, body.get(0).y);
		switch(snakeDir){
		case UP:
			head.x --;
			break;
		case DOWN:
			head.x ++;
			break;
		case LEFT:
			head.y --;
			break;
		case RIGHT:
			head.y ++;
			break;
		}
		int canvas_width = SysConfig.CANVAS_WIDTH / SysConfig.STONE_WIDTH - 2;
		int canvas_height = SysConfig.CANVAS_HEIGHT/ SysConfig.STONE_HEIGHT - 2;
		if( head.x < 0  ||  head.x > canvas_height-1 ||  head.y < 0  ||  head.y > canvas_width-1 ){
			life = false;	//蛇die
			JOptionPane.showMessageDialog(null, "游戏结束");
			return;
		} else {
			body.add(0, head);
			if(isSnakeEatFood(head)){
				//没有吃到食物
				body.remove(body.size()-1);
			} else {
				getFood().setLocation(this);
				setScore(getScore()+10);
			}
			for(int i = 1 ; i <= body.size()-1 ; i++){
				Point point = body.get(i);
				if(point.x == head.x && point.y == head.y){
					life = false;
					JOptionPane.showMessageDialog(null, "撞到自己啦~游戏结束");
					//System.exit(0);
					return;
				}
				
			}
		}
	}
/**
	 * 判断蛇是否吃到食物
	 * @param head	蛇头
	 * @return
	 */
	public boolean isSnakeEatFood(Point head){
		
		if(this.food.getLocation().x == head.x && this.food.getLocation().y == head.y)
			return false;
		return true;
		
	}

然后在食物这个对象中,我们需要实现的只有声称食物的方法:

	/**
	 * 生成食物的位置
	 * @param snake
	 * @return	返回Point
	 */
	public Point setLocation(Snake snake) {
		location = new Point();
		
		int canvas_width = SysConfig.CANVAS_WIDTH / SysConfig.STONE_WIDTH - 2;
		int canvas_height = SysConfig.CANVAS_HEIGHT/ SysConfig.STONE_HEIGHT - 2;
		int temp = (int) (Math.random() * 1000) ;
	
		int rand = temp% (canvas_width * canvas_height - snake.getBody().size()) + 1;
		//int rand = temp% 50 + 1;
		boolean flag ;
		for(int i = 0 ; i < canvas_height ; i++){
			for(int j = 0 ; j < canvas_width ; j++){
				flag = true;
				for(Point point : snake.getBody()){
					//System.out.println("point: ("+ point.x + "," + point.y + ")");
					if(i == point.x && j == point.y){
						flag = false;
						break;
					}
				}
				if(flag){
					rand--;
					if(rand == 0){
						location.x = i;
						location.y = j;
						return location;
					}
				}
			}
		}
		return null;
	}


其他剩下来的操作就都是一些将蛇和食物联系起来的代码:

//GameController.java
package org.sysit.game.snake;

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

import javax.swing.JTextField;
import javax.swing.Timer;

public class GameController {
	

	private Ground ground;
	private Snake snake ;
	private Food food ;
	private Timer timer;
	private boolean pause = false;
	private int score = 0;
	private JTextField txtScore;

	
	
	public JTextField getTxtScore() {
		return txtScore;
	}
	public void setTxtScore(JTextField txtScore) {
		this.txtScore = txtScore;
	}
	public GameController(final Snake snake, Food food, final Ground ground) {
		this.snake = snake;
		this.food = food;
		this.ground = ground;
		timer = new Timer(200, new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if(snake.isLife()){
					snake.move();
					if(snake.isLife()){
						score = snake.getScore();
						getTxtScore().setText(score + "");
						ground.repaint();
					} else {
						timer.stop();
					}
				}
			}
		});
	}
	/**
	 * 游戏初始化
	 */
	public void init(){
		getTxtScore().setText("0");
		
	}
	
	/**
	 * 开始游戏
	 */
	public void startGame(){
		init();
		timer.start();
		ground.requestFocus();
	}
	
	/**
	 * 暂停游戏
	 */
	public void pauseGame() {
		if(!pause){
			timer.stop();
			pause = true;
		}
		ground.requestFocus();
	}

	/**
	 * 继续游戏
	 */
	public void resumeGame() {
		if(pause){
			timer.restart();
			pause = false;
		}
		ground.requestFocus();
	}
	
	
	public boolean isPause() {
		return pause;
	}

	public void setPause(boolean pause) {
		this.pause = pause;
	}
}

//Ground.java
package org.sysit.game.snake;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.List;

import org.sysit.game.snake.Snake.dir;

public class Ground extends Canvas {

	private Snake snake;
	private Food food;
	private Image iBuffer;
	
	public Ground() {
		setBounds(0, 0, SysConfig.CANVAS_WIDTH, SysConfig.CANVAS_HEIGHT);
		setBackground(Color.BLACK);
		addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				int keyCode = e.getKeyCode();
				switch(keyCode){
				case KeyEvent.VK_UP:
					snake.setSnakeDir(dir.UP);
					break;
				case KeyEvent.VK_DOWN:
					snake.setSnakeDir(dir.DOWN);
					break;
				case KeyEvent.VK_LEFT:
					snake.setSnakeDir(dir.LEFT);
					break;
				case KeyEvent.VK_RIGHT:
					snake.setSnakeDir(dir.RIGHT);
					break;
				}
			
			}
		
		});
	}

	public Snake getSnake() {
		return snake;
	}

	public void setSnake(Snake snake) {
		this.snake = snake;
	}

	public Food getFood() {
		return food;
	}

	public void setFood(Food food) {
		this.food = food;
	}
	
	/**
	 * 双缓冲技术解决屏幕闪烁问题
	 */
	@Override
	public void update(Graphics g) {
		if(iBuffer == null){
			iBuffer = createImage(this.getSize().width, this.getSize().height);
			
		}
		//if(gBuffer == null){
		Graphics gBuffer = iBuffer.getGraphics();
		//}
		gBuffer.setColor(getBackground());
		gBuffer.fillRect(0, 0, this.getSize().width, this.getSize().height);
		paint(gBuffer);
		gBuffer.dispose();
		g.drawImage(iBuffer, 0, 0, this);
	}
	
	/**
	 * 画墙
	 */
	public void drawWall(Graphics g) {

		g.setColor(Color.GRAY);
		int canvas_width = SysConfig.CANVAS_WIDTH / SysConfig.STONE_WIDTH;
		int canvas_height = SysConfig.CANVAS_HEIGHT / SysConfig.STONE_WIDTH;
		
		for (int i = 0; i < canvas_width ; i++) {
			g.fill3DRect(i * SysConfig.STONE_WIDTH, 0, SysConfig.STONE_WIDTH,
					SysConfig.STONE_HEIGHT, true);
		}
		for (int i = 0; i < canvas_width ; i++) {
			g.fill3DRect(i * SysConfig.STONE_WIDTH, SysConfig.CANVAS_HEIGHT
					- SysConfig.STONE_HEIGHT, SysConfig.STONE_WIDTH,
					SysConfig.STONE_HEIGHT, true);
		}

		for (int i = 0; i < canvas_height ; i++) {
			g.fill3DRect(0, i * SysConfig.STONE_WIDTH, SysConfig.STONE_WIDTH,
					SysConfig.STONE_HEIGHT, true);
		}

		for (int i = 0; i < canvas_height ; i++) {
			g.fill3DRect(SysConfig.CANVAS_WIDTH - SysConfig.STONE_WIDTH, i
					* SysConfig.STONE_WIDTH, SysConfig.STONE_WIDTH,
					SysConfig.STONE_HEIGHT, true);
		}
	}

	/**
	 * 画草地
	 */
	public void drawGrass(Graphics g) {
		g.setColor(Color.DARK_GRAY);

		for (int i = 1; i < SysConfig.CANVAS_WIDTH / SysConfig.STONE_WIDTH - 1; i++) {
			for (int j = 1; j < SysConfig.CANVAS_HEIGHT
					/ SysConfig.STONE_HEIGHT - 1; j++) {
				g.fill3DRect(i * SysConfig.STONE_WIDTH, j
						* SysConfig.STONE_HEIGHT, SysConfig.STONE_WIDTH,
						SysConfig.STONE_HEIGHT, true);
			}
		}
	}

	/**
	 * 画食物
	 */
	public void drawFood(Graphics g) {

		Point point = getFood().getLocation();
		//System.out.println("location : (" + point.x + "," +point.y +")");
		g.setColor(getFood().getColor());
		g.fill3DRect(( point.y + 1 ) * SysConfig.STONE_WIDTH, (point.x + 1)* SysConfig.STONE_HEIGHT, SysConfig.STONE_WIDTH,SysConfig.STONE_HEIGHT, true);

	}

	/**
	 * 画蛇
	 */
	public void drawSnake(Graphics g) {
		g.setColor(getSnake().getColor());
		List<Point> body = getSnake().getBody();
		for (Point point : body) {
			g.fill3DRect((point.y + 1) * SysConfig.STONE_WIDTH, (point.x + 1)
					* SysConfig.STONE_HEIGHT, SysConfig.STONE_WIDTH,
					SysConfig.STONE_HEIGHT, true);
		}
	}

	@Override
	public void paint(java.awt.Graphics g) {
		drawWall(g);
		drawGrass(g);
		//snake.move();
		if(snake != null){
			drawSnake(g);
		}
		if(food != null){
			drawFood(g);
		}
	};
}

//MainFrame.java
package org.sysit.game.snake;

import java.awt.BorderLayout;

public class MainFrame extends JFrame {
	private JButton start;
	private JButton pause;
	private JPanel panel;
	private JPanel showScore;
	private JLabel lblNewLabel;
	private JTextField txtScore;
	public MainFrame() {

		super("贪吃蛇");
		
		getContentPane().setLayout(new BorderLayout());
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		Ground ground = new Ground();
		//controller.setGround(ground);
		Snake snake = new Snake(3);
		ground.setSnake(snake);
		Food food = new Food();
		ground.setFood(food);
		snake.setFood(food);
		food.setLocation(snake);
			
		final GameController controller = new GameController(snake, food, ground);
			
		JPanel control = new JPanel();
		start = new JButton("开始");
		start.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				controller.startGame();
				pause.setEnabled(true);
			}
		});
		start.setSize(100, 50);
		
		pause = new JButton("暂停");
		pause.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				if(controller.isPause()){
					pause.setText("暂停");
					controller.resumeGame();	
				}else{
					pause.setText("继续");
					controller.pauseGame();
				}
			}
		});
		pause.setEnabled(false);
		pause.setSize(100, 50);
		
		control.add(start);
		control.add(pause);
		
		add(ground, BorderLayout.CENTER);
		add(control, BorderLayout.SOUTH);
		
		pack();
		
		panel = new JPanel();
		control.add(panel);
		panel.setLayout(null);
		
		showScore = new JPanel();
		getContentPane().add(showScore, BorderLayout.NORTH);
		showScore.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
		
		lblNewLabel = new JLabel("\u5206\u6570 : ");
		showScore.add(lblNewLabel);
		
		txtScore = new JTextField();
		showScore.add(txtScore);
		txtScore.setColumns(10);
		txtScore.setEditable(false);
		controller.setTxtScore(txtScore);
		
		Toolkit tool = Toolkit.getDefaultToolkit();
		Dimension dime = tool.getScreenSize();
		int screenWidth = dime.width;
		int screenHeight = dime.height;
		int frameWidth = SysConfig.CANVAS_WIDTH + 6;
		int frameHeight = SysConfig.CANVAS_HEIGHT + 94;
		
		setBounds((screenWidth - frameWidth)/2, (screenHeight - frameHeight)/2, frameWidth, frameHeight);
		setResizable(false);
		
		setVisible(true);
	}

	
	public static void main(String[] args) {
		new MainFrame();
	}
}

完整代码:http://download.csdn.net/detail/zhang__bing/4377159

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
import java.awt.*; import javax.swing.*; import java.awt.event.*; import java.util.*; public class snate extends JFrame implements KeyListener,Runnable { JLabel j; Canvas j1; public static final int canvasWidth = 200; public static final int canvasHeight = 300; public static final int nodeWidth = 10; public static final int nodeHeight = 10; //SnakeModel se=null; //222222 // boolean[][] matrix; LinkedList nodeArray = new LinkedList();//表 Node food;//节点 int maxX; int maxY; int direction = 2; boolean running = false; int timeInterval = 200; double speedChangeRate = 0.75; boolean paused = false; int score = 0; int countMove = 0; // UP and DOWN should be even // RIGHT and LEFT should be odd public static final int UP = 2; public static final int DOWN = 4; public static final int LEFT = 1; public static final int RIGHT = 3; snate() { super(); //setSize(500,400); Container c=getContentPane(); j=new JLabel("Score:"); c.add(j,BorderLayout.NORTH); j1=new Canvas(); j1.setSize(canvasWidth+1,canvasHeight+1); j1.addKeyListener(this); c.add(j1,BorderLayout.CENTER); JPanel p1 = new JPanel(); p1.setLayout(new BorderLayout()); JLabel j2; j2 = new JLabel("PageUp, PageDown for speed;", JLabel.CENTER); p1.add(j2, BorderLayout.NORTH); j2 = new JLabel("ENTER or R or S for start;", JLabel.CENTER); p1.add(j2, BorderLayout.CENTER); j2 = new JLabel("SPACE or P for pause",JLabel.CENTER); p1.add(j2, BorderLayout.SOUTH); c.add(p1,BorderLayout.SOUTH); addKeyListener(this); pack(); setResizable(false); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); // begin(); // //2222222 // this.gs = gs; this.maxX = maxX; this.maxY = maxY; // initial matirx matrix = new boolean[maxX][]; for(int i=0; i<maxX; ++i){ matrix[i] = new boolean[maxY]; Arrays.fill(matrix[i],false); } // initial the snake int initArrayLength = maxX > 20 ? 10 : maxX/2; for(int i = 0; i < initArrayLength; ++i){ int x = maxX/2+i; int y = maxY/2; nodeArray.addLast(new Node(x, y)); matrix[x][y] = true; } food = createFood(); matrix[food.x][food.y] = true; } public void keyPressed(KeyEvent e) { if(e.getKeyCode()==KeyEvent.VK_UP) { //se.changeDirection(SnakeModel.UP); } if(e.getKeyCode()==KeyEvent.VK_DOWN) { //se.changeDirection(SnakeModel.DOWN); } if(e.getKeyCode()==KeyEvent.VK_LEFT) { //se.changeDirection(SnakeModel.LEFT); } if(e.getKeyCode()==KeyEvent.VK_RIGHT) { //se.changeDirection(SnakeModel.RIGHT); } if(e.getKeyCode()==KeyEvent.VK_R||e.getKeyCode()==KeyEvent.VK_S||e.getKeyCode()==KeyEvent.VK_ENTER) { } } public void keyTyped(KeyEvent e) {} public void keyReleased(KeyEvent e) {} public void repaint() { Graphics g = j1.getGraphics(); //背景 g.setColor(Color.red); g.fillRect(0,0,canvasWidth,canvasHeight); //蛇 //g.setColor(Color.BLUE); } public void paint(Graphics g) { g.setColor(Color.red); g.fillRect(10,10,10,10); } // //222222 // public void changeDirection(int newDirection){ if (direction % 2 != newDirection % 2){ direction = newDirection; } } public boolean moveOn(){ Node n = (Node)nodeArray.getFirst(); int x = n.x; int y = n.y; switch(direction){ case UP: y--; break; case DOWN: y++; break; case LEFT: x--; break; case RIGHT: x++; break; } if ((0 <= x && x < maxX) && (0 <= y && y < maxY)){ if (matrix[x][y]){ if(x == food.x && y == food.y){ nodeArray.addFirst(food); int scoreGet = (10000 - 200 * countMove) / timeInterval; score += scoreGet > 0? scoreGet : 10; countMove = 0; food = createFood(); matrix[food.x][food.y] = true; return true; } else return false; } else{ nodeArray.addFirst(new Node(x,y)); matrix[x][y] = true; n = (Node)nodeArray.removeLast(); matrix[n.x][n.y] = false; countMove++; return true; } } return false; } public void run(){ running = true; while (running){ try{ Thread.sleep(timeInterval); } catch(Exception e){ break; } if(!paused){ if (moveOn()){ gs.repaint(); } else{ JOptionPane.showMessageDialog( null, "you failed", "Game Over", JOptionPane.INFORMATION_MESSAGE); break; } } } running = false; } private Node createFood(){ int x = 0; int y = 0; do{ Random r = new Random(); x = r.nextInt(maxX); y = r.nextInt(maxY); }while(matrix[x][y]); return new Node(x,y); } public void speedUp(){ timeInterval *= speedChangeRate; } public void speedDown(){ timeInterval /= speedChangeRate; } public void changePauseState(){ paused = !paused; } public String toString(){ String result = ""; for(int i=0; i<nodeArray.size(); ++i){ Node n = (Node)nodeArray.get(i); result += "[" + n.x + "," + n.y + "]"; } return result; } } class Node{ int x; int y; Node(int x, int y){ this.x = x; this.y = y; } } public static void main(String[] args) { //Graphics g=j1.getGraphics(); snate s=new snate(); //s.draw_something(g); //s.setVisible(true); } }
Java实现贪吃蛇小游戏可以使用Java Swing和AWT库来实现界面和交互,使用Java集合框架来实现蛇身体的存储和移动,以及使用定时器来控制游戏的速度和刷新。 具体实现步骤如下: 1. 定义一个Snake类代表蛇,包含蛇头的坐标、蛇的长度以及蛇的方向等属性,以及包含蛇身体的坐标列表等属性和方法。 2. 定义一个Food类代表食物,包含食物的坐标等属性和方法。 3. 定义一个GamePanel类代表游戏面板,继承自JPanel类,包含游戏的主要逻辑和交互,如蛇的移动、食物的生成和判断、游戏结束等。 4. 在GamePanel类中,使用定时器Timer来控制游戏的速度和刷新,以及使用Java集合框架来实现蛇身体的存储和移动,以及检测蛇头是否撞墙或撞到自己身体等。 下面是Java代码实现的伪代码: ```java // 定义Snake类 class Snake { // 蛇头的坐标 int x, y; // 蛇的长度 int length; // 蛇的方向 int direction; // 蛇身体的坐标列表 List<Point> body; // 蛇的移动方法 void move(); // 检测蛇头是否撞到自己身体的方法 boolean checkCollision(); } // 定义Food类 class Food { // 食物的坐标 int x, y; // 食物的生成方法 void generate(); } // 定义GamePanel类 class GamePanel extends JPanel implements ActionListener { // 蛇和食物的实例 Snake snake; Food food; // 定时器 Timer timer; // 构造方法 public GamePanel() { // 初始化蛇和食物 snake = new Snake(); food = new Food(); food.generate(); // 创建定时器 timer = new Timer(100, this); timer.start(); } // 绘制游戏界面的方法 void paintComponent(Graphics g); // 处理定时器事件的方法 void actionPerformed(ActionEvent e); // 处理按键事件的方法 void keyPressed(KeyEvent e); // 判断游戏是否结束的方法 boolean isGameOver(); } ``` 上述代码中,Snake类包含蛇头的坐标、长度和方向等属性,以及蛇身体的坐标列表和移动、检测撞墙和撞到自己身体等方法。Food类包含食物的坐标和生成方法。GamePanel类继承自JPanel类,包含游戏的主要逻辑和交互,如蛇的移动、食物的生成和判断、游戏结束等,并使用定时器控制游戏的速度和刷新。在main方法中,创建GamePanel实例并添加到JFrame中即可实现贪吃蛇小游戏

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值