コード例 #1
0
ファイル: Game.java プロジェクト: paleber/Catan
  public Game(IGameControl control, String... playerNames) {
    players = new Player[playerNames.length];
    for (int i = 0; i < players.length; i++) {
      players[i] = new Player(playerNames[i], i, Color.PINK, control, this);
    }

    this.control = control;

    IBoardBuilder builder = new EasyBoardBuilder();
    Collections.addAll(intersections, builder.getIntersections());
    Collections.addAll(paths, builder.getPaths());
    terrains = builder.getTerrains();

    for (Intersection i : intersections) {
      control.sendGameEvent(i.createSetupEvent());
    }

    for (Path p : paths) {
      control.sendGameEvent(p.createSetupEvent());
    }

    for (Terrain t : terrains) {
      control.sendGameEvent(t.createSetupEvent());
    }

    control.sendGameEvent(new PreparationSettlementPhaseEvent(curPlayerIndex));
  }
コード例 #2
0
ファイル: World.java プロジェクト: JulienNigon/MetaCivTk3
  @Override
  public void update() {

    tick++;

    if (tick == 1) {
      /*Install starting civilizations*/
      ArrayList<String[]> listeCivs =
          Initialiseur.getListeChamp(
              "Civilisation",
              new File(
                  Configuration.pathToRessources
                      + "/environnements/"
                      + Configuration.environnementACharger
                      + Configuration.getExtension()));
      for (int i = 0; i < listeCivs.size(); i++) {

        int u = Integer.parseInt(listeCivs.get(i)[1]);
        int v = Integer.parseInt(listeCivs.get(i)[2]);

        Communaute c = new Communaute(Configuration.getCivilisationByName(listeCivs.get(i)[0]));
        TurtleGenerator.getInstance().createTurtle(c);
        c.moveTo(u, -v);
      }
    }

    /* Periodic actions of the environment*/
    if (tick % 150 == 0) {
      for (int xx = 0; xx < x; xx++) {
        for (int yy = 0; yy < y; yy++) {
          Terrain t = Configuration.couleurs_terrains.get(this.getPatch(xx, yy).getColor());
          for (int i = 0; i < t.getPheroCroissance().size(); i++) {
            this.getPatch(xx, yy)
                .dropPheromone(
                    t.getPheromones().get(i).getNom(), t.getPheroCroissance().get(i).floatValue());
          }

          Pheromone ph = this.getPheromone("passage");
          float phVal = ph.get(xx, yy);
          // if (phVal >= 100)  System.out.println(phVal);
          if (phVal > Configuration.EffacementRoute) {
            ph.set(xx, yy, phVal - Configuration.EffacementRoute);
          } else {
            ph.set(xx, yy, 0);
          }
          phVal = ph.get(xx, yy);
          if (this.getPatch(xx, yy).isMarkPresent("Route")
              && phVal < Configuration.EffacementRoute) {
            this.getPatch(xx, yy).getMark("Route");
          }
        }
      }
    }

    exportData();
  }
コード例 #3
0
ファイル: Grid.java プロジェクト: Enigmamemory/Oranje-Star
 public boolean hasHQ(String side) {
   for (int x = 0; x < Board.length; x++) {
     for (int y = 0; y < Board[x].length; y++) {
       Terrain a = Board[x][y].Floor;
       if (a.getname().equals("HQ    ") && a.getside().equals(side)) {
         return true;
       }
     }
   }
   return false;
 }
