您现在的位置: 安卓中文网 >> OPhone中文网 >> 使用教程 >> 正文

谈移植OPhone游戏的经验与技巧

谈移植OPhone游戏的经验与技巧

OPhone平台开发, 2010-04-07 10:17:59

标签 : OPhone游戏 游戏移植

一、对不同屏幕大小的适配

这个游戏是从J2ME的NokiaN73版本移植过来的,是一个专门针对QVGA屏幕大小的游戏版本。不仅手机屏幕的宽高都人为赋值定死的,而且游戏中的所有图片都是针对QVGA的,在屏幕上的位置也进行了数值的固定。因此,这个游戏的可移植性并不好。
 

1. 图片大小的适配

从游戏原来的QVGA大小改变到HVGA,nHD乃至超大的WVGA大小,我们可以走两条路。一是通过程序放大图片到所需要的大小,这样做可以做到一个apk文件适配所有屏幕大小,可是代价是图片会失真。代码如下:
 
view plaincopy to clipboardprint?
  1. public static Bitmap resizeImage(Bitmap bitmap, int w, int h) { // 此处的bitmap即为要转换的图片,w, h是要形成图片的宽和高 Bitmap BitmapOrg = bitmap; int width = BitmapOrg.getWidth(); int height = BitmapOrg.getHeight(); int newWidth = w; int newHeight = h; float scaleWidth = ((float) newWidth) / width; float scaleHeight = ((float) newHeight) / height; // 创建转换矩阵 Matrix matrix = new Matrix(); matrix.postScale(scaleWidth, scaleHeight); // 重新生成所要的图片 Bitmap resizedBitmap = Bitmap.createBitmap(BitmapOrg, 0, 0, width, height, matrix, true); return resizedBitmap; }  
 
可是这样做的代价是图片会失真,特别在WVGA和FWVGA屏幕大小严重影响游戏的效果。另一种方法就是分别在不同的分辨率下,绘制不同的四套图片,这样就会使得移植性下降,每个版本都会有一个配套的apk,可是游戏的效果会很好。因此我们选择了第二种方案。
 

2. 自动获取手机参数,尽最大可能增加游戏的可移植性

首先,我们通过参数获取手机的分辨率,在Activity的子类里实现如下功能:
view plaincopy to clipboardprint?
  1. this.requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); final DisplayMetrics wH = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(wH); GameScreen.ScreenWidth = wH.widthPixels;//手机屏幕宽 GameScreen.ScreenHeight = wH.heightPixels;//手机屏幕高  
 
 
同时,在游戏里,尽可能用上述两个变量代替原来的数字。并且通过前面的转化图片函数,可以把一些需要放大的图片放大到手机屏幕大小,减少美工工作量。
 
3. 画图位置适配
 
与之前J2ME的设置数字相比,用手机屏幕的比例设置画图位置,我们就可以大大简化移植的复杂性。在画位图或者调用Paint画文字、图形等时候,按照在手机上显示的比例或者按照图片的大小让图片显示在手机的某个位置来绘制,就会很好的适配各种屏幕大小。
 
二、图片的翻转和旋转
 
此游戏中用到了图片的翻转,因此我结合一下这个游戏谈一下图片的旋转和翻转。
图片的旋转:在Ophone的SDK里我们可以找到图片的旋转函数,如下:
view plaincopy to clipboardprint?
  1. Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.icon);//载入要转换的图片 bmpWidth = bmp.getWidth(); bmpHeight = bmp.getHeight(); Matrix matrix = new Matrix(); matrix.postScale(scaleWidth, scaleHeight); matrix.setRotate(-5);//转换的角度 Bitmap resizeBmp = Bmp.createBitmap(bmp, 0, 0, bmpWidth, bmpHeight, matrix, true); //重新生成图片  
 
图片的翻转:在SDK中我没有找到翻转的接口(就是镜像),因此我采用了图片矩阵的方法。
 
我们知道图片是以矩阵的方式存储的,图片的转化在本质上就是数组和矩阵的变化。其中的Matrix本身就是一个3*3的矩阵,它可以通过他的接口去实现旋转的角度,而在这个矩阵内部会根据角度生成一个相对应的三维矩阵。
 
下面我们看矩阵如何实现旋转角度和翻转的。如果将平面中的点视为 1×2 矩阵,则可通过将该点乘以一个 2×2 矩阵来将该点变换。例如,[1,2],将它点乘[0,1;1,0]结果是[2,1],就实现了关于Y轴的镜像。实例如下:  
 
 
因此,对于在程序里实现镜像只需要把matrix赋值为一个可以让翻转的矩阵即可。下面是实现水平镜像的函数:
view plaincopy to clipboardprint?
  1. Bitmap bitmap; float[] a = { -1, 0, 0, 0, 1, 0, 0, 0, 1 }; // 镜像所需要的矩阵   
  2.        Matrix ma1 = new Matrix();   
  3.        ma1.reset();   
  4.        ma1.setValues(a);// 赋值给matrix矩阵   
  5.        int width = image.getWidth();   
  6.        int height = image.getHeight();   
  7.        bitmap = Bitmap.createBitmap(image, 0, 0, width, height,        ma1, true);   
  8.    return bitmap;  
 
