再读J2ME游戏编程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了再读J2ME游戏编程相关的知识,希望对你有一定的参考价值。

再读J2ME游戏编程(2013.11.01)

决定再读一遍J2ME游戏编程。这本书是我2005年购自黄岛新华书店,那是第一次听说J2ME可以开发手机上的游戏,立刻就惊呆了,久久不能离去,再书店的角落捧着此书贪婪的看着,因为就这一本,可笑的怕被别人先买走,当天花了RMB79购入,这是近十天的生活费了。

重读此书,作为对作者Martin.J.Wells的崇拜之情,也因为此书是自己游戏开发的启蒙读物。虽然,从现在来讲,J2ME技术本身已经过时,但是此书中包含的游戏开发的思想,流程,步骤,术语,以及技术要点,都值得细细回味。

Java的成功秘诀,简单来说就一句话:Write Once,Run Anywhere。在我看来,Java的前身,star seven的电子设备,在当时应该是有一定的前瞻性的。只不过生不逢时,这就同2004年NOKIA的S80,S90系列一样,其他环境达不到,出现这么一个东西,没有无线信号,没有互联网,这样的设备,以现在的标准,确实不应该称之为下一代计算机技术。

oak比Java更好听,James Gosling为啥不继续使用这一个名字呢?Java的成功在于跨平台,在不同平台上实现了各自的虚拟机,然后上层统一使用一种语言。WebRunner搭上了当时的互联网的车票,具体到现在的ios,android,winphone平台,为什么不继续使用这一个技术?android自己实现的Dalvik虚拟机与KVM差别有多大?

Java的三大分支J2SE,J2EE,J2ME,目前J2ME已经没落,除了部分低端山寨机的MTK平台还继续使用之外,好像已经不多见。J2SE也在磕磕绊绊的发展,脚本化。只有J2EE在企业级开发上有足够的底蕴和积累,目前还是主流。

Java抛弃的多重继承,模板,运算符重载,确实是大部分程序员所厌恶的,也只因为此,Java让程序员成了一个大众化的,门槛较低的职业,也变成了人们眼中所谓的码农。

最后,到处都是微型设备,前景依旧光明,便携式设备室真是一个令人兴奋的产业。比如,NOKIA S30,S40,S60,S80,S90...SONY ERICSSON MOTOROLA ...由此而来的,是设备的分散化,碎片化,所以J2ME平台在设计之初,根据类别来设计,设计为“配置”和“简表”。
配置:对一组相似性设备的抽象底层描述。CDC AND CLDC
简表:更倾向于上层UI界面的一种抽象描述。MIDP
在不同的配置上,JAVA为它们设计了不同的虚拟机。比如,Hotspot VM,CVM,KVM。设计不同的虚拟机是一个正确的选择,我们不能兼容性限制再最低的硬件设备上,这对高端设备是一个不公平的折中。

J2ME安全控制在虚拟机安全(预校验)和应用程序安全(沙箱)。
MIDlet:JAR AND JAD,注意JAR和JAD的关系,以及为什么需要这么做?

最后,我们真的可以用这些有限的资源来开发一流的游戏,而且一个很棒的事情是不用把灵魂出卖给出版商获取¥200万美元的预算去开发一个大型游戏--如果果可以的话,创建一个成功的J2ME游戏只需要志同道合的几个朋友,最好都有点疯狂,当项目完成后,会有可靠的方法来实现盈利。

再读J2ME游戏编程之二(2013.12.09)

本内容是J2ME游戏编程书籍附录的Java2回顾,虽然比较简单,但是可以基本了解Java2的全貌。

一 Java概述

二 Java程序运行机制

三 对象

1.对象描述(状态和行为)/ Java对象描述

数据描述-->数据行为-->渲染层

Car:{int x,int y}-->move:{run x,y}-->paint:{setPosition}

2.实例化 构造器 域 方法

3.多个构造器

4.对象和内存

引用和对象的关系

没有什么途径可以释放内存

通过引用是否还在有用判断是否需要回收对象

四 基本语法

1.注释

2.基本类型boolean byte char short int long float double,没有unsigned

3.常用类型

数字:十进制=12   八进制=012   十六进制=0X12  长整型=12L 单浮点=12F  双浮点=12D

