I'm new to cocos2D and I want to draw lines in it, which I tried to implement from here
I've a problem with the frame set in it. I set background image by the below code
CCSprite* background = [CCSprite spriteWithFile:imgPath rect:frame];
where imgPath is the path of the image file that is set to CCSprite and frame is the view bounds. CCSprite's frame is ok and now I added
[background addChild: [LineDrawingClass node]];
Then I added a CCRenderTexture instance to the LineDrawingClass with the following code snips
renderTexture.anchorPoint = ccp(0, 0);
renderTexture.position = ccp(self.width * 0.5f, self.height * 0.5f);
then I added renderTexture to LineDrawingClass
What I got is the CCSprite's background set to correct frame, with no problem but renderTexture's frame is set some five pixel below the CCSprite.
I also set the anchor point to
renderTexture.anchorPoint = ccp(0.5f, 0.5f);
but the lag in origin.y of renderTexture remains.
Please see the attached image for reference. Can some one point out the mistake and correct me that renderTexture's frame is exactly over the CCSprite's frame (which is now 5px lag with origin.y)??
Try setting the height of the texture a bit larger say if 480 is ur height, set it as 580 or greater than that could match ur requirements.
renderTexture.position = ccp(self.width * 0.5f, (self.height + 100) * 0.5f);
Its becoz of some orientation problem.
Related
I am testing a UIView using a UISlider as in the example images below:
I have a custom UIView with a yellow background that draws the gray square, the drawRect method is like so:
-(void)drawRect:(CGRect)rect{
NSLog(#"Draw rect called");
UIBezierPath* squarePath = [UIBezierPath bezierPathWithRect: CGRectMake(10, 10, 100, 100)];
[UIColor.grayColor setFill];
[squarePath fill];
}
And the method for my slide changing value:
- (IBAction)changeValue:(id)sender {
CGAffineTransform transform = CGAffineTransformScale(CGAffineTransformIdentity, self.slider.value, self.slider.value);
self.tableView.transform = transform;
[self.tableView setNeedsDisplay];
}
I dont understand why the square is getting larger. I've noticed that drawRect is called every time the slider is moved. If this happens then why is the square size changing? Shouldn't it remain the same size and just the frame grow with the square in the top left corner?
My second question is, how would I change the code so just the frame grows and the drawing size stays the same? I ask this because actually I want the drawing size to change dynamically using my own code in drawRect.
Any pointers would be really appreciated! thanks!
The reason why the size of the square changes is because you've transformed it. Transformations don't just affect the frame of a view; they will affect the content. The square is getting drawn into its context at its constant size (100x100) and then the transform is stretching it before it gets rendered.
The reason why it's not expanding to the right and down is because by default the anchor point of a transform is the center of the bounds. Thus it'll scale from the center outwards. From the documentation:
The origin of the transform is the value of the center property ...
Transformations aren't intended to be used to simply scale the width and height of your frame. The frame property is for that. Simply store the view's frame in a variable, change its width and height, then set it back. In your drawRect: code you can check the dimensions of the rectangle that's given to you and make your square's width/height a percentage of that.
guys!
I need to draw some image to CGContext.This is the relevant code:
CGContextSaveGState(UIGraphicsGetCurrentContext());
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGRect rect = r;
CGContextRotateCTM(ctx, DEGREES_TO_RADIANS(350));
[image drawInRect:r];
CGContextRestoreGState(UIGraphicsGetCurrentContext());
Actually,the rectangle is rotate and display on a area what is not my purpose.I just want to
rotate the image and display on the same position.
Any ideas ?????
Rotation is about the context's origin, which is the same point that rectangles are relative to. If you imagine a sheet of graph paper in the background, you can see what's going on more clearly:
The line is the “bottom” (y=0) of your window/view/layer/context. Of course, you can draw below the bottom if you want, and if your context is transformed the right way, you might even be able to see it.
Anyway, I'm assuming that what you want to do is rotate the rectangle in place, relative to an unrotated world, not rotate the world and everything in it.
The only way to rotate anything is to rotate the world, so that's how you need to do it:
Save the graphics state.
Translate the origin to the point where you want to draw the rectangle. (You probably want to translate to its center point, not the rectangle's origin.)
Rotate the context.
Draw the rectangle centered on the origin. In other words, your rectangle's origin point should be negative half its width and negative half its height (i.e., (CGPoint){ width / -2.0, height / -2.0 })—don't use the origin it had before, because you already used that in the translate step.
Restore the gstate so that future drawing isn't rotated.
What worked for me was to first use a rotation matrix to calculate the amount of translation required to keep your image centered. Below I assume you've already calculated centerX and centerY to be the center of your drawing frame and 'theta' is your desired rotation angle in radians.
let newX = centerX*cos(theta) - centerY*sin(theta)
let newY = centerX*sin(theta) + centerY*cos(theta)
CGContextTranslateCTM(context,newX,newY)
CGContextRotateCTM(context,theta)
<redraw your image here>
Worked just fine for me. Hope it helps.
use following code to rotate your image
// convert degrees to Radians
CGFloat DegreesToRadians(CGFloat degrees)
{
return degrees * M_PI / 180;
};
write it in drawRect method
// create new context
CGContextRef context = UIGraphicsGetCurrentContext();
// define rotation angle
CGContextRotateCTM(context, DegreesToRadians(45));
// get your UIImage
UIImage *img = [UIImage imageNamed:#"yourImageName"];
// Draw your image at rect
CGContextDrawImage(context, CGRectMake(100, 0, 100, 100), [img CGImage]);
// draw context
UIGraphicsGetImageFromCurrentImageContext();
I am using the following code to rotate and transform an image view:
myImageView.transform = CGAffineTransformMakeRotation(45); // rotation
CGRect frame = myImageView.frame;
frame.origin.x = x_position;
frame.origin.y = y_position;
myImageView.frame = frame; // transformation
tl;dr: The frame is bogus when you have a non-identity transform. Change the center instead.
From the documentation:
Warning If the transform property is not the identity transform, the value of this property is undefined and therefore should be ignored.
When you are setting the transform on the first line and then reading the frame after it is undefined what you actually get back.
// Setting a non-identity transform (1)
myImageView.transform = CGAffineTransformMakeRotation(45);
CGRect frame = myImageView.frame; // At this point the frame is undefined (2)
// You are modifying something which is undefined from now on ...
Also, not only should you not read the frame because it is undefined, you should also not set it.
if the transform property contains a non-identity transform, the value of the frame property is undefined and should not be modified.
The solution to that problem comes in the next sentence of the documentation
In that case, you can reposition the view using the center property and adjust the size using the bounds property instead.
Since you are only changing the position I would suggest that you don't touch the frame and instead read the center of the image view and set it to it's new value. The center is not affected by the transform in the same way as the frame.
CGPoint center = myImageView.center;
center.x = x_center_position; // Note that the `center` is not the same as the frame origin.
center.y = y_center_position; // Note that the `center` is not the same as the frame origin.
myImageView.center = center;
Try to remove autoresizing Mask of ImageView
imageView.autoresizingMask = UIViewAutoresizingNone;
This may solve your problem
I have a round image that I want to "squish" vertically so that it looks more like a horizontal line, then expand it back to the original shape. I thought this would work by setting the layer's anchor point to the center and then animating the frame via UIViewAnimation with the height of the frame = 1.
[self.imageToSquish.layer setAnchorPoint:CGPointMake(0.5, 0.5)];
CGRect newFrame = CGRectMake(self.imageToSquish.frame.origin.x, self.imageToSquish.frame.origin.y, self.imageToSquish.frame.size.width, 1 );
[UIView animateWithDuration:3
animations:^{self.imageToSquish.frame = newFrame;}
completion:nil];
But the image shrinks toward the top instead of around the center.
You’re giving it a frame that has its origin—at the top left—in the same position as it started. You probably want to do something more like this, adding half the image’s height:
CGRect newFrame = CGRectMake(self.imageToSquish.frame.origin.x, self.imageToSquish.frame.origin.y + self.imageToSquish.frame.size.height / 2, self.imageToSquish.frame.size.width, 1);
Alternatively—and more efficiently—you could set the image view’s transform property to, say, CGAffineTransformMakeScale(1, 0.01) instead of messing with its frame. That’ll be centered on the middle of the image, and you can easily undo it by setting the transform to CGAffineTransformIdentity.
I am trying to create a background to flow with the game. However the image isn't Continuous. There is a space between each of the image loads. I want the image to continue to loop.
Here is the method to create the sprite
CCSprite *sprite = [CCSprite spriteWithFile:#"Image.png" rect:CGRectMake(0, 0, 960, 640)];
ccTexParams tp = {GL_NEAREST, GL_NEAREST, GL_REPEAT, GL_REPEAT};
[sprite.texture setTexParameters:&tp];
sprite.anchorPoint = ccp(1.0f/8.0f, 0);
sprite.position = ccp(screenW/8, 0);
Method to update the position of the sprite.
- (void) setOffsetX:(float)offsetX {
if (_offsetX != offsetX) {
_offsetX = offsetX;
CGSize size = _sprite.textureRect.size;
_sprite.textureRect = CGRectMake(_offsetX, 0, size.width, size.height);
}
}
Any help please
Your image width needs to be a power of two. i.e. the width has to be 64, 128, 256, 512, etc if you want it to repeat
The gap you are seeing is where OpenGL has padded empty space to your texture to make it power of two.
After trying it a few times, the best way is to ensure that the sprite dimensions are a power of 2. This will ensure that you can scale the layer and all remains fine. If you don't plan on scaling the layer, then you can use any size sprites and use this:
[[CCDirector sharedDirector] setProjection:CCDirectorProjection2D];
http://ak.net84.net/iphone/gap-between-sprites-when-moving-in-cocos2d/