cocos2dx实例开发之飞机大战

2023-05-16

曾经,微信里面可以玩一个打飞机的小游戏,很有趣,后来又没有了,这里基于原版素材写了一个高仿微信打飞机的小游戏

预览

在这里插入图片描述

工程结构

环境

  • Mac os Mojave
  • xcode 7.0
  • cocos2dx 3.17

代码目录
在这里插入图片描述

游戏架构
在这里插入图片描述
主要包括以下场景

  • 主菜单
  • 游戏(天空、玩家、敌机、子弹、道具)

步骤

菜单场景

游戏主菜单界面,进入游戏的入口界面

bool MainMenuScene::init()
{
    //
    // 1. super init first
    if ( !Scene::init() )
    {
        return false;
    }

    auto visible_size = Director::getInstance()->getVisibleSize();
    auto visible_origin = Director::getInstance()->getVisibleOrigin();

	// 添加背景图
    Sprite* background = Sprite::create("img/background.png");
    background->setContentSize(visible_size);
    background->setPosition(visible_origin.x + visible_size.width / 2,
                            visible_origin.y + visible_size.height / 2);
    addChild(background);
    
    Sprite* title = Sprite::create("img/title.png");
    title->setScale(1.5); // 尺寸适当调整
    title->setPosition(visible_origin.x + visible_size.width / 2,
                            visible_origin.y + visible_size.height / 2 + 40);
    addChild(title);

    // 添加按钮
    Button* start_btn = Button::create("img/game_resume_nor.png", "img/game_resume_pressed.png", "img/game_resume_nor.png"); // 指定好各种状态图的按钮
    start_btn->setScale(1.5); // 尺寸适当调整
    start_btn->setPosition(Vec2(visible_origin.x + visible_size.width / 2,
                                visible_origin.y + visible_size.height / 2));
    start_btn->addTouchEventListener([&](Ref* sender, Widget::TouchEventType type){
        // 按钮点击事件
        switch (type)
        {
            case ui::Widget::TouchEventType::BEGAN:
                // 播放音效
                SimpleAudioEngine::getInstance()->playEffect("sound/button.wav");
                break;
            case ui::Widget::TouchEventType::ENDED:
            {
                // 切换到主游戏场景
                auto game_scene = GameScene::createScene();
                TransitionScene* transition_scene = TransitionFade::create(0.5, game_scene);
                Director::getInstance()->replaceScene(transition_scene);
            }
                break;
            default:
                break;
        }
    });
    addChild(start_btn);
    
    return true;
}

游戏场景

游戏场景就是主要的游戏逻辑,控制玩家飞机发射子弹攻击敌机,拾取道具等

数据结构

在场景中,玩家、敌机、子弹、道具、天空背景都是不同的对象,分别具有不同的行为

玩家

class Player : public cocos2d::Sprite
{
public:
    virtual bool init();
    
    CREATE_FUNC(Player);
    
public:
    Bullet* shootSingle(); // 射击一次,产生一颗子弹
    cocos2d::Vector<Bullet*> shootDouble(); // 射击一次,产生双子弹
    void fetchWeapon(WeaponType weapon_type); // 拾取道具
    void destroy(); // 玩家over
    
    BulletType m_bullet_type; // 根据子弹类型改变子弹
};
  • 射击(不同子弹类型)
  • 拾取道具
  • 被摧毁

子弹

enum BulletType
{
    BASE, // 单子弹
    POWER // 双子单
};

class Bullet : public cocos2d::Sprite
{
public:
    virtual bool init();
    void initWithType(BulletType bullet_type); // 根据子弹类型设置纹理
    CREATE_FUNC(Bullet);
    void pauseMove();
    void resumeMove();
    
public:
    int m_kill_hp; // 子弹的杀伤力
    bool m_hit_flag; // 标记子弹是否已击中
    
private:
    void move(float tm);
    float m_speed;
};
  • 不同类型
  • 子弹飞行
  • 不同的速度
  • 不同的杀伤力

敌机

enum EnemyType
{
    SMALL,  // 小飞机
    MEDIUM, // 中等飞机
    BIG     // 大飞船
};

class Enemy : public cocos2d::Sprite
{
public:
    virtual bool init();
    
    CREATE_FUNC(Enemy);
    void pauseMove();
    void resumeMove();
    
    void initWithType(EnemyType enemy_type);
    void move(float tm);
    void hit(int reduce_hp); // 敌机被子弹打中
    void die(); // 敌机死亡
    
