package test1;
import java.awt.*;
import javax.swing.*;
import java.util.*;
public class Map1 extends JPanel {
private static int x1, y1, x2, y2, width, height, width2, height2, centerX, centerY, centerX2, centerY2, cellAuto, radius;
public static final int tileWidth = 10;
public static final int tileHeight = 10;
public static final int gridSize = 70;
public static float a, b, circleX, circleY;
public static double t;
public static Random rn = new Random();
// Map array values
public static final int cave = 0;
public static final int wall = 1;
public static final int room = 2;
public static final int dungeon = 3;
public static final int dungeonWall = 4;
public static final int player = 5;
public static final int mob = 6;
public static final int door = 7;
public static int [][][][] myMap = new int[gridSize][gridSize][50][10];
// Generate room count and room stats
public static int roomCount = 5 + rn.nextInt(5);
public static int [][][] roomList = new int[roomCount][4][100];
// CONSTRUCTOR
public Map1() {
// Generates caverns
for (int i = 0; i < roomCount; i++) {
// Make X coordinates and width
x1 = 3 + rn.nextInt(55);
width = 7 + rn.nextInt(10);
if (x1 + width > myMap.length) {
x1 = x1 - width;
}
// Make Y coordinates and height
y1 = 3 + rn.nextInt(55);
height = 7 + rn.nextInt(10);
if (y1 + height > myMap.length - 1) {
y1 = y1 - height;
}
// Add to roomList
centerX = x1 + width / 2;
centerY = y1 + height / 2;
roomList[i][0][0] = centerX;
roomList[i][1][0] = centerY;
roomList[i][2][0] = width;
roomList[i][3][0] = height;
// Choose random cavern shape
if (rn.nextInt(20) < 1) {
// Add a rectangular cavern to map
for (int x = x1; x < width + x1; x++) {
for (int y = y1; y < height + y1; y++) {
myMap[x][y][0][0] = room;
}
}
} else {
// Add a circular cavern to map
radius = width / 2;
for (int x = -radius; x < radius; x++) {
a = x;
b = (float) Math.sqrt(radius * radius - a * a);
for (int y = (int) Math.round(-b + 1); y < b; y++) {
try {
myMap[centerX + x][centerY + y][0][0] = room;
} catch (Exception ex) {
myMap[centerX + x][centerY + y - 2][0][0] = room;
}
}
}
}
}
// Draws halls between caverns (before cellular automata)
for (int i = 0; i + 1 < roomCount; i++) {
centerX = roomList[i][0][0];
centerY = roomList[i][1][0];
width = roomList[i][2][0];
height = roomList[i][3][0];
centerX2 = roomList[i + 1][0][0];
centerY2 = roomList[i + 1][1][0];
width2 = roomList[i + 1][2][0];
height2 = roomList[i + 1][3][0];
while (centerX < centerX2) {
myMap[centerX][centerY][0][0] = 2;
centerX++;
}
while (centerY < centerY2) {
myMap[centerX][centerY][0][0] = 2;
centerY++;
}
while (centerX > centerX2) {
myMap[centerX][centerY][0][0] = 2;
centerX--;
}
while (centerY > centerY2) {
myMap[centerX][centerY][0][0] = 2;
centerY--;
}
}
// Counts total cavern area before paths
int cavernArea = 0;
int caveArea = 0;
for (int x = 0; x < myMap.length; x++) {
for (int y = 0; y < myMap.length; y++) {
if (myMap[x][y][0][0] == 2) {
cavernArea++;
}
}
}
System.out.println("The area of the caverns is: " + cavernArea + " tiles.");
// Cellular automata algorithm to smooth cavern walls
for (int p = 0; p < 20; p++) {
// Scan map
for (int x = 1; x < gridSize - 1; x++) {
for (int y = 1; y < gridSize - 1; y++) {
cellAuto = 0;
// Scans adjacent tiles
for (int adjX = x - 1; adjX < x + 2; adjX++) {
for (int adjY = y - 1; adjY < y + 2; adjY++) {
if (myMap[adjX][adjY][0][0] == 0) {
cellAuto++;
}
if (cellAuto == 4 && adjX == x + 1 && adjY == y + 1) {
myMap[adjX - 1][adjY - 1][0][0] = 2;
} else if (cellAuto > 6 && adjX == x + 1 && adjY == y + 1) {
myMap[adjX - 1][adjY - 1][0][0] = 0;
} else if (cellAuto == 5 && adjX == x + 1 && adjY == y + 1) {
myMap[adjX - 1][adjY - 1][0][0] = 0;
} else if (cellAuto == 2 && adjX == x + 1 && adjY == y + 1) {
myMap[adjX - 1][adjY - 1][0][0] = 2;
} else if (cellAuto == 1 && adjX == x + 1 && adjY == y + 1) {
myMap[adjX - 1][adjY - 1][0][0] = 2;
}
}
}
}
}
}
// Draws halls between caverns
for (int i = 0; i + 1 < roomCount; i++) {
centerX = roomList[i][0][0];
centerY = roomList[i][1][0];
width = roomList[i][2][0];
height = roomList[i][3][0];
centerX2 = roomList[i + 1][0][0];
centerY2 = roomList[i + 1][1][0];
width2 = roomList[i + 1][2][0];
height2 = roomList[i + 1][3][0];
// Set bezier start and finish
int bx1, bx2a, bx2b, bx3, by1, by2a, by2b, by3, btX, btY, timeX, timeY;
bx1 = centerX;
bx3 = centerX2;
by1 = centerY;
by3 = centerY2;
// Set middle X and Y for bezier path
bx2a = centerX + (centerX2 - centerX) / 2;
by2a = centerY + (centerY2 - centerY) / 2;
// Determine length of curve
if (centerX >= centerX2) {
timeX = centerX - centerX2;
} else {
timeX = centerX2 - centerX;
}
if (centerY >= centerY2) {
timeY = centerY - centerY2;
} else {
timeY = centerY2 - centerY;
}
// Set random deviation of bezier
if (rn.nextInt(2) == 0) {
bx2b = bx2a + rn.nextInt(5);
} else {
bx2b = bx2a - rn.nextInt(5);
}
if (rn.nextInt(2) == 0) {
by2b = by2a + rn.nextInt(5);
} else {
by2b = by2a - rn.nextInt(5);
}
// Stop middle X and Y from leaving array
if (bx2b > 68) {
bx2b = 68;
} else if (bx2b < 2) {
bx2b = 2;
}
if (by2b > 68) {
by2b = 68;
} else if (by2b < 2) {
by2b = 2;
}
System.out.println("\nX1 is " + bx1 + " and Y1 is " + by1);
System.out.println("X2 is " + bx2a + " and Y2 is " + by2a);
System.out.println("X3 is " + bx3 + " and Y3 is " + by3);
System.out.println("X2 modified is " + bx2b + " and Y2 modified is " + by2b);
System.out.println("X time is " + timeX + " and Y time is " + timeY + " and total time is " + (1 / (timeX + timeY)) + "\n");
// Bezier path from top left to bottom right
for (double time = (1 / (timeX + timeY)); time < 1;) {
// Determine point on bezier curve
btX = (int) ((1 - (time * time)) * bx1 + 2 * (1 - time) * time * bx2b + (time * time) * bx3);
btY = (int) ((1 - (time * time)) * by1 + 2 * (1 - time) * time * by2b + (time * time) * by3);
// Stop curve leaving array
if (btX > 67) {
btX = 67;
} else if (btX < 3) {
btX = 3;
}
if (btY > 67) {
btY = 67;
} else if (btY < 3) {
btY = 3;
}
// Attempts to draw bezier path
try {
myMap[btX][btY][0][0] = 2;
myMap[btX + 1][btY][0][0] = 2;
myMap[btX][btY + 1][0][0] = 2;
myMap[btX + 1][btY + 1][0][0] = 2;
} catch (Exception ex) {
System.out.println("X is " + btX + " and Y is " + btY + " at t " + t);
System.out.println(ex + " is wrong");
}
time = time + 1 / (timeX + timeY);
if (btX >= bx3 - 1 && btY >= by3 - 1) {
time = 1;
}
}
}
// Counts total cave area after paths and then counts path area
for (int x = 0; x < myMap.length; x++) {
for (int y = 0; y < myMap.length; y++) {
if (myMap[x][y][0][0] == 2) {
caveArea++;
}
}
}
System.out.println("The area of the cave, including paths, is: " + caveArea + " tiles.");
System.out.println("The area of the paths is: " + (caveArea - cavernArea) + " tiles.");
// Generates walls around playable areas
for (int x = 1; x < gridSize - 1; x++) {
for (int y = 1; y < gridSize - 1; y++) {
if ((myMap[x][y][0][0] == 2) && (x < gridSize - 1) && (1 < x)) {
// Scans adjacent tiles
for (int adjX = x - 1; adjX < x + 2; adjX++) {
for (int adjY = y - 1; adjY < y + 2; adjY++) {
if (myMap[adjX][adjY][0][0] == 0) {
myMap[adjX][adjY][0][0] = wall;
}
}
}
}
}
}
// Draw outer walls
for (int x = 0; x < myMap.length; x++) {
for (int y = 0; y < myMap.length; y++) {
if (x == 0 || y == 0) {
if (myMap[x][y][0][0] == 2) {
myMap[x][y][0][0] = wall;
}
}
if (x == myMap.length - 1 || y == myMap.length - 1) {
if (myMap[x][y][0][0] == 2) {
myMap[x][y][0][0] = wall;
}
}
}
}
}
// Paint myMap to a window
public void paint(Graphics g) {
super.paintComponent(g);
this.setBackground(Color.BLACK);
for (int x = 0; x < myMap.length; x++) {
for (int y = 0; y < myMap.length; y++) {
x2 = tileWidth * x;
y2 = tileHeight * y;
// Draws array tiles
if (myMap[x][y][0][0] == room) {
g.setColor(Color.GRAY);
g.fillRect(x2, y2, tileWidth, tileHeight);
g.setColor(Color.BLACK);
g.drawRect(x2, y2, tileWidth, tileHeight);
} else if (myMap[x][y][0][0] == wall) {
g.setColor(Color.DARK_GRAY);
g.fillRect(x2, y2, tileWidth, tileHeight);
} else if (myMap[x][y][0][1] == dungeon) {
g.setColor(Color.RED);
g.drawRect(x2, y2, tileWidth, tileHeight);
} else {
g.setColor(Color.BLACK);
g.fillRect(x2, y2, tileWidth, tileHeight);
//g.setColor(Color.BLACK);
//g.drawRect(x2, y2, tileWidth, tileHeight);
}
}
}
}
}