From 57e16a639d9eb00b5cb83f61a41caf7d1810b751 Mon Sep 17 00:00:00 2001 From: Victor Date: Thu, 15 Nov 2018 00:00:30 +0200 Subject: [PATCH] 2 --- src/Grid.java | 201 +++++++++++++++++++++++++++++++++++++++++++++ src/Keyboard.java | 8 +- src/RayCanvas.java | 97 +++++++++++----------- 3 files changed, 251 insertions(+), 55 deletions(-) create mode 100644 src/Grid.java diff --git a/src/Grid.java b/src/Grid.java new file mode 100644 index 0000000..c120c70 --- /dev/null +++ b/src/Grid.java @@ -0,0 +1,201 @@ + +import java.util.Random; +import java.util.Vector; + +/** + * This class contains the data necessary to draw the maze. + * + * @author Carol Hamer + */ +public class Grid { + + /** + * Random number generator to create a random maze. + */ + private Random myRandom = new Random(); + /** + * data for which squares are filled and which are blank. + * 0 = black + * 1 = white + * values higher than 1 are used during the maze creation + * algorithm. + * 2 = the square could possibly be appended to the maze this round. + * 3 = the square's color is not yet decided, and the square is + * not close enough to be appended to the maze this round. + */ + int[][] mySquares; + int width, height; + + //-------------------------------------------------------- + // maze generation methods + /** + * Create a new maze. + */ + public Grid(int width, int height) { + this.width = width; + this.height = height; + } + + public void newMaze() { + mySquares = new int[width][height]; + // initialize all of the squares to white except a lattice + // framework of black squares. + for (int i = 1; i < width - 1; i++) { + for (int j = 1; j < height - 1; j++) { + if ((i % 2 == 1) || (j % 2 == 1)) { + mySquares[i][j] = 1; + } + } + } + // the entrance to the maze is at (0,1). + mySquares[0][1] = 0; + createMaze(); + mySquares[mySquares.length-1][mySquares[0].length-2] = 5; + } + + /** + * This method randomly generates the maze. + */ + private void createMaze() { + // create an initial framework of black squares. + for (int i = 1; i < mySquares.length - 1; i++) { + for (int j = 1; j < mySquares[i].length - 1; j++) { + if ((i + j) % 2 == 1) { + mySquares[i][j] = 0; + } + } + } + // initialize the squares that can be either black or white + // depending on the maze. + // first we set the value to 3 which means undecided. + for (int i = 1; i < mySquares.length - 1; i += 2) { + for (int j = 1; j < mySquares[i].length - 1; j += 2) { + mySquares[i][j] = 3; + } + } + // Then those squares that can be selected to be open + // (white) paths are given the value of 2. + // We randomly select the square where the tree of maze + // paths will begin. The maze is generated starting from + // this initial square and branches out from here in all + // directions to fill the maze grid. + Vector possibleSquares = new Vector(mySquares.length + * mySquares[0].length); + int[] startSquare = new int[2]; + startSquare[0] = getRandomInt(mySquares.length / 2) * 2 + 1; + startSquare[1] = getRandomInt(mySquares[0].length / 2) * 2 + 1; + mySquares[startSquare[0]][startSquare[1]] = 2; + possibleSquares.addElement(startSquare); + // Here we loop to select squares one by one to append to + // the maze pathway tree. + while (possibleSquares.size() > 0) { + // the next square to be joined on is selected randomly. + int chosenIndex = getRandomInt(possibleSquares.size()); + int[] chosenSquare = (int[]) possibleSquares.elementAt(chosenIndex); + // we set the chosen square to white and then + // remove it from the list of possibleSquares (i.e. squares + // that can possibly be added to the maze), and we link + // the new square to the maze. + mySquares[chosenSquare[0]][chosenSquare[1]] = 1; + possibleSquares.removeElementAt(chosenIndex); + link(chosenSquare, possibleSquares); + } + // now that the maze has been completely generated, we + // throw away the objects that were created during the + // maze creation algorithm and reclaim the memory. + possibleSquares = null; + System.gc(); + } + + /** + * internal to createMaze. Checks the four squares surrounding + * the chosen square. Of those that are already connected to + * the maze, one is randomly selected to be joined to the + * current square (to attach the current square to the + * growing maze). Those squares that were not previously in + * a position to be joined to the maze are added to the list + * of "possible" squares (that could be chosen to be attached + * to the maze in the next round). + */ + private void link(int[] chosenSquare, Vector possibleSquares) { + int linkCount = 0; + int i = chosenSquare[0]; + int j = chosenSquare[1]; + int[] links = new int[8]; + if (i >= 3) { + if (mySquares[i - 2][j] == 1) { + links[2 * linkCount] = i - 1; + links[2 * linkCount + 1] = j; + linkCount++; + } else if (mySquares[i - 2][j] == 3) { + mySquares[i - 2][j] = 2; + int[] newSquare = new int[2]; + newSquare[0] = i - 2; + newSquare[1] = j; + possibleSquares.addElement(newSquare); + } + } + if (j + 3 <= mySquares[i].length) { + if (mySquares[i][j + 2] == 3) { + mySquares[i][j + 2] = 2; + int[] newSquare = new int[2]; + newSquare[0] = i; + newSquare[1] = j + 2; + possibleSquares.addElement(newSquare); + } else if (mySquares[i][j + 2] == 1) { + links[2 * linkCount] = i; + links[2 * linkCount + 1] = j + 1; + linkCount++; + } + } + if (j >= 3) { + if (mySquares[i][j - 2] == 3) { + mySquares[i][j - 2] = 2; + int[] newSquare = new int[2]; + newSquare[0] = i; + newSquare[1] = j - 2; + possibleSquares.addElement(newSquare); + } else if (mySquares[i][j - 2] == 1) { + links[2 * linkCount] = i; + links[2 * linkCount + 1] = j - 1; + linkCount++; + } + } + if (i + 3 <= mySquares.length) { + if (mySquares[i + 2][j] == 3) { + mySquares[i + 2][j] = 2; + int[] newSquare = new int[2]; + newSquare[0] = i + 2; + newSquare[1] = j; + possibleSquares.addElement(newSquare); + } else if (mySquares[i + 2][j] == 1) { + links[2 * linkCount] = i + 1; + links[2 * linkCount + 1] = j; + linkCount++; + } + } + if (linkCount > 0) { + int linkChoice = getRandomInt(linkCount); + int linkX = links[2 * linkChoice]; + int linkY = links[2 * linkChoice + 1]; + mySquares[linkX][linkY] = 1; + int[] removeSquare = new int[2]; + removeSquare[0] = linkX; + removeSquare[1] = linkY; + possibleSquares.removeElement(removeSquare); + } + } + + /** + * a randomization utility. + * @param upper the upper bound for the random int. + * @return a random non-negative int less than the bound upper. + */ + public int getRandomInt(int upper) { + int retVal = myRandom.nextInt() % upper; + if (retVal < 0) { + retVal += upper; + } + return (retVal); + } +} diff --git a/src/Keyboard.java b/src/Keyboard.java index 158c182..39b356d 100644 --- a/src/Keyboard.java +++ b/src/Keyboard.java @@ -16,12 +16,8 @@ public class Keyboard { } private int getKeyNum(int key) { - if (key == Canvas.KEY_NUM0) Main.midlet.destroyApp(true); - else if(key == Canvas.KEY_STAR) Main.midlet.dsp.setCurrent(null); - else { - for (int i = 0; i < keys.length; i++) { - if (key == keys[i]) return i; - } + for (int i = 0; i < keys.length; i++) { + if (key == keys[i]) return i; } return -1; } diff --git a/src/RayCanvas.java b/src/RayCanvas.java index 513476a..efd86c2 100644 --- a/src/RayCanvas.java +++ b/src/RayCanvas.java @@ -5,37 +5,12 @@ import javax.microedition.lcdui.*; public class RayCanvas extends Canvas {// implements Runnable { private Keyboard keyb; + private Grid grid; //private final int mapWidth = 24; //private final int mapHeight = 24; private int gluk; private Image pr; - private final int[][] worldMap = - { - {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, - {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1}, - {1,0,0,0,0,3,3,3,3,3,0,3,0,3,3,3,2,2,2,2,0,0,1,0,0,1,4,0,4,0,3,3,3,3,3,0,1}, - {1,0,0,0,0,0,0,0,0,0,2,2,2,2,0,3,3,0,0,2,2,0,1,0,1,1,4,0,4,0,3,3,0,0,3,0,1}, - {1,0,0,0,0,0,2,2,2,2,2,0,0,0,0,1,0,0,0,2,2,0,1,0,1,0,4,0,4,0,3,0,3,3,3,0,1}, - {1,0,0,0,0,0,2,0,0,0,2,2,2,1,1,1,3,3,0,2,2,0,1,0,1,0,1,0,1,0,3,0,3,0,3,0,1}, - {1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,1,1,1,0,2,2,2,1,0,1,0,1,0,1,3,3,0,3,0,3,3,1}, - {1,0,0,0,0,0,2,0,0,0,2,0,0,1,1,1,1,1,1,1,0,0,3,0,1,0,1,0,1,0,3,0,0,0,0,0,1}, - {1,0,0,1,0,0,2,2,0,2,2,0,0,1,0,0,0,0,0,0,0,0,3,0,1,0,2,0,2,0,3,0,3,0,0,0,1}, - {1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,3,0,2,0,2,0,2,0,2,0,0,0,1}, - {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,3,0,2,0,2,0,0,0,0,0,0,0,1}, - {1,0,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,3,0,2,0,2,0,0,0,0,0,0,0,1}, - {1,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,3,0,3,0,3,0,0,0,0,0,0,0,1}, - {1,3,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,3,0,3,0,3,0,0,0,0,0,0,0,1}, - {1,2,0,2,0,2,2,1,1,1,1,0,0,0,0,0,0,0,0,0,3,3,3,0,3,0,3,0,3,0,0,0,0,0,0,0,1}, - {1,0,0,3,0,0,0,0,0,0,3,0,2,2,2,2,2,2,0,0,3,0,0,0,3,0,3,0,3,0,0,0,0,0,0,0,1}, - {1,4,4,4,4,4,4,4,4,0,3,0,2,0,0,2,2,2,2,0,2,0,3,0,0,4,1,0,1,0,0,0,0,0,0,0,1}, - {1,4,0,4,0,0,0,0,4,0,3,3,2,2,0,0,0,0,0,0,0,0,3,4,4,4,1,0,1,0,0,0,0,0,0,0,1}, - {1,4,0,0,0,0,5,0,4,0,0,0,0,4,0,4,0,4,4,4,4,4,4,4,0,0,1,0,1,0,0,0,0,0,0,0,1}, - {1,4,0,4,0,0,0,0,4,0,2,3,0,4,0,4,0,4,0,4,4,0,4,4,0,0,2,0,2,0,0,0,0,0,3,3,1}, - {1,4,0,4,4,4,4,4,4,0,3,3,0,0,0,4,0,4,0,0,0,0,0,4,0,0,3,0,3,0,0,0,0,0,3,0,1}, - {1,4,0,0,0,0,0,0,0,0,3,4,4,4,4,4,0,4,0,4,4,4,4,4,1,2,4,0,4,3,2,1,1,2,3,0,1}, - {1,4,4,4,4,4,4,4,4,3,3,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1}, - {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} - }; + private int[][] colors = new int[][] { {0xcccc44, 0x444444, 0x333333, 0x222222, 0x111111},//gluk0 {0xcccc44, 0xaaaaaa, 0x888888, 0x555555, 0xcccccc},//gluk1 @@ -47,18 +22,22 @@ public class RayCanvas extends Canvas {// implements Runnable { private double planeX, planeY; //the 2d raycaster version of camera plane private int w,h; private long lastTime; - private int iFps, iActFps, iTimeToCountFps; + private boolean showUI; + private final int size = 4; public RayCanvas() { setFullScreenMode(true); w = getWidth(); h = getHeight(); + grid = new Grid(24, 24); + grid.newMaze(); - posX = 22; - posY = 27.5; + showUI = false; + posX = 7; + posY = 6.5; dirX = -1; + lastTime = 0; dirY = planeX = 0; - iFps = iActFps = iTimeToCountFps = 0; planeY = 0.66; gluk = 1; @@ -79,7 +58,10 @@ public class RayCanvas extends Canvas {// implements Runnable { // } protected void keyPressed(int key) { - keyb.onPressed(key, getGameAction(key)); + if(key == KEY_STAR) showUI = !showUI; + else if (key == -6) grid.newMaze(); + else if (key == KEY_NUM0) Main.midlet.destroyApp(true); + else keyb.onPressed(key, getGameAction(key)); } protected void keyReleased(int key) { @@ -88,16 +70,9 @@ public class RayCanvas extends Canvas {// implements Runnable { public void paint(Graphics g) { long thisTime = System.currentTimeMillis(); // текущее время - int dTime = (int) (thisTime - lastTime); // время, прошедшее с прошлого кадра + int dTime = (int) (thisTime - lastTime);// время, прошедшее с прошлого кадра lastTime = thisTime; - iTimeToCountFps += dTime; - iFps++; - if (iTimeToCountFps >= 1000) {// если набралось 1 секунда - обновляем счетчик - iActFps = iFps; - iTimeToCountFps = iFps = 0; - } - g.setColor(0); g.fillRect(0, 0, w, h); @@ -155,8 +130,11 @@ public class RayCanvas extends Canvas {// implements Runnable { side = 1; } //Check if ray has hit a wall - if (worldMap[mapX][mapY] > 0) + try { + if (getCell(mapX, mapY) > 0) hit = 1; + } catch (Exception e) { hit = 1; + } } //Calculate distance projected on camera direction (oblique distance will give fisheye effect!) if (side == 0) { @@ -186,7 +164,7 @@ public class RayCanvas extends Canvas {// implements Runnable { } int color = 0; try { - color = colors[gluk][worldMap[mapX][mapY]]; + color = colors[gluk][getCell(mapX, mapY)]; //give x and y sides different brightness if (side == 1) color -= 0x333333; } catch (Exception e) { @@ -205,19 +183,19 @@ public class RayCanvas extends Canvas {// implements Runnable { //move forward if no wall in front of you if (keyb.getKeyState(UP)) { - if (worldMap[(int) (posX + dirX * moveSpeed)][(int) posY] == 0) { + if (getCell((int) (posX + dirX * moveSpeed), (int) posY) == 0) { posX += dirX * moveSpeed; } - if (worldMap[(int) posX][(int) (posY + dirY * moveSpeed)] == 0) { + if (getCell((int) posX, (int) (posY + dirY * moveSpeed)) == 0) { posY += dirY * moveSpeed; } } //move backwards if no wall behind you if (keyb.getKeyState(DOWN)) { - if (worldMap[(int) (posX - dirX * moveSpeed)][(int) posY] == 0) { + if (getCell((int) (posX - dirX * moveSpeed), (int) posY) == 0) { posX -= dirX * moveSpeed; } - if (worldMap[(int) posX][(int) (posY - dirY * moveSpeed)] == 0) { + if (getCell((int) posX, (int) (posY - dirY * moveSpeed)) == 0) { posY -= dirY * moveSpeed; } } @@ -242,9 +220,30 @@ public class RayCanvas extends Canvas {// implements Runnable { planeY = oldPlaneX * Math.sin(rotSpeed) + planeY * Math.cos(rotSpeed); } - // fps - g.setColor(0xff); - g.drawString("" + iActFps, 1, 1, 20); + if(showUI) showLabirinth(g, (int)posX, (int)posY); repaint(); } + + private void showLabirinth(Graphics g, int x, int y) { + System.out.println("x= "+x+" y= "+y+" id= "+grid.mySquares[x][y]); + g.setColor(0xFFFFFF); + g.fillRect(0, 0, grid.width, grid.height); + g.setColor(0x00FF); + for(int i=0; i