老程序员教你一天时间完成Java迷宫小游戏

目录
  • 效果图
  • 实现思路
  • 迷宫算法(网上参考的)
  • 相关图示说明
  • 代码实现
    • 创建窗口
    • 创建菜单及菜单选项
  • 绘制迷宫的每个单元
    • 计算并打通迷宫
    • 绘制起点终点
  • 加入键盘移动监听
    • 收尾
  • 总结

效果图

实现思路

1.创建运行窗口。
2.创建菜单。
3.绘制迷宫的每个单元。
4.通过算法计算迷宫路径,并打通路径,形成迷宫。
5.绘制起点终点。
6.添加键盘事件控制起点方块移动。
7.收尾。

迷宫算法(网上参考的)

1.将起点作为当前迷宫单元并标记为已访问

2.当还存在未标记的迷宫单元,进行循环

1).如果当前迷宫单元有未被访问过的的相邻的迷宫单元

(1).随机选择一个未访问的相邻迷宫单元

(2).将当前迷宫单元入栈

(3).移除当前迷宫单元与相邻迷宫单元的墙

(4).标记相邻迷宫单元并用它作为当前迷宫单元

2).如果当前迷宫单元不存在未访问的相邻迷宫单元,并且栈不空

(1).栈顶的迷宫单元出栈

(2).令其成为当前迷宫单元

**这个算法叫做“深度优先”,简单来说,就是从起点开始走,寻找它的上下左右4个邻居,然后随机一个走,到走不通的时候就返回上一步继续走,直到全部单元都走完。 **

相关图示说明

每个单元的墙,分为上墙、右墙、下墙、左墙,把这些墙用长度为4的数组表示,元素的值为true则表示墙存在,否则墙不存在,代码里数组的下标方式来确定墙是否存在。

单元是根据行列来创建的,会用到双循环,类似表格,比如第二行用 i 来表示的话就是 1,第3列用 j 来表示就是2,那第二行第3列的元素组合起来就是(1,2)

那同理它的上邻居就是(0,2),右邻居(1,3),下邻居(2,2),左邻居(1,1),也就是上下邻居是 i 减加1,左右邻居是 j 减加1。

正方形4个点的坐标分别为(x1,y1)(x2,y2)(x3,y3)(x4,y4),计算坐标的公式为(其中start为相对偏移量,为了让迷宫两边有些空隙):

//i代表行 j代表列 h为单元高度
//左上角坐标
this.x1=start+j*h;
this.y1=start+i*h;
//右上角坐标
this.x2=start+(j+1)*h;
this.y2=start+i*h;
//右下角坐标
this.x3=start+(j+1)*h;
this.y3=start+(i+1)*h;
//左下角坐标
this.x4=start+j*h;
this.y4=start+(i+1)*h;

计算坐标,假如每个正方形的宽高都是40,那么(1,2)这个单元的坐标如下图:

5. 墙的处理,之前说到墙是以一个4个元素的数组来表示的,比如数组为:[true,true,true,true],则图为:

如果数组为[false,true,true,true],则图为:

6. 如果要联通右边的邻居要怎么做呢?当前单元去除右墙,右边单元去除左墙,这样就联通了。

去除后就这样,以此类推

代码实现

创建窗口

首先创建一个游戏窗体类GameFrame,继承至JFrame,用来显示在屏幕上(window的对象),每个游戏都有一个窗口,设置好窗口标题、尺寸、布局等就可以。

import javax.swing.JFrame;
/**
 *窗体类
 */
public class GameFrame extends JFrame {
	//构造方法
	public GameFrame(){
		setTitle("迷宫");//设置标题
		setSize(420, 470);//设置窗体大小
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭后进程退出
		setLocationRelativeTo(null);//居中
		setResizable(false);//不允许变大
		//setVisible(true);//设置显示窗体
	}
}

创建面板容器GamePanel继承至JPanel

import javax.swing.JMenuBar;
import javax.swing.JPanel;
/*
 * 画布类
 */
public class GamePanel extends JPanel{
	private JMenuBar jmb = null;
	private GameFrame mainFrame = null;
	private GamePanel panel = null;
	private String gameFlag="start";//游戏状态
	//构造方法
	public GamePanel(GameFrame mainFrame){
		this.setLayout(null);
		this.setOpaque(false);
		this.mainFrame=mainFrame;
		this.panel =this;
	}
}

