日志 教程
当前位置: 教程  >  游戏开发  >  手机游戏开发  >  正文

OPhone平台2D游戏引擎实现——概述及框架一(3)

作者:董涵 发表于 2010/10/11 13:47:36     评论(0)     阅读(2330)     
代码清单1-2:Director构架实现
  1. public class Director implements GLSurfaceView.Renderer {   
  2.     private static Director sInstance;   
  3.     //投影的类型,分为2D,3D等   
  4.     public static final int PROJECTION_2D = 1;   
  5.     public static final int PROJECTION_3D = 2;   
  6.     public static final int PROJECTION_CUSTOM = 3;   
  7.     //默认为2D   
  8.     public static final int PROJECTION_DEFAULT = PROJECTION_2D;   
  9.     public Context context = null;   
  10.     public GL10 gl = null;   
  11.     public GL11 gl11 = null;   
  12.     public GL11ExtensionPack gl11ext = null;   
  13.     private GLSurfaceView mGLView;   
  14.     private long mLastUpdateTime;   
  15.     private boolean mPaused;   
  16.     private int mProjection;   
  17.     private int mWidth;   
  18.     private int mHeight;   
  19.     private DisplayMetrics mDM;   
  20.     private List<IDestroyable> mDestroyables;   
  21.     //生命周期   
  22.     private List<IDirectorLifecycleObserver> mLifecycleObservers;   
  23.     //取得本类对象   
  24.     public static Director getInstance() {   
  25.        synchronized (Director.class) {   
  26.            if (sInstance == null) {   
  27.               sInstance = new Director();   
  28.            }   
  29.            return sInstance;   
  30.        }   
  31.     }   
  32.     protected Director() {   
  33.        synchronized (Director.class) {   
  34.            this.mPaused = false;   
  35.            this.mDestroyables = new ArrayList();   
  36.            this.mLifecycleObservers = new ArrayList();   
  37.        }   
  38.     }   
  39.     //生命周期相关   
  40.     public void addLifecycleObserver(IDirectorLifecycleObserver observer) {   
  41.        this.mLifecycleObservers.add(observer);   
  42.     }   
  43.     public void removeLifecycleObserver(IDirectorLifecycleObserver observer) {   
  44.        this.mLifecycleObservers.remove(observer);   
  45.     }   
  46.     public void registerDestroyable(IDestroyable destroyable) {   
  47.        this.mDestroyables.add(destroyable);   
  48.     }   
  49.     public void unregisterDestroyable(IDestroyable destroyable) {   
  50.        this.mDestroyables.remove(destroyable);   
  51.     }   
  52.     //激活GL视图   
  53.     public boolean attachInView(GLSurfaceView view) {   
  54.        return initOpenGLViewWithView(view);   
  55.     }   
  56.     //获取屏幕的相关属性   
  57.     public DisplayMetrics getDisplayMetrics() {   
  58.        if (this.mDM == null) {   
  59.            this.mDM = this.context.getResources().getDisplayMetrics();   
  60.        }   
  61.        return this.mDM;   
  62.     }   
  63.     //计算fps   
  64.     private void calculateDeltaTime() {   
  65.        long now = SystemClock.uptimeMillis();   
  66.        if (this.mLastUpdateTime == 0L) {   
  67.            this.mDelta = 0.0F;   
  68.        } else {   
  69.            this.mDelta = ((float) (now - this.mLastUpdateTime) / 1000.0F);   
  70.            this.mDelta = Math.max(0.0F, this.mDelta);   
  71.        }   
  72.        this.mLastUpdateTime = now;   
  73.     }   
  74.     //退出处理   
  75.     private boolean detach() {   
  76.        try {   
  77.            if ((this.context instanceof Activity)   
  78.                   && (!((Activity) this.context).isFinishing()))   
  79.               ((Activity) this.context).finish();   
  80.            return true;   
  81.        } catch (Exception e) {   
  82.        }   
  83.        return false;   
  84.     }   
  85.     //结束时释放空间   
  86.     public void end() {   
  87.        if ((this.mGLView != null) && (!this.mPaused)) {   
  88.            this.mGLView.onPause();   
  89.        }   
  90.        for (IDirectorLifecycleObserver ob : this.mLifecycleObservers)   
  91.            ob.onDirectorEnd();   
  92.        this.mLifecycleObservers.clear();   
  93.        this.mDM = null;   
  94.        this.gl = null;   
  95.        this.gl11 = null;   
  96.        this.gl11ext = null;   
  97.        for (IDestroyable destroyable : this.mDestroyables)   
  98.            destroyable.destroy();   
  99.        this.mDestroyables.clear();   
  100.        detach();   
  101.        this.context = null;   
  102.        this.mGLView = null;   
  103.        sInstance = null;   
  104.        //释放所有资源,内存空间,,包括后面将介绍的贴图,scene,layer等   
  105.     }   
  106.     public Context getContext() {   
  107.        return this.context;   
  108.     }   
  109.     //取得屏幕方向   
  110.     public boolean isPortrait() {   
  111.        Display display = ((WindowManager) this.context   
  112.               .getSystemService("window")).getDefaultDisplay();   
  113.        return display.getOrientation() == 0;   
  114.     }   
  115.     //得到GL视图   
  116.     public GLSurfaceView getOpenGLView() {   
  117.        return this.mGLView;   
  118.     }   
  119.     //得到投影类型   
  120.     public int getProjection() {   
  121.        return this.mProjection;   
  122.     }   
  123.     //初始化GL的默认属性   
  124.     private void initGLDefaultValues(GL10 gl) {   
  125.        this.gl = gl;   
  126.        if (gl instanceof GL11)   
  127.            this.gl11 = ((GL11) gl);   
  128.        if (gl instanceof GL11ExtensionPack) {   
  129.            this.gl11ext = ((GL11ExtensionPack) gl);   
  130.        }   
  131.        //开启抖动   
  132.        gl.glDisable(GL10.GL_DITHER);   
  133.        //设置插值算法及其渲染模式   
  134.        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);   
  135.        //设置是否开启混合(是)   
  136.        setAlphaBlending(true);   
  137.        //设置混色的方式   
  138.        gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);   
  139.        //开启光效   
  140.        gl.glDisable(GL10.GL_LIGHTING);   
  141.        //设置渲染模式   
  142.        gl.glShadeModel(GL10.GL_FLAT);   
  143.        //设置清理屏幕颜色rgba   
  144.        gl.glClearColor(0.0F, 0.0F, 0.6F, 0.0F);   
  145.     }   
  146.     //根据GLSurfaceView来初始化GL视图   
  147.     private boolean initOpenGLViewWithView(GLSurfaceView view) {   
  148.        this.mGLView = view;   
  149.        DisplayMetrics dm = getDisplayMetrics();   
  150.        this.mWidth = dm.widthPixels;   
  151.        this.mHeight = dm.heightPixels;   
  152.        EventDispatcher.getInstance().setDispatchEvents(true);   
  153.        return true;   
  154.     }   
  155.     //判断是否被激活   
  156.     public boolean isOpenGLAttached() {   
  157.        return this.mGLView != null;   
  158.     }   
  159.     //渲染   
  160.     public void onDrawFrame(GL10 gl) {   
  161.        if (this.mGLView == null) {   
  162.            return;   
  163.        }   
  164.        //允许设置顶点数组,颜色数组,纹理坐标数组   
  165.        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);   
  166.        gl.glDisableClientState(GL10.GL_COLOR_ARRAY);   
  167.        gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);   
  168.        //允许2D贴图   
  169.        gl.glDisable(GL10.GL_TEXTURE_2D);   
  170.        //清理屏幕(颜色缓存,深度缓存)   
  171.        gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);   
  172.        //计算fps   
  173.        calculateDeltaTime();   
  174.        if (this.mPaused)   
  175.            return;   
  176.     }   
  177.     //屏幕窗口大小改变   
  178.     public void onSurfaceChanged(GL10 gl, int width, int height) {   
  179.        this.mWidth = width;   
  180.        this.mHeight = height;   
  181.        gl.glViewport(00, width, height);   
  182.        setDefaultProjection();   
  183.     }   
  184.     //窗口创建时   
  185.     public void onSurfaceCreated(GL10 gl, EGLConfig config) {   
  186.        initGLDefaultValues(gl);   
  187.     }   
  188.     //销毁时   
  189.     public void onSurfaceDestroyed() {   
  190.     }   
  191.     //暂停处理   
  192.     public void pause() {   
  193.        if (this.mPaused) {   
  194.            return;   
  195.        }   
  196.        if (this.mGLView != null)   
  197.            this.mGLView.onPause();   
  198.        this.mPaused = true;   
  199.        for (IDirectorLifecycleObserver ob : this.mLifecycleObservers)   
  200.            ob.onDirectorPause();   
  201.     }   
  202.     //中断之后重新激活   
  203.     public void resume() {   
  204.        if (!this.mPaused) {   
  205.            return;   
  206.        }   
  207.        this.mLastUpdateTime = SystemClock.uptimeMillis();   
  208.        if (this.mGLView != null) {   
  209.            this.mGLView.onResume();   
  210.        }   
  211.        this.mPaused = false;   
  212.        this.mDelta = 0.0F;   
  213.        for (IDirectorLifecycleObserver ob : this.mLifecycleObservers)   
  214.            ob.onDirectorResume();   
  215.     }   
  216.     //设置投影类型为2D   
  217.     public void set2DProjection() {   
  218.        setProjection(PROJECTION_2D);   
  219.     }   
  220.     //设置投影类型为3D   
  221.     public void set3DProjection() {   
  222.        setProjection(PROJECTION_3D);   
  223.     }   
  224.     //设置是否开启混合   
  225.     public void setAlphaBlending(boolean on) {   
  226.        if (on)   
  227.        ,    this.gl.glEnable(GL10.GL_BLEND);   
  228.        else  
  229.            this.gl.glDisable(GL10.GL_BLEND);   
  230.     }   
  231.     //设置默认投影方式   
  232.     private void setDefaultProjection() {   
  233.        setProjection(PROJECTION_DEFAULT);   
  234.     }   
  235.     //设置深度测试   
  236.     public void setDepthTest(boolean on) {   
  237.        if (on) {   
  238.            this.gl.glEnable(GL10.GL_DEPTH_TEST);   
  239.            this.gl.glDepthFunc(GL10.GL_LEQUAL);   
  240.            this.gl.glDepthRangef(0.0F, 1.0F);   
  241.            this.gl.glClearDepthf(1.0F);   
  242.        } else {   
  243.            this.gl.glDisable(GL10.GL_DEPTH_TEST);   
  244.        }   
  245.     }   
  246.     //设置双面显示,,,背面裁切   
  247.     public void setCullFace(boolean on) {   
  248.        this.gl.glFrontFace(GL10.GL_CCW);   
  249.        this.gl.glEnable(GL10.GL_CULL_FACE);   
  250.        this.gl.glCullFace(GL10.GL_BACK);   
  251.     }   
  252.     //设置投影类型   
  253.     public void setProjection(int projection) {   
  254.        switch (projection) {   
  255.        case PROJECTION_2D:   
  256.            this.gl.glMatrixMode(GL10.GL_PROJECTION);   
  257.            this.gl.glLoadIdentity();   
  258.            //正交   
  259.            this.gl.glOrthof(0.0F, this.mWidth, 0.0F, this.mHeight, -1.0F, 1.0F);   
  260.            this.gl.glMatrixMode(GL10.GL_MODELVIEW);   
  261.            this.gl.glLoadIdentity();   
  262.            setDepthTest(false);   
  263.            break;   
  264.        case PROJECTION_3D:   
  265.            this.gl.glViewport(00this.mWidth, this.mHeight);   
  266.            this.gl.glMatrixMode(GL10.GL_MODELVIEW);   
  267.            this.gl.glLoadIdentity();   
  268.            //透视   
  269.            GLU.gluPerspective(this.gl, 60.0F, this.mWidth / this.mHeight,   
  270.                   0.5F, 1500.0F);   
  271.            this.gl.glMatrixMode(GL10.GL_MODELVIEW);   
  272.            this.gl.glLoadIdentity();   
  273.            //lookat   
  274.            GLU.gluLookAt(this.gl, this.mWidth / 2this.mHeight / 2,   
  275.                   Camera.getZEye(), this.mWidth / 2this.mHeight / 20.0F,   
  276.                   0.0F, 1.0F, 0.0F);   
  277.            setDepthTest(true);   
  278.            break;   
  279.        case PROJECTION_CUSTOM:   
  280.            break;   
  281.        }   
  282.        this.mProjection = projection;   
  283.     }   
  284.     //销毁接口   
  285.     public static abstract interface IDestroyable {   
  286.        public abstract void destroy();   
  287.     }   
  288.     //生命周期接口   
  289.     public static abstract interface IDirectorLifecycleObserver {   
  290.        public abstract void onDirectorPause();   
  291.        public abstract void onDirectorResume();   
  292.        public abstract void onDirectorEnd();   
  293.     }   
  294. }  
