Skip to content

Instantly share code, notes, and snippets.

@nossidge
Last active December 20, 2015 22:08
Show Gist options
  • Save nossidge/6202248 to your computer and use it in GitHub Desktop.
Save nossidge/6202248 to your computer and use it in GitHub Desktop.
Processing. My prototype of Sean Howard's 83rd game mechanic, ASCII 3D. http://www.squidi.net/three/entry.php?id=83
//
// ASCII 3D
//
// Idea by Sean Howard:
// http://www.squidi.net/three/entry.php?id=83
//
// Prototype code by Paul Thompson
//
////////////////////////////////////////////////////////////////////////////////
// Stuff to handle key presses
import java.util.HashSet;
import java.awt.event.KeyEvent;
// List of currently pressed keys
HashSet<Integer> keysDown = new HashSet<Integer>();
// The font to use (should be a monospace)
PFont f = createFont("Courier New",16,true);
// Difference in Z value between each wall layer
final int zDiff = 9;
// Number of wall layer levels to draw
final int zLevelMax = 5;
// Characters for tiles
final char charWall = '#';
final char charFloor = '.';
final char charVoid = '/';
final char charGuy = '@';
// Pixels per character
final int tileDimX = 10;
final int tileDimY = 17;
// Location of dungeon (because we move the dungeon around the guy)
int distFromEdgeX = 0;
int distFromEdgeY = 10;
int distFromEdgeXPrev = 0;
int distFromEdgeYPrev = 10;
// Where the guy is drawn. He should always be in the centre
final int guyTileX = 20;
final int guyTileY = 11;
final int guyLocationX = distFromEdgeX+guyTileX*tileDimX;
final int guyLocationY = distFromEdgeY+guyTileY*tileDimY;
// Characters surrounding the guy
char aroundN = ' ';
char aroundS = ' ';
char aroundE = ' ';
char aroundW = ' ';
char aroundNE = ' ';
char aroundNW = ' ';
char aroundSE = ' ';
char aroundSW = ' ';
// Array of the dungeon tiles
String[] dungeon = new String[37];
////////////////////////////////////////////////////////////////////////////////
void setup() {
size(400,400,P3D);
textFont(f,16);
frameRate(15);
background(0);
int p = 0;
dungeon[p++]="////////////////////////////////////////////////////////////////////////////////////////////";
dungeon[p++]="////////////////////////////////////////////////////////////////////////////////////////////";
dungeon[p++]="////////////////////////////////////////////////////////////////////////////////////////////";
dungeon[p++]="////////////////////////////////////////////////////////////////////////////////////////////";
dungeon[p++]="////////////////////////////////////////////////////////////////////////////////////////////";
dungeon[p++]="////////////////////////////////////////////////////////////////////////////////////////////";
dungeon[p++]="////////////////////////////////////////////////////////////////////////////////////////////";
dungeon[p++]="////////////////////////////////////////////////////////////////////////////////////////////";
dungeon[p++]="////////////////////////////////////////////////////////////////////////////////////////////";
dungeon[p++]="////////////////////////////////////////////////////////////////////////////////////////////";
dungeon[p++]="///////////////////###########///////##########//////#######################################";
dungeon[p++]="///////////////////#.........#///////#........#//////#......................................";
dungeon[p++]="///////////////////#.........#########........#//////#......................................";
dungeon[p++]="///////////////////#..........................#//////#......................................";
dungeon[p++]="///////////////////####.......................#//////#......................................";
dungeon[p++]="//////////////////////#.......................########......................................";
dungeon[p++]="//////////////////////##.######.............................................................";
dungeon[p++]="///////////////////////#.#////#.............................................................";
dungeon[p++]="///////////////////////#.#////#############.################################################";
dungeon[p++]="///////////////////#####.#####///////######.###/////////////////////////////////////////////";
dungeon[p++]="///////////////////#.........#///////#....#...#////////////////////////////##########///////";
dungeon[p++]="///////////////////#.........#########........#///######///////////////////#........#///////";
dungeon[p++]="///////////////////#......................#####///#....#///////////////////#........#///////";
dungeon[p++]="///////////////////####........######.........#####....#///////////////////#........#///////";
dungeon[p++]="//////////////////////#........#////#..................#///////////////////#........#///////";
dungeon[p++]="//////////////////////##########////####################///////////////////##########///////";
dungeon[p++]="////////////////////////////////////////////////////////////////////////////////////////////";
dungeon[p++]="////////////////////////////////////////////////////////////////////////////////////////////";
dungeon[p++]="////////////////////////////////////////////////////////////////////////////////////////////";
dungeon[p++]="////////////////////////////////////////////////////////////////////////////////////////////";
dungeon[p++]="////////////////////////////////////////////////////////////////////////////////////////////";
dungeon[p++]="////////////////////////////////////////////////////////////////////////////////////////////";
dungeon[p++]="////////////////////////////////////////////////////////////////////////////////////////////";
dungeon[p++]="////////////////////////////////////////////////////////////////////////////////////////////";
dungeon[p++]="////////////////////////////////////////////////////////////////////////////////////////////";
dungeon[p++]="////////////////////////////////////////////////////////////////////////////////////////////";
dungeon[p++]="////////////////////////////////////////////////////////////////////////////////////////////";
}
////////////////////////////////////////////////////////////////////////////////
void keyPressed() { keysDown.add(keyEvent.getKeyCode()); }
void keyReleased() { keysDown.remove(keyEvent.getKeyCode()); }
boolean keyPressedN() { return ( keysDown.contains(KeyEvent.VK_W) || keysDown.contains(KeyEvent.VK_UP) ); }
boolean keyPressedS() { return ( keysDown.contains(KeyEvent.VK_S) || keysDown.contains(KeyEvent.VK_DOWN) ); }
boolean keyPressedE() { return ( keysDown.contains(KeyEvent.VK_D) || keysDown.contains(KeyEvent.VK_RIGHT) ); }
boolean keyPressedW() { return ( keysDown.contains(KeyEvent.VK_A) || keysDown.contains(KeyEvent.VK_LEFT) ); }
void moveN() { distFromEdgeY = distFromEdgeY + tileDimY; }
void moveS() { distFromEdgeY = distFromEdgeY - tileDimY; }
void moveE() { distFromEdgeX = distFromEdgeX - tileDimX; }
void moveW() { distFromEdgeX = distFromEdgeX + tileDimX; }
void handleKeyEvents() {
PVector newPos;
// Handle opposite directions
if ( (keyPressedN() && keyPressedS()) || (keyPressedE() && keyPressedW()) ) {
return;
}
// Handle two key diagonals
if (keyPressedN() && keyPressedE()) {
if (aroundNE != charWall) { moveN();
moveE();
} else if (aroundE != charWall) { moveE();
} else if (aroundN != charWall) { moveN();
}
} else if (keyPressedN() && keyPressedW()) {
if (aroundNW != charWall) { moveN();
moveW();
} else if (aroundW != charWall) { moveW();
} else if (aroundN != charWall) { moveN();
}
} else if (keyPressedS() && keyPressedE()) {
if (aroundSE != charWall) { moveS();
moveE();
} else if (aroundE != charWall) { moveE();
} else if (aroundS != charWall) { moveS();
}
} else if (keyPressedS() && keyPressedW()) {
if (aroundSW != charWall) { moveS();
moveW();
} else if (aroundW != charWall) { moveW();
} else if (aroundS != charWall) { moveS();
}
} else {
// Now handle single keys
if (keyPressedN() && aroundN != charWall) { moveN(); }
if (keyPressedS() && aroundS != charWall) { moveS(); }
if (keyPressedE() && aroundE != charWall) { moveE(); }
if (keyPressedW() && aroundW != charWall) { moveW(); }
}
}
////////////////////////////////////////////////////////////////////////////////
void mousePressed() {
save(System.currentTimeMillis() + ".png");
}
void draw() {
background(0);
handleKeyEvents();
aroundN = ' ';
aroundS = ' ';
aroundW = ' ';
aroundE = ' ';
aroundNE = ' ';
aroundNW = ' ';
aroundSE = ' ';
aroundSW = ' ';
boolean positionValid = true;
// Draw the first one
for (int iLine=0; iLine<dungeon.length; iLine++) {
for (int iChar=0; iChar<dungeon[iLine].length(); iChar++) {
char theChar = dungeon[iLine].charAt(iChar);
if (theChar == charWall) { fill(255); }
if (theChar == charFloor) { fill(255); }
if (theChar == charGuy) { fill(255); }
if (theChar == charVoid) { fill(0,134,186); }
int charPosX = distFromEdgeX+iChar*tileDimX;
int charPosY = distFromEdgeY+iLine*tileDimY;
boolean axisXSame = (charPosX == guyLocationX);
boolean axisYSame = (charPosY == guyLocationY);
boolean axisXEast = (charPosX == guyLocationX+tileDimX);
boolean axisXWest = (charPosX == guyLocationX-tileDimX);
boolean axisYNorth = (charPosY == guyLocationY-tileDimY);
boolean axisYSouth = (charPosY == guyLocationY+tileDimY);
// Positions around the guy
if ( axisYSame && axisXWest ) { aroundW = theChar; }
else if ( axisYSame && axisXEast ) { aroundE = theChar; }
else if ( axisXSame && axisYNorth ) { aroundN = theChar; }
else if ( axisXSame && axisYSouth ) { aroundS = theChar; }
else if ( axisYNorth && axisXEast ) { aroundNE = theChar; }
else if ( axisYNorth && axisXWest ) { aroundNW = theChar; }
else if ( axisYSouth && axisXEast ) { aroundSE = theChar; }
else if ( axisYSouth && axisXWest ) { aroundSW = theChar; }
// Don't draw character where the guy is.
if ( !( (charPosX==guyLocationX) && (charPosY == guyLocationY) ) ) {
text(theChar, charPosX, charPosY);
// Check if the guy is somehow in the wall
} else if (theChar == charWall) {
positionValid = false;
}
}
}
// Draw the walls in the other Z levels
fill(255,220);
for (int zLevel=1; zLevel<=zLevelMax; zLevel++) {
for (int iLine=0; iLine<dungeon.length; iLine++) {
for (int iChar=0; iChar<dungeon[iLine].length(); iChar++) {
char theChar = dungeon[iLine].charAt(iChar);
if (theChar == charWall) {
text(theChar, distFromEdgeX+iChar*tileDimX,
distFromEdgeY+iLine*tileDimY, zLevel*zDiff);
}
}
}
}
// Draw the guy right in the middle of the screen
if (positionValid) {
text(charGuy, guyLocationX, guyLocationY);
// If the position isn't correct somehow, go to the last good position
} else {
distFromEdgeX = distFromEdgeXPrev;
distFromEdgeY = distFromEdgeYPrev;
}
distFromEdgeXPrev = distFromEdgeX;
distFromEdgeYPrev = distFromEdgeY;
}
////////////////////////////////////////////////////////////////////////////////
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment