2
This commit is contained in:
parent
d05ddef0cf
commit
57e16a639d
201
src/Grid.java
Normal file
201
src/Grid.java
Normal file
@ -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);
|
||||
}
|
||||
}
|
@ -16,13 +16,9 @@ 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;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -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,9 +130,12 @@ 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) {
|
||||
perpWallDist = Math.abs((mapX - rayPosX + (1 - stepX) / 2) / rayDirX);
|
||||
@ -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<grid.width; i++) {
|
||||
for(int j=0; j<grid.height; j++) {
|
||||
if(grid.mySquares[i][j]==1)
|
||||
g.fillRect(i*size, j*size, size, size);
|
||||
}
|
||||
}
|
||||
g.setColor(0xFF0000);
|
||||
g.fillRect(x*size, y*size, size, size);
|
||||
}
|
||||
|
||||
private int getCell(int x, int y) {
|
||||
try {
|
||||
return grid.mySquares[x][y];
|
||||
}catch(Exception ex) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user