Sprite collision with tile map - c++

So, I'm trying to build my own game engine and my first project is creating a pacman clone. I've worked out how to create the tilemap and move pacman around on it. But I've having issues creating a collision detector with the tilemap. Particularly the issue is that the collision detects fine for any tiles north of the current location, however it thinks the tile below the current location is actually 1 tile larger than normal. And 0 collision exists for tiles east and west of the current location. I'm confused because the collision works for the north tile... but I'm using the same logic for the other directions and it's not working.
The logic I am using is that 'okay' tiles to move into are value 0. Any other tile is not able for movement.
Here is the code I'm using for the actual wall collision:
//checks for a sprite colliding with a wall tile
//direction refers to 1=North, 2=South, 3=West, 4=East
bool Wall_Collision(SPRITE sprite, int direction)
{
//grab center of sprite
Posx = sprite.x + Sprite_Radius;
Posy = sprite.y + Sprite_Radius;
//create rectangle for the sprite
RECT spriteRect;
spriteRect.left = (long)sprite.x;
spriteRect.top = (long)sprite.y;
spriteRect.right = (long)sprite.x + sprite.width * sprite.scaling;
spriteRect.bottom = (long)sprite.y + sprite.height * sprite.scaling;
//recover North tile info
int N_posx, N_posy;
int N_tilex, N_tiley;
int N_tilevalue;
N_posx = Posx / TILEWIDTH;
N_posy = (Posy - TILEHEIGHT) / TILEHEIGHT;
N_tilex = N_posx * TILEWIDTH;
N_tiley = N_posy * TILEHEIGHT;
N_tilevalue = MAPDATA[(N_posy * MAPWIDTH + N_posx)];
//create rectangle for tile North of sprite center
RECT northRect;
northRect.left = N_tilex;
northRect.top = N_tiley;
northRect.right = N_tilex + TILEWIDTH;
northRect.bottom = N_tiley + TILEHEIGHT;
//recover South tile info
int S_posx, S_posy;
int S_tilex, S_tiley;
int S_tilevalue;
S_posx = Posx / TILEWIDTH;
S_posy = (Posy + TILEHEIGHT) / TILEHEIGHT;
S_tilex = S_posx * TILEWIDTH;
S_tiley = S_posy * TILEHEIGHT;
S_tilevalue = MAPDATA[(S_posy * MAPWIDTH + S_posx)];
//create rectangle for tile South of sprite center
RECT southRect;
southRect.left = S_tilex;
southRect.top = S_tiley;
southRect.right = S_tilex + TILEWIDTH;
southRect.bottom = S_tiley + TILEHEIGHT;
//recover West tile info
int W_posx, W_posy;
int W_tilex, W_tiley;
int W_tilevalue;
W_posx = (Posx - TILEWIDTH) / TILEWIDTH;
W_posy = Posy / TILEHEIGHT;
W_tilex = W_posx * TILEWIDTH;
W_tiley = W_posy * TILEHEIGHT;
W_tilevalue = MAPDATA[(W_posy * MAPWIDTH + W_posx)];
//create rectangle for tile West of sprite center
RECT westRect;
westRect.left = W_tilex;
westRect.top = W_tiley;
westRect.right = W_tilex + TILEWIDTH;
westRect.bottom = W_tiley + TILEHEIGHT;
//recover East tile info
int E_posx, E_posy;
int E_tilex, E_tiley;
int E_tilevalue;
E_posx = (Posx + TILEWIDTH) / TILEWIDTH;
E_posy = Posy / TILEHEIGHT;
E_tilex = E_posx * TILEWIDTH;
E_tiley = E_posy * TILEHEIGHT;
E_tilevalue = MAPDATA[(E_posy * MAPWIDTH + E_posx)];
//create rectangle for tile East of sprite center
RECT eastRect;
eastRect.left = E_tilex;
eastRect.top = E_tiley;
eastRect.right = E_tilex + TILEWIDTH;
eastRect.bottom = E_tiley + TILEHEIGHT;
RECT dest; //ignored
//check North collision
if (direction == 1 && N_tilevalue != 0)
{
return IntersectRect(&dest, &spriteRect, &northRect);
}
else return false;
//check South collision
if (direction == 2 && S_tilevalue != 0)
{
return IntersectRect(&dest, &spriteRect, &southRect);
}
else return false;
//check West collision
if (direction == 3 && W_tilevalue != 0)
{
return IntersectRect(&dest, &spriteRect, &westRect);
}
else return false;
//check East collision
if (direction == 4 && E_tilevalue != 0)
{
return IntersectRect(&dest, &spriteRect, &eastRect);
}
else return false;
}
And then the context I'm using the function to move the player sprite:
void MovePacman()
{
if (Wall_Collision(pacman, 1))
{
pacman.y -= pacman.vely;
pacman.vely = 0.0f;
}
else
{
if (Key_Down(DIK_UP))
{
pacman.vely = -0.2f;
pacman.velx = 0.0f;
}
}
if (Wall_Collision(pacman, 2))
{
pacman.y -= pacman.vely;
pacman.vely = 0.0f;
}
else
{
if (Key_Down(DIK_DOWN))
{
pacman.vely = 0.2f;
pacman.velx = 0.0f;
}
}
if (Wall_Collision(pacman, 3))
{
pacman.x -= pacman.velx;
pacman.velx = 0.0f;
}
else
{
if (Key_Down(DIK_LEFT))
{
pacman.velx = -0.2f;
pacman.vely = 0.0f;
}
}
if (Wall_Collision(pacman, 4))
{
pacman.x -= pacman.velx;
pacman.velx = 0.0f;
}
else
{
if (Key_Down(DIK_RIGHT))
{
pacman.velx = 0.2f;
pacman.vely = 0.0f;
}
else;
}
if (pacman.vely < 0)
Sprite_Animate(pacman.frame, pacman.startframe, 18, 4, pacman.starttime, 250);
else if (pacman.vely > 0)
Sprite_Animate(pacman.frame, pacman.startframe, 16, 2, pacman.starttime, 250);
else if (pacman.velx < 0)
Sprite_Animate(pacman.frame, pacman.startframe, 17, 3, pacman.starttime, 250);
else if (pacman.velx > 0)
Sprite_Animate(pacman.frame, pacman.startframe, 15, 1, pacman.starttime, 250);
pacman.y += pacman.vely;
pacman.x += pacman.velx;
}
trust that I've defined everything that is not pasted and linked headers correctly. Any ideas where I'm going wrong?

