I have a node. In this particular case, it's a CCLayer, but I'm looking for a general solution. My node is centered at point1 (let's say { 100, 100 }). I'd like it to move to point1 (say { 200, 200 }) over the course of 0.5 seconds.
Really simple stuff, right? But I'm just not finding the docs/tutorials I need to do it.
Hints?
Thanks!
Extra credit: same question with a CC3Node, if the answer is different. :)
You can move anything inherits CCNode using runAction: [CCMoveTo actionWithDuration: 0.5 position:ccp(x,y)]
http://www.cocos2d-iphone.org/wiki/doku.php/prog_guide:actions
// assuming you've already got a CCLayer called "myLayer"
[myLayer runAction:[CCMoveTo actionWithDuration:0.5 position:ccp(200,200)]];
EDIT: Changed to CCMoveTo rather than CCMoveBy after re-reading the question.
/*
Moving an entire layer including all of his children (sprites, labels etc.). Insert this code into your 'init' method which belongs to the layer you'd like to be moved to the new point. X and Y are exactly coords of the new position of the layer relative to his center.
Example: x = 0; x = 100; in this case the layer will be moving vertical.
*/
x = ?; // X value
y = ?; // Y value
[self runAction:[CCMoveTo actionWithDuration:5.0f position:ccp(x, y)]];
Are you trying to move the layer or does your layer contain sprites that you want to move? i am not sure if it is even possible to move a layer (or stacks of layers) that contain childs (ccnodes, ccsprites, etc.).
My advice would be to move the layers child elements using ccanimation/ccmoveby/ccmoveto/etc.
Related
I've been working on a top view game, where there're two virtual joysticks present to control a character. For the joysticks, I've used Spritekit-Joystick. The character shoots automatically. The right Joystick is used for changing direction, and I have implemented this function to move the character:
-(void)update:(CFTimeInterval)currentTime {
/* Called before each frame is rendered */
if (self.imageJoystick.velocity.x != 0 || self.imageJoystick.velocity.y != 0)
{
myCharacter.zRotation = self.imageJoystick.angularVelocity;
}
}
For the self.imageJoystick.angularVelocity, the Joystick library uses this code (the code is available from the link above, but just for the sake of making things easier and more readily available):
angularVelocity = -atan2(thumbNode.position.x - self.anchorPointInPoints.x, thumbNode.position.y - self.anchorPointInPoints.y);
There' a problem with the rotation. When I push the joystick (thumbnode) up, the rotation points to the right. I've used NSLog to get the value, and it shows around 0. When I push the joystic (thumbnode above) to the left, the character points upwards, and I get around 1.5 reading for angularVelocity. Pushing it down points the character to left and gives a -3 reading. Finally, when I push right, I point the character to South, and geta reading of around 1.5.
The same thing happens with the 'bullets' I shoot out. For now I'm using beams, which I found the answer in this [POST] on here2. I have added it below for your convenience (Not my answer, but I've changed it to be used in my game):
[[self childNodeWithName:#"RayBeam"]removeFromParent];
int x = myCharacter.position.x + 1000 * cos(myCharacter.zRotation);
int y = myCharacter.position.y + 1000 * sin(myCharacter.zRotation);
SKShapeNode* beam1 = [SKShapeNode node];
CGMutablePathRef pathToDraw = CGPathCreateMutable();
CGPathMoveToPoint(pathToDraw, NULL, myCharacter.position.x, myCharacter.position.y);
CGPathAddLineToPoint(pathToDraw, NULL, x, y);
beam1.path = pathToDraw;
[beam1 setStrokeColor:[UIColor redColor]];
[beam1 setName:#"RayBeam"];
[self addChild:beam1];
The exact same thing happens. When I 1) push the joystick up, I shoot to right. 2) push the joystick to the left, I shoot Upward. 3) push downward, I shoot left, and 4) when I push the joystick to the right, I shoot downward.
I think I need to tweek the math and trigonometry equations, but maths isn't my forte, and I'm relatively new to this.
The image below is the image of the game (it's not completed at all), and you can see I'm pushing up but I'm pointing, and shooting to right.
Note: my sprite is also point to the right by default. I tried rotating all my sprites counter clockwise, and that works with the sprites, but not with the beam.
I really appreciate your help.
Thank you in advance.
If up is 0 radians then you should be calculating your beam's x and y with:
int x = myCharacter.position.x - 1000 * sin(myCharacter.zRotation);
int y = myCharacter.position.y + 1000 * cos(myCharacter.zRotation);
If I'm trying to spawn in enemies in 2 defined areas of the screen (top and bottom with a middle section where they can't spawn in), how do I prevent them from spawning on top of or too near each other .
My sprites are relatively quite small to the screen, and the only suggestion I've found on here is to create an array of possible positions and every time you use one of those positions take it off the list, but first of all I don't know how that would even look, second of all I've got SO many possible positions because I'm working with 5px high sprites, and I want for them to be able to respawn once that area is clear.
My method of choosing top or bottom is just picking a random number 1 or 2, and depending I've got 2 functions that make them either on top or on bottom.
I just need for no 2 objects to spawn in a ball's diameter from each other. Any ideas how to incorporate that into my spawning?
edit:
//Create your array and populate it with potential starting points
var posArray = Array<CGPoint>()
posArray.append((CGPoint(x: 1.0, y: 1.0))
posArray.append((CGPoint(x: 1.0, y: 2.0))
posArray.append((CGPoint(x: 1.0, y: 3.0))
//Generate an enemy by rolling the dice and
//remove its start position from our queue
let randPos = Int(arc4random()) % posArray.count
posArray[randPos]
posArray.removeAtIndex(randPos)
...
//Play game and wait for enemy to die
//Then repopulate the array with that enemy's start position
posArray.append(enemyDude.startPosition)
This is the recommendation I found, but this gives errors "expected separator" that I don't really know how to fix.
And so really, I'd have to make a HUGE array of possible positions going across the X and Y covering all areas, or is there some better way to do this?
Not spawning a node on top of another is simply enough by using intersectsNode(_ node: SKNode) -> Bool.
As for not spawning too close, that's another story. The only way you can do that is too have all your current nodes in an array, enumerate the array and check each node's position to that of the spawning node. Dependent on your parameters, you either spawn or not spawn.
I am not versed in Swift so you will have to translate the code yourself.
-(void)testMethod {
// an array with all your current nodes
NSMutableArray *myArray = [NSMutableArray new];
// the potential new spawn node with the proposed spawn position
SKSpriteNode *mySpawnNode = [SKSpriteNode new];
BOOL tooClose = NO;
// enumerate your node array
for(SKSpriteNode *object in myArray) {
// get the absoulte x and y position distance differences of the spawn node
// and the current node in the array
// using absolute so you can check both positive and negative values later
// in the IF statement
float xPos = fabs(object.position.x - mySpawnNode.position.x);
float yPos = fabs(object.position.y - mySpawnNode.position.y);
// check if the spawn position is less than 10 for the x or y in relation
// to the current node in the array
if((xPos < 10) || (yPos < 10))
tooClose = YES;
}
if(tooClose == NO) {
// spawn node
}
}
Note that the array should be a property and not declared in the scope I have it in the example.
I'm trying to add perspective to a view by using CATransform3D. Currently, this is what I'm getting:
And this is what I wanna get:
I'm having a hard time doing that. I'm completely lost here. Here's my code:
CATransform3D t = CATransform3DIdentity;
t.m11 = 0.8;
t.m21 = 0.1;
t.m31 = -0.1;
t.m41 = 0.1;
[[viewWindow layer] setTransform:t];
Matrix element .m34 is responsible for perspective. It's not discussed much in the documentation, so you'll have to toy with it. This answer talks a little bit about how to use it: https://stackoverflow.com/a/7596326/1228525
To actually see the effects of that matrix you need to do two things:
1. Apply that perspective matrix to the parent view's sublayer transform
2. Rotate the child view (the one on which you want perspective) - otherwise it will remain flat and you won't be able to tell it now has a 3D perspective.
The numbers are arbitrary, make them whatever looks best:
CATransform3D t = CATransform3DIdentity;
t.m34 = .005;
parentView.layer.sublayerTransform. = t;
childview.layer.transform = CATransform3DMakeRotation(45,1,0,0);
The perspective will look different depending on where the child is in the parent view. If the child is in the center of the parent it will be like you are looking at the child view in 3D straight on. The further from the center it is, the more it will be like you are viewing from a glancing angle.
This is what I got using the above code and centering the child view: (apparently I'm not allowed to post pictures since I'm new, so you'll have to see the link) http://i.stack.imgur.com/BiYCS.png
It's very hard to tell what you're going for based on those pictures; a bit more explanation might be helpful if my answer isn't what you want. From what I can tell from the picture, the bottom one isn't perspective...
I was able to easily achieve the right CATransform3D using AGGeometryKit.
#import <AGGeometryKit/AGGeometryKit.h>
UIView *view = ...; // create a view
// setting anchorPoint to zero
view.layer.anchorPoint = CGPointZero;
view.layer.transform = CATransform3DMakeTranslation(-view.layer.bounds.size.width * .5, -view.layer.bounds.size.height * .5, 0);
// setting a trapezoid transform
AGKQuad quad = view.layer.quadrilateral;
quad.tl.x -= 10; // shift top left x-value with 10 pixels
view.layer.quadrilateral = quad; // the quad is converted to CATransform3D and applied
I've using cocos2d for a while and I want to make a battleship game.
The thing is I can probably do a battleship with UiKit(UIButtons and UIImageView) easier and faster than in cocos2d but I want to take full advantage of cocos2d because I think it's better for games. The problem is that I need a grid for the battleship or something to separate the touches in quadrants. Is there something like a gridview in cocos2d? If not I think I would have to create my own quadrants by programming?
What do you think is the best method?
Thanks a lot
Carlos Vargas
There's not a base class in Cocos2d to do that, but you could easily make a Class specifically designed to handle touches, and mapping them to the correct quadrants.
So if you have a 480x320 screen, and quadrant size is 32, you can get the correct quadrant for a touch like:
With a configuration like this you would have 480/32 = 15 , 320/32 = 10, 10*15 = 150; a 150 quadrants grid.
e.g: To get the quadrant for a touch
// Defined the Quadrant size for your grid
CGPoint quadrantSize = CGPointMake(32.0, 32.0)
// Obtain the quadrant X, Y coordinates for a user touch (assume touchPoint is CGPoint)
int quadrant_x = (int)ceilf(touchPoint.x/quadrantSize.x);
int quadrant_y = (int)ceilf(touchPoint.y/quadrantSize.y);
// Access a Quadrant
quadrantArray[quadrant_x][quadrant_y].touched = YES;
How can I make such an interface with cocos2d for iphone? Cortex interface
I already made a subclass of CCSprite and override the draw
method like this:
-(void)draw {
ccDrawCircle(CGPointMake(480/2, 320/2), 70, 0, 50000, NO);
ccDrawCircle(CGPointMake(480/2, 320/2), 25, 0, 50000, NO);
ccDrawLine(CGPointMake(480/2, 320/2+25), CGPointMake(480/2, 320/2+70));
ccDrawLine(CGPointMake(480/2+25, 320/2), CGPointMake(480/2+70, 320/2));
ccDrawLine(CGPointMake(480/2, 320/2-25), CGPointMake(480/2, 320/2-70));
ccDrawLine(CGPointMake(480/2-25, 320/2), CGPointMake(480/2-70, 320/2));
}
The problem is that I don't have any control over the circle (can't set the position of it)...and i don't know how to place text/images into these "cells". Another problem is the touch detection..mayby just cgrects? but what if i have more than 4 cells and one cell is "rotated"?
Any ideas?
I think you have two options here, but I don't recommend subclassing CCSprite, infact very rarely would recommend doing so, theres almost no need to.
In my opinion, you could do either of these to get your image.
1. Use OpenGL to draw your image.
2. Use CCSprite to draw your image. (Cleaner)
Once you have drawn it, its simply a matter of creating it when you press down on the screen.
Once you press down on the screen (or any prescribed object) I would then employ a simple trigonometric solution.
This is the algorithm I would use:
Press down on screen, Get the position of touch. (sourcepos) and create your cortex img
On Movement of finger on screen, get the position (currentpos) the angle and magnitude in relation to the original (sourcepos) touch.
Now, using simple angles we can install different bounds on your CCSprite using if statements. Its also a good idea to use #define kMinMagnitude X statement to ensure the user moves their finger adequately.
I suppose you can either execute the //Load Twitter or Load Facebook either on the movement or the cancelation of a touch. Thats entirely up to you.
(PSUDOCODE):
dx = currentpos.x - sourcepos.x
dy = currentpos.y - sourcepos.y
mag = sqrt(dx*dx + dy*dy);
ang = CC_RADIANS_TO_DEGREES(atan2f(dy/dx));
if (ang > 0 && ang < 80 && mag > kMinMagnitude) //Load Twitter
if (ang > 80 && ang < 120 && mag > kMinMagnitude) //Load facebook
I don't think making a subclass of CCSprite is the right choice here. You will probably want a NSObject that creates the CCSprites for you.
Also CCSprite.position = CGPointMake( X, Y ) should allow you to set the position of the sprite. Don't forget to add it to a layer just like any other CCNode object.