I have following code in my Application.
I am new to game development in iPhone using COCOS.
Sprite *bg=[Sprite spriteWithFile:#"menu.png"];
[bg setPosition:ccp(240,160)];
[self addChild:bg z:0];
[self addChild:[GameLayer node] z:1];
}
return self;
}
#end
#implementation GameLayer
-(id)init{
if(self=[super init]){
Label *test=[Label labelWithString:#"Hello World" fontName:#"Helvetica" fontSize:24];
test.position=cpv(160, 240);
test.visible=YES;
[self addChild:test];
}
return self;
}
What is the function of ccp & cpv?
( I think it is for setting the layer's position, But I am not sure. So I am Asking)
Sagar
ccp is a simple macro defined by COCOS to easily create a CGPoint. So it's nothing more than just a point (x,y coordinate) It is defined as:
#define ccp(__X__,__Y__) CGPointMake(__X__,__Y__)
position is a property of the Label object, which probably sets the position on the screen to the point created by ccp(). I don't know which corner is being used as a reference point (center/top-left/bottom-left?) as I've never used COCOS so please try that yourself.
Good luck
From the source code:
From CGPointExtension.h
#define ccp(__X__,__Y__) CGPointMake(__X__,__Y__)
From cpVect.h
#define cpVect CGPoint
static inline cpVect cpv(const cpFloat x, const cpFloat y)
{
cpVect v = {x, y};
return v;
}
Related
i have his code for making movemnt of the object through horizontal postion.
#define kAccelerationSpeed 10
#define kAccelerometerFrequency 200
-(void) accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
CGPoint pt = thePlayer.position ;
CGFloat accel = acceleration.x * kAccelerationSpeed;
pt = [[CCDirector sharedDirector] convertToGL:pt];
pt = ccp (pt.x+accel>0 , yLocationOfPlayer+accel<768 );
}
in init statment
-(id) init
{
// always call "super" init
// Apple recommends to re-assign "self" with the "super" return value
if( (self=[super init])) {
[[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0 / kAccelerometerFrequency)];
[[UIAccelerometer sharedAccelerometer] setDelegate:self];
}
whats wrong with the above code,it is not working,when i tilt the screen,it is not making any movemnt for the "theplayer" object.please help me to do this.
thanks in advance.
Are you sure your delegates are setup to report accelerometer information? Are you also assigning thePlayer.position in the accelerometer callback? I can't recall why but I do recall trying assignment within the callback and the results were rather stuttered and problematic. The solution for me was to have a variable the accelerometer delegate call will modify and assign the position of thePlayer inside of a tick script based on the variable update in the delegate callback.
you're not assigning the position of the player sprite. Try this:
NSLog(#"position before = %#", [NSValue valueWithCGPoint:thePlayer.position]);
thePlayer.position = ccp (pt.x+accel>0 , yLocationOfPlayer+accel<768 );
NSLog(#"position after = %#", [NSValue valueWithCGPoint:thePlayer.position]);
The logging will help you to determine if 1) the delegate method is getting fired and 2) the positions are as you are expecting.
In an cocos 2d game i user 3 heart sprites to update lives of hero.If hero lost one life..one heart should be hided.
I use below code but its not working properly.please help me.
- (void)updateLives {
int i = _lives;
[self livess:(int)i];
}
- (void)livess:(int)ii {
CGSize winSize = [CCDirector sharedDirector].winSize;
heart1=[CCSprite spriteWithFile:#"heart.png"];
heart2=[CCSprite spriteWithFile:#"heart.png"];
heart3=[CCSprite spriteWithFile:#"heart.png"];
[heart1 setPosition:ccp(winSize.width/2*1.3, winSize.height * 0.9)];
[self addChild:heart1 z:0];
[heart2 setPosition:ccp(winSize.width/2*1.1, winSize.height * 0.9)];
[self addChild:heart2 z:0];
[heart3 setPosition:ccp(winSize.width/2*0.9, winSize.height * 0.9)];
[self addChild:heart3 z:0];
if (ii==3) {
NSLog(#"%d",ii);
}
else if (ii==2)
{
NSLog(#"%d",ii);
[heart3 setVisible:NO];
} else if (ii==1)
{
NSLog(#"%d",ii);
[heart3 setVisible:NO];
[heart2 setVisible:NO];
}
else
{
}
}
note:in above code..nslog is printing correct values ..for example 1,2
It should hide correctly from your code. However, if this updateLives is called inside the game loop, probably the reason you see it is not hided as you expected is the heart from the previous frame. Try
1) creating the heart1, heart2, heart3 once
2) in the update, don't create the sprite. i.e. keep only if... else part of your code there.
Hope it helps.
I want a snow particle effect to follow my sprite and I tried some methods but all that ends up happening is the snow will just stay still instead of following. I did this one tutorial (will post as soon as I find it) thats shows how it do it with fire but didn't work out at all. Any tutorials or suggestions will be appreciated. I believe i have to add some kind of code to the snippet part where it says create enemy off screen.
[self schedule:#selector(gameLogicboss:) interval:180 ];
[self schedule:#selector(updateboss:)];
-(void)addTarget1 {
Boss *target1 = nil;
if ((arc4random() % 2) == 0) {{
target1 = [WeakAndFastBoss boss];
}} else {
target1 = [WeakAndFastBoss boss];
}
// Determine where to spawn the target along the Y axis
CGSize winSize = [[CCDirector sharedDirector] winSize];
int minY = target1.contentSize.height/2;
int maxY = winSize.height - target1.contentSize.height/2;
int rangeY = maxY - minY;
int actualY = (arc4random() % rangeY) + minY;
// Create the target slightly off-screen along the right edge,
// and along a random position along the Y axis as calculated above
target1.position = ccp(winSize.width + (target1.contentSize.width/2), actualY);
[self addChild:target1 ];
// Determine speed of the target
int minDuration = target1.minMoveDuration;
int maxDuration = target1.maxMoveDuration;
int rangeDuration = maxDuration - minDuration;
int actualDuration = (arc4random() % rangeDuration) + minDuration;
// Create the actions
id actionMove = [CCMoveTo actionWithDuration:actualDuration position:ccp(-target1.contentSize.width/2, actualY)];
id actionMoveDone = [CCCallFuncN actionWithTarget:self
selector:#selector(spriteMoveFinished:)];
[target1 runAction:[CCSequence actions:actionMove, actionMoveDone, nil]];
target1.tag = 1;
[_targets addObject:target1];
}
-(void)gameLogicboss:(ccTime)dt {
[self addTarget1];
iterations_++;
}
- (void)updateboss:(ccTime)dt {
CGRect projectileRect = CGRectMake(projectile.position.x - (projectile.contentSize.width/2), projectile.position.y - (projectile.contentSize.height/2), projectile.contentSize.width, projectile.contentSize.height);
BOOL bossHit = FALSE;
NSMutableArray *targetsToDelete = [[NSMutableArray alloc] init];
for (CCSprite *target1 in _targets) {
CGRect target1Rect = CGRectMake(target1.position.x - (target1.contentSize.width/2), target1.position.y - (target1.contentSize.height/2), target1.contentSize.width, target1.contentSize.height);
if (CGRectIntersectsRect(projectileRect, target1Rect)) {
//[targetsToDelete addObject:target];
bossHit = TRUE;
Boss *boss = (Boss *)target1;
boss.hp--;
if (boss.hp <= 0) {
_score ++;
[targetsToDelete addObject:target1];
}
break;
}
}
for (CCSprite *target in targetsToDelete) {
[_targets removeObject:target];
[self removeChild:target cleanup:YES];
_projectilesDestroyed++;
if (_projectilesDestroyed > 2) {
}
}
if (bossHit) {
//[projectilesToDelete addObject:projectile];
[[SimpleAudioEngine sharedEngine] playEffect:#"explosion.caf"];
}
[targetsToDelete release];
}
-(void)spriteMoveFinishedboss:(id)sender {
CCSprite *sprite = (CCSprite *)sender;
[self removeChild:sprite cleanup:YES];
GameOverScene *gameOverScene = [GameOverScene node];
[gameOverScene.layer.label setString:#"You Lose"];
[[CCDirector sharedDirector] replaceScene:gameOverScene];
if (sprite.tag == 1) { // target
[_targets removeObject:sprite];
} else if (sprite.tag == 2) { // projectile
[_projectiles removeObject:sprite];
}
}
I Have found this, at CCParticleSystem.h
/** #typedef tCCPositionType
possible types of particle positions
/
typedef enum {
/* Living particles are attached to the world and are unaffected by emitter repositioning. */
kCCPositionTypeFree,
/** Living particles are attached to the world but will follow the emitter repositioning.
Use case: Attach an emitter to an sprite, and you want that the emitter follows the sprite.
*/
kCCPositionTypeRelative,
/** Living particles are attached to the emitter and are translated along with it. */
kCCPositionTypeGrouped,
you should set it like
myparticleSystem.positionType=kCCPositionTypeGrouped;
Hope it helps.
You don't need to update the particle emitter's position with the sprite.
You can add a particle system to the sprite as a child.
The particle system does need to be typed as such:
CCParticleSystem * booster = [CCParticleSystem particleWithFile:#"boosterParticles.plist"];
//customize your particles' options
//assuming you have a sprite defined as _motherShip
[_motherShip addChild:booster];
/*
* now that the particles are the _motherShip's child, you must remember
* to set the position relative to the mothership's origin...
*/
particles.position = ccp(15,0);
...So now whenever _motherShip.position changes, the booster will follow. It will even rotate with the ship.
Very simple logic without getting into code:
I spawn a sprite and give it a location (x, y).
For each sprite, I also spawn a CCParticleSystem, give it the required particle type, spawn rates etc.
The CCParticleSystem location is now set to be the same (x,y) location as the sprite, and it should get updated as the sprite's (x,y) location is update.
As the sprite and the CCParticleSystem move around, this location (x, y) is getting updates constantly at random in your schedule method per the interval step time.
Hope that makes sense.
I do this
vehicleParticleSystem = [CCParticleSystemQuad particleWithFile:#"vehicleParticle.plist"];
vehicleParticleSystem.position = ccp(_ship.position.x - _ship.contentSize.width/3, _ship.position.y - _ship.contentSize.height/3);
if (UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPad) {
vehicleParticleSystem.scale = 0.5;
}
[self addChild:vehicleParticleSystem z:-1];
and update its position with this
- (void) updateParticleSystem:(ccTime)dt {
vehicleParticleSystem.position = ccp(_ship.position.x - _ship.contentSize.width/3, _ship.position.y - _ship.contentSize.height/3);
}
which is called in the -(void) update:(ccTime)dt method.
The ship is moved by the user via a joypad.
hope this helps. The positioning for the particle is slightly behind the vehicle for an engine effect.
Did you tried to update your particle position taking advantage of the update method?
I'm doing something like the following lines in one of my games and it works as I think you expect
-(void) update:(CCTime)delta{
_sprite.position = CGPointMake(newXPosition, newYPosition);
_fire.position = CGPointMake(_sprite.position.x, _sprite.position.y);
}
I hope it helps!
As a very beginner in Cocos2D i´m trying to make an iPhone game where some cows move randomly around the screen. I used the code for moving the sprites from here: highoncoding.com/.../. I´m adding the sprites in the init method wia an addAnimal method:
-(void) addAnimal {
animal = [CCSprite spriteWithFile:#"cow.png"];
animal.position = [self generateRandomCoordinates];
[self addChild:animal];
[self startAnimation:animal];
}
My problem:
When i add more than one cow to my game, they move from that random spawn position to another random position and then the first cow stops and the other cow goes on correctly. The startAnimation command in the finishedMoving method goes always to the last sprite. That means i need better control over my sprites but how to da that right?
You can try to implement animal class, that will contain your sprite and incapsulate random movement. Smth like
#implementation Cow
- (id) init
{
self = [super init];
if( self != nil )
{
CCSprite* cowSprite = [CCSprite spriteWithFile:#"cow.png"];
[self addChild: cowSprite];
}
return self;
}
- (void) onEnter
{
[super onEnter];
[self makeRandomMovement];
}
- (void) makeRandomMovement
{
id randomMoveAction = // create your random move action here
id moveEndCallback = [CCCallFunc actionWithTarget: self selector: #selector(makeRandomMovement)];
id sequence = [CCSequence actionOne: randomMoveAction two: moveEndCallback];
[self runAction: sequence];
}
#end
In such way after ending random movement part, method makeRandomMovement will be called again to generate and start new random movement part.
then remake your addAnimal method to smth like
- (void) addAnimal
{
Cow* newCow = [Cow node];
[newCow setPosition: [self generateRandomPosition]];
[self addChild: newCow];
}
I'm new to Objective C and app development so please go easy on me!
I'm trying to make a basic game and need to move a sprite left or right continuously while the user's finger is on the screen - left side to go left, right to go right...
I'm trying to use update to repeat movements of a few pixels every 1/60th second. So far, this is what I have (and sorry about the formatting):
#import "GameplayLayer.h"
#implementation GameplayLayer
-(id)init {
self = [super init];
if (self != nil) {
CGSize screenSize = [CCDirector sharedDirector].winSize;
// enable touches
self.isTouchEnabled = YES;
blobSprite = [CCSprite spriteWithFile:#"blob.png"];
[blobSprite setPosition: CGPointMake(screenSize.width/2, screenSize.height*0.17f)];
ball = [CCSprite spriteWithFile:#"ball.png"];
[ball setPosition:CGPointMake(10, screenSize.height*0.75f)];
[self addChild:blobSprite];
[self addChild:ball];
[self schedule:#selector(update) interval:1.0f/60.0f];
}
return self;
}
-(void) update:(ccTime)dt{
if (_tapDownLeft == YES){
blobSprite.position.x==blobSprite.position.x-5;
}
if (_tapDownRight == YES){
blobSprite.position.x==blobSprite.position.x+5;
}
}
-(void) ccTouchesBegan:(UITouch*)touch withEvent: (UIEvent *)event{
CGPoint touchLocation = [touch locationInView:[touch view]];
touchLocation = [[CCDirector sharedDirector] convertToGL:touchLocation];
if (touchLocation.x > 400) {
if ((blobSprite.position.x+10)<460){
_tapDownRight = YES;
}
}
if (touchLocation.x < 200) {
if ((blobSprite.position.x-10>20)){
_tapDownLeft = YES;
}
}
else {
_tapDownLeft = NO;
_tapDownRight = NO;
}
}
-(void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event{
_tapDownLeft = NO;
_tapDownRight = NO;
}
-(void) registerWithTouchDispatcher{
[[CCTouchDispatcher sharedDispatcher]addTargetedDelegate:self priority:0 swallowsTouches:YES];
}
#end
Am I on the right lines with this? At the moment it's giving me 'expression result unused' in update. Could anyone tell me what I'm missing? Any help would be greatly appreciated.
Thanks,
Patrick
i see a few things here:
not certain your selector will call update : #selector(update:)
I would not rely on dt being either exactly 1/60th of a second, nor being constant. I would favor defining a speed constant (in points per second) and compute the deltaX in points based on the desired speed and dt, at each update cycle.
I dont see a 'registerWithTouchDispatcher' call (i try to place them in onEnter and onExit) methods.
Somewhere in there, make certain you remove your children (either in dealloc, or better in a local cleanup method (dont forget to invoke [super cleanup]).
Remove the argument in the update function