《一个都不能死》 游戏开发 (物理引擎)_wu745187355的博客-程序员宅基地

技术标签: cocos2d-x  

《一个都不能死》 游戏开发 (物理引擎)

//创建物理场景
auto scene = Scene::createWithPhysics();
//设置重力
scene->getPhysicsWorld()->setGravity(Vec2(0,-1000));

Scene* HelloWorld::createScene()
{
    // 'scene' is an autorelease object
    //auto scene = Scene::create();
    auto scene = Scene::createWithPhysics();
    //scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
    scene->getPhysicsWorld()->setGravity(Vec2(0,-1000));

    // 'layer' is an autorelease object
    auto layer = HelloWorld::create();

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    //////////
    // 1. super init first
    if (!LayerColor::initWithColor(Color4B(255, 255, 255, 255)))
    {
        return false;
    }

    Size visibleSize = Director::getInstance()->getVisibleSize();

    //gcs.pushBack(GameController::create(this, 30));
    gcs.insert(0, GameController::create(this, 30));
    //gcs.insert(0, GameController::create(this, 250));

    scheduleUpdate();

    //创建碰撞检测监听
    auto listener = EventListenerPhysicsContact::create();
    listener->onContactBegin = [this](PhysicsContact &contact){
        this->unscheduleUpdate();

        Director::getInstance()->replaceScene(GameOver::createScene());

        return true;

    };

    Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);

    //添加点击监听
    auto touchListener = EventListenerTouchOneByOne::create();
    touchListener->onTouchBegan = [this](Touch * t, Event *e){

        for (auto it = gcs.begin(); it != gcs.end(); it++){
            if ((*it)->hitTestPoint(t->getLocation())){
                (*it)->onUserTouch();
                break;
            }
        }
        return false;
    };
    Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(touchListener, this);



    return true;
}
void HelloWorld::update(float dt)
{
    for (auto it = gcs.begin(); it != gcs.end(); it++)
    {
        (*it)->onUpdate(dt);
    }
}

创建一个物理世界边缘(一般是窗口大小),

class Edge:public Node{
public:
    virtual bool init();
    CREATE_FUNC(Edge);
};

bool Edge::init(){
    Node::init();

    Size visibleSize = Director::getInstance()->getVisibleSize();
    //创建一个物理世界边缘
    setPhysicsBody(PhysicsBody::createEdgeBox(visibleSize));

    setContentSize(visibleSize);
    return true;
}

创建人物(刚体)

class Hero :public Sprite{
public:
    virtual bool init();
    CREATE_FUNC(Hero);

};

bool Hero::init(){
    Sprite::init();

    Size s = Size(44, 52);

    runAction(RepeatForever::create(FlashTool::readJsonSpriteSheet("Hero.json", 0.2f)));

    setPhysicsBody(PhysicsBody::createBox(s));
    setContentSize(s);

    //被撞击后不旋转
    getPhysicsBody()->setRotationEnable(false);
    //开启碰撞检测
    getPhysicsBody()->setContactTestBitmask(1);
    //getPhysicsBody()->setCategoryBitmask(1);

    //getPhysicsBody()->setCollisionBitmask(1);


    return true;
}

创建阻挡物

class Block :public Sprite{
public:
    virtual bool init();

    //实现向左移动  超出后删除
    virtual void update(float dt);
    CREATE_FUNC(Block);


};


bool Block::init(){
    Sprite::init();

    Size s = Size((rand() % 20) + 5, (rand()%30) + 10);

    Size visibleSize = Director::getInstance()->getVisibleSize();

    setPhysicsBody(PhysicsBody::createBox(s));
    setTextureRect(Rect(0, 0, s.width, s.height));
    setColor(Color3B(0,0,0));
    setContentSize(s);

    setPositionX(visibleSize.width);
    scheduleUpdate();

    //设置静态,不会因为人物卡住 持续运动
    getPhysicsBody()->setDynamic(false);
    //设置碰撞检测
    getPhysicsBody()->setContactTestBitmask(1);

    return true;
}

void Block::update(float dt)
{
    this->setPositionX(getPositionX() - 3);
    if (getPositionX() < 0){    
        unscheduleUpdate();
        removeFromParent();
    }
}

//创建控制器

class GameController :public Ref{
private:
    Layer *_layer;
    float _positionY;
    Size visibleSize;
    int currentFrameIndex;
    int nextFrameCount;
    Edge *edge;
    Hero *hero;

private:
    void resetFrames();
    void addBlock();
public:
    virtual bool init(Layer *layer,float positionY);
    //每过一段时间添加一个障碍物
    void onUpdate(float dt);
    //是否包含点  用于判断用户点击的位置是否在edgebody中 
    bool hitTestPoint(Vec2 point);
    //用户点击后给英雄一个向上的冲力。
    void onUserTouch();

    static GameController * create(Layer *layer, float position);
};



GameController * GameController::create(Layer *layer, float position)
{
    auto _ins = new GameController();
    _ins->init(layer, position);
    _ins->autorelease();

    return _ins;

}

bool GameController::init(Layer *layer, float positionY)
{
    _layer = layer;
    _positionY = positionY;

    visibleSize = Director::getInstance()->getVisibleSize();

    //add edge
    edge = Edge::create();
    edge->setPosition(visibleSize.width / 2, visibleSize.height / 2 + positionY);
    edge->setContentSize(visibleSize);
    layer->addChild(edge);

    //add ground
    auto ground = Sprite::create();
    ground->setColor(Color3B(0, 0, 0));
    ground->setTextureRect(Rect(0, 0, visibleSize.width, 3));
    ground->setPosition(visibleSize.width/2, 1.5 + positionY);
    layer->addChild(ground);
    //add hero
    hero = Hero::create();
    hero->setPosition(50, hero->getContentSize().height/2 + positionY);
    layer->addChild(hero);

    resetFrames();
    return true;
}

