/* built with Studio Sketchpad:
* https://sketchpad.cc
*
* observe the evolution of this sketch:
* https://studio.sketchpad.cc/sp/pad/view/ro.ALuTIcV$K3D/rev.28
*
* authors:
* GoToLoop
* license (unless otherwise specified):
* creative commons attribution-share alike 3.0 license.
* https://creativecommons.org/licenses/by-sa/3.0/
*/
/**
* Random Tiled Terrain Gen (v4.12)
* by Asimes (2014/Jun)
* mod Matyze & GoToLoop
*
* forum.Processing.org/two/discussion/5985/
* how-can-a-roguelike-have-so-large-maps#Item_16
*
* OpenProcessing.org/sketch/436477
* studio.ProcessingTogether.com/sp/pad/export/ro.9Ql2E8JBC54LJ
*/
static final byte VOID = ' ', HERO = '@', MOUNT = '^';
static final byte TREE = 'T', GRASS = '#';
static final byte LAND = '%', WATER = '~';
static final int COLORS = 0200;
static final color[] colors = new color[COLORS];
//static // comment this line out for JS Mode!
{
colors[VOID] = #808080;
colors[HERO] = #E0E0E0;
colors[MOUNT] = #803000;
colors[GRASS] = #008000;
colors[TREE] = #005000;
colors[LAND] = #C0C000;
colors[WATER] = #0000C0;
};
void terrainGenerator(byte[][] terrain, float noiseScale) {
noiseSeed((long) random(MIN_INT, MAX_INT));
for (int row = terrain.length; row-- != 0; ) {
byte[] columns = terrain[row];
for (int col = columns.length; col-- != 0; ) {
float val = noise(row*noiseScale, col*noiseScale);
byte type;
if (val > .65) type = MOUNT;
else if (val > .55) type = GRASS;
else if (val > .45) type = TREE;
else if (val > .35) type = LAND;
else type = WATER;
columns[col] = type;
}
}
}
static final int GRID = 05000, UNIT = 030;
static final int GW = 8*UNIT << 2, GH = 6*UNIT << 2;
static final int UW = GW/UNIT, UH = GH/UNIT;
final byte[][] tiles = new byte[GRID][GRID];
static final byte[] FPS = { 25, 40, 60, 80, 100 };
int fps;
static final int DIAM = UNIT>>1, SMOOTH = 3;
static final color INK = #FF0000, BG = 0;
static final float NOISE = .05, WEIGHT = 1.5;
static final boolean ONLINE = 1/2 == 1/2.;
static final boolean OUTLINE = true;
static final String RENDER = ONLINE? JAVA2D : FX2D; // P3+
//static final String RENDER = JAVA2D; // P2
//static final String RENDER = P2D; // P1
int px, py, ix, iy;
int north, south, west, east;
boolean rogue = true;
void settings() {
size(GW, GH, RENDER);
smooth(SMOOTH); // P2+
//smooth(); // P1
}
void setup() {
if (width != GW) settings();
frameRate(FPS[fps]);
if (OUTLINE) stroke(BG);
else noStroke();
strokeWeight(WEIGHT);
textSize(UNIT);
textAlign(LEFT, TOP);
rectMode(CORNER);
ellipseMode(CENTER);
px = (width>>1) + DIAM;
py = (height>>1) + DIAM;
reset();
}
void draw() {
if (rogue) background(BG);
moveHero();
renderTerrain(tiles);
if (rogue) drawHeroChar();
else drawHeroTile();
if (!ONLINE) info();
}
void info() {
frame.setTitle("Grid: " + GRID + " x " + GRID
+ " (" + nf(ix, 4) + ", " + nf(iy, 4)
+ ") FPS: " + nf(round(frameRate), 2));
}
void reset() {
terrainGenerator(tiles, NOISE);
teleport();
}
void drawHeroTile() {
fill(INK);
ellipse(px, py, DIAM, DIAM);
}
void drawHeroChar() {
fill(colors[HERO]);
text((char) HERO, px - DIAM, py - DIAM);
}
void drawTile(int x, int y, int diam, color c) {
fill(c);
rect(x, y, diam, diam);
}
void drawChar(int x, int y, char ch, color c) {
fill(c);
text(ch, x + (UNIT>>2), y);
}
void renderTerrain(byte[][] terrain) {
for (int row = UH; row-- != 0; ) {
int oy = iy+row - (UH>>1);
if (oy < 0 | oy >= GRID) for (int col = UW; col-- != 0; )
if (rogue) drawChar(col*UNIT, row*UNIT, (char) VOID, colors[VOID]);
else drawTile(col*UNIT, row*UNIT, UNIT, colors[VOID]);
else {
byte[] columns = terrain[oy];
for (int col = UW; col-- != 0; ) {
int ox = ix+col - (UW>>1);
char ch;
color c;
if (ox >= 0 & ox < GRID) {
ch = (char) columns[ox];
c = colors[ch];
} else {
ch = VOID;
c = colors[VOID];
}
if (rogue) drawChar(col*UNIT, row*UNIT, ch, c);
else drawTile(col*UNIT, row*UNIT, UNIT, c);
}
}
}
}
void keyPressed() {
int k = keyCode;
if (k == ENTER | k == RETURN) frameRate(FPS[fps = (fps+1)%FPS.length]);
else if (k == CONTROL | k == 'T') teleport();
else if (k == DELETE | k == ALT) reset();
else if (k == SHIFT | k == ' ') rogue ^= true;
else setDirection(k, 1);
}
void keyReleased() {
setDirection(keyCode, 0);
}
void setDirection(int k, int spd) {
if (k == UP | k == 'W') north = spd;
else if (k == DOWN | k == 'S') south = spd;
else if (k == LEFT | k == 'A') west = spd;
else if (k == RIGHT | k == 'D') east = spd;
}
void moveHero() {
int ox = ix + east - west;
int oy = iy + south - north;
if (ox < 0 | ox >= GRID | oy < 0 | oy >= GRID) return;
byte ch = tiles[oy][ox];
if (ch != WATER & ch != MOUNT) {
ix = ox;
iy = oy;
}
}
void teleport() {
byte ch;
do {
ix = (int) random(GRID);
iy = (int) random(GRID);
ch = tiles[iy][ix];
} while (ch == WATER | ch == MOUNT);
}