コード例 #4
0
ファイル: LevelIO.java プロジェクト: titibuga/UNSWgraphics2
  /**
   * Write Terrain to a JSON file
   *
   * @param file
   * @throws IOException
   */
  public static void save(Terrain terrain, File file) throws IOException {
    JSONObject json = new JSONObject();

    Dimension size = terrain.size();
    json.put("width", size.width);
    json.put("depth", size.height);

    JSONArray jsonSun = new JSONArray();
    float[] sunlight = terrain.getSunlight();
    jsonSun.put(sunlight[0]);
    jsonSun.put(sunlight[1]);
    jsonSun.put(sunlight[2]);
    json.put("sunlight", jsonSun);

    JSONArray altitude = new JSONArray();
    for (int i = 0; i < size.width; i++) {
      for (int j = 0; j < size.height; j++) {
        altitude.put(terrain.getGridAltitude(i, j));
      }
    }
    json.put("altitude", altitude);

    JSONArray trees = new JSONArray();
    for (Tree t : terrain.trees()) {
      JSONObject j = new JSONObject();
      double[] position = t.getPosition();
      j.put("x", position[0]);
      j.put("z", position[2]);
      trees.put(j);
    }
    json.put("trees", trees);

    JSONArray roads = new JSONArray();
    for (Road r : terrain.roads()) {
      JSONObject j = new JSONObject();
      j.put("width", r.width());

      JSONArray spine = new JSONArray();
      int n = r.size();

      for (int i = 0; i <= n * 3; i++) {
        double[] p = r.controlPoint(i);
        spine.put(p[0]);
        spine.put(p[1]);
      }
      j.put("spine", spine);
      roads.put(j);
    }
    json.put("roads", roads);

    FileWriter out = new FileWriter(file);
    json.write(out);
    out.close();
  }
コード例 #5
0
ファイル: RandomLevel.java プロジェクト: Kondou-ger/WORM
  /**
   * Generate a new level.
   *
   * @return a new level
   */
  public Level generate() {
    // Select a theme
    int theme = random.nextInt(3);
    switch (theme) {
      case 0:
        Level.theme = "normal";
        break;
      case 1:
        Level.theme = "horror";
        break;
      case 2:
        Level.theme = "oriental";
        break;
    }

    Terrain terrain = new Terrain();
    /*While not done because of Terrain*/
    while (width < Terrain.width) {

      // Fill a row
      for (int i = Terrain.height - 1; i > height; i--) {
        AbstractTerrainObject toAdd;
        /*If its a 10 the block is explosive*/
        if (random.nextInt(10) == 9) {
          toAdd = new ExplosiveBuildingBlock(width, i);

        } else {
          toAdd = new SquareBuildingBlock(width, i);
        }
        terrain.addTerrainObject(toAdd);
      }
      /* If Random is a 5 */
      if (random.nextInt(6) == 5) {
        wormSpawns.add(new int[] {width, height - 1});
      }
      int nextAction = random.nextInt(5);
      /* If its a 5 or 1 we go down */
      if (nextAction == 0 && height < Terrain.height - 1) {
        height++;
      } else if (nextAction == 4 && height > 0) {
        height--;
      }
      /* Else we keep the height */
      width++;
    }
    Level level = new Level(terrain);
    for (int[] spawn : wormSpawns) {
      level.addWormStartPosition(spawn[0], spawn[1]);
    }

    return level;
  }
コード例 #6
0
ファイル: City.java プロジェクト: ICCARUZ/Ace
 public static void load() {
   if (!City.loaded) {
     City.terrain = new Terrain();
     terrain.defense = 1;
     terrain.mountain = false;
     terrain.moveCost = 1;
     terrain.name = "CITY";
     animations = new Animation[Skirmish.playerCount + 1];
     for (int i = 0; i < Skirmish.playerCount + 1; i++) {
       animations[i] = new Animation("./res/art/structures/city.png", i, 16, 16);
     }
     Structure.structures.add(new City(-1));
     City.loaded = true;
   }
 }
コード例 #7
0
  public void draw() {

    background(0);
    rotate++;
    gl.glColor4f(1, 1, 1, 0.7f);
    gl.glTranslatef(0, 0, -200);
    gl.glRotatef(rotate, 0, 1, 0);
    gl.glRotatef(10, 1, 0, 0);

    t.draw();
  }
コード例 #8
0
  public void setup() {
    size(640, 480, OPENGL);

    ogl = new OpenGL(this);
    this.gl = ogl.gl;
    glu = new GLU();
    s = new Shape(gl);
    t = new Terrain();
    try {
      t.generate(
          100,
          100,
          2,
          20,
          this.getClass().getDeclaredMethod("terrainFunc", new Class[] {Float.class, Float.class}),
          this);
    } catch (Exception e) {
      println(e.getClass() + " : " + e.getMessage());
    }
  }