再创建一个Main类,来启动这个窗口。

//Main类
public class Main {
	public static void main(String[] args) {
		GameFrame frame = new GameFrame();
		GamePanel panel = new GamePanel(frame);
		frame.add(panel);
		frame.setVisible(true);
	}
}

右键执行这个Main类,窗口建出来了

创建菜单及菜单选项

创建菜单

private Font createFont(){
	return new Font("思源宋体",Font.BOLD,18);
}
//创建菜单
private void createMenu() {
	//创建JMenuBar
	jmb = new JMenuBar();
	//取得字体
	Font tFont = createFont();
	//创建游戏选项
	JMenu jMenu1 = new JMenu("游戏");
	jMenu1.setFont(tFont);
	//创建帮助选项
	JMenu jMenu2 = new JMenu("帮助");
	jMenu2.setFont(tFont);
	JMenuItem jmi1 = new JMenuItem("新游戏");
	jmi1.setFont(tFont);
	JMenuItem jmi2 = new JMenuItem("退出");
	jmi2.setFont(tFont);
	//jmi1 jmi2添加到菜单项“游戏”中
	jMenu1.add(jmi1);
	jMenu1.add(jmi2);
	JMenuItem jmi3 = new JMenuItem("操作帮助");
	jmi3.setFont(tFont);
	JMenuItem jmi4 = new JMenuItem("胜利条件");
	jmi4.setFont(tFont);
	//jmi13 jmi4添加到菜单项“游戏”中
	jMenu2.add(jmi3);
	jMenu2.add(jmi4);

	jmb.add(jMenu1);
	jmb.add(jMenu2);
	mainFrame.setJMenuBar(jmb);
	//添加监听
	jmi1.addActionListener(this);
	jmi2.addActionListener(this);
	jmi3.addActionListener(this);
	jmi4.addActionListener(this);
	//设置指令
	jmi1.setActionCommand("restart");
	jmi2.setActionCommand("exit");
	jmi3.setActionCommand("help");
	jmi4.setActionCommand("win");
}

实现ActionListener并重写方法actionPerformed

此时GamePanel是报错的,需重写actionPerformed方法。

actionPerformed方法的实现

@Override
public void actionPerformed(ActionEvent e) {
	String command = e.getActionCommand();
	System.out.println(command);
	UIManager.put("OptionPane.buttonFont", new FontUIResource(new Font("思源宋体", Font.ITALIC, 18)));
	UIManager.put("OptionPane.messageFont", new FontUIResource(new Font("思源宋体", Font.ITALIC, 18)));
	if ("exit".equals(command)) {
		Object[] options = { "确定", "取消" };
		int response = JOptionPane.showOptionDialog(this, "您确认要退出吗", "",
				JOptionPane.YES_OPTION, JOptionPane.QUESTION_MESSAGE, null,
				options, options[0]);
		if (response == 0) {
			System.exit(0);
		}
	}else if("restart".equals(command)){
		restart();
	}else if("help".equals(command)){
		JOptionPane.showMessageDialog(null, "通过键盘的上下左右来移动",
				"提示!", JOptionPane.INFORMATION_MESSAGE);
	}else if("win".equals(command)){
		JOptionPane.showMessageDialog(null, "移动到终点获得胜利",
				"提示!", JOptionPane.INFORMATION_MESSAGE);
	}
}

此时的GamePanel代码如下:

package main;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.plaf.FontUIResource;
/*
 * 画布类
 */
