How to move background in cocos 2d - cocos2d-iphone

Hi i want to develop game like 'Doodle jump'.But i have some problem with the following features-
1.How to move background scene/image.
2.How to detect collision between object.Is it needed a physics engine like box2d or i should just use manual collision.
3.what should be the size of the background image.
4.In fact i have no idea how does background move .So i need a explanation from someone.

Background Movement
A) You could create a TMX Tilemap and then make a very high Tiled-Map.
B) You could create one texture and then cycle the texture coords instead of really moving it.
Detect it manually. Best is detect it via "Point in Boundingbox" or "Rect in Rect".
For more detail visit my blog entry for collision detection with cocos2d : http://www.anima-entertainment.de/?p=262
Size of an Image
Keep in Mind that textures are always at power of 2 in the memory. If you want to create one Background-Image at retina highresolution (960x640 Pixel) in the memory will be a texture of 1024x1024. If possible use smaller Background-Images and stretch them. (like 512x512). But I really would recommend for big scrolling images the TMX Support.
CCTMXTiledMap * tmxNode = [CCTMXTiledMap tiledMapWithGMXFile:#"Level.tmx"];
// lets say you want to move it 50 pixels down in 1 second :
[tmxNode runAction:[CCMoveBy actionWithDuration:1.0 position:ccp(0,-50)];
To create a tilemap : http://www.mapeditor.org/

In the folder of cocos2d, you could get many demos of tilemap.
TileMapTest.h
TileMapTest.m

refer this tutorial this will helpful for you.
http://www.raywenderlich.com/2343/how-to-drag-and-drop-sprites-with-cocos2d
this is used screen movement with pan recognizer

Related

High-DPI scaling of QQuickItem-derived class

I use QtQuickControls 2 together with QQuickItem-derived class in my app. After I set AA_EnableHighDpiScaling attribute and all QQuickControls 2 components look correctly on my smartphone but object of my custom class is scaled incorrectly. Here is the app without HighDpi scaling with minimum zoom(the way it is meant to work):
And here is the one with scaling with minimum zoom:
It seems that on the second screen the object is scaled too much and I can see square pixels of all textures that I draw with QPixmap or QImage. However, the images that I load from external memory and nodes like QSGGeometryNode look correct. Can I switch off scaling for just one particular QQuickItem? If no, what should I set to render it correctly?
Also, when I try to set opacity on QQuickItem with a lot of QSGOpacityNodes in scene graph node tree I get segmentation fault. What can cause this?
So I solved this problem by dividing the size of QSGTexture by QQuickWindow::effectiveDevicePixelRatio() and also multiplying the size of the image from which texture is created by this ratio.
If you are drawing the text using on QImage you should also multiply your font's size by this ratio. The same thing should be done with geometrical shapes and QPixmap::scaled().

How to rotate an image around its centre in QT QWidgets C++?

I am trying to rotate am image around its origin(center) in QT using QWidgts in C++. I experimented a lot of things here, but no matter what I do, the image keeps rotating around some arbitrary position I have no clue of. Kindly, help me out here. I am new to QT.
void gaugeWithRedZoneImage::rotate()
{
QPixmap pixmap(*gaugeMainScreen->pixmap());
QMatrix rm;
rm.translate(0, 0);
rm.rotate(-360);
pixmap = pixmap.transformed(rm);
gaugeMainScreen->setPixmap(pixmap);
/*QTransform rotate_disc;
rotate_disc.translate(pixmap.width()/2.0 , pixmap.height()/2.0);
rotate_disc.rotate(-60);
rotate_disc.translate(-(pixmap.width()/2.0) , -(pixmap.height()/2.0));
pixmap = pixmap.transformed(rotate_disc);
gaugeMainScreen->setPixmap(pixmap);*/
}
Form the documentation of QPixmap::transformed():
The transformation transform is internally adjusted to compensate for unwanted translation; i.e. the pixmap produced is the smallest pixmap that contains all the transformed points of the original pixmap.
This means that the method ensures no clipping takes place by appending the canvas. No matter what your rotation center was, the automatic extension of canvas will almost always result in a perceived shift.
Image examples might help to further diagnose the problem.
As ypnos said, your problem isn't the rotation center. When you rotate your image, its width and height will most likely change and no longer fit your container (gaugeMainScreen) dimensions.
You have some possibilities to overcome this problem. One of them is to set your container to scale its contents (you can use the method setScaledContents()). In this case, you have to keep the original image around and use it whenever you apply a rotation, otherwise your image will appear increasingly smaller.

C++ and Qt: Paint Program - Rendering Transparent Lines Without Alpha Joint Overlap

I have started to create a paint program that interacts with drawing tablets. Depending on the pressure of the pen on the tablet I change the alpha value of the line being drawn. That mechanism works.
Thin lines look decent and it looks a real sketch. But since I am drawing lines between two points (like in the Qt scribble tutorial) to paint there is an alpha overlap between the line joints and it is very noticeable for thick strokes.
This is the effect with line to line conjuction:
As you can see, there is an ugly alpha blend between the line segments.
In order to solve this I decided to use a QPainterPath to render lines.
Two problems with this:
A long, continuous, thick path quickly lags the program.
Since the path is connected it acts as one, so any change to the alpha value affects the the entire path(which I don't want since I want to preserve a blending effect).
The following images use a QPainterPath.
The blend effect I want to keep.
The following image shows the 2nd problem which changes the alpha and thickness of the entire path
The red text should read: "if more pressure is added without removing the pen from the tablet surface the line thickens" (and alpha becomes opaque)
Another thing is that with this approach I can only get a blending trail from a dark to light (or thick to thin path width) but not light to dark. I am not sure why this effect occurs but my best guess is that it has to do with the line segments of the path updating as whole.
I did make the program increase/decrease alpha and line thickness based on the pressure of the pen on the tablet.
The problem is that I want to render lines without the alpha overlap and QPainterPath updates the entire path's alpha and thickness which I don't want.
This is the code that creates the path:
switch(event->type()){
case QEvent::TabletPress:
if(!onTablet){
onTablet = true;
//empty for new segment
freePainterPath();
path = new QPainterPath(event->pos());
} break;
case QEvent::TabletRelease:
if(onTablet)
onTablet = false;
break;
case QEvent::TabletMove:
if(path != NULL)
path->lineTo(event->pos());
if(onTablet){
//checks for pressure of pen on tablet to change alpha/line thickness
brushEffect(event);
QPainter painter(&pixmap);
//renders the path
paintPixmap(painter, event);
} break;
default:;
}
update();
The desired effect that I want as a single path (image created with Krita paint program):
To emulate the Krita paint program:
Keep a backup of the original target surface.
Paint with your brush onto a scratch surface that starts out completely transparent.
On that surface, your composting rule is "take maximum opacity".
Keep track of the dirty regions of that surface, and do a traditional composite of (scratch surface) onto (original target surface) and display the result. Make sure this operation doesn't damage the original target surface.
Now, you don't have to keep the entire original target surface -- just the parts you have drawn on with this tool. (A good tile based lazy-write imaging system will make this easy).
Depending on the segment size you are drawing with, you may want to interpolate between segments to make the strength of the brush be a bit less sharp. The shape of your brush may also need work. But these are independent of the transparency problem.
As for the Qt strangeness, I don't know enough Qt to tell you how to deal with the quirks of Qt's brush code. But the above "key-mask" strategy should solve your alpha overlap problem.
I do not know how to do this in Qt. Glancing at the Qt compositing modes I don't see an obvious way to say "take maximum" as the resulting alpha. Maybe something involving both color and alpha channels in some clever way.
I know this question is very old, and has an accepted answer, but in case someone else needs the answer, here it is:
You need to set the composition mode of painter to source. It draws both source and destination right now.
painter.setCompositionMode(QPainter::CompositionMode_Source);
If you want your transparent areas to show through underlying drawings, you need to set the composition mode of your result back to CompositionMode_SourceOver and draw over destination.
I don't know if you still look for an answer, but I hope this helps someone.

changing textureRect of a CCSprite created by CCRenderTexture

I have a CCSprite which gradually needs to be exhausted linearly from one end, lets say from left to right.For this purpose ,I am trying to change the textureRect property of the sprite so that the part that got exhausted from one end is 'outside' the displaying frame of the sprite.
I did this sort of thing before with a sprite that gets loaded from a spritesheet.And it worked perfectly.But I created this CCSprite using CCRenderTexture and by changing the textureRect property,the entire sprite gets disappeared.
The first image is the original CCSprite which I get from CCRenderTexture.The second image shows what I want to achieve.The black dotted rectangular portion of the Sprite needs to be omitted out.Only the blue dotted portion of the sprite needs to be displayed.Essentially,this blue dotted rectangle is my textureRect.
Is there any way how I could make my sprite reduce from one end.
Also is there any difference between a sprite created normally,and one created using CCRenderTexture.
I have done similar thing like this before using some low-level hack.
There is a work around solution if you use CCProgressTimer, that's very easy and I think it should be enough for your examples.
But you said in comment that you have some special requirements like "exhaust it from both the ends at once" then some low-level hack is needed. My solution from my last object is:
1) Get the texture image's raw data. In cocos2d you can use CCRenderTexture and in cocos2d-x you can use CCImage.
2) CCRenderTexture has a method of - (BOOL) saveToFile: (NSString *) name
format: (tCCImageFormat) format
. You can read its source code then try to save it into an 2D array instead like byte raw[1024][768]. Each element in this array represents one pixel on your picture(the type may not be byte, I'm not sure, nearly forget the details). The format MUST BE PNG since transparency will be needed.
3) Modify raw data directly, set pixel's transparency to 0x0 which you want it to disappear.
4) Re-initialize a CCRenderTexture using picture data you modified.
I can't provide the code directly since is a trade secret and core part of one of my projects. But I can share you my solution. You also need some knowledge about how PNG file works. Read:
https://en.wikipedia.org/wiki/Portable_Network_Graphics#File_header
Turns out I was making a silly mistake.While supplying values to the textureRect(CGRect),I was actually setting the textureRect.origin.y to the height of the texture which made my textureRect go beyond(above) the texture area.This explains why they were disappearing.