    int m_hp; // 敌机总血量
	EnemyType m_type;
    
private:
    float m_speed;
};
  • 不同类型
  • 敌机飞行
  • 不同的速度
  • 被子弹击中
  • 不同的生命值
  • 减生命值
  • 被摧毁

道具

enum WeaponType
{
    AMMO,
    BOMB
};

class Weapon : public cocos2d::Sprite
{
public:
    virtual bool init();
    
    CREATE_FUNC(Weapon);
    void initWithType(WeaponType weapon_type);
    void pauseMove();
    void resumeMove();
    
    WeaponType m_type;
    
private:
    void move(float tm);
};
  • 不同类型
  • 道具飞行

背景滚动

天空背景实际上只有一张图,构造两张图循环移动,产生天空无限移动的效果

  • 定时器调度移动
  • 在关键位置两张图位移重置
bool SkyBackground::init()
{
    if (!Node::init())
        return false;
    
    Size visible_size = Director::getInstance()->getVisibleSize();
    Point visible_origin = Director::getInstance()->getVisibleOrigin();
    
    // 增加两张背景图,循环交替,构造连续滚动效果
    m_background1 = Sprite::create("img/background.png");
    m_background1->setContentSize(visible_size); // 与屏幕适应
    m_background1->setAnchorPoint(Point::ZERO); // 锚点设为左下坐标点,方便计算
    m_background1->setPosition(visible_origin); // 一定要设置初始位置
    addChild(m_background1);
    m_background2 = Sprite::create("img/background.png");
    m_background2->setContentSize(visible_size);
    m_background2->setAnchorPoint(Point::ZERO);
    m_background2->setPosition(visible_origin.x, visible_origin.y + visible_size.height);
    addChild(m_background2);
    
    // 调度两张图的移动
    schedule(schedule_selector(SkyBackground::backgroundRotate), kFrameUpdateInterval); // delta time smaller, move more smooth
    
    return true;
}

void SkyBackground::backgroundRotate(float tm)
{
    Size visible_size = Director::getInstance()->getVisibleSize();
    Point visible_origin = Director::getInstance()->getVisibleOrigin();
    
    // 背景2在背景1上方无缝衔接,当背景2到达底部时候,将背景1重新归位
    m_background1->setPositionY(m_background1->getPositionY() - 0.3); // rotate speed
    m_background2->setPositionY(m_background1->getPositionY() + visible_size.height);
    if (m_background2->getPositionY() <= visible_origin.y)
        m_background1->setPositionY(visible_origin.y);
}

玩家控制

玩家飞机根据触摸移动进行相应的移动

  • 伴随动画
  • 跟随触摸位置
  • 产生射击子弹
bool GameScene::onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *event)
{
    if (m_is_over)
        return true;
    
    CCLOG("onTouchBegan");
    m_pretouch_pos = touch->getLocation();
    m_preplayer_pos = m_player->getPosition();
    
    return true;
}

void GameScene::onTouchMoved(cocos2d::Touch *touch, cocos2d::Event *event)
{
    if (m_is_over)
        return;
    CCLOG("onTouchMoved");
    Point current_touch_pos = touch->getLocation();
    Vec2 move_delta = current_touch_pos - m_pretouch_pos;
    m_player->setPosition(m_preplayer_pos + move_delta);
}

void GameScene::onTouchEnded(cocos2d::Touch *touch, cocos2d::Event *event)
{
    if (m_is_over)
        return;
    
    CCLOG("onTouchEnded");
    m_pretouch_pos = kInitPoint;
}
Bullet* Player::shootSingle()
{
    // 发射子弹音效
    SimpleAudioEngine::getInstance()->playEffect("sound/bullet.wav");
    
    // 子弹从飞机头部打出来
    Bullet* bullet = Bullet::create();
    bullet->initWithType(BulletType::BASE);
    bullet->setPosition(getPositionX(), getPositionY() + getContentSize().height / 2);
    return bullet;
}

Vector<Bullet*> Player::shootDouble()
{
    // 发射子弹音效
    SimpleAudioEngine::getInstance()->playEffect("sound/bullet.wav");
    
    Vector<Bullet*> double_bullets;
    // 子弹都从飞机头部打出来,左右两个子弹分布在机头
    Bullet* bullet_left = Bullet::create();
    bullet_left->initWithType(BulletType::POWER);
    bullet_left->setPosition(getPositionX() - getContentSize().width / 4, getPositionY() + getContentSize().height / 2);
    double_bullets.pushBack(bullet_left);
    
    Bullet* bullet_right = Bullet::create();
    bullet_right->initWithType(BulletType::POWER);
    bullet_right->setPosition(getPositionX() + getContentSize().width / 4, getPositionY() + getContentSize().height / 2);
    double_bullets.pushBack(bullet_right);
    
    return double_bullets;
}

