Cocos2d-x collision won't trigger OnContactBegin callback - c++

I've been trying to prevent the collision between the Player and a VisionZone (a cone in front of the player that represent a flash light effect). The VisionZone is spawning on top of the player.
My problem is : since they both have physic bodies, they collide and the VisionZone pushes the player. This is not what I want.
The VisionZone and the Player have the same entity_collision_bitmask, I thought this would actually prevent them from colliding in the begining ?
Since it didn't work, I tried using a CollisionManager, but I'm never getting into the OnContactBegin callback. The Init()method is called in the init()method of the scene and I call this line :
_eventDispatcher->addEventListenerWithSceneGraphPriority(CollisionManager::GetContactListener(), this);
CollisionManager.cpp
EventListenerPhysicsContact *CollisionManager::m_contactListener = nullptr;
void CollisionManager::Init() {
m_contactListener = EventListenerPhysicsContact::create();
m_contactListener->onContactBegin = [](PhysicsContact &contact) { return ContactBeginCallback(contact); };
m_contactListener->onContactSeparate = [](PhysicsContact &contact) { return ContactSeparateCallback(contact); };
}
bool CollisionManager::ContactBeginCallback(PhysicsContact &contact) {
PhysicsBody *_bodyA = contact.getShapeA()->getBody();
PhysicsBody *_bodyB = contact.getShapeB()->getBody();
const bool visionAndWallCondition = ((_bodyA->getCategoryBitmask() == vision_zone_collision_bitmask &&
_bodyB->getCategoryBitmask() == map_collision_bitmask) ||
(_bodyB->getCategoryBitmask() == vision_zone_collision_bitmask &&
_bodyA->getCategoryBitmask() == map_collision_bitmask));
if (visionAndWallCondition) {
for (Vec2 _p: contact.getContactData()->points) VisionZone::sm_shapeCollisionPoints.push_back(_p);
return true;
}
return false;
}
bool CollisionManager::ContactSeparateCallback(PhysicsContact &contact) {
PhysicsBody *_bodyA = contact.getShapeA()->getBody();
PhysicsBody *_bodyB = contact.getShapeB()->getBody();
const bool visionAndWallCondition = ((_bodyA->getCategoryBitmask() == vision_zone_collision_bitmask &&
_bodyB->getCategoryBitmask() == map_collision_bitmask) ||
(_bodyB->getCategoryBitmask() == vision_zone_collision_bitmask &&
_bodyA->getCategoryBitmask() == map_collision_bitmask));
if (visionAndWallCondition) {
VisionZone::sm_shapeCollisionPoints.clear();
return true;
}
return false;
}
NB : For the map_collision_bitmask, it will be added to the walls physicBodies so the VisionZone collides with them, using Ray Tracing.
VisionZone.cpp
void VisionZone::CreateNewPhysicBody(std::vector<Vec2> &points) {
points.push_back(m_origin);
PhysicsBody *_body = PhysicsBody::createEdgePolygon(
&points.front(),
int(points.size()),
PHYSICSBODY_MATERIAL_DEFAULT,
1
);
_body->setCategoryBitmask(entity_collision_bitmask);
_body->setCollisionBitmask(map_collision_bitmask);
_body->setContactTestBitmask(contact_test_bitmask);
_body->setDynamic(true);
_body->setGravityEnable(false);
setPhysicsBody(_body);
}
Bitmasks.h
constexpr int vision_zone_collision_bitmask = 0x01;
constexpr int map_collision_bitmask = 0x02;
constexpr int entity_collision_bitmask = 0x03;
constexpr int contact_test_bitmask = 0x04;

Related

Dynamic Light effect with Cocos2d-x 4.0 and C++