public class GamePanel extends JPanel implements ActionListener{
	private JMenuBar jmb = null;
	private GameFrame mainFrame = null;
	private GamePanel panel = null;
	private String gameFlag="start";//游戏状态
	//构造方法
	public GamePanel(GameFrame mainFrame){
		this.setLayout(null);
		this.setOpaque(false);
		this.mainFrame=mainFrame;
		this.panel =this;
		//创建菜单
		createMenu();
	}
	private Font createFont(){
		return new Font("思源宋体",Font.BOLD,18);
	}
	//创建菜单
	private void createMenu() {
		//创建JMenuBar
		jmb = new JMenuBar();
		//取得字体
		Font tFont = createFont();
		//创建游戏选项
		JMenu jMenu1 = new JMenu("游戏");
		jMenu1.setFont(tFont);
		//创建帮助选项
		JMenu jMenu2 = new JMenu("帮助");
		jMenu2.setFont(tFont);
		JMenuItem jmi1 = new JMenuItem("新游戏");
		jmi1.setFont(tFont);
		JMenuItem jmi2 = new JMenuItem("退出");
		jmi2.setFont(tFont);
		//jmi1 jmi2添加到菜单项“游戏”中
		jMenu1.add(jmi1);
		jMenu1.add(jmi2);
		JMenuItem jmi3 = new JMenuItem("操作帮助");
		jmi3.setFont(tFont);
		JMenuItem jmi4 = new JMenuItem("胜利条件");
		jmi4.setFont(tFont);
		//jmi13 jmi4添加到菜单项“游戏”中
		jMenu2.add(jmi3);
		jMenu2.add(jmi4);

		jmb.add(jMenu1);
		jmb.add(jMenu2);
		mainFrame.setJMenuBar(jmb);
		//添加监听
		jmi1.addActionListener(this);
		jmi2.addActionListener(this);
		jmi3.addActionListener(this);
		jmi4.addActionListener(this);
		//设置指令
		jmi1.setActionCommand("restart");
		jmi2.setActionCommand("exit");
		jmi3.setActionCommand("help");
		jmi4.setActionCommand("win");
	}
	@Override
	public void actionPerformed(ActionEvent e) {
		String command = e.getActionCommand();
		System.out.println(command);
		UIManager.put("OptionPane.buttonFont", new FontUIResource(new Font("思源宋体", Font.ITALIC, 18)));
		UIManager.put("OptionPane.messageFont", new FontUIResource(new Font("思源宋体", Font.ITALIC, 18)));
		if ("exit".equals(command)) {
			Object[] options = { "确定", "取消" };
			int response = JOptionPane.showOptionDialog(this, "您确认要退出吗", "",
					JOptionPane.YES_OPTION, JOptionPane.QUESTION_MESSAGE, null,
					options, options[0]);
			if (response == 0) {
				System.exit(0);
			}
		}else if("restart".equals(command)){
			restart();
		}else if("help".equals(command)){
			JOptionPane.showMessageDialog(null, "通过键盘的上下左右来移动",
					"提示!", JOptionPane.INFORMATION_MESSAGE);
		}else if("win".equals(command)){
			JOptionPane.showMessageDialog(null, "移动到终点获得胜利",
					"提示!", JOptionPane.INFORMATION_MESSAGE);
		}
	}
	void restart(){
	}
}

运行它

绘制迷宫的每个单元

初始化相关参数

public final int ROWS=20;//行
public final int COLS=20;//列
public final int H=20;//每一块的宽高
Block[][] blocks = null;//存储每个单元的二维数组

创建迷宫单元类(如果对坐标计算不明白,可以往上翻,有图示说明解释)

import java.awt.Graphics;
import java.util.ArrayList;
import java.util.List;
/*
 * 迷宫单元类
 */
public class Block {
	private GamePanel panel = null;
	private int i=0;//二维数组的下标i
	private int j=0;//二维数组的下标j
	private int h=0;//宽高
	private int start=6;//偏移像素
	//4个顶点坐标
	private int x1=0;//x1坐标
	private int y1=0;//y1坐标
	private int x2=0;//x2坐标
	private int y2=0;//y2坐标
	private int x3=0;//x3坐标
	private int y3=0;//y3坐标
	private int x4=0;//x4坐标
	private int y4=0;//y4坐标
	//上下左右4个墙是否显示,true:显示,false:隐藏
	boolean[] walls=new boolean[4];
	private boolean visited=false;//是否被访问
	//构造
	public Block(int i,int j,int h,GamePanel panel){
		this.i=i;
		this.j=j;
		this.h=h;
		this.panel=panel;
		//计算4个顶点的坐标
		init();
	}
	//计算4个顶点的坐标
	private void init() {
		//i代表行 j代表列
		//左上角坐标
		this.x1=start+j*h;
		this.y1=start+i*h;
		//右上角坐标
		this.x2=start+(j+1)*h;
		this.y2=start+i*h;
		//右下角坐标
		this.x3=start+(j+1)*h;
		this.y3=start+(i+1)*h;
		//左下角坐标
		this.x4=start+j*h;
		this.y4=start+(i+1)*h;
		//默认上下左右4个墙都显示
		walls[0]=true;
		walls[1]=true;
		walls[2]=true;
		walls[3]=true;
	}
	//绘制指示器的方法
	public void draw(Graphics g) {
		//绘制迷宫块
		drawBlock(g);
	}
	//绘制迷宫块
	private void drawBlock(Graphics g) {
		//判断上、右、下、左 的墙,true的话墙就会有,否则墙就没有
		boolean top    = walls[0];
		boolean right  = walls[1];
		boolean bottom = walls[2];
		boolean left   = walls[3];
		if(top){//绘制上墙
			g.drawLine(x1, y1, x2, y2);
		}
		if(right){//绘制右墙
			g.drawLine(x2, y2, x3, y3);
		}
		if(bottom){//绘制下墙
			g.drawLine(x3, y3, x4, y4);
		}
		if(left){//绘制左墙
			g.drawLine(x4, y4, x1, y1);
		}
	}
}

