Android Open Source - nahlc-g Renderer






From Project

Back to project page nahlc-g.

License

The source code is released under:

Apache License

If you think the Android project nahlc-g listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 *   Copyright 2014 oddlydrawn//  w  w  w.  j a  va 2s  .  c o m
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

package com.tumblr.oddlydrawn.nahlc;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;

/** @author oddlydrawn */
public class Renderer {
  final public static float WIDTH = 320; // 320
  final public static float HEIGHT = 480; // 480
  private final String FONT_LOC = "data/fonts/d.fnt";
  private final String SCORE = "Score:";
  private final String LEVEL = "Level:";
  private final String HI_SCORE = "HiScore:";
  private final float GLYPH_WIDTH = 11; // 11
  private final float RIGHT_ORIGIN = 300; // 300
  public static final float LOVELY_GRAY = 0.18f; // 0.18f
  private final int NEXT_SHAPE_ORIGIN_X = 15; // 15
  private final int NEXT_SHAPE_ORIGIN_Y = 1; // 1
  private final int NEXT_SHAPE_BG_X = 15; // 15
  private final int NEXT_SHAPE_BG_Y = 1; // 1
  private final int PAD_HORIZONTAL = 16; // 16
  private final int PAD_VERTICAL = 0; // 0
  private final int BACKGROUND = 7; // 7
  private final int PAD_THREE = 3; // 3
  private final int PAD_TWO = 2; // 2
  private final int I = 0; // 0
  private final int O = 1; // 1
  private final int T = 2; // 2
  private final int J = 3; // 3
  private final int L = 4; // 4
  private final int S = 5; // 5
  private final int Z = 6; // 6
  private BitmapFont font;
  private SpriteBatch batch;
  private OrthographicCamera camera;
  private Board board;
  private Floater floater;
  private Assets assets;
  private TextureRegion region;
  private Texture distanceFontTexture;
  // Coords for next shape.
  private Coords posOne;
  private Coords posTwo;
  private Coords posThree;
  private Coords posFour;
  private String tmpString;
  private String highScoreString;
  private SavedStuff savedStuff;
  private ShaderProgram fontShader;
  private int highScore;
  private int color;
  private int x;
  private int y;
  private int tmpX;
  private int tmpY;
  private int nextShape;

  /** Creates new objects and sets camera up. */
  public Renderer () {
    batch = new SpriteBatch();
    camera = new OrthographicCamera(WIDTH, HEIGHT);
    camera.setToOrtho(true, WIDTH, HEIGHT);

    distanceFontTexture = new Texture(Gdx.files.internal("data/fonts/d.png"), true); // true enables mipmaps
    distanceFontTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear); // linear filtering in nearest
// mipmap image

    font = new BitmapFont(Gdx.files.internal(FONT_LOC), new TextureRegion(distanceFontTexture), true);

    fontShader = new ShaderProgram(Gdx.files.internal("data/shaders/distancefield.vert"),
      Gdx.files.internal("data/shaders/distancefield.frag"));
    if (!fontShader.isCompiled()) {
      Gdx.app.error("fontShader", "compilation failed:\n" + fontShader.getLog());
    }

