In cocos2dx, the horizontal version of the game sorts out how cameras move

Source: Internet
Author: User

In cocos2dx, the horizontal version of the game sorts out how cameras move

When playing a horizontal version game, it is inevitable to use the camera to move, and generally in a 2D horizontal version game to simulate some 3D effects, the method of stratified movement is used (that is, the moving speed of each layer is different, to simulate the slow moving of objects in 3D.

In cocos2d, parallaxNode is provided to achieve different levels of moving speed. This node sets a moving scale for the added object to control its moving speed. The principle is that when the location is set for parallaxNode, parallaxNode will adjust the moving speed ratio of its child nodes, you can reset its subnodes to their locations to achieve different speeds for different nodes. For example, parallaxNode has two subnodes, with the moving speed ratio of 1 and 0.5 respectively, and the initial position is 0. When we move the prallaxNode to 1000 pixels, then, the child with a moving speed ratio of 1 will not modify the position, and the object with a moving speed of 0.5 will update the position to 500 again, in this way, the first-level object moves 1000, while the second-level object moves 0.5.

When moving the camera, we have two options: Moving parallaxNode while the camera does not move. In this way, we will frequently update the location of parallaxNode, resulting in matrix update of the object. If we bind a physical system at this time, the physical body cannot be sleep due to the update of the World coordinates of the object. Therefore, when there is a physical system, simulating camera movement by moving parallaxNode will lead to a reduction in system performance.

To solve the problem above, we must use a real camera to move, that is, to move the camera position (modify the vmatrix in opengl MVP ). Cocos2dx abstracts the camera into camera, so we only need to change the mobile paranllax to the mobile camera to implement this function.

However, after this modification, I encountered two problems:

1. if I move camera, parallaxNode does not move hierarchically.

2. When camera moves, sprite cropping may cause problems. The objects displayed in the camera should have been cropped.

3. The UI is invisible because the camera is moving.

Therefore, you need to modify cocos and programs as follows:

1. Modify the parallaxNode so that it can move layers based on the relative camera location rather than the location of the world coordinate system.

 

Vec2 ParallaxNode::absolutePosition(){    Vec2 ret = _position;    Node *cn = this;//Modify By Funship    while (cn->getParent() != nullptr)    {        cn = cn->getParent();        ret = ret + cn->getPosition();    }    return ret;}
The preceding Code obtains the coordinates of parallaxNode relative to the world coordinate system (provided that parallaxNode and its parent are not correctly rotated or scaled). You need to change it to the coordinates of the relative camera.

 

First, convert the location of parallaxNode to the world coordinate system, use the convertWorldSpace function of paraent of parallaxNode, and then convert the coordinates to the coordinate system of camera node. I will not be able to access the code.

2. Modify the cropping

In the draw function of sprite

 

_insideBounds = (flags & FLAGS_TRANSFORM_DIRTY) ? renderer->checkVisibility(transform, _contentSize) : _insideBounds;
Here, checkVisibility is the code for cropping. First, this line of code needs to be modified.

 

Here, we only re-run the cropping operation when the transform dirty is used. However, because we move the camera, the transform of the model will not change, therefore, we need to add a variable in camera to indicate that camera is moving, and then add a judgment on the camera matrix change here. If camera is moving, we also need to perform the cropping operation, the second is the checkvisibility function. This function is cropped based on the world coordinate system and needs to be modified to crop based on the camera coordinate system.

 

// helpersbool Renderer::checkVisibility(const Mat4 &transform, const Size &size){    auto scene = Director::getInstance()->getRunningScene();    // only cull the default camera. The culling algorithm is valid for default camera.    if (scene && scene->_defaultCamera != Camera::getVisitingCamera())        return true;        // half size of the screen    Size screen_half = Director::getInstance()->getWinSize();    screen_half.width /= 2;    screen_half.height /= 2;    float hSizeX = size.width/2;    float hSizeY = size.height/2;    Vec4 v4world, v4local;    v4local.set(hSizeX, hSizeY, 0, 1);    transform.transformVector(v4local, &v4world);    // center of screen is (0,0)    v4world.x -= screen_half.width;    v4world.y -= screen_half.height;    // convert content size to world coordinates    float wshw = std::max(fabsf(hSizeX * transform.m[0] + hSizeY * transform.m[4]), fabsf(hSizeX * transform.m[0] - hSizeY * transform.m[4]));    float wshh = std::max(fabsf(hSizeX * transform.m[1] + hSizeY * transform.m[5]), fabsf(hSizeX * transform.m[1] - hSizeY * transform.m[5]));    // compare if it in the positive quadrant of the screen    float tmpx = (fabsf(v4world.x)-wshw);    float tmpy = (fabsf(v4world.y)-wshh);    bool ret = (tmpx < screen_half.width && tmpy < screen_half.height);    return ret;}
Here, you only need to input the current camera to convert the camer's visible rectangular box to the world coordinate system (that is, to convert the upper left and lower right vertices of camera to the world coordinate system) to get the rectangle, then, use the resulting rectangle to determine the intersection of the visible rectangle of the object.

 

You can change screen_half.width and screen_half.height in the code above to half of the width and height of A, and add A center with vec2 center =. Then modify

    // center of screen is (0,0)    v4world.x -= screen_half.width;    v4world.y -= screen_half.height;
V4world. x-= center. x, v4world. y-= center. y.

 

3. Concerning the UI, because we have moved camera, the UI will be cut down, because we need to set a separate camera for the UI so that we can solve the UI cropping problem, another method is to update the UI location based on the location of camera. I recommend the previous method, but I still don't know the amount of modified code.


 

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.