当前位置: 代码迷 >> Android >> Android游戏之荧幕类TestScreen和游戏类AndroidGame设计
  详细解决方案

Android游戏之荧幕类TestScreen和游戏类AndroidGame设计

热度:16   发布时间:2016-04-28 02:23:47.0
Android游戏之屏幕类TestScreen和游戏类AndroidGame设计

Android游戏之屏幕类TestScreen和游戏类AndroidGame设计

 

1、基础知识:


A. WakeLock

http://developer.android.com/reference/android/os/PowerManager.WakeLock.html
B. requestWindowFeature
http://developer.android.com/reference/android/app/Activity.html#requestWindowFeature(int)
C. getWindow().setFlags
http://developer.android.com/reference/android/app/Activity.html#getWindow()
http://developer.android.com/reference/android/view/Window.html#setFlags(int, int)
D. getResources().getConfiguration()
http://developer.android.com/reference/android/content/res/Configuration.html
E. Bitmap.createBitmap
http://developer.android.com/reference/android/graphics/Bitmap.html
F. getWindowManager().getDefaultDisplay()
http://developer.android.com/reference/android/view/WindowManager.html
http://developer.android.com/reference/android/view/Display.html
G. powerManager.newWakeLock
http://developer.android.com/reference/android/os/PowerManager.html#newWakeLock(int, java.lang.String)
H.BufferedReader
http://developer.android.com/reference/java/io/BufferedReader.html
I.BufferedWriter
http://developer.android.com/reference/java/io/BufferedWriter.html
J.Thread
http://developer.android.com/reference/java/lang/Thread.html


2、设计屏幕接口Screen和游戏接口Game

package com.badlogic.androidgames.framework;public abstract class Screen {    protected final Game game;    public Screen(Game game) {        this.game = game;    }    public abstract void update(float deltaTime);    public abstract void present(float deltaTime);    public abstract void pause();    public abstract void resume();    public abstract void dispose();}


 

package com.badlogic.androidgames.framework;public interface Game {    public Input getInput();    public FileIO getFileIO();    public Graphics getGraphics();    public Audio getAudio();    public void setScreen(Screen screen);    public Screen getCurrentScreen();    public Screen getStartScreen();}


 

 

3. 实现屏幕类TestScreen和游戏类AndroidGame

package com.badlogic.androidgames.framework;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.util.List;import android.graphics.Color;import android.util.Log;import com.badlogic.androidgames.framework.Graphics.PixmapFormat;import com.badlogic.androidgames.framework.Input.KeyEvent;import com.badlogic.androidgames.framework.Input.TouchEvent;class TestScreen extends Screen {    long startTime = System.nanoTime();    int frames;    Pixmap bob;    Pixmap bobAlpha;    Sound sound;    Music music;            public TestScreen(Game game) {        super(game);            bob = game.getGraphics().newPixmap("bobrgb888.png", PixmapFormat.RGB565);        bobAlpha = game.getGraphics().newPixmap("bobargb8888.png", PixmapFormat.ARGB4444);        music = game.getAudio().newMusic("music.ogg");        music.setLooping(true);        music.setVolume(0.5f);        music.play();        sound = game.getAudio().newSound("music.ogg");                try {            BufferedReader in = new BufferedReader(new InputStreamReader(game.getFileIO().readAsset("test.txt")));            String text = in.readLine();            in.close();                        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(game.getFileIO().writeFile("test.txt")));            out.write("This is a freaking test");            out.close();                        in = new BufferedReader(new InputStreamReader(game.getFileIO().readFile("test.txt")));            String text2 = in.readLine();            in.close();                        Log.d("MrNom", text + ", " + text2 );        } catch(Exception ex) {            ex.printStackTrace();        }    }        @Override    public void update(float deltaTime) {    }    @Override    public void present(float deltaTime) {        Graphics g = game.getGraphics();        Input inp = game.getInput();        g.clear(Color.RED);        g.drawLine(0,0,320, 480, Color.BLUE);        g.drawRect(20,20,100,100, Color.GREEN);        g.drawPixmap(bob, 100, 100);        g.drawPixmap(bobAlpha, 100, 200);        g.drawPixmap(bob, 200, 200, 0, 0, 64, 64);        for(int i=0; i < 2; i++) {            if(inp.isTouchDown(i)) {                g.drawPixmap(bob, inp.getTouchX(i), inp.getTouchY(i), 0, 0, 64, 64);            }        }                g.drawPixmap(bob, (int)(inp.getAccelX() * 10) + 160 - 16, (int)(inp.getAccelY() * 10) + 240 - 16, 0, 0, 32, 32 );                List<KeyEvent> keyEvents = inp.getKeyEvents();        int len = keyEvents.size();        for(int i = 0; i < len; i++) {            Log.d("MrNom", keyEvents.get(i).toString());        }                List<TouchEvent> touchEvents = inp.getTouchEvents();        len = touchEvents.size();        for(int i = 0; i < len; i++) {            Log.d("MrNom", touchEvents.get(i).toString());            if(touchEvents.get(i).type == TouchEvent.TOUCH_UP)                sound.play(1);        }                frames++;        if(System.nanoTime() - startTime > 1000000000l) {            Log.d("MrNom", "fps: " + frames + ", delta: " + deltaTime);            frames = 0;            startTime = System.nanoTime();        }    }    @Override    public void pause() {        Log.d("MrNom", "pause");                    }    @Override    public void resume() {        Log.d("MrNom", "resume");       }    @Override    public void dispose() {        Log.d("MrNom", "dispose");        music.dispose();    }            }


 

