I'm using AVCaptureSession to capture video from my iPhone 3G and I need to capture the image and change it before displaying on my AVCaptureVideoPreviewLayer. In my current implementation, I am simply implementing the captureOutput: method and displaying the UIImage in a UIImageView, but that does not work for some reason.
Any ideas? Subclass AVCaptureSession somehow?
Thanks!
Check out this https://developer.apple.com/library/ios/#samplecode/SquareCam/Introduction/Intro.html
I think it does this.
It draws face boxes onto faces.
- (void)drawFaceBoxesForFeatures:(NSArray *)features forVideoBox:(CGRect)clap orientation:(UIDeviceOrientation)orientation// videoMirrored:(const BOOL)ISVIDEOMIRRORED
{
NSArray *sublayers = [NSArray arrayWithArray:[previewLayer sublayers]];
NSInteger sublayersCount = [sublayers count], currentSublayer = 0;
NSInteger featuresCount = [features count], currentFeature = 0;
[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
// hide all the face layers
for ( CALayer *layer in sublayers ) {
if ( [[layer name] isEqualToString:#"FaceLayer"] )
[layer setHidden:YES];
}
if ( featuresCount == 0 || !detectFaces ) {
[CATransaction commit];
return; // early bail.
}
CGSize parentFrameSize = [previewView frame].size;
NSString *gravity = [previewLayer videoGravity];
//BOOL isMirrored = isVideoMirrored;
#warning Deprecated
const BOOL isMirrored = [previewLayer isMirrored]; // deprecated
CGRect previewBox = [SquareCamViewController videoPreviewBoxForGravity:gravity
frameSize:parentFrameSize
apertureSize:clap.size];
for ( CIFaceFeature *ff in features ) {
// find the correct position for the square layer within the previewLayer
// the feature box originates in the bottom left of the video frame.
// (Bottom right if mirroring is turned on)
CGRect faceRect = [ff bounds];
// flip preview width and height
CGFloat temp = faceRect.size.width;
faceRect.size.width = faceRect.size.height;
faceRect.size.height = temp;
temp = faceRect.origin.x;
faceRect.origin.x = faceRect.origin.y;
faceRect.origin.y = temp;
// scale coordinates so they fit in the preview box, which may be scaled
CGFloat widthScaleBy = previewBox.size.width / clap.size.height;
CGFloat heightScaleBy = previewBox.size.height / clap.size.width;
faceRect.size.width *= widthScaleBy;
faceRect.size.height *= heightScaleBy;
faceRect.origin.x *= widthScaleBy;
faceRect.origin.y *= heightScaleBy;
if ( isMirrored )
faceRect = CGRectOffset(faceRect, previewBox.origin.x + previewBox.size.width - faceRect.size.width - (faceRect.origin.x * 2), previewBox.origin.y);
else
faceRect = CGRectOffset(faceRect, previewBox.origin.x, previewBox.origin.y);
CALayer *featureLayer = nil;
// re-use an existing layer if possible
while ( !featureLayer && (currentSublayer < sublayersCount) ) {
CALayer *currentLayer = [sublayers objectAtIndex:currentSublayer++];
if ( [[currentLayer name] isEqualToString:#"FaceLayer"] ) {
featureLayer = currentLayer;
[currentLayer setHidden:NO];
}
}
// create a new one if necessary
if ( !featureLayer ) {
featureLayer = [CALayer new];
[featureLayer setContents:(id)[square CGImage]];
[featureLayer setName:#"FaceLayer"];
[previewLayer addSublayer:featureLayer];
[featureLayer release];
}
[featureLayer setFrame:faceRect];
switch (orientation) {
case UIDeviceOrientationPortrait:
[featureLayer setAffineTransform:CGAffineTransformMakeRotation(DegreesToRadians(0.))];
break;
case UIDeviceOrientationPortraitUpsideDown:
[featureLayer setAffineTransform:CGAffineTransformMakeRotation(DegreesToRadians(180.))];
break;
case UIDeviceOrientationLandscapeLeft:
[featureLayer setAffineTransform:CGAffineTransformMakeRotation(DegreesToRadians(90.))];
break;
case UIDeviceOrientationLandscapeRight:
[featureLayer setAffineTransform:CGAffineTransformMakeRotation(DegreesToRadians(-90.))];
break;
case UIDeviceOrientationFaceUp:
case UIDeviceOrientationFaceDown:
default:
break; // leave the layer in its last known orientation
}
currentFeature++;
}
[CATransaction commit];
}
Related
I am a newbie to the world of cocos2d i am developing my first tutorial and facing one problem
my problem is i have an image (1024 X 320) and my orientation is landscape i need to move that image continuously from right to left for this purpose i have used space shooter tutorial by Ray(Thanks to him) but the image doesn't seem to be appearing again and again.
my code is..
-(id) init
{
if( (self=[super init])) {
CGSize screenSize = [CCDirector sharedDirector].winSize;
// 1) Create the CCParallaxNode
backgroundNode = [CCParallaxNode node];
[self addChild:backgroundNode z:-1];
// 2) Create the sprites we'll add to the CCParallaxNode
Back = [CCSprite spriteWithFile:#"bg_front_spacedust.png"];
//Back.position=ccp(screenSize.width/2, screenSize.height/2);
Back.rotation = -90;
Back1 = [CCSprite spriteWithFile:#"bg_front_spacedust.png"];
Back1.rotation = -90;
// 3) Determine relative movement speeds for space dust and background
CGPoint dustSpeed = ccp(0.1, 0.1);
// 4) Add children to CCParallaxNode
[backgroundNode addChild:Back z:0 parallaxRatio:dustSpeed positionOffset:ccp(screenSize.width/2, screenSize.height/2)];
NSLog(#"back.content width is...%f",Back.contentSize.width);
[backgroundNode addChild:Back1 z:1 parallaxRatio:dustSpeed positionOffset:ccp(screenSize.width/2, screenSize.height*2)];
// 5) Enable updates
[self scheduleUpdate];
}
return self;
}
- (void)update:(ccTime)dt {
// 1) Update background position
CGPoint backgroundScrollVel = ccp(0,-1000);
backgroundNode.position = ccpAdd(backgroundNode.position, ccpMult(backgroundScrollVel, dt));
// 2) Check for background elements moving offscreen
NSArray *spaceDusts = [NSArray arrayWithObjects:Back, Back1, nil];
for (CCSprite *spaceDust in spaceDusts) {
if ([backgroundNode convertToWorldSpace:spaceDust.position].x < -spaceDust.contentSize.width) {
[backgroundNode incrementOffset:ccp(2*spaceDust.contentSize.width,0) forChild:spaceDust];
}
}
}
please help me out of this
Thanks in advance.
try this one
if (backgroundNode.position.y <-screenSize.height*2)
backgroundNode.position = ccp(0,0);
As init method is called only once the approach you are doing will be done only one time you need to again set the Position of the backgroundNode to 0 in your update method.
here the multiple may vary
Try this code it is creating a paralax moving from bottom to top change CGPointMake(0, 1.0) to this CGPointMake(1.0,0) in paraNode addChild line.
-(id) init
{
// always call "super" init
// Apple recommends to re-assign "self" with the "super's" return value
if( (self=[super init]) )
{
float yPos =0.0;
NSMutableString *fileNameString = [[NSMutableString alloc]initWithCapacity:0];
if (IS_IPHONE_5)
{
[fileNameString appendString:#"Background-568h.png"];
yPos= 560.0;
}
else
{
[fileNameString appendString:#"Background.png"];
yPos= 470.0;
}
background1 = [CCSprite spriteWithFile:fileNameString];
background1.tag = 1;
background1.anchorPoint = CGPointMake(0,0);
background2 = [CCSprite spriteWithFile:fileNameString];
background2.tag = 2;
background2.anchorPoint = CGPointMake(0,0);
background3 = [CCSprite spriteWithFile:fileNameString];
background3.tag = 3;
background3.anchorPoint = CGPointMake(0,0);
background4 = [CCSprite spriteWithFile:fileNameString];
background4.tag = 4;
background4.anchorPoint = CGPointMake(0,0);
paraNode = [CCParallaxNode node];
[paraNode addChild:background1 z:1 parallaxRatio:CGPointMake(0, 1.0) positionOffset:CGPointMake(0, 0)];
[paraNode addChild:background2 z:2 parallaxRatio:CGPointMake(0, 1.0) positionOffset:CGPointMake(0, -yPos)];
[paraNode addChild:background3 z:3 parallaxRatio:CGPointMake(0, 1.0) positionOffset:CGPointMake(0, -yPos*2)];
[paraNode addChild:background4 z:4 parallaxRatio:CGPointMake(0, 1.0) positionOffset:CGPointMake(0, -yPos*3)];
[self addChild:paraNode z:-1 tag:123];
[self updateFrameRate:0.7 andYposition:yPos];
[fileNameString release];
fileNameString = nil;
}
return self;
}
-(void)updateFrameRate:(float)speedValue andYposition:(float)yposToSet
{
move1 = [CCMoveBy actionWithDuration:speedValue position:CGPointMake(0, yposToSet)];
move2 = [CCMoveBy actionWithDuration:0.0 position:CGPointMake(0, -yposToSet)];
move3 = [CCMoveBy actionWithDuration:0.0 position:CGPointMake(0, 0)];
CCSequence* sequence = [CCSequence actions:move1,move2,move3, nil];
CCRepeatForever* repeat = [CCRepeatForever actionWithAction:sequence];
[paraNode runAction:repeat];
}
I want to display a CALayer on video captured by AVCapture.
I am able to display the layer but for the next frame the previous should be removed.
My code is:
[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
for (int i = 0; i < faces.size(); i++) {
CGRect faceRect;
// Get the Graphics Context
faceRect.origin.x = xyPoints.x;
faceRect.origin.y = xyPoints.y;
faceRect.size.width =50; //faces[i].width;
faceRect.size.height =50;// faces[i].height;
CALayer *featureLayer=nil;
// faceRect = CGRectApplyAffineTransform(faceRect, t);
if (!featureLayer) {
featureLayer = [[CALayer alloc]init];
featureLayer.borderColor = [[UIColor redColor] CGColor];
featureLayer.borderWidth = 10.0f;
[self.view.layer addSublayer:featureLayer];
}
featureLayer.frame = faceRect;
NSLog(#"frame-x - %f, frame-y - %f, frame-width - %f, frame-height - %f",featureLayer.frame.origin.x,featureLayer.frame.origin.y,featureLayer.frame.size.width,featureLayer.frame.size.height);
}
// [featureLayer removeFromSuperlayer];
[CATransaction commit];
where face is (const std::vector<cv::Rect)face OpenCV format.
I need to know where to place the code [featureLayer removeFromSuperLayer];
Note: "face" is not for face detection... it is just a rectangle.
I have got the solution ...
featureLayer is CALayer object I gave this as identity. Like
featureLayer.name = #"earLayer";
and whenever I detect the Object in frame I get the sublayers from main view like
NSArray *sublayers = [NSArray arrayWithArray:[self.view.layer sublayers]];
and count the sublayer to check in for loop like below:
int sublayersCount = [sublayers count];
int currentSublayer = 0;
for (CALayer *layer in sublayers) {
NSString *layerName = [layer name];
if ([layerName isEqualToString:#"earayer"])
[layer setHidden:YES];
}
Now I am getting the proper layer with Detected objects.
My Code For Continuous Scrolling ......
NSArray *spaceDusts = [NSArray arrayWithObjects:_spacedust1, _spacedust2, nil];
for (CCSprite *spaceDust in spaceDusts) {
if ([_backgroundNode convertToWorldSpace:spaceDust.position].x < - spaceDust.contentSize.width) {
[_backgroundNode incrementOffset:ccp(2*spaceDust.contentSize.width,0) forChild:spaceDust];
}
}
Background image size is 1024*384
when rune this into simulator its work properly but when i use in device(iphone)
its set the background into center and take some to load the image
thanks in advance.....
My code for background scroll in cocos2d game:
#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#define MM_BG_SPEED_DUR ( IS_IPAD ? (6.0f) : (2.0f) )
-(void)onEnter
{
[super onEnter];
[self initBackground];
[self schedule: #selector(tick:)];
}
-(void)initBackground
{
NSString *tex = #"BG/Background.png";//[self getThemeBG];
mBG1 = [CCSprite spriteWithFile:tex];
mBG1.position = ccp(s.width*0.5f,s.height*0.5f);
[self addChild:mBG1 z:LAYER_BACKGROUND];
mBG2 = [CCSprite spriteWithFile:tex];
mBG2.position = ccp(s.width+s.width*0.5f,s.height*0.5f);
mBG2.flipX = true;
[self addChild:mBG2 z:LAYER_BACKGROUND];
}
-(void)scrollBackground:(ccTime)dt
{
CGSize s = [[CCDirector sharedDirector] winSize];
CGPoint pos1 = mBG1.position;
CGPoint pos2 = mBG2.position;
pos1.x -= MM_BG_SPEED_DUR;
pos2.x -= MM_BG_SPEED_DUR;
if(pos1.x <=-(s.width*0.5f) )
{
pos1.x = pos2.x + s.width;
}
if(pos2.x <=-(s.width*0.5f) )
{
pos2.x = pos1.x + s.width;
}
mBG1.position = pos1;
mBG2.position = pos2;
}
-(void)tick:(ccTime)dt
{
[self scrollBackground:dt];
}
For detecting face in camera I am reffering to SquareCam(iOS developer library). But I am unable to show left eye, right eye and mouth position. I am using the following code
NSArray *sublayers = [NSArray arrayWithArray:[previewLayer sublayers]];
NSInteger sublayersCount = [sublayers count], currentSublayer = 0;
NSInteger featuresCount = [features count], currentFeature = 0;
[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
// hide all the face layers
for ( CALayer *layer in sublayers )
{
if ( [[layer name] isEqualToString:#"FaceView"] )
[layer setHidden:YES];
}
if ( featuresCount == 0 || !detectFaces ) {
[CATransaction commit];
return; // early bail.
}
CGSize parentFrameSize = [previewView frame].size;
NSString *gravity = [previewLayer videoGravity];
BOOL isMirrored = [previewLayer isMirrored];
CGRect previewBox = [SquareCamViewController videoPreviewBoxForGravity:gravity
frameSize:parentFrameSize
apertureSize:clap.size];
for ( CIFaceFeature *ff in features ) {
// find the correct position for the square layer within the previewLayer
// the feature box originates in the bottom left of the video frame.
// (Bottom right if mirroring is turned on)
CGRect faceRect = [ff bounds];
CGRect leftEyeFrameRect;
CGFloat temp = faceRect.size.width;
faceRect.size.width = faceRect.size.height;
faceRect.size.height = temp;
temp = faceRect.origin.x;
faceRect.origin.x = faceRect.origin.y;
faceRect.origin.y = temp;
// scale coordinates so they fit in the preview box, which may be scaled
CGFloat widthScaleBy = previewBox.size.width / clap.size.height;
CGFloat heightScaleBy = previewBox.size.height / clap.size.width;
faceRect.size.width *= widthScaleBy;
faceRect.size.height *= heightScaleBy;
faceRect.origin.x *= widthScaleBy;
faceRect.origin.y *= heightScaleBy;
if ( isMirrored )
{
faceRect = CGRectOffset(faceRect, previewBox.origin.x + previewBox.size.width - faceRect.size.width - (faceRect.origin.x * 2), previewBox.origin.y);
}
else
{
faceRect = CGRectOffset(faceRect, previewBox.origin.x, previewBox.origin.y);
leftEyeFrameRect=CGRectOffset(faceRect,ff.leftEyePosition.x, ff.leftEyePosition.y);
}
CALayer *featureLayer = nil;
CALayer *eyeLayer = nil;
// re-use an existing layer if possible
while ( !featureLayer && (currentSublayer < sublayersCount) )
{
CALayer *currentLayer = [sublayers objectAtIndex:currentSublayer++];
if ( [[currentLayer name] isEqualToString:#"FaceLayer"] ) {
featureLayer = currentLayer;
[currentLayer setHidden:NO];
}
}
// create a new one if necessary
if ( !featureLayer ) {
featureLayer = [CALayer new];
[featureLayer setContents:(id)[square CGImage]];
[featureLayer setName:#"FaceLayer"];
[previewLayer addSublayer:featureLayer];
[featureLayer release];
}
[featureLayer setFrame:faceRect];
if (faceView !=nil) {
[faceView removeFromSuperview];
[faceView release];
}
if (leftEyeView != nil) {
[leftEyeView removeFromSuperview];
[leftEyeView release];
}
faceView = [[UIView alloc] initWithFrame:CGRectMake(faceRect.origin.x, faceRect.origin.y ,faceRect.size.width, faceRect.size.height)];
faceView.layer.borderWidth = 1;
faceView.layer.borderColor = [[UIColor redColor] CGColor];
[self.view addSubview:faceView];
leftEyeView = [[UIView alloc] initWithFrame:CGRectMake(faceView.frame.origin.x+(faceView.frame.size.height/2), faceView.frame.origin.y+(faceView.frame.size.height*0.10) ,faceView.frame.size.width*0.40, faceView.frame.size.height*0.40)];
UIImageView *leftEyeImageView=[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"eye.png"]];
leftEyeImageView.frame = CGRectMake(0, 0, faceView.frame.size.width*0.40, faceView.frame.size.height*0.40);
[leftEyeView addSubview:leftEyeImageView];
[self.view addSubview:leftEyeView];
if (ff.hasLeftEyePosition) {
CGPoint leftEyeCenter= ff.leftEyePosition;
UIView *vv= [[UIView alloc] initWithFrame:CGRectMake(leftEyeCenter.x, leftEyeCenter.y, 50, 50)];
vv.center = leftEyeCenter;
vv.layer.borderWidth= 4.0;
vv.layer.borderColor= [[UIColor blackColor]CGColor];
[self.view addSubview:vv];
}
It is detecting eye but not showing in right position. Can anyone help to resolve this.
Thanks in advance.
I faced the same problem as you in the preview when using the front camera, because the preview is mirrored and I could not find any good information to scale.
The following code is the closest I got. Please note that I have an image defined as property that is called heartImage and that I assume you are using the Apple Sample called SquareCam.
In the method - (void)drawFaceBoxesForFeatures:(NSArray *)features forVideoBox:(CGRect)clap orientation:(UIDeviceOrientation)orientation
if(ff.hasLeftEyePosition)
{
//swap coordinates
CGFloat leftEyeRectOriginX = ff.leftEyePosition.y ;
CGFloat leftEyeRectOriginY = ff.leftEyePosition.x ;
CGFloat leftEyeRectWidth = faceRect.size.width*0.3;
CGFloat leftEyeRectHeight = faceRect.size.width*0.3;
//adjust scale
leftEyeRectOriginX *= widthScaleBy;
leftEyeRectOriginY *= heightScaleBy;
NSLog(#"LeftEyePosition: %#", NSStringFromCGPoint(ff.leftEyePosition));
CGRect r = CGRectMake(leftEyeRectOriginX - (leftEyeRectWidth/2) , leftEyeRectOriginY - (leftEyeRectHeight/2), leftEyeRectWidth, leftEyeRectHeight);
if ( isMirrored ){
r = CGRectOffset(r, previewBox.origin.x + previewBox.size.width - (rightEyeRectOriginX*2) - rightEyeRectWidth+ faceRect.origin.x, previewBox.origin.y);
NSLog(#"LeftEyeRect mirrored: %#", NSStringFromCGRect(r));
}
else{
r = CGRectOffset(r, previewBox.origin.x, previewBox.origin.y);
}
while ( !leftEyeEyeLayer && (currentSublayer < sublayersCount) ) {
CALayer *currentLayer = [sublayers objectAtIndex:currentSublayer++];
if ( [[currentLayer name] isEqualToString:#"LeftEyeLayer"] ) {
leftEyeEyeLayer = currentLayer;
[currentLayer setHidden:NO];
}
}
// create a new one if necessary
if ( !leftEyeEyeLayer ) {
leftEyeEyeLayer = [CALayer new];
[leftEyeEyeLayer setContents:(id)[heartImage CGImage]];
[leftEyeEyeLayer setName:#"LeftEyeLayer"];
[previewLayer addSublayer:leftEyeEyeLayer];
[leftEyeEyeLayer release];
}
[leftEyeEyeLayer setFrame:r];
}
The same applies for the Right Eye, with the exception that I use this in case it's mirrored: r = CGRectOffset(r, previewBox.origin.x + previewBox.size.width - (rightEyeRectOriginX*2) - rightEyeRectWidth+ faceRect.origin.x, previewBox.origin.y);
.
The only difference with the sample code is that you first want to remove all the featureLayers, so some lines above my code looks like this:
// hide all the face layers
for ( CALayer *layer in sublayers ) {
if ( [[layer name] isEqualToString:#"FaceLayer"] || [[layer name] isEqualToString:#"LeftEyeLayer"] || [[layer name] isEqualToString:#"RightEyeLayer"] )
[layer setHidden:YES];
}
To be precise, I have troubles only in the live camera preview. When using the method to save picture in library (- (CGImageRef)newSquareOverlayedImageForFeatures:(NSArray *)features
inCGImage:(CGImageRef)backgroundImage
withOrientation:(UIDeviceOrientation)orientation
frontFacing:(BOOL)isFrontFacing
) it works correctly by using:
if(ff.hasLeftEyePosition)
{
CGRect r = CGRectMake(ff.leftEyePosition.x-faceWidth*0.15, ff.leftEyePosition.y-faceWidth*0.15, faceWidth*0.3, faceWidth*0.3);
CGContextDrawImage(bitmapContext, r, [rotatedHeartImage CGImage]);
}
Please let me know if and how I should improve my answer.
This is probably caused by incorrect orientations between your input, detector and output. If the faces are detected, then probably only the output coordinates need to be translated from landscape to portrait or vice versa. Otherwise, take a look here.
You could investigate in Haar cascade training files and OPENGL but that's a total different approuch. It does support iOS versions below 6.0 that's a pro. But it's way harder then the Squarecam sample of Apple (con).
This OpenGL was able to detect ears, eyes etc. There could already be some training files on the web.
I made my map to scroll automatically however I would like to know how can I slow down the scrolling before the map reaches the end and when it does I would like the map to stop scrolling. I want to know how to do this because my game is about the player trying to shoot the enemy before he reaches the end of the map where there is shelter for him to hide. I would like that before the enemy reaches the shelter have the scrolling slow down and when the enemy reaches the shelter I would like the map to stop scrolling.
Here is the code:
#implementation GameplayScrollingLayer
// Scrolling with TileMap Layers inside of a Parallax Node
-(void)addScrollingBackgroundWithTileMapInsideParallax {
CGSize screenSize = [[CCDirector sharedDirector] winSize];
CGSize levelSize = [[GameManager sharedGameManager]
getDimensionsOfCurrentScene];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
tileMapNode = [CCTMXTiledMap
tiledMapWithTMXFile:#"Level2TileMap.tmx"];
} else {
tileMapNode = [CCTMXTiledMap
tiledMapWithTMXFile:#"Level2TileMapiPhone.tmx"];
}
CCTMXLayer *groundLayer = [tileMapNode layerNamed:#"GroundLayer"];
CCTMXLayer *rockColumnsLayer = [tileMapNode
layerNamed:#"RockColumnsLayer"];
CCTMXLayer *rockBoulderLayer = [tileMapNode
layerNamed:#"RockBoulderLayer"];
parallaxNode = [CCParallaxNode node];
[parallaxNode setPosition:
ccp(levelSize.width/2,screenSize.height/2)];
float xOffset = 0.0f;
xOffset = (levelSize.width/2);
[groundLayer retain];
[groundLayer removeFromParentAndCleanup:NO];
[groundLayer setAnchorPoint:CGPointMake(0.5f, 0.5f)];
[parallaxNode addChild:groundLayer z:30 parallaxRatio:ccp(1,1)
positionOffset:ccp(0,0)];
[groundLayer release];
xOffset = (levelSize.width/2) * 0.8f;
[rockColumnsLayer retain];
[rockColumnsLayer removeFromParentAndCleanup:NO];
[rockColumnsLayer setAnchorPoint:CGPointMake(0.5f, 0.5f)];
[parallaxNode addChild:rockColumnsLayer z:20
parallaxRatio:ccp(0.2,1)
positionOffset:ccp(xOffset, 0.0f)];
[rockColumnsLayer release];
xOffset = (levelSize.width/2) * 0.3f;
[rockBoulderLayer retain];
[rockBoulderLayer removeFromParentAndCleanup:NO];
[rockBoulderLayer setAnchorPoint:CGPointMake(0.5f, 0.5f)];
[parallaxNode addChild:rockBoulderLayer z:30
parallaxRatio:ccp(0.7,1)
positionOffset:ccp(xOffset, 0.0f)];
[rockBoulderLayer release];
[self addChild:parallaxNode z:1];
}
// Accelerometer
-(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration { //new
shipSpeedY = 9.0 + acceleration.x*20;
shipSpeedX = -acceleration.y*20;
}
// Updating ship based on accelerometer
-(void)updateShip {
float maxY = winSize.height - ship.contentSize.height/2;
float minY = ship.contentSize.height/2;
float newY = ship.position.y + shipSpeedY;
newY = MIN(MAX(newY, minY), maxY);
float maxX = winSize.width - ship.contentSize.width/2;
float minX = ship.contentSize.width/2;
float newX = ship.position.x + shipSpeedX;
newX = MIN(MAX(newX, minX), maxX);
ship.position = ccp(newX, newY);
}
// Making background scroll automatically
-(void)update:(ccTime)dt {
[self updateShip];
CGPoint backgroundScrollVel = ccp(-100, 0);
parallaxNode.position = ccpAdd(parallaxNode.position, ccpMult(backgroundScrollVel, dt));
}
// Adding sprite ship
-(id)init {
self = [super init];
if (self != nil) {
winSize = [CCDirector sharedDirector].winSize;
ship=[CCSprite spriteWithFile:#"ship.png"];
ship.position=ccp(60,160);
[self addChild:ship z:100];
self.isAccelerometerEnabled = YES; //new
[self scheduleUpdate]; //new
[self addScrollingBackgroundWithTileMapInsideParallax];
}
return self;
}
- (void) dealloc
{
[super dealloc];
}
#end