基于cocos2dx的RPG简单实用算法之3 - 多角色跟随阵型移动

2024-06-14 02:38

本文主要是介绍基于cocos2dx的RPG简单实用算法之3 - 多角色跟随阵型移动,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!



1. 确定到一个阵型中心对象。

也许是一个英雄,也可以是一个隐藏的对象。也就是下文种的 GridCenter

2. 预先计算号每个阵型“槽” 相对中心对象的 向量。

void GameControlManager::startGridMode()
{
    if(m_MainScene->heroList.empty())
        return;
    m_IsStartGridMode = true;
    Point GridCenter = findGridCenter();
    if(memberNumber == 1)
        return;
    else if(memberNumber == 2)
    {
        //     0
        //     1
        originRelativeVec[0] = Vec2(0,Grid_Slot_Radius);
        originRelativeVec[1] = Vec2(0,-Grid_Slot_Radius);
    }
    else if(memberNumber == 3)
    {
        Point firstPos = GridCenter + Vec2(0,Grid_Slot_Radius);
        Point secondPos = firstPos.rotateByAngle(GridCenter, CC_DEGREES_TO_RADIANS(-120));
        Point thirdPos = secondPos.rotateByAngle(GridCenter, CC_DEGREES_TO_RADIANS(-120));
        
        //      0
        //
        //  1       2
        originRelativeVec[0] = firstPos - GridCenter;
        originRelativeVec[1] = secondPos - GridCenter;
        originRelativeVec[2] = thirdPos - GridCenter;
    }
    else if(memberNumber == 4)
    {
        Point firstPos = GridCenter + Vec2(0,Grid_Slot_Radius);
        Point secondPos = firstPos.rotateByAngle(GridCenter, CC_DEGREES_TO_RADIANS(-90));
        Point thirdPos = secondPos.rotateByAngle(GridCenter, CC_DEGREES_TO_RADIANS(-90));
        Point fourthPos = thirdPos.rotateByAngle(GridCenter, CC_DEGREES_TO_RADIANS(-90));
        
        //     0          战士
        //  1     2     猎人  法师
        //     3          牧师
        originRelativeVec[0] = firstPos - GridCenter;
        originRelativeVec[1] = fourthPos - GridCenter;
        originRelativeVec[2] = secondPos - GridCenter;
        originRelativeVec[3] = thirdPos - GridCenter;
    }

    
    //认领slot位置
    int slotIndex = 0;
    int minSpeed = 999;
    for(auto hero : m_MainScene->heroList) //已经排序
    {
        if(!hero->getIsAlly() && !hero->getIsDead())
        {
            hero->setSlotIndex(slotIndex);
            slotIndex ++;
            
            auto actorInfo = GameData::getActorInfoFromMap(hero->getUnitID());
            if(actorInfo->speed < minSpeed)
                minSpeed = actorInfo->speed;
        }
    }

3. 根据一号英雄相对中心对象的方向来确定阵型初始朝向

    Point firstmanPos = m_MainScene->heroList.front()->getCenterPoint();
//    crossover_point(firstmanPos, GridCenter, )
    
    Vec2 heroVec = firstmanPos - GridCenter;
    heroVec.normalize();
    m_GridAngle = getDirectionByChief(heroVec);
    
    for(int index = 0; index < memberNumber; index++)
    {
        Vec2 cur = originRelativeVec[index];
        Point curPoint = cur + GridCenter;
        curPoint = curPoint.rotateByAngle(GridCenter, m_GridAngle);
        cur = curPoint - GridCenter;
        slotRelativeVec[index] = cur;
    }

4. 所有英雄各就各位

    for(auto hero : m_MainScene->heroList)
    {
        if(!hero->getIsAlly() && !hero->getIsDead())
        {
            Vec2 curVec = slotRelativeVec[hero->getSlotIndex()];
            Point des = GridCenter + curVec;
            hero->setDestinationPoint(des);
        }
    }
....
}


5.  当阵型移动,根据 ”中心对象“相对目的地位置 targetPos来更新阵型朝向角度GridAngle

再根据GridAngle刷新 每个槽的相对向量 cur

void GameControlManager::setGridDirection(Point targetPos)
{
    //更新阵型朝向
    auto GridCenter = getGridCenter();
    Vec2 chiefVec = targetPos - GridCenter;
    chiefVec.normalize();
    m_GridAngle = getDirectionByChief(chiefVec);
    for(int index = 0; index < memberNumber; index++)
    {
        Vec2 cur = originRelativeVec[index];
        Point curPoint = cur + m_gridObject->getPosition();
        curPoint = curPoint.rotateByAngle(m_gridObject->getPosition(),m_GridAngle); //在原基础上旋转
        cur = curPoint - m_gridObject->getPosition();
        slotRelativeVec[index] = cur;
    }
    m_gridObject->setRotation(CC_RADIANS_TO_DEGREES(-m_GridAngle));
}


