How to set CCLayer size in Cocos2d-x? - cocos2d-x

I used setContentSize but it doesn't work. And I don't want to scale stuff in the layer so I won't use setScale.
What should I do?

setContentSize should work as the following. How did you do that?
https://github.com/cocos2d/cocos2d-x/blob/master/samples/Cpp/TestCpp/Classes/LayerTest/LayerTest.cpp#L841
CCLayerGradient* layer1 = CCLayerGradient::create(ccc4(255, 0, 0, 255), ccc4(255, 0, 255, 255));
layer1->setContentSize(CCSizeMake(80, 80));
EDITED
So you mean you want to clip the image by the content size of the layer? Try to use CCClippingNode or this glScissor node example.

Try! this it works for me.
CCSize screenSize = CCDirector::sharedDirector()->getVisibleSize();
float x = screenSize.width;
float y = screenSize.height;
CCLayer* layer = new MyLayer();
float layerX = layer->getContentSize().width;
float layerY= layer->getContentSize().height;
float scaleX = x/layerX;
float scaleY = y/layerY;
layer->setScaleX(scaleX*1.2f);
layer->setScaleY(scaleY*1.2f);

Maybe?
auto layerInstance = LayerColor::create();
auto layerInstanceSize = layerInstance->getContentSize();
float layerInstanceSizeWidth = layerInstanceSize.width;
float layerInstanceSizeHeight = layerInstanceSize.height;

Related

Is it possible to control canvas texture upscale behavior?