void GameController::resetFrames()
{
    currentFrameIndex = 0;
    nextFrameCount = (rand() % 120) + 100;
}

void GameController::addBlock()
{
    auto b = Block::create();
    _layer->addChild(b);
    b->setPositionY(b->getContentSize().height / 2 + _positionY);


}
void GameController::onUpdate(float dt)
{
    currentFrameIndex++;
    if (currentFrameIndex >= nextFrameCount){
        resetFrames();
        addBlock();
    }
}

bool GameController::hitTestPoint(Vec2 point)
{
    return edge->getBoundingBox().containsPoint(point);
}

void GameController::onUserTouch()
{
    hero->getPhysicsBody()->setVelocity(Vec2(0, 400));
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/wu745187355/article/details/45047037

智能推荐

学PYTHON笔记_I3E4zm的博客-程序员宅基地

1.a//b     意思是a整除b2.叠边形import turtleturtle.setup(500,500)turtle.pensize(5)for i in range(9):     turtle.fd(100)    turtle.right(80)“天天向上的力量”第三问#DayDayUpQ3.pydayup=1.0dayfactor=0.01for i in range(365):...

python中文件最重要的功能是什么和接收数据_python面试题_weixin_39602108的博客-程序员宅基地

正文Python基础篇1:为什么学习Python家里有在这个IT圈子里面,也想让我接触这个圈子,然后给我建议学的Python,然后自己通过百度和向有学过Python的同学了解了Python,Python这门语言,入门比较简单,它简单易学,生态圈比较强大,涉及的地方比较多,特别是在人工智能,和数据分析这方面。在未来我觉得是往自动化,人工智能这方面发展的,所以学习了Python2:通过什么途径学习Py...

串口、COM口、TTL、RS-232的区别详解_You_Never_Come_Here的博客-程序员宅基地

1、串口、COM口是指的物理接口形式(硬件)。而TTL、RS-232、RS-485是指的电平标准(电信号)。  2、接设备的时候,一般只接GND RX TX。不会接Vcc或者+3.3v的电源线,避免与目标设备上的供电冲突。  3、PL2303、CP2102芯片是 USB 转 TTL串口 的芯片,用USB来扩展串口(TTL电平)。  4、MAX232芯片是 TTL电平与RS2

《Unity3D网络游戏实战》第2章_yxqq378287007的博客-程序员宅基地

《Unity3D网络游戏实战》第2章异步代码异步客户端异步代码Async.csusing System;using System.Threading;namespace Async { class MainClass { public static void Main (string[] args) { Timer timer = new Timer(Timeout, null, 2000, 0); Thread.Sleep(2000*2); Console.WriteL

安装系统_iefanrui的博客-程序员宅基地

第一步、准备工作    安装系统前要做一些准备工作,首先是制作你要安装的系统的系统镜像。制作系统镜像要先下载一个UltraISO软件。然后右键点击选择“以管理员的身份运行”(注意:必须这样做)。打开后点击左上角的“文件”-—“打开”,找到存放系统镜像的目录,选中系统镜像,然后点击“打开”。然后点击 “启动”—“开始硬盘录入”,然后选择一个U盘作为系统启动盘(注意:这个U盘必须足够大,一般16G的就...

随便推点

MT6752 LTE这个器件是什么型号?_szx940213的博客-程序员宅基地

MT6752 LTE这个器件是什么型号?这原理图上也没有写明确。问题来源:一牛网论坛 答案链接:MT6572

阿里云轻量级服务器CentOS7.3系统连接问题(Putty,Xshell)_贾继康的博客-程序员宅基地

文章目录阿里云轻量级服务器CentOS7.3系统连接问题(Putty,Xshell)一、前言二、准备工作三、为何不能使用密码连接?四、解决之道五、相关链接:五、Xshell5相关设置阿里云轻量级服务器CentOS7.3系统连接问题(Putty,Xshell)一、前言&nbsp; &nbsp;&nbsp; &nbsp; 博主之前通过密钥的方式实现了与Putty的连接(可参考此链接如何连接),...

苹果iPhone如何区分港版、国行、水货_weixin_33777877的博客-程序员宅基地

要想分辨所购买的苹果产品[iPhone 4、iPod Touch、iPad 2、iMac、MacBook及iPhone 4S]是大陆行货、水货、港货还是其它,其实很简单。今天来教大家如何区分。大陆行货、水货、港货还是其它XX货,其实就是它们的发行地不同,功能都是一样的。首先,要让大家了解,何谓为发行地的不同。发行地是说苹果产品所发行的国家或地区的不同,ZP为在香港发行的,LL为在美国发行的,CH为...

SD省队集训2019Day8之“有没有空”_weixin_30917213的博客-程序员宅基地

有没有空(busy)([Ynoi2018]天降之物)给你一个长为 n 的序列 a你需要实现 m 个操作,操作有两种:1.把序列中所有值为 x 的数的值变成 y2.找出一个位置 i 满足 ai==x,找出一个位置 j 满足 aj==y,使得|i-j|最小,并输出|i-j|部分分:二分考虑把整个区间分成两部分,那么这两个数要么都在左边,要么都在右边,要么一左一右。前两种情况可以递归解决,同...

关于PAT配置_赵文超z的博客-程序员宅基地

PAT配置 问题 在R1通过PAT配置实现企业内网192.168.0.0/24复用f0/1端口 方案网络拓扑如图-3所示:图-3 步骤实现此案例需要按照如下步骤进行。步骤一:基于端口的PAT配置限制1)删除动态NAT配置tarena-R1(config)#no ip nat inside source list 1tarena-R1(config)#no ip n...