在GamePanel类中创建方法createBlocks

//创建数组内容
private void createBlocks() {
	blocks = new Block[ROWS][COLS];
	Block block ;
	for (int i = 0; i < ROWS; i++) {
		for (int j = 0; j < COLS; j++) {
			block = new Block(i, j,H,this);
			blocks[i][j]=block;
		}
	}
}

在构造函数中调用此方法

//构造方法
public GamePanel(GameFrame mainFrame){
	this.setLayout(null);
	this.setOpaque(false);
	this.mainFrame=mainFrame;
	this.panel =this;
	//创建菜单
	createMenu();
	//创建数组内容
	createBlocks();
}

在GamePanel中重新paint方法,绘制这些方块

public void paint(Graphics g) {
	super.paint(g);
	//绘制网格
	drawBlock(g);
}
//绘制迷宫块
private void drawBlock(Graphics g) {
	Block block ;
	for (int i = 0; i < ROWS; i++) {
		for (int j = 0; j < COLS; j++) {
			block = blocks[i][j];
			if(block!=null){
				block.draw(g);
			}
		}
	}
}

运行可以看到一个个的方形绘制出来了

计算并打通迷宫

给每个单元都增加邻居查找方法(Block类中)

//查找当前单元是否有未被访问的邻居单元
public List<Block> findNeighbors() {
	//邻居分为上下左右
	List<Block> res= new ArrayList<Block>();//返回的数组
	Block top    = this.getNeighbor(0,false);
	Block right  = this.getNeighbor(1,false);
	Block bottom = this.getNeighbor(2,false);
	Block left   = this.getNeighbor(3,false);
	if(top!=null){
		res.add(top);
	}
	if(right!=null){
		res.add(right);
	}
	if(bottom!=null){
		res.add(bottom);
	}
	if(left!=null){
		res.add(left);
	}
	return res;//返回邻居数组
}
//根据方向,获得邻居
public Block getNeighbor(int type,boolean lose_visited) {
	Block neighbor;
	int ti=0,tj=0;
	if(type==0){
		ti = this.i-1;
		tj = this.j;
	}else if(type==1){
		ti = this.i;
		tj = this.j+1;
	}else if(type==2){
		ti = this.i+1;
		tj = this.j;
	}else if(type==3){
		ti = this.i;
		tj = this.j-1;
	}
	Block[][] blocks = panel.blocks;
	if(ti<0 || tj<0 || ti>=panel.ROWS || tj>=panel.COLS){//超出边界了
		neighbor = null;
	}else{
		//首先找到这个邻居
		neighbor = blocks[ti][tj];
		//判断是否被访问,如果被访问了返回null
		if(neighbor.visited && !lose_visited){//lose_visited等于true表示忽略访问
			neighbor = null;
		}
	}
	return neighbor;
}

计算

跟着算法来写的代码,唯一要注意的是我设置了一个值unVisitedCount,初始值为所有单元的数量,每当一个单元被标记为已访问后,这个值就递减1,当值为0后就终止循环,结束算法。