I've been trying to create a dynamic light effect with cocos2d-x, but I cannot find a good tutorial for the 4.0 version.
For the context, I'm developping a top-down game for as a personnal project. The light would spread directly in front of the player like a flash-light, lighting every object in front of him and "colliding" with the walls and entities
The Shader hint
I've found multiple repos creating a custom light effect with cocos2d-x, but they all use the 3.0 version. The 4.0 version changed how the OpenGL code is managed in the Cocos backend.
Here's the repos I've found :
https://github.com/CodeAndWeb/cocos2d-x-dynamic-lighting
https://github.com/zerodarkzone/Cocos2d-x-lights
https://github.com/wantnon2/EffectNodes-for-cocos2dx
I've also read the Cocos2d-x Gitbook which explains what exactly changed in the CCSprite file.
Since I'm a beginner to Cocos2d-x and shader rendering, I did not understand what I had to change to make the old repos work ..
The polygon hint
I tried to create a VisionZone that would be a Cocos2d-x Node. The node would have a physic body colliding with the walls. On collision, the shape would update and adapt its shape.
Here's what the code would look like :
VisionZone.h
class VisionZone : public Node {
public:
static std::vector<Vec2> sm_shapeCollisionPoints;
static VisionZone *create(Vec2 origin, int visionDetail);
bool init() override;
void update(float delta) override;
void UpdateWithPlayer(Vec2 playerPos);
private:
void CreateNewPhysicBody(std::vector<Vec2> &points);
void UpdateShapeAndRedraw();
static bool IsInLine(Vec2 segmentStart, Vec2 segmentEnd, Vec2 point);
void CompareWithContactPoints();
void Rotate();
std::vector<Vec2> m_nonCollidedSegmentsEnds;
std::vector<Vec2> m_collidedSegmentsEnds;
Vec2 m_origin;
DrawNode *m_pVisionZoneDrawer;
int m_visionDetail;
VisionZone.cpp
std::vector<Vec2> VisionZone::sm_shapeCollisionPoints = {};
VisionZone *VisionZone::create(Vec2 origin, int visionDetail) {
auto *_obj = new(std::nothrow) VisionZone();
if (_obj && _obj->init()) {
_obj->m_origin = origin;
_obj->m_visionDetail = visionDetail;
int mid = std::floor(_obj->m_visionDetail * 0.5);
for (int i = -(mid); i <= mid; i++) {
_obj->m_nonCollidedSegmentsEnds.emplace_back(
static_cast<float>(_obj->m_origin.x + float(i) * 1.3f), _obj->m_origin.y + 300
);
}
_obj->m_collidedSegmentsEnds = _obj->m_nonCollidedSegmentsEnds;
std::vector<Vec2> _points = _obj->m_nonCollidedSegmentsEnds;
_points.emplace_back(_obj->m_origin);
_obj->CreateNewPhysicBody(_points);
} else
CC_SAFE_DELETE(_obj);
return _obj;
}
bool VisionZone::init() {
if (!Node::init()) return false;
m_pVisionZoneDrawer = DrawNode::create();
m_pVisionZoneDrawer->setPosition(m_origin);
assert(m_pVisionZoneDrawer);
addChild(m_pVisionZoneDrawer);
return true;
}
void VisionZone::update(float delta) {
Node::update(delta);
CompareWithContactPoints();
Rotate();
UpdateShapeAndRedraw();
}
void VisionZone::UpdateWithPlayer(Vec2 playerPos) {
m_origin = playerPos;
setPosition(m_origin);
}
void VisionZone::CreateNewPhysicBody(std::vector<Vec2> &points) {
points.push_back(m_origin);
PhysicsBody *_body = PhysicsBody::createEdgePolygon(
&points.front(),
int(points.size()),
PHYSICSBODY_MATERIAL_DEFAULT,
1
);
_body->setCategoryBitmask(vision_zone_collision_bitmask);
_body->setCollisionBitmask(map_collision_bitmask);
_body->setContactTestBitmask(true);
_body->setDynamic(false);
setPhysicsBody(_body);
}
bool VisionZone::IsInLine(Vec2 segmentStart, Vec2 segmentEnd, Vec2 point) {
float _startToPoint = sqrt(pow((segmentStart.x - point.x), 2) + pow((segmentStart.y - point.y), 2));
float _pointToEnd = sqrt(pow((point.x - segmentEnd.x), 2) + pow((point.y - segmentEnd.y), 2));
float _startToEnd = sqrt(pow((segmentStart.x - segmentEnd.x), 2) + pow((segmentStart.y - segmentEnd.y), 2));
return (_startToPoint + _pointToEnd == _startToEnd);
}
void VisionZone::CompareWithContactPoints() {
if (sm_shapeCollisionPoints.empty()) {
m_collidedSegmentsEnds = {m_origin, m_nonCollidedSegmentsEnds.front(), m_nonCollidedSegmentsEnds.back()};
return;
}
for (Vec2 &_nonCollidedEnd: m_nonCollidedSegmentsEnds) {
for (Vec2 &_contactPoint: sm_shapeCollisionPoints) {
if (IsInLine(m_origin, _nonCollidedEnd, _contactPoint)) {
Vec2 _midPoint = (m_nonCollidedSegmentsEnds.front() + m_nonCollidedSegmentsEnds.back()) / 2;
if (IsInLine(m_nonCollidedSegmentsEnds.front(), _midPoint, _contactPoint)) {
m_collidedSegmentsEnds = {
m_origin, sm_shapeCollisionPoints.front(), sm_shapeCollisionPoints.back(),
m_nonCollidedSegmentsEnds.back()
};
} else if (IsInLine(_midPoint, m_nonCollidedSegmentsEnds.back(), _contactPoint)) {
m_collidedSegmentsEnds = {
m_origin, m_nonCollidedSegmentsEnds.front(), sm_shapeCollisionPoints.front(),
sm_shapeCollisionPoints.back()
};
}
}
}
}
}
void VisionZone::Rotate() {
float _distanceX = InputManager::GetCursorPosX() - getPositionX();
float _distanceY = InputManager::GetCursorPosY() - getPositionY();
float _angle = atan2(_distanceY, _distanceX) * 180.f / static_cast<float>(M_PI);
setRotation(_angle);
}
void VisionZone::UpdateShapeAndRedraw() {
PhysicsShape *_newShape = getPhysicsBody()->addShape(PhysicsShapePolygon::create(
m_collidedSegmentsEnds.data(), int(m_collidedSegmentsEnds.size()))
);
assert(_newShape);
m_pVisionZoneDrawer->clear();
m_pVisionZoneDrawer->drawSolidPoly(
&m_collidedSegmentsEnds.front(),
m_collidedSegmentsEnds.size(),
Color4F(1.f, 0.94, 0.7, 1)
);
}
CollisionManager.cpp
#include "CollisionManager.h"
#include "Utility/Bitmasks.h"
USING_NS_CC;
EventListenerPhysicsContact *CollisionManager::m_contactListener = nullptr;
void CollisionManager::Init() {
m_contactListener = EventListenerPhysicsContact::create();
m_contactListener->onContactBegin = [](PhysicsContact &contact) { return ContactBeginCallback(contact); };
m_contactListener->onContactSeparate = [](PhysicsContact &contact) { return ContactSeparateCallback(contact); };
}
bool CollisionManager::ContactBeginCallback(PhysicsContact &contact) {
PhysicsBody *_bodyA = contact.getShapeA()->getBody();
PhysicsBody *_bodyB = contact.getShapeB()->getBody();
const bool visionAndWallCondition = ((_bodyA->getCategoryBitmask() == vision_zone_collision_bitmask &&
_bodyB->getCategoryBitmask() == map_collision_bitmask) ||
(_bodyB->getCategoryBitmask() == vision_zone_collision_bitmask &&
_bodyA->getCategoryBitmask() == map_collision_bitmask));
if (visionAndWallCondition) {
for (Vec2 _p: contact.getContactData()->points) VisionZone::sm_shapeCollisionPoints.push_back(_p);
return true;
}
return false;
}
bool CollisionManager::ContactSeparateCallback(PhysicsContact &contact) {
PhysicsBody *_bodyA = contact.getShapeA()->getBody();
PhysicsBody *_bodyB = contact.getShapeB()->getBody();
const bool visionAndWallCondition = ((_bodyA->getCategoryBitmask() == vision_zone_collision_bitmask &&
_bodyB->getCategoryBitmask() == map_collision_bitmask) ||
(_bodyB->getCategoryBitmask() == vision_zone_collision_bitmask &&
_bodyA->getCategoryBitmask() == map_collision_bitmask));
if (visionAndWallCondition) {
VisionZone::sm_shapeCollisionPoints.clear();
return true;
}
return false;
}
GameLayer.cpp
bool GameLayer::init() {
if (!Layer::init()) return false;
CollisionManager::Init();
_eventDispatcher->addEventListenerWithSceneGraphPriority(CollisionManager::GetContactListener(), this);
// ... SOME CODE ... //
m_visionZone = VisionZone::create(player->getPosition(), 100);
addChild(m_visionZone, 1);
return true;
}
void GameLayer::update(float delta) {
Node::update(delta);
m_visionZone->UpdateWithPlayer(m_player->getPosition());
}
I am not sure about this method though ... I feels like it is not optimal at all ?
Really curious to have some feedback on this, thanks in advance, sorry for the quantity of code :)
Let me know if you need more informations, code or links

Why setPosition work in some condition but doesn't work in other condition?

i make a game let's say ThrowBall, the Player can pick up the ball spawned and throw it into target get the score added then the ball return it's position and repeat. The problem is when Ball dragged by Player (i make the Ball as child of Player) into target, the Ball return it's position correctly into desired position, but the odd happens when it collided after i send the Ball into target by applying impulse it won't return the ball into desired position, why is this happening?
i'm running this game for android, i'm running this code in VS'17 using cocos2d-x-3.17. I tried changing impulse into force, moveby. I tried making the ball stop (setVelocity to zero before setPosition). I tried changing Point into Vect, vec2. I tried to break point debug, the code do read setPosition but do nothing.
GameScene.cpp
bool GameScene::init()
{
//////////////////////////////
// 1. super init first
if ( !Layer::init() )
{
return false;
}
auto pickupListener = EventListenerPhysicsContact::create();
pickupListener->onContactBegin = CC_CALLBACK_1(GameScene::onContactBegin, this);
Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(pickupListener, this);
return true;
}
bool GameScene::onContactBegin(cocos2d::PhysicsContact &contact)
{
PhysicsBody *a = contact.getShapeA()->getBody();
PhysicsBody *b = contact.getShapeB()->getBody();
if (
(BALL_COLLISION_BITMASK == a->getCollisionBitmask() && PLAYER_COLLISION_BITMASK == b->getCollisionBitmask()) ||
(BALL_COLLISION_BITMASK == b->getCollisionBitmask() && PLAYER_COLLISION_BITMASK == a->getCollisionBitmask())
)
{
// make the ball follow Player
isfollow = true;
}
else if (
(BALL_COLLISION_BITMASK == a->getCollisionBitmask() && TARGET_COLLISION_BITMASK == b->getCollisionBitmask()) ||
(BALL_COLLISION_BITMASK == b->getCollisionBitmask() && TARGET_COLLISION_BITMASK == a->getCollisionBitmask())
)
{
isfollow = false;
// add score
score++;
__String *tempScore = __String::createWithFormat("%i", score);
scoreLabel->setString(tempScore->getCString());
// return spawn ball
ball->returnPos();
return false;
}
void GameScene::throwBall() {
if (isfollow == true) {
isfollow = false;
ball->getSprite()->getPhysicsBody()->applyImpulse(Vec2(100000, 100000));
}
}
Ball.h
class Ball
{
public:
Ball(cocos2d::Layer *layer);
cocos2d::Sprite *getSprite() { return randomSpawn; };
void returnPos();
private:
cocos2d::Size visibleSize;
cocos2d::Vec2 origin;
cocos2d::Sprite *randomSpawn;
};
Ball.cpp
Ball::Ball(cocos2d::Layer *layer)
{
visibleSize = Director::getInstance()->getVisibleSize();
origin = Director::getInstance()->getVisibleOrigin();
randomSpawn = Sprite::create("res/ball.png");
randomSpawn->setPosition(Vec2(400, 80));
auto randomBallBody = PhysicsBody::createCircle(randomSpawn->getContentSize().width / 2);
randomBallBody->setCollisionBitmask(BALL_COLLISION_BITMASK);
randomBallBody->setContactTestBitmask(true);
randomBallBody->setGravityEnable(false);
randomSpawn->setPhysicsBody(randomBallBody);
layer->addChild(randomSpawn);
}
void Ball::returnPos()
{
randomSpawn->setPosition(Vec2(400, 80));
}
i want to make the object (Ball) return position when collided into Target and repeat. i'm sorry if the format is a mess, i'm new here, also it's not my full code, it's actually works fine i can run it, but only the setPosition won't work

How to make trigger area in Cocos2d

I am doing a Flappy Bird game following some tutorials. To count up the score, I have set PhysicsBody among the score area, but it is just like a Rigibody in Unity, other objects cannot get through it.
You can take reference at https://www.youtube.com/watch?v=3zGTCGgwt_U&list=PLRtjMdoYXLf7GSD9crXIjMQiRuIZ7mUVp&index=12, it is the result that I want. I followed it but I don't know why here comes a difference.
In my situation, the score line blocks my flying bird. As the score lines and pipes are moving backward, my flappy bird is pushed by the score line until it reaches the screen edge and turns out a gameover.
I want something like a Trigger Collider in Unity. Is there any similar thing in cocos2d?
Also attach my code here, it spawns the pipes as well as the score line:
void Pipe::Spawn(Layer* pipeLayer) {
auto upperPipe = Sprite::create("pipe_upper.png");
upperPipe->setAnchorPoint(Vec2(0.5,0));
upperPipe->setScale(spriteScale);
auto upperPipeBody = PhysicsBody::createBox(upperPipe->getContentSize());
upperPipeBody->setDynamic(false);
upperPipeBody->setCollisionBitmask(OBSTACLE_COLLISION_BITMASK);
upperPipeBody->setContactTestBitmask(true);
upperPipe->setPhysicsBody(upperPipeBody);
auto bottomPipe = Sprite::create("pipe_bottom.png");
bottomPipe->setAnchorPoint(Vec2(0.5,1));
bottomPipe->setScale(spriteScale);
auto bottomPipeBody = PhysicsBody::createBox(bottomPipe->getContentSize());
bottomPipeBody->setDynamic(false);
bottomPipeBody->setCollisionBitmask(OBSTACLE_COLLISION_BITMASK);
bottomPipeBody->setContactTestBitmask(true);
bottomPipe->setPhysicsBody(bottomPipeBody);
float randomPosIndex = CCRANDOM_0_1();
if (randomPosIndex < PIPE_BOTTOM_THRESHOLD) {
randomPosIndex = PIPE_BOTTOM_THRESHOLD;
}
else if (randomPosIndex > PIPE_UPPER_THRESHOLD) {
randomPosIndex = PIPE_UPPER_THRESHOLD;
}
float gapHeight = Sprite::create("flappybird1_01.png")->getContentSize().height * spriteScale * PIPE_GAP_INDEX;
Size visibleSize = Director::getInstance()->getVisibleSize();
//setup bottom pipe
bottomPipe->setPosition(Point(visibleSize.width, visibleSize.height * randomPosIndex));
//setup upper pipe
upperPipe->setPosition(Point(visibleSize.width, bottomPipe->getPositionY() + gapHeight));
//setup score area
auto scoreNode = Node::create();
auto scoreNodeBody = PhysicsBody::createBox(Size(1, gapHeight));
scoreNodeBody->setDynamic(false);
scoreNodeBody->setCollisionBitmask(SCORE_COLLISION_BITMASK);
scoreNodeBody->setContactTestBitmask(true);
scoreNode->setPhysicsBody(scoreNodeBody);
scoreNode->setPosition(Point(bottomPipe->getPositionX(), bottomPipe->getPositionY() + gapHeight / 2));
auto bottomPipeAction = RepeatForever::create(MoveBy::create(1, Vec2(-PIPE_MOVE_SPEED, 0)));
auto upperPipeAction = RepeatForever::create(MoveBy::create(1, Vec2(-PIPE_MOVE_SPEED, 0)));
auto scoreNodeAction = RepeatForever::create(MoveBy::create(1, Vec2(-PIPE_MOVE_SPEED, 0)));
bottomPipe->runAction(bottomPipeAction);
upperPipe->runAction(upperPipeAction);
scoreNode->runAction(scoreNodeAction);
pipeLayer->addChild(bottomPipe);
pipeLayer->addChild(upperPipe);
pipeLayer->addChild(scoreNode);
CCLOG("Spawn Pipe");
}
Credits to ryemoss's reference. Simply return false in the collision callback function solves everything!
bool GameScene::onContactBegin(PhysicsContact &contact)
{
PhysicsBody* a = contact.getShapeA()->getBody();
PhysicsBody* b = contact.getShapeB()->getBody();
if ( (a->getCollisionBitmask() == FLAPPYBIRD_COLLISION_BITMASK && b->getCollisionBitmask() == OBSTACLE_COLLISION_BITMASK) ||
(b->getCollisionBitmask() == FLAPPYBIRD_COLLISION_BITMASK && a->getCollisionBitmask() == OBSTACLE_COLLISION_BITMASK)
)
{
auto gameoverScene = GameOverScene::createScene();
Director::getInstance()->replaceScene(TransitionFade::create(SCENE_TRANSITION_DURATION, gameoverScene));
}
else if ((a->getCollisionBitmask() == FLAPPYBIRD_COLLISION_BITMASK && b->getCollisionBitmask() == SCORE_COLLISION_BITMASK) ||
(b->getCollisionBitmask() == FLAPPYBIRD_COLLISION_BITMASK && a->getCollisionBitmask() == SCORE_COLLISION_BITMASK))
{
score++;
CCLOG("Score Count: %i", score);
return false;
}
return true;
}

How to move an entity with a mouse click?

Ok i now manage to figure out the problem but now another issue appear, my robot seem to move on its own to another point which i have no idea where its from. Here my code
His code make this robot move to the location i click on the terrain.
bool DemoApp::nextLocation(void){
mDestination = mtoward;
mRobotDir = mDestination - mRobotNode[0]->getPosition();
mDistance = mRobotDir.normalise();
return true;
}
bool DemoApp::frameRenderingQueued(const Ogre::FrameEvent& evt)
{
if (mRobotDir == Ogre::Vector3::ZERO) {
if (nextLocation()) {
// Set walking animation
mAnimationState = mRobot[0]->getAnimationState("Walk");
mAnimationState->setLoop(true);
mAnimationState->setEnabled(true);
}//if
}else{
Ogre::Real move = mWalkSpeed * evt.timeSinceLastFrame;
mDistance -= move;
if (mDistance <= 0.0f){
mRobotNode[0]->setPosition(mDestination);
mRobotDir = Ogre::Vector3::ZERO;
// Set animation based on if the robot has another point to walk to.
if (!nextLocation()){
// Set Idle animation
mAnimationState = mRobot[0]->getAnimationState("Idle");
mAnimationState->setLoop(true);
mAnimationState->setEnabled(true);
}else{
// Rotation Code will go here later
Ogre::Vector3 src = mRobotNode[0]->getOrientation() * Ogre::Vector3::UNIT_X;
if ((1.0f + src.dotProduct(mRobotDir)) < 0.0001f) {
mRobotNode[0]->yaw(Ogre::Degree(180));
}else{
Ogre::Quaternion quat = src.getRotationTo(mRobotDir);
mRobotNode[0]->rotate(quat);
} // else
}//else
}else{
mRobotNode[0]->translate(mRobotDir * move);
} // else
} // if
mAnimationState->addTime(evt.timeSinceLastFrame);
}
Here is the raycast code for my mouse click
Ogre::Terrain* pTerrain = mTerrainGroup->getTerrain(0, 0);
Ogre::Viewport* vp = this->mWindow->getViewport(0);
Ogre::Ray mouseRay = mCamera->getCameraToViewportRay(static_cast<float>(mMouse->getMouseState().X.abs)/mMouse->getMouseState().width, static_cast<float>(mMouse->getMouseState().Y.abs)/mMouse->getMouseState().height);
std::pair <bool, Ogre::Vector3> result;
result = pTerrain->rayIntersects(mouseRay, true, 0);
if (result.first = true)
{
mtoward = result.second - mRobotNode[0]->_getDerivedPosition();
mRobotNode[0]->translate(mtoward, Ogre::Node::TS_LOCAL);
}

Xcode Collision Detection Error Cocos2D Assertion Error

I am making a ball game in cocos2D, where you can slide the ball in a direction, and it will travel until it collides with a wall. My collision detection is giving me an "assertion error" when I swipe the ball in a direction.
I am using tiledmap to make the levels.
The way I've coded it is that I find the tilesize that my ball is in, then, in a for loop, I check if there are any wall sprites around the ball.
Any ideas where its going wrong?
-(void)callEveryFrame:(ccTime)dt{
//Error Here vvv (Assertion Failure in -[CCTMXLayer tileAt:])
NSLog(#"First Touch x: /%f Last Touch x: /%f First Touch y: /%f Last Touch y: /%f", firstTouch.x, lastTouch.x, firstTouch.y, lastTouch.y);
if(swipeLeft || swipeRight || swipeDown || swipeUp)
{
bool collision = false;
int ballTileX = (player.position.x / level1.tileSize.width);
int ballTileY = (player.position.y / level1.tileSize.width);
int collisionAreaX = ballTileX-1;
int collisionAreaY = ballTileY-1;
for(int i = 0; i < 9; i++)
{
bool tilePresent = [background tileAt:CGPointMake(collisionAreaX, collisionAreaY)] != NULL;
if(tilePresent && CGRectIntersectsRect(CGRectMake(collisionAreaX*level1.tileSize.width, collisionAreaY*level1.tileSize.height, level1.tileSize.width, level1.tileSize.height), CGRectMake(ballTileX*level1.tileSize.width, ballTileY*level1.tileSize.height, level1.tileSize.width, level1.tileSize.height)))
{
collision = true;
break;
}
if(i % 3 == 0)
{
collisionAreaX -= 2;
collisionAreaY++;
}
else
{
collisionAreaX++;
}
}
if(collision) {
swipeLeft = false;
swipeRight = false;
swipeDown = false;
swipeUp = false;
}
}
}