    posOne = new Coords();
    posTwo = new Coords();
    posThree = new Coords();
    posFour = new Coords();

  }

  /** render() renders stuff, clears the screen. */
  public void render (float delta) {
    Gdx.gl.glClearColor(LOVELY_GRAY, LOVELY_GRAY, LOVELY_GRAY, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    if (floater.isGameOver()) {
      System.out.println("game over");
    }
    batch.setProjectionMatrix(camera.combined);
    batch.begin();

    batch.setShader(null);
    batch.disableBlending();

    // Next shape isn't a board so it doesn't have empty squares to serve as a background.
    drawNextShapeBackground();

    // Order matters. Board's empty squares serve as background.
    if (savedStuff.isUpsideDown() == true) {
      drawBoardUpsideDown();
      nextShapePosUpdate();
      vertInvertNextShape();
    } else {
      drawBoard(batch);
      nextShapePosUpdate();
    }
    drawNextShape();

    batch.enableBlending();

    assets.getLeftSprite().draw(batch);
    assets.getRightSprite().draw(batch);
    assets.getDownSprite().draw(batch);
    assets.getRotateLeftSprite().draw(batch);
    assets.getRotateRightSprite().draw(batch);
    assets.getDropDownSprite().draw(batch);
    assets.getPauseSprite().draw(batch);

    batch.setShader(fontShader);
    // "Level:"
    font.draw(batch, LEVEL, 235, 120);
    // Level number
    tmpString = Integer.toString(board.getCurrentLevel());
    font.draw(batch, tmpString, rightJustify(tmpString), 142);

    // "Score:"
    font.draw(batch, SCORE, 235, 174);
    // Score number from board
    tmpString = Integer.toString(board.getCurrentScore());
    font.draw(batch, tmpString, rightJustify(tmpString), 196);

    // "HiScore:"
    font.draw(batch, HI_SCORE, 235, 228);
    if (board.getCurrentScore() < highScore) {
      font.draw(batch, highScoreString, rightJustify(highScoreString), 250);
    } else {
      tmpString = Integer.toString(board.getCurrentScore());
      font.draw(batch, tmpString, rightJustify(tmpString), 250);
    }

    batch.setShader(null);

    if (floater.isPaused() == true) {
      assets.getBoxPatch().draw(batch, Assets.BLOCK_WIDTH * PAD_TWO, Assets.BLOCK_HEIGHT * PAD_TWO,
        (Board.BOARD_WIDTH - PAD_TWO) * Assets.BLOCK_WIDTH, (Board.BOARD_HEIGHT - PAD_THREE) * Assets.BLOCK_HEIGHT);
      assets.getPauseNoticeSprite().draw(batch);
    }
    batch.end();
  }

  private void drawBoard (SpriteBatch batch) {
    // Since board's y=0 is just padding for correct, simple drops, we omit that.
    for (y = 1; y < Board.BOARD_HEIGHT; y++) {
      for (x = 0; x < Board.BOARD_WIDTH; x++) {
        // Converts for() coordinates to pixels.
        tmpX = x * Assets.BLOCK_WIDTH;
        tmpY = y * Assets.BLOCK_HEIGHT;

        // Adds the padding for pretty and even borders.
        tmpX += PAD_HORIZONTAL;
        tmpY += PAD_VERTICAL;

        // Gets the color of the block at combinedBoard's (x, y)
        color = board.getColor(x, y);

        // Gets the corresponding textureRegion from assets.
        region = assets.getBlock(color);

        // Then we paint it to the screen. Isn't it pretty?
        batch.draw(region, tmpX, tmpY, Assets.BLOCK_WIDTH, Assets.BLOCK_HEIGHT);
      }
    }
    drawFloaterBlock(floater.getPosOne());
    drawFloaterBlock(floater.getPosTwo());
    drawFloaterBlock(floater.getPosThree());
    drawFloaterBlock(floater.getPosFour());
  }

  private void drawFloaterBlock (Coords coords) {
    tmpX = coords.getX() * Assets.BLOCK_WIDTH;
    tmpY = coords.getY() * Assets.BLOCK_HEIGHT;
    tmpX += PAD_HORIZONTAL;
    tmpY += PAD_VERTICAL;
    color = floater.getShapeColor();
    region = assets.getBlock(color);
    batch.draw(region, tmpX, tmpY, Assets.BLOCK_WIDTH, Assets.BLOCK_HEIGHT);
  }

  private void drawBoardUpsideDown () {
    // Since board's y=0 is just padding for correct, simple drops, we omit that.
    for (y = 0; y < Board.BOARD_HEIGHT - 1; y++) {
      for (x = 0; x < Board.BOARD_WIDTH; x++) {
        // Converts for() coordinates to pixels.
        tmpX = x * Assets.BLOCK_WIDTH;
        tmpY = y * Assets.BLOCK_HEIGHT;

        // Adds the padding for pretty and even borders.
        tmpX += PAD_HORIZONTAL;
        tmpY += PAD_HORIZONTAL;

        // Gets the color of the block at combinedBoard's (x, y)
        color = board.getColor(x, Board.BOARD_HEIGHT - 1 - y);

        // Gets the corresponding textureRegion from assets.
        region = assets.getBlock(color);

        // Then we paint it to the screen. Isn't it pretty?
        batch.draw(region, tmpX, tmpY, Assets.BLOCK_WIDTH, Assets.BLOCK_HEIGHT);
      }
    }
    drawFloaterBlockUpsideDown(floater.getPosOne());
    drawFloaterBlockUpsideDown(floater.getPosTwo());
    drawFloaterBlockUpsideDown(floater.getPosThree());
    drawFloaterBlockUpsideDown(floater.getPosFour());
  }

  private void drawFloaterBlockUpsideDown (Coords coords) {
    tmpX = coords.getX() * Assets.BLOCK_WIDTH;
    // Upside down the vertical
    tmpY = Board.BOARD_HEIGHT - 1 - coords.getY();
    tmpY *= Assets.BLOCK_HEIGHT;

    // Adds the padding for pretty and even borders.
    tmpX += PAD_HORIZONTAL;
    tmpY += PAD_HORIZONTAL;

    color = floater.getShapeColor();

    // Gets the corresponding textureRegion from assets.
    region = assets.getBlock(color);

    // Then we paint it to the screen. Isn't it pretty?
    batch.draw(region, tmpX, tmpY, Assets.BLOCK_WIDTH, Assets.BLOCK_HEIGHT);
  }

  private void drawNextShapeBackground () {
    region = assets.getBlock(BACKGROUND);
    for (x = 0; x < 4; x++) {
      for (y = 0; y < 6; y++) {
        // Converts for() coordinates to pixels.
        tmpX = x + NEXT_SHAPE_BG_X;
        tmpX *= Assets.BLOCK_WIDTH;

        tmpY = y + NEXT_SHAPE_BG_Y;
        tmpY *= Assets.BLOCK_HEIGHT;

        // Pretty, pretty.
        batch.draw(region, tmpX, tmpY, Assets.BLOCK_WIDTH, Assets.BLOCK_HEIGHT);
      }
    }
  }

  private void nextShapePosUpdate () {
    // Gets next shape and corresponding region.
    nextShape = floater.getNextShape();
    region = assets.getBlock(nextShape);

    // Determines the basic coordinates needed to draw the right shape.
    switch (nextShape) {
    case I:
      posOne.set(1, 1);
      posTwo.set(1, 2);
      posThree.set(1, 3);
      posFour.set(1, 4);
      break;
    case O:
      posOne.set(1, 2);
      posTwo.set(2, 2);
      posThree.set(1, 3);
      posFour.set(2, 3);
      break;
    case T:
      posOne.set(1, 2);
      posTwo.set(1, 3);
      posThree.set(2, 3);
      posFour.set(1, 4);
      break;
    case J:
      posOne.set(1, 2);
      posTwo.set(1, 3);
      posThree.set(1, 4);
      posFour.set(2, 2);
      break;
    case L:
      posOne.set(2, 2);
      posTwo.set(2, 3);
      posThree.set(2, 4);
      posFour.set(1, 2);
      break;
    case S:
      posOne.set(1, 2);
      posTwo.set(1, 3);
      posThree.set(2, 3);
      posFour.set(2, 4);
      break;
    case Z:
      posOne.set(2, 2);
      posTwo.set(2, 3);
      posThree.set(1, 3);
      posFour.set(1, 4);
      break;
    }
  }

  private void vertInvertNextShape () {
    posOne.y = 5 - posOne.y;
    posTwo.y = 5 - posTwo.y;
    posThree.y = 5 - posThree.y;
    posFour.y = 5 - posFour.y;
  }

  private void drawNextShape () {
    // Adds the distance from origin to block's coordinates.
    posOne.x += NEXT_SHAPE_ORIGIN_X;
    // Converts to pixels.
    posOne.x *= Assets.BLOCK_WIDTH;

    // Does the same with y coordinates.
    posOne.y += NEXT_SHAPE_ORIGIN_Y;
    posOne.y *= Assets.BLOCK_HEIGHT;

    // Draws the single block.
    batch.draw(region, posOne.x, posOne.y, Assets.BLOCK_WIDTH, Assets.BLOCK_HEIGHT);

    // Et cetera, et cetera.
    posTwo.x += NEXT_SHAPE_ORIGIN_X;
    posTwo.x *= Assets.BLOCK_WIDTH;
    posTwo.y += NEXT_SHAPE_ORIGIN_Y;
    posTwo.y *= Assets.BLOCK_HEIGHT;
    batch.draw(region, posTwo.x, posTwo.y, Assets.BLOCK_WIDTH, Assets.BLOCK_HEIGHT);

    posThree.x += NEXT_SHAPE_ORIGIN_X;
    posThree.x *= Assets.BLOCK_WIDTH;
    posThree.y += NEXT_SHAPE_ORIGIN_Y;
    posThree.y *= Assets.BLOCK_HEIGHT;
    batch.draw(region, posThree.x, posThree.y, Assets.BLOCK_WIDTH, Assets.BLOCK_HEIGHT);

    posFour.x += NEXT_SHAPE_ORIGIN_X;
    posFour.x *= Assets.BLOCK_WIDTH;
    posFour.y += NEXT_SHAPE_ORIGIN_Y;
    posFour.y *= Assets.BLOCK_HEIGHT;
    batch.draw(region, posFour.x, posFour.y, Assets.BLOCK_WIDTH, Assets.BLOCK_HEIGHT);
  }

  /** Numbers should be right justified, I think. This does that.
   * @return The X position needed to correctly right justify text. */
  private float rightJustify (String s) {
    x = s.length() - 1;
    x *= GLYPH_WIDTH;
    return RIGHT_ORIGIN - x;
  }

  public void setFloater (Floater floater) {
    this.floater = floater;
    int bagSize = savedStuff.getBagSize();
    floater.setBagSize(bagSize);
  }

  public void setAssets (Assets assets) {
    this.assets = assets;
  }

  public void setBoard (Board board) {
    this.board = board;
  }

  public void setAudio (Audio audio) {
    boolean soundOn = savedStuff.isSoundOn();
    boolean musicOn = savedStuff.isMusicOn();
    audio.setSoundTo(soundOn);
    audio.setMusicTo(musicOn);
  }

  public OrthographicCamera getCam () {
    return camera;
  }

  public void resize (int width, int height) {
    if (camera != null) {
      camera.setToOrtho(true, WIDTH, HEIGHT);
    }
  }

  public void setController (Controller controller) {
    controller.setSavedStuff(savedStuff);
  }

  public void setSavedStuff (SavedStuff savedStuff) {
    this.savedStuff = savedStuff;

    highScoreString = savedStuff.getHighScore();
    highScore = Integer.parseInt(savedStuff.getHighScore());
  }

  public void dispose () {
    fontShader.dispose();
    distanceFontTexture.dispose();
    font.dispose();
    batch.dispose();
  }
}




