J2ME游戏开发的高级优化技巧

本文探讨了在资源受限的J2ME平台上优化游戏的方法,包括何时需要优化、如何使用Profiler定位瓶颈,以及具体的代码优化策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  为什么要优化?

  游戏能够被划分为两种较广泛的类型:实时型和按键驱动型。按键驱动类型的游戏一般在屏幕上显示游戏目前所处的状态,并且等待玩家输入某些按键来驱动游戏继续运行。棋牌类游戏,大部分的解谜类游戏以及策略类和文字类游戏都属于这类游戏。而实时游戏,特别是动作游戏不会等待玩家的输入,他们一直运行直到游戏的结束。

  动作类游戏一个重要的特征就是将大量的运算花在屏幕显示上,而且刷新率(FPS)必须保持在10以上。这类游戏还必须要有大量的动作来使得游戏具有更高的挑战性。这类游戏需要玩家有快速的反应和很好的手眼协调能力,所以这类游戏对键盘输入的反应也有极高的要求。为使得程序在高速运行时能对键盘做出及时的反应,图像能以高速的FPS来运行,我们就必须优化我们的代码,以使得我们的程序能以最快的速度运行。

  J2ME是一个精简的Java版本,适合只有有限容量的小型设备,例如手机和PDA,J2ME设备有:

  ◆有限的输入能力

  ◆屏幕尺寸很小

  ◆受限的内存及堆大小

  ◆很慢的CPU

  这些特点使得在J2ME平台上编写快速的游戏并不是件易事。相对于电脑游戏来说,编写J2ME平台上的游戏会对程序有更高的要求和更进一步的挑战。

  何时不用优化?

  如果你编写的游戏不时动作游戏,有可能不必去优化。假如玩家需要几秒钟甚至几分钟去思考他下一步怎样走,那他将不会注意到你的游戏的按键响应超过几百毫秒。不过一个例外是如果你的程序需要大量的运算去决定它下一步怎样走,例如棋类游戏需要在几百万种组合中去寻找。假如这样的话,你有可能想要优化你的代码以使得电脑仅需要几秒钟而不是几分钟去决定他下一步的动向。

  即使你正在编写这类游戏,优化也是相当危险的。这些技术将伴随着高昂的代价,他将使你的代码不易读。这就需要开发者自己去平衡。增大了JAR文件的大小来换取程序少量性能的提高是否是值得的。下面给出不要去优化的更多的理由。

  ◆优化将很容易引入bug

  ◆有些优化技术将使得移植变得困难

  ◆有可能你付出了巨大的努力却收效甚微

  ◆统一的优化一般比较困难

  我需要对最后一点做一些解释:由于优化的是一个不定的目标及平台,有些方法可能在Java平台上运行快一点,而有些可能在J2ME平台上运行快一点。由于执行环境存在着巨大的差异,你的代码可能在模拟器上跑得很快,但是在真机上却很慢。反之也有可能。你对一种机型的优化可能会造成在另一种平台上性能的下降。

  但这些并不代表我们没有了希望。你可以通过两种方法来进行优化,高级优化和低级优化。高级优化可以在任意的平台上来提高程序的性能,甚至全面的提高代码的质量。而低级优化则是相对于某种特定机型的优化技术。高级优化即算法上的优化,低级优化即程序层面对于单个函数执行效率的优化。Michael Abrash, Quake的开发者之一,曾经写到:"the best optimizer is between your ears". (最好的优化者在你的两耳之间).使用优良的算法所能提高的效率比在一个普通算法的程序上使用低级优化所能提高的效率要高得多。

  我们将使用J2ME Wireless Toolkit的Profiler去剖析你的代码的运行效率,它也将帮助你更精确的测量出这些技术对于提高性能的有效性。

  在哪里优化?

  在动作类游戏中,90%的程序执行时间被花费在了10%的代码段中。这10%的代码段是我们需要集中全力去优化的部分。我们将使用profiler去找到这10%代码的位置。照下图我们打开J2ME Wireless Toolkit的Profiler功能。

  我们必须要在模拟器中运行程序并退出后才会弹出Profiler窗口

  注意在左窗口中该函数所占用cpu百分比,这个百分比是总执行时间花在每个特定函数上的百分比,接下来我们只要找到占用百分比最多的那个函数来优化就可以了。

  有几点需要注意的。首先:你的百分比数和我的肯定有很大的不同,但是有一点是相同的即花费时间最长的函数所占的百分比数最大。每次运行程序我的百分比数都会不同,为了尽可能的保持统一,我们在测试前应当关闭其他的程序。其次:测试时不要混淆,否则你将看到函数名类似于a,b,z..最后:Profiler并不知道你模拟的是什么机型。记住,真机才是真理。

  如何优化?

  知道了在那里优化,但如何进行优化呢?我们知道大部分的运算时间被花在了绘图函数上,J2ME已经为我们提供了这些函数,我们没有办法对这些函数的内部进行优化,但是我们仍然有选择权。下面我们来对J2ME提供给我们的绘图函数作一测试。

  在Canvas类里添加测试代码如下:

  protected void paint(Graphics g) {

  TestPaint(g);

  }

  void TestPaint(Graphics g) {

  setClip(g);

  setColor(g);

  m_font = getFont();

  setFont(g);

  drawString(g);

  drawRect(g);

  fillRect(g);

  drawImage(g);

  drawRegion(g);

  drawArc(g);

  drawChar(g);

  drawLine(g);

  drawRoundRect(g);

  fillArc(g);

  fillRoundRect(g);

  }

  void setColor(Graphics g) {

  g.setColor(0);

  }

  void drawArc(Graphics g) {

  g.drawArc(0, 0, 100, 100, 4, 4);

  }

  void drawChar(Graphics g) {

  g.drawChar('你', 0, 0, GE.TOPLEFT);

  }

  void drawRoundRect(Graphics g) {

  g.drawRoundRect(0, 0, 100, 100, 4, 4);

  }

  void fillRoundRect(Graphics g) {

  g.fillRoundRect(0, 0, 100, 100, 4, 4);

  }

  void fillArc(Graphics g) {

  g.fillArc(0, 0, 100, 100, 4, 4);

  }

  void drawLine(Graphics g) {

  g.drawLine(0, 0, 100, 100);

  }

  Font getFont() {

  return Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_SMALL);

  }

  void setFont(Graphics g) {

  g.setFont(m_font);

  }

  void drawString(Graphics g) {

  g.drawString("你好", 0, 0, GE.TOPLEFT);

  }

  void drawRect(Graphics g) {

  g.drawRect(0, 0, 100, 100);

  }

  void setClip(Graphics g) {

  g.setClip(0, 0, 300, 300);

  }

  void fillRect(Graphics g) {

  g.fillRect(100, 0, 100, 100);

  }

  void drawImage(Graphics g) {

  g.drawImage(GE.m_images[GRes.PNG_MAP], 0, 100, GE.TOPLEFT);

  }

  void drawRegion(Graphics g) {

  g.drawRegion(GE.m_images[GRes.PNG_MAP], 0, 0, 100, 100, Sprite.TRANS_MIRROR,100, 100, GE.TOPLEFT);

  }

  该程序各函数分别四川白癜风医院绘制100*100的图形,经过一段时间以后,退出应用程序

  根据Profiler窗口所显示的数据,我们发现drawString最耗时。其次是drawRegion,所以我们应尽量避免使用drawString函数。

  通过Profiler对各种函数及程序的测试,我总结如下结论:

  ◆仅当你需要的时候才去优化代码!

  ◆仅优化那些最耗时的代码!

  ◆使用Profiler去查找哪里需要优化!

  ◆记住Profiler不代表真机上的优化结果,使用System Timer来在真机上做最后的测试!

  ◆在做低级优化之前,总是要先思考算法是否是最优!

  ◆绘图是很占用时间的,所以尽可能的减少Graphics函数的调用!

  ◆尽可能的使用SetClip()来减少绘图区域,相对于SetClip(),drawImage()所花的时间会更可观!

  ◆尽可能的将变量定义在循环以外!

  ◆尽最大可四川白癜风专科医院能的进行对需要的数据进行预先计算并将结果保存在缓冲里!

  ◆String类很容易产生垃圾内存,尽可能的使用StringBuffer代替String或用final static来定义之!

  ◆假设是不被接受的,一切要以真机为据!

  ◆尽量使用static final修饰函数,而避免synchronized修饰符!

  ◆对于频繁调用的函数要使用尽可能少的参数!

  ◆尽可能的不使用函数调用!

  ◆尽可能的使用<<和>>来代替*和/!

  ◆使用位操作来代替%运算!

  ◆与0比较比与其他数值比较快!

  ◆数组存取比C语言慢,尽可能不在循环中存取数组!

  ◆局部变量比其他类型的变量运算要快!

  ◆在switch()中尽量使用连续的小数值判断!