//线路的计算处理
private void computed(){
	/*
	1.将起点作为当前迷宫单元并标记为已访问
	2.当还存在未标记的迷宫单元,进行循环
		1).如果当前迷宫单元有未被访问过的的相邻的迷宫单元
			(1).随机选择一个未访问的相邻迷宫单元
			(2).将当前迷宫单元入栈
			(3).移除当前迷宫单元与相邻迷宫单元的墙
			(4).标记相邻迷宫单元并用它作为当前迷宫单元
		2).如果当前迷宫单元不存在未访问的相邻迷宫单元,并且栈不空
			(1).栈顶的迷宫单元出栈
			(2).令其成为当前迷宫单元
	 */
	Random random = new Random();
	Stack<Block> stack = new Stack<Block>();//栈
	Block current = blocks[0][0];//取第一个为当前单元
	current.setVisited(true);//标记为已访问
	int unVisitedCount=ROWS*COLS-1;//因为第一个已经设置为访问了
	List<Block> neighbors ;//定义邻居
	Block next;
	while(unVisitedCount>0){
		neighbors = current.findNeighbors();//查找邻居集合(未被访问的)
		if(neighbors.size()>0){//如果当前迷宫单元有未被访问过的的相邻的迷宫单元
			//随机选择一个未访问的相邻迷宫单元
			int index = random.nextInt(neighbors.size());
			next = neighbors.get(index);
			//将当前迷宫单元入栈
			stack.push(current);
			//移除当前迷宫单元与相邻迷宫单元的墙
			this.removeWall(current,next);
			//标记相邻迷宫单元并用它作为当前迷宫单元
			next.setVisited(true);
			//标记一个为访问,则计数器递减1
			unVisitedCount--;//递减
			current = next;
		}else if(!stack.isEmpty()){//如果当前迷宫单元不存在未访问的相邻迷宫单元,并且栈不空
			/*
				1.栈顶的迷宫单元出栈
				2.令其成为当前迷宫单元
			*/
			Block cell = stack.pop();
			current = cell;
		}
	}
}

移除墙

//移除当前迷宫单元与相邻迷宫单元的墙
private void removeWall(Block current, Block next) {
	if(current.getI()==next.getI()){//横向邻居
		if(current.getJ()>next.getJ()){//匹配到的是左边邻居
			//左边邻居的话,要移除自己的左墙和邻居的右墙
			current.walls[3]=false;
			next.walls[1]=false;
		}else{//匹配到的是右边邻居
			//右边邻居的话,要移除自己的右墙和邻居的左墙
			current.walls[1]=false;
			next.walls[3]=false;
		}
	}else if(current.getJ()==next.getJ()){//纵向邻居
		if(current.getI()>next.getI()){//匹配到的是上边邻居
			//上边邻居的话,要移除自己的上墙和邻居的下墙
			current.walls[0]=false;
			next.walls[2]=false;
		}else{//匹配到的是下边邻居
			//下边邻居的话,要移除自己的下墙和邻居的上墙
			current.walls[2]=false;
			next.walls[0]=false;
		}
	}
}

在构造函数中调用computed方法

//构造方法
public GamePanel(GameFrame mainFrame){
	this.setLayout(null);
	this.setOpaque(false);
	this.mainFrame=mainFrame;
	this.panel =this;
	//创建菜单
	createMenu();
	//创建数组内容
	createBlocks();
	//计算处理线路
	computed();
}

运行效果

绘制起点终点

创建Rect类

package main;
import java.awt.Color;
import java.awt.Graphics;
//开始结束方块
public class Rect {
	private int i=0;//二维数组的下标i
	private int j=0;//二维数组的下标j
	private int x=0;//x坐标
	private int y=0;//y坐标
	private int h=0;//宽高
	private int start=6;//偏移像素
	private String type="";//start end
	public Rect(int i,int j,int h,String type){
		this.i=i;
		this.j=j;
		this.h=h;
		this.type=type;
	}
	//初始化
	private void init() {
		this.x=start+j*h+2;
		this.y=start+i*h+2;
	}
	//绘制
	void draw(Graphics g){
		//计算x、y坐标
		init();
		Color oColor = g.getColor();
		if("start".equals(type)){//红色
			g.setColor(Color.red);
		}else{
			g.setColor(Color.blue);
		}
		g.fillRect(x, y, h-3, h-3);
		g.setColor(oColor);
	}
	//移动
	public void move(int type, Block[][] blocks,GamePanel panel) {
		//根据当前start方形,获得对应的迷宫单元
		Block cur = blocks[this.i][this.j];
		boolean wall = cur.walls[type];//得到对应的那面墙
		if(!wall){
			//得到移动方块对应的单元
			Block next = cur.getNeighbor(type,true);
			if(next!=null){
				this.i = next.getI();
				this.j = next.getJ();
				panel.repaint();
				//判断如果i,j等于终点的,则表示获得成功
				if(this.i==panel.end.i && this.j==panel.end.j){
					panel.gameWin();
				}
			}
		}
	}
	public int getI() {
		return i;
	}
	public void setI(int i) {
		this.i = i;
	}
	public int getJ() {
		return j;
	}
	public void setJ(int j) {
		this.j = j;
	}
}

