Android Open Source - DivisionByZero Tower Menu






From Project

Back to project page DivisionByZero.

License

The source code is released under:

Apache License

If you think the Android project DivisionByZero 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

package com.ggstudios.divisionbyzero;
//  w  ww . java  2  s. c o  m
import java.util.ArrayList;
import java.util.List;

import com.ggstudios.utils.BitmapUtils;
import com.ggstudios.utils.BufferUtils;
import com.ggstudios.utils.DebugLog;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.opengl.GLES20;
import android.view.MotionEvent;
import android.view.ViewConfiguration;

import static fix.android.opengl.GLES20.glVertexAttribPointer;

public class TowerMenu extends Drawable implements Clickable, Updatable {
  private static final String TAG = "TowerMenu";
  /*
   * HUD design:
   * 
   * |--------------------------------|
   * |                |
   * |                |
   * |                | 
   * |                |
   * |           ___________|
   * |          |      |< HUD Tower Menu
   * |--------------------------------|
   * 
   */

  // in SDP
  private static final float MENU_WIDTH = 7.0f;
  private static final float MENU_HEIGHT = 1.75f;

  private static final float ITEM_WIDTH = 1.55f;
  private static final float ITEM_HEIGHT = 1.55f;

  private float itemW;

  private float margin;

  private PictureBox bg;
  private PictureBox selectionBox;

  float width;
  float height;

  float x, y;

  private RectF rect = new RectF();

  private List<Tower> towers = new ArrayList<Tower>();
  private List<Drawable> drawables = new ArrayList<Drawable>();
  private List<Label> labels = new ArrayList<Label>();
  private List<Label> shadows = new ArrayList<Label>();
  private List<RectF> precalculatedClickBounds = new ArrayList<RectF>();

  private int maxDisplay;
  private int index = 0;
  private int end = 0;
  private int drawableLen = 0;
  private boolean itemSelected = false;
  private int itemSelectedIndex = -1;

  private Updatable selectionBoxUpdatable;
  private RectF thisRegion;

  // scroll bar variables:

  // 
  //     |--------| 
  // ____|________|_______
  // ^scrollLeft
  private static final int SCROLL_BAR_COLOR = 0xFF33B5E5;
  private static final float SCROLL_BAR_HEIGHT_SDP = 0.1f;
  private static final float FADE_TIME = 0.5f;
  private static final float SHOW_TIME = 0.5f;

  private float timeLeft;
  private int scrollBarId;
  private int scrollBarHandle;
  private float scrollBarWidth;
  private float scrollX = 0f;
  private float scrollLeft = 0f;  // denote the area to the left of the current scroll position
  private float totalW = 0f;
  private float maxScrollLeft = 0f;
  private float scrollBarTop;
  private float touchSlop;
  private boolean scrollEnabled = true;
  // End of scroll bar variables...

  private TowerInfoDialog towerInfoDialog;
  
  public TowerMenu(float x, float y) {
    this.x = x;
    this.y = y;

    width = MENU_WIDTH * Core.SDP;
    height = MENU_HEIGHT * Core.SDP;

    margin = ((MENU_HEIGHT - ITEM_HEIGHT)/ 2f) * Core.SDP;

    itemW = ITEM_WIDTH * Core.SDP + margin * 2;

    maxDisplay = (int)(MENU_WIDTH / ITEM_WIDTH);

    DebugLog.d(TAG, "maxDisplay: " + maxDisplay);

    bg = new PictureBox(0, 0, 
        width, height, R.drawable.right_panel);

    selectionBox = new PictureBox(0, 0, 
        Core.SDP * MENU_HEIGHT, Core.SDP * MENU_HEIGHT, R.drawable.selection_box);

    towerInfoDialog = new TowerInfoDialog();
    
    thisRegion = new RectF();
    thisRegion.left = 0;
    thisRegion.right = width;
    thisRegion.top = 0;
    thisRegion.bottom = height;

    touchSlop = ViewConfiguration.get(Core.context).getScaledTouchSlop();

    setIndex(0);
  }

  public void addTower(Tower tower) {
    towers.add(tower);
  }