转义字符:

数值赋值:

4.运算符

赋值 算术 位操作(>>   <<   >>>) 条件运算

5.语句

顺序  条件  循环

特例:break label

6.字符串String

判断字符串是否相等的问题== vs equals

String.valueof()//数字转字符串

7.数组

int array[];

int array[]={1,2,3,4,5,6,7};

array.length;//数组长度

五 面向对象编程

1.继承

extends

super()//父类构造器

Vector()//数据类型Java1.2

instanceof//判断实例

object.getClass().getName().equals("...");

2.重载和重写

3.abstract

虚拟类没法被实例化虚

虚拟方法子类必须被实例化

4.接口

5.访问保护

6.内部类

内部类可以不受限制的访问封装类的所有数据,封装类不能访问任何内部类的数据。

7.析构器

void finalize();//垃圾回收之前

8.this

不能用在static方法中

9.static

类共用属性

10.final

final修饰的属性和方法不能被改变

final修饰的方法不能被重载

六 异常

try{}

catch(Exception e){}

finall

七 其他

package i

 

再读J2ME游戏编程之三(2013.12.22)

本书的第二部分是介绍开发方式和基本API的使用。
虽然可视化集成开发环境更加友好方便,但是命令行方式更能够让我们理解运行应用程序的原理。在J2ME中,共分三步:
1.javac编译
2.preverify预校验
3.midp运行

J2ME在的API在设计上分为Application,Timer,Network,RMS,UI五大部分。
应用程序方面,一个MIDLET是一个应用程序,一个应用程序由JAM控制。MIDLET的API功能主要分为2个方面,即JAM告诉MIDLET一些事情,MIDLET告诉JAM一些事情。
定时器方面,分为Timer和TimerTask。这里没有什么特别的东西,和J2SE的里面是一致性。
网络方面,采用的时一套名为GCF的框架,采用了工厂模式。
数据保存上,采用了一套简单的RMS系统,都比较简单,没有什么可以多说的...
接下来是大头的一块,UI。
UI分为高级UI(Screen)和低级UI(Canvas)组成。Display上显示的唯一的一个Displayable。在Screen中,List,TextBox,Alert,Form.Form是一个比较特殊的控件,是其他控件的集合容器。在Canvas中,我们使用Graphics在Canvas上绘制Image.

这里面提到过两个问题比较有意思,
一个是何谓可变图像和不可变图像?不能修改的图像就是不可变的,否则是可变的。
另外一个是何谓双缓冲?先不要直接在屏幕上使用Graphics工具绘图,而是先创建一张图片,在这上面得到图片的Graphics,然后在这上面绘图,最终,把这个图片一次性绘制到屏幕上。

虽然这里主要以MIDP1.0进行讲解,但是,相信我,再MIDP1.0上积累的开发经验不会白扔的,在MIDP2.0上大多可以继续使用,并且拥有更好的特性。
事实上确实如此。

再读J2ME游戏编程之四(2016.01.04)

下面的内容作者以一个小游戏实例,讲解了一个游戏的基本框架和J2ME常用的API的使用,这个游戏就是去年非常流行的天天过马路的初级版。
一个游戏的核心,其实就是一个游戏循环,这个循环的每一次之中,把所有的任务都做一遍,要足够快,使得对玩家看上去有一种真实感,就像播放电影一样,播放电影是每一秒24帧,就是每一秒24个循环,游戏可能需要更快,不管什么游戏,基本结构如下:
void run()
{
input();
logic();
paint();
//计算FPS
if(curtime-lasttime>1000)
{
lasttime=curtime;
out("FPS");
FPS=0;
}
else
{
FPS++;
}
//通过FPS可以得到PFS,就是每一帧的时间,然后通过时间运算,可以发现是否有剩余的时间,有的话可以休眠线程。
FPS=24;
pfs=1000/FPS;
if(curtime-lasttime<pfs)
{
sleep(pfs-(curtime-lasttime));
}
//注意,以上两个FPS和PFS是两种不同的情况
}
在logic循环中,这里有一个问题,如何解决没有浮点数的情况下的游戏循环移动逻辑?本书的做法是:以100ms为一个渲染单位,假设20ms左右为一个游戏循环,每一个循环,都把这个循环的dtime相加,当到达100的时候,开始一次渲染。然后如果时间有剩余,积攒记录之。直到积攒到下一个100ms。
上面讲的是游戏的通用结构,说白了就是一个大循环。最后,让我们来熟悉一下游戏渲染的通用结构。
1.首先,要有一个应用程序管理器,在J2ME里面是JAM,MIDLET,这里面有应用下程序的入口和出口。
APPManager.java
start()/pause()/exit()....
2.应该有一个游戏菜单Menu.java,这里放置的是游戏界面的各个入口。
3.游戏场景GameScene.java,游戏的场景,游戏主循环(即本文开头的循环)在这里。游戏的主循环看需求是否要展开独立的线程。
void run()
{
while(true)
{
...
}
}
这里面包含所有演员的逻辑处理和渲染,使用接口。注意,这里要用双缓冲。
void paint()
{
Vector...paint();
ArrayList...paint();
}

