Android Open Source - lib_base Surface Renderer






From Project

Back to project page lib_base.

License

The source code is released under:

Apache License

If you think the Android project lib_base 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 2013 MicaByte Systems//w w  w  . j av  a  2s.c  om
 * 
 * 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.micabyte.android.graphics;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.Log;

/**
 * SurfaceRenderer is the superclass of the renderer. The game should subclass the renderer and extend the drawing methods to add game drawing.
 * <p/>
 * - BitmapSurfaceRenderer can be extended for apps that require background images
 * - TileMapSurfaceRenderer can be extended for apps that need to display TileMaps (not currently up to date)
 * - HexMapSurfaceRenderer can be extended for apps that need to display HexMaps
 *
 * @author micabyte
 */
@SuppressWarnings("WeakerAccess")
public abstract class SurfaceRenderer {
    // View Size Minimum
    private final static int MINIMUM_PIXELS_IN_VIEW = 50;
    // Context
    protected final Context context_;
    // The ViewPort
    protected final ViewPort viewPort_ = new ViewPort();
    // The Dimensions of the Game Area
    final Point backgroundSize_ = new Point();

    /**
     * Constructor for the surface renderer
     *
     * @param c We need to pass in the context, so that we have it when we create bitmaps for drawing operations later. Since the draw operations are
     *          run in a thread, we can't pass the context through the thread (at least not easily)
     */
    SurfaceRenderer(Context c) {
        context_ = c;
    }

    /**
     * Rendering thread started
     */
    public abstract void start();

    /**
     * Rendering thread stopped
     */
    public abstract void stop();

    /**
     * Rendering updates can be suspended
     */
    public abstract void suspend(boolean b);

    /**
     * Draw to the canvas
     */
    public void draw(Canvas c) {
        viewPort_.draw(c);
    }

    /**
     * Draw the base (background) layer of the SurfaceView image
     */
    protected abstract void drawBase();

    /**
     * Draw the game (dynamic) layer of the SurfaceView image
     */
    protected abstract void drawLayer();

    /**
     * Draw any final touches
     */
    protected abstract void drawFinal();

    /**
     * Get the position (center) of the view
     */
    public void getViewPosition(Point p) {
        viewPort_.getOrigin(p);
    }

    /**
     * Set the position (center) of the view
     */
    public void setViewPosition(int x, int y) {
        viewPort_.setOrigin(x, y);
    }

    /**
     * Set the position (center) of the view based on map coordinates. This is intended to be used with Tile/HexMaps, and needs to be implemented in
     * the derived player Map class.
     */
    public void setMapPosition(int x, int y) {
        viewPort_.setOrigin(x, y);
    }

    /**
     * Get the dimensions of the view
     */
    public void getViewSize(Point p) {
        viewPort_.getSize(p);
    }

    /**
     * Set the dimensions of the view
     */
    public void setViewSize(int w, int h) {
        viewPort_.setSize(w, h);
    }

    /**
     * Returns a Point representing the size of the scene. Don't modify the returned Point!
     */
    public Point getBackgroundSize() {
        return backgroundSize_;
    }


    public void zoom(float scaleFactor, PointF screenFocus) {
        viewPort_.zoom(scaleFactor, screenFocus);
    }

    public float getZoom() {
        return viewPort_.getZoom();
    }

    /**
     * View Port. This handles the actual drawing, managing dimensions, etc.
     */
    public class ViewPort {
        // The Bitmap of the current ViewPort
        public Bitmap bitmap_ = null;
        // The rect defining where the viewport is within the scene
        public final Rect window = new Rect(0, 0, 0, 0);
        // The zoom factor of the viewport
        float zoom = 1.0f;

        public void getOrigin(Point p) {
            synchronized (this) {
                p.set(window.left, window.top);
            }
        }

        public void setOrigin(int xp, int yp) {
            synchronized (this) {
                int x = xp;
                int y = yp;
                final int w = window.width();
                final int h = window.height();
                // check bounds
                if (x < 0)
                    x = 0;
                if (y < 0)
                    y = 0;
                if (x + w > backgroundSize_.x)
                    x = backgroundSize_.x - w;
                if (y + h > backgroundSize_.y)
                    y = backgroundSize_.y - h;
                // Set the Window rect
                window.set(x, y, x + w, y + h);
            }
        }

        public void setSize(int w, int h) {
            synchronized (this) {
                if (bitmap_ != null) {
                    bitmap_.recycle();
                    bitmap_ = null;
                }
                bitmap_ = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565);
                Log.d("SF", "Created bitmap of size " + w + " " + h);
                int x = window.left;
                int y = window.top;
                // check bounds
                if (x < 0)
                    x = 0;
                if (y < 0)
                    y = 0;
                if (x + w > backgroundSize_.x)
                    x = backgroundSize_.x - w;
                if (y + h > backgroundSize_.y)
                    y = backgroundSize_.y - h;
                // Set the Window rect
                window.set(x, y, x + w, y + h);
                /*window.set(
                        window.left,
                        window.top,
                        window.left + w,
                        window.top + h);*/
            }
        }

        public void getSize(Point p) {
            synchronized (this) {
                p.x = window.width();
                p.y = window.height();
            }
        }

