昨天在编译以前的代码的时候发现Stage类发生了变化,编译出错。Stage 开始使用viewpoint来初始化。
viewpoint是什么?
现在用个简单的方法来理解。
举起双手,两手食指和拇指圈一个类似的矩形,然后我们通过手指的这个矩形看我们的电脑屏幕。看到一小块地方是吗。
眼睛-->手指组成的矩形-->屏幕
眼睛是一个点,手指组成的矩形稍微大点,屏幕最大,这是不是一个类似金字塔样的锥形视角。
我们把手指组成的这个小矩形称为viewpoint,实际上屏幕也是个viewpoint。
通过手指的矩形看到的图像实际大小肯定远大于手指组成的矩形的大小。距离越远看到的越广,物体也越小。距离越近看到的越少,物体也就越大。我们把手指组成的矩阵看到的这部分投影到手机屏幕上,这就是手机屏幕显示的内容了。
然后介绍下正交相机,它就是我们上面说的那种情况的一种特殊情况,眼睛的视线不是随着距离增加不断变大的一个锥形视野,而是平行的。
可以想象一下我们的太阳,无限远。它发出的光我们近似认为是平行的。也就是说。距离再远视野也不会变大,物体也不会变小。所以正交相机一般用在二维游戏中。
想想我前面做的那些工作,把屏幕划分成10*6的方格,然后计算每个方格的像素大小。我突然发现,使用正交相机也是可以实现的
我们直接把10*6的正交相机的viewpoint投射到屏幕上不就是可以了。还省的计算了。
修改前面的GirlView代码:
很简单,定义一个正交相机,然后初始化。投影到屏幕的矩阵。
设置为10*6大小,位置在中间。最后那个0其实是三维中z轴。咱是二维的。
然后在spriteBatch begin之前插入
Ok,搞定。渲染方法也不用根据像素进行相乘计算了。好happy。
其实这只是个简单的相机的应用,例如天天酷跑的背景的移动,人物的放大缩小,都可以使用相机实现。具体可参考官方API和这篇介绍相机的文章。还不理解的可以去看看。
http://blog.sina.com.cn/s/blog_940dd50a0101cpnb.html
在正式开始之前先复习下中学物理知识,真是苦逼,都忘光了。我发现除了基本的加减乘除,和一次元运算,别的基本都还给老师了。物理数学完全没印象了。这对游戏开发来说无疑是个大坑啊。和我一样的同学来以前复习中学知识。这都是为了模拟出比较真实的游戏感觉。
游戏中的匀加速运动:
初速度不为0的情况:Vt=Vo+a*t (Vt为末速度,Vo为初速度,*为乘号,a为加速度)
初速度为0:Vt=a*t
再看看游戏中的跳跃动作。起跳的时候我们可以给它一个初速度Vo,受重力影响,达到最高点后开始回落。这里我们只需要第一个公式就可以了,具体后边要用到的物理知识和向量几何知识只能边学边写了。 :wink:
先修改GirlActor类。有两个地方需要修改。我们要增加一个加速度的属性。
还要修改下update方法
修改update
多了个cpy,其实就是返回一个新的对象,不对原来对象进行修改。
原来我么直接使用velocity.scl(deltatime)
这会改变velocity的值。上面的公式中,我们每刷新一次屏幕,就要获取现在的速度做为初始速度Vo计算下次的Vt,下次的Vt作为下下次的Vo,所以为了不修改这个变量的值,使用cpy方法new个新的。
上篇我们使用枚举类型定义按键状态,后来我发现这么做不怎么合适。
因为普遍我们的输入不是单点输入的,可能会同时按下几个按键,所以我们略微变通下,让控制可以支持多按键。
修改GirlControl
我在world中定义了一个静态的重力变量GRAVITY,设置为-18。
这样在上升中girlActor的初始速度 private float speed_y = 10f;会不断减少,然后变成负值,直到落回地面。然后我们判断演员的位置的Y的值是否小于0来判断是否落地。并改变演员状态为站立状态。
[size=x-large][color=red]重点代码的含义。[/color][/size]
girl.getVelocity().add(girl.getAcceleration().cpy().scl(Gdx.graphics.getDeltaTime()));
这里我们为了理解,我把这段代码拆分开
这样就好理解了。我们这里也使用了cpy,所以acceleration的值不会因为运算发生变化,那么我们每次也不用重新赋值给它。这和演员类中的update方法中的修改是一样的道理。
处理下mygame的按键的操作。
点击屏幕上半部分就是跳起操作。
需要注意的就一点。screenX,screenY是以屏幕左上角为原点的,这和android的坐标系相同。
源码
指明左上角开始的。
接下来实现下演员的飞行,其实这里不能算飞行,相当于扔东西的感觉,把演员抛出去。抛物线运动,实现非常简单。
前几篇有提到使用屏幕的手势操作,因为当时用不到所以现在我们实现下手势操作。
修改Mygame实现GestureDetector.GestureListener
修改下输入监听的注册
这里使用到了InputMultiplexer,很好理解,可以监听多个进程的输入事件。
因为 GestureDetector 没有touchUp这些操作,所以我们保留InputProcessor
并且同时监听这两个输入进程。
接下来实现GestureDetector.GestureListener的方法,我们现在只实现它的fling方法
顾名思义:滑动操作,它实际上返回的是一个速度向量,也就是我们滑动的速度和方向的这样一个向量。想一想,把它和演员的位置信息的向量进行加运算就可以了。
修改下控制类
增加了滑动的按键状态。
这里为了方便简单,直接设置为跳起状态,让它受跳动作重力影响。当然可以自己定义一个飞行的状态。
好了,轻轻滑动下屏幕,演员被扔飞了。别滑动太大,因为我们判断按键状态是把屏幕分成了左右和上下几部分,小范围的滑动就可以了。如果从左边滑到右边演员状态会出现异常。
源码地址:http://pan.baidu.com/s/1mgM9QdU