在GamePanel类中创建方法,并在构造中调用。

//创建开始结束的方形
private void createRects() {
	start = new Rect(0, 0, H, "start") ;
	end = new Rect(ROWS-1, COLS-1, H, "end") ;
}
//构造方法
public GamePanel(GameFrame mainFrame){
	this.setLayout(null);
	this.setOpaque(false);
	this.mainFrame=mainFrame;
	this.panel =this;
	//创建菜单
	createMenu();
	//创建数组内容
	createBlocks();
	//计算处理线路
	computed();
	//创建开始结束的方形
	createRects();
}

在paint方法中绘制

@Override
public void paint(Graphics g) {
	super.paint(g);
	//绘制网格
	drawBlock(g);
	//绘制开始结束方向
	drawRect(g);
}
//绘制开始结束方块
private void drawRect(Graphics g) {
	end.draw(g);
	start.draw(g);
}

运行一下

加入键盘移动监听

创建监听方法

//添加键盘监听
private void createKeyListener() {
	KeyAdapter l = new KeyAdapter() {
		//按下
		@Override
		public void keyPressed(KeyEvent e) {
			if(!"start".equals(gameFlag)) return ;
			int key = e.getKeyCode();
			switch (key) {
				//向上
				case KeyEvent.VK_UP:
				case KeyEvent.VK_W:
					if(start!=null) start.move(0,blocks,panel);
					break;
				//向右
				case KeyEvent.VK_RIGHT:
				case KeyEvent.VK_D:
					if(start!=null) start.move(1,blocks,panel);
					break;
				//向下
				case KeyEvent.VK_DOWN:
				case KeyEvent.VK_S:
					if(start!=null) start.move(2,blocks,panel);
					break;
				//向左
				case KeyEvent.VK_LEFT:
				case KeyEvent.VK_A:
					if(start!=null) start.move(3,blocks,panel);
					break;
			}
		}
		//松开
		@Override
		public void keyReleased(KeyEvent e) {
		}
	};
	//给主frame添加键盘监听
	mainFrame.addKeyListener(l);
}

在构造中调用

//构造方法
public GamePanel(GameFrame mainFrame){
	this.setLayout(null);
	this.setOpaque(false);
	this.mainFrame=mainFrame;
	this.panel =this;
	//创建菜单
	createMenu();
	//创建数组内容
	createBlocks();
	//计算处理线路
	computed();
	//创建开始结束的方形
	createRects();
	//添加键盘事件监听
	createKeyListener();
}

运行

收尾

此时代码已经基本完成,加入游戏胜利、重新开始等方法即可

//重新开始
void restart() {
	/*参数重置
	1.游戏状态
	2.迷宫单元重置
	3.重新计算线路
	*/
	//1.游戏状态
	gameFlag="start";
	//2.迷宫单元重置
	Block block ;
	for (int i = 0; i < ROWS; i++) {
		for (int j = 0; j < COLS; j++) {
			block = blocks[i][j];
			if(block!=null){
				block.setVisited(false);
				block.walls[0]=true;
				block.walls[1]=true;
				block.walls[2]=true;
				block.walls[3]=true;
			}
		}
	}
	//3.计算处理线路
	computed();
	//开始方块归零
	start.setI(0);
	start.setJ(0);
	//重绘
	repaint();
}

总结

