How to split screen or have variable layer size

How to split screen or have variable layer size
0.0 0

#1

Hello

I recently switched from SFML to cocos, and I having some difficulties. One of the difficult is, in SFML, we had easy to use viewports which allowed us to cut the screens and independently display anything on them. Right now, in cocos, I want to split my screen in 1:4 ratio, and want the second part of the screen to follow the player (this part is done) while the first part shows some static info at the same place. One option is that I draw the first screen on top of the second screen, and this works, but sometimes, I have transparent content to display in first screen, and because of this, the content of the second screen gets visible. So this won’t work. I want the layers to have sizes other than the window size. How is that possible?


#2

This is just pseudo-code. Remember that 0,0 is the bottom left corner. You can get info about your viewable size by using: auto visibleSize = Director::getInstance()->getVisibleSize();

layer->setContentSize(cocos2d::Size(visibleSize.width/2, visibleSize.height/2));
layer->setAnchorPoint(0.5, 0.5); //optional depending upon your needs and this value can be different
layer->setPosition(cocos2d::Vec2(300, 300)); // decide where you want the layer to be.


#3

But isn’t this true:

 /**
     * Sets the untransformed size of the node.
     *
     * The contentSize remains the same no matter the node is scaled or rotated.
     * All nodes has a size. Layer and Scene has the same size of the screen.
     *
     * @param contentSize   The untransformed size of the node.
     */

virtual void setContentSize(const Size& contentSize);
I tried using your method, but it seems that content size is not changing anything, as the document suggests.


#4

Show me your code.


#5
#include "GameScene.h"
#include "SimpleAudioEngine.h"

using namespace cocos2d;

Scene* GameScene::createScene()
{
	auto scene = Scene::createWithPhysics();
	scene->getPhysicsWorld()->setFixedUpdateRate(60);
	
#ifdef _DEBUG
	scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
#endif	

	auto layer = GameScene::create();
	scene->addChild(layer);

	return scene;
}

GameScene::GameScene()
{
	mKeyPressState.fill(false);
}

bool GameScene::init()
{
	mGameHUDLayer = Layer::create();
	mGameWorldLayer = Layer::create();

	auto visibleSize = Director::getInstance()->getVisibleSize();
	mGameWorldLayer->setContentSize(cocos2d::Size(visibleSize.width, visibleSize.height * 0.8));
	mGameWorldLayer->setAnchorPoint(Size(0, 0));
	mGameWorldLayer->setPosition(cocos2d::Vec2(0, visibleSize.height));

	addChild(mGameWorldLayer, 1);
	addChild(mGameHUDLayer, 2);

	auto HUDBanner = Sprite::create("F:/DEN Games/Bang Bang/Game/Images/HUDBanner.png");
	HUDBanner->setAnchorPoint(Vec2(0, 1));
	HUDBanner->setPosition(0, HUDBanner->getContentSize().height);
	mGameHUDLayer->addChild(HUDBanner);

	auto map = TMXTiledMap::create("F:/DEN Games/Bang Bang/Game/Levels/Level2.tmx");
	auto layer = map->getLayer("Tile Layer 1");
	mGameWorldLayer->addChild(map, -1);

	mPlayer = Sprite::create("F:/DEN Games/Bang Bang/Game/Images/Tank.png");
	mPlayer->setAnchorPoint(Vec2(0, 1));
	mPlayer->setPosition(0, mPlayer->getContentSize().height);
	mGameWorldLayer->addChild(mPlayer);

	Size size = Director::getInstance()->getVisibleSize();
	mGameWorldLayer->runAction(Follow::create(mPlayer, Rect(0, 0, size.width, size.height + 500)));

	return true;
}

#6
auto myLayer = LayerColor::create(cocos2d::Color4B(223, 150, 122, 255));
myLayer->setContentSize(cocos2d::Size(visibleSize.width/2, visibleSize.height/2));
myLayer->setAnchorPoint(cocos2d::Size(0, 0));
myLayer->setPosition(cocos2d::Vec2(0, 100));
this->addChild(myLayer,0);

or:

auto myLayer = LayerColor::create(cocos2d::Color4B(223, 150, 122, 255));
myLayer->setContentSize(cocos2d::Size(visibleSize.width/2, visibleSize.height/2));
myLayer->setAnchorPoint(Size(0, 0));
myLayer->setPosition(cocos2d::Vec2(0, 100));
this->addChild(myLayer,0);
    
auto myLayer2 = LayerColor::create(cocos2d::Color4B(199, 150, 199, 255));
myLayer2->setContentSize(cocos2d::Size(visibleSize.width/2, visibleSize.height/2));
myLayer2->setAnchorPoint(Size(0, 0));
myLayer2->setPosition(cocos2d::Vec2(225, 100));
this->addChild(myLayer2,0);


#7

Ahh, got it! thanks for the help! It was because of this:

mGameWorldLayer->runAction(Follow::create(mPlayer, Rect(0, 0, size.width, size.height + 500)));

I commented the line and it worked.


#8

There is another problem now. The camera. If I comment the line (runAction(Follow)), it works fine, but I want my camera to follow the player. How do I accomplish that? The camera moves, and layer1 starts drawing behind layer2.

Layer1 shows the game world on 80% of the screen and the world size is twice the screen size. So I want it to be scrollable, and make it draw in it’s area only. And I am guessing that won’t be possible, right? If not, can you suggest me any working alternative?


#9

a ParallaxNode, perhaps?


#10

Sorry, am still new to cocos. From what I understood, parallax node is used to move different layers, stacked upon each other, at different speeds. How can I use that in my problem?? Can you please explain them with an example or some code??


#11

Anyone can help plz?


#12

There are a few ways you can move around layers

  1. parallaxNode
  2. Actions/Sequences/Spawns
  3. Camera

Are you making a 3D game?

Can you tell me more about what you are trying to do?


#13

I am making a 2D side scroller game (instead of left to right, I want to move up and down according to the player).
The camera method allows me to do that fine.

Now I want the game to be displayed in only 80% of the screen. The 20% I want for HUD, which has transparent elements. Because of this transparency, I don’t want to use z-order method, in which I draw the HUD on top of the Game World. For splitting the screen, I use your method suggested, and it works fine too, but when I add the camera function, the layer drawing size increases and it starts drawing behind the HUD.


#14

Thanks. I am not sure of Camera obeys z-order the same way. You really don’t need a camera in a 2D game, IMHO. Just shift the position of the layer up or down or use a ParallaxNode. I am using this in a game I am finishing now.


#15

Can you tell me how do I use the parallax node. I am having difficulty figuring that out. If you could provide a code snippet in which I add the player and the map (probably to a parallax node) and then move the parallax node (set position)


#16

There is a great example in cpp-tests. Are you familiar with this project?


#17

You mean ‘ParallaxTest’ one??


#18

yup. You can look at the source too.


#19

I understood the code. I tried implementing it, but it’s very confusing. The problem is, I am able to create the scrolling effect, but the screen splitting isn’t working. Why doesn’t cocos have any viewport mechanism like SFML have? I mean, how do you create minimaps in cocos? In SFML, it was easy, you can split the screen in n numbers of n sizes and scale. Why can’t cocos add a feature similar to that?


#20

use an orthographic camera to make a mini-map. I assume you are using a perspective camera for trying to move your layers.