void Player::fetchWeapon(WeaponType weapon_type)
{
    // 如果道具是子弹,且之前是单子弹,切换子弹,并持续一段时间
    if (m_bullet_type == BulletType::BASE && weapon_type == WeaponType::AMMO)
    {
        m_bullet_type = BulletType::POWER;
        // 播放音效
        SimpleAudioEngine::getInstance()->playEffect("sound/get_double_laser.wav");
        
        // 子弹有效时间,用lambda做单次定时器回调
        scheduleOnce([&](float delay){
            m_bullet_type = BulletType::BASE;
            SimpleAudioEngine::getInstance()->playEffect("sound/out_porp.wav");
        }, kPowerTime, "power_status");
    }
    else if (weapon_type == WeaponType::BOMB)
    {
        // 播放音效
        SimpleAudioEngine::getInstance()->playEffect("sound/get_bomb");
        
        // TODO: 储存炸弹
    }
}

子弹生成

子弹是由场景通过定时器调度的,每次固定时间间隔根据当前玩家的子弹类型生成新的子弹

  • 子弹射出后就自动飞行
  • 子弹产生的位置都在玩家飞机头部
void GameScene::generateBullet(float interval)
{
    if (m_is_over)
        return;
    
    // 由定时器触发产生子弹,也可以由某个按键触发
    // 根据玩家子弹状态产生不同的子弹,加到场景和管理器
    if (m_player->m_bullet_type == BulletType::BASE)
    {
        Bullet* bullet = m_player->shootSingle();
        addChild(bullet, kBattleZorder);
        m_bullets.pushBack(bullet);
    }
    else if (m_player->m_bullet_type == BulletType::POWER)
    {
        Vector<Bullet*> double_bullets = m_player->shootDouble();
        for (Bullet* bullet : double_bullets)
        {
            addChild(bullet, kBattleZorder);
            m_bullets.pushBack(bullet);
        }
    }
}

敌机生成

敌机会随机从顶部生成出来,也是由定时器调度

  • 位置随机
  • 类型根据概率来,越厉害的飞机越少出现
  • 飞机出现后会飞行
  • 飞船有伴随动画
void GameScene::generateEnemy(float interval)
{
    if (m_is_over)
        return;
    
    Size visible_size = Director::getInstance()->getVisibleSize();
    Point visible_origin = Director::getInstance()->getVisibleOrigin();
    
    // 定时器触发产生道具,根据概率生成不同类型
    // 加载到场景和管理器
    EnemyType enemy_type;
    float random_factor = CCRANDOM_0_1();
    if (random_factor >= 0.9)
        enemy_type = EnemyType::BIG;
    else if (random_factor >= 0.6 && random_factor < 0.9)
        enemy_type = EnemyType::MEDIUM;
    else
        enemy_type = EnemyType::SMALL;

    Enemy* enemy = Enemy::create();
    enemy->initWithType(enemy_type);
    
    // 生成随机位置,但要保证敌机显示完整,所以左右各留出半个敌机身位
    float random_x = enemy->getContentSize().width / 2 +
                    (visible_size.width - enemy->getContentSize().width) * CCRANDOM_0_1();
    
    enemy->setPosition(visible_origin.x + random_x,
                       visible_origin.y + visible_size.height + enemy->getContentSize().height / 2);
    addChild(enemy, kBattleZorder);
    m_enemies.pushBack(enemy);
}

道具生成

道具有子弹和炸弹两种,由定时器调度

  • 道具出现位置随机
  • 道具类型根据概率来,炸弹概率较小
  • 道具出现后会飞行

碰撞检测

判断敌机是否死亡、道具拾取、玩家是否被摧毁都要做碰撞检测

  • 敌机碰撞到子弹后,先减生命值,生命值为则死亡
  • 道具拾取后,如果是子弹,则玩家射击的子弹专版为加强版,维持一段时间,如果是炸弹,则立即炸毁场景里所有存活的飞机
  • 玩家碰撞到任何敌机就被摧毁
  • 碰撞会有多种动画伴随
