/* * Copyright 2013 MicaByte Systems * * 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.micabytes.map; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Point; import android.graphics.Rect; import com.micabytes.gfx.SurfaceRenderer; import com.micabytes.util.GameLog; /** * HexMap superclass <p/> This implementation works for pointy-side up HexMaps. Needs to be adjusted * if it is going to be used for flat-side up maps. */ @SuppressWarnings("unused") public abstract class HexMap { private static final String TAG = HexMap.class.getName(); private static boolean standardOrientation = true; private static int mapWidth = 0; private static int mapHeight = 0; private static int tileSlope = 0; private static Rect tileRect = new Rect(); protected TileMapZone[][] zones; protected float scaleFactor; protected final Point viewPortOrigin = new Point(); protected final Point viewPortSize = new Point(); protected final Rect destRect = new Rect(); protected int windowLeft; protected int windowTop; protected int windowRight; protected int windowBottom; private final Paint tilePaint = new Paint(); protected final Paint tileText = new Paint(); // Draw protected final Canvas canvas = new Canvas(); protected HexMap() { tilePaint.setAntiAlias(true); tilePaint.setFilterBitmap(true); tilePaint.setDither(true); Paint select = new Paint(); select.setStyle(Paint.Style.STROKE); select.setColor(Color.RED); select.setStrokeWidth(2); } @SuppressWarnings("AssignmentToStaticFieldFromInstanceMethod") public void setHexMap(TileMapZone[][] map) { zones = new TileMapZone[map.length][map[0].length]; for (int i = 0; i < map.length; i++) { System.arraycopy(map[i], 0, zones[i], 0, map[i].length); } mapHeight = map[0].length; mapWidth = map.length; tileRect = new Rect(0, 0, map[0][0].getWidth(), map[0][0].getHeight()); tileSlope = tileRect.height() / 4; } @SuppressWarnings({"MethodWithMultipleLoops", "OverlyComplexMethod", "OverlyLongMethod", "NumericCastThatLosesPrecision"}) public void drawBase(Context con, SurfaceRenderer.ViewPort p) { if (p.getBitmap() == null) { GameLog.e(TAG, "Viewport bitmap is null"); return; } canvas.setBitmap(p.getBitmap()); scaleFactor = p.getZoom(); int yOffset = tileRect.height() - tileSlope; p.getOrigin(viewPortOrigin); p.getSize(viewPortSize); windowLeft = viewPortOrigin.x; windowTop = viewPortOrigin.y; windowRight = viewPortOrigin.x + viewPortSize.x; windowBottom = viewPortOrigin.y + viewPortSize.y; int xOffset; if (standardOrientation) { // Clip tiles not in view int iMn = (windowLeft / tileRect.width()) - 1; if (iMn < 0) iMn = 0; int jMn = (windowTop / (tileRect.height() - tileSlope)) - 1; if (jMn < 0) jMn = 0; int iMx = (windowRight / tileRect.width()) + 2; if (iMx >= mapWidth) iMx = mapWidth; int jMx = (windowBottom / (tileRect.height() - tileSlope)) + 2; if (jMx >= mapHeight) jMx = mapHeight; // Draw Tiles for (int i = iMn; i < iMx; i++) { for (int j = jMn; j < jMx; j++) { if (zones[i][j] != null) { xOffset = (j % 2) == 0 ? tileRect.width() / 2 : 0; destRect.left = (int) (((i * tileRect.width()) - windowLeft - xOffset) / scaleFactor); destRect.top = (int) (((j * (tileRect.height() - tileSlope)) - windowTop - yOffset) / scaleFactor); destRect.right = (int) ((((i * tileRect.width()) + tileRect.width()) - windowLeft - xOffset) / scaleFactor); destRect.bottom = (int) ((((j * (tileRect.height() - tileSlope)) + tileRect.height()) - windowTop - yOffset) / scaleFactor); zones[i][j].drawBase(canvas, tileRect, destRect, tilePaint); } } } } else { // Clip tiles not in view int iMn = mapWidth - (windowRight / tileRect.width()) - 2; if (iMn < 0) iMn = 0; int jMn = mapHeight - ((windowBottom / (tileRect.height() - tileSlope)) + 2); if (jMn < 0) jMn = 0; int iMx = mapWidth - ((windowLeft / tileRect.width()) + 1); if (iMx >= mapWidth) iMx = mapWidth - 1; int jMx = mapHeight - ((windowTop / (tileRect.height() - tileSlope)) + 1); if (jMx >= mapHeight) jMx = mapHeight - 1; // Draw Tiles for (int i = iMx; i >= iMn; i--) { for (int j = jMx; j >= jMn; j--) { if (zones[i][j] != null) { xOffset = (j % 2) == 1 ? tileRect.width() / 2 : 0; destRect.left = (int) ((((mapWidth - i - 1) * tileRect.width()) - windowLeft - xOffset) / scaleFactor); destRect.top = (int) ((((mapHeight - j - 1) * (tileRect.height() - tileSlope)) - windowTop - yOffset) / scaleFactor); destRect.right = (int) (((((mapWidth - i - 1) * tileRect.width()) + tileRect.width()) - windowLeft - xOffset) / scaleFactor); destRect.bottom = (int) (((((mapHeight - j - 1) * (tileRect.height() - tileSlope)) + tileRect.height()) - windowTop - yOffset) / scaleFactor); zones[i][j].drawBase(canvas, tileRect, destRect, tilePaint); } } } } } public abstract void drawLayer(Context context, SurfaceRenderer.ViewPort p); public abstract void drawFinal(Context context, SurfaceRenderer.ViewPort p); public abstract Point getViewPortOrigin(int x, int y, SurfaceRenderer.ViewPort p); public static boolean isStandardOrientation() { return standardOrientation; } @SuppressWarnings("StaticMethodOnlyUsedInOneClass") public static void setStandardOrientation(boolean orient) { standardOrientation = orient; } public static int getMapWidth() { return mapWidth; } public static void setMapWidth(int i) { mapWidth = i; } public static int getMapHeight() { return mapHeight; } public static void setMapHeight(int i) { mapHeight = i; } public static int getTileSlope() { return tileSlope; } public static void setTileSlope(int i) { tileSlope = i; } public static Rect getTileRect() { return tileRect; } public static void setTileRect(Rect rect) { tileRect = rect; } }