基于数据挖掘的音乐推荐系统设计与实现 需要一个代码说明,不需要论文 采用python语言,django框架,mysql数据库开发 编程环境:pycharm,mysql8.0 系统分为前台+后台模式开发 网站前台: 用户注册, 登录 搜索音乐,音乐欣赏(可以在线进行播放) 用户登陆时选择相关感兴趣的音乐风格 音乐收藏 音乐推荐算法:(重点) 本课题需要大量用户行为(如播放记录、收藏列表)、音乐特征(如音频特征、歌曲元数据)等数据 (1)根据用户之间相似性或关联性,给一个用户推荐与其相似或有关联的其他用户所感兴趣的音乐; (2)根据音乐之间的相似性或关联性,给一个用户推荐与其感兴趣的音乐相似或有关联的其他音乐。 基于用户的推荐和基于物品的推荐 其中基于用户的推荐是基于用户的相似度找出相似相似用户,然后向目标用户推荐其相似用户喜欢的东西(和你类似的人也喜欢**东西); 而基于物品的推荐是基于物品的相似度找出相似的物品做推荐(喜欢该音乐的人还喜欢了**音乐); 管理员 管理员信息管理 注册用户管理,审核 音乐爬虫(爬虫方式爬取网站音乐数据) 音乐信息管理(上传歌曲MP3,以便前台播放) 音乐收藏管理 用户 用户资料修改 我的音乐收藏 完整前后端源码,部署后可正常运行! 环境说明 开发语言:python后端 python版本:3.7 数据库:mysql 5.7+ 数据库工具:Navicat11+ 开发软件:pycharm
MPU6050是一款广泛应用在无人机、机器人和运动设备中的六轴姿态传感器,它集成了三轴陀螺仪和三轴加速度计。这款传感器能够实时监测并提供设备的角速度和线性加速度数据,对于理解物体的动态运动状态至关重要。在Arduino平台上,通过特定的库文件可以方便地与MPU6050进行通信,获取并解析传感器数据。 `MPU6050.cpp`和`MPU6050.h`是Arduino库的关键组成部分。`MPU6050.h`是头文件,包含了定义传感器接口和函数声明。它定义了类`MPU6050`,该类包含了初始化传感器、读取数据等方法。例如,`begin()`函数用于设置传感器的工作模式和I2C地址,`getAcceleration()`和`getGyroscope()`则分别用于获取加速度和角速度数据。 在Arduino项目中,首先需要包含`MPU6050.h`头文件,然后创建`MPU6050`对象,并调用`begin()`函数初始化传感器。之后,可以通过循环调用`getAcceleration()`和`getGyroscope()`来不断更新传感器读数。为了处理这些原始数据,通常还需要进行校准和滤波,以消除噪声和漂移。 I2C通信协议是MPU6050与Arduino交互的基础,它是一种低引脚数的串行通信协议,允许多个设备共享一对数据线。Arduino板上的Wire库提供了I2C通信的底层支持,使得用户无需深入了解通信细节,就能方便地与MPU6050交互。 MPU6050传感器的数据包括加速度(X、Y、Z轴)和角速度(同样为X、Y、Z轴)。加速度数据可以用来计算物体的静态位置和动态运动,而角速度数据则能反映物体转动的速度。结合这两个数据,可以进一步计算出物体的姿态(如角度和角速度变化)。 在嵌入式开发领域,特别是使用STM32微控制器时,也可以找到类似的库来驱动MPU6050。STM32通常具有更强大的处理能力和更多的GPIO口,可以实现更复杂的控制算法。然而,基本的传感器操作流程和数据处理原理与Arduino平台相似。 在实际应用中,除了基本的传感器读取,还可能涉及到温度补偿、低功耗模式设置、DMP(数字运动处理器)功能的利用等高级特性。DMP可以帮助处理传感器数据,实现更高级的运动估计,减轻主控制器的计算负担。 MPU6050是一个强大的六轴传感器,广泛应用于各种需要实时运动追踪的项目中。通过 Arduino 或 STM32 的库文件,开发者可以轻松地与传感器交互,获取并处理数据,实现各种创新应用。博客和其他开源资源是学习和解决问题的重要途径,通过这些资源,开发者可以获得关于MPU6050的详细信息和实践指南
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值