  public void build() {
    synchronized(drawables) {
      drawables.clear();
      int n = 0;

      final float w = ITEM_WIDTH * Core.SDP;
      final float h = ITEM_HEIGHT * Core.SDP;

      Paint paintShadow = new Paint();
      paintShadow.setTypeface(Typeface.DEFAULT_BOLD);
      paintShadow.setAntiAlias(true);
      paintShadow.setTextSize(Core.SDP_H * 1.1f);
      paintShadow.setColor(0xB0000000);

      Paint paint = new Paint();
      paint.setTypeface(Typeface.DEFAULT_BOLD);
      paint.setAntiAlias(true);
      paint.setTextSize(Core.SDP_H * 1f);
      paint.setColor(0xE082dbe0);

      for(Tower t : towers) {
        t.build(w, h);
        t.x = itemW * n + margin;
        t.y = margin;
        n++;

        RectF r = new RectF();
        r.top = t.y;
        r.left = t.x;
        r.bottom = r.top + t.h;
        r.right = r.left + t.w;

        Label l = new Label(t.x, t.y, paint, String.valueOf(t.getCost()));
        l.x += t.w - l.w;//t.x + (t.w - l.w) / 2f;
        l.y += t.h - l.h;
        labels.add(l);

        Label shadow = new Label(l.x, l.y, paintShadow, l.getText());
        shadows.add(shadow);

        drawables.add(t);
        precalculatedClickBounds.add(r);
      }

      drawableLen = drawables.size();
    }
    
    if(maxDisplay >= towers.size()) {
      // if we can show everything in the menu then no need for scrolling...
      scrollEnabled = false;
    } else {
      scrollEnabled = true;
    }
    
    totalW = towers.size() * itemW;
    maxScrollLeft = totalW - width;
    scrollBarWidth = (maxDisplay / (float)towers.size()) * width;
    genScrollBar((int) scrollBarWidth);
    
    towerInfoDialog.build();
  }

  public void setIndex(int index) {
    this.index = index;
    this.end = index + maxDisplay;

    DebugLog.d(TAG, "Beginning index set to: " + index + " end: " + end);
  }
  
  public void setSelectedIndex(int index) {
    if(index >= 0) {
      this.itemSelected = true;
      this.itemSelectedIndex = index;
    } else {
      this.itemSelected = false;
    }
  }

  @Override
  public void draw(float offX, float offY) {
    bg.draw(x, y);

    // enable clipping...
    GLES20.glEnable(GLES20.GL_SCISSOR_TEST);
    GLES20.glScissor((int)x, 0, (int) (width), (int)Core.canvasHeight);

    if(itemSelected)
      selectionBox.draw(x + scrollLeft, y);

    for(int i = index; i < end && i < drawableLen; i++){
      drawables.get(i).draw(x + scrollLeft, y);
      shadows.get(i).draw(x + scrollLeft, y);
      labels.get(i).draw(x + scrollLeft, y);
    }
    
    GLES20.glDisable(GLES20.GL_SCISSOR_TEST);

    // draw our scroll bar...
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, scrollBarId);