You're only checking for collisions in one case:
//check North collision
if (direction == 1 && N_tilevalue != 0)
{
return IntersectRect(&dest, &spriteRect, &northRect);
}
else return false; // <--- this
//check South collision
if (direction == 2 && S_tilevalue != 0)
{
return IntersectRect(&dest, &spriteRect, &southRect);
}
else return false; // <--- and this, etc...
See the line highlighted above. If it doesn't test for a North collision (i.e. if direction isn't 1 or N_tilevalue is 0) then the function returns at that point in all other cases. It can never go on to do the other collision checks.

Related

Sprite can not move in cocos2d-x

I am new on cocos2d-x, i followed Cocos2d-x Game Development Essentials Ebook and trying to make demo app in iOS. with the help of its guidance,but when i trying to Move Astroids in GameScreen.cpp file as written in book, they actually doesn't move and i can't understand what am i missing?
here is code that i used:
bool GameScene::init()
{
//////////////////////////////
// 1. super init first
if ( !Layer::init() )
{
return false;
}
//Add EVENT LISTENER TO HANDLE TOUCH EVENT,
auto listener = EventListenerTouchOneByOne::create();
listener->setSwallowTouches(true);
listener->onTouchBegan = CC_CALLBACK_2(GameScene::ontouchBegin,this);
listener->onTouchMoved = CC_CALLBACK_2(GameScene::ontouchMoved, this);
listener->onTouchCancelled = CC_CALLBACK_2(GameScene::ontouchCanceled, this);
listener->onTouchEnded = CC_CALLBACK_2(GameScene::ontouchEnded, this);
this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);
istouching = false;
touchPosition = 0;
visibleSize = Director::getInstance()->getVisibleSize();
origin = Director::getInstance()->getVisibleOrigin();
auto backgroundSprite = Sprite::create("Game_Screen_Background.png");
backgroundSprite->setPosition(Point((visibleSize.width/2)+origin.x,(visibleSize.height/2)+origin.y));
this->addChild(backgroundSprite, -1);
auto pauseItem =
MenuItemImage::create("Pause_Button.png","Pause_Button(Click).png",CC_CALLBACK_1(GameScene::PushToGamePauseScene, this));
pauseItem->setPosition(Point(pauseItem->getContentSize().width-(pauseItem->getContentSize().width/4)+origin.x,visibleSize.height - pauseItem->getContentSize().height +(pauseItem->getContentSize().width / 4) + origin.y));
auto menu = Menu::create(pauseItem, NULL);
menu->setPosition(Point::ZERO);
this->addChild(menu);
for (int i = 0; i < 2; i ++){
backgroundSpriteArray[i] = Sprite::create("Game_Screen_Background.png");
backgroundSpriteArray[i]->setPosition(Point((visibleSize.width/2)+origin.x,(-1*visibleSize.height*i)+(visibleSize.height/2)+origin.y));
this->addChild(backgroundSpriteArray[i],-2);
}
playerSprite = Sprite::create("Space_Pod.png");
playerSprite->setPosition(Point(visibleSize.width/2,pauseItem->getPosition().y-(pauseItem->getContentSize().height/2)-(playerSprite->getContentSize().height/2)));
this->addChild(playerSprite, 1);
this->schedule(schedule_selector(GameScene::spawnAsteroid), 1.0);
this->scheduleUpdate();
return true;
}
Following is update method
void GameScene::update(float dt){
Size visibleSize = Director::getInstance()->getVisibleSize();
Point origin = Director::getInstance()->getVisibleOrigin();
for (int i = 0; i < 2; i ++){
if (backgroundSpriteArray[i]->getPosition().y >=visibleSize.height + (visibleSize.height / 2) -1){
backgroundSpriteArray[i]->setPosition(Point((visibleSize.width / 2) + origin.x, (-1 *visibleSize.height) + (visibleSize.height / 2)));
}
}
for (int i = 0; i < 2; i ++){
backgroundSpriteArray[i]->setPosition(Point(backgroundSpriteArray[i]->getPosition().x,backgroundSpriteArray[i]->getPosition().y + (0.75 *visibleSize.height * dt)));
}
for (int i = 0; i < asteroids.size(); i++){
asteroids[i]->setPosition(Point(asteroids[i]->getPosition().x,asteroids[i]->getPosition().y+(0.75 * visibleSize.height * dt)));
if (asteroids[i]->getPosition().y > visibleSize.height * 2){
this->removeChild(asteroids[i]);
asteroids.erase(asteroids.begin() + i);
}
}
//check for Touching
if(istouching == true){
//now check, which side of the screen is being touched
if(touchPosition < visibleSize.width /2){
//now, move the space pod to left
float positionX = playerSprite->getPosition().x;
playerSprite->setPositionX(positionX - (0.50* visibleSize.width * dt));
positionX = playerSprite->getPositionX();
//prevent space pod to getting off the screen (left side)
if(positionX <= 0+(playerSprite->getContentSize().width/2))
{
playerSprite->setPositionX(playerSprite->getContentSize().width / 2);
}
}
else{
//now, move the space pod to right
float positionX = playerSprite->getPositionX();
playerSprite->setPositionX(positionX + (0.50 * visibleSize.width *dt));
positionX = playerSprite->getPositionX();
// check to prevent the space pod from going off the screen (right side)
if(positionX >= visibleSize.width-(playerSprite->getContentSize().width/2))
{
playerSprite->setPositionX(visibleSize.width-(playerSprite->getContentSize().width/2));
}
}
}
}
For move astroid code:
void GameScene::spawnAsteroid(float dt){
Size visibleSize = Director::getInstance()->getVisibleSize();
Point origin = Director::getInstance()->getVisibleOrigin();
int asteroidIndex = (arc4random() % 3) + 1;
__String* asteroidString = __String::createWithFormat("Asteroid_%i.png",asteroidIndex);
auto *tempAsteroid = Sprite::create(asteroidString->getCString());
int xRandomPosition = (arc4random() % (int)(visibleSize.width - (tempAsteroid->getContentSize().width / 2))) + (tempAsteroid->getContentSize().width / 2);
tempAsteroid->setPosition(Point(xRandomPosition + origin.x, -tempAsteroid->getContentSize().height +origin.y));
asteroids.push_back(tempAsteroid);
this->update(touchPosition);
this->addChild(asteroids[asteroids.size() - 1], -1);
}
That method has been called at run time but don't know that my astroid object does not moved can anybody please help me for figure it out issue and how to fix it.
Edit
OK,i put this->scheduleUpdate() in init(),and starts moving astroids on the screen but when i move my sprite(not astroids) with touchBegin event the astroid got disappear from screen. please guide me on this.
please put this line in your init method
this->scheduleUpdate();
Hope it helps
Sprite->runAction(Sequence::create(MoveTo::create(1.0f, Vec2(100,200)),NULL));

