# Noite de Processing - 30 de maio
## Jam ambientes bidimensionais
```Processing
boolean[] dir;
PVector pos;
float vel;
int cx, cy;
float zoom = 1;
int zI = 0;
float antizoom = 1;
//PVector[] planetas;
void setup(){
size(600, 600);
cx = width / 2;
cy = height / 2;
dir = new boolean[4];
pos = new PVector(cx, cy);
vel = 0.1;
//planetas = new PVector[100];
//for( int i = 0; i < planetas.length; i++ ){
// planetas[i] = new PVector(random(-2000,2000), random(-2000,2000), random(80,180) );
//}
noiseDetail(3,0.5);
noStroke();
}
void draw(){
background( 0 );
if( dir[0] ) pos.y -= vel;
if( dir[1] ) pos.y += vel;
if( dir[2] ) pos.x -= vel;
if( dir[3] ) pos.x += vel;
for( int i = 0; i < width/4; i++ ){
for( int j = 0; j <height/4; j++ ){
fill( 255 * noise(cx + pos.x + antizoom * 0.01 * i,
cy + pos.y + antizoom * 0.01 * j ) );
rect( 4*i, 4*j, 4, 4 );
}
}
//translate( cx, cy );
//scale(zoom);
//translate( -pos.x, -pos.y );
//ellipse( pos.x, pos.y, 25, 25 );
fill(0,0,255);
ellipse( cx, cy, zoom*25, zoom*25 );
//for( int i = 0; i < planetas.length; i++ ){
// ellipse( planetas[i].x, planetas[i].y, planetas[i].z, planetas[i].z );
//}
}
void mouseWheel(MouseEvent E) {
//zoom -= 0.1 * E.getCount();
zI -= E.getCount();
zoom = pow( 1.1, zI );
antizoom = 1 / zoom;
}
void keyPressed(){
if( key == 'w' ) dir[0] = true;
if( key == 's' ) dir[1] = true;
if( key == 'a' ) dir[2] = true;
if( key == 'd' ) dir[3] = true;
}
void keyReleased(){
if( key == 'w' ) dir[0] = false;
if( key == 's' ) dir[1] = false;
if( key == 'a' ) dir[2] = false;
if( key == 'd' ) dir[3] = false;
}
```
## tiles, A*