6. 每一帧让角色移动到自己对应的槽

void GameControlManager::updateGridDirection()
{
            Point slot = getSlotPosByIndex(hero->getSlotIndex());
            if(hero->getCenterPoint().distance(slot) > getElasticRange())
            {
                hero->moveToward(slot);
            }
}


这篇关于基于cocos2dx的RPG简单实用算法之3 - 多角色跟随阵型移动的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1059139

相关文章

Python 基于http.server模块实现简单http服务的代码举例

《Python基于http.server模块实现简单http服务的代码举例》Pythonhttp.server模块通过继承BaseHTTPRequestHandler处理HTTP请求,使用Threa... 目录测试环境代码实现相关介绍模块简介类及相关函数简介参考链接测试环境win11专业版python

从基础到进阶详解Python条件判断的实用指南

《从基础到进阶详解Python条件判断的实用指南》本文将通过15个实战案例,带你大家掌握条件判断的核心技巧,并从基础语法到高级应用一网打尽,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录​引言:条件判断为何如此重要一、基础语法:三行代码构建决策系统二、多条件分支:elif的魔法三、

Python 字符串裁切与提取全面且实用的解决方案

《Python字符串裁切与提取全面且实用的解决方案》本文梳理了Python字符串处理方法,涵盖基础切片、split/partition分割、正则匹配及结构化数据解析(如BeautifulSoup、j... 目录python 字符串裁切与提取的完整指南 基础切片方法1. 使用切片操作符[start:end]2

python连接sqlite3简单用法完整例子

《python连接sqlite3简单用法完整例子》SQLite3是一个内置的Python模块,可以通过Python的标准库轻松地使用,无需进行额外安装和配置,:本文主要介绍python连接sqli... 目录1. 连接到数据库2. 创建游标对象3. 创建表4. 插入数据5. 查询数据6. 更新数据7. 删除

Jenkins的安装与简单配置过程

《Jenkins的安装与简单配置过程》本文简述Jenkins在CentOS7.3上安装流程,包括Java环境配置、RPM包安装、修改JENKINS_HOME路径及权限、启动服务、插件安装与系统管理设置... 目录www.chinasem.cnJenkins安装访问并配置JenkinsJenkins配置邮件通知

把Python列表中的元素移动到开头的三种方法

《把Python列表中的元素移动到开头的三种方法》在Python编程中,我们经常需要对列表(list)进行操作,有时,我们希望将列表中的某个元素移动到最前面,使其成为第一项,本文给大家介绍了把Pyth... 目录一、查找删除插入法1. 找到元素的索引2. 移除元素3. 插入到列表开头二、使用列表切片(Lis

Python按照24个实用大方向精选的上千种工具库汇总整理

《Python按照24个实用大方向精选的上千种工具库汇总整理》本文整理了Python生态中近千个库,涵盖数据处理、图像处理、网络开发、Web框架、人工智能、科学计算、GUI工具、测试框架、环境管理等多... 目录1、数据处理文本处理特殊文本处理html/XML 解析文件处理配置文件处理文档相关日志管理日期和

Python yield与yield from的简单使用方式

《Pythonyield与yieldfrom的简单使用方式》生成器通过yield定义,可在处理I/O时暂停执行并返回部分结果,待其他任务完成后继续,yieldfrom用于将一个生成器的值传递给另一... 目录python yield与yield from的使用代码结构总结Python yield与yield

精选20个好玩又实用的的Python实战项目(有图文代码)

《精选20个好玩又实用的的Python实战项目(有图文代码)》文章介绍了20个实用Python项目,涵盖游戏开发、工具应用、图像处理、机器学习等,使用Tkinter、PIL、OpenCV、Kivy等库... 目录① 猜字游戏② 闹钟③ 骰子模拟器④ 二维码⑤ 语言检测⑥ 加密和解密⑦ URL缩短⑧ 音乐播放

python中列表应用和扩展性实用详解

《python中列表应用和扩展性实用详解》文章介绍了Python列表的核心特性:有序数据集合,用[]定义,元素类型可不同,支持迭代、循环、切片,可执行增删改查、排序、推导式及嵌套操作,是常用的数据处理... 目录1、列表定义2、格式3、列表是可迭代对象4、列表的常见操作总结1、列表定义是处理一组有序项目的