コード例 #9
0
ファイル: MapGenerator.java プロジェクト: pyr0man1a/StickWars
 /**
  * Starter map for two players. Contains two player controlled factories, one at each corner. The
  * rest is plains.
  *
  * @return
  */
 public static Map generateMap01(Player player1, Player player2) {
   Map newMap = new Map(16, 16);
   newMap.addPlayer(player1);
   newMap.addPlayer(player2);
   for (int i = 0; i < 16; i++) {
     for (int j = 0; j < 16; j++) {
       // Loop through all the coordinates
       if (i == 0 && j == 0) {
         // Player 1's factory.
         Terrain playerOneFactory = Structure.createFactory(player1);
         try {
           newMap.addTerrain(0, 0, playerOneFactory);
         } catch (MapException e) {
           System.out.println("GenerateMap01 Terrain Adding Error: This should never happen.");
           e.printStackTrace();
         }
       } else if (i == 15 && j == 15) {
         // Player 2's factory.
         Terrain playerTwoFactory = Structure.createFactory(player2);
         try {
           newMap.addTerrain(i, j, playerTwoFactory);
         } catch (MapException e) {
           System.out.println("GenerateMap01 Terrain Adding Error: This should never happen.");
           e.printStackTrace();
         }
       } else {
         // Fill with plain.
         Terrain plainTerrain = Terrain.createPlainTerrain();
         try {
           newMap.addTerrain(i, j, plainTerrain);
         } catch (MapException e) {
           System.out.println("GenerateMap01 Terrain Adding Error: This should never happen.");
           e.printStackTrace();
         }
       }
     }
   }
   return newMap;
 }
コード例 #10
0
ファイル: LevelIO.java プロジェクト: titibuga/UNSWgraphics2
  /**
   * Load a terrain object from a JSON file
   *
   * @param mapFile
   * @return
   * @throws FileNotFoundException
   */
  public static Terrain load(File mapFile) throws FileNotFoundException {

    Reader in = new FileReader(mapFile);
    JSONTokener jtk = new JSONTokener(in);
    JSONObject jsonTerrain = new JSONObject(jtk);

    int width = jsonTerrain.getInt("width");
    int depth = jsonTerrain.getInt("depth");
    Terrain terrain = new Terrain(width, depth);

    JSONArray jsonSun = jsonTerrain.getJSONArray("sunlight");
    float dx = (float) jsonSun.getDouble(0);
    float dy = (float) jsonSun.getDouble(1);
    float dz = (float) jsonSun.getDouble(2);
    terrain.setSunlightDir(dx, dy, dz);

    JSONArray jsonAltitude = jsonTerrain.getJSONArray("altitude");
    for (int i = 0; i < jsonAltitude.length(); i++) {
      int x = i % width;
      int z = i / width;

      double h = jsonAltitude.getDouble(i);
      terrain.setGridAltitude(x, z, h);
    }

    if (jsonTerrain.has("trees")) {
      JSONArray jsonTrees = jsonTerrain.getJSONArray("trees");
      for (int i = 0; i < jsonTrees.length(); i++) {
        JSONObject jsonTree = jsonTrees.getJSONObject(i);
        double x = jsonTree.getDouble("x");
        double z = jsonTree.getDouble("z");
        terrain.addTree(x, z);
      }
    }

    if (jsonTerrain.has("others")) {
      JSONArray jsonTrees = jsonTerrain.getJSONArray("others");
      for (int i = 0; i < jsonTrees.length(); i++) {
        JSONObject jsonTree = jsonTrees.getJSONObject(i);
        double x = jsonTree.getDouble("x");
        double z = jsonTree.getDouble("z");
        terrain.addOther(x, z);
      }
    }

    if (jsonTerrain.has("roads")) {
      JSONArray jsonRoads = jsonTerrain.getJSONArray("roads");
      for (int i = 0; i < jsonRoads.length(); i++) {
        JSONObject jsonRoad = jsonRoads.getJSONObject(i);
        double w = jsonRoad.getDouble("width");

        JSONArray jsonSpine = jsonRoad.getJSONArray("spine");
        double[] spine = new double[jsonSpine.length()];

        for (int j = 0; j < jsonSpine.length(); j++) {
          spine[j] = jsonSpine.getDouble(j);
        }
        terrain.addRoad(w, spine);
      }
    }
    return terrain;
  }
