手把手教你制作一款Box2D小游戏(三)

news/2024/7/20 21:07:49 标签: IOS, box2d, 游戏


接着我们先来重写ContactListener:

类声明:

#import "Box2D.h"

 

class ContactListener : public b2ContactListener

{

public:

      voidBeginContact(b2Contact* contact);

      voidPreSolve(b2Contact* contact, const b2Manifold* oldManifold);

      voidPostSolve(b2Contact* contact, const b2ContactImpulse* impulse);

      voidEndContact(b2Contact* contact);

};

类定义:

#import "ContactListener.h"

#import "cocos2d.h"

#import "GameLayer.h"

 

void ContactListener::BeginContact(b2Contact*contact)

{

    b2Body* body =contact->GetFixtureA()->GetBody();

    NSNumber* userData =(NSNumber*)(body->GetUserData());

    if (userData == nil) {

        return;

    }

    int tag = [userDataintValue];

    if (tag == -1) {

        body= contact->GetFixtureB()->GetBody();

        userData= (NSNumber*)(body->GetUserData());

        if(userData == nil) {

            return;

        }

        tag= [userData intValue];

        if(tag == -2) {

            return;

        }

    }

   

    int lastScoredStep =[[GameLayer gameLayer] lastScoredStep];

    if (lastScoredStep == -1){

        [GameLayergameLayer].lastScoredStep = tag;

        return;

    } else if (lastScoredStep!= tag) {

        [GameLayergameLayer].lastScoredStep = tag;

        [[GameLayergameLayer] addScore];

    }

}

void ContactListener::PreSolve(b2Contact* contact,const b2Manifold* oldManifold){}

void ContactListener::PostSolve(b2Contact*contact, const b2ContactImpulse* impulse){}

void ContactListener::EndContact(b2Contact*contact){}

这里我们重写了BeginContact方法,当有刚体之间的碰撞发生时,我们通过判断两个刚体的类型来判断是否得分,刚体类型的判断就用的是我们前面的tag,注意这里我们做了判断,由于我们没有为墙体指定tag,所以当墙体的userData转换为NSNumber指针时为nil,这时候就没有必要再做判断了,并且我们为了防止重复记分,例如小球连续两次碰到当前Block(例如小球碰撞之后弹起又碰撞,或者遇到高矮台阶的那种Block),这时候就通过lastScoredStep来比较,lastScoredStep始终记录前一次得分的StepBlock。

最后我们来定义Ball类:

声明如下:

#import "CCNode.h"

#import "cocos2d.h"

#import "Box2D.h"

 

@interface Ball : CCNode{

    float screenWidth;

    float screenHeight;

    b2Body* body;

    CCSprite* shape;

}

 

+ (Ball*)ball;

 

- (void)reset;

- (void)pushLeft;

- (void)pushRight;

 

@end

定义:

#import "Ball.h"

#import "cocos2d.h"

#import "GB2ShapeCache.h"

#import "TagDefinitions.h"

#import "GameLayer.h"

 

@implementation Ball

 

+ (Ball*)ball{

    return [[[Ball alloc]init] autorelease];

}

 

- (id)init{

    if (self = [super init]) {

        //screendimensions

        CGSizescreenSize = [[CCDirector sharedDirector] winSize];

        screenHeight= screenSize.height;

        screenWidth= screenSize.width;

       

        shape= [CCPhysicsSprite spriteWithFile:@"ball.png"];

        shape.anchorPoint= ccp(0.5f, 0.5f);

        CGPointposition = ccp(screenWidth*0.5f, screenHeight*0.5f+50);

        b2BodyDefbodyDef;

        bodyDef.type= b2_dynamicBody;

        bodyDef.userData= [NSNumber numberWithInteger:-1];

        bodyDef.position.Set(position.x/PTM_RATIO,position.y/PTM_RATIO);

        body= [[GameLayer gameLayer] sharedWorld]->CreateBody(&bodyDef);

        [[GB2ShapeCachesharedShapeCache] addFixturesToBody:body forShapeName:@"ball"];

        [shapesetPTMRatio:PTM_RATIO];

        [shapesetB2Body:body];

        [shapesetPosition:position];

       

        [selfaddChild:shape];

    }

   

    return self;

}

 