本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • java实现弹球小游戏

    GUI实现弹球小游戏,供大家参考,具体内容如下 先看一下游戏效果图. 一个简单的Demo.也比较简单,新手试着做一做完善改进. 源代码 import Com.Style.FontStyle; import javax.swing.*; import java.awt.*; import java.awt.event.*; /** * @Author: 冀十三 * @DescIption: 弹球小游戏 * @Date:2021--06--10--17:08 */ public class Demo

  • Java实现斗地主小游戏

    本文实例为大家分享了Java实现斗地主小游戏的具体代码,供大家参考,具体内容如下 原理图: 斗地主过程: *  1.组合牌  *  2.洗牌  *  3.发牌  *  4.看牌 代码实现: package itcast.demo6; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; public class DouDiZhu { public static void main(S

  • Java实现三子棋小游戏

    # 前言 之前在学习C语言的时候,做过一个三子棋的小游戏,最近开始学习Java,就想着能不能用Java再把之前的练习重新实现一边,既然有这个想法了,那就开始行动啦~. 再写的过程中,能感觉到面向过程语言和面向对象语言的一些差异.最让我头疼的是类的设计,感觉不仅得考虑功能得实现,还需要考虑类之间得逻辑关系,函数的功能是单一的,但函数与函数之间谈不上什么关系,你要用的上我,你就用,不用就拉倒.类在设计的时候需要考虑将哪些方法封装在哪个类当中,封装位置不合适,尽管也可能实现功能,但总感觉怪怪的.自己最

  • java五子棋小游戏实现代码

    前言 之前学完java基础课程,试着简单做了一下java的一个五子棋小游戏,记录下来. 界面 由于直接用的java库中的一些基本控件写的一个GUI,并没有做过多优化,感觉比较丑 下面是界面展示: 黑子先行,但是我这边简化规则,并没有考虑黑子先行的一些禁手. 下面直接贴代码 接口类 我把五子棋界面的一些常量都定义在了这个接口类中,包括棋盘的起始坐标,棋盘线的间距和棋子半径 public interface constant { int[][] chessLocation = new int[15]

  • 使用java实现猜拳小游戏

    本文实例为大家分享了java实现猜拳小游戏的具体代码,供大家参考,具体内容如下 实现下图要求 public class User { private String u_name; private int u_score; public User() { super(); } public User(String name, int score) { super(); this.u_name = name; this.u_score = score; } public String getName

  • 老程序员教你一天时间完成Java迷宫小游戏

    目录 效果图 实现思路 迷宫算法(网上参考的) 相关图示说明 代码实现 创建窗口 创建菜单及菜单选项 绘制迷宫的每个单元 计算并打通迷宫 绘制起点终点 加入键盘移动监听 收尾 总结 效果图 实现思路 1.创建运行窗口. 2.创建菜单. 3.绘制迷宫的每个单元. 4.通过算法计算迷宫路径,并打通路径,形成迷宫. 5.绘制起点终点. 6.添加键盘事件控制起点方块移动. 7.收尾. 迷宫算法(网上参考的) 1.将起点作为当前迷宫单元并标记为已访问 2.当还存在未标记的迷宫单元,进行循环 1).如果当前

  • 老程序员教你一天时间完成C语言扫雷游戏

    目录 扫雷游戏 1.菜单 2.初始化棋盘 3.打印棋盘 4.布置雷 5.排查雷 6.整体效果展示 7.代码分享 7.1 test.c 7.2 game.c 7.3 game.h 总结 扫雷游戏 今天我们就要设计一款这样的游戏,首先需要设置棋盘,然后对棋盘进行随机布雷,最后在排雷. 1.菜单 首先制作一个简易菜单 int main() { int input; srand((unsigned int)time(NULL)); do { menu(); printf("请选择:\n");

  • 老程序员教你一天时间完成C++俄罗斯方块游戏

    目录 一.主要文件 二.界面设计 三.方块设计 四.设计思路 设计思路如下: 五.总结 首先,看下效果图: 图1 游戏运行过程 下面详细讲解下制作过程. 一.主要文件 文件包含三个:tetris.cpp.tetris.h.main.cpp,各个文件的用途如下: tetris.cpp 文件:函数实现: tetris.h : 类和函数声明: main.cpp : 主函数: 二.界面设计 bool vis[100][100]; // 用于标记坐标 int Co[100][100]; // 坐标的颜色

  • 教你用Python实现一个轮盘抽奖小游戏

    一.Python GUI 编程简介 Tkinter 模块(Tk 接口)是 Python 的标准 Tk GUI 工具包的接口 .Tk 和 Tkinter 可以在大多数的 Unix 平台下使用,同样可以应用在 Windows 和 Macintosh 系统里.Tk8.0 的后续版本可以实现本地窗口风格,并良好地运行在绝大多数平台中. wxPython 是一款开源软件,是 Python 语言的一套优秀的 GUI 图形库,允许 Python 程序员很方便的创建完整的.功能健全的 GUI 用户界面. pyq

  • 教你用Python写一个植物大战僵尸小游戏

    一.前言 上次写了一个俄罗斯方块,感觉好像大家都看懂了,这次就更新一个植物大战僵尸吧 二.引入模块 import pygame import random 三.完整代码 配置图片地址 IMAGE_PATH = 'imgs/' 设置页面宽高 scrrr_width = 800 scrrr_height = 560 创建控制游戏结束的状态 GAMEOVER = False 图片加载报错处理 LOG = '文件:{}中的方法:{}出错'.format(__file__, __name__) 创建地图类

  • 一个合格的程序员应该读过哪些书(偏java)

    很多程序员响应,他们在推荐时也写下自己的评语. 以前就有国内网友介绍这个程序员书单,不过都是推荐数 Top 10的书. 其实除了前10本之外,推荐数前30左右的书籍都算经典,笔者整理编译这个问答贴,同时摘译部分推荐人的评语. 下面就按照各本书的推荐数排列. 1.<代码大全> 史蒂夫·迈克康奈尔 推荐数:1684 "优秀的编程实践的百科全书,<代码大全>注重个人技术,其中所有东西加起来, 就是我们本能所说的"编写整洁的代码".这本书有50页在谈论代码布局

  • 教你利用pygame模块制作跳跃小球小游戏

    前言 pygame是用来开发游戏的一套基于SDL的模板,它可以是python创建完全界面化的游戏和多媒体程序,而且它基本上可以在任何系统上运行.本文将详细介绍你利用pygame模块制作跳跃小球小游戏的相关内容,下面来一起看看吧 实现方法 首先创建一个游戏窗口,然后再窗口内创建一个小球.以一定的速度移动小球,当小球碰到游戏窗口的边缘时,小球弹回,继续移动.可以按照如下步骤实现该功能. (1)首先来创建一个游戏窗口,宽和高设置为640×480.代码如下: import sys #导入sys模块 im

  • 教你使用python做一个“罚点球”小游戏

    在学习了一点 Python 基础之后,我们可以做一个罚点球的小游戏,大概流程是这样: 每一轮,你先输入一个方向射门,然后电脑随机判断一个方向扑救.方向不同则算进球得分,方向相同算扑救成功,不得分. 之后攻守轮换,你选择一个方向扑救,电脑随机方向射门. 第5轮结束之后,如果得分不同,比赛结束. 5轮之内,如果一方即使踢进剩下所有球,也无法达到另一方当前得分,比赛结束. 5论之后平分,比赛继续进行,直到某一轮分出胜负. 实现方法有很多种,我这里提供的只是一种参考.你可以按照自己喜欢的方式去做,那样才

  • 手把手教你用vue3开发一个打砖块小游戏

    前言 用vue3写了几个实例,感觉Vue3的composition Api设计得还是很不错,改变了一下习惯,但写多两个就好了. 这次写一个也是儿时很觉得很好玩的游戏-打砖块, 无聊的时候玩一下也觉得挺好玩,游戏性也挺高.这次我直接用vite+vue3打包尝试一下,vite也是开箱即用,特点是也是可以清除死代码,按需打包,所以打包速度也是非常快的.没用过的同学可以尝试用用. 游戏效果 游戏需求 创建一个场景 创建一个球,创建一堆被打击方块 创建一个可以移动方块并可控制左右移动 当球碰撞左右上边界及

  • 如何成为一个优秀的jsp程序员

    在网上看到很多问题是关于如何学习jsp的,正好网上看到一篇关于学习jsp的文章,就摘了一部分翻译过来,希望能对大家学习jsp有点指 导. 一个普通的错误是把JSP当作简化的 Java.它不是,(事实上, JSP 是简化的 servlets .)程序员通常试着没有学习要求的支持技巧而 直接学习 JSP .JSP 是一个衔接技术,并且成功地连接你需要理解的另外的技术.如果你已经知道 Java , HTML 和 Javascript,这意味着 JSP 将确实是简单的. 需要成为一个成功的 JSP 程序

随机推荐