コード例 #11
0
ファイル: World.java プロジェクト: JulienNigon/MetaCivTk3
  public void activate() {
    super.activate();

    initExportData();

    new Initialiseur(); // Initialize simulation

    x =
        Integer.parseInt(
            Initialiseur.getChamp(
                "Largeur",
                new File(
                    Configuration.pathToRessources
                        + "/environnements/"
                        + Configuration.environnementACharger
                        + Configuration.getExtension()))[0]);
    y =
        Integer.parseInt(
            Initialiseur.getChamp(
                "Hauteur",
                new File(
                    Configuration.pathToRessources
                        + "/environnements/"
                        + Configuration.environnementACharger
                        + Configuration.getExtension()))[0]);

    /*Reglages sur les civilisations*/
    for (int i = 0; i < Configuration.civilisations.size(); i++) {
      Configuration.civilisations.get(i).postWorldSetup();
    }

    /*Init pheromons*/
    for (int i = 0; i < Configuration.itemsPheromones.size(); i++) {
      this.addFlavor(Configuration.itemsPheromones.get(i).getNom());
    }

    // System.out.println(Configuration.environnementACharger);

    if (Configuration.environnementACharger != null) {
      // System.out.println("Chargement de l'environnement");
      HashMap<Integer, Terrain> typeTerrains = new HashMap<Integer, Terrain>();
      ArrayList<String[]> listeTerrains =
          Initialiseur.getListeChamp(
              "Terrain",
              new File(
                  Configuration.pathToRessources
                      + "/environnements/"
                      + Configuration.environnementACharger
                      + Configuration.getExtension()));
      for (int i = 0; i < listeTerrains.size(); i++) {
        // System.out.println("hash "+i+" "+listeTerrains.get(i)[0]+"
        // "+Configuration.getTerrainByName(listeTerrains.get(i)[0]));

        typeTerrains.put(i, Configuration.getTerrainByName(listeTerrains.get(i)[0]));
        // System.out.println(typeTerrains.get(i) + typeTerrains.get(i).getCouleur().toString());
      }

      ArrayList<String[]> terrains =
          Initialiseur.getListeChamp(
              "Rang",
              new File(
                  Configuration.pathToRessources
                      + "/environnements/"
                      + Configuration.environnementACharger
                      + Configuration.getExtension()));
      for (int i = 0; i < x; i++) {
        for (int j = 0; j < y; j++) {
          Terrain t = typeTerrains.get(Integer.parseInt(terrains.get(y - j - 1)[i]));
          this.getPatch(i, j).setColor(t.getCouleur());
          for (int k = 0; k < t.getPheromones().size(); k++) {
            this.getPatch(i, j)
                .dropPheromone(
                    t.getPheromones().get(k).getNom(), t.getPheroInitiales().get(k).floatValue());
          }
        }
      }

      /*
      AddOn a = new AddOn();
      TurtleGenerator.getInstance().createTurtle(a);
       */

    } else {
      /*Old World Generator*/
      // TODO : Adapt to Metaciv

      /*	int posX;
      int posY;

      for(int i=0;i<this.getWidth();i++)
      	for(int j=0;j<this.getHeight();j++)
      		this.grid[i][j].setColor(ColorOcean);

      for (int i=0; i<nContinents;i++)
      {
      	genererContinents((int)(Math.random()*this.getWidth()) , (int)(Math.random()*this.getHeight()) , 5000 , 8);
      }
      dessinerLesCotes();
      for (int i=0; i< nMontagnes;i++)
      {
      	do
      	{
      		posX = (int)(Math.random()*this.getWidth());
      		posY = (int)(Math.random()*this.getHeight());
      	} while (this.grid[posX][posY].getColor() == ColorOcean);
      	genererMassifMontagneux(posX, posY, 300);
      }
      for (int i=0; i< nForets;i++)
      {
      	do
      	{
      		posX = (int)(Math.random()*this.getWidth());
      		posY = (int)(Math.random()*this.getHeight());
      	} while (this.grid[posX][posY].getColor() == ColorOcean);
      	genererForet(posX, posY, 200, 3);
      }
      for (int i=0; i< nDesertsNord;i++)
      {
      	posX = (int)(Math.random()*this.getWidth());
      	genererDesert(posX, 200, 3, 23.6);
      }
      for (int i=0; i< nDesertsSud;i++)
      {
      	posX = (int)(Math.random()*this.getWidth());
      	genererDesert(posX, 200, 3, -23.6);
      }
      for (int i=0; i< nFleuves;i++)
      {
      	do
      	{
      		posX = (int)(Math.random()*this.getWidth());
      		posY = (int)(Math.random()*this.getHeight());
      	} while (this.grid[posX][posY].getColor() != ColorCollines);
      	while (genererFleuves(posX, posY) == false)
      		{
      			do
      			{
      				posX = (int)(Math.random()*this.getWidth());
      				posY = (int)(Math.random()*this.getHeight());
      			} while (this.grid[posX][posY].getColor() != ColorCollines);
      		}
      }
      genererLittoral();
      initialiserRessources();*/
    }

    // System.out.println("---End World Setup---");

  }
