Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to realize the complex Maze of Classical Games by Java

2025-01-15 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly shows you "Java how to achieve the classic game complex maze", the content is easy to understand, clear, hope to help you solve your doubts, the following let the editor lead you to study and learn "how to achieve the classic game complex maze Java" this article.

Preface

Humans have been building mazes for 5000 years. In different periods of cultural development in the world, these strange buildings have always attracted people to walk laboriously along the winding and difficult paths in search of the truth. The labyrinth Mini Game came into being. In the game, the maze is shown as a dangerous area with a variety of wonders and puzzles or treasures on the adventure stage. There are caves, man-made buildings, monster nests, dense forests or mountain roads. There are villains or ferocious creatures (real or imaginary objects) wandering in the labyrinth, in which there may be traps, unknown facilities, relics, etc.

The game of "complex maze" is implemented in java language, using swing technology to deal with the interface, and the design idea is object-oriented.

Main demand

Key control movement, the role out of the maze, the game victory. Increase the difficulty of the game and increase random maps.

Main design

1. Build the game map panel.

2. Set up the maze map, including walkable passageways, unwalkable walls, and exit locations.

3. Press the up and down keys of the keyboard to control the movement of the character

4. the algorithm of character movement, the channel can go, but can not go when it comes to the wall.

5. When you come to the end, there is a hint of successful customs clearance.

6. Increase the difficulty choice of the game, difficulty 1, difficulty 2 and difficulty 3

7. The map generated each time is random

8. The size of the map is optional. The length of the maze is between 10-45 and the width is between 10-90.

9. Increase the musical effect of hitting the wall.

Function screenshot

Game start page

Generate a maze map with a difficulty of 1pm and 10mm.

Random map: generating a maze map with difficulty of 1pm 10mm 10

Generate a labyrinth map with a difficulty of 2pm and 30mm.

Generate a maze map with a difficulty of 350,90,45.

Successful clearance-effect

Code implementation

Window layout