When upscaling a texture in canvas, the behavior differs greatly across browsers.
Here is a fiddle creating a 2x1 texture (composed of one black and one white texel) and applying it on a 256x128px rectangle: https://jsfiddle.net/ozirus/x1c3m50o/
var texture = ...
var ctx = document.createElement("canvas").getContext("2d");
ctx.canvas.width = 512;
ctx.canvas.height = 512;
document.body.appendChild(ctx.canvas);
ctx.setTransform(128, 0, 0, 128, 0, 0);
ctx.fillStyle = ctx.createPattern(texture, "no-repeat");;
ctx.rect(0, 0, 2, 1);
ctx.fill("evenodd");
The following screenshots showcase the results when run in different browsers.
In Chrome:
In Firefox:
In IE11/Edge:
Are there any flags/options available to control this behavior and make it more consistent?
The IE/Edge behavior where the last pixels are the result of a wrapping/repeating interpolation is the major issue I'm actually trying to solve.
PS: I am aware of some workarounds that could do the trick (half texel offset + scale up, transparent border on textures, ...) but I'd rather configure this behavior if possible.
EDIT: as pointed out by #Ryan in the comments, CanvasRenderingContext2D.imageSmoothingEnabled property can be used to have matching behaviors in nearest neighbour mode but I want to keep smooth interpolation of the textures
No.
No there is no way to access the code behind the 2D API (CPU and GPU) from javascript. The standard has many holes and thus browser developers are left to interpret it however it suits them.
If you use "repeat" you will get the same result as "no-repeat" on Edge on all 3 browsers.
On Edge, Firefox and Chrome with
ctx.fillStyle = ctx.createPattern(textureCanvas, "repeat");;
If you want the result to be like FF then use ctx.drawImage to render the bitmap. If you want irregular shapes then render using the ctx.drawImage then mask with a path and ctx.globalCompositeOperation = "destination-in". If you need to render to existing canvas content then use a second canvas to render the bitmaps and masks and then render that canvas onto the existing content.
On Edge, Firefox and Chrome with
ctx.drawImage(textureCanvas,0,1,2,1);
If you want the same result as Chrome on all 3 browsers you need to add a one pixel transparent border around the image and then render the 2 pixel center.
Same result on Firefox, Edge and chrome in example below (copied and modified from your fiddle https://jsfiddle.net/ozirus/x1c3m50o/)
var textureCanvas = document.createElement("canvas");
textureCanvas.width = 4;
textureCanvas.height = 3;
var textureContext = textureCanvas.getContext("2d");
var imgData = textureContext.createImageData(4, 3);
var i = 20;
imgData.data[i++] = 0;
imgData.data[i++] = 0;
imgData.data[i++] = 0;
imgData.data[i++] = 255;
imgData.data[i++] = 255;
imgData.data[i++] = 255;
imgData.data[i++] = 255;
imgData.data[i++] = 255;
textureContext.putImageData(imgData, 0, 0);
var ctx = document.createElement("canvas").getContext("2d");
ctx.canvas.width = 512;
ctx.canvas.height = 512;
document.body.appendChild(ctx.canvas);
ctx.setTransform(128, 0, 0, 128, 0, 0);
ctx.drawImage(textureCanvas,1,1,2,1,0,0,2,1);
html {
background-color: red;
}
Yes.
So I guess that means you can control it, but indirectly using different techniques.

get a position of a sprite from another sprite

I have 2 sprite, spriteA and spriteB, one is added to HelloWord Layer and the other added to a node:
node = Node::create();
this->addChild(node);
spriteA = Sprite::create("spriteA.png");
node->addChild(spriteA);
spriteB = Sprite::create("spriteB.png");
this->addChild(spriteB);
Then I need to move the node to spriteB center, and keep the spriteA position from the spriteB:
//get screen position of spriteA and (maybe not) position of spriteA from spriteB
Vec2 point = center->convertToWorldSpace(spriteA->getPosition());
Vec2 position = Vec2(point.x - SpriteB->getPositionX(), point.y - spriteB->getPositionY());
node->setPosition(spriteB->getPosition());
spriteA->setPosition(position);
But I can get the good position of the spriteA from the spriteB, someone can help please?
i tried this code, and it works
auto posB = spriteB->getPosition();
auto posA = spriteA->getPosition();
auto dis = node->getPosition() - posB;
node->setPosition(posB);
spriteA->setPosition(posA + dis);
if still not work, maybe you need to set node contentsize and anchorpoint

How to flip a card with cocos2d-x

I need to flip a card to see its back, then side and then front gradually with animation like this: https://www.youtube.com/watch?v=te0Je0y4zU0 . How I can do this with cocos2d-x? I have took a look on OrbitCamera and RotateBy in 3D tests. They are very close to the one I want to, the only problem is that when the sprite turns around I see not the back (as at should be another texture, but the same spite from back camera). I understand that I should use 2 sprites to get the effect, but how I should do that, I don't know. Should I position 2 sprite with different Z order? Please advice.
Try this:
float duration = 2.0f;
auto actionBy = RotateBy::create(duration / 2, Vec3(0, 90, 0));
backCard->runAction(RotateBy::create(0, Vec3(0, 90, 0)));
frontCard->runAction( Sequence::create(
actionBy,
CallFunc::create([backCard, actionBy](){backCard->runAction(actionBy);}),
nullptr)
you need to simply do this :
CCRotateTo *act1= CCRotateTo::create(0.5, -180);
CCRotateTo *act2= CCRotateTo::create(1.0, 180);
CCSequence* act3 = CCSequence::create(act1,act2,NULL);
sprite->runAction(act3);
you should view https://www.youtube.com/watch?v=Q4fJrMvZVhI
same with cocos2dx using javascript.
reveal: function (pIsFaceUp) {
let self = this;
let timeFlip =0.5;
let callFunc = cc.callFunc(function () {
self.cardBG.spriteFrame = pIsFaceUp ? self.texFrontBG : self.texBackBG;
self.point.node.active = pIsFaceUp;
self.suit.node.active = pIsFaceUp;
self.mainPic.node.active = pIsFaceUp;
if(!pIsFaceUp)
self.node.skewY=135;
else
self.node.skewY=45;
});
if(!pIsFaceUp)
{
self.node.skewY=0;
let action = cc.skewBy(timeFlip/2,0,45);
let action2 = cc.skewTo(timeFlip/2,0,180);
self.node.runAction(cc.sequence(action,callFunc,action2));
}else
{
self.node.skewY=180;
let action = cc.skewBy(timeFlip/2,0,-45);
let action2 = cc.skewTo(timeFlip/2,0,0);
self.node.runAction(cc.sequence(action,callFunc,action2));
}
},
Use 2 Sprites: spriteFront, spriteBack
init (show spriteBack at first):
scale spriteFront to (0, 1) (scale X to 0, while keeping scale Y to 1)
scale spriteBack to (1, 1)
flip animation:
scale spriteBack to (0, 1)
after the animation,
scale spriteFront to (1, 1)
float fDuration = 0.8f;
CCArray* pArray = CCArray::create();
pArray->addObject(CCScaleTo::create(fDuration/2, 0, 1));
pArray->addObject(CCTargetedAction::create(spriteFront, CCScaleTo::create(fDuration/2, 1)));
CCFiniteTimeAction* flipCardAnimation = CCSequence::create(pArray);
spriteBack->runAction(flipCardAnimation);

RotateX a square around its center

I have 3 squares (50 px x 50 px) in a Sprite, one next to each other. Pivot of each is at 0, 0.
1st square X, Y: 0, 0
2nd square X, Y: 50, 0
3rd square X, Y: 100, 0
I would like to rotateX each square around its center-line. I cannot seem to figure out how to set the vanishing point so that all the squares rotate around their individual point and not all of them around the same point.
Any help greatly appreciated!
You can make the rotation of child movieclips by rotating and translating them to newer position. Required the pivot of the child movieclip coincides with it's registration point
in the following code, the holder is your sprite and content are the squares. ( Required that squares are having the pivot, coinciding with the registration point)
PS: Holder must have a width and height bigger than the content's. It's assumed that holder here is some kind of big container ( say stage).
var holder_Mc:MovieClip = holder_Mc
var content_Mc:MovieClip = holder_Mc.content_Mc ;
var rotation_val_num:Number = 50// in degrees
var bnd = holder_Mc.getBounds(MovieClip(holder_Mc.parent)) ;
var cw:Number = bnd.width ;
var ch:Number = bnd.height;
var cx:Number = bnd.x ;
var cy:Number = bnd.y ;
content_Mc.rotation = rotation_val_num ;
var bnd2 = holder_Mc.getBounds(MovieClip(holder_Mc.parent)) ;
var cw2 = bnd2.width ;
var ch2 = bnd2.height;
var cx2 = bnd2.x ;
var cy2 = bnd2.y ;
var dx = Math.abs( holder_Mc.x - cx2 ) ;
var dy = Math.abs( holder_Mc.y - cy2) ;
holder_Mc.x = cx + cw/2 + dx - cw2/2
holder_Mc.y = cy + ch/2 + dy - ch2/2
Basically, you need to move the box while it is rotating to get that effect. Since you also know the width/height of the box and the pivot points positions the calculations aren't that hard.
However, why calculate it yourself? With TweenLite, You could use the TransformAroundCenterPlugin, which handles the transformation for you. I would recommend to use it. If you don't want to tween it, then set the tween-duration (second parameter) to 0.
// Activate plugin (should be called once)
TweenPlugin.activate([TransformAroundPointPlugin]);
// Transform your boxes around it's center, does not use the pivot point.
TweenLite.to(this.mcBox1, 1, new TweenLiteVars().transformAroundCenter({rotationX: 50}));
TweenLite.to(this.mcBox2, 1, new TweenLiteVars().transformAroundCenter({rotationX: 190}));
TweenLite.to(this.mcBox3, 0, new TweenLiteVars().transformAroundCenter({rotationX: 5}));

how to turn an existing color image into a black-white image?

What diffrent approaches exists out there in actionscript 3.0 ?
I found this library: mojocolors
But this is more for graphics-color I guess…
Thx
var n:Number = 1/3;
var matrix:Array = [n,n,n,0,0,
n,n,n,0,0,
n,n,n,0,0,
0,0,0,1,0];
var cmf:ColorMatrixFilter = new ColorMatrixFilter(matrix);
bitmap.filters = [cmf];
In general, assuming that you start with an RGB image, you convert it to HSI color space and use the I (intensity) component.
To convert an image to grayscale, you need to iterate over each pixel in the image buffer and average the R, G and B component into one entity, then duplicate it three times to get the new color. pseudo-code (assuming 8bit color):
for each pixel in buffer:
pixel.rgb = ((pixel.red + pixel.green + pixel.blue) / 3) * 0x010101;
I am sure you can do something with Adobe's PixelBender to achieve this faster.
Apply the filter created by this method to the DisplayObject that contains the image you want in black and white:
public static function createBlackAndWhiteFilter():ColorMatrixFilter {
var rLum:Number = 0.2225;
var gLum:Number = 0.7169;
var bLum:Number = 0.0606;
var bwMatrix:Array = [rLum, gLum, bLum, 0, 0, rLum, gLum, bLum, 0, 0, rLum, gLum, bLum, 0, 0, 0, 0, 0, 1, 0];
return new ColorMatrixFilter(bwMatrix);
}//createBlackAndWhiteFilter