// --- 碰撞监测 ---
// 判断玩家
for (Enemy* enemy : m_enemies)
{
    if (enemy->m_hp > 0 && enemy->getBoundingBox().intersectsRect(m_player->getBoundingBox()))
    {
        // 玩家飞机撞了
        m_is_over = true;
        m_player->destroy();

// 游戏结束,处理后续(延迟等到玩家飞机t摧毁动画结束)
        scheduleOnce([&](float delay){
            gameOver();
        }, 2.0, "game over");

        return;
    }
}

// 判断敌机被子弹击中
Vector<Bullet*> hit_bullets;
for (Bullet* bullet : m_bullets)
{
    for (Enemy* enemy : m_enemies)
    {
        // 注意,某个子弹撞击了后要消失,并且不可再参与碰撞检测
        if (!bullet->m_hit_flag
            && enemy->m_hp > 0
            && bullet->getBoundingBox().intersectsRect(enemy->getBoundingBox()))
        {
            enemy->hit(bullet->m_kill_hp);
            if (enemy->m_hp <= 0)
            {
	// 先更新分数,再移除飞机
	getScore(enemy->m_type);

                enemy->die(); // 这里面做了对象销毁
                m_enemies.eraseObject(enemy); // 这里可以先于动画放完就移出管理器
            }
            
            // 移除子弹, 先标记起来放到移除列表
            bullet->m_hit_flag = true;
            hit_bullets.pushBack(bullet);
        }
    }
}
// 这里统一移除子弹,避免边判断边移除导致的内存问题
for (Bullet* bullet : hit_bullets)
{
    m_bullets.eraseObject(bullet);
    bullet->removeFromParent();
}
hit_bullets.clear();

// 判断拾取道具
for (Weapon* weapon : m_weapons)
{
    if (weapon->getBoundingBox().intersectsRect(m_player->getBoundingBox()))
    {
        if (weapon->m_type == WeaponType::AMMO)
            m_player->fetchWeapon(WeaponType::AMMO);
        else if (weapon->m_type == WeaponType::BOMB)
        {
            // 炸掉所有敌机
            SimpleAudioEngine::getInstance()->playEffect("sound/use_bomb.wav");
            CCLOG("before bomb enemy number = %d", m_enemies.size());
            for (Enemy* enemy : m_enemies)
            {
	// 先更新分数,再移除飞机
	getScore(enemy->m_type);

                enemy->m_hp = 0; // 先把血量置空
                enemy->die(); // 这里面做了对象销毁
            }
            m_enemies.clear(); // 一定要放在这里统一清空
            CCLOG("after bomb enemy number = %d", m_enemies.size());
        }
        
        // 道具本身也要消失
        m_weapons.eraseObject(weapon);
        weapon->removeFromParent();
    }
}

元素管理

场景里看不见的元素需要销毁做内存回收

  • 监测子弹、敌机、道具如果出了平面就销毁回收内存
  • 这种销毁不需要播放动画
// --- 元素管理 ---
for (Bullet* bullet : m_bullets)
{
    // 若飞行的子弹出了屏幕,则移除
    if (bullet->getPositionY() > visible_origin.y +
                                visible_size.height + bullet->getContentSize().height / 2)
    {
        m_bullets.eraseObject(bullet); // erase from vector should before itself cleanup
        bullet->removeFromParent();
    }
}
CCLOG("current bullets count: %d", m_bullets.size());

for (Enemy* enemy : m_enemies)
{
    // 若存活敌机出了平面,则移除
    if (enemy->getPositionY() < visible_origin.y - enemy->getContentSize().height / 2)
    {
        m_enemies.eraseObject(enemy);
        enemy->removeFromParent();
    }
}
CCLOG("alive enemy count: %d", m_enemies.size());

for (Weapon* weapon : m_weapons)
{
    // 若未拾取的道具出了屏幕,则移除
    if (weapon->getPositionY() < visible_origin.y - weapon->getContentSize().height / 2)
    {
        m_weapons.eraseObject(weapon);
        weapon->removeFromParent();
    }
}
CCLOG("unfetched weapon count: %d", m_weapons.size());

计分

在摧毁敌机或者炸掉敌机时都要更新游戏分数

  • 不同类型敌机得分不同
  • 获得里程碑分数会有成就音效
