100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > 使用java编写贪吃蛇小游戏

使用java编写贪吃蛇小游戏

时间:2024-05-02 19:45:26

相关推荐

使用java编写贪吃蛇小游戏

小游戏(贪食蛇)

线程

面向对象

文件操作

内部类

数据库

步骤:

1–了解swing相关知识和小游戏设计

通过main方法启动初始化界面

逐步添加界面元素

蛇的构成(多个关节组成)和运动方式(确认好方向,去尾加头)食物的构成怎么出现(随机,位置与界面宽度和高度保持整除关系(余数为龙))蛇如何吃豆子(头部元素与豆子元素坐标重合)确定使用哪一种容器(LinkedList)2--配置界面宽度、高度3--画出蛇准备数据(一个关节就是一个对象 一条蛇是一个容器)初始多个关节数据(关联着)4--蛇运动(按照方向运动) 可以自定义线程、Timer方向控制(键盘方向键控制方向 、 snake按照要求的方向继续运动)360、撞墙、咬自己、调速、暂停5--蛇吃豆子(不能出现在蛇身上 、 不能出界)Bean初始化豆子画出豆子吃豆子(循环)身体长长6--记录每次游戏的成绩初始化数据通过配置文件配置(.properties、txt)7 关卡设计3关 (速度、分数、时间)

开始代码编程:

所需类: SnakeEle.java(蛇的类) , Bean.java(豆子类) , Constant(常量类) , Main(实现代码类) , config.properties配置文件

----------SnakeEle.java------------

package com.java0917.snake;

import java.io.Serializable;

/*

蛇身体关节元素 实体类

*/

public class SnakeEle implements Serializable{

private static final long serialVersionUID = -8508352375136668149L;

private int se_size;

private int se_x;

private int se_y;

public SnakeEle() {

super();

}

public SnakeEle(int se_size, int se_x, int se_y) {

super();

this.se_size = se_size;

this.se_x = se_x;

this.se_y = se_y;

}

public int getSe_size() {

return se_size;

}

public void setSe_size(int se_size) {

this.se_size = se_size;

}

public int getSe_x() {

return se_x;

}

public void setSe_x(int se_x) {

this.se_x = se_x;

}

public int getSe_y() {

return se_y;

}

public void setSe_y(int se_y) {

this.se_y = se_y;

}

@Override

public String toString() {

return “SnakeEle [se_size=” + se_size + “, se_x=” + se_x + “, se_y=” + se_y + “]”;

}

}

---------- Bean.java------------

package com.java0917.snake;

import java.io.Serializable;

public class Bean implements Serializable{

private static final long serialVersionUID = 1894645424910104002L;private int be_x;private int be_y;private int be_size;public Bean() {super();// TODO Auto-generated constructor stub}public Bean(int be_x, int be_y, int be_size) {super();this.be_x = be_x;this.be_y = be_y;this.be_size = be_size;}public int getBe_x() {return be_x;}public void setBe_x(int be_x) {this.be_x = be_x;}public int getBe_y() {return be_y;}public void setBe_y(int be_y) {this.be_y = be_y;}public int getBe_size() {return be_size;}public void setBe_size(int be_size) {this.be_size = be_size;}public static long getSerialversionuid() {return serialVersionUID;}@Overridepublic String toString() {return "Bean [be_x=" + be_x + ", be_y=" + be_y + ", be_size=" + be_size + "]";}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + be_size;result = prime * result + be_x;result = prime * result + be_y;return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Bean other = (Bean) obj;if (be_size != other.be_size)return false;if (be_x != other.be_x)return false;if (be_y != other.be_y)return false;return true;}

}

----------Constant.java------------

package com.java0917.snake;

/*

常亮接口

/

public interface Constant {

/

方向常亮*/

public static final String UP = “up”;

public static final String DOWN = “down”;

public static final String LEFT = “left”;

public static final String RIGHT = “right”;

public static final String TIP = “GAME OVER!”;

public static final String STOP = “stop” ;

public static final String PAUSE = “pause” ;

}

