Sticking nodes to SkSpriteNode after enlargement - ios

Problem
As of right now, I've just realised a pretty major design flaw in my application..
So, the problem is:
A rifle shot is fired, and lands based on no trajectory as of right now, I'm toying with the idea. However, the bullets land and their marks are left as nodes.
-(void)applyShot:(int) posX with:(int) posY {
SKSpriteNode *impact = [[SKSpriteNode alloc] initWithColor:[UIColor grayColor] size:CGSizeMake(2, 2)];
impact.zPosition = 1;
impact.userInteractionEnabled = NO;
impact.position = CGPointMake(posX , posY);
[backgroundImage addChild:impact];
}
And posX / posY are sent this way.
//Find difference between centre and background moved distance.
CGPoint positionNow = CGPointMake(backgroundImage.position.x, backgroundImage.position.y);
CGPoint positionPrev = CGPointMake(0.5, 0.5);
float xdiff = positionNow.x - positionPrev.x;
float ydiff = positionNow.y - positionPrev.y;
//Calculate ydrop
int newYDrop = yDrop * 10;
//
CGPoint newPositionOne = CGPointMake(0.5 - xdiff, 0.5 - ydiff);
newPositionOne = CGPointMake((newPositionOne.x + [self myRandom:15 withFieldLower:-15]), (newPositionOne.y - newYDrop));
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(secondsDelay * NSEC_PER_SEC)), dispatch_get_main_queue(), ^(void){
[self applyShot:newPositionOne.x with:newPositionOne.y];
});
Which seems to work fine, until I started toying with zoom.
Now, this application basically is a 1080p image for the reticle, and the background enlarges to give the (zoom) effect, then the background is touch-dragged/inverted to give the reticle moving effect.
Then I managed to get it to fire exactly where the crosshair was, which was good.. Then I started toying with zoom and noticed this.
So if it's not too easy to notice, the (bullet hits) are the grey marks, however, when you enlarge the backgroundImage they aren't tied to it. so they remain the same spread.
Solution
Now what I need is to either,
A: tie the nodes to the backgroundImage
B: enlarge the spread to the same factor as the enlargement.
But I'm pretty confused at how to achieve this.
Additional problem
When calibrating the drop, the drop will remain a burden no matter of the zoom as of right now. so if it's a 1 mil-dot drop on 6x zoom, it's also a 1 mil-dot drop at 10x zoom or 1x zoom ( I keep saying zoom when I mean enlargement )
How can I achieve a calibration for drop intensity no matter what enlargement the background image is at?
Thanks for reading and confusing yourself with my dire problems, it's appreciated!
What I've Tried
saving the children to a mutable array, then recreating them after a zoom change;
//recreate children
[backgroundImage removeAllChildren];
for (int i=0; i < [shotsHitX count]; i++) {
double posX = ([shotsHitX[i] doubleValue] / 5) * rifleZoom;
double posY = ([shotsHitY[i] doubleValue] / 5) * rifleZoom;
SKSpriteNode *impact = [[SKSpriteNode alloc] initWithColor:[UIColor grayColor] size:CGSizeMake(2, 2)];
impact.zPosition = 1;
impact.userInteractionEnabled = NO;
impact.position = CGPointMake(posX , posY);
[shotsHitX addObject:[NSNumber numberWithDouble:posX]];
[shotsHitY addObject:[NSNumber numberWithDouble:posY]];
[backgroundImage addChild:impact];
}
//end recreate children
Crash with memory error.
not so good at this!
[backgroundImage removeAllChildren];
for (int i=0; i < [shotsHitX count]; i++) {
double posX = ([shotsHitX[i] doubleValue] / 5) * rifleZoom;
double posY = ([shotsHitY[i] doubleValue] / 5) * rifleZoom;
SKSpriteNode *impact = [[SKSpriteNode alloc] initWithColor:[UIColor grayColor] size:CGSizeMake(2, 2)];
impact.zPosition = 1;
impact.userInteractionEnabled = NO;
impact.position = CGPointMake(posX , posY);
[backgroundImage addChild:impact];
}
//end recreate children
Works, however, now It doesn't just seem quite right..
I think the problem is when the initial zoom goes in it works, then when it reverts it's mixing zoom shots in the array with old shots.. Here we go again, MORE ARRAYS.
//recreate children
[backgroundImage removeAllChildren];
for (int i=0; i < [shotsHitRem count]; i+= 2) {
double posX = ([shotsHitRem[i] doubleValue] / 5) * rifleZoom;
double posY = ([shotsHitRem[i+1] doubleValue] / 5) * rifleZoom;
SKSpriteNode *impact = [[SKSpriteNode alloc] initWithColor:[UIColor grayColor] size:CGSizeMake(2, 2)];
impact.zPosition = 1;
impact.userInteractionEnabled = NO;
impact.position = CGPointMake(posX , posY);
[backgroundImage addChild:impact];
//add olds m4
if ([shotsHitM4 count] > 0) {
posX = ([shotsHitM4[i] doubleValue] / 2) * rifleZoom;
posY = ([shotsHitM4[i+1] doubleValue] / 2) * rifleZoom;
impact.position = CGPointMake(posX, posY);
[backgroundImage addChild:impact];
}
}
//end recreate children
Now I crash attempting to add a sknode which already has a parent
Confusing as it should removeAllChildren before looping

