Android坦克大战游戏设计解析(连载)
在前文曾经写过Java坦克大战游戏设计,但是后来由于没有时间,就没写完,最近,计划将地图开发包移植到Android平台。因此需要对Android平台进行学习,在看过Android开发指南后,对Android平台有了一些了解,但是还是无实战经验,学习一个平台最好的办法是通过一个项目,也就是通过编程来学习一个新的移动开发平台。因此想起几年前在Java ME平台上写的坦克大战游戏,这个一个既有趣以能充分了解一个新平台的项目。而且通过两个平台的比较,也就更好的理解Android平台开发的一些特点。下图是Java ME平台下坦克大战的界面效果图。
http://img.freeoz.org/ibbs/attachments/month_0801/20080122_7a2b1fb3658ce5476d848tyVEBDJKvUh.png
在移植到过程中,发现尽管Android,和Java ME都是以Java为开发语言的手机平台,两都之间的差异还是不少的,但好处是,两者都采用Java语言,相当一部分与平台无关(如除图形,网络之类)的代码是可以通用的,这大大减少了从Java ME到Android平台移植的工作量。
这里先给出一些移植过程中的总结,后续文章将较详细的说明坦克大战游戏的设计过程(适用于各个平台)。
1. Android应用一般无主程序入口,但对于单Activity的应用来说,Activity相当于Java ME的 Midlet.
2. Android中View的概念类同于其它平台中Control的,ViewGroup相当于Container. 当然它也可以用作一个窗口View,在移植的过程中,采用单Activity,多窗口View的方法来对应于Java ME的Midlet和多个Displayable类.
3. Android绘制图形时,没有一般图形库中提供的Pen, Brush类,设置Pen和Brush,字体都是通过Paint类来设置的,对于初学者一开始会觉得有些困惑。
4. Rect 一般是通过left,top, bottom, right来定义,而Java ME平台是通过left, top, width, height,如果不注意,会造成意想不对结果:-),如android 平台中canavs.drawRect, 以及canvas.clipRect 是通过left,top, bottom, right来定义一个四边形,而Java ME是通过left,top及宽度,高度来定义,移植过程如果不注意就出错了。
5. Android在非UI 线程中更新Canvas里,需要调用postInvalidate, view.invalidate 相当于 Jave ME中 Canvas 的repaint.
如果想在非UI线程执行和UI相关的方法,一般是通过hander.post 来实现,而与这对应的 Java ME是display的callSerially.
6. Android中提供一个SurfaceView类,允许在使用另一个thread来更新Canvas,这对于游戏的图形的刷新性能提高非常重要。
7. Android没有提供类似Java ME中的Game API,但是实现或是移植一个类似的Game API也不困难,Android坦克大战游戏中移植了Java ME Game API中Layer, LayerManager,TiledLayer,Sprite类,使得整个移植工作变得非常顺利。
总体感觉Android平台相对来说还是比较容易上手,对于会Java或是C#的程序员,即使以前没有从事过手机软件开发,也是比较容易入门的。而且Android平台和Java SE有相当一部分类是公用的,也是二进制兼容的,也就是说在Java SE平台上的类库(.jar)文件,可以直接用在Anroid平台,这里先给出一个移植后的截图。后面将详细说明这个游戏的设计,最后会给出所有源码,有兴趣的朋友可以扩展成联网游戏或是作为学习游戏设计的参考,坦克大战游戏是一个中等难度的游戏,对于有志从事手机游戏开发的朋友,可以自行写个坦克大战游戏后基本就能入门手机软件开发。
[ 本帖最后由 trisun 于 15-8-2010 23:55 编辑 ]
Android坦克大战游戏设计解析二
Java ME中提供了一个Game API (javax.microedition.lcdui.game).大大方便了程序员在移动平台上开发复杂游戏。一般的游戏可以分为游戏人物及背景,可以将游戏场景分成多个层次。在Java ME Game API中提供了几个类。http://img.freeoz.org/ibbs/attachments/month_1008/20100827_57302eb27ff0964fccb7NAdi5not5QOF.png
Layer类,该类为一抽象类,提供了游戏人物及背景的层次的基本构架,它代表了游戏场景中一个可视化的元素,如游戏人物(Sprite)或是分片背景(TiledLayer).
Sprite类,为一个基本动画游戏人物,它可以显示多个动画帧中其中一帧,比如人向前,向后,向左,向右,坦克大战游戏中各种坦克就是一个sprite类对象,它可以显示坦克向四个方向移动的图象,并可很容易实现动态效果,如坦克履带移动的动态效果。它也支持了各种碰撞检测,比如子弹击中坦克,或是打中砖块等等。
TiledLayer类,一般用作显示游戏背景,为了能显示范围较大的背景,一般游戏背景地图可以通过小的图片拼接而成。TiledLayer用于实现由一个二维cell (分片地图)组成背景,这个类也提供了动态背景的支持,比如,坦克大战背景中水面的动态效果。
LayerManager 类用于管理多个Layer ,sprite,及TiledLayer都是Layer的子类。在坦克大战游戏中,LayerManager用来管理坦克及背景,TiledLayer 及sprites在LayerManager管理下有层次的关系(Z-Order),前面的Layer会遮挡后面的Layer.
而Andorid中没有提供 Game API,如果大家看过Android例子中snake的实现,其中 TileView的功能类似于 Game API中TiledLayer. 为了使减少移植工作,第一步是将Java ME中 Game API移植到 Android平台。
移植是基于microemulator中相应代码,移植工作量不大。在后面会提供移植后源码。
[ 本帖最后由 trisun 于 7-9-2010 00:50 编辑 ]
Android坦克大战游戏设计解析三
游戏中使用图象及声音资源坦克大战游戏中用到游戏资源(音效及图片)来自网络。
这里先对游戏用到的资源做个说明
音效 snd1--snd2 格式为 midi 用于过场音乐及字弹发射及爆炸音效。
图片
img1 - img5 为游戏中各种坦克,物体的分解图片。
其中 img1 由下面图片组成
各种增强宝贝 (最左边两个是家,和炸毁的家),依次为加一辆,定时器等等
坦克或子弹爆炸动画效果
子弹(四个方向飞行)
我方坦克动画(四个方向及履带动态效果),最右方为无敌时状态
多种敌方坦克
img2 由下列图片组成
雪地
砖块
树林
水面 (两片可以形成水面动态效果)
石头(一般情况下不能被坦克打穿)
img 3 由下列图片组成
开始画面
分数画面
显示玩家剩余坦克数
显示剩余敌方坦克数
img4由下列图片组成
显示分数
显示第几关
img5由下列图片组成
imgX 格式为这些PNG图片连接而成。如何读取请参见代码中的ResourceManager ,这些图片可以在程序包中的Resources目录中找到,代码中实际用到的资源snd1-snd5,img1-img5 在 src 目录下。
图片及音效链接请叁见http://blog.csdn.net/guidebee/archive/2010/09/06/5867287.aspx
或下载附件
[ 本帖最后由 trisun 于 7-9-2010 00:49 编辑 ]
Android坦克大战游戏设计解析四
有了游戏所需的图象及声音资源后,下面就可以开始定义游戏中的各种角色。为了方便起见,坦克大战游戏中定义了一个角色接口。public interface Actor{////////////////////////////////////////////////////////////////////////////
/**
* Operation be done in each tick.
*/
void tick();
}该接口有一个tick方法,为每个游戏帧该角色所要完成的动作,比如说背景可能要更换图形以形成动画效果(如水面波浪)。坦克可以完成前面一步,子弹飞行等等。
坦克大战游戏中定义了背景类BattleField ,子弹Bullet,各种坦克类(Tank, PlayTank, EnemyTank, FastTank, HeavyTank, SimpleTank,PlayerTank,SmartTank) , 升级法宝Powerup,以及动态显示的分数Score类,都实现了Actor接口。
而这些角色类同时又是Game API中 Layer的子类。因些游戏逻辑比较简单,下面代码是GameScene中线程Run的方法,为游戏进行时主线程public void run(){
Thread currentThread = Thread.currentThread();
try {
while (currentThread == animationThread) {
long startTime = System.currentTimeMillis();
// Don't advance game or draw if canvas is covered by a system
// screen.
if (isShown()) {
tick();
if(hasSurface){
Canvas canvas=holder.lockCanvas();
updateGame(canvas);
holder.unlockCanvasAndPost(canvas);
}
}
timeTaken = System.currentTimeMillis() - startTime;
if (timeTaken < MILLIS_PER_TICK) {
synchronized (this) {
if(MILLIS_PER_TICK > timeTaken){
wait(MILLIS_PER_TICK - timeTaken);
timeTaken = System.currentTimeMillis() - startTime;
}
}
} else {
Thread.yield();
}
}
} catch (InterruptedException e) {
}
}而其中的tick()方法就是调用游戏中所有角色的tick()方法:private void tick(){
for(int i=0;i<TOTALLAYERS;I++){
Layer layer=layerManager.getLayerAt(i);
if(layer.isVisible()){
Actor actor=(Actor)layer;
actor.tick();
}
}
applyGameLogic();
}这样参与游戏中的各个角色完成自已每帧所需要更新,整个游戏就动起来了。
http://img.freeoz.org/ibbs/attachments/month_1008/20100815_b16b777828940c10c45718hiqZltwvh1.png
在后面的文章将主要介绍各个角色类的基本实现方法。
[ 本帖最后由 trisun 于 10-9-2010 00:28 编辑 ]
Android坦克大战游戏设计解析五
本篇介绍坦克大战游戏场景类BattleField的设计思路。BattleField 是Game API中TiledLayer的子类。TiledLayer实现了由小的图形(称为tile)拼接成大的背景,坦克大战游戏的背景是由砖块,石块,树林,水面,雪地等小的图片拼接而成。TiledLayer可以很容易的实现这种类型的背景,包括水面波汶的动态效果。
下面的图片是一个简单由多个小tile组成的游戏背景。
http://img.freeoz.org/ibbs/attachments/month_1009/20100908_8d0b9734c5ae3fa5b819V3p6nKtu0N6D.gif
理论上TiledLayer可以实现无限大的背景。为简单起见坦克大战游戏中采用了半随机的方法来生成游戏背景,同时也提供了从文件读取游戏背景的方法,如果想完全复现FC的每一关,可以使用地图编辑器或是文本编辑器生成文件,然后从文件中读取背景。
这里给出一个关口的例子文件。0000000000000
0202020202020
0202020202020
0202026202020
0202020202020
0000020200000
6022000002206
0000020200000
0202020202020
0202020202020
0202000002020
0000000000000其中0代表空白,1代表雪地,2代表砖块,3代表树林,4,5代表水面,6代表石块。由于每个tile比较小,这里每个数据代表一个2X2的区块,下面代表实现从文件生成游戏背景。/**
* Read the battle from an input stream.
* @param is input stream stores the battle field information.
*/
private void readBattlefield(java.io.InputStream is) throws IOException {
int c = -1;
int x0 = (WIDTH_IN_TILES-NUMBER_IN_TILES)/2;
int y0 = (HEIGHT_IN_TILES-NUMBER_IN_TILES)/2;
int x=0,y=0;
while ((c = is.read()) != -1 && y < NUMBER_IN_TILES) {
switch (c) {
case ' '://empty
case '0':
duplicateCell(x+x0, y+y0, 0);x+=2;
break;
case '1'://snow field
duplicateCell(x+x0, y+y0,SNOW);x+=2;
break;
case '2'://brick wall
duplicateCell(x+x0, y+y0, BRICK_WALL);x+=2;
break;
case '3'://forest
duplicateCell(x+x0, y+y0, FOREST);x+=2;
break;
case '4':
case '5'://water
duplicateCell(x+x0, y+y0, -1 - ((x ^ y) & 1));x+=2;
break;
case '6': //Concrete wall
duplicateCell(x+x0, y+y0, CONCRETE_WALL);x+=2;
break;
case '\n'://new line
y+=2;
x = 0;
break;
default:
}
}
}实现在游戏中采用了半随机的方法,这样游戏关卡可以有无限多,半随机是指一半的砖块是从HZK16(16点阵汉字库)读取一个汉字,用其点阵显示为砖块,其它雪地,树林等采用随机数随机分布在游戏场景中。前几关的汉字是“引路蜂软件”。
坦克大战游戏中还会随机出现一些增强法宝,比如定时器可以让敌方坦克停止运动,地雷可以使屏幕中敌方坦克全部炸毁。铁锹可以让“家”全部被石块包住从而使敌方子弹无法打穿。星星可以让已方坦克加速,同时发射的子弹数增加并增加打击能力(比如可以打穿石块甚至树林等等)。
所以BattleField中同时也定义了显示PowerUp(增强法宝),初始化敌方坦克位置(一般是从最上方的左,中,右依次出现)。另外还要判断某个位置坦克是否可能通过(有砖块,石头,水面不能通过),雪地要加速,其它地方可以通行。另外还要判断子弹是否击中墙壁(子弹击中墙壁后要爆炸等等)。
最后来看看它的tick()中主要做些什么:public void tick() {
int tickState = (tickCount++ >> 3); // slow down x8
int tile = tickState % 2;
setAnimatedTile(-1 - tile, waterFrames[(tickState % 4) / 2]);
if(concreteWallStartTime>0){
long tickTime=System.currentTimeMillis();
if(tickTime-concreteWallStartTime>concreteWallPeriod){
makeHomeBrickWall();
concreteWallStartTime=0;
}
}
}它主要显示水面的动态效果,如果当前需要显示石块做的家,则将相应的cell中填入石块,由于宝贝有时效性,到了一定时间后将“家”变回普通砖块做成。
[ 本帖最后由 trisun 于 10-9-2010 00:28 编辑 ]
Android坦克大战游戏设计解析六
本篇介绍坦克大战游戏除坦克之外的几个角色。1. Bullet 子弹类 坦克发射出的子弹在游戏中飞行
2.Explosion 爆炸类 子弹击中子弹,障碍物,或是坦克显示爆炸
3. Powerup 增强宝贝类星星,加坦克,定时器等
4. Score 分数类。 击中坦克或是攻取增强宝贝,加分显示,分数有100,200,300,400,500,击中不同坦克分数不同。
为直观起见,参见下图,红圈里从上到下分别是Bullet, Powerup, Explosion, Score.
http://img.freeoz.org/ibbs/attachments/month_1009/20100910_e8aba645cdd8aa756475wo6546n2vvFu.png
子弹类,屏幕中所有显示子弹从一个子弹池BULLET_POOL中取出,子弹有方向,速度,及强度等属性,高强度的子弹可以击破石块。
它每个游戏帧所要完成的操作如下/**
* Operation be done in each tick.
*/
public void tick(){
if (!isVisible() || direction==BattleField.NONE)
return;
// Move the bullet.
move(dx, dy);
int x = getRefPixelX();
int y = getRefPixelY();
PlayerTank playerTank=(PlayerTank)Tank.getTank(0);
//outside the battle field, hitting the border
if (x <= 0 || x >= battleField.getWidth() || y <= 0
|| y >= battleField.getHeight()) {
//this is to avoid explosition outside the battlefield.
if(x<=0) x=0;
if(x >= battleField.getWidth()) x= battleField.getWidth();
if(y<=0) y=0;
if(y>= battleField.getHeight())y=battleField.getHeight();
setPosition(x,y);
explode();
return;
}
// See if it hit a tank.
if (friendly) {
// See if it hit an enemy tank.
for (int i = 1; i < Tank.POOL_SIZE; i++) {
EnemyTank enemy = (EnemyTank)Tank.getTank(i);
if (enemy!=null && enemy.isVisible() &&
collidesWith(enemy, false)) {
enemy.explode();
explode();
return;
}
}
} else {
// See if it hit player tank.
if (collidesWith(playerTank, false)) {
playerTank.explode();
explode();
return;
}
}
//check to see if hit player's home
if(Powerup.isHittingHome(this)){
//TODO: Game Over
explode();
return;
}
// See if it hit a wall.
if (battleField.hitWall(x, y, strength)) {
explode();
return;
}
// See if it hit another bullet.
for (int i = 0; i < POOL_SIZE; i++) {
Bullet anotherBullet=BULLET_POOL;
if(this!=anotherBullet && anotherBullet.isVisible()){
if (collidesWith(anotherBullet, false)) {
explode();
BULLET_POOL.explode();
return;
}
}
}
}要判断是否击中墙壁,对方坦克,或是对方子弹,是否击中“家”,如果有,则爆炸,如都没有,则同方向前行一步。
爆炸类,子弹击中障碍物(墙,子弹,坦克)时显示爆炸动画效果。它有两种一个是大爆炸,一个是小爆炸。
它每个游戏帧所要完成的操作比较简单,每步显示一个动画帧,直到显示完。/**
* Operation be done in each tick.
*/
public void tick() {
if (!isVisible())
return;
nextFrame();
if (getFrame() == 0){
setVisible(false);
}
}增强宝贝类,有多种,无敌,加坦克,地雷,定时器等。不同的增强宝贝可以使玩家获得不同的能力,玩过坦克大战游戏的人都比较熟悉。
在游戏进行中, 会不时或者当玩家打中红色坦克时,会有游戏中随机出现不同增强宝贝。
它每个游戏帧所要完成的操作如下:
如果玩家得到“无敌”增强功能时,“无敌”具有一定的时效性,需要判断无敌是否过时,其它时候则让该增强宝贝有闪烁效果,引起玩家注意。/**
* Operation be done in each tick.
*/
public void tick(){
if(type==NOTHING || !isVisible()) return;
long tickTime = System.currentTimeMillis();
long refreshPeriod=MILLIS_PER_TICK;
//invulnerable powerup is controlled by the player tank.
if(type!=INVULNERABLE &&type!=HOME && type!=HOME_DESTROYED){
if(tickTime-startTime>livePeriod){
setFrame(NOTHING);
setVisible(false);
return;
}
}else{
refreshPeriod=MILLIS_PER_TICK/10;
}
if(timeTaken>=refreshPeriod){
showNextFrame=!showNextFrame;
if(type==INVULNERABLE){
if(showNextFrame){
setFrame(0);
}else{
setFrame(1);
}
}else if(type==HOME || type==HOME_DESTROYED){
setFrame(type);
}else{
if(showNextFrame){
setFrame(type);
}else{
setFrame(NOTHING);
}
}
timeTaken = System.currentTimeMillis() - tickTime;
} else{
timeTaken+=1;
}
}最后一个是分数类,比较简单,它每个游戏帧所要完成的操作如下/**
* Operation be done in each tick.
*/
public void tick(){
if(isVisible()){
long tickTime = System.currentTimeMillis();
if(startTime>0){
if(tickTime-startTime>livePeriod){
setVisible(false);
startTime=0;
return;
}
}
}
}在屏幕上显示几秒种后消失。
[ 本帖最后由 trisun 于 10-9-2010 00:33 编辑 ]
Android坦克大战游戏设计解析七
本篇介绍坦克大战游戏中的主角,坦克类。游戏中坦克种类有多种,但主要特性大同小异。下图为游戏中定义的坦克类层次图。http://img.freeoz.org/ibbs/attachments/month_1009/20100911_ac82fcf9f11dfd22ba70kS5LxjZ9kjQB.png
Tank为所有坦克类的基类,它定义了几个主要的方法
think() 思考,如有AI,算法在这里实现,对于简单坦克SimpleTank,可能随机选择一步,而对SmartTank来说,向靠近玩家坦克的方向前进一步。
drive()根据Think决定前进一步
shoot() 根据当前条件决定发射一棵子弹。PlayerTank由玩家和可同时发射的子弹来控制,Enemy坦克一般随机控制是否要发射子弹。
基类每个游戏帧的操作如下:/**
* Operation be done in each tick.
*/
public void tick(){
if(isVisible()){
think();
drive();
shoot();
}
} 派生类中PlayerTank 和 SmartTank逻辑相对复杂一些,FastTank,和HeavyTank都是SimpleTank的子类,FastTank行驶速度较快,而HeavyTank可以承受多次子弹才会被击毁。
PlayerTank中需要处理玩家按键事件,用于控制上下左右以及发射子弹,还要处理升级功能,如吃到增加宝贝。它的
public void upgrade(Powerup powerup)用于处理升级功能。
而在SmartTank的Think方法,它要根据玩家坦克当前位置算出下一步的方向,以便可以不断向玩家坦克靠近,并发射子弹试图击毁玩家坦克。
这些坦克类都定义在om.pstreets.game.battlecity.actors.tank,代码中有较详细的注释,这里不详细一一说明了。
[ 本帖最后由 trisun 于 11-9-2010 00:39 编辑 ]
Android坦克大战游戏设计解析八
这是本系列最后一篇,最后就是将整个程序组成起来。坦克大战游戏中有六个用户界面:音效设置
开始界面
选择关卡界面
游戏主界面
分数界面
游戏结束界面
按照Android程序一般设计方法,一般一个界面对应一个Activity。这样就需要设计6个Activity子类对实现各个界面。
在移植的过程,这里采用了一个简单的方法,采用一个Activity对就于 Java ME中的Midlet。
主Activity采用FrameLayout
view plaincopy to clipboardprint?
01.<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
02. android:id="@+id/mainwindow"
03. android:layout_width="fill_parent"
04. android:layout_height="fill_parent"
05. >
06.lt;/FrameLayout>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mainwindow"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
</FrameLayout>
FrameLayout 可以将它其中的其它View象扑克牌一样叠放在一起,这样将六个界面都放在主Activity的FrameLayout中,开始将它们都设置为不可见,需要显示某个界面时,设为可见并放在最前面,也就实现了多个用户界面。
ResoureManager中setCurrentScreen
view plaincopy to clipboardprint?
01.public static void setCurrentScreen(View newScreen){
02. currentScreen.setVisibility(View.INVISIBLE);
03. currentScreen=newScreen;
04. currentScreen.setVisibility(View.VISIBLE);
05. theDisplay.bringChildToFront(currentScreen);
06. }
public static void setCurrentScreen(View newScreen){
currentScreen.setVisibility(View.INVISIBLE);
currentScreen=newScreen;
currentScreen.setVisibility(View.VISIBLE);
theDisplay.bringChildToFront(currentScreen);
}
就是用于屏幕切换。
另外,有于程序主要移植于JavaME,并且主要目的是为了了解Android 平台,和 JavaME版相比不够完善,但基本功能是实现了,如有兴趣的可以进一步完善
[ 本帖最后由 trisun 于 15-9-2010 00:38 编辑 ]
Android Battle city source code
Android 源码[ 本帖最后由 trisun 于 18-9-2010 18:33 编辑 ]
Java ME source code
Java ME source code[ 本帖最后由 trisun 于 15-9-2010 00:47 编辑 ] 好多的坑啊。。。
回复 #1 trisun 的帖子
.出门去户外玩不好么?为什么要在手机上打游戏呢?;P 原帖由 刘叔 于 16-8-2010 11:51 发表 http://www.freeoz.org/ibbs/images/common/back.gif
.
出门去户外玩不好么?为什么要在手机上打游戏呢?;P
带着手机出门去户外.... 然后掏出手机来玩游戏;P 经典游戏,呵呵~不过触摸屏的怎么打? 原帖由 8戒 于 16-8-2010 12:01 发表 http://www.freeoz.org/ibbs/images/common/back.gif
经典游戏,呵呵~不过触摸屏的怎么打?
还没试过,用gesture可以实现。不过触摸屏也开是可以实现发现建的。
[ 本帖最后由 trisun 于 16-8-2010 12:37 编辑 ] 不错,来学习 曾经每过年必打的游戏呀 童年经典!!!! 经典游戏重现,支持:) 楼主厉害
我也做Android,有兴趣的话可以上market搜索idea matters试下我的作品,呵呵。。。 原帖由 8戒 于 16-8-2010 10:01 发表 http://www.freeoz.org/ibbs/images/common/back.gif
经典游戏,呵呵~不过触摸屏的怎么打?
触摸屏更好控制;看了几个iPad上面的角色扮演游戏,控制界面做的更加友好。 好多坑啊...
支持支持 :lol :lol 支持支持!! 自己顶一下,已写好六篇,再有几个就写完了:lol :lol ,最后会附上源码。 正好在学android
呵呵 楼主很厉害啊 基本写完了,源码在9,10楼
另外由于程序主要移植于JavaME,并且主要目的是为了了解Android 平台,和 JavaME版相比不够完善,但基本功能是实现了,如有兴趣的可以进一步完善,可以叁考10楼Java ME的实现
回复 #26 trisun 的帖子
什么時候放到Market上?我体验一下:lol :lol或者把Apk文件放在这里下载也行。 原帖由 ubuntuhk 于 15-9-2010 01:44 发表 http://www.freeoz.org/ibbs/images/common/back.gif
什么時候放到Market上?我体验一下:lol :lol
或者把Apk文件放在这里下载也行。
放错代码了,两个都放了Java ME的 :lol
重新上传更新过了,Android 包里有 apk ,但没有用开发用的证书签名,不知道你能不能直接装,开发时是可以在手机上运行的。 感謝樓主 !!! ^___^ :good 楼主太有才了,敬仰:)
页:
[1]