package com.badlogic.androidgames.framework.impl;import android.app.Activity;import android.content.Context;import android.content.res.Configuration;import android.graphics.Bitmap;import android.graphics.Bitmap.Config;import android.os.Bundle;import android.os.PowerManager;import android.os.PowerManager.WakeLock;import android.view.Window;import android.view.WindowManager;import com.badlogic.androidgames.framework.Audio;import com.badlogic.androidgames.framework.FileIO;import com.badlogic.androidgames.framework.Game;import com.badlogic.androidgames.framework.Graphics;import com.badlogic.androidgames.framework.Input;import com.badlogic.androidgames.framework.Screen;public abstract class AndroidGame extends Activity implements Game {    AndroidFastRenderView renderView;    Graphics graphics;    Audio audio;    Input input;    FileIO fileIO;    Screen screen;    WakeLock wakeLock;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        requestWindowFeature(Window.FEATURE_NO_TITLE);        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,                WindowManager.LayoutParams.FLAG_FULLSCREEN);        boolean isLandscape = getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;        int frameBufferWidth = isLandscape ? 480 : 320;        int frameBufferHeight = isLandscape ? 320 : 480;        Bitmap frameBuffer = Bitmap.createBitmap(frameBufferWidth,                frameBufferHeight, Config.RGB_565);                float scaleX = (float) frameBufferWidth                / getWindowManager().getDefaultDisplay().getWidth();        float scaleY = (float) frameBufferHeight                / getWindowManager().getDefaultDisplay().getHeight();        renderView = new AndroidFastRenderView(this, frameBuffer);        graphics = new AndroidGraphics(getAssets(), frameBuffer);        fileIO = new AndroidFileIO(getAssets());        audio = new AndroidAudio(this);        input = new AndroidInput(this, renderView, scaleX, scaleY);        screen = getStartScreen();        setContentView(renderView);                PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);        wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "GLGame");    }    @Override    public void onResume() {        super.onResume();        wakeLock.acquire();        screen.resume();        renderView.resume();    }    @Override    public void onPause() {        super.onPause();        wakeLock.release();        renderView.pause();        screen.pause();        if (isFinishing())            screen.dispose();    }    @Override    public Input getInput() {        return input;    }    @Override    public FileIO getFileIO() {        return fileIO;    }    @Override    public Graphics getGraphics() {        return graphics;    }    @Override    public Audio getAudio() {        return audio;    }    @Override    public void setScreen(Screen screen) {        if (screen == null)            throw new IllegalArgumentException("Screen must not be null");        this.screen.pause();        this.screen.dispose();        screen.resume();        screen.update(0);        this.screen = screen;    }        public Screen getCurrentScreen() {        return screen;    }}


 

 

4.游戏类AndroidGame用到了快速重绘视图类AndroidFastRenderView

 