    Utils.resetMatrix();
    Utils.translateAndCommit(x + scrollX, y + scrollBarTop);

    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, scrollBarHandle);
    glVertexAttribPointer(Core.A_POSITION_HANDLE, 2, GLES20.GL_FLOAT, false, 0, 0);

    Shader.setColorMultiply(1f, 1f, 1f, timeLeft / FADE_TIME);
    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
    Shader.resetColorMultiply();
  }

  @Override
  public void refresh() {
    bg.refresh();
    selectionBox.refresh();
    for(int i = 0; i < drawableLen; i++){
      drawables.get(i).refresh();
      labels.get(i).refresh();
      shadows.get(i).refresh();
    }
    
    genScrollBar((int) scrollBarWidth);
  }

  @Override
  public boolean update(float dt) {
    if(timeLeft < 0) return true;
    timeLeft -= dt;
    if(timeLeft < 0) timeLeft = 0;
    return true;
  }

  private float lastX;
  private float startingX, startingY;
  private boolean canceled = false;

  public Tower getSelectedTower() {
    if(itemSelected)
      return towers.get(itemSelectedIndex);
    else
      return null;
  }

  @Override
  public boolean onTouchEvent(int action, float x, float y) {
    switch(action) {
    case MotionEvent.ACTION_UP:
    {
      if(canceled) return false;

      final float xx = Core.originalTouchX - this.x - scrollLeft;
      final float yy = Core.originalTouchY - this.y;

      // only those drawn can be clicked...
      for(int i = index; i < end && i < drawableLen; i++){
        final RectF r = precalculatedClickBounds.get(i);

        if(r.contains(xx, yy)) {
          itemSelectedIndex = i;

          if(!itemSelected) {
            selectionBox.x = r.left - margin;
            itemSelected = true;
          } else {
            if(selectionBoxUpdatable != null)
              Core.gu.removeUiUpdatable(selectionBoxUpdatable);

            selectionBoxUpdatable = new Updatable() {

              private final float FINAL_X = r.left - margin;
              private final float START_X = selectionBox.x;
              private final float d = FINAL_X - START_X;
              private float time = 0.0f;
              private float duration = 1f;

              @Override
              public boolean update(float dt) {
                time += dt;
                if(time < duration) {
                  float t = time;
                  t /= duration/2;
                  if (t < 1){ 
                    selectionBox.x = d/2*t*t + START_X;
                  } else {
                    t--;
                    selectionBox.x = -d/2 * (t*(t-2) - 1) + START_X;
                  }

                  t = time / duration;
                  return true;
                } else {
                  selectionBox.x = FINAL_X;
                  return false;
                }
              }

            };
            Core.gu.addUiUpdatable(selectionBoxUpdatable);
          }
          return true;
        }
      }
      return false;
    }
    case MotionEvent.ACTION_MOVE:
      if(!rect.contains(x, y)) return false;

      if(canceled && scrollEnabled) {
        // do scrolling here...
        final float deltaX = x - lastX;

        scrollLeft += deltaX;
        if(scrollLeft > 0) scrollLeft = 0;
        else if(scrollLeft < -maxScrollLeft) scrollLeft = -maxScrollLeft;

        scrollX = (-scrollLeft / totalW) * width;

        // calculate which items to draw...
        int startIndex = (int) (-scrollLeft / itemW);
        index = startIndex < 0 ? 0 : startIndex;
        end = startIndex + maxDisplay + 1;

        // refresh fade counter
        timeLeft = FADE_TIME + SHOW_TIME;
      } else {
        final float deltaX2 = x - startingX;
        final float deltaY2 = y - startingY;

        if(Math.abs(deltaX2) > touchSlop || Math.abs(deltaY2) > touchSlop) {
          canceled = true;
        }
      }

      lastX = x;

      return true;
    case Event.ACTION_DOUBLE_TAP:
      final float xx = Core.originalTouchX - this.x - scrollLeft;
      final float yy = Core.originalTouchY - this.y;

      // only those drawn can be clicked...
      for(int i = index; i < end && i < drawableLen; i++){
        final RectF r = precalculatedClickBounds.get(i);

        if(r.contains(xx, yy)) {
          itemSelectedIndex = i;

          Tower t = getSelectedTower();
          if(t != null) {
            towerInfoDialog.lightSetup(t.evoTree, t.level);
            towerInfoDialog.show();
            return true;
          }
        }
      }
    return false;
    case MotionEvent.ACTION_DOWN:
      if(!rect.contains(x, y)) return false;

      canceled = false;

      lastX = x;

      startingX = x;
      startingY = y;

      return true;
    default:
      return false;
    }
  }

  private void genScrollBar(int scrollBarWidth){
    // this is the size of the texture to be created in pixels
    // since this texture will be stretched to the right size
    // it really doesn't matter what size the texture is... so 1 is chosen
    // since it is POT and it takes very little memory.
    final int FILL_TEXTURE_SIZE = 1;
    
    final int scrollBarHeight = (int) (SCROLL_BAR_HEIGHT_SDP * Core.SDP);

    Bitmap bitmap = Bitmap.createBitmap(FILL_TEXTURE_SIZE, FILL_TEXTURE_SIZE, Bitmap.Config.RGB_565);

    bitmap.eraseColor(Color.TRANSPARENT);
    Canvas canvas = new Canvas(bitmap);

    Paint paint = new Paint();
    paint.setColor(SCROLL_BAR_COLOR);
    canvas.drawRect(0, 0, FILL_TEXTURE_SIZE, FILL_TEXTURE_SIZE, paint);

    scrollBarTop = height - scrollBarHeight;

    scrollBarId = BitmapUtils.loadBitmap(bitmap, scrollBarId);

    scrollBarHandle = BufferUtils.createRectangleBuffer(scrollBarWidth, scrollBarHeight);

  }

  public void notifyPositionChanged() {
    // re-adjust click bounds since this object's position changed...
    rect.left = x;
    rect.right = rect.left + width;
    rect.top = y;
    rect.bottom = rect.top + height;
  }
}




Java Source Code List

