I made a space game where you use the accelerometer to move a spaceship, When I try the game on my devices (iPad, iPhone) it work well with no errors or incorrect behavior.
I upload my game to the App Store and it was approved, but when I downloaded the game from the App Store, the accelerometer wasn't working and my spaceship was stuck in one direction.
I tried many devices and they all have same problem.
Note: I used the cocos2d and box2d frameworks.
If anybody have any idea, please help!
Use UIAccelerometerDelegate
UIAccelerometer *accelerometer;
In .m file
# pragma mark To Enable Acceleromete
self.isAccelerometerEnabled = YES;
self.accelerometer = [UIAccelerometer sharedAccelerometer];
self.accelerometer.updateInterval = 0.025;
self.accelerometer.delegate = self;
Use these delegates methods
#pragma Mark Accelerometer
-(void) accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
// Set up variables
CGSize winSize = [CCDirector sharedDirector].winSize;
#define kFilteringFactor 0.5
#define kShipMaxPointsPerSec (winSize.height*0.5)
#define kRestAccelX (xCallib)
#define kMaxDiff 0.2
#define kRestAccelY (yCallib)
#define kMaxDiffY 0.1
UIAccelerationValue rollingX=0;
float accelX;
// High pass filter for reducing jitter
rollingX = (acceleration.x * kFilteringFactor) + (rollingX * (1.0 - kFilteringFactor));
accelX = acceleration.x - rollingX;
// Calculate movement for x and y axis
float accelDiffX = accelX - kRestAccelX;///
float accelFractionX = accelDiffX / kMaxDiff;//
movementX = kShipMaxPointsPerSec * accelFractionX;
// Thresh holds for x and y axis movement
willMoveX = YES;
if (((movementX < 45.0f) && (movementX > -45.0f)))
willMoveX = NO;
}
#pragma Mark Accelerometer Update Methods
-(void) update:(ccTime)dt
{
CCSprite *player =(CCSprite *) [self getChildByTag:objPlayerShipTag];
CGSize screenSize = [[CCDirector sharedDirector]winSize];
float oldX = [player position].x;
float newX;
if (willMoveX) {
newX = [player position].x + (movementX * dt);
} else newX = oldX;
if ((newX > (screenSize.width -45)) || newX < 45.0f ) {
newX = oldX;
}
[player setPosition:ccp(newX,90)];
// ++++++++ To generate Bullet and Bomb Power +++++++
[self checkForCollisionWithPowersBullets]; //NEW
[self checkForCollisionWithPowersBomb];
}
Related
I'm using accelerometer in my first Cocos2D game and it work fine, i'm able to move the sprite using the below code however, when i change the orientation from landscapeLeft to landscapeRight, the sprite stops responding to Y coordination, and the sprite goes to the top of the screen and doesn't properly respond... I believe it's because of changing the device orientation, but i'm not sure since i'm pretty new to App Development, any help will be appreciated.
Here is the sample code i'm using...
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
//this determines how sensitive the accelerometer reacts (higher = more sensitive)
NSUserDefaults *defaulObj = [NSUserDefaults standardUserDefaults];
float sensitivity = [defaulObj floatForKey:#"Sensitivity"]; //10.0f
if (!sensitivity) {
sensitivity = 6;
}
// this controls how quickly the velocity decelerates (lower = quicker to change direction)
float deceleration = 0.4f;
static float xVal = 0;
if (!self.isFlag) {
xVal = -acceleration.x;
self.isFlag = TRUE;
}
playerVelocity.x = playerVelocity.x * deceleration + (xVal + acceleration.x) * sensitivity;
playerVelocity.y = playerVelocity.y * deceleration + acceleration.y * sensitivity;
playerVelocity.y = playerVelocity.y*-1;
}
Perhaps this helps out, flips Y along your current device orientation.
float rotatedY = acceleration.y;
if ([UIApplication sharedApplication].statusBarOrientation==UIInterfaceOrientationLandscapeLeft) {
rotatedY *= -1;
}
then use rotatedY insteat of acceleration.y
i am working on game in which i want to move CCSprite in direction of accelerometer tilt.i have referred this tutorial http://www.raywenderlich.com/457/intro-to-box2d-with-cocos2d-tutorial-bouncing-balls but i am not clear with it. Please can any one help me.
Thanks in Advance.
Refer this solution. I used same for moving sprite from left to right in landscape game.: See answer here
Only change for landscape mode is use accelerometer y in place of x.
-(void) accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
if(self.isGamePaused || self.isGameOver)
return;
float deceleration = 1.0f, sensitivity = 15.0f, maxVelocity = 450;
if(sGame.IsIpad)
{
sensitivity = 14.0f;
maxVelocity = 850;
deceleration = 1.5f;
}
// adjust velocity based on current accelerometer acceleration
// vel.x = vel.x * deceleration + acceleration.x * sensitivity;
AppController *app = (AppController*)[UIApplication sharedApplication].delegate;
float velocity_x = self.gameActor.velocity.x ;
self.gameActor.accelVal = ABS(acceleration.y);
if(app.orient == UIInterfaceOrientationLandscapeLeft)
{
velocity_x = velocity_x * deceleration + acceleration.y * sensitivity;
}
else
{
velocity_x = velocity_x * deceleration + (-acceleration.y) * sensitivity;
}
//limit the maximum velocity of the player sprite, in both directions (positive & negative values)
velocity_x = fmaxf(fminf(velocity_x, maxVelocity), -maxVelocity);
self.gameActor.velocity = ccp(velocity_x, self.gameActor.velocity.y);
}
I am new in Box2D....
I have ball image in CCSprite. I want to move ball in whole screen using accelerometer...
tell me
How to use accelerometer in box2d??
Thanks...in advance
The standard cocos2d-box2d template file moves boxes using the accelerometer by applying gravity relative to the accelerometer value.
- (void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration
{
static float prevX=0, prevY=0;
//#define kFilterFactor 0.05f
#define kFilterFactor 1.0f // don't use filter. the code is here just as an example
float accelX = (float) acceleration.x * kFilterFactor + (1- kFilterFactor)*prevX;
float accelY = (float) acceleration.y * kFilterFactor + (1- kFilterFactor)*prevY;
prevX = accelX;
prevY = accelY;
// accelerometer values are in "Portrait" mode. Change them to Landscape left
// multiply the gravity by 10
b2Vec2 gravity( -accelY * 10, accelX * 10);
world->SetGravity( gravity );
}
You need to be more specific on what you want the ball to do dependent on how you move the phone. Your question is difficult to answer in its current form.
Get the accelerometer measurements and say Force = coefficient*measurements. The apply this force to your b2Body
Let your Ball Sprite having tag is 1.
Replace this code with your Accelerometer delegate,
I test it on device, its working.
and your ball will move with accelerometer.
-(void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration
{
#define kFilterFactor 0.75
accelerometer.updateInterval = 1.0f/60.0f;
static UIAccelerationValue rollingX = 0, rollingY = 0;
for (b2Body *b = world->GetBodyList(); b; b = b->GetNext())
{
if (b->GetUserData() != NULL)
{
CCSprite *sprite = (CCSprite*)b->GetUserData();
if (sprite.tag == 1) {
rollingX = (acceleration.x * kFilterFactor) + (rollingX * 0.25);
rollingY = (acceleration.y * kFilterFactor) + (rollingY * 0.25);
float accelX = rollingX;
float accelY = rollingY;
CGPoint moveNewPosition = sprite.position;
if (accelX > 0.1) {
moveNewPosition.y += 2;
} if (accelX < 0.1) {
moveNewPosition.y -= 2;
}
if (accelY > 0.1) {
moveNewPosition.x -= 2;
} if (accelY < -0.1) {
moveNewPosition.x += 2;
}
b->SetLinearVelocity(b2Vec2(2,2));
sprite.position = ccp(moveNewPosition.x , moveNewPosition.y );
sprite.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());
}
}
}
}
I hope it'll work.
I'm French so excuse me for my English. So I use an accelerometer, but in my code the accelerometer works for a view and not for an image. What I want to do is to use this accelerometer for an image instead of a view. How can I do this? Here is the code:
#define CONST_fps 100.
#define CONST_map_shift 0.01
#define kFilteringFactor 0.1
UIAccelerationValue rollingX, rollingY, rollingZ;
#implementation MapViewRotationViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// accelerometer settings
[[UIAccelerometer sharedAccelerometer] setDelegate:self];
[[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0 / CONST_fps)];
}
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
rollingX = (acceleration.x * kFilteringFactor) + (rollingX * (1.0 - kFilteringFactor));
rollingY = (acceleration.y * kFilteringFactor) + (rollingY * (1.0 - kFilteringFactor));
rollingZ = (acceleration.z * kFilteringFactor) + (rollingZ * (1.0 - kFilteringFactor));
float accelX = acceleration.x - rollingX;
float accelY = acceleration.y - rollingY;
float accelZ = acceleration.z - rollingZ;
static CGFloat ZZ = 0.;
CGFloat z = (atan2(rollingX, rollingY) + M_PI);
if (fabsf(ZZ - z) > CONST_map_shift)
{
viewToRotate.layer.transform = CATransform3DMakeRotation(ZZ=z, 0., 0., 1.);
}
}
#end
You don't need to have a view as callback instead you can choose any class to conform to protocol UIAccelerometerDelegate. Just declare your class in the header file as
#interface MyClass : NSObject <UIAccelerometerDelegate> {
// my members
}
In MyClass.m you have to implement method
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
// do what you like
}
But if you are not forced to support iOS version 3.x, you should consider using CoreMotion API. See Event Handling Guide for iOS / Motion Events for more information and samples.
I'm trying to rotate a sprite using the accelerometer. when I tilt right, I want him to rotate slightly to the right, and when I tilt left, I want him to rotate slightly to the left...
Thanks in advance,
Reed
Firs off - in your h file you need to make the following variables:
UIAccelerationValue accelerationX;
UIAccelerationValue accelerationY;
float currentRawReading;
float calibrationOffset;
Also ensure that your h file has:
#interface myViewName : UIViewController <UIAccelerometerDelegate>
Then in your .m file just below your imports at the top put:
#define kFilteringFactor 0.05
CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;};
CGFloat RadiansToDegrees(CGFloat radians) {return radians * 180/M_PI;};
Then in your .m file on your viewDidLoad Function put:
UIAccelerometer *accel = [UIAccelerometer sharedAccelerometer];
accel.delegate = self;
accel.updateInterval = 1.0f/60.0f;
also add the following function to your .m file:
-(void) accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration{
accelerationX = acceleration.x * kFilteringFactor + accelerationX * (1.0 - kFilteringFactor);
accelerationY = acceleration.y * kFilteringFactor + accelerationY * (1.0 - kFilteringFactor);
// keep the raw reading, to use during calibrations
currentRawReading = atan2(accelerationY, accelerationX);
float rotation = -RadiansToDegrees(currentRawReading);
targetView.transform = CGAffineTransformMakeRotation(-(DegreesToRadians(rotation)));
//targetView.transform = CGAffineTransformRotate(targetView.transform, -(rotation * 3)); //if you want easing
}
you will have to tweak it slightly based on what view or object you are targeting -- but thats pretty much it.
Hope this helps,
Michael
Shouldn't be too difficult. Just have somewhere in your code that handles the UIAccelerometerDelegate class and apply changes to your sprites based on the values you receive through parameters to the – accelerometer:didAccelerate: callback.
Apple docs for the delegate class are available at...
https://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIAccelerometerDelegate_Protocol/UIAccelerometerDelegate/UIAccelerometerDelegate.html
In the delegate function of accelerometer just write the code -->>
float angleRadians = atanf((float)X_Position / (float)Y_Position);
float angleDegrees = CC_RADIANS_TO_DEGREES(angleRadians);
float cocosAngle = 1 * angleDegrees;
sprite.rotation = cocosAngle;
and the sprite will get rotated to desired angle with changes in the values of X_position, Y_Position and angle.
Njoy.. :)