4.Actor.java。演员,也就是平常我们所说的精灵。演员有自己的逻辑运算和渲染。
void ticker(float dtime)
{

}

void render()
{

}
5.碰撞检测:矩形碰撞

再读J2ME游戏编程之五(2016.01.21)

在本书的第三部分,作者使用J2ME提供的API做了一个详细的游戏,名Star Assault,中文名就叫空间大战吧。这里虽然是一个游戏实例,但是从另外一个角度来看,它有两个功能。第一是作者用MIDP1.0的API实现了MIDP2.0的游戏库API。第二,从整体来看,这个项目实现了一个简单的2D游戏引擎,至少具有初级的引擎模型。从这部分开始,通过再次阅读这个项目,来复习一下如何制作一个简单的游戏引擎。
首先,就是我们要说的精灵的实现。精灵是一个游戏内容的主体表现者,是不可或缺的一部分,它是通过如下代码结构实现的。
1.图片打包,杂凑和简凹。
这个在cocos引擎的时代已经非常常见了,即把许多散图打包在一张图片上,不过在J2ME时代要简陋的多,至少在本项目中,这一切都是有序的,不需要plist描述文件。
2.加载图像,这里,图像以左上角为基准原点。
void loadImage(String filename);
2.图像裁剪,用到一个概念,之前讲过的可变图像和不可变图像,我们把不可变图像绘制在可变图像上,完成了图像裁剪。
Image getImageRegion(Image source,int x,int y,int width,int height);
取得source图片的一部分,从x,y点开始去width,height的大小,并返回新的图片。
3.分离帧,既然上面的方法可以取出图片的一部分,我们可认为每次取出一帧,然后保存起来。
Image[] extractFrames(Image source,int x,int y,int wide,int high,int width,int height);
参数含义同上,只不过加了x,y方向上分别有多少帧的数字。
4.图像集,其实就是把多状态的精灵归集,每一个状态都有对应的Image[]
ImageSet.java
numStates;//状态数
stateFrameWidth[numStates];//状态帧宽度
stateFrameHeight[numStates];//状态帧高度
stateFrames[numStates][];//状态和帧数 ?复习一维数组和二维数组
addState(Image frames[],int aniTime);//添加状态及时间,实际上这个也是这一步中最关键的方法
void draw(Graphics g,int state,int frame,int x,int y);//绘制帧
5.精灵,精灵和图像集为啥要分开,作者并没有详谈,但是把图像加载和实体渲染分开,好像还是必要的。
Sprite.java,最注重的是动画处理,这里用到了我们之前说过的cycle(float dt),通过时间间隔决定是否换帧
curState;//当前状态
curFrame;//当前帧
Sprite(ImageSet set,int state,int frame);//初始化
setState(int state,bool force);//状态切换,是否强制
6.可能的改进
动画反向播放
状态自切换
事件触发器
图像集管理
资源数据化

以上是关于再读J2ME游戏编程的主要内容,如果未能解决你的问题,请参考以下文章

学java有啥不为人知的技巧

使用 j2me 在游戏中的诺基亚设备振动

游戏编程入门

初级游戏外挂编程详解 windows运行原理+游戏辅助编程 游戏外挂编程

2-Python游戏编程-拼图游戏(教程+源码)steam少儿编程课件

3-Python游戏编程-扫雷游戏(教程+源码)steam少儿编程课件