- (void)pushLeft{

    b2Vec2 force;

    force.Set(-4.0f, 0);

    body->ApplyForceToCenter(force);

}

 

- (void)pushRight{

    b2Vec2 force;

    force.Set(4.0f, 0);

    body->ApplyForceToCenter(force);

}

 

- (void)reset{

    CGPoint position =ccp(screenWidth*0.5f, screenHeight*0.5f+50);

    b2Vec2 pos;

    pos.Set(position.x/PTM_RATIO,position.y/PTM_RATIO);

    body->SetTransform(pos,0);

    [shapesetPosition:position];

}

 

- (CGPoint)position{

    return shape.position;

}

 

@end

小球的图片素材:


小球类比较简单,通过ApplyForceToCenter来对小球施力即可。

这样我们的游戏就基本制作完成了,限于篇幅,我们没有列出各个类的dealloc方法,请读者补充完成,释放资源。此外,还可以添加一些音效,添加开始界面和GameOver界面等等。

 

教程就到这里,如果有问题,欢迎留言~



http://www.niftyadmin.cn/n/878363.html

相关文章

mysql5.7.17x64位_mysql5.7.17在win2008R2的64位系统安装与配置实例

易采站长站已经给大家讲解过MYSQL其他版本在各种环境中的安装过程,大家可以参阅正文下面的相关文章,今天一起来学习下mysql5.7.17的实例安装教学,配置上稍微不同,希望能够帮助到你。安装MySql操作系统:Windows Server …

手把手教你使用PhysicsEditor来辅助制作Box2D刚体

本篇教程需要读者对Box2D有了一些基本了解,如果过程中有什么概念不清楚,请参考Box2Dv2.3.0 用户指南中的相关章节进行学习。 我们知道,在利用Box2D引擎开发游戏的时候,对于规则的物体(刚体&a…

wcf mysql_WCF+EF+mysql发布到IIS7上

1.创建一个 【WCF服务应用程序】。2.增加内部类库的引用&#xff0c;EntityFramework (Version 6.2)。MySql.Data, MySql.Data.Entity.EF6 (Version 6.9.9)3.配置Web.config1 <?xml version"1.0" encoding"utf-8"?>2 3 4 5 6 7 8 9 10 11 12 13…

Box2D v2.3.0 用户指南(第一章)

&#xfeff;&#xfeff;原著&#xff1a;2007-2013 Erin Catto 翻译&#xff1a;远行的风 关注我的博客&#xff1a;http://blog.csdn.net/qwertyupoiuytr 网上已经有很多版本的Box2D用户手册了&#xff0c;这里我们翻译的是最新的2.3.0这个版本的手册&#xff0c;也是为了…

Box2D v2.3.0 用户指南(第二章)

&#xfeff;&#xfeff;第二章 HelloBox2D 在Box2D中包含一个HelloWorld项目。程序创建了一个大的地面盒子&#xff08;ground box&#xff09;和一个小的动态盒子。工程代码中没有包含任何图形&#xff0c;你仅能在文字输出控制台中看到随时间更新的盒子位置。 从如何搭建…

Box2D v2.3.0 用户指南(第三章)

&#xfeff;&#xfeff;第三章 公共模块&#xff08;Common&#xff09; 3.1简介 公共模块包含设置&#xff08;settings&#xff09;&#xff0c;内存管理&#xff08;memorymanagement&#xff09;&#xff0c;矢量计算&#xff08;vector math&#xff09;。 3.2设置 头…

Box2D v2.3.0 用户指南(第四章)

&#xfeff;&#xfeff;第四章 碰撞模块&#xff08;Collision Module&#xff09; 4.1简介 碰撞模块包含形状&#xff08;shape&#xff09;以及操作它们的函数。此外&#xff0c;碰撞模块还包括dynamictree和broad-phase来加快大型系统的碰撞处理速度。 碰撞模块被设计为…

a星 rvo_大型集群战斗寻路AI初探

最近调研SLG2.0的战斗原型(即大兵团会战)中的AI寻路模块&#xff0c;经过一周左右的资料阅读与代码学习&#xff0c;大概有了一些心得体会&#xff0c;这里简单写一下。我们说的这种大兵团战斗寻路一般分两块&#xff0c;一块叫大寻路&#xff0c;一块叫小寻路。大寻路就是战斗…