代码清单1-2则是我们为引擎实现的一个渲染器,其中我们主要对Opengl视图进行了初始化,大家可以看出,我们留好了3D处理的接口(因为某些2D游戏为了能做得更逼真,同样需要3D的一些效果,当然这也可能需要更高的版本才能支持),这里我们需要给大家特别说明一下设置插值算法及其渲染模式,其中GL_PERSPECTIVE_CORRECTION_HINT是指按照指定颜色和纹理坐标的插值质量。GL_FASTES为使用速度最快的模式GL_NICEST为使用质量最好的模式。由于我们很多时候在做游戏时需要在质量和效率上进行选择,为了保证效率,我们不免会牺牲一些画质,这些将根据具体的游戏来确定;另外我们还开启了抖动(GL_DITHER),因为一旦输入的片元通过了所有的测试,它就可以与颜色缓存中的当前内容按某种方式合并起来。最简单的方法,也是默认操作,就是将当前值覆盖掉。在RGBA模式中,如果希望片元是半透明的或是消除了锯齿现象的,程序员可以将该片元值与缓存中的值作一平均,即混合。对于可用颜色较少的系统,可以以牺牲分辨率为代价,通过颜色值的抖动来增加可用颜色数量。抖动操作是和硬件相关的,OpenGL允许程序员所做的操作就只有打开或关闭抖动操作。实际上,若机器的分辨率已经相当高,激活抖动操作根本就没有任何意义。要激活或取消抖动,可以用glEnable(GL_DITHER)和glDisable(GL_DITHER)函数。默认情况下,抖动是激活的。在颜色索引模式中,可以利用任意的按位逻辑操作,将输入片元与已写入的象素进行合成;最后需要注意的是我们在设置2D投影方式时选择了glOrthof来设置一个正交视口,3D时我们选择了GLU.gluPerspective来实现一个透视投影效果。当然这里目前只有一部分,因为我们所有的事情几乎都于渲染器相关,所以我们后期还会对该类进行完善,包括场景堆栈管理,坐标系转换,中断、暂停等处理。这里我们将先介绍这么多。
 
数据类型
为了方便开发,我们需要对该引擎的数据类型进行统一,该引擎我们将使用如下一些数据类型,下面我们将分别介绍他们的功能及其作用。
评论
显示
悄悄话
汇众教育官网 | 联系方式 | 版权声明 | 友情链接
Copyright 2008© 汇众益智(北京)教育科技有限公司. All Rights Reserved
京ICP备09092043号 京公网安备11010802009023号