コード例 #12
0
ファイル: MapGenerator.java プロジェクト: pyr0man1a/StickWars
  /**
   * Starter map for two players. Contains two player controlled factories, one at each corner. The
   * rest is plains.
   *
   * @return
   */
  public static Map generateMap02(Player player1, Player player2) {
    Map newMap = new Map(16, 16);
    newMap.addPlayer(player1);
    newMap.addPlayer(player2);
    for (int i = 0; i < 16; i++) {
      for (int j = 0; j < 16; j++) {
        // Loop through all the coordinates
        if ((i == 0 && j == 0) || (i == 2 && j == 0) || (i == 0 && j == 2)) {
          // Player 1's factory.
          Terrain playerOneFactory = Structure.createFactory(player1);
          try {
            newMap.addTerrain(i, j, playerOneFactory);
          } catch (MapException e) {
            System.out.println("GenerateMap01 Terrain Adding Error: This should never happen.");
            e.printStackTrace();
          }
        } else if ((i == 15 && j == 15) || (i == 13 && j == 15) || (i == 15 && j == 13)) {
          // Player 2's factory.
          Terrain playerTwoFactory = Structure.createFactory(player2);
          try {
            newMap.addTerrain(i, j, playerTwoFactory);
          } catch (MapException e) {
            System.out.println("GenerateMap01 Terrain Adding Error: This should never happen.");
            e.printStackTrace();
          }
        } else if ((i == 3 || i == 11) && (j > 3 && j < 11)) {
          // Fill with mountain.
          Terrain mountainTerrain = Terrain.createMountainTerrain();
          try {
            newMap.addTerrain(i, j, mountainTerrain);
          } catch (MapException e) {
            System.out.println("GenerateMap01 Terrain Adding Error: This should never happen.");
            e.printStackTrace();
          }
        } else if ((i > 3 && i < 11) && (j > 3 && j < 11)) {
          // Fill with wood.
          Terrain woodTerrain = Terrain.createWoodTerrain();
          try {
            newMap.addTerrain(i, j, woodTerrain);
          } catch (MapException e) {
            System.out.println("GenerateMap01 Terrain Adding Error: This should never happen.");
            e.printStackTrace();
          }
        } else {
          // Fill with plain.
          Terrain plainTerrain = Terrain.createPlainTerrain();
          try {
            newMap.addTerrain(i, j, plainTerrain);
          } catch (MapException e) {
            System.out.println("GenerateMap01 Terrain Adding Error: This should never happen.");
            e.printStackTrace();
          }
        }
      }
    }

    // Add a unit for each player.
    try {
      newMap.createUnit(0, 0, Unit.createSoldier(player1));
      newMap.createUnit(15, 15, Unit.createSoldier(player2));
    } catch (MapException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }

    return newMap;
  }