Well after some major messing around
[backgroundImage setScale:rifleZoom];
Programming is my favourite, oh yeah.. Five hours, Oh yeah.. For one line, oh yeah!
I wasn't scaling before, I was creating a new cgsize. and that was my problem.
I now have the issue of scaling and trying to render a new centrepoint as it still remembers the centrepoint of scale = 1 and scale = 2, nightmare.

Related

cocos2d animation not showing of sprite sheet

I have some strange error happening with my game. How anyone can help me to get solve form this.
I have a runner game and hero is collecting coins while running ,when hero touches the coin,now I am showing a particle effect created with the help of particle maker.and it's working fine. But last day I purchased a software and it gives us really good particle effects but it can only export as pngs. so I made sprite sheet and instead of previous particle animation I put this on the contact listener code for showing this effect when hero touches the coin. Unfortunately it is not showing anything. Here is my previous code :
-(void) checkHeroAndCoins {
float fDelta = 0;
if(m_hero->m_bMagnet)
fDelta = iDevPixelX(30);
for(Coin *coin in m_drawLayer.children){
if([coin isKindOfClass:[Coin class]]){
CGRect rCoin = CGRectMake(coin.position.x - coin.contentSize.width * coin.scaleX / 2.0f - fDelta,
coin.position.y - coin.contentSize.height * coin.scaleY / 2.0f - fDelta,
coin.contentSize.width * coin.scaleX + fDelta * 2, coin.contentSize.height * coin.scaleY + fDelta * 2);
CGRect rHero = CGRectMake(m_hero.position.x - m_hero.contentSize.width * m_hero.scaleX / 2.0f, m_hero.position.y, m_hero.contentSize.width * m_hero.scaleX, m_hero.contentSize.height * m_hero.scaleY);
if(CGRectIntersectsRect(rCoin, rHero)){
coin.tag = DELETED_TAG;
g_nCoin++;
[[AppDelegate getDelegate] playSystemEffect:E_COIN];
// this below code is to show the particle effect and its working perfect
CCParticleSystem *effect = [ARCH_OPTIMAL_PARTICLE_SYSTEM particleWithFile:#"arroweffect.plist"];
[self addChild:effect];
effect.position = ccp(self.contentSize.width * self.scaleX / 2, self.contentSize.height * self.scaleY / 2.0f);
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
effect.scale *= 2;
}
}
}
[[AppDelegate getDelegate] saveSetting];
}
But after I put sprite sheet as animation to show the effect , it is not working , I tried my best but not able to solve this. this is my code for the sprite sheet animation :
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile: #"coinsprite.plist"];
//load the sprite sheet into a CCSpriteBatchNode object. If you're adding a new sprite
//to your scene, and the image exists in this sprite sheet you should add the sprite
//as a child of the same CCSpriteBatchNode object otherwise you could get an error.
CCSpriteBatchNode *parrotSheet12 = [CCSpriteBatchNode batchNodeWithFile:#"coinsprite.png"];
//add the CCSpriteBatchNode to your scene
[self addChild:parrotSheet12];
//load each frame included in the sprite sheet into an array for use with the CCAnimation object below
NSMutableArray *flyAnimFrames12 = [NSMutableArray array];
for(int i = 1; i <=30; ++i) {
[flyAnimFrames12 addObject:
[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:
[NSString stringWithFormat:#"coins%04d.png", i]]];
}
//Create the animation from the frame flyAnimFrames array
CCAnimation *flyAnim12 = [CCAnimation animationWithFrames:flyAnimFrames12 delay:1.0f];
//create a sprite and set it to be the first image in the sprite sheet
CCSprite * dragont2 = [CCSprite spriteWithSpriteFrameName:#"coins0000.png"];
//set its position to be dead center, i.e. screen width and height divided by 2
[dragont2 setPosition:ccp(600,600)];
//[self moveRandom:theParrot];
//create a looping action using the animation created above. This just continuosly
//loops through each frame in the CCAnimation object
CCAction *flyAction12 = [CCRepeatForever actionWithAction:
[CCAnimate actionWithAnimation:flyAnim12 restoreOriginalFrame:NO]];
//start the action
[dragont2 runAction:flyAction12];
//add the sprite to the CCSpriteBatchNode object
[parrotSheet12 addChild:dragont2];
problem got solved
-(void) coinanimationeffect:(CGPoint) ptPos {
m_gamecoinffect = [CCSprite spriteWithSpriteFrameName:#"coins0001.png"];
[self addChild:m_gamecoinffect];
CCAnimate *coineffect = [CCAnimate actionWithSpriteSequence:#"coins%04d.png" numFrames:30 delay:0.01f restoreOriginalFrame:NO];
[m_gamecoinffect runAction:[CCRepeatForever actionWithAction:coineffect]];
m_gamecoinffect.position = ptPos;
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
m_gamecoinffect.scale *= 2;
}
added this function
and call that function in
-(void) checkHeroAndCoins {
float fDelta = 0;
if(m_hero->m_bMagnet)
fDelta = iDevPixelX(30);
for(Coin *coin in m_drawLayer.children){
if([coin isKindOfClass:[Coin class]]){
CGRect rCoin = CGRectMake(coin.position.x - coin.contentSize.width * coin.scaleX / 2.0f - fDelta,
coin.position.y - coin.contentSize.height * coin.scaleY / 2.0f - fDelta,
coin.contentSize.width * coin.scaleX + fDelta * 2, coin.contentSize.height * coin.scaleY + fDelta * 2);
CGRect rHero = CGRectMake(m_hero.position.x - m_hero.contentSize.width * m_hero.scaleX / 2.0f, m_hero.position.y, m_hero.contentSize.width * m_hero.scaleX, m_hero.contentSize.height * m_hero.scaleY);
if(CGRectIntersectsRect(rCoin, rHero)){
coin.tag = DELETED_TAG;
g_nCoin++;
[[AppDelegate getDelegate] playSystemEffect:E_COIN];
[self coinanimationeffect:ccp(coin.position.x, coin.position.y)];
}
}
}
[[AppDelegate getDelegate] saveSetting];
}

Sprite Kit: Rope with SKPhysicsJointLimit breaks under excessive force?

The following code works great. It creates a dangling rope made of square links, and then applies a force to the bottom link to swing it around. It is executed in the SKScene object when the SKScene is created.
However, if you change the force on the last line from 2000 to 4000, the physics go haywire, and the links sometimes break. Sometimes the links seem to be vibrating or they’ll just submit entirely to gravity as if there is no joint. Additionally, if you have other physics bodies, they no longer collide with the haywire links, even if they did before the force was applied.
Although 4000 seems excessive, I’ve encountered this issue with much less force on lighter objects, or smaller forces on ropes with less of a gap between links.
Am I doing something wrong? Is there a bug in Sprite Kit or some other explanation? I couldn’t find any answers online.
It also doesn't matter if the force is applied during SKScene creation or delayed until later.
self.scaleMode = SKSceneScaleModeAspectFit;
self.anchorPoint = CGPointMake(0.5, 0.5);
CGFloat length = 20;
CGFloat gapMult = 1.8;
int numBoxes = 10;
SKSpriteNode *prevBox = nil;
for (int i = 0; i < numBoxes; i++) {
SKSpriteNode *box = [SKSpriteNode spriteNodeWithColor:[UIColor yellowColor] size:CGSizeMake(length, length)];
box.position = CGPointMake(0, -i * length * gapMult);
[self addChild:box];
box.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(length, length)];
if (i == 0) {
box.physicsBody.dynamic = NO;
} else {
CGPoint pt1 = CGPointMake(0, prevBox.position.y - length / 2);
CGPoint pt2 = CGPointMake(0, box.position.y + length / 2);
SKPhysicsJointLimit *joint = [SKPhysicsJointLimit jointWithBodyA:prevBox.physicsBody bodyB:box.physicsBody anchorA:pt1 anchorB:pt2];
[self.physicsWorld addJoint:joint];
}
prevBox = box;
}
[prevBox.physicsBody applyForce:CGVectorMake(2000, 0)];

How to spawn CCSprites in random heights like flappy bird

In the iOS game flappy bird, there are pipes that generate after a certain distance and they generate at random heights
I am also trying to make flappy bird pipes (I called it a tree branch in my code instead of pipe). Except the pipes are moving vertically instead of horizontally because it is a vertical scrolling game (it scrolls like the game doodle jump)
This is a drawing of what I want it to be: https://docs.google.com/drawings/d/18bxsVsNOlScCvgi1mwuzD2At7R6xKM3QCh6BfAVMuMo/edit?usp=sharing
(The horizontal lines are the branches)
So this is what I have tried to do so far to make the vertical branches (or pipes)...
in my .h
CCSprite *branch;
NSMutableArray *_branches;
CCSprite *obstacle;
CCNode *previousBranch;
CGFloat previousBranchYPosition;
in my .m
#implementation HelloWorldLayer
static const CGFloat firstBranchPosition = 426.f;
static const CGFloat distanceBetweenBranches = 140.f;
#define ARC4RANDOM_MAX 0x100000000
static const CGFloat minimumXPositionRightBranch = 280.f;
static const CGFloat maximumXPositionLeftBranch = 50.f;
static const CGFloat pipeDistance = 100.f;
static const CGFloat maximumXPositionRightBranch = maximumXPositionLeftBranch - pipeDistance;
setBranchInitialPosition method
/* This is where I am setting the initial position of the branches.
So I am specifying the position of the first branch and the other branches after it so it gets placed every time a certain distance is passed. I have a left branch and a right branch*/
-(void) setBranchInitialPosition {
CGFloat random = ((double)arc4random() / ARC4RANDOM_MAX);
CGFloat range = maximumXPositionRightBranch - minimumXPositionRightBranch;
_rightBranch.position = ccp(minimumXPositionRightBranch + (random * range), _rightBranch.position.y);
_leftBranch.position = ccp(_rightBranch.position.x + pipeDistance, _leftBranch.position.y);
}
spawnNewBranches method
// This is how I want the branches to spawn and I want to add them to an array full of branches
- (void)spawnNewBranches {
previousBranch = [_branches lastObject];
previousBranchYPosition = previousBranch.position.y;
if (!previousBranch) {
// this is the first obstacle
previousBranchYPosition = firstBranchPosition;
}
_rightBranch = [CCSprite spriteWithFile:#"branch.png"];
_leftBranch = [CCSprite spriteWithFile:#"branch.png"];
[_leftBranch addChild:_rightBranch];
[self setBranchInitialPosition];
obstacle = [CCSprite node];
[obstacle addChild:_leftBranch];
obstacle.position = ccp(160, previousBranchYPosition + distanceBetweenBranches);
[self addChild:obstacle];
[_branches addObject:obstacle];
}
scroll method
-(void) scroll:(ccTime)dt
{
// moves the bg
background.position = ccp(screenCenter.x, background.position.y + [[NSUserDefaults standardUserDefaults] integerForKey:#"scrollSpeed"]*dt);
bg2.position = ccp(screenCenter.x, background.position.y-background.contentSize.height);
// it adds the new bg's to the screen before the old bg's move off the screen
if (background.position.y >= screenSize.height*1.5)
{
background.position = ccp(screenCenter.x, (screenCenter.y)-(background.size.height/2));
} else if (bg2.position.y >= screenSize.height*1.5) {
bg2.position = ccp(screenCenter.x, (screenCenter.y)-(bg2.size.height/2));
}
// This is where I want them to appear every certain distance and also move with the brackground
obstacle.position = ccp(obstacle.position.x, obstacle.position.y*[[NSUserDefaults standardUserDefaults] integerForKey:#"scrollSpeed"]*dt);
NSMutableArray *offScreenObstacles = nil;
if (obstacle.position.y >= screenSize.height*1.5) {
[offScreenObstacles addObject:obstacle];
}
for (CCNode *obstacleToRemove in offScreenObstacles) {
[obstacleToRemove removeFromParent];
[_branches removeObject:obstacleToRemove];
// for each removed obstacle, add a new one
[self spawnNewBranches];
}
}
Right now, the branches are appearing, but they stay in the bottom left corner and they dont move or spawn at all. I want to make them move with the background and spawn after a certain distance while also being generated in random heights. I provided you with all my code, do you know how I can make this work? Thanks in advance!
You may want to try placement of the pipes based on a trigonometric curve like sine or cosine (https://en.wikipedia.org/wiki/Trigonometric_functions). It seems like you are placing the pipes within a fairly define random range though if you change this range to an offset from the plot of the trigonometric curve it would take into account the ability of the player to transition between the open gaps better. At least that's my feel. I think the code would be easier to follow as well as I'm a bit confused going through it. You can also easily vary the difficulty of the curve by changing the parameters such as increasing the amplitude or frequency.
I created a copy of Flappy Bird just for fun. I used this code to create the pipes:
-(void)createPipes{
//Create Random
int from = 65;
int max = [[UIScreen mainScreen] bounds].size.height - 124;
int delta = max - from - dy;
int y = from + arc4random() % (delta - from);
//Pipe Bottom
UIImageView *pipeBottom = [[UIImageView alloc] init];
[pipeBottom setContentMode:UIViewContentModeTop];
[pipeBottom setImage:[UIImage imageNamed:#"pipeBottom"]];
[pipeBottom setFrame:CGRectMake(320, y+dy, 60, max - y - dy)];
[pipeBottom setClipsToBounds:YES];
//Pipe Top
UIImageView *pipeTop = [[UIImageView alloc] init];
[pipeTop setFrame:CGRectMake(320, 0, 60, y)];
[pipeTop setContentMode:UIViewContentModeBottom];
[pipeTop setImage:[UIImage imageNamed:#"pipeTop"]];
[self.view insertSubview:pipeTop atIndex:1];
[self.view insertSubview:pipeBottom atIndex:1];
if (!self.pipes)
self.pipes = [[NSMutableArray alloc] init];
[self.pipes addObject:pipeBottom];
[self.pipes addObject:pipeTop];
}
and to move them:
-(void)moveArray:(NSMutableArray *)array{
float ds = dv * dt;
NSMutableArray *trash = [NSMutableArray array];
for (UIImageView *obj in array) {
CGRect frame = obj.frame;
frame.origin.x -= ds;
if (frame.origin.x < -frame.size.width) {
[obj removeFromSuperview];
[trash addObject:obj];
}else{
obj.frame = frame;
}
}
[array removeObjectsInArray:trash];
}
-(void)movePipes{
[self moveArray:self.pipes];
}
I call this function every 0.01 seconds, to run the game:
-(void)runGame{
_time += dt;
if (_time >= 180.0/dv) {
_time = 0;
[self createPipes];
}
[self movePipes];
[self moveEnemies];
[self moveYoshi];
[self moveBar];
[self verifyScore];
[self verifyCollision];
[self verifyState];
}
I defined dt = 0.01 and dv = 110.
You can see my parody in youtube: (http://www.youtube.com/watch?v=tTcYdpSIKJg)
I hope this help you.
Best, Rafael Castro.

Cocos2D & ccDrawLine - Drawing smooth lines

I have some troubles when I try to draw lines with cocos2d! I store points, got from touchMoved method, in a NSMutableArray, and pass that array to a subclass of CCNode called Lines that I use to draw the lines from the array of points. The problem is that the line is not smooth when I swipe slowly, but when I swipe faster, the line is way much smoother. See the pictures below :
Slow Swipe :
Fast Swipe :
I tried to solve the problem with ccpDistance, which calculate the distance between the last saved point and if it's not far enough I don't save it. I also tried to draw little circles at each saved positions, but this isn't really nice neither. Here's my code :
In my GameScene :
- (void) ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event
{
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
if (ccpDistance(lastPoint, location) > 10) {
//SAVE THE POINT
[linePoints addObject:[NSValue valueWithCGPoint:location]];
[line updatePoints:linePoints];
lastPoint = location;
}
}
And my Line Class :
- (void) updatePoints:(NSMutableArray *)_point
{
points = _point;
}
- (void) draw
{
if ([points count] > 0) {
ccGLEnable(GL_LINE_STRIP);
ccDrawColor4B(209, 75, 75, 255);
float lineWidth = 6.0 * CC_CONTENT_SCALE_FACTOR();
glLineWidth(lineWidth);
int count = [points count];
for (int i = 0; i < (count - 1); i++){
CGPoint pos1 = [[points objectAtIndex:i] CGPointValue];
CGPoint pos2 = [[points objectAtIndex:i+1] CGPointValue];
ccDrawLine(pos1, pos2);
ccDrawSolidCircle(pos2, 2.5, 20);
}
}
}
Also, is there something in my code that could be done better to improve performance? Right now I don't have any problems even with 1000+ points, but just in case...
Any help will be greatly appreciated! Thanks in advance!
Ok, I found a website explaining really clearly how to do smooth lines, and it worked wonderfully! There's still anti-aliasing that's left to do, but maybe I will never do, since it looks really great on retina devices. Here's the website : Drawing Smooth Lines with Cocos2D
And here's the result :
Also, for those interested in the finished code, here it is :
Line.m
- (void) drawCurPoint:(CGPoint)curPoint PrevPoint:(CGPoint)prevPoint
{
float lineWidth = 6.0;
ccColor4F red = ccc4f(209.0/255.0, 75.0/255.0, 75.0/255.0, 1.0);
//These lines will calculate 4 new points, depending on the width of the line and the saved points
CGPoint dir = ccpSub(curPoint, prevPoint);
CGPoint perpendicular = ccpNormalize(ccpPerp(dir));
CGPoint A = ccpAdd(prevPoint, ccpMult(perpendicular, lineWidth / 2));
CGPoint B = ccpSub(prevPoint, ccpMult(perpendicular, lineWidth / 2));
CGPoint C = ccpAdd(curPoint, ccpMult(perpendicular, lineWidth / 2));
CGPoint D = ccpSub(curPoint, ccpMult(perpendicular, lineWidth / 2));
CGPoint poly[4] = {A, C, D, B};
//Then draw the poly, and a circle at the curPoint to get smooth corners
ccDrawSolidPoly(poly, 4, red);
ccDrawSolidCircle(curPoint, lineWidth/2.0, 20);
}
- (void) draw
{
if ([points count] > 0) {
ccGLEnable(GL_LINE_STRIP);
ccColor4F red = ccc4f(209.0/255.0, 75.0/255.0, 75.0/255.0, 1.0);
ccDrawColor4F(red.r, red.g, red.b, red.a);
float lineWidth = 6.0 * CC_CONTENT_SCALE_FACTOR();
glLineWidth(lineWidth);
int count = [points count];
for (int i = 0; i < (count - 1); i++){
CGPoint pos1 = [[points objectAtIndex:i] CGPointValue];
CGPoint pos2 = [[points objectAtIndex:i+1] CGPointValue];
[self drawCurPoint:pos2 PrevPoint:pos1];
}
}
}
As for the GameScene, nothing changed there (See the question for the code)! Note that you can change the line if (ccpDistance(lastPoint, location) > X), where X is the minimum distance between two points before the game saves another one. The lower X is, the smoother the line will be, but you will have way more points in your array, which could affect performance!
Anyway, thank you guys for your suggestions and your help, it helped me to get in the right way!
I think that you could smooth up your line drawing with some averaging.
- (void) updatePoints:(NSMutableArray *)_point
{
points = _point;
int count = [points count];
for (int i = 3; i < (count - 4); i++) {
CGPoint pos1 = [[points objectAtIndex:i - 2] CGPointValue];
CGPoint pos2 = [[points objectAtIndex:i - 1] CGPointValue];
CGPoint pos3 = [[points objectAtIndex:i] CGPointValue];
CGPoint pos4 = [[points objectAtIndex:i + 1] CGPointValue];
CGPoint pos5 = [[points objectAtIndex:i + 2] CGPointValue];
CGFloat xpos = (pos1.x + pos2.x + 2 * pos3.x + pos4.x + pos5.x)/6;
...
(now calcuclate ypos similarly and store the point into an array)
}
}

Set sprite using background position

I am new to cocos2d so please help me if u can
I have background moving from right to left, and the background contains small windows with 3 rows of windows
_spaceDust1 = [CCSprite spriteWithFile:#"bg_front_spacedust.png"];
_spaceDust2 = [CCSprite spriteWithFile:#"bg_front_spacedust.png"];
CGPoint dustSpeed = ccp(0.1 , 0.1);
CGPoint bgSpeed = ccp(0.05 , 0.05);
[_backgroundNode addChild:_spaceDust1 z:0 parallaxRatio:dustSpeed positionOffset:ccp(0,winSize.height / 2)];
[_backgroundNode addChild:_spaceDust2 z:0 parallaxRatio:dustSpeed positionOffset:ccp(_spaceDust1.contentSize.width , winSize.height / 2)];
Now add enemies wich also move from right to left with same speed
_robbers = [[CCArray alloc] initWithCapacity:kNumAstroids];
for (int i = 0; i < kNumAstroids; ++i) {
CCSprite *asteroid = [CCSprite spriteWithSpriteFrameName:#"robber.png"];
asteroid.visible = NO;
[_batchNode addChild:asteroid];
[_robbers addObject:asteroid];
}
in update method:
double curTime = CACurrentMediaTime();
if (curTime > _nextRunemanSpawn) {
float randSecs = [self randomValueBetween:0.20 andValue:1.0];
_nextRunemanSpawn = randSecs + curTime;
float randY = 80.0;
float randY1 = 185.0;
float randY2 = 293.0;
float randDuration = [self randomValueBetween:5.2 andValue:5.2];
float randDuration1 = [self randomValueBetween:1.0 andValue:1.0];
CCSprite *asteroid = [_robbers objectAtIndex:_nextRobber];
_nextRobber++;
if (_nextRobber >= _robbers.count) {
_nextRobber = 0;
}
//[asteroid stopAllActions];
int winChoice = arc4random() % 3;
if (winChoice == 0) {
asteroid.position = ccp(winSize.width +asteroid.contentSize.width / 2 , randY);
asteroid.visible = YES;
}
else if(winChoice == 1){
asteroid.position = ccp(winSize.width +asteroid.contentSize.width / 2 , randY1);
asteroid.visible = YES;
}else {
asteroid.position = ccp(winSize.width +asteroid.contentSize.width / 2 , randY2);
asteroid.visible = YES;
}
[asteroid runAction:[CCSequence actions:[CCMoveBy actionWithDuration:randDuration position:ccp(-winSize.width-asteroid.contentSize.width, 0)],
[CCCallFuncN actionWithTarget:self selector:#selector(setInvisible:)],nil]];
All is going well but i want to set this enemies in to window and in random position
so how can i set x-argument of enemies so it can be fix in to window of the background?
For some reason I cannot comment so this is written as an answer. What exactly are you trying to do? I am a bit confused. It sounds like you want the X position to be set so that it is in one of 3 random positions, is that correct?

Resources