Public class StartView extends JFrame {public StartView () {this.setTitle (complex maze); this.setSize (240,265); this.setLocationRelativeTo (null); this.setDefaultCloseOperation (EXIT_ON_CLOSE); this.setResizable (false); initialize (); this.setVisible (true);} private void initialize () {JPanel contentPane = new JPanel () This.setContentPane (contentPane); contentPane.setLayout (null); JLabel widthLabel = new JLabel ("maze length:"); JLabel heightLabel = new JLabel ("labyrinth height:"); JLabel levelLabel = new JLabel ("difficulty:"); JTextField widthText = new JTextField (); JTextField heightText = new JTextField (); JRadioButton level1 = new JRadioButton ("1"); JRadioButton level2 = new JRadioButton ("2") JRadioButton level3 = new JRadioButton ("3"); ButtonGroup levelGroup = new ButtonGroup (); levelGroup.add (level1); levelGroup.add (level2); levelGroup.add (level3); JButton run = new JButton ("generate maze"); / / set label position widthLabel.setBounds (20,20,100,30); heightLabel.setBounds (20,70,110,30) WidthText.setBounds (120,20,70,30); heightText.setBounds (120,70,70,30); levelLabel.setBounds (20,120,60,30); level1.setBounds (80,120,50,30); level2.setBounds (130,120,50,30); level3.setBounds (180,120,50,30); run.setBounds (55,170,120,30) / / restrict the input box to receive only digits widthText.setDocument (new NumberTextField ()); heightText.setDocument (new NumberTextField ()); / / change the font Font font = new Font ("italics", Font.PLAIN, 17); widthLabel.setFont (font); heightLabel.setFont (font); widthText.setFont (font); heightText.setFont (font) LevelLabel.setFont (font); level1.setFont (font); level2.setFont (font); level3.setFont (font); run.setFont (font); / / uncheck the border level1.setFocusPainted (false); level2.setFocusPainted (false); level3.setFocusPainted (false); / / default selection difficulty 3 level3.setSelected (true) ContentPane.add (widthLabel); contentPane.add (heightLabel); contentPane.add (widthText); contentPane.add (heightText); contentPane.add (levelLabel); contentPane.add (level1); contentPane.add (level2); contentPane.add (level3); contentPane.add (run) / / generate the labyrinth listener run.addActionListener (e-> {/ / the recommended width is 10-90 and the length is 10-45 if (widthText.getText (). Equals (")) {JOptionPane.showMessageDialog (null," length cannot be empty! " , "prompt", JOptionPane.INFORMATION_MESSAGE);} else if (heightText.getText (). Equals (")) {JOptionPane.showMessageDialog (null," height cannot be empty! " , JOptionPane.INFORMATION_MESSAGE);} else {int width = Integer.parseInt (widthText.getText ()); int height = Integer.parseInt (heightText.getText ()) If (width > = 10 & & width = 10 & & height recursive segmentation algorithm generates maze, 2-> recursive backtracking algorithm generates maze, 3-> Prim algorithm generates maze * / public MazeModel (int width, int height, int level) {super (); this.width = width; this.height = height Switch (level) {case 1: this.mazePoints = recursiveDivision (); case 2: this.mazePoints = recursiveBacktracker (); case 3: this.mazePoints = prim () }} / * * Recursive backtracking to generate a maze * * @ the set of cells generated by return * / private ArrayList recursiveBacktracker () {ArrayList maze = new ArrayList (); / / initialize so that all cells are strongly surrounded by for (int h = 0; h)

< height; h++) { for (int w = 0; w < width; w++) { MazePoint point = new MazePoint(w, h, true); maze.add(point); } } // 建立一个存放操作单元格的栈 Stack stack = new Stack(); // 选择(0,0)点作为起始点,开始打通迷宫 stack.push(maze.get(0)); maze.get(0).visited = true; Random random = new Random(); int x; // 操作单元格的横坐标 int y; // 操作单元格的纵坐标 int direction; // 方向 while (!stack.empty()) { // 选择栈顶元素作为当前操作数 MazePoint operatingPoint = stack.peek(); x = operatingPoint.getX(); y = operatingPoint.getY(); direction = random.nextInt(4); MazePoint adjacency; switch (direction) { case 0: // 左边 if ((x - 1) >

= 0) {/ / determine whether the left is the edge adjacency = maze.get (x-1 + y * width); / / determine whether the left cell has been accessed by if (! adjacency.visited) {operatingPoint.setLeft (0) / / get through the left wall of the action cell, and the right wall of the left cell adjacency.setRight (0); stack.push (adjacency); / / put the left wall on the stack as the operation cell of the next loop adjacency.visited = true / / set the cell on the left to have visited XMMI; / / change the coordinates of the operation cell to make it easier to determine whether all around the current cell have visited}} break. Case 1: / / right / / Notes refer to case0 if ((x + 1))

< width) { adjacency = maze.get(x + 1 + y * width); if (!adjacency.visited) { operatingPoint.setRight(0); adjacency.setLeft(0); stack.push(adjacency); adjacency.visited = true; x++; } } break; case 2: // 上边 // 注释参照case0 if ((y - 1) >

= 0) {adjacency = maze.get (x + (y-1) * width); if (! adjacency.visited) {operatingPoint.setUp (0); adjacency.setDown (0); stack.push (adjacency) Adjacency.visited = true; ymurmuri;}} break; case 3: / / the following / / Notes refer to case0 if ((y + 1))

< height) { adjacency = maze.get(x + (y + 1) * width); if (!adjacency.visited) { operatingPoint.setDown(0); adjacency.setUp(0); stack.push(adjacency); adjacency.visited = true; y++; } } break; } // 若操作单元格四周都被访问过,将该单元格出栈。 if ((x - 1 < 0 || maze.get(x - 1 + y * width).visited) && (x + 1 >

= width | | maze.get (x + 1 + y * width) .visited) & & (y-1

< 0 || maze.get(x + (y - 1) * width).visited) && (y + 1 >

= height | | maze.get (x + (y + 1) * width) .visited) {stack.pop ();}} maze.get (0) .setLeft (0); / / the upper left corner opens the wall as the entrance maze.get (width * height-1) .setRight (0); / / the lower right corner opens the wall as the exit return maze } / * split the maze region * * @ param maze cell collection * @ the width of the param right region * @ param top region high * / private void divide (ArrayList maze, int left, int right, int top Int down) {if (right-left > 0 & & top-down > 0) {/ / build a wall in the center of the region for (int x = left, y = (top-down) / 2 + down) X x + 1) {tempX = random.nextInt (right-(x + 1) + 1) + x + 1;} else {tempX = x + 1;} tempY = y; maze.get (tempX + tempY * this.width) .setDown (0) Maze.get (tempX + (tempY + 1) * this.width) .setup (0);} if (direction! = 2) {/ / break through the wall above tempX = x; if (y-down > down) {tempY = random.nextInt (y-down + 1) + down } else {tempY = down;} maze.get (tempX + tempY * this.width) .setRight (0); maze.get (tempX + 1 + tempY * this.width) .setLeft (0) } if (direction! = 3) {/ / get through the wall below tempX = x; if (top-(y + 1) > y + 1) {tempY = random.nextInt (top-(y + 1) + 1) + y + 1;} else {tempY = y + 1 } maze.get (tempX + tempY * this.width) .setRight (0); maze.get (tempX + 1 + tempY * this.width) .setLeft (0);} maze.stream () .limit (this.width) .forEach (m-> m.setUp (1)) Maze.stream () .skip ((this.height-1) * this.width) .forEach (m-> m.setDown (1)); maze.stream () .filter (m-> m.getX () = = 0) .forEach (m-> m.setLeft (1)); maze.stream () .filter (m-> m.getX () = = width-1) .forEach (m-> m.setRight (1)) Divide (maze, left, (right-left) / 2 + left, (top-down) / 2 + down, down); divide (maze, left, (right-left) / 2 + left, top, (top-down) / 2 + down + 1); divide (maze, (right-left) / 2 + left + 1, right, (top-down) / 2 + down, down) Divide (maze, (right-left) / 2 + left + 1, right, top, (top-down) / 2 + down + 1) }} / * Recursively split the set of cells in the maze generated by return * / private ArrayList recursiveDivision () {/ / initialize all the cells of the maze ArrayList maze = new ArrayList (); for (int h = 0; h)

< height; h++) { for (int w = 0; w < width; w++) { MazePoint point = new MazePoint(w, h); maze.add(point); } } divide(maze, 0, width - 1, height - 1, 0); // 递归分割迷宫 maze.get(0).setLeft(0); // 左上角开墙作为入口 maze.get(width * height - 1).setRight(0); // 右下角开墙作为出口 return maze; } private ArrayList prim() { ArrayList mazePoints = new ArrayList(); PrimMaze primMaze = new PrimMaze(width * 2 + 1, height * 2 + 1); int[][] tempMaze = primMaze.getMaze(); for (int i = 0; i < tempMaze.length; i++) { for (int j = 0; j < tempMaze[i].length; j++) { if (i % 2 != 0 && j % 2 != 0) { MazePoint mazePoint = new MazePoint(i / 2, j / 2); if (tempMaze[i - 1][j] == 10) { mazePoint.setLeft(1); } if (tempMaze[i + 1][j] == 10) { mazePoint.setRight(1); } if (tempMaze[i][j - 1] == 11) { mazePoint.setUp(1); } if (tempMaze[i][j + 1] == 11) { mazePoint.setDown(1); } mazePoints.add(mazePoint); } } } mazePoints.get(0).setLeft(0); // 左上角开墙作为入口 mazePoints.get(width * height - 1).setRight(0); // 右下角开墙作为出口 return mazePoints; } public void draw() { new PlayView(mazePoints); }} 普里姆算法 class PrimMaze { private int[][] maze; public int[][] getMaze() { return maze; } PrimMaze(int row, int column) { int row1 = row / 2; int column1 = column / 2; maze = new int[row1 * 2 + 1][column1 * 2 + 1]; for (int x = 0; x < row1 * 2 + 1; x++) //初始化迷宫 { for (int y = 0; y < column1 * 2 + 1; y++) { if (x == 0 || x == row1 * 2) { maze[x][y] = -1; } if (y == 0 || y == column1 * 2) { maze[x][y] = -1; } } } for (int x = 1; x < row1 * 2; x++) { for (int y = 1; y < column1 * 2; y++) { if (x % 2 == 1 || y % 2 == 1) { maze[x][y] = 0; } if (x % 2 == 0 || y % 2 == 0) { maze[x][y] = 1; } } } ArrayList list = new ArrayList(); //记录已连通的"路"的坐标的集合 int[] coordinate = new int[2]; //记录未访问的点坐标 int x = 1, y = 1; //设置起点位置 coordinate[0] = coordinate[1] = 1; list.add(coordinate); //将起点加入已经连通的路集合 //x,y表示当前访问坐标 while (list.size() < row1 * column1) //当所有点都已访问完时结束 { boolean flag1; //标识坐标是否已经被访问 int[] record = {-1, -1, -1, -1}; //用于记录四周未被访问的方位,0代表上,1代表下,2代表左,3代表右 if (x - 2 >

