Advertisement
MrMusAddict

A Star Road Maker

Mar 17th, 2017
556
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 10.58 KB | None | 0 0
  1. int cols = 200;
  2. int rows = cols;
  3.  
  4. Spot[][] grid = new Spot[cols][rows];
  5.  
  6. Spot current;
  7. Spot start;
  8. Spot end;
  9.  
  10. float wi;
  11. float hi;
  12.  
  13. float heightWeight = 40;
  14. float zoom = 20;
  15. float noiseZoom = (cols+rows)/4*(zoom/50);
  16. float intensity = 5;
  17.  
  18. boolean set1 = false;
  19. boolean set2 = false;
  20. boolean reset = false;
  21. int step = 0;
  22.  
  23. Cam c = new Cam();
  24. Terrain t = new Terrain();
  25.  
  26. void setup() {
  27.   size(600, 600, P3D);
  28.   t.generate();
  29. }
  30.  
  31. void draw() {
  32.  
  33.   background(255);
  34.   if (set1 && set2) {
  35.     t.p.find();
  36.     c.update();
  37.     t.p.update();
  38.     t.update();
  39.   } else {
  40.     reset = false;
  41.     t.update();
  42.   }
  43. }
  44.  
  45. void mouseClicked() {
  46.   if (!set1) {
  47.     start = grid[int(mouseX*cols/width)][int(mouseY*rows/height)];
  48.     t.p.openSet.add(start);
  49.     c.closestPoint = start;
  50.     start.col = color(255, 0, 0);
  51.     set1 = true;
  52.     start.city = true;
  53.     c.currentX = -start.i*wi+width/2;
  54.     c.currentY = -start.j*hi+height/2;
  55.     c.currentZ = 400-start.renderHeight;
  56.     c.targetX = c.currentX;
  57.     c.targetY = c.currentY;
  58.     c.targetZ = c.currentZ;
  59.     c.targetTX = c.currentX;
  60.     c.targetTY = c.currentY;
  61.     c.targetTZ = c.currentZ;
  62.   } else if (!set2) {
  63.     end = grid[int(mouseX*cols/width)][int(mouseY*rows/height)];
  64.     end.col = color(0, 255, 0);
  65.     set2 = true;
  66.     end.city = true;
  67.   }
  68. }
  69.  
  70. class Cam {
  71.   float z = 0;
  72.  
  73.   float targetX;
  74.   float targetY;
  75.   float targetZ;
  76.  
  77.   float targetTX;
  78.   float targetTY;
  79.   float targetTZ;
  80.  
  81.   float currentX;
  82.   float currentY;
  83.   float currentZ;
  84.  
  85.   Spot closestPoint;
  86.  
  87.   void update() {
  88.     z += 1;
  89.     getClosestPoint();
  90.     getCameraPos();
  91.     translate(currentX, currentY, currentZ);
  92.   }
  93.  
  94.   void getClosestPoint() {
  95.     float tempD1 = pow(pow(closestPoint.i-end.i, 2)+pow(closestPoint.j-end.j, 2), 0.5);
  96.     for (int i = 0; i < t.p.openSet.size(); i++) {
  97.       Spot s = t.p.openSet.get(i);
  98.       float tempD2 = pow(pow(s.i-end.i, 2)+pow(s.j-end.j, 2), 0.5);
  99.       if (tempD2 < tempD1) {
  100.         closestPoint = s;
  101.       }
  102.     }
  103.  
  104.     targetTX = -current.i*wi+width/2;
  105.     targetTY = -current.j*hi+height/2;
  106.     targetTZ = 400-start.renderHeight-dist(closestPoint.i, closestPoint.j, start.i, start.j)*2;
  107.  
  108.     targetX = (targetTX-targetX)/100+targetX;
  109.     targetY = (targetTY-targetY)/100+targetY;
  110.     targetZ = (targetTZ-targetZ)/100+targetZ;
  111.   }
  112.  
  113.   void getCameraPos() {
  114.     currentX = (targetX-currentX)/100+currentX;
  115.     currentY = (targetY-currentY)/100+currentY;
  116.     currentZ = (targetZ-currentZ)/100+currentZ;
  117.   }
  118.  
  119.   public float heuristic(Spot a, Spot b) {
  120.     float roadMod = 1;
  121.     boolean positive = true;
  122.     float effort = abs(a.k-b.k);
  123.     float dist2D = dist(a.i, a.j, b.i, b.j);
  124.     float dist3D = dist(a.i, a.j, a.k*heightWeight, b.i, b.j, b.k*heightWeight);
  125.  
  126.     if (b.k > a.k) {
  127.       positive = false;
  128.     }
  129.  
  130.     if (positive) {
  131.       effort = map(effort, 0, intensity, 1, 4);
  132.     } else {
  133.       effort = map(effort, 0, intensity, 1, 0.25);
  134.     }
  135.  
  136.     if (a.road && b.road) {
  137.       roadMod = 0;
  138.     }
  139.     if (a.k < 5*intensity/16 && b.k < 5*intensity/16) {
  140.       return dist2D;
  141.     } else if ((a.k > 5*intensity/16 && b.k < 5*intensity/16) || (a.k < 5*intensity/16 && b.k > 5*intensity/16)) {
  142.       return dist3D*3*effort;
  143.     } else if (a.k > 11*intensity/16 || b.k > 11*intensity/16) {
  144.       return dist3D*2*roadMod*effort;
  145.     } else {
  146.       return dist3D*roadMod*effort;
  147.     }
  148.   }
  149. }
  150.  
  151. class Path {
  152.  
  153.   ArrayList<Spot> openSet = new ArrayList<Spot>();
  154.   ArrayList<Spot> closedSet = new ArrayList<Spot>();
  155.   ArrayList<Spot> path = new ArrayList<Spot>();
  156.  
  157.   void update() {
  158.     if (step == 0) {
  159.       step =1;
  160.     } else {
  161.       Spot temp = current;
  162.       path.clear();
  163.       path.add(temp);
  164.       while (temp.previous != null) {
  165.         path.add(temp.previous);
  166.         temp = temp.previous;
  167.       }
  168.  
  169.       noFill();
  170.       stroke(255, 0, 200);
  171.       strokeWeight(wi / 2);
  172.       beginShape(LINES);
  173.       for (int x = 0; x < path.size()-1; x++) {
  174.         vertex(path.get(x).i * wi + wi / 2, path.get(x).j * hi + hi / 2, path.get(x).renderHeight + 2);
  175.         vertex(path.get(x+1).i * wi + wi / 2, path.get(x+1).j * hi + hi / 2, path.get(x).renderHeight + 2);
  176.       }
  177.       endShape();
  178.     }
  179.   }
  180.  
  181.   void find() {
  182.     if (openSet.size() > 0) {
  183.       int winner = 0;
  184.       for (int i = 0; i < openSet.size(); i++) {
  185.         if (openSet.get(i).f < openSet.get(winner).f) {
  186.           winner = i;
  187.         }
  188.       }
  189.  
  190.       current = openSet.get(winner);
  191.  
  192.  
  193.       if (current == end) {
  194.         finishCycle();
  195.         print("Path Found!");
  196.         reset = true;
  197.       }
  198.  
  199.       if (!reset) {
  200.         removeFromArray(openSet, current);
  201.         closedSet.add(current);
  202.  
  203.         ArrayList<Spot> neighbors = current.neighbors;
  204.  
  205.         for (int i = 0; i < neighbors.size(); i++) {
  206.           Spot n = neighbors.get(i);
  207.           boolean contains = false;
  208.  
  209.           for (Spot x : closedSet) {
  210.             if (x == n) {
  211.               contains = true;
  212.             }
  213.           }
  214.  
  215.           if (!contains) {
  216.             float tempG = current.g+heuristic(n, current);
  217.  
  218.             boolean newPath = false;
  219.             boolean contains2 = false;
  220.  
  221.             for (Spot x : openSet) {
  222.               if (x == n) {
  223.                 contains2 = true;
  224.               }
  225.             }
  226.  
  227.             if (contains2) {
  228.               if (tempG < n.g) {
  229.                 n.g = tempG;
  230.                 newPath = true;
  231.               }
  232.             } else {
  233.               n.g = tempG;
  234.               newPath = true;
  235.               openSet.add(n);
  236.             }
  237.  
  238.             if (newPath) {
  239.               n.h = heuristic(n, end);
  240.               n.f = n.g + n.h;
  241.               n.previous = current;
  242.             }
  243.           }
  244.         }
  245.       }
  246.     } else {
  247.       print("No Solution!");
  248.       noLoop();
  249.       return;
  250.     }
  251.   }
  252.  
  253.   void removeFromArray(ArrayList<Spot> arr, Spot elt) {
  254.     for (int i = arr.size() - 1; i >= 0; i--) {
  255.       if (arr.get(i) == elt) {
  256.         arr.remove(i);
  257.       }
  258.     }
  259.   }
  260.  
  261.   public float heuristic(Spot a, Spot b) {
  262.     float roadMod = 1;
  263.     boolean positive = true;
  264.     float effort = abs(a.k-b.k);
  265.     float dist2D = dist(a.i, a.j, b.i, b.j);
  266.     float dist3D = dist(a.i, a.j, a.k*heightWeight, b.i, b.j, b.k*heightWeight);
  267.  
  268.     if (b.k > a.k) {
  269.       positive = false;
  270.     }
  271.  
  272.     if (positive) {
  273.       effort = map(effort, 0, intensity, 1, 4);
  274.     } else {
  275.       effort = map(effort, 0, intensity, 1, 0.25);
  276.     }
  277.  
  278.     if (a.road && b.road) {
  279.       roadMod = 0.15;
  280.     }
  281.     if (a.k < 5*intensity/16 && b.k < 5*intensity/16) {
  282.       return dist2D;
  283.     } else if ((a.k > 5*intensity/16 && b.k < 5*intensity/16) || (a.k < 5*intensity/16 && b.k > 5*intensity/16)) {
  284.       return dist3D*3*effort;
  285.     } else if (a.k > 11*intensity/16 || b.k > 11*intensity/16) {
  286.       return dist3D*2*roadMod*effort;
  287.     } else {
  288.       return dist3D*roadMod*effort;
  289.     }
  290.   }
  291.  
  292.   void finishCycle() {
  293.     drawRoad();
  294.     start.col = color(0, 0, 0);
  295.     end.col = color(0, 0, 0);
  296.     openSet.clear();
  297.     closedSet.clear();
  298.     path.clear();
  299.     start = grid[0][0];
  300.     end = grid[0][0];
  301.     set1 = false;
  302.     set2 = false;
  303.   }
  304.  
  305.   void drawRoad() {
  306.     Spot temp = current;
  307.     path.clear();
  308.     path.add(temp);
  309.     while (temp.previous != null) {
  310.       if (temp.k > 5*intensity/16) {
  311.         temp.road = true;
  312.       }
  313.       path.add(temp.previous);
  314.       temp = temp.previous;
  315.     }
  316.     start.road = true;
  317.   }
  318. }
  319.  
  320. class Spot {
  321.  
  322.   ArrayList<Spot> neighbors = new ArrayList<Spot>();
  323.   Spot previous = null;
  324.  
  325.   boolean road = false;
  326.   boolean city = false;
  327.   float f;
  328.   float g;
  329.   float h;
  330.  
  331.   int i;
  332.   int j;
  333.   float k;
  334.   float renderHeight;
  335.  
  336.   color col;
  337.  
  338.   Spot(int i_, int j_, float k_) {
  339.     i = i_;
  340.     j = j_;
  341.     k = k_;
  342.  
  343.     f = 0;
  344.     g = 0;
  345.     h = 0;
  346.  
  347.     if (k<5*intensity/16) {
  348.       col = color(map(k, 0, 5*intensity/16, 0, 28), map(k, 0, 5*intensity/16, 0, 107), map(k, 0, 5*intensity/16, 0, 160));
  349.     } else if (k>11*intensity/16) {
  350.       col = color(map(k, 11*intensity/16, intensity, 139, 255), map(k, 11*intensity/16, intensity, 141, 255), map(k, 11*intensity/16, intensity, 122, 255));
  351.     } else {
  352.       col = color(map(k, 5*intensity/16, 11*intensity/16, 239, 0), map(k, 5*intensity/16, 11*intensity/16, 221, 96), map(k, 5*intensity/16, 11*intensity/16, 111, 20));
  353.     }
  354.  
  355.     if (k<5*intensity/16) {
  356.       renderHeight = 5*intensity/16 * 20;
  357.     } else {
  358.       renderHeight = k * 20;
  359.     }
  360.   }
  361.  
  362.   void showBackground() {
  363.     noStroke();
  364.     if (city) {
  365.       col = color(0, 0, 0);
  366.     } else if (road) {
  367.       col = color(120, 72, 0);
  368.     }
  369.     fill(col);
  370.     if (set1 && set2) {
  371.       translate(0, 0, renderHeight);
  372.       rect(i * wi, j * hi, wi, hi);
  373.       translate(0, 0, -renderHeight);
  374.     } else {
  375.       rect(i * wi, j * hi, wi, hi);
  376.     }
  377.   }
  378.  
  379.   void show(color c) {
  380.     if (road) {
  381.       fill(color(120, 72, 0));
  382.     } else {
  383.       fill(c);
  384.     }
  385.     if (set1 && set2) {
  386.       translate(0, 0, renderHeight);
  387.       rect(i * wi, j * hi, wi, hi);
  388.       translate(0, 0, -renderHeight);
  389.     } else {
  390.       rect(i * wi, j * hi, wi, hi);
  391.     }
  392.   }
  393.  
  394.   void addNeighbors() {
  395.     if (i < cols - 1) {
  396.       neighbors.add(grid[i + 1][j]);
  397.     }
  398.     if (i > 0) {
  399.       neighbors.add(grid[i - 1][j]);
  400.     }
  401.     if (j < rows - 1) {
  402.       neighbors.add(grid[i][j + 1]);
  403.     }
  404.     if (j > 0) {
  405.       neighbors.add(grid[i][j - 1]);
  406.     }
  407.     if (i > 0 && j > 0) {
  408.       neighbors.add(grid[i - 1][j - 1]);
  409.     }
  410.     if (i < cols - 1 && j > 0) {
  411.       neighbors.add(grid[i + 1][j - 1]);
  412.     }
  413.     if (i > 0 && j < rows - 1) {
  414.       neighbors.add(grid[i - 1][j + 1]);
  415.     }
  416.     if (i < cols - 1 && j < rows - 1) {
  417.       neighbors.add(grid[i + 1][j + 1]);
  418.     }
  419.   }
  420. }
  421.  
  422. class Terrain {
  423.  
  424.   Path p = new Path();
  425.  
  426.   void update() {
  427.     for (int i = 0; i < cols; i++) {
  428.       for (int j = 0; j < rows; j++) {
  429.         grid[i][j].showBackground();
  430.       }
  431.     }
  432.  
  433.     for (Spot s : p.openSet) {
  434.       s.show(color(255, 0, 0, 50));
  435.     }
  436.  
  437.     for (Spot s : p.closedSet) {
  438.       s.show(color(0, 255, 0, 50));
  439.     }
  440.   }
  441.  
  442.   void generate() {
  443.     wi = width / cols;
  444.     hi = height / rows;
  445.  
  446.     for (int i = 0; i < cols; i++) {
  447.       for (int j = 0; j < rows; j++) {
  448.         grid[i][j] = new Spot(i, j, noise(((i-1000)/noiseZoom), ((j-1000)/noiseZoom))*intensity);
  449.       }
  450.     }
  451.     for (int i = 0; i < cols; i++) {
  452.       for (int j = 0; j < rows; j++) {
  453.         grid[i][j].addNeighbors();
  454.       }
  455.     }
  456.  
  457.     start = grid[0][0];
  458.     end = grid[cols - 1][rows-1];
  459.   }
  460.  
  461.  
  462. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement