概述

人工智能(Artificial Intelligence,AI),一种对人类的意识思维过程模仿,本身作为计算机科学的一门分支学科,是一门极为复杂而又具有挑战性的科学。在游戏中,人工智能的出现十分普遍,比如一个游戏中的非玩家角色(Non-Player Character,NPC)往往是这个游戏中人工智能的常见表现形式。简单到生物自行移动,复杂到怪物的攻击行为,这些行为无不是人工智能在起作用。

1.8版本的Minecraft引入了新的人工智能系统,这套系统为一种实体生物AI的注册、使用提供了一套比较方便的AI,这也是本部分讲述的重点。当然正如我上面所讲到的一样,人工智能的设计本身就是一门学问,一般情况下游戏中对于AI的设计和游戏的可玩性等密切相关,这还是要靠开发者的自己去掌握相关的知识,多看看原版的AI是如何实现的,并多动手实践。

AI任务

Minecraft把若干个AI分解为相对独立的AI任务,比如随机游走、寻路、攻击等。这些类都是名为EntityAIBase的抽象类的子类。一些类具有通用性,不过很多类只是这个实体生物特有的。所以我们这里把这个类作为实体的子类体现在代码中:

src/main/java/com/github/ustc_zzzz/fmltutor/entity/EntityGoldenChicken.java(部分):

    protected static class AIStackBlock extends EntityAIBase
    {
        private final EntityGoldenChicken entity;

        public AIStackBlock(EntityGoldenChicken entity)
        {
            this.entity = entity;
        }

        @Override
        public boolean shouldExecute()
        {
            return true;
        }

        @Override
        public void updateTask()
        {

        }
    }

自然,这个抽象类的重点就是这两个没有被实现的方法:shouldExecuteupdateTask

顾名思义,这两个方法的作用,一个是判断当前AI是否应当执行,另一个就是执行方法,这里作者简单作了一个捡起脚下方块并放置的实现,虽然这个实现还不够严谨,但是作为一个示例应该够用了。

src/main/java/com/github/ustc_zzzz/fmltutor/entity/EntityGoldenChicken.java(部分):

    protected static class AIStackBlock extends EntityAIBase
    {
        private final EntityGoldenChicken entity;

        public AIStackBlock(EntityGoldenChicken entity)
        {
            this.entity = entity;
        }

        @Override
        public boolean shouldExecute()
        {
            return this.entity.worldObj.getGameRules().getBoolean("mobGriefing");
        }

        @Override
        public void updateTask()
        {
            BlockPos entityPos = new BlockPos(entity);
            if (entity.worldObj.isAirBlock(entityPos.up()))
            {
                AxisAlignedBB aabb = AxisAlignedBB.fromBounds(entityPos.getX() - 1, entityPos.getY(),
                        entityPos.getZ() - 1, entityPos.getX() + 2, entityPos.getY() + 1, entityPos.getZ() + 2);
                for (Object e : entity.worldObj.getEntitiesWithinAABB(EntityItem.class, aabb))
                {
                    ItemStack stack = ((EntityItem) e).getEntityItem();
                    Block block = Block.getBlockFromItem(stack.getItem());
                    if (block != null)
                    {
                        entity.setLocationAndAngles(entity.posX, entity.posY + 1, entity.posZ, entity.rotationYaw,
                                entity.rotationPitch);
                        entity.worldObj.setBlockState(entityPos, block.getDefaultState());
                        if (--stack.stackSize <= 0)
                        {
                            ((EntityItem) e).setDead();
                        }
                    }
                }
            }
        }
    }

注册AI任务

EntityLiving类提供了两个名为EntityAITasks的类的实例,它们分别是taskstargetTasks。前者负责一些非攻击AI,如移动、交配等。而后者负责一些攻击AI,如跟踪目标、发动攻击等。

EntityAITasks类提供了两个方法,它们分别是addTaskremoveTask。我们可以通过在实体生物的构造函数中通过调用这两个方法的方式传入EntityAIBase类子类的实例,就可以实现实体AI的加载与卸载。addTask方法的第一个参数表示这个AI的优先级,值越低越早执行,可以重复,不过作者给出的示例中因为没有必要就没有使用重复优先级值:

src/main/java/com/github/ustc_zzzz/fmltutor/entity/EntityGoldenChicken.java(部分):

    public EntityGoldenChicken(World worldIn)
    {
        super(worldIn);
        this.setSize(1.2F, 1.8F);
        this.tasks.addTask(8, new AIStackBlock(this));
    }

打开游戏试试吧~

results matching ""

    No results matching ""