三、Activity的活动
 
我们知道Ophone的程序在按下挂机键时候,程序没有关闭,而是挂起状态。如果这时候在
view plaincopy to clipboardprint?
  1. protected void onPause() { super.onPause(); }  
 
函数里不做设置的话,程序可能一直在后台运行。这是中断所不允许的,这个时候我们可以设置一个掌管暂停的变量,在暂停时候,设置为True,然后在
 
view plaincopy to clipboardprint?
  1. public void onResume() { super.onResume(); }  
里面设置为False,在这个变量为True的时候程序里的线程暂停。这样可以实现游戏的暂停。这时候要注意的是,暂停时候的音频播放对象MediaPlayer的对象如果正在播放的话,在暂停时候要执行pause();恢复时候要在在Resume里执行start();
 
四、实现滑动和拖动动作
 
我们知道在Ohone的SDK中有触摸屏的触摸函数public boolean onTouchEvent(MotionEvent event),其中有触摸、滑动和释放动作。结构如下
view plaincopy to clipboardprint?
  1. public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub switch (event.getAction()) { case MotionEvent.ACTION_DOWN: /*****************触摸响应*********************/ break; case MotionEvent.ACTION_UP: /*****************释放响应*********************/ break; case MotionEvent.ACTION_MOVE:   
  2. /*****************滑动 应*********************/  
  3.                        
 
对于ACTION_DOWN我们很好理解,即触摸某个范围给他一定的响应。对于实现滑动就略显复杂点,首先我们要通过ACTION_DOWN获得初始坐标值,然后在ACTION_MOVE里面作出判断,我们的触摸坐标相对初始坐标有什么变化,然后把动作写在相应的变化里。例如下面是一个上下滑动实现类似于上下按键的响应的例子:
 
 
view plaincopy to clipboardprint?
  1. switch (event.getAction()) { case MotionEvent.ACTION_DOWN: temp[0] = x; temp[1] = y;//获取初始坐标 break; case MotionEvent.ACTION_MOVE: if (temp[1] > y) { key_press = KeyDown;//向上滑动则相当于按上键 } else if (temp[1] < y) { key_press = KeyUP;//向下滑动则相当于按下键 } break; case MotionEvent.ACTION_UP: key_press = 0; //释放触摸 break; }  
 
下面我们再来看看拖动动作的实现,例如我们要去拖动屏幕上的某个物体,首先我们得先判断我们的初始ACTION_DOWN是否是按在物体上了,因此我们有必要设置一个变量判断这个条件。只有这个条件成立,我们才能拖动物体。然后我们在ACTION_MOVE里面进行拖动操作。下面是一个拖动物体的例子:
 
view plaincopy to clipboardprint?
  1. int x = (int) event.getRawX(); int y = (int) event.getRawY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: if (/**判断物体是否在触摸区域**/) { isPress = true; } break; case MotionEvent.ACTION_MOVE: if (isPress) { player.curX = x;//把当前的坐标值赋值给物体 player.curY = y;// } break; …… }  
 
当然我们要进行更深入的动作,比如拖动的速度、范围…,就要在ACTION_MOVE做更多的事情。


(编辑: toto56 )

Gridshock 消格子
gem miner 宝石矿工
灌篮高手 爆发!樱木
Qrossfire v1.1.12
LauncherPro PLUSV0.8.11 全功能解锁版
UC浏览器 7.4 稳定版
友录通讯录 1.0 正式版
UC影音 2.2beta2
3.5寸大屏Ophone 中兴U900多图鉴赏
大板凳 手机登论坛

    您可以使用“← | →”键快速翻页,或者进入全文阅读模式!
    事件进展:
    观后感:
    相关文章:
      {tgbus_tag:include file="http://inc.tgbusdata.cn/file/tuijian.html?v=5" charset="gb2312" /}
      热门新闻排行
      • 本周
      • 本月
    • 此栏目下没有文章
    • 此栏目下没有文章
    • 关于我们  广告投放  联系我们  网站地图  友情链接  诚聘英才  版权声明  WAP手机版
      皖ICP备12012248号-15  ICP:皖B2-20130011  广电节目制作(皖)字第00154号  皖公网安备34020302200005

      Copyright 2004-2018 TGBUS Corporation, All Rights Reserved