为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

第十一章 演员(Actor)、视口(ViewWindow),演出开始

2018-09-11 7页 doc 58KB 9阅读

用户头像

is_593420

暂无简介

举报
第十一章 演员(Actor)、视口(ViewWindow),演出开始从零开始Android游戏编程(第二版) 第十一章 演员(Actor)、视口(ViewWindow),演出开始 收藏 第十一章 演员(Actor)、视口(ViewWindow),演出开始 本章内容与第七章、第八章关系非常密切,如果对这两章的内容不熟悉请大家先浏览一下七、八章,再回来看本章。 Actor 是一个接口,他的作用是统一类的行为(读者可以阅读一下Facede模式相关文章)。我们用一个比喻来说明:演员们有了各自的剧本,导演对所有演员说:做 下一个动作!演员们就会各自行动。而不用导演分别告诉每个人,你要这样做,他要那样做...
第十一章 演员(Actor)、视口(ViewWindow),演出开始
从零开始Android游戏编程(第二版) 第十一章 演员(Actor)、视口(ViewWindow),演出开始 收藏 第十一章 演员(Actor)、视口(ViewWindow),演出开始 本章内容与第七章、第八章关系非常密切,如果对这两章的内容不熟悉请大家先浏览一下七、八章,再回来看本章。 Actor 是一个接口,他的作用是统一类的行为(读者可以阅读一下Facede模式相关文章)。我们用一个比喻来说明:演员们有了各自的剧本,导演对所有演员说:做 下一个动作!演员们就会各自行动。而不用导演分别告诉每个人,你要这样做,他要那样做。具体到程序中,帧动画、动态图块两种操作会调用完全不同的函数,这 样不利于在游戏循环中做出一致的处理。所以我们让他们都实现Actor接口,只要调用接口定义的函数,他们就会做出各自的动作。Actor接口的定义很简 单: public interface Actor { public void tick(); } 对于实现了Actor接口的任何类型,发出的指令就只有一个:tick。 下面请看实例演示: 我们将创建两个类Tank和Map,分别继承自Sprite和TiledLayer,都实现Actor接口。为tank创建帧动画,为Map创建动态图块,然后将他们显示在SceneMain中。 首先,我们可以复制第十章的例子创建一个新项目,并将第八章中用到的org.yexing.android.games.common包拷贝到项目中。 创建一个Tank类,继承自Sprite,实现Actor接口。 在tick函数中播放帧动画 public void tick() { // TODO Auto-generated method stub nextFrame(); } 然后创建一个Map类继承自TiledLayer,实现Actor接口。 在tick函数中播放动态图块 public void tick() { // TODO Auto-generated method stub if (getAnimatedTile(-1) == 4) { setAnimatedTile(-1, 5); } else { setAnimatedTile(-1, 4); } } 最后在SceneMain中创建这两个类的实例并显示他们 Layer layers[] = new Layer[2]; int mapdate[][] = { { 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, 0, 0, 0, 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 }, }; public SceneMain() { paint = new Paint(); paint.setColor(Color.WHITE); paint.setTextAlign(Align.CENTER); Bitmap bmpTank = BitmapFactory.decodeFile("/sdcard/player1.png"); Bitmap bmpTile = BitmapFactory.decodeFile("/sdcard/tile.png"); Tank tank = new Tank(bmpTank, 32, 32); tank.setFrameSequence(new int[]{0, 1}); Map map = new Map(13, 13, bmpTile, 32, 32); map.createAnimatedTile(4); for(int y=0; y<13; y++) { for(int x=0; x<13; x++) { map.setCell(y, x, mapdate[x][y]); } } layers[0] = map; layers[1] = tank; } @Override public void update(Canvas c) { // TODO Auto-generated method stub c.drawARGB(255, 0, 0, 0); c.drawText("SceneMain", GameView.width/2, GameView.height/2, paint); for(int i=0; i<2; i++) { ((Actor)layers[i]).tick(); layers[i].paint(c); } } 需要读者关注的就是update方法中对tick的调用。运行程序,我们可以看到动画的效果。 还需要注意一点,我们将位图文件放置在了sdcard的根目录。读者可以在项目的res/drawable下找到这两个文件,自行push到sdcard中。 下 面再来看ViewWindow。我们可以将它理解成舞台的前台,或者相机的取景器。演员只有走到前台,观众才能看得见。而演员走下台,就从观众视线消失。 通常,屏幕就是一个视口,因为无论如何我们也看不到屏幕之外的东西。而有时候,我们需要更小的视口,局部的变化,就需要自行定义视口了。其实,视口的功能 我们已经实现了,他就在LayerManager中,只是我们前面没有用到也就没有做介绍。 下面就先让我们来了解一下 LayerManager的功能。我们知道Sprite、TiledLayer都是继承自Layer,那么LayerManager,顾名思义,就是用来 管理Layer的。具体说是管理Layer的显示的。要使用LayerManager,我们首先调用函数append()或insert()将Layer 加入到LayerManager中,就如我们将纸张放入文件夹一样,然后调用paint就可以将所有Layer一次显示出来。Layer有一个属性:z, 表示Layer的Z坐标,如图: Z坐标从屏幕内指向屏幕外,也就是说Z坐标越大离用户越近,前面的Layer会遮住后面的Layer。 我们改写前面的程序,用LayerManager代替Layer数组 public SceneMain() { super(); …… layerManager.append(map); layerManager.insert(tank, 100); …… public void update(Canvas c) { …… for(int i=0; i<="" p=""> ((Actor)layerManager.getLayerAt(i)).tick(); } layerManager.paint(c, 0, 0); } 熟悉了LayerManager之后就让我们来学习视口。我们可以将Layer想像成一张张非常大的画布,他们被放在LayerManager这个容器中,视口就是在容器上开一个小窗户,使用户只能看到窗口那一部分,其余的区域都不可见。 让我们看一下LayerManager的构造函数 public LayerManager() { setViewWindow(0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE); } 我们可以看到在这里,已经定义了一个视口。这个视口非常大,可以想象他与Layer一般大,所以我们看不到他的效果。但是如果我们把视口缩小呢? public void update(Canvas c) { …… layerManager.setViewWindow(0, 0, 100, 100); layerManager.paint(c, 0, 0); } 运行程序,可以看到只有视口内的部分被显示了出来。 ViewWindow的难点在坐标。让我们回头看 layerManager.setViewWindow(x, y, width, height); layerManager.paint(c, x, y); 这 两个函数都用到了坐标,他们有着完全不同的含义。首先看paint,其中的x,y表示视口的左上角相对于屏幕的坐标。我们前面说过,视口可以理解为 LayerManager上的窗口,改变这个坐标,整个LayerManager就会跟着一起移动。让我们修改程序,将视口显示在(100,100)的位 置 layerManager.paint(c, 100, 100); 可以看到,所有Layer的左上角都移动到了(100,100)的位置。 再来看setViewWindow,其中的x,y表示视口相对于Layer左上角的坐标,让我们修改他们的数值,看看效果。 layerManager.setViewWindow(50, 50, 100, 100); 可以看到,左上角的坦克不见了。 合理的运用setViewWindow可以很方便的实现滚屏效果。
/
本文档为【第十一章 演员(Actor)、视口(ViewWindow),演出开始】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索