com.ggstudios.divisionbyzero.ActivityAbout.java
com.ggstudios.divisionbyzero.ActivityLevelSelection.java
com.ggstudios.divisionbyzero.ActivityMainMenu.java
com.ggstudios.divisionbyzero.ActivitySettings.java
com.ggstudios.divisionbyzero.ActivitySplashScreen.java
com.ggstudios.divisionbyzero.ApplicationMain.java
com.ggstudios.divisionbyzero.BaseActivity.java
com.ggstudios.divisionbyzero.BaseDialog.java
com.ggstudios.divisionbyzero.BulletManager.java
com.ggstudios.divisionbyzero.Bullet.java
com.ggstudios.divisionbyzero.Button.java
com.ggstudios.divisionbyzero.Circle.java
com.ggstudios.divisionbyzero.ClickableCollection.java
com.ggstudios.divisionbyzero.Clickable.java
com.ggstudios.divisionbyzero.ConfirmDialog.java
com.ggstudios.divisionbyzero.Core.java
com.ggstudios.divisionbyzero.CustomGLSurfaceView.java
com.ggstudios.divisionbyzero.DialogManager.java
com.ggstudios.divisionbyzero.DrawableCollection.java
com.ggstudios.divisionbyzero.DrawableString.java
com.ggstudios.divisionbyzero.Drawable.java
com.ggstudios.divisionbyzero.EndDialog.java
com.ggstudios.divisionbyzero.Event.java
com.ggstudios.divisionbyzero.ExplosionGenerator.java
com.ggstudios.divisionbyzero.ExtrasManager.java
com.ggstudios.divisionbyzero.FontManager.java
com.ggstudios.divisionbyzero.GameRenderer.java
com.ggstudios.divisionbyzero.GameUpdater.java
com.ggstudios.divisionbyzero.Game.java
com.ggstudios.divisionbyzero.Grid.java
com.ggstudios.divisionbyzero.Hud.java
com.ggstudios.divisionbyzero.InGameMenu.java
com.ggstudios.divisionbyzero.InfoDialog.java
com.ggstudios.divisionbyzero.Label.java
com.ggstudios.divisionbyzero.LevelManager.java
com.ggstudios.divisionbyzero.LevelMap.java
com.ggstudios.divisionbyzero.LineGuide.java
com.ggstudios.divisionbyzero.MainActivity.java
com.ggstudios.divisionbyzero.Map.java
com.ggstudios.divisionbyzero.MessageDialog.java
com.ggstudios.divisionbyzero.ParticleEngine.java
com.ggstudios.divisionbyzero.PathFinder.java
com.ggstudios.divisionbyzero.PauseMenu.java
com.ggstudios.divisionbyzero.PictureBox.java
com.ggstudios.divisionbyzero.Player.java
com.ggstudios.divisionbyzero.PopupMenu.java
com.ggstudios.divisionbyzero.Rectangle.java
com.ggstudios.divisionbyzero.Shader.java
com.ggstudios.divisionbyzero.SpawnManager.java
com.ggstudios.divisionbyzero.SpriteAnimation.java
com.ggstudios.divisionbyzero.SpriteManager.java
com.ggstudios.divisionbyzero.Sprite.java
com.ggstudios.divisionbyzero.Statbar.java
com.ggstudios.divisionbyzero.StateManager.java
com.ggstudios.divisionbyzero.TargetRectangle.java
com.ggstudios.divisionbyzero.TextureManager.java
com.ggstudios.divisionbyzero.TowerInfoDialog.java
com.ggstudios.divisionbyzero.TowerLibrary.java
com.ggstudios.divisionbyzero.TowerManager.java
com.ggstudios.divisionbyzero.TowerMenu.java
com.ggstudios.divisionbyzero.Tower.java
com.ggstudios.divisionbyzero.UpdatableCollection.java
com.ggstudios.divisionbyzero.Updatable.java
com.ggstudios.divisionbyzero.UpgradeDialog.java
com.ggstudios.divisionbyzero.Utils.java
com.ggstudios.divisionbyzero.VBO.java
com.ggstudios.divisionbyzero.WaveControlDialog.java
com.ggstudios.divisionbyzero.WaveControlHud.java
com.ggstudios.divisionbyzero.ZoomControl.java
com.ggstudios.utils.BitmapUtils.java
com.ggstudios.utils.BufferUtils.java
com.ggstudios.utils.DebugLog.java
com.ggstudios.utils.ShaderUtils.java
com.ggstudios.widget.LevelMapBackground.java
fix.android.opengl.GLES20.java