``` Processing
int E = 40;
int hE = E/2;
int W, H;
boolean[][] walls;
boolean mode;
boolean[] dir;
Index P;
ArrayList<Index> path;
void setup(){
size(600, 600);
dir = new boolean[4];
W = width / E;
H = height / E;
P = new Index(0,0);
walls = new boolean[W][H];
path = new ArrayList();
}
void draw(){
for( int i = 0; i < W; i++ ){
for( int j = 0; j < H; j++ ){
if( walls[i][j] ) fill(10);
else if( i % 2 == j % 2 ) fill(127);
else fill(80);
rect(E*i, E*j, E, E);
}
}
if( dir[0] ){
P.j -= 1;
dir[0] = false;
}
if( dir[1] ){
P.j += 1;
dir[1] = false;
}
if( dir[2] ){
P.i -= 1;
dir[2] = false;
}
if( dir[3] ){
P.i += 1;
dir[3] = false;
}
fill(0,0,255);
ellipse( (P.i*E)+hE, (P.j*E)+hE, E, E );
if( path.size() > 0 ){
fill(255,0,0);
for( int i = 0; i < path.size(); i++ ){
ellipse( (path.get(i).i * E)+hE, (path.get(i).j * E)+hE, hE, hE );
}
}
}
void mousePressed(){
if( mouseButton == LEFT ){
mode = !(walls[ int(mouseX/E) ][ int(mouseY/E) ]);
}
else if( mouseButton == RIGHT ){
path = A_Star( P, new Index( int(mouseX/E), int(mouseY/E) ) );
}
}
void mouseDragged(){
if( mouseButton == LEFT ){
walls[ int(mouseX/E) ][ int(mouseY/E) ] = mode;
}
}
void keyReleased(){
if( key == 'w' ) dir[0] = true;
if( key == 's' ) dir[1] = true;
if( key == 'a' ) dir[2] = true;
if( key == 'd' ) dir[3] = true;
}
class Index{
int i, j;
Index( int i, int j ){
this.i = i;
this.j = j;
}
boolean equals( Index b ){
if( i == b.i && j == b.j ) return true;
else return false;
}
Index get(){ return new Index( i, j ); }
}
ArrayList<Index> A_Star( Index start, Index goal ){
// The set of nodes already evaluated.
ArrayList<Index> closedSet = new ArrayList();
// The set of currently discovered nodes still to be evaluated.
// Initially, only the start node is known.
ArrayList<Index> openSet = new ArrayList();
openSet.add( start );
// For each node, which node it can most efficiently be reached from.
// If a node can be reached from many nodes, cameFrom will eventually contain the
// most efficient previous step.
Index[][] cameFrom = new Index[W][H];
// For each node, the cost of getting from the start node to that node.
float[][] gScore = new float[W][H];//:= map with default value of Infinity
for(int i = 0; i < W; i++) for(int j = 0; j < H; j++) gScore[i][j] = -1;
// The cost of going from start to start is zero.
gScore[start.i][start.j] = 0;
// For each node, the total cost of getting from the start node to the goal
// by passing by that node. That value is partly known, partly heuristic.
float[][] fScore = new float[W][H];// := map with default value of Infinity
for(int i = 0; i < W; i++) for(int j = 0; j < H; j++) fScore[i][j] = -1;
// For the first node, that value is completely heuristic.
fScore[start.i][start.j] = heuristic_cost_estimate(start, goal);
float r = sqrt(2);
int[] ik = { -1, 0, 1, 1, 1, 0, -1, -1 };
int[] jk = { -1, -1, -1, 0, 1, 1, 1, 0 };
float[] dist = { r, 1, r, 1, r, 1, r, 1 };
while( openSet.size() > 0 ){ //openSet is not empty
Index current;
float[] openSet_fscores = new float[openSet.size()];
for( int u = 0; u < openSet.size(); ++u ) openSet_fscores[u] = fScore[ openSet.get(u).i ][ openSet.get(u).j ];
int theU = openSet.size()-1;
int theI = openSet.get(theU).i;
int theJ = openSet.get(theU).j;
float small = ( fScore[ openSet.get(theU).i ][ openSet.get(theU).j ] >= 0 )? fScore[ openSet.get(theU).i ][ openSet.get(theU).j ] : 9999999;
for( int u = openSet_fscores.length-2; u >= 0; --u ){
if( openSet_fscores[u] >= 0 && openSet_fscores[u] < small ){
small = openSet_fscores[u];
theI = openSet.get(u).i;
theJ = openSet.get(u).j;
theU = u;
}
}
//println( "("+openSet.size()+")", fScore[ openSet.get(0).i ][ openSet.get(0).j ], ". "+theI+", "+theJ );
current = new Index( theI, theJ ); //the node in openSet having the lowest fScore[] value
if( current.equals(goal) ) return reconstruct_path(cameFrom, start, goal );
openSet.remove( theU );
closedSet.add( current.get() );
for( int u = 0; u < 8; ++u ){ // each neighbor of current
int ni = current.i + ik[u];
int nj = current.j + jk[u];
if( ni < 0 || ni >= W ) continue; // Ignore the world borders
if( nj < 0 || nj >= H ) continue;
Index neighbor = new Index( ni, nj );
if( walls[ni][nj] ) continue; // Ignore the solid walls
int oi = -1, oj = -1;
switch( u ){
case 0:
oi = current.i -1;
oj = current.j -1;
break;
case 2:
oi = current.i +1;
oj = current.j -1;
break;
case 4:
oi = current.i +1;
oj = current.j +1;
break;
case 6:
oi = current.i -1;
oj = current.j +1;
break;
}
if( oi >= 0 && oi < W && oj >=0 && oj < H ){
if( walls[oi][current.j] || walls[current.i][oj] ) continue; // Ingnore blocked diagonals
}
//print( ni+", "+nj+" | " );
if( contains( closedSet, neighbor) ) continue; // Ignore the neighbor which is already evaluated.
// The distance from start to a neighbor
float tentative_gScore = gScore[current.i][current.j] + dist[u]; //dist_between(current, neighbor)
if( !contains( openSet, neighbor ) ){ // Discover a new node
openSet.add( neighbor );
}
else if( tentative_gScore >= gScore[ni][nj] && gScore[ni][nj] >= 0 ) continue; // This is not a better path.
// This path is the best until now. Record it!
cameFrom[ni][nj] = current.get();
gScore[ni][nj] = tentative_gScore;
fScore[ni][nj] = gScore[ni][nj] + heuristic_cost_estimate(neighbor, goal);
}
//println(".");
//ddraw( closedSet, openSet, cameFrom, gScore, start, goal );
}
//println("fuck");
return null; //failure
}
float heuristic_cost_estimate( Index a, Index b ){
return dist( a.i, a.j, b.i, b.j );
}
ArrayList<Index> reconstruct_path(Index[][] cameFrom, Index start, Index goal ){
ArrayList<Index> tp = new ArrayList(); //total_path
tp.add( goal );
while( !tp.get( tp.size() -1 ).equals( start ) ){
tp.add( cameFrom[ tp.get( tp.size() -1 ).i ][ tp.get( tp.size() -1 ).j ].get() );
}
//shorten path
return tp;
}
boolean contains( ArrayList<Index> list, Index item ){
for(int i = 0; i < list.size(); i++){
if( list.get(i).equals( item ) ) return true;
}
return false;
}
```