CCSprite children coordinates transform fails when using CCLayerPanZoom and CCRenderTexture?

Thanks for reading.
I'm working on a setup in Cocos2D 1.x where I have a huge CCLayerPanZoom in a scene with free panning and zooming.
Every frame, I have to additionally draw a CCRenderTexture on top to create "darkness" (I'm cutting out the light). That works well.
Now I've added single sprites to the surface, and they are managed by Box2D. That works as well. I can translate to the RenderTexture where the light sources ought to be, and they render fine.
And then I wanted to add a HUD layer on top, by adding a CCLayer to the scene. That layer needs to contain several sprites stacked on top of each other, as user interface elements.
Only, all of these elements fail to draw where I need them to be: Exactly in the center of screen. The Sprites added onto the HUD layer are all off, and I have iterated through pretty much every variation "convertToWorldSpace", "convertToNodeSpace", etc.
It is as if the constant scaling by the CCPanZoomLayer in the background throws off anchor points in the layer above each frame, and resetting them doesn't help. They all seem to default into one of the corners of the node bounding box they are attached to, as if their transform is blocked or set to zero when it comes to the drawing.
Has anyone run into this problem? Is this a known issue when using CCLayerPanZoom and drawing a custom CCRenderTexture on top each frame?
Ha! I found the culprit! There's a bug in Cocos2D' way of using Zwoptex data. (I'm using Cocos2D v 1.0.1).
It seems that when loading in Zwoptex v3 data, sprite frames' trim offset data is ignored when the actual sprite frame anchor point is computed. The effect is that no anchor point on a sprite with trim offset in its definition (eg in the plist) has its anchor point correctly set. Really strange... I wonder whether this has occurred to anybody else? It's a glaring issue.
Here's how to reproduce:
Create any data for a sprite frame in zwoptex v3 format (the one that uses the trim data). Make sure you actually have a trimmed sprite, i.e. offset must be larger than zero, and image size must be larger than source.
Load in sprite, and try to position it at center of screen. You'll see it's off. Here's how to compute your anchor point correctly:
CCSprite *floor = [CCSprite spriteWithSpriteFrameName:#"Menu_OmeFloor.png"]; //create a sprite
CCSpriteFrame *frame=[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:#"Menu_OmeFloor.png"]; //get its frame to access frame data
[floor setTextureRectInPixels:frame.rect rotated:frame.rotated untrimmedSize:frame.originalSizeInPixels]; //re-set its texture rect
//Ensure that the coordinates are right: Texture frame offset is not counted in when determining normal anchor point:
xa = 0.5 + (frame.offsetInPixels.x / frame.originalSizeInPixels.width);
ya = 0.5 + (frame.offsetInPixels.y / frame.originalSizeInPixels.height);
[floor setAnchorPoint:ccp(xa,ya)];
floor.position=(where you need it);
Replace the 0.5 in the xa/ya formula with your required anchor point values.