void GameScene::getScore(EnemyType enemy_type)
{
	// 根据不同敌机类别得不同分数
    static int phase = 0;
	switch (enemy_type)
	{
	case EnemyType::SMALL:
		m_score += kSmallPlaneScore;
		break;
	case EnemyType::MEDIUM:
		m_score += kMediumPlaneScore;
		break;
	case EnemyType::BIG:
		m_score += kBigPlaneScore;
		break;
	default:
		break;
	}

	// 如果分数达到一定阶段,播放成就音效
    int new_phase = m_score / kAchievementScoreUnit;
	if (new_phase > phase)
    {
        SimpleAudioEngine::getInstance()->playEffect("sound/achievement.wav");
        phase = new_phase;
    }

	// 刷新UI
    m_score_label->setString(__String::createWithFormat("score: %d", m_score)->_string);
//    m_score_label->setString(StringUtils::format("score: %d", m_score)); // the same
}

游戏状态管理

游戏结束、暂停、恢复

  • 游戏结束出现新画面
  • 游戏暂停和恢复要保证场景里所有元素同时动作
void GameScene::gameOver()
{
    CCLOG("player hit, game over");
    
    Size visible_size = Director::getInstance()->getVisibleSize();
    Point visible_origin = Director::getInstance()->getVisibleOrigin();
    
    // 停止背景音乐
    // FIXME: stop background music may cause crash
    if (SimpleAudioEngine::getInstance()->isBackgroundMusicPlaying())
        SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
    
    // 停止所有的调度器
    unschedule(schedule_selector(GameScene::generateEnemy));
    unschedule(schedule_selector(GameScene::generateWeapon));
    unschedule(schedule_selector(GameScene::generateBullet));
    
    // 添加结束画面
    Sprite* game_over_background = Sprite::create("img/gameover.png");
    game_over_background->setContentSize(visible_size);
    game_over_background->setAnchorPoint(Point::ZERO);
    game_over_background->setPosition(visible_origin);
    addChild(game_over_background, kGameoverZorder);
    
    Label* final_score_label = Label::createWithTTF(std::to_string(m_score), "fonts/Marker Felt.ttf", 14);
    final_score_label->setColor(Color3B::BLACK);
    final_score_label->setPosition(visible_origin.x + visible_size.width / 2,
                               visible_origin.y + visible_size.height / 2);
    addChild(final_score_label, kGameoverZorder);
    
    // 重新开始按钮
    Button* restart_btn = Button::create("img/restart.png"); // 只添加一张背景图按钮
    restart_btn->setScale(1.5);
    restart_btn->setPosition(Vec2(visible_origin.x + visible_size.width / 2,
                                  visible_origin.y + visible_size.height / 2 - 30));
    restart_btn->addTouchEventListener([&](Ref* sender, Widget::TouchEventType type){
        // 按钮点击事件
        switch (type)
        {
            case ui::Widget::TouchEventType::BEGAN:
                // 播放音效
                SimpleAudioEngine::getInstance()->playEffect("sound/button.wav");
                break;
            case ui::Widget::TouchEventType::ENDED:
            {
                // 重载主游戏场景
                auto game_scene = GameScene::createScene();
                TransitionScene* transition_scene = TransitionFade::create(0.5, game_scene);
                Director::getInstance()->replaceScene(transition_scene);
            }
                break;
            default:
                break;
        }
    });
    addChild(restart_btn, kGameoverZorder);
    
    // 结束游戏按钮
    Button* quit_btn = Button::create("img/quit.png"); // 只添加一张背景图按钮
    quit_btn->setScale(1.5);
    quit_btn->setPosition(Vec2(visible_origin.x + visible_size.width / 2,
                                  visible_origin.y + visible_size.height / 2 - 60));
    quit_btn->addTouchEventListener([&](Ref* sender, Widget::TouchEventType type){
        // 按钮点击事件
        switch (type)
        {
            case ui::Widget::TouchEventType::BEGAN:
                // 播放音效
                SimpleAudioEngine::getInstance()->playEffect("sound/button.wav");
                break;
            case ui::Widget::TouchEventType::ENDED:
            {
                // 返回到菜单场景
                auto main_menu_scene = MainMenuScene::createScene();
                TransitionScene* transition_scene = TransitionFade::create(0.5, main_menu_scene);
                Director::getInstance()->replaceScene(main_menu_scene);
            }
                break;
            default:
                break;
        }
    });
    addChild(quit_btn, kGameoverZorder);
}

void GameScene::gamePause()
{
    // 暂停背景音乐
    SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
    
    // 暂停游戏标志
    m_is_pause = true;
    
    // 暂停所有调度器
    unschedule(schedule_selector(GameScene::generateEnemy));
    unschedule(schedule_selector(GameScene::generateWeapon));
    unschedule(schedule_selector(GameScene::generateBullet));
    
    // 暂停所有的元素移动
    m_sky_background->pauseRotate();
    for (Enemy* enemy : m_enemies)
        enemy->pauseMove();
    for (Bullet* bullet : m_bullets)
        bullet->pauseMove();
    for (Weapon* weapon : m_weapons)
        weapon->pauseMove();
}