コード例 #13
0
ファイル: Map.java プロジェクト: twhscs/game
  private void partition() {
    // TODO: Improve partitioning efficiency. Currently O(n^3).

    /*

    Partition the map into multiple vertex arrays for rendering.
    Vertex arrays speed up rendering time.
    We create these arrays only once as opposed to every frame for even greater optimization.

    See: http://www.sfml-dev.org/tutorials/2.0/graphics-vertex-array.php

     */

    // Loop through each chunk.
    for (int chunkID = 0; chunkID < TOTAL_CHUNKS; chunkID++) {
      // Initialize the chunk's vertex array.
      for (int i = 0; i < ANIMATION_FRAMES; i++) {
        VERTEX_ARRAYS[chunkID][i] = new VertexArray(PrimitiveType.QUADS);
      }
      // Get the top left corner of the current chunk.
      Vector2f position = chunkIDToPosition(chunkID);
      // Loop through the current chunk tile by tile.
      for (int i = (int) position.x; i < position.x + CHUNK_SIZE; i++) {
        for (int j = (int) position.y; j < position.y + CHUNK_SIZE; j++) {
          // Make sure the current tile is valid.
          if (isValidPosition(new Vector2f(i, j))) {
            // Get the current tile.
            final Terrain tile = TILE_ARRAY[i][j];
            // Get the correct texture for the current tile.
            Vector2f textureCoordinates = tile.getTextureCoordinates();
            for (int frame = 0; frame < ANIMATION_FRAMES; frame++) {
              Vector2f animatedTexture;
              if (tile.isAnimated()) {
                animatedTexture =
                    Vector2f.add(textureCoordinates, new Vector2f(TILE_SIZE * frame, 0));
              } else {
                animatedTexture = textureCoordinates;
              }
              if (tile.isAnimated() || frame == 0) {
                // Create a vector for each corner of the texture.
                Vector2f[] positions = new Vector2f[4];
                // Set each corner.
                positions[0] = animatedTexture;
                positions[1] = Vector2f.add(animatedTexture, new Vector2f(0, TILE_SIZE));
                positions[2] = Vector2f.add(animatedTexture, new Vector2f(TILE_SIZE, TILE_SIZE));
                positions[3] = Vector2f.add(animatedTexture, new Vector2f(TILE_SIZE, 0));
                // Determine whether or not the tile is to be randomly rotated.
                boolean random = tile.isRandomized();
                boolean flipped = true;
                if (random) {
                  // Randomly choose 1 - 3 rotations.
                  int rotations = (int) (Math.random() * 3) + 1;
                  // For each rotation shift the coordinates in a circular fashion.
                  for (int k = 0; k < rotations; k++) {
                    Vector2f temp;
                    temp = positions[3];
                    positions[3] = positions[2];
                    positions[2] = positions[1];
                    positions[1] = positions[0];
                    positions[0] = temp;
                  }
                  // Randomly determine whether or not to flip with a 50-50 chance.
                  flipped = (Math.random() < 0.5);
                  if (flipped) {
                    // If flipped, flip the texture coordinates.
                    Vector2f temp;
                    temp = positions[0];
                    positions[0] = positions[1];
                    positions[1] = temp;
                    temp = positions[2];
                    positions[2] = positions[3];
                    positions[3] = temp;
                  }
                }
                if (!tile.isRandomized() || flipped) {
                  // Fix for a JSFML bug. See: http://en.sfml-dev.org/forums/index.php?topic=15889.0
                  for (int k = 0; k < 4; k++) {
                    positions[k] = Vector2f.add(positions[k], new Vector2f(0.01f, -0.01f));
                  }
                }
                // Create and add a vertex for the bottom left corner of the tile.
                VERTEX_ARRAYS[chunkID][frame].add(
                    new Vertex(new Vector2f(i * TILE_SIZE, j * TILE_SIZE), positions[0]));
                // Create and add a vertex for the top left corner of the tile.
                VERTEX_ARRAYS[chunkID][frame].add(
                    new Vertex(
                        new Vector2f(i * TILE_SIZE, j * TILE_SIZE + TILE_SIZE), positions[1]));
                // Create and add a vertex for the top right corner of the tile.
                VERTEX_ARRAYS[chunkID][frame].add(
                    new Vertex(
                        new Vector2f(i * TILE_SIZE + TILE_SIZE, j * TILE_SIZE + TILE_SIZE),
                        positions[2]));
                // Create and add a vertex for the bottom right corner of the tile.
                VERTEX_ARRAYS[chunkID][frame].add(
                    new Vertex(
                        new Vector2f(i * TILE_SIZE + TILE_SIZE, j * TILE_SIZE), positions[3]));
              }
            }
          }
        }
      }
    }
  }
コード例 #14
0
ファイル: GameTile.java プロジェクト: threerings/atlantis
 @Override
 public int hashCode() {
   return terrain.hashCode() ^ (hasShield ? 1 : 0);
 }
