Cocos2d:使用 CCCamera 做滚动效果 (Four Ways of Scrolling wi
原文:http://www.koboldtouch.com/display/IDCAR/Four+Ways+of+Scrolling+with+Cocos2D
There are two classes of scrolling,"fake" and "real". Altogether there are four ways to create a scrolling view in Cocos2D: with CCCamera,with CCFollow,manually moving a layer and "faking it". I'll discuss each approach and show their advantages and disadvantages as well as point out for which types of games they work best. The example projects for this article can bedownloaded from github. Fake Scrolling - Merely creating the Illusion of ScrollingIdeal for "endless scrolling" games. Typical genres include jumping or running games like Doodle Jump and Canabalt,as well as shoot'em ups. These games mainly scroll along one axis,often scrolling only in one direction. The other axis has a limited range or is not scrolled at all. The fake scrolling approach prevents the coordinates of game objects to "explode" to similarly infinite coordinate points. This could introduce rounding errors in floating point values which may accumulate over time,causing inaccuracies at later stages of the game. To create the illusion of scrolling,at least two background image sprites are needed. Four are needed if you also want to scroll a little along the minor scrolling axis. The background images must be repeating seamlessly,and each must be at least the size of the screen. The trick is to use the two or four images and move them in the opposite direction of where the player is supposedly heading. This creates the illusion that the player is actually moving in a certain direction. Once one background image has scrolled entirely outside the view,it will be repositioned by adding the width or height of the screen(depending on major scrolling axis) to the position of all background sprites. The player does not notice this repositioning,which allows the background sprites to continue moving in the current direction seemingly endlessly. Game objects (enemies,items,etc.) usually enter the screen from the side towards which the player is moving,but any location is possible. You would normally spawn these objects one screen ahead (or behind) what is currently visible,then move them on screen. Movement of enemies can be fixed if the scrolling occurs at a constant rate and never stops. Otherwise all game object's positions must be updated with the delta scroll value every time to keep them fixed at their current position. You would do this at a central location before or after moving the game objects. Without this,varying the scrolling speed would also speed up or slow down the movement of game objects,which is probably not what you want. This voids the use of CCMove* actions because they don't consider external modification of the position property while they're running. From a game construction perspective this type of scrolling lends itself well for randomly generated worlds. You can alway use a certain location in front of or behind the scrolling direction to spawn new game objects. You always have only a relatively short list of game objects that are alive in this "world",so each object can be allowed to run relatively complex code. And you can dismiss game objects easily by checking if they have moved past the threshold location. All coordinates are relative to screen coordinates,so at most you're dealing with a value range 3 times that the size or width of the screen (one screen ahead,one screen behind,and the actual screen - more if you allow scrolling along both axes). Using object pooling you can reuse a predetermined amount of game objects of a certain type and thus also avoid spawning too many of the same type. For example if there can be 10 Zombies on the screen at once,you'd create 10 Zombies up front,set them to inactive and simply reposition and activate them to spawn one. When you have 10 Zombies on the screen and game logic dictates to spawn another one,you can't and no new Zombie gets spawned. This design lends itself well to high performance and has built-in limits that avoid many (but not all) possibly unfair game situations that can occur in randomly generated worlds. Code Example:The scrolling effect is created by moving the background images. This example uses two images moving from right to left,to give the impression of movement from left to right. You can also put the background images into a separate layer and move them all at once by adjusting the layer's position. Use when:
Avoid when:
All objects use relative screen coordinates,easy to work with. No "explosion" of coordinate values in infinitely scrolling worlds. Code complexity increases if direction of scrolling can go both ways (ie rightandleft,or upanddown) or allows scrolling at variable speed. CCMove* actions can not be used in these cases. "Real" Scrolling - Using the Screen as View onto the WorldIdeal for larger worlds. The player can travel freely in all four directions at any speed. Typical examples include games where the player traverses large worlds,for example Zelda or Super Mario. You can scroll a world either by using CCCamera or my adjusting the position of a parent node. The CCFollow method falls into the latter category. The main difference between CCCamera and CCFollow or layer movement is that CCCamera moves the viewport over the fixed (non-moving) world whereas CCFollow or layer movement move the world underneath the fixed camera. The end result is the same. Scrolling with CCCameraCCCamera is a wrapper for the OpenGL gluLookAt function. It has the most flexibility allowing free rotating,zoom and even perspective views. But it's also more difficult to work with and not fully compatible with all aspects of cocos2d. CCMenu won't work,and converting touch coordinates will be a challenge. The biggest problem of CCCamera is probably that there's a serious lack of expertise - there are many CCCamera related questions on the cocos2d forum and in other places,but hardly any good answers. Most questions simply remain unanswered.CCCamera works differently than anything else in cocos2d,and affects cocos2d rendering in ways you may not understand or foresee.Therefore I strongly discourage anyone from using CCCamera unless that anyone is familiar with OpenGL viewport basics,gluLookAt andtransformation matrices (conversion of screen to view coordinates). Even if you do know about these things,use CCCamera only when you need the full flexibility of a zooming,rotating or perspective camera view. For example if you want a driving game which should keep the car always facing up,rotating the world relative to where the car is going,then you'd have to use the CCCamera. Implementing this with layer movement will be more difficult and certainly requires a different approach to how the car movement is handled (the car would actually never rotate by itself,and would always face in a fixed direction). You first need to get all the camera values by reference (¢erX) in C programming language fashion. Then you need to update both center and eye to be at the same position in order to maintain an orthogonal (top down) view. Introducing 3D effects is as simple as allowing center and eye to deviate. Then you must set all values back to the camera,including those you haven't modified to ensure you don't accidentally change one of the values you didn't modify.For example,if you hard code the value 0.0 when setting centerZ and eyeZ,for some reason the screen goes black even though the values for centerZ and eyeZ returned from CCCamera are 0.0 as well. This is just one of the oddities of CCCamera. Scroll in any direction. CCCamera is not well documented or tutorialized. It's also rarely used so it's hard to get (good) answers to CCCamera related questions. Many issues require a deeper understanding of OpenGL. Scrolling with CCFollowCCFollow works by changing the position of the node that is running the CCFollow action relative to the position of the followed node. Typically you'll run it on the layer that contains the node (usually the player-controlled object) to be followed. CCFollow should only run on non-drawing nodes (CCNode,CCLayer,CCScene) and should follow a node that is one of its direct children. Especially if the followed node is not a direct children you might notice that the screen follows the object but it does so at an offset. CCFollow is the easiest way to create a scrolling view,but it's also the least flexible. You can choose between limitless scrolling,or scrolling that stops at predefined (world) boundaries. That is all. For everything else you'll have to subclass CCFollow and add whatever code you need to improve the scrolling behavior. CCFollow requires the least amount of code to implement scrolling. Just add this code in init or onEnter to allow the layer (self) to scroll so that the followed node (_player) is always centered on screen. Additionally this code enables the world boundaries check so that scrolling stops before any part outside of the world becomes visible. The player is still able to move up to the world border,or even beyond that if you don't limit the player's movement as well.
Scroll in any direction. No control whatsoever. Follow speed,follow range,acceleration/deceleration of scrolling movement,prevent scrolling in a particular direction,and so on - none of that is supported. Custom Scrolling by subclassing CCFollowThis is essentially the same method that CCFollow uses,but you will have to implement any additional behavior yourself. Typically you will want to subclass CCFollow because that'll be easier,but you can also rip out the guts of CCFollow and put the scrolling code in your layer's update method. For example if you want the scrolling to happen only when the followed node is getting close enough to one of the screen borders,you'd have to subclass CCFollow,override the step method,put the original code back in and then start modifying how CCFollow updates the position. An example is given in the CCCustomFollow demo. The main downside caused by moving an underlying layer is that the position of that layer is the inverse of the actual movement.For example to scroll 100 pixels to the right,you have to subtract 100 pixels from the layer's position,which then may have a negative position of -100. You might find it counterintuitive that the targetPos CGPoint in CCFollow uses mostly negative coordinates - because to scroll to the right and up,the target node (usually the layer) must move in the opposite direction,to the left and down. First create a subclass of CCFollow,in this case I named it CCCustomFollow. Initialize it like CCFollow above,and override the step method in CCCustomFollow. You can start with the CCFollow code as basis,understand it first,then start modifying it.This example prevents scrolling while the followed node is within 120 points of the center. Once the followed node crosses that distance,the scrolling will start following the followed node. This is a very simplified example of "border scrolling". You still need to improve this in several ways,for example to ensure that the scrolling correctly stops at world boundaries and perhaps to improve it so that the non-scrolling area is not a circle but a rectangle. You might also attempt to scroll faster when the followed node leaves the threshold so that the followed node becomes centered on the screen again. All of those tasks aren't exactly trivial,but they're manageable if you have a reasonably solid understanding of trigonometry. Scroll in any direction. Do it yourself,but youcan use the CCFollow code as basis.Here's anothergood starting pointbut the code has "All Rights Reserved". (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- iOS 正则表达式判断纯数字及匹配11位手机号码的方法
- ruby-on-rails – 我的/ public目录可以是rails 3 passenge
- ruby-on-rails – 作业无法加载:“@”不允许作为实例变量名
- Oracle总结【视图、索引、事务、用户权限、批量操作】
- cocos2dx 利用随机数模拟雪花飘落、粒子系统
- wpf – 使用具有FormattedText的TextOptions.TextFormattin
- reactjs – React-Native按钮对齐中心
- c – 非类型模板参数的隐式转换是如何工作的?
- c# – Visual Studio 2017测试资源管理器特征发现:显示超过
- c – 创建一个排序向量的向量