void GameScene::gameResume()
{
    // 恢复背景音乐
    SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
    
    // 恢复游戏标志
    m_is_pause = false;
    
    // 恢复所有调度器
    schedule(schedule_selector(GameScene::generateEnemy), kEnemyGenerateInterval);
    schedule(schedule_selector(GameScene::generateWeapon), kWeaponGenerateInterval);
    schedule(schedule_selector(GameScene::generateBullet), kBulletGenerateInterval);
    
    // 恢复所有的元素移动
    m_sky_background->resumeRotate();
    for (Enemy* enemy : m_enemies)
        enemy->resumeMove();
    for (Bullet* bullet : m_bullets)
        bullet->resumeMove();
    for (Weapon* weapon : m_weapons)
        weapon->resumeMove();
}

效果图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码

csdn:飞机大战
github:飞机大战

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

cocos2dx实例开发之飞机大战 的相关文章

  • 4_竞赛无人机基本自动飞行支持函数与导航控制函数解析——零基础学习竞赛无人机搭积木式编程

    竞赛无人机基本自动飞行支持函数与导航控制函数解析 基本自动飞行支持函数 void basic auto flight support void 根据前面几讲的介绍 xff0c 要想实现无人机的自动飞行 xff0c 单依靠姿态自稳 高度控制远
  • Ubuntu20.04/Ubuntu22.04 配置VScode+Opencv+cmake(C++)

    下面介绍Ubuntu20 04下安装opencv xff0c 当然Ubuntu22 04也适用 xff0c 然后将opencv链接到VsCode 先主体按照 gt 点我 xff1a 链接1 lt 的第一点进行安装 xff0c 但是特别注意
  • makefile和cmake

    目录 作用优点cmake 作用 makefile关系到了整个工程的编译规则 一个工程中的源文件不计其数 xff0c 其按类型 功能 模块分别放在若干个目录中 xff0c makefile定义了一系列的规则来指定 xff0c 哪些文件需要先编
  • Linux查看线程的堆栈信息

    1 使用top命令 xff0c 查找pid 2 显示线程 xff0c 查找线程tid ps mp pid o THREAD tid time sort rn 3 将线程id转化为16进制0xtid printf 34 x n 34 tid
  • MPU6050 简介

    目录 关于MPU6050芯片 关于小板 关于厂家和DATASHEET 关于漂移 关于角加速度还是角速度 关于精度和量程 xff08 可调 xff0c 可选 xff09 关于功耗 xff0c 陀螺仪 43 加速器工作电流 xff1a 3 8m
  • 银河麒麟V10操作系统安装putty和cutecom和网络调试助手(mNetAssist)

    银河麒麟V10操作系统安装putty和cutecom和网络调试助手 xff08 mNetAssist xff09 安装Putty 需要连接网络 sudo apt get install putty 安装Cutecom 需要连接网络 sudo
  • STM32串口中断接收和中断发送

    STM32串口USART1中断接收和中断发送 先贴出中断函数 void USART1 IRQHandler void if USART GetITStatus USART1 USART IT RXNE 61 RESET USART Clea
  • ICP(Iterative Closest Point迭代最近点)算法学习笔记

    背景 xff1a 博主从百度百科开始学习icp算法 xff0c 主要是后期加得学习笔记 xff08 红色部分 xff09 ICP算法 xff1a 以点集对点集 xff08 PSTPS xff09 配准方法为基础 xff0c 他们阐述了一种曲
  • linux设备上的Onvif 实现21:解决大华摄像头无法使用问题

    好长时间没有再写该系列文章了 xff0c 最近刚好摸索着解决了大华摄像头无法使用问题 xff0c 记录下来 xff0c 应该对其他博友有所帮助 之前虽然写了一大堆文章说明了如何使用gsoap连接摄像头 xff0c 但这是针对一台海康的摄像头
  • NRF24L01工作原理(发送接收通道地址)解读 图示

    NRF24L01工作原理 xff08 发送接收通道地址 xff09 解读 图示 NRF24l01工作原理 xff08 发送接收通道地址 xff09 网上说明不清晰 xff0c 特制作本说明 xff0c xff08 制作 xff1a 流浪的蛙
  • Realsense D435i 使用

    工作之后才发现问题不是单线程地来找你 xff0c 而是多线程并发地涌向你 D435i是一款良心传感器 xff0c 美中不足的是你拿不到广角图像 虽然现在不负责传感器测试了 xff08 老大布置什么 xff0c 打工的就去做什么就好了 xff
  • Kalibr标定d435i

    figure it out 最近准备使用realsense d435i xff0c 先对其进行标定 整体环境是基于ROS的 xff0c 因为Kalibr是在ROS环境下 大致过程如下 xff1a imu标定 gt 双目标定 gt 双目 43
  • cout函数未定义问题和函数隐形类型转换

    cout函数未定义的一些问题 xff1a 看上面的图片 xff0c 有个朋友说 xff0c 按照上面using和修改了iostream为什么还是显示未定呢 xff1f 到底怎么办呢 xff1f 解决 xff1a include lt ios
  • C++ primer plus

    https github com lilinxiong cppPrimerPlus six https github com lilinxiong cppPrimerPlus six 最近在看C 43 43 primer plus这本书 x
  • ROS编译过程中的错误

    一 catkin make编译错误 xff08 1 xff09 Could not find a package configuration file provided by 34 gazebo ros control 34 with an
  • 算法导论学习笔记-2

    第二章 xff1a 函数的增长 2 1渐近记号 记号 定义 xff1a g n 61 f n 存在正常数c1 c2和n0 xff0c 使对所有n n0 xff0c 有0 c1 g n f n c2 g n xff1b 满足该定义 xff0c
  • C++理论复习之运算符重载

    C 43 43 运算符重载 重载操作符的一般格式 xff1a Type operator 43 Type A Type B 可重载与不可重载的操作符列表 操作符重载的注意事项 重载操作符必须有一个类类型的操作数 xff0c 不能重载内置类型
  • 计算机网络概述

    OSI参考模型 国际标准化组织 I S O 开发了开放式系统互联 O S I 参考模型 xff0c 以促进计算机系统的开放互联 开放式互联就是可在多个厂家的环境中支持互联 很少有产品是完全的O S I 模式 xff1b 相反 xff0c 其
  • PCL:如何自定义一个点云PointT类型

    1 xff0c 使用基础点云类型 include 34 pcl point types h 34 include 34 pcl impl instantiate hpp 34 include 34 foo h 34 include 34 i
  • IP地址

    ip地址的分类 A类地址 设计IPv4 A类地址的目的是支持巨型网络 xff0c 因为对规模巨大网络的需求很小 xff0c 因此开发了这种结构使主机地址数很大 xff0c 而严格限制可被定义为A类网络的数量 一个A类I P地址仅使用第一个8