コード例 #15
0
ファイル: MyFrame.java プロジェクト: dlarudgus20/pfps
  @Override
  public void display(GLAutoDrawable drawable) {
    GL2 gl2 = drawable.getGL().getGL2();
    GLU glu = GLU.createGLU();

    gl2.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
    gl2.glEnable(GL2.GL_DEPTH_TEST);
    gl2.glDisable(GL2.GL_CULL_FACE);

    gl2.glMatrixMode(GL2.GL_PROJECTION);
    gl2.glLoadIdentity();
    glu.gluPerspective(60, drawable.getSurfaceWidth() / drawable.getSurfaceHeight(), 0.1f, 100);

    gl2.glMatrixMode(GL2.GL_MODELVIEW);
    gl2.glLoadIdentity();

    camera_.apply(gl2, glu);
    light_.apply(gl2, glu);

    terrain_.draw(gl2, glu);

    Runnable triangle =
        () -> {
          gl2.glBegin(GL2.GL_TRIANGLES);
          {
            gl2.glColor3f(1, 1, 1);
            gl2.glNormal3f(0, 0, 1);
            gl2.glVertex3f(0, 1, 0);
            gl2.glColor3f(1, 0, 0);
            gl2.glNormal3f(0, 0, 1);
            gl2.glVertex3f(-0.87f, -0.5f, 0);
            gl2.glColor3f(0, 0, 1);
            gl2.glNormal3f(0, 0, 1);
            gl2.glVertex3f(0.87f, -0.5f, 0);

            gl2.glColor3f(1, 1, 1);
            gl2.glNormal3f(0.71898836f, 0.4170133f, -0.5560177f);
            gl2.glVertex3f(0, 1, 0);
            gl2.glColor3f(0, 0, 1);
            gl2.glNormal3f(0.71898836f, 0.4170133f, -0.5560177f);
            gl2.glVertex3f(0.87f, -0.5f, 0);
            gl2.glColor3f(0, 1, 0);
            gl2.glNormal3f(0.71898836f, 0.4170133f, -0.5560177f);
            gl2.glVertex3f(0, 0, -0.75f);

            gl2.glColor3f(1, 0, 0);
            gl2.glNormal3f(-0.7189883f, 0.41701326f, -0.5560177f);
            gl2.glVertex3f(-0.87f, -0.5f, 0);
            gl2.glColor3f(1, 1, 1);
            gl2.glNormal3f(-0.7189883f, 0.41701326f, -0.5560177f);
            gl2.glVertex3f(0, 1, 0);
            gl2.glColor3f(0, 1, 0);
            gl2.glNormal3f(-0.7189883f, 0.41701326f, -0.5560177f);
            gl2.glVertex3f(0, 0, -0.75f);

            gl2.glColor3f(0, 0, 1);
            gl2.glNormal3f(0, -1.305f, -0.87f);
            gl2.glVertex3f(0.87f, -0.5f, 0);
            gl2.glColor3f(1, 0, 0);
            gl2.glNormal3f(0, -1.305f, -0.87f);
            gl2.glVertex3f(-0.87f, -0.5f, 0);
            gl2.glColor3f(0, 1, 0);
            gl2.glNormal3f(0, -1.305f, -0.87f);
            gl2.glVertex3f(0, 0, -0.75f);
          }
          gl2.glEnd();
        };

    gl2.glPushMatrix();
    {
      gl2.glPushMatrix();
      gl2.glTranslatef(0, 0, 0);
      gl2.glRotatef(angle__, 0, 1, 0);
      triangle.run();
      gl2.glPopMatrix();

      gl2.glPushMatrix();
      gl2.glTranslatef(0, 3.2f, 0);
      gl2.glRotatef(angle__ + 30, 0, 1, 0);
      triangle.run();
      gl2.glPopMatrix();

      gl2.glPushMatrix();
      gl2.glTranslatef(3.2f, 0, 0);
      gl2.glRotatef(angle__ + 60, 0, 1, 0);
      triangle.run();
      gl2.glPopMatrix();
    }
    gl2.glPopMatrix();
    angle__ += 1;

    gl2.glPushMatrix();
    gl2.glTranslatef(0.05f, -1.5f, 5);
    gl2.glScalef(0.05f, 0.05f, 0.05f);
    for (Face face : glock3__.faces) {
      gl2.glBegin(GL2.GL_POLYGON);
      for (FaceVertex vertex : face.vertices) {
        gl2.glColor3f(1, 1, 1);
        gl2.glNormal3f(vertex.n.x, vertex.n.y, vertex.n.z);
        gl2.glVertex3f(vertex.v.x, vertex.v.y, vertex.v.z);
      }
      gl2.glEnd();
    }
    gl2.glPopMatrix();
  }