        public void getPhysicalSize(Point p) {
            synchronized (this) {
                p.x = getPhysicalWidth();
                p.y = getPhysicalHeight();
            }
        }

        public int getPhysicalWidth() {
            return bitmap_.getWidth();
        }

        public int getPhysicalHeight() {
            return bitmap_.getHeight();
        }

        public float getZoom() {
            return zoom;
        }

        public void zoom(float factor, PointF screenFocus) {
            if (bitmap_ == null) return;
            if (factor != 1.0) {
                final PointF screenSize = new PointF(bitmap_.getWidth(), bitmap_.getHeight());
                final PointF sceneSize = new PointF(getBackgroundSize());
                final float screenWidthToHeight = screenSize.x / screenSize.y;
                final float screenHeightToWidth = screenSize.y / screenSize.x;
                synchronized (this) {
                    float newZoom = zoom * factor;
                    final RectF w1 = new RectF(window);
                    final RectF w2 = new RectF();
                    final PointF sceneFocus = new PointF(
                            w1.left + (screenFocus.x / screenSize.x) * w1.width(),
                            w1.top + (screenFocus.y / screenSize.y) * w1.height()
                    );
                    float w2Width = getPhysicalWidth() * newZoom;
                    if (w2Width > sceneSize.x) {
                        w2Width = sceneSize.x;
                        newZoom = w2Width / getPhysicalWidth();
                    }
                    if (w2Width < MINIMUM_PIXELS_IN_VIEW) {
                        w2Width = MINIMUM_PIXELS_IN_VIEW;
                        newZoom = w2Width / getPhysicalWidth();
                    }
                    float w2Height = w2Width * screenHeightToWidth;
                    if (w2Height > sceneSize.y) {
                        w2Height = sceneSize.y;
                        w2Width = w2Height * screenWidthToHeight;
                        newZoom = w2Width / getPhysicalWidth();
                    }
                    if (w2Height < MINIMUM_PIXELS_IN_VIEW) {
                        w2Height = MINIMUM_PIXELS_IN_VIEW;
                        w2Width = w2Height * screenWidthToHeight;
                        newZoom = w2Width / getPhysicalWidth();
                    }
                    w2.left = sceneFocus.x - ((screenFocus.x / screenSize.x) * w2Width);
                    w2.top = sceneFocus.y - ((screenFocus.y / screenSize.y) * w2Height);
                    if (w2.left < 0)
                        w2.left = 0;
                    if (w2.top < 0)
                        w2.top = 0;
                    w2.right = w2.left + w2Width;
                    w2.bottom = w2.top + w2Height;
                    if (w2.right > sceneSize.x) {
                        w2.right = sceneSize.x;
                        w2.left = w2.right - w2Width;
                    }
                    if (w2.bottom > sceneSize.y) {
                        w2.bottom = sceneSize.y;
                        w2.top = w2.bottom - w2Height;
                    }
                    window.set((int) w2.left, (int) w2.top, (int) w2.right, (int) w2.bottom);
                    zoom = newZoom;
                    Log.d("Debug",String.format(
                            "f=%.2f, z=%.2f, screen focus (%.0f,%.0f), scene focus (%.0f,%.0f) w1s(%.0f,%.0f) w2s(%.0f,%.0f) w1(%.0f,%.0f,%.0f,%.0f) w2(%.0f,%.0f,%.0f,%.0f)",
                            factor,
                            zoom,
                            screenFocus.x,
                            screenFocus.y,
                            sceneFocus.x,
                            sceneFocus.y,
                            w1.width(),w1.height(),
                            w2Width, w2Height,
                            w1.left,w1.top,w1.right,w1.bottom,
                            w2.left,w2.top,w2.right,w2.bottom
                            ));
                }
            }
        }

        void draw(Canvas c) {
            drawBase();
            drawLayer();
            drawFinal();
            synchronized (this) {
                if (c != null && bitmap_ != null) {
                    c.drawBitmap(bitmap_, 0F, 0F, null);
                }
            }
        }
    }

}




Java Source Code List

com.micabyte.android.ApplicationTest.java
com.micabyte.android.BaseObject.java
com.micabyte.android.app.BalloonPopup.java
com.micabyte.android.app.BaseActivity.java
com.micabyte.android.app.BaseFragment.java
com.micabyte.android.app.Popup.java
com.micabyte.android.graphics.BitmapSurfaceRenderer.java
com.micabyte.android.graphics.HexMapSurfaceRenderer.java
com.micabyte.android.graphics.ImageHandler.java
com.micabyte.android.graphics.MicaSurfaceView.java
com.micabyte.android.graphics.SurfaceListener.java
com.micabyte.android.graphics.SurfaceRenderer.java
com.micabyte.android.graphics.TileMapSurfaceRenderer.java
com.micabyte.android.map.HexMap.java
com.micabyte.android.map.TileMapZone.java
com.micabyte.android.map.TileMap.java
com.micabyte.android.math.Polygon.java
com.micabyte.android.media.MusicHandler.java
com.micabyte.android.util.GameHelperUtils.java
com.micabyte.android.util.GameHelper.java
com.micabyte.android.util.GameUtils.java
com.micabyte.android.util.RandomHandler.java
com.micabyte.android.util.StringHandler.java