----------Main.java------------

package com.java0917.snake;

import java.awt.Color;

import java.awt.Font;

import java.awt.Graphics;

import java.awt.event.KeyEvent;

import java.awt.event.KeyListener;

import java.io.FileInputStream;

import java.io.IOException;

import java.util.Enumeration;

import java.util.LinkedList;

import java.util.Properties;

import java.util.Random;

import javax.swing.JFrame;

import javax.swing.JOptionPane;

import javax.swing.JPanel;

/**

1–初始化界面 2–初始化面板 3–面板与界面合并

*/

public class Main extends JFrame implements KeyListener {

private static final long serialVersionUID = -1803858577233572276L;private JPanel jp = null;// 窗口的宽度private int fw = 600;// 窗口的高度private int fh = 600;// 蛇身初始长度private int count = 10;// 蛇身元素,每个方块大小20private int se_size = 20;// 蛇的横坐标private int se_x = 100;// 蛇的纵坐标private int se_y = 200;// 豆子的大小private int bean_size = 20;// 豆子计数的初始化private int bean_count = 0;// 豆子集合private LinkedList<Bean> bean = new LinkedList<Bean>();// 蛇运动的默认方向为UP,向上运动private String direction = Constant.UP;// 弹框提示语private String tip = "";// 蛇的运动状态private String status = "";// 蛇运动的速度private long speed = 200;// 关卡初始化,第一关private int guanqia = 1;// 蛇运动的开始时间private long snake_start;// 蛇结束运动的时间private long snake_end;// 按下暂停键的开始时间private long snake_pause_start;// 松开暂停键的结束时间private long snake_pause_end;// 记录暂停的时间差private long snake_pause_time;// 蛇的集合private LinkedList<SnakeEle> snake = new LinkedList<SnakeEle>();// 总初识化方法private void init() {// 文件的读写方法initProperties();// 初始化蛇的方法initSnake();// 初始化豆子的方法initBean();// 初始化面板的方法initPanel();// 初始化窗口的方法initFrame();// 线程initThread();}// 文件的读写方法private void initProperties() {try {Properties pps = new Properties();/** load(InputStream inStream) 从输入流中读取属性列表,通过对指定的文件,进行装载来获取该文件中的所有键 - 值对*/pps.load(new FileInputStream("D:/A工具/java0917/src/config.properties"));Enumeration enu = pps.propertyNames();// 获取配置文件的名字// 要修改的变量fw = Integer.parseInt(pps.getProperty("fw"));fh = Integer.parseInt(pps.getProperty("fh"));speed = Integer.parseInt(pps.getProperty("speed"));while (enu.hasMoreElements()) {String strKey = (String) enu.nextElement();String strValue = pps.getProperty(strKey);System.out.println(strKey + "=" + strValue);}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}// 豆子的初始化方法private void initBean() {// 随机生成豆子,使其范围在窗口的范围里,窗口的宽高是600,所以豆子也在宽高为600的范围中// bean_x 豆子的横坐标,bean_y 豆子的纵坐标int bean_x = 20 * Math.round((new Random().nextInt(30)));int bean_y = 20 * Math.round((new Random().nextInt(30)));// 判断,豆子随机的产生不能出现在蛇身上if (!snake.contains(new SnakeEle(bean_size, bean_x, bean_y))) {bean.add(new Bean(bean_x, bean_y, bean_size));}}// 线程private void initThread() {new Thread(new Runnable() {@Overridepublic void run() {while (true) {// 如果蛇的头部,即第一个元素的横纵坐标与豆子的横纵坐标相等,重合if (snake.getFirst().getSe_x() == bean.getFirst().getBe_x()&& snake.getFirst().getSe_y() == bean.getFirst().getBe_y()) {// 先将豆子清除bean.clear();// 再调用初始化豆子方法initBean();// 对豆子进行计数bean_count++;// 同时再蛇的尾部添加元素snake.add(new SnakeEle(se_size, snake.getLast().getSe_x(), snake.getLast().getSe_y()));// 豆子的数量可以对3整除,就进入下一个关卡,关卡自增,速度变快if (bean_count % 3 == 0 && bean_count < 10) {// 关卡自增guanqia++;// 重画jp.repaint();// 弹框int op_result = JOptionPane.showConfirmDialog(jp, "下一关!", "恭喜你!",JOptionPane.OK_CANCEL_OPTION, JOptionPane.ERROR_MESSAGE);// 弹框有两个按钮,继续和取消,值分别为0和2if (op_result == 0) {// 重新开始游戏speed -= 50;}if (op_result == 2) {System.exit(0);}}}if ("".equalsIgnoreCase(status)) {// 判断是否咬到自己(即 头部坐标与身体上的任何一个元素的坐标重合)for (int i = 1; i < snake.size(); i++) {if (snake.getFirst().getSe_x() == snake.get(i).getSe_x()&& snake.getFirst().getSe_y() == snake.get(i).getSe_y()) {fangfa();}}// 操作snake容器中的元素// 移除最后一个snake.removeLast();// 判断头部向上是否出界if (direction.equalsIgnoreCase(Constant.UP)) {if (snake.getFirst().getSe_y() - se_size < 0) {// 如果新的头部y坐标出界 提示game over调用方法,弹出信息框fangfa();} elsesnake.addFirst(new SnakeEle(se_size, snake.getFirst().getSe_x(),snake.getFirst().getSe_y() - se_size));}// 判断头部向右是否出界if (direction.equalsIgnoreCase(Constant.RIGHT)) {// 如果新的头部y坐标出界 提示game overif (snake.getFirst().getSe_x() + se_size > fw) {// 如果新的头部y坐标出界 提示game over调用方法,弹出信息框fangfa();} elsesnake.addFirst(new SnakeEle(se_size, snake.getFirst().getSe_x() + se_size,snake.getFirst().getSe_y()));}// 判断头部向左是否出界if (direction.equalsIgnoreCase(Constant.LEFT)) {if (snake.getFirst().getSe_x() - se_size < 0) {// 如果新的头部y坐标出界 提示game over调用方法,弹出信息框fangfa();} elsesnake.addFirst(new SnakeEle(se_size, snake.getFirst().getSe_x() - se_size,snake.getFirst().getSe_y()));}// 判断头部向下是否出界if (direction.equalsIgnoreCase(Constant.DOWN)) {if (snake.getFirst().getSe_y() + se_size > fh) {// 如果新的头部y坐标出界 提示game over调用方法,弹出信息框fangfa();} elsesnake.addFirst(new SnakeEle(se_size, snake.getFirst().getSe_x(),snake.getFirst().getSe_y() + se_size));}// 重画jp.repaint();try {Thread.sleep(speed);} catch (InterruptedException e) {e.printStackTrace();}}}}}).start();}// 初始化蛇的方法private void initSnake() {// 创建多个有关联着的SankeEle对象// 添加到snake容器中for (int i = 0; i < count; i++) {snake.add(new SnakeEle(se_size, se_x, se_y + se_size * i));}// 记录蛇运动的开始时间snake_start = System.nanoTime();}// 初始化面板的方法private void initPanel() {jp = new JPanel() {private static final long serialVersionUID = 437643914299841L;@Overridepublic void paint(Graphics g) {super.paint(g);if (!"".equals(tip)) {g.setColor(Color.RED);g.setFont(new Font("", Font.BOLD, 40));g.drawString(tip, 160, 160);}for (int i = 0; i < snake.size(); i++) {if (i == 0) {g.setColor(Color.RED);} else {g.setColor(Color.white);}g.fill3DRect(snake.get(i).getSe_x(), snake.get(i).getSe_y(), snake.get(i).getSe_size(),snake.get(i).getSe_size(), true);}for (int i = 0; i < bean.size(); i++) {g.setColor(Color.orange);g.fill3DRect(bean.get(i).getBe_x(), bean.get(i).getBe_y(), bean.get(i).getBe_size(),bean.get(i).getBe_size(), true);}Integer bc = new Integer(bean_count);String s = bc.toString();g.setFont(new Font("", Font.BOLD, 30));g.setColor(Color.white);g.drawString("总长:", 50, 50);g.setColor(Color.red);g.drawString(s, 140, 50);Long sp = new Long(speed);String spe = Long.toString(sp);g.setColor(Color.white);g.drawString("速度:", 50, 80);g.setColor(Color.red);g.drawString(spe, 130, 80);g.setColor(Color.white);g.drawString("关卡:", 420, 50);Integer gq = new Integer(guanqia);String gg = gq.toString();g.setColor(Color.red);g.drawString(gg, 500, 50);g.setColor(Color.white);snake_end = System.nanoTime();g.drawString("时长:" + (snake_end - snake_start - snake_pause_time) / 1000000000, 50, 110);}};jp.setOpaque(false);}// 弹出提示信息框的方法private void fangfa() {tip = Constant.TIP;status = Constant.STOP;int op_result = JOptionPane.showConfirmDialog(jp, "GAME OVER!", "你挂了!", JOptionPane.OK_CANCEL_OPTION,JOptionPane.ERROR_MESSAGE);if (op_result == 0) {// 重新开始游戏tip = "";direction = Constant.UP;status = "";snake.clear();initSnake();bean_count = 0;guanqia = 1;speed = 200;}if (op_result == 2) {System.exit(0);}}// 初始化窗口的方法private void initFrame() {

// this.setTitle(“测试!”);

this.setSize(fw, fh);

this.getContentPane().setBackground(Color.BLACK);

this.setUndecorated(true);

this.add(jp);this.setAlwaysOnTop(true);this.setLocationRelativeTo(null);this.setVisible(true);// 当前对象具有多重省份 (这是由继承结构决定的)// 第一个this -- 窗口对象// 第二个this -- 键盘监听器this.addKeyListener(this);}public Main() {// 调用初始化的总方法init();}public static void main(String[] args) {new Main();}@Overridepublic void keyTyped(KeyEvent e) {// TODO Auto-generated method stub}@Overridepublic void keyPressed(KeyEvent e) {// 按下哪一个按键 停止虚拟机运行

// System.out.println(e.getKeyCode());

// 按下esc键 关停虚拟机

if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {

System.exit(0);

}

// 如果当前方向的值不是左键并且按下的键为右键,即蛇在向右运动时,按左键无效,不能立马掉头

if (!this.direction.equalsIgnoreCase(Constant.LEFT) && e.getKeyCode() == KeyEvent.VK_RIGHT) {

// 则当前方向向右

this.direction = Constant.RIGHT;

}

// 同上,即相对立的两个方向值不能同时存在

if (!this.direction.equalsIgnoreCase(Constant.RIGHT) && e.getKeyCode() == KeyEvent.VK_LEFT) {

this.direction = Constant.LEFT;

}

if (!this.direction.equalsIgnoreCase(Constant.UP) && e.getKeyCode() == KeyEvent.VK_DOWN) {

this.direction = Constant.DOWN;

}

if (!this.direction.equalsIgnoreCase(Constant.DOWN) && e.getKeyCode() == KeyEvent.VK_UP) {

this.direction = Constant.UP;

}

// 松开暂停键if (e.getKeyCode() == KeyEvent.VK_SPACE) {// 先检查status的值 如果是 "" 就修改成 pause 如果是 pause 就改成 ""switch (status) {// 重启case Constant.PAUSE:this.status = "";// 记录松开暂停键的结束时间snake_pause_end = System.nanoTime();// 暂停的时间差snake_pause_time += (snake_pause_end - snake_pause_start);break;case "":// 按下暂停键// 当前状态为按下暂停键this.status = Constant.PAUSE;// 记录按下暂停键的开始时间snake_pause_start = System.nanoTime();break;}}}@Overridepublic void keyReleased(KeyEvent e) {// TODO Auto-generated method stub}

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。