随机推荐

  • 数据存储大端小端模式的理解

    Big Endian和Little Endian的定义如下 xff1a 1 Little Endian就是低位字节排放在内存的低地址端 xff0c 高位字节排放在内存的高地址端 2 Big Endian 就是高位字节排放在内存的低地址端 x
  • cocos2dx实例开发之经典坦克

    小时候红白机上玩的的经典90坦克 xff0c 看起来简单 xff0c 做起来其实有点复杂 xff0c 这里用原版素材还原了一个简版 预览 工程结构 游戏架构 包括场景 xff1a 欢迎界面 xff0c 主菜单游戏场景 步骤 菜单场景 对于图
  • 数值分析C++:统计(均值/方差/偏度/峰度),积分,微分,蒙特卡罗

    用C 43 43 实现几个简单的数值分析计算 xff0c 以便深入理解计算机在求解代数问题的过程 原理 以下主要针对普通实数 xff0c 以及一元代数 统计 算数平均值 几何平均值 方差 偏度 峰度 积分 求解定积分的一般数学描述式 但是由
  • python脚本编程:监控指定进程的cpu和内存使用率

    为了测试某个服务的稳定性 xff0c 通常需要在服务长时间运行的情况下 xff0c 监控其资源消耗情况 xff0c 比如cpu和内存使用 这里借助python的psutil这个包可以很方便的监控指定进程号 xff08 PID xff09 的
  • python脚本编程:实时监控日志文件

    用python可以很小巧轻便的实时监控日志文件增量刷新 xff0c 根据某些关键字进行匹配 xff0c 方便做运维异常告警 代码 span class token keyword import span time span class to
  • C++获取机器启动至今的时长和机器启动的时间戳

    根据当前时间戳与机器启动至今的时间长度相减 xff0c 可以精确计算出机器启动时刻的时间戳epochtime 代码 span class token macro property span class token directive key
  • pytorch基于RNN实现文本情感分析并用C++加载模型预测

    文本情感分析是机器学习自然语言处理NLP中常见的应用场景 xff0c 给定一段文本 xff0c 识别其中的情绪或态度 xff0c 对其进行分类并标签化 这个手段可以应用于书籍电影评价 用户对产品满意度调查 人机对话感情色彩提取和金融研报分析
  • pytorch使用matplotlib和tensorboard实现模型和训练的可视化

    pytorch构建和训练深度学习模型的过程中 xff0c 往往需要能够直观的观测到可视化的过程 xff0c 比如画出训练曲线等 对于简单的曲线绘制可以使用matplotlib库做出基本的图 xff0c 如果需要更加高级的可视化过程 xff0
  • Eigen库:常见错误(最坑的库,没有之一)

    1 3rdparty eigen eigen3 eigen src core assignevaluator h 833 error C2338 YOU MIXED MATRICES OF DIFFERENT SIZES Eigen Mat
  • win10 资源管理器打开FTP站点跳到IE

    原文链接 xff1a https zhidao baidu com question 549827901 html 我也遇到一样的问题 xff0c 参考很多网页 xff0c 最好终于解决了 xff0c 我不能保证一定解决你的问题 xff0c
  • C++11写的一个简洁的单例类型模版包装器

    单例是经常用到的设计模式实践 xff0c 对于全局使用的唯一资源事例一般都把类型封装成单例 xff0c 但是有时候觉得对于每个class都要改造一遍单例会觉得比较繁琐 xff0c 尤其是在预先不知道哪些类型会使用为单例的时候 为了应对这种情
  • C++获取对应进程的cpu和内存使用情况(支持linux和windows)

    运维监控程序中经常需要根据一个进程号pid去监控实时的cpu和内存占用 xff0c 以下整理了一个C 43 43 实现的简单例子 xff0c 并封装为方便跨平台调用的函数 代码 span class token macro property
  • 基于C++ spdlog日志库的完善封装

    spdlog是一个C 43 43 编写的极速日志打印库 xff0c 支持异步写日志以及多种模式和格式化选项 以下基于spdlog库封装了一个简单易用的功能类 xff0c 采用的是header only方式 xff0c 便于项目集成 代码 p
  • C++11写的线程安全STL库

    用C 43 43 写的程序 xff0c 如果用到了自带的标准模板库STL xff0c 在多线程访问的时候如果不加锁很容易造成segment fault导致程序崩溃coredump xff0c 也就是说C 43 43 标准的STL不是线程安全
  • 使用cmake构建C++ imgui上手项目(支持Windows,Mac,Linux)

    优秀的即时渲染C 43 43 GUI开发框架imgui xff08 https github com ocornut imgui xff09 在很多场合能发挥非常棒的作用 但是由于官方源码仓库一直没有提供基于cmake构建和创建新项目的工具
  • 使用cmake构建C++ workflow上手项目(支持Windows,Linux)

    开源的C 43 43 后端开发框架workflow xff08 https github com sogou workflow xff09 已经在成熟的互联网公司得到非常稳定广泛的应用 xff0c 它结合了网络 异步 计算多个后端常用场景
  • 使用cmake构建C++ live555流媒体服务上手项目(支持Windows,Linux)

    开源的流媒体视频和音频RTSP开发框架live555 xff08 http www live555 com xff09 对于学习和构建音视频流媒体或者直播服务是很方便的 官方的源码包对各平台编译单独列出了对应的makefile xff0c
  • C++20新特性

    目录 新增关键字 keywords conceptrequiresconstinitconstevalco awaitco returnco yieldchar8 t 新增标识符 Identifies importmodule 模块 Mod
  • pytorch导出模型并使用onnxruntime C++部署加载模型推理

    机器学习的框架众多 xff0c 为了方便复用和统一后端模型部署推理 xff0c 业界主流都在采用onnx格式的模型 xff0c 支持pytorch xff0c tensorflow xff0c mxnet多种AI框架 为了提高部署推理的性能
  • cocos2dx实例开发之飞机大战

    曾经 xff0c 微信里面可以玩一个打飞机的小游戏 xff0c 很有趣 xff0c 后来又没有了 xff0c 这里基于原版素材写了一个高仿微信打飞机的小游戏 预览 工程结构 环境 Mac os Mojavexcode 7 0cocos2dx