Java Source Code List

com.tumblr.oddlydrawn.nahlc.Assets.java
com.tumblr.oddlydrawn.nahlc.Audio.java
com.tumblr.oddlydrawn.nahlc.Board.java
com.tumblr.oddlydrawn.nahlc.Controller.java
com.tumblr.oddlydrawn.nahlc.Coords.java
com.tumblr.oddlydrawn.nahlc.Floater.java
com.tumblr.oddlydrawn.nahlc.IOSLauncher.java
com.tumblr.oddlydrawn.nahlc.MyGdxGame.java
com.tumblr.oddlydrawn.nahlc.Renderer.java
com.tumblr.oddlydrawn.nahlc.SavedStuff.java
com.tumblr.oddlydrawn.nahlc.android.AndroidLauncher.java
com.tumblr.oddlydrawn.nahlc.client.GwtLauncher.java
com.tumblr.oddlydrawn.nahlc.desktop.DesktopLauncher.java
com.tumblr.oddlydrawn.nahlc.screens.GameOverScreen.java
com.tumblr.oddlydrawn.nahlc.screens.GameScreen.java
com.tumblr.oddlydrawn.nahlc.screens.LicenseScreen.java
com.tumblr.oddlydrawn.nahlc.screens.LoadingScreen.java
com.tumblr.oddlydrawn.nahlc.screens.MainMenuScreen.java
com.tumblr.oddlydrawn.nahlc.screens.SettingScreen.java
com.tumblr.oddlydrawn.nahlc.screens.SetupScreen.java
com.tumblr.oddlydrawn.nahlc.screens.SplashScreen.java