0) / / determine whether there is a path above the current position {int [] a = new int [2]; a [0] = x-2; a [1] = y; flag1 = judge (a, list) / / determine whether the above has been accessed if (flag1) {record [0] = 0;}} if (x + 2)

< row1 * 2) //判断当前位置下方是否有路 { int[] a = new int[2]; a[0] = x + 2; a[1] = y; flag1 = judge(a, list); //判断下方是否已经被访问 if (flag1) { record[1] = 1; } } if (y - 2 >

0) / / determine whether there is a path on the left side of the current position {int [] a = new int [2]; a [0] = x; a [1] = y-2; flag1 = judge (a, list) / / determine whether the left side has been accessed if (flag1) {record [2] = 2;}} if (y + 2 < column1 * 2) / / determine whether there is a path on the right side of the current position {int [] a = new int [2] A [0] = x; a [1] = y + 2; flag1 = judge (a, list); / / determine whether the right side has been accessed if (flag1) {record [3] = 3;}} boolean flag2 = false / / flag2 identifies whether there is an unvisited path around for (int I = 0; I < 4; iSum +) / / determines whether there are unvisited paths in the four directions of the current location {if (record [I] = = I) {flag2 = true / / if there is an unvisited path, jump out of the loop break;}} int r = new Random () .nextInt (4); while (record [r] = = r) {r = new Random () .nextInt (4) } while (record [r]! = r & & flag2) / / when the azimuth marks are wrong and there are unvisited points around the current position, continue to obtain a new azimuth mark at random until the mark is correct {r = new Random () .nextInt (4) / / randomly select a qualified wall and smash it into if (record [r] = = r) / / when marked correctly, break the wall between two points {if (r = = 0) {/ / when there are unvisited points above Smash the upper wall maze [x-1] [y] = 0 } if (r = = 1) {/ / when there is an unvisited point below, break the lower wall maze [x + 1] [y] = 0 } if (r = = 2) {/ / when there is an unvisited point on the left, break the wall on the left maze [x] [y-1] = 0 } if (r = = 3) {/ / when there is an unvisited point on the right, break the wall on the right maze [x] [y + 1] = 0 } / / remove if (r = = 0 & & flag2) from the collection where the coordinates of the broken road between the current coordinates and the current coordinates have never been accessed / / if it is the upper wall Then add the upper path to the connected path set {int [] b = new int [2] B [0] = x-2; b [1] = y; if (judge (b, list)) {list.add (b) }} if (r = = 1 & & flag2) / / if the lower wall is broken, add the lower path to the connected path set {int [] b = new int [2]; b [0] = x + 2; b [1] = y If (judge (b, list)) {list.add (b);}} if (r = = 2 & & flag2) / / if the left wall is broken, add the left path to the connected path set {int [] b = new int [2] B [0] = x; b [1] = y-2; if (judge (b, list)) {list.add (b) }} if (r = = 3 & & flag2) / / if the right wall is broken, add the right path to the connected path set {int [] b = new int [2]; b [0] = x; b [1] = y + 2 If (judge (b, list)) {list.add (b);}} int I = new Random (). NextInt (list.size ()); / / randomly select a connected path coordinate x = list.get (I) [0] / / get the path coordinates y = list.get (I) [1];} for (int r = 0; r < maze.length; r +) / / convert the grid wall to a line wall, 10 for horizontal, 11 for vertical {for (int c = 0; c < maze [r] .length) C++) {if (r% 2 = = 0 & & c% 2 = = 1) {if (maze [r] [c]! = 0) {maze [r] [c] = 10 }} if (r% 2 = = 1 & & c% 2 = = 0) {if (maze [r] [c]! = 0) {maze [r] [c] = 11 }} boolean judge (int [] coordinate, ArrayList list) / / determines whether the path has joined the path set, and returns false {boolean flag = true if it has been added. For (int [] ints: list) {if (coordinate [0] = = ints [0] & & coordinate [1] = = ints [1]) / / if the accessed point set contains the coordinates of the location, it indicates that the location has been accessed and there is no need to add the coordinates {flag = false; break of the location repeatedly. }} return flag;}} above is all the content of the article "how to realize the complex maze of classic games by Java". Thank you for reading! I believe we all have a certain understanding, hope to share the content to help you, if you want to learn more knowledge, welcome to follow the industry information channel!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report