arduino编程从零开始始Android游戏编程(第二版)源码

君,已阅读到文档的结尾了呢~~
广告剩余8秒
文档加载中
从零开始Android游戏编程(第二版)
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
从零开始Android游戏编程(第二版)
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer--144.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口1、广告,发现一律封IP;
2、水贴,酌情处理,从警告到封IP惩罚不等;
3、附件,有效附件(代码、书籍、资料等)酌情加分。
4、申精、求高亮、求置顶等请在发帖前注明如:《【申精】关于游戏编程的一些策略》
5、在此讨论内容请尽量和游戏编程相关,不然的话我们将会有一个漫长的移动帖子的过程……
祝各位交流愉快!
作者/回复/查看
站长提醒 /1
为了能给广大编程爱好者提供一个更好的学习交流平台,从即日起面向广大网友特举办《发原创得奖励》活动。Vip教程,驿站U盘,无线鼠标 免费送,礼品丰厚,赶快来参加吧!
VC驿站微信公众号cctry2009
Powered by Discuz! X3.3您所在的位置: &
从零开始23天完成一款Android游戏开发(一)
从零开始23天完成一款Android游戏开发(一)
bigosaur译
Part 1:我想开发一款 Android 游戏有一段时间了,但从来没有一个好的 idea。最近,我一直在玩一款跑酷游戏,发现它实在太有意思了。这款游戏也让我意识到,一款 Android 游戏没有必要非要有什么大的来头和复杂的游戏设置,简单随意就好。
1 & 开篇与前 2 天】
我想开发一款
Android 游戏有一段时间了,但从来没有一个好的
idea。最近,我一直在玩一款跑酷游戏,发现它实在太有意思了。通常来讲,我不喜欢没有终点的游戏,因为你不可能通关,所以每次我玩这些游戏的时候,我总会随意设置一些目标然后再去玩。这次我的目标是得到
倍分数复乘技能。当我实现这个目标的时候,我就获得一些技能然后就会迷上这款游戏。这款游戏也让我意识到,一款 Android
游戏没有必要非要有什么大的来头和复杂的游戏设置,简单随意就好。
不管怎样,我觉得一个游戏如果能做到仅需你将手指对准一个东西然后向它射击就很好了。如果再能有一个系统性的任务,每天每周需完成的挑战和一些武器升级的 话,那么这个游戏就会很有趣了。我的第一个想法是创立一款游戏,让一些可爱的小怪兽在一个美丽的场景中到处跑,可以藏在树后面,或者躲在老房子里,甚至可 以是在云朵里。你需要做的就是尽可能多地将它们打下。我说的可爱的小怪兽,指的是一些像
Gremlins(小精灵)之类的玩意。它们会搬一些体形巨大的机器,或者是做一些其他的愚蠢的事情来让你哈哈大笑。当然,作为一个拥有零预算的独立游戏 开发者,就按我可以想象到的动画复杂程度来看,我知道这些将需要投入大量的艺术设计和开发时间。所以我决定采用一种不同的设计,这样我可以在合理的时间内 自己完成。
我现在的目标是在一个月内开发一款有趣而可玩的
Android 游戏。
1 天:后院大恐慌
在逛动画素材网站的时候,我发现了一些给力又免费的僵尸动画。有僵尸走动、僵尸被枪击中之类的。所以,这可能是个类似于僵尸射手的游戏。
游戏角色会在他的走廊上,射杀从外面的麦田涌来的僵尸。游戏的名字就叫后院大恐慌。你可以转换不同的游戏角色,老奶奶、拿着猎枪的抠脚大汉或者是拿着远射程来复枪的大兵。下图是非常非常草的草图。
498)this.width=498;' onmousewheel = 'javascript:return big(this)' width="480" height="206" style="border-style: padding: 0 line-height: 1.5 margin: 0 display:" alt="" src="/wyfs01/M01/31/A3/wKioJlJyGG-jZwU0AAAg2nbdYVM487.jpg" />
更新:我刚才玩了会僵尸在美国。游戏倒是挺有意思,但是像疯子一样一直按射击多少有点无聊。我打算把后院大恐慌设计成一碰就死的模式,至少僵尸里不要有
boss。我仔细的想了想,僵尸主题对我来说有点太阴郁了,而且只要市面上有,这个类型就不稀罕了。所以,我不确定游戏会不会做成这个类型。另外,这个游 戏看起来会涉及到
3D 图形,不过我会坚持 2D,至少我的第一个安卓游戏会坚持。
2 天:安装&Eclipse,选择游戏库
我下载了安卓包,然后在
Linux 系统上安装了 Eclipse。 能在 Galaxy S2 手机上运行&Hello World&。 你好 Java。我真的得记住所有这些 Java
指令,因为从 2002 起,我就没用过这些玩意儿了。
498)this.width=498;' onmousewheel = 'javascript:return big(this)' width="480" height="220" style="border-style: padding: 0 line-height: 1.5 margin: 0 display:" alt="" src="/wyfs01/M00/31/A3/wKioJlJyGG-SA1itAABWKasWH0w521.jpg" />
2D/3D OpenGL 类的东西,似乎用工具包/库来搭建游戏会是一个好办法。我从 NordicGame2013 上弄到一些免费的
序列号,但是还没有在 Google Play 上发行的权限。所以我想我得暂时跳过 Unity 了。现在我正着手于
CoronaSDK 和一些其他的库。
翻译:bigosaur &
译文链接:
【编辑推荐】
【责任编辑: TEL:(010)】
关于&&&&的更多文章
一款《Flappy Bird》捧红了越南开发者阮哈东,引来无数关注。小
随着云计算、物联网、大数据、移动互联网的大发展,你应该知道这些。
手机游戏开发可以很简单,如Flappy Bird,一个人一杯
张小龙已经成为产品经理心中的神,无数人纷纷膜拜憧憬
国际消费类电子产品展览会(International Consumer E
本书是对Java EE各种技术之间互相协作的概览和补充。
本书还展示了如何编写JavaServer Page(JSP)页面或者企业级JavaBean(EJ
Windows Phone专家
Android开发专家
51CTO旗下网站gui205 的BLOG
用户名:gui205
访问量:406
注册日期:
阅读量:5863
阅读量:12276
阅读量:390997
阅读量:1081871
51CTO推荐博文
这本来是第十章,前面计划还有两章的内容,一是跟第四章一样,完成一个Asteroid游戏作为小结,总结一下前面讲过的Sprite的用法,并演示NPC和子弹的处理方法。但是,在写第七章的最后一个例子的时候,把本来简单的碰撞检测的例子扩充了一下,加入了NPC和子弹,基本和Asteroid的功能差不多了,所以就把原定的Asteroid砍掉了。另外一章是讲解程序的生命周期,内容相对简单,但考虑到上一章讲Sprite时已经引入了TiledLayer,如果接着讲地图应该会更连贯些,所以把生命周期向后移了一章。那么,就先让我们看看地图的设计和实现。如果我们需要的地图很小又很少,完全可以将整个地图画在一张图片上。但是如果地图很多,绘制和管理地图的工作就会很麻烦,这时我们就需要用到另外一种技术――图块(Tile)。所谓Tile,就是将地图中的公共元素提取出来,然后在显示的时候组合这些元素形成完整的地图,这就是本章要介绍的主要内容。如下图是组成坦克大战地图的所有元素(16x16像素):接下来让我们看一幅游戏中的场景:可以看到,整个游戏场景就是由上面那些Tile构成的。这样,摆在我们面前的任务就很简单了:将地图依照Tile的大小分成若干格,将对应的Tile填到格子中。在前面讲Sprite的时候,我们知道可以将组合在一张图片中的关键桢编号,以后就可以通过编号来使用这个桢(参看上一章桢动画的相关内容),这种方法也同样适用于Tile。而2D地图很容易让我们想到二维数组。也就是说我们可以将Tile的编号放到二维数组中,这样我们就可以通过历遍数组元素,像显示Sprite那样将整张地图一块一块的显示出来。以上面的那张游戏截图为例,一共13行13列,我们可以定义一个13x13的二维数组(因为地图上有空白区域,所以我们将Tile的编号从1开始,用0表示空白)。让我们找到GameView_Old.java,增加成员变量map[][]:int[][] map = {{0,0,0,2,0,0,0,2,0,0,0,0,0},{0,1,0,2,0,0,0,1,0,1,0,1,0},{0,1,0,0,0,0,1,1,0,1,2,1,0},{0,0,0,1,0,0,0,0,0,2,0,0,0},{3,0,0,1,0,0,2,0,0,1,3,1,2},{3,3,0,0,0,1,0,0,2,0,3,0,0},{0,1,1,1,3,3,3,2,0,0,3,1,0},{0,0,0,2,3,1,0,1,0,1,0,1,0},{2,1,0,2,0,1,0,1,0,0,0,1,0},{0,1,0,1,0,1,1,1,0,1,2,1,0},{0,1,0,1,0,1,1,1,0,0,0,0,0},{0,1,0,0,0,1,1,1,0,1,0,1,0},{0,1,0,1,0,1,6,1,0,1,1,1,0},};在资源中增加tile.png在构造函数中初始化bitmap对象res = context.getResources();bmp = BitmapFactory.decodeResource(res, R.drawable.tile);在onDraw中绘图//用来显示图块的Rect对象Rect src=\'#\'" >new&Rect(0, 0, 0, 16);Rect dst =&new&Rect();for(int&i=0; i&13; i++) {for(int&j=0; j&13; j++) {//根据Tile的编号得到对应的位置src.left = (map[i][j]-1) * 16;src.right = src.left + 16;//根据地图上的编号计算对应的屏幕位置dst.left = j * 16;dst.right = dst.left + 16;dst.top = i * 16;dst.bottom = dst.top + 16;canvas.drawBitmap(bmp, src, dst, paint);}}最后不要忘了修改Main.java中的setContentViewGameView_Old gameV/** Called when the activity is first created. */@Overridepublic&void&onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);gameView =&new&GameView_Old(this);setContentView(gameView);}好了,运行一下程序看看结果:对比一下原图,除了基地四周的砖块之外两者并无二致,可以说我们的Tile地图实践基本成功。现在我们知道了使用Tile显示地图的原理,实际上,我们不需要每次都很麻烦的写那么多代码,还记得前面说过的TiledLayer么?其中早已封装了上述操作。不仅如此,TiledLayer还能显示动态的地图呢。下面就让我们看一看TiledLayer的基本用法。其实,它与Sprite的用法非常相似(我们需要将TiledLayer.java加入到项目中,请使用本章附带程序的TiledLayer.java文件,上一章的TiledLayer并不能正确工作):这次让我们使用GameView,把刚刚的数组map拷贝到GameView中,并声明一个TiledLayer类型变量//背景TiledLayer backG在构造函数中初始化TiledLayer// 背景图backGround =&new&TiledLayer(13, 13, BitmapFactory.decodeResource(res,R.drawable.tile), 16, 16);TiledLayer的构造函数有5个参数,分别是地图的行列数(是以Tile为单位的),包含Tile的bitmap对象,Tile的宽度和高度。通过setCell方法将定义在数组中的Tile编号传递给TiledLayer。for(int&i=0; i&13; i++) {for(int&j=0; j&13; j++) {backGround.setCell(i, j, map[i][j]);}}最后,只需要在run函数中调用paint方法,就可以将TiledLayer显示出来了。当然,你可以像控制Sprite那样控制TiledLayer显示的位置。backGround.paint(c);让我们看一下运行的效果下面让我们来学习如何实现动态地图。所谓动态地图跟前面讲到的桢动画是一个道理,就是循环显示几个关键桢。让我们看一下前面Tiles的图片我们会发现有两张水域的图片,这就是为动态地图准备的,组合起来之后应该会有如下的效果:那么,我们如何在TiledLayer中实现动态地图呢?TiledLayer为我们准备了这样几个函数:createAnimatedTile:创建动态图块。很多人会迷惑于这个函数的名字,说是创建动态图块,可是创建在哪儿啊?创建出来怎么用呢?只有天知道。其实,这个函数的主要功能也就是为动态图块分配了一个存储结构。你不调用它还会报错,调用了其实也没什么用。createAnimatedTile返回一个动态图块的编号,从-1开始依次递减,第一次调用返回-1,这样就分配了一个编号为-1的动态图块。第二次调用会返回-2,依次类推。这个返回值一般没有用,因为我们做地图的时候肯定已经确定了动态图块的位置,这个编号早就写到了数组中了。以后你就可以通过这个编号来控制相应的图块。函数有一个参数,指定一个Tile的编号,动态图块最初显示的就是这个Tile。而正是通过改变这个Tile来实现动画的。请看下面代码:backGround.createAnimatedTile(4);我们初始化了一个动态图块,编号是-1,参数4表示当前显示Tile序列图中的第四个Tile,就是第一张水域的图片。setAnimatedTile:动态图块的内容就是使用这个函数改变的。函数的第一个参数是动态图块的编号,如刚刚的-1。第二个参数是Tile的编号。说到这里,大家应该清楚动态地图的用法了吧:首先在地图数组中确定需要显示动态图块的位置,填入相应的编号,例如我们将上一张地图的第三行增加三块水域int[][] map = {{0,0,0,2,0,0,0,2,0,0,0,0,0},{0,1,0,2,0,0,0,1,0,1,0,1,0},{0,1,-1,-1,-1,0,1,1,0,1,2,1,0},{0,0,0,1,0,0,0,0,0,2,0,0,0},{3,0,0,1,0,0,2,0,0,1,3,1,2},{3,3,0,0,0,1,0,0,2,0,3,0,0},{0,1,1,1,3,3,3,2,0,0,3,1,0},{0,0,0,2,3,1,0,1,0,1,0,1,0},{2,1,0,2,0,1,0,1,0,0,0,1,0},{0,1,0,1,0,1,1,1,0,1,2,1,0},{0,1,0,1,0,1,1,1,0,0,0,0,0},{0,1,0,0,0,1,1,1,0,1,0,1,0},{0,1,0,1,0,1,6,1,0,1,1,1,0},};然后在GameView的构造函数中初始化TiledLayer,除了在setCell之前调用createAnimatedTile之外,没有其他区别。最后就是在run函数中调用setAnimatedTile,不断地改变图块了if(backGround.getAnimatedTile(-1) == 4) {backGround.setAnimatedTile(-1, 5);}&else&{backGround.setAnimatedTile(-1, 4);}backGround.paint(c);来让我们看一下运行的效果其实笔者觉得TiledLayer完全也可以像Sprite那样使用桢序列和nextFrame来实现动态效果,似乎更易用一些,有兴趣的读者可以自己修改TiledLayer实现这个功能。到这里,我们已经掌握了显示地图的方法,但是,这个地图还不能真正运用到我们的游戏中。读者肯定也看到了,在TiledLayer的第一个例子中,我们的坦克可以穿墙而过,显然,这个地图还缺少最基本的功能――阻挡。有一种简单的方案可以实现阻挡,让我们看一下Sprite类,其中有一个方法:public&final&boolean&collidesWith(TiledLayer t,&boolean&pixelLevel)检测Sprite与TiledLayer的碰撞。这种检测是以Tile为单位的,当与Sprite重合的Tiles编号不为0时函数返回true,否则返回false。下面让我们做一个小例子测试一下:打开GameView_Old,增加一个Sprite类型的成员变量// 主角S在构造函数中初始化player// 初始化主角player =&new&Sprite(BitmapFactory.decodeResource(res,R.drawable.player1), 16, 16);player.setFrameSequence(new&int[] { 0, 1 });在onDraw中绘制playerplayer.paint(c);backGround.paint(c);在onKeyDown中控制Sprite的运动@Overridepublic&boolean&onKeyDown(int&keyCode, KeyEvent event) {//&TODO&Auto-generated method stubswitch&(keyCode) {case&KeyEvent.KEYCODE_DPAD_UP:x = player.getX();y = player.getY();player.move(0, -16);if(!player.collidesWith(backGround,&false)) {y -= 16;}player.setTransform(Sprite.TRANS_NONE);player.setPosition(x, y);break;case&KeyEvent.KEYCODE_DPAD_DOWN:x = player.getX();y = player.getY();player.move(0, 16);if(!player.collidesWith(backGround,&false)) {y += 16;}player.setTransform(Sprite.TRANS_ROT180);player.setPosition(x, y);break;case&KeyEvent.KEYCODE_DPAD_LEFT:x = player.getX();y = player.getY();player.move(-16, 0);if(!player.collidesWith(backGround,&false)) {x -= 16;}player.setTransform(Sprite.TRANS_ROT270);player.setPosition(x, y);break;case&KeyEvent.KEYCODE_DPAD_RIGHT:x = player.getX();y = player.getY();player.move(16, 0);if(!player.collidesWith(backGround,&false)) {x += 16;}player.setTransform(Sprite.TRANS_ROT90);player.setPosition(x, y);break;}postInvalidate(); // 通知系统刷新屏幕return&super.onKeyDown(keyCode, event);}可以看到,坦克只能在空白区域运动,这回不能上墙了。但是这种方法还是比较粗糙的,很多时候不能实现我们的目的,比如坦克大战中,水和砖头是坦克不能通过的,但是掩体是可以通过的,还有子弹可以通过水域,这时候还是检测Tile的编号来的准确些。就是说,我们事先确定好那些编号的Tile可以通过,哪些不能。然后模仿collidesWith方法根据Tank的位置取得它下一步要到达的Tile的编号,并判断坦克是否被阻挡。让我们用这个方案重写onKeyDown方法(为了简化教程,我们假设每次player和tile都是完全重合的):首先我们先定义一个函数用来判断Tank是否可以通过// 判断坦克是否可以通过private&boolean&tankPass(int&x,&int&y) {// 不超过地图范围if&(x & 0 || x & 12 * 16 || y & 0 || y & 12 * 16) {return&false;}int&tid = map[y / 16][x / 16];if&(tid == 1 || tid == 2 || tid == -1)return&false;return&true;}然后在onKeyDown中运用新的方案@Overridepublic&boolean&onKeyDown(int&keyCode, KeyEvent event) {//&TODO&Auto-generated method stubswitch&(keyCode) {case&KeyEvent.KEYCODE_DPAD_UP:x = player.getX();y = player.getY();player.move(0, -16);if&(tankPass(player.getX(), player.getY())) {y -= 16;}player.setTransform(Sprite.TRANS_NONE);player.setPosition(x, y);break;case&KeyEvent.KEYCODE_DPAD_DOWN:x = player.getX();y = player.getY();player.move(0, 16);if&(tankPass(player.getX(), player.getY())) {y += 16;}player.setTransform(Sprite.TRANS_ROT180);player.setPosition(x, y);break;case&KeyEvent.KEYCODE_DPAD_LEFT:x = player.getX();y = player.getY();player.move(-16, 0);if&(tankPass(player.getX(), player.getY())) {x -= 16;}player.setTransform(Sprite.TRANS_ROT270);player.setPosition(x, y);break;case&KeyEvent.KEYCODE_DPAD_RIGHT:x = player.getX();y = player.getY();player.move(16, 0);if&(tankPass(player.getX(), player.getY())) {x += 16;}player.setTransform(Sprite.TRANS_ROT90);player.setPosition(x, y);break;}postInvalidate(); // 通知系统刷新屏幕return&super.onKeyDown(keyCode, event);}现在让我们运行一下看看吧,这回终于能够达到了我们想要的效果,我们的坦克正藏在掩体下面,并且它不能通过墙和水域。到此为止,关于地图的内容就讲解完毕了。这些内容并不复杂,首先介绍了使用Tile组成地图的原理,然后介绍了TiledLayer已经动态地图,最后演示了阻挡的实现方法。本章的大部分例子使用了GameView_Old,并没有使用游戏循环,也没有涉及到地图的平滑滚动,在以后需要的时候会补充这部分知识。本章示例程序
了这篇文章
类别:未分类┆阅读(0)┆评论(0)}

我要回帖

更多关于 从零开始学linux编程 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信