package com.badlogic.androidgames.framework.impl;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Rect;import android.view.SurfaceHolder;import android.view.SurfaceView;public class AndroidFastRenderView extends SurfaceView implements Runnable {    AndroidGame game;    Bitmap framebuffer;    Thread renderThread = null;    SurfaceHolder holder;    volatile boolean running = false;        public AndroidFastRenderView(AndroidGame game, Bitmap framebuffer) {        super(game);        this.game = game;        this.framebuffer = framebuffer;        this.holder = getHolder();    }    public void resume() {         running = true;        renderThread = new Thread(this);        renderThread.start();             }              public void run() {        Rect dstRect = new Rect();        long startTime = System.nanoTime();        while(running) {              if(!holder.getSurface().isValid())                continue;                                   float deltaTime = (System.nanoTime()-startTime) / 1000000000.0f;            startTime = System.nanoTime();            game.getCurrentScreen().update(deltaTime);            game.getCurrentScreen().present(deltaTime);                        Canvas canvas = holder.lockCanvas();            canvas.getClipBounds(dstRect);            canvas.drawBitmap(framebuffer, null, dstRect, null);                                       holder.unlockCanvasAndPost(canvas);        }    }    public void pause() {                                running = false;                                while(true) {            try {                renderThread.join();                break;            } catch (InterruptedException e) {                // retry            }        }    }        }


 

 

5. 另外基于openGL ES的游戏类GLGame(之前的游戏类AndroidGame是基于普通绘图类Graphics)

 

package com.badlogic.androidgames.framework.impl;import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.opengles.GL10;import android.app.Activity;import android.content.Context;import android.opengl.GLSurfaceView;import android.opengl.GLSurfaceView.Renderer;import android.os.Bundle;import android.os.PowerManager;import android.os.PowerManager.WakeLock;import android.view.Window;import android.view.WindowManager;import com.badlogic.androidgames.framework.Audio;import com.badlogic.androidgames.framework.FileIO;import com.badlogic.androidgames.framework.Game;import com.badlogic.androidgames.framework.Graphics;import com.badlogic.androidgames.framework.Input;import com.badlogic.androidgames.framework.Screen;public abstract class GLGame extends Activity implements Game, Renderer {    enum GLGameState {        Initialized,        Running,        Paused,        Finished,        Idle    }        GLSurfaceView glView;        GLGraphics glGraphics;    Audio audio;    Input input;    FileIO fileIO;    Screen screen;    GLGameState state = GLGameState.Initialized;    Object stateChanged = new Object();    long startTime = System.nanoTime();    WakeLock wakeLock;        @Override     public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        requestWindowFeature(Window.FEATURE_NO_TITLE);        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,                             WindowManager.LayoutParams.FLAG_FULLSCREEN);        glView = new GLSurfaceView(this);        glView.setRenderer(this);        setContentView(glView);                glGraphics = new GLGraphics(glView);        fileIO = new AndroidFileIO(getAssets());        audio = new AndroidAudio(this);        input = new AndroidInput(this, glView, 1, 1);        PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);        wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "GLGame");            }        public void onResume() {        super.onResume();        glView.onResume();        wakeLock.acquire();    }        @Override    public void onSurfaceCreated(GL10 gl, EGLConfig config) {                glGraphics.setGL(gl);                synchronized(stateChanged) {            if(state == GLGameState.Initialized)                screen = getStartScreen();            state = GLGameState.Running;            screen.resume();            startTime = System.nanoTime();        }            }        @Override    public void onSurfaceChanged(GL10 gl, int width, int height) {            }    @Override    public void onDrawFrame(GL10 gl) {                        GLGameState state = null;                synchronized(stateChanged) {            state = this.state;        }                if(state == GLGameState.Running) {            float deltaTime = (System.nanoTime()-startTime) / 1000000000.0f;            startTime = System.nanoTime();                        screen.update(deltaTime);            screen.present(deltaTime);        }                if(state == GLGameState.Paused) {            screen.pause();                        synchronized(stateChanged) {                this.state = GLGameState.Idle;                stateChanged.notifyAll();            }        }                if(state == GLGameState.Finished) {            screen.pause();            screen.dispose();            synchronized(stateChanged) {                this.state = GLGameState.Idle;                stateChanged.notifyAll();            }                    }    }           @Override     public void onPause() {                synchronized(stateChanged) {            if(isFinishing())                            state = GLGameState.Finished;            else                state = GLGameState.Paused;            while(true) {                try {                    stateChanged.wait();                    break;                } catch(InterruptedException e) {                         }            }        }        wakeLock.release();        glView.onPause();          super.onPause();    }            public GLGraphics getGLGraphics() {        return glGraphics;    }          @Override    public Input getInput() {        return input;    }    @Override    public FileIO getFileIO() {        return fileIO;    }    @Override    public Graphics getGraphics() {        throw new IllegalStateException("We are using OpenGL!");    }    @Override    public Audio getAudio() {        return audio;    }    @Override    public void setScreen(Screen screen) {        if (screen == null)            throw new IllegalArgumentException("Screen must not be null");        this.screen.pause();        this.screen.dispose();        screen.resume();        screen.update(0);        this.screen = screen;    }    @Override    public Screen getCurrentScreen() {        return screen;    }}


 

 


本文浅述了“beginning-android-games”书本的相关基础知识和相关类的设计分析,
书本和源码:
http://download.csdn.net/detail/yangzhenping/8420261
本篇中的类实现来自“beginning-android-games\ch07-gl-basics”

  相关解决方案