Sphere-cube collision detection in Opengl?

I am trying to build a game in Opengl. Before I start making better movement mechanics I want to get collision working. I have cube-cube collision working and I have sphere-sphere collision working, but can't figure out cube-sphere collision. Since I want it in 3d I have the pivot at the center of the objects. Anyone have any suggestions?
EDIT: This is the code I currently have:
bool SphereRectCollision( Sphere& sphere, Rectangle& rect)
{
//Closest point on collision box
float cX, cY;
//Find closest x offset
if( sphere.getCenterX() < rect.GetCenterX())//checks if the center of the circle is to the left of the rectangle
cX = rect.GetCenterX();
else if( sphere.getCenterX() > rect.GetCenterX() + rect.GetWidth()) //checks if the center of the circle is to the right of the rectangle
cX = rect.GetCenterX() + rect.GetWidth();
else //the circle is inside the rectagle
cX = sphere.getCenterX();
//Find closest y offset
if( sphere.getCenterY() > rect.GetCenterY() + rect.GetHeight() )
cY = rect.GetCenterY();
else if( sphere.getCenterY() < rect.GetCenterY() - rect.GetHeight() )
cY = rect.GetCenterY() + rect.GetHeight();
else
cY = sphere.getCenterY();
//If the closest point is inside the circle
if( distanceSquared( sphere.getCenterX(), sphere.getCenterY(), cX, cY ) < sphere.getRadius() * sphere.getRadius() )
{
//This box and the circle have collided
return false;
}
//If the shapes have not collided
return true;
}
float distanceSquared( float x1, float y1, float x2, float y2 )
{
float deltaX = x2 - x1;
float deltaY = y2 - y1;
return deltaX*deltaX + deltaY*deltaY;
}
I found the solution. I had the right idea, but didn't quite know how to execute it:
bool SphereRectCollision( Sphere& sphere, Rectangle& rect)
{
float sphereXDistance = abs(sphere.X - rect.X);
float sphereYDistance = abs(sphere.Y - rect.Y);
float sphereZDistance = abs(sphere.Z - rect.Z);
if (sphereXDistance >= (rect.Width + sphere.Radius)) { return false; }
if (sphereYDistance >= (rect.Height + sphere.Radius)) { return false; }
if (sphereZDistance >= (rect.Depth + sphere.Radius)) { return false; }
if (sphereXDistance < (rect.Width)) { return true; }
if (sphereYDistance < (rect.Height)) { return true; }
if (sphereZDistance < (rect.GetDepth)) { return true; }
float cornerDistance_sq = ((sphereXDistance - rect.Width) * (sphereXDistance - rect.Width)) +
((sphereYDistance - rect.Height) * (sphereYDistance - rect.Height) +
((sphereYDistance - rect.Depth) * (sphereYDistance - rect.Depth)));
return (cornerDistance_sq < (sphere.Radius * sphere.Radius));
}
This algorithm doesn't work when a hit happen on an edge, the 2nd set of if conditions triggers but a collision isn't occuring

