基于PF规则的CRPG制作尝试(六)近战攻击判定

基于PF规则的CRPG制作尝试(六)近战攻击判定

终于到了近战攻击判定…这部分的东西难度不是很高,但是需要实现的零碎功能却不少。

CRPG的攻击判定相对于3D动作游戏的攻击判定来说有一些简单之处,但也有一些难点。3D动作游戏的攻击判定当然避不开的就是刚体碰撞的判定,这对于只要相距不超过攻击范围就一定能攻击得到的CRPG来相比还是比较麻烦的,但距离计算这方面自然就可以省去了,应该算是有得有失吧。

在我看来,想要实现crpg的攻击判定是需要完成以下几个功能的:
1.新建一个ActorController中的ATTACK状态,
2.在ATTACK状态中能够实现识别鼠标悬停位置的角色的功能,为以后显示敌我状态栏做铺垫。
3.在ATTACK状态下对敌人点击鼠标右键进行攻击判定
首先只有点击的目标为敌人时下能进行攻击操作,然后角色方向转向攻击对象,如果敌人距角色距离(monsterdis)小于等于5尺(1.66米)执行攻击操作,并返回攻击信息,否则就要在角色头上显示“超出范围”。
接下来是详细的说明:

一、新建ATTACK状态

在之前枚举的状态中添加一个新的状态,切换条件暂定为点击K键。当然是只有在GameManager的Actor状态,即玩家回合中才能进入。(见上一节)这个ATTACK状态就是PF规则中占用一个标准动作的攻击动作。

二、识别鼠标悬停位置的角色

上一节也实现了,这一节主要是添加一个识别,只有在鼠标悬停的位置是敌方的时候才能够识别,我把这个方法做成了一个函数。具体的识别方法而言,我选择在敌人的gameobject上加一个名为monster的tag,然后通过.transform.gameObject.tag 的方式取得tag。具体代码如下:

 void showname()
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hitinfo;
        if (Physics.Raycast(ray, out hitinfo) && hitinfo.transform.gameObject.tag == "monster")
        {
            print("鼠标放在具有名为monster的tag的gameobject”+gob.ToString()“上了");
            GameObject gob = hitinfo.collider.gameObject;
        }
    }

三、点击鼠标右键进行攻击

 if (Input.GetMouseButtonDown(1))
            {
                //在普通状态下直接走
                if (state == STATE.IDLE)
                {
                    anim.SetBool("movewithoutsword", true);
                    UpdateControl();
                }
                //在移动预设线状态下画预设线
                if (state == STATE.MOVEPRE)
                    DrawPreviewLine();
                //在攻击状态下进行攻击判定
                if (state == STATE.ATTACK)
                {
                    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                    RaycastHit hit;
                    if (Physics.Raycast(ray, out hit) && hit.transform.gameObject.tag == "monster")
                    {
                        ActorTrans.LookAt(hit.transform.position);
                        if (monsterdis <= 1.66)
                        {                      
                            anim.SetTrigger("attack");
                        }
                        else
                            outofrange();
                        print("delta攻击了"+hit.transform.name);//打印选中物体的名字   
                    }
                }
            }
    void outofrange()
    {
        Oortext = GameObject.Find("outofrange");
        if (state == STATE.ATTACK)
            Oortext.GetComponent<TMP_Text>().text = "out of range";
        else
            Oortext.GetComponent<TMP_Text>().text = " ";
    }

本来还想讲讲代码,这么一看好像还挺简单的…就 不讲了吧。
Oortext是绑在角色头上的一个TextMeshPro,具体操作见上一节的第三部分。

写一个简易 CRPG 是一项很复杂的任务,需要设计游戏世界、角色、道具、怪物等众多要素,并编写相关的代码来实现游戏逻辑。下面是一个简单的示例,只包含了一些基本的游戏元素和逻辑: ```c++ #include <iostream> #include <cstdlib> #include <ctime> using namespace std; // 定义角色结构体 struct Player { string name; int hp; int mp; int level; int exp; int gold; }; // 定义怪物结构体 struct Monster { string name; int hp; int attack; int defense; int exp; int gold; }; // 初始化角色 void initPlayer(Player& player) { player.name = "Hero"; player.hp = 100; player.mp = 50; player.level = 1; player.exp = 0; player.gold = 0; } // 显示角色状态 void showPlayer(Player& player) { cout << "Name: " << player.name << endl; cout << "Level: " << player.level << endl; cout << "HP: " << player.hp << endl; cout << "MP: " << player.mp << endl; cout << "Exp: " << player.exp << endl; cout << "Gold: " << player.gold << endl; } // 初始化怪物 void initMonster(Monster& monster) { monster.name = "Slime"; monster.hp = 50; monster.attack = 10; monster.defense = 5; monster.exp = 20; monster.gold = 10; } // 显示怪物状态 void showMonster(Monster& monster) { cout << "Name: " << monster.name << endl; cout << "HP: " << monster.hp << endl; cout << "Attack: " << monster.attack << endl; cout << "Defense: " << monster.defense << endl; cout << "Exp: " << monster.exp << endl; cout << "Gold: " << monster.gold << endl; } // 角色攻击怪物 void playerAttack(Player& player, Monster& monster) { int damage = player.level * 10 + rand() % 10 - monster.defense; if (damage < 0) damage = 0; monster.hp -= damage; cout << player.name << " deals " << damage << " damage to " << monster.name << endl; if (monster.hp <= 0) { cout << monster.name << " is defeated!" << endl; player.exp += monster.exp; player.gold += monster.gold; if (player.exp >= player.level * 100) { player.exp -= player.level * 100; player.level++; cout << player.name << " levels up!" << endl; } initMonster(monster); } } // 怪物攻击角色 void monsterAttack(Player& player, Monster& monster) { int damage = monster.attack - player.level * 2; if (damage < 0) damage = 0; player.hp -= damage; cout << monster.name << " deals " << damage << " damage to " << player.name << endl; if (player.hp <= 0) { cout << player.name << " is defeated!" << endl; exit(0); } } // 主函数 int main() { srand(time(NULL)); Player player; Monster monster; initPlayer(player); initMonster(monster); while (true) { showPlayer(player); showMonster(monster); cout << "1. Attack" << endl; cout << "2. Run away" << endl; int choice; cin >> choice; if (choice == 1) { playerAttack(player, monster); monsterAttack(player, monster); } else if (choice == 2) { cout << "You run away!" << endl; initMonster(monster); } } return 0; } ``` 这个简易 CRPG 的逻辑很简单,玩家需要与怪物战斗,获得经验和金币,提升自己的等级。玩家每次攻击怪物或者被怪物攻击时,都会有一定的随机因素,使得游戏更加有趣。这只是一个简单的示例,实际上一个完整的 CRPG 需要更加复杂的设计和实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值