Tilemap collision sfml c++ platformer

I have a problem with my 2d platformer. As i have just started out with c++ i'm having trouble with tile collision. I'm able to prevent the player from entering the tile and also being able to move away from it but somehow he cant move along the tile.
This is the function for checking if the new position is inside a solid tile:
void Maps::drawColMap(Player& _player){
for (int i = 0; i < _player.tiles.size(); i++)
{
if (colMap[_player.tiles[i].y][_player.tiles[i].x] == 1) //solid tile = 1
{
_player.willCollide = true;
break;
}
else {
_player.willCollide = false;
}
}
}
And here is the code for moving the player:
void Player::update()
{
sf::Vector2f newPosition;
sf::Vector2f oldPosition;
oldPosition.x = playerImage.getPosition().x; // store the current position
oldPosition.y = playerImage.getPosition().y;
newPosition.x = playerImage.getPosition().x; // store the new position
newPosition.y = playerImage.getPosition().y;
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
{
source.y = Left; //sprite stuff
moving = true;
newPosition.x -= 2;
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
{
source.y = Right;
moving = true;
newPosition.x += 2;
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
{
source.y = Up;
moving = true;
newPosition.y -= 2;
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
{
source.y = Down;
moving = true;
newPosition.y += 2;
}
if (!(sf::Keyboard::isKeyPressed(sf::Keyboard::Left) || sf::Keyboard::isKeyPressed(sf::Keyboard::Right) || sf::Keyboard::isKeyPressed(sf::Keyboard::Up) || sf::Keyboard::isKeyPressed(sf::Keyboard::Down)))
{
moving = false;
}
//create corners to check collision
bottom = newPosition.y + 32; //tile size is 32 px
left = newPosition.x;
right = newPosition.x + 32;
top = newPosition.y;
sf::Vector2i topLeft(sf::Vector2i((int)left / 32, (int)top / 32)); // get the corners of the new position
sf::Vector2i topRight(sf::Vector2i((int)right / 32, (int)top / 32));
sf::Vector2i bottomLeft(sf::Vector2i((int)left / 32, (int)bottom / 32));
sf::Vector2i bottomRight(sf::Vector2i((int)right / 32, (int)bottom / 32));
tiles.clear();
tiles.push_back(topLeft);
if (std::find(tiles.begin(), tiles.end(), topRight) == tiles.end()) tiles.push_back(topRight); //check the corners
if (std::find(tiles.begin(), tiles.end(), bottomLeft) == tiles.end()) tiles.push_back(bottomLeft);
if (std::find(tiles.begin(), tiles.end(), bottomRight) == tiles.end()) tiles.push_back(bottomRight);
//if no collision set the position to the new position
if (!willCollide)
playerImage.setPosition(newPosition);
else
playerImage.setPosition(oldPosition); //if collision then set the position to the previous position
}
Any help is appreciated!
//edit 1
I tried logging the collision and it says that the player is still in the collision area even if i dont press anything. But how do i prevent the player from entering? I cant find the problem.
//edit 2
I think i found another problem.
The collision check should probably be run just before moving the player and after moving the new position.
After the player collides, and you change the positions, move it over by 1 pixel in the away from the collision area (the appropriate direction). It's possible that your corner is still within the collision bounds if it wasn't moved out of of the collision area properly.

Prevent moving a sprite onto another sprite

I have some sprites (2d-boxes) of the same type stored in a formation vector. Now i want to move them around with the mouse, that works well. But the code should prevent the player to move one sprite onto another already existing sprite of the vector.
My solution is quite ugly and does not work. Whenever a sprite is moved around, i test with the spriteoverlap function if the sprite is moved onto another. The Problem:
Whenever the sprite is directly close to the it stops moving, which is what wanted.
But i can't move it anymore afterwards because the overlapfunction sets the bool always to false.
while (App.pollEvent(Event))
{
//Moving the playerbuttons on the formation screen
for (size_t k = 0; k < formation.size(); k++)
{
bool drag_onto_otherplayer = false;
if (isMouseOver(formation[k], App) == true)
{
//The next loop tests if the sprite being moved with the mouse overlaps with another sprite from the formation vector
for (size_t j = 0; j < formation.size(); j++)
{
if (spriteOverlap(formation[j], formation[k], App) == true && k!=j)
{
std::cout << drag_onto_otherplayer << std::endl;
drag_onto_otherplayer = true;
std::cout << drag_onto_otherplayer <<std::endl;
}
if (drag_onto_otherplayer == false)
//(If the sprite does not overlap getting the new sprite position from the mouseposition)
{
Mouseposition =sf::Vector2f(sf::Mouse::getPosition(App));
Mouseposition.x = Mouseposition.x - formation[k].getLocalBounds().width / 2;
Mouseposition.y = Mouseposition.y - formation[k].getLocalBounds().height / 2;
formation[k].setPosition(sf::Vector2f(Mouseposition));
Formation_playernames.clear();
Formation_playerinformation.clear();
Formation_Playernames(Font, Formation_playernames, formation, playerlist);
Formation_Playerinformation(Font, Formation_playerinformation, formation, playerlist);
}
So the problem are my loops and the bool test i guess, but i don't know how to solve it.
Any ideas ?
Here is my spriteoverlap function:
bool spriteOverlap(sf::Sprite &sprite1, sf::Sprite &sprite2, sf::RenderWindow &App)
{
float x_min1 = sprite1.getPosition().x;
float x_max1 = sprite1.getPosition().x + sprite1.getLocalBounds().width;
float y_min1 = sprite1.getPosition().y;
float y_max1 = sprite1.getPosition().y + sprite1.getLocalBounds().height;
float x_min2 = sprite2.getPosition().x;
float x_max2 = sprite2.getPosition().x + sprite2.getLocalBounds().width;
float y_min2 = sprite2.getPosition().y;
float y_max2 = sprite2.getPosition().y + sprite2.getLocalBounds().height;
if (x_min1 > x_max2 | x_max1 < x_min2 | y_min1 > y_max2 | y_max1 < y_max2)
return false;
else
return true;
};
And my isMouseover function:
bool isMouseOver(sf::Sprite &sprite, sf::RenderWindow &App)
{
float pos_x = sprite.getPosition().x;
float pos_y = sprite.getPosition().y;
if (sf::Mouse::getPosition(App).x > pos_x && sf::Mouse::getPosition(App).x < pos_x+sprite.getLocalBounds().width &&
sf::Mouse::getPosition(App).y >pos_y && sf::Mouse::getPosition(App).y < pos_y + sprite.getLocalBounds().height)
{
return true;
}
else
return false;
};
Check for collision is already included somewhat in sfml:
bool spriteOverlap(sf::Sprite& sprite1, sf::Sprite& sprite2) // possibly const, dunno
{
return sprite1.getGlobalBounds().intersects(sprite2.getGlobalBounds());
}
Generally try this: Only move, if the position of the next frame is valid. This prevents objects being stuck, because you already moved them into an invalid position, thus preventing any further movement
edit:
//untested
bool spritesWillOverlap(sf::Sprite& sprite1, sf::Sprite& sprite2, sf::Vector2f vel)
{
top1 = sprite1.getGobalBounds().top + vel.y;
left1 = sprite1.getGlobalBounds().left + vel.x;
right1 = left1 + sprite1.getGlobalBounds().width;
bottom1 = top1 + sprite1.getGlobalBounds().height;
top2 = sprite2.getGobalBounds().top + vel.y;
left2 = sprite2.getGlobalBounds().left + vel.x;
right2 = left2 + sprite1.getGlobalBounds().width;
bottom2 = top2 + sprite1.getGlobalBounds().height;
sf::FloatRect rect1(top1, left1, right1 - left1, bottom1 - top1);
sf::FloatRect rect2(top2, left2, right2 - left2, bottom2 - top2);
return rect1.intersects(rect2);
}
vel: velocity -> an object is moved by this 2D vector every frame
If the concept of "frames" is unfamiliar, read up on framerates/fixed framerate and/or timestep. here's an example article to get started: Fix Your Timestep!

Cocos2d Accelerometer Landscape

Im having trouble getting the accelerometer to work correctly in landscape mode with cocos2d. Everything works perfectly in portrait, but cant figure out how to flip it to correctly work in landscape. here is my code:
-(void) accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
float deceleration = 0.0f;
float sensativity = 15.0f;
float maxVelocity = 100;
playerVelocity.x = playerVelocity.x * deceleration + acceleration.x * sensativity;
playerVelocity.y = playerVelocity.y * deceleration + acceleration.y * sensativity;
if (playerVelocity.x > maxVelocity)
{
playerVelocity.x = maxVelocity;
}
else if (playerVelocity.x < - maxVelocity)
{
playerVelocity.x = - maxVelocity;
}
if (playerVelocity.y > maxVelocity)
{
playerVelocity.y = maxVelocity;
}
else if (playerVelocity.y < - maxVelocity)
{
playerVelocity.y = - maxVelocity;
}
}
-(void) update:(ccTime) delta
{
CGPoint pos = player.position;
pos.x += playerVelocity.x;
pos.y += playerVelocity.y;
CGSize screeSize = [[CCDirector sharedDirector]winSize];
float imageHalf = [player texture].contentSize.width * 0.5f;
float leftLimit = imageHalf;
float rightLimit = screeSize.width - imageHalf -20;
float bottomLimit = imageHalf;
float topLimit = screeSize.height - imageHalf - 20;
if (pos.y < bottomLimit) {
pos.y = bottomLimit;
}
else if (pos.y > topLimit){
pos.y = topLimit;
}
if (pos.x < leftLimit) {
pos.x = leftLimit;
}
else if (pos.x > rightLimit){
pos.x = rightLimit;
}
player.position = pos;
}
In landscape orientation, the accelerometer x and y values are flipped. Furthermore, in interface orientation landscape right, x is negative. In landscape left, y is negative:
// landscape right:
position.x = -acceleration.y
position.y = acceleration.x
// landscape left:
position.x = acceleration.y
position.y = -acceleration.x
Look at answer in this question
Best way for accelerometer usage in cocos2d game.