猫史档案馆


详细解析 从天启大陆到肝帝地图 代码解析

用户:卑微OIer卑微OIer查看:1 回复:8 评论:1 创建时间:2021-09-19T10:40:11


肝帝地图解析

众所周知,肝帝地图是一种非常有趣的地图。他拥有三个核心机制

     1.打怪&采集&合成&购买  获取物品

     2.装备 的 穿着

     3.等级机制( SQL 狂喜)

下面,我们从天启大陆的部分代码详细解析

PART1   require函数的应用

const ITEM = require('./item.js').item;
const SKILLS = require('./skills.js').skills;
const MOBS = require('./mobs.js').mobs;

天启大陆有这三行代码,代表着 物品、技能、怪物类型

其中,我选取一部分item.js里面的code

const ApocalypseThingType = {
    HEAD: 'head',
    BODY: 'body',
    RIGHT_HAND: 'right_hand',
    ALL: 'all',
    LEFT_HAND: 'left_hand',
    THING: 'thing',
    SKIRT: 'skirt',
    HEAD: 'head',
    SHOE: 'shoe',
    PANT: 'pant',
    CALL: 'call',
}
const PARTICLES = require('./particles.js');
const Quat = new Box3Quaternion(0,0,0,1);
module.exports.item = {
    '无': {
        type: ApocalypseThingType.ALL,
        describe:'错误的bug',
        style: [],
        damage: 5,
        defense: 0,
        effect(entity){fist_attack(entity)},
        content: ['丢弃'],
    },
    'Lv1生命药水': {
        type: ApocalypseThingType.THING,
        describe: '使用可回复15hp',
        content: ['使用','丢弃'],
        effect: [15,0],
        meaning: 0,
    },
    'Lv2生命药水': {
        type: ApocalypseThingType.THING,
        describe: '使用可回复30hp',
        content: ['使用','丢弃'],
        effect: [30,0],
        meaning: 0,
    },
    '喵': {
        type: ApocalypseThingType.THING,
        describe: '使用会喵掉',
        content: ['使用','丢弃'],
        effect: [-999,0],
        meaning: 2,
    },
}

我们发现天气大陆(一般肝帝式地图)的物品一般格式都是

'物品名称':{
    物品类型列表
    效果
    可用操作
}

我们再次用reqire去引用他

不仅阅读方便,还易于修改

PART2 引用列表

上一个part里面,我们看见了TQ的item里面基本都有一个content属性

他代表着这个物品的可用操作,天启是这样定义这些操作的

'丢弃': async function (item, part, index) {
      const result = await this.player.dialog({
           type: Box3DialogType.SELECT,
           title: item,
           content: '确定丢弃吗?若丢弃就永远无法找回',
           options: ['丢弃', '取消'],
      })
      if (!result || result.index) return;
      this.bagRemove(index);
      this.update();
},

这是丢弃物品的一部分,自行体会一下其中的奥妙

至少人家没有if else到底

PART3 SQL

天启是这样定义数据的

const INIT = {
    money: 50,
    position: [21, 8.5, 233],
    head: '无',
    body: '无',
    pant: '无',
    shoe: '无',
    left_hand: '无',
    right_hand: '无',
    level: 0,
    xp: 0,
    bag: [],
    pull: 0,
    gets: 0,
    spirits: [],
    bodySpirit: '无',
    hp: 100,
    vip: 0,
    skirt: '无',
    spiritMagics: [],
    spirithp: [],
    hostV: '无',
    maxHp: 100,
    fans: [],
    follows: [],
    call: null,
    magicPower: 100,
    maxMagicPower: 100,
    skills: [],
    capacity: 15,
    wins: 0,
    bankMoney: 0,
    skillIndex: 0,
    assignment: [],
}

由于天启的数据库已经进入的PG所以用的是pg的方法

PART4 用户识别

天启有给予系统,你说™要是有人喵这么办,上黑名单啊

用什么当黑名单呢 : userKey

const KEYS = ['j9UPDRyRjN+TTI8H', 'UkWNoT5QGxDkmVOH', 'Ik9uUQ3tu1Tw9ujG', 'qsLs11/s1nAKpHgm', 'YnVNnwsH7DDoEQEz', 'Za8X8AzuORiA05dz', 'j07Y8T7wHF0I1Rat'];

管喵列表就是用userKey来存储的

PART5 怪物的生成

天启是用这样一个函数生成怪物的

MOBS['狱魔蛛皇'].spawn(new Box3Vector3(80, 10, 47));

在mob.js里面(提前引用过)是这样写的【截取一小段,不然3k多行你看不下去了】

module.exports.mobs = {
    '狱魔蛛皇': {
        hp: 5000+Math.round(Math.random()*1000-500),
        defense: 1.2+Math.round(Math.random()*0.2-0.1),
        spawn: async function(position){
            const e = world.createEntity({
                mesh: 'mesh/蜘蛛身.vb',
                meshScale: [0.2,0.2,0.2],
                position,
                mass: 100,
            })
            e.left1 = world.createEntity({
                mesh: 'mesh/蜘蛛前腿.vb',
                meshScale: [0.2,0.2,0.2],
                position,
                gravity: false,
                fixed: true,
            })
            e.left2 = world.createEntity({
                mesh: 'mesh/蜘蛛中腿.vb',
                meshScale: [0.2,0.2,0.2],
                position,
                gravity: false,
                fixed: true,
            })
            e.left3 = world.createEntity({
                mesh: 'mesh/蜘蛛前腿.vb',
                meshScale: [0.2,0.2,0.2],
                position,
                gravity: false,
                fixed: true,
            })
            e.left4 = world.createEntity({
                mesh: 'mesh/蜘蛛前腿.vb',
                meshScale: [0.2,0.2,0.2],
                position,
                gravity: false,
                fixed: true,
            })
            e.right1 = world.createEntity({
                mesh: 'mesh/蜘蛛前腿.vb',
                meshScale: [0.2,0.2,0.2],
                position,
                gravity: false,
                fixed: true,
            })
            e.right2 = world.createEntity({
                mesh: 'mesh/蜘蛛中腿.vb',
                meshScale: [0.2,0.2,0.2],
                position,
                gravity: false,
                fixed: true,
            })
            e.right3 = world.createEntity({
                mesh: 'mesh/蜘蛛前腿.vb',
                meshScale: [0.2,0.2,0.2],
                position,
                gravity: false,
                fixed: true,
            })
            e.right4 = world.createEntity({
                mesh: 'mesh/蜘蛛前腿.vb',
                meshScale: [0.2,0.2,0.2],
                position,
                gravity: false,
                fixed: true,
            })
            e.addTag('mob');
            e.left1.addTag('mob');
            e.left2.addTag('mob');
            e.left3.addTag('mob');
            e.left4.addTag('mob');
            e.right1.addTag('mob');
            e.right2.addTag('mob');
            e.right3.addTag('mob');
            e.right4.addTag('mob');
            e.angle = 2;
            let step = 0;
            e.walk = function(){
                if(step == 0){
                    e.left1.meshOrientation = Quat.rotateX(0.5);
                    e.left2.meshOrientation = Quat.rotateX(0);
                    e.left3.meshOrientation = Quat.rotateX(0);
                    e.left4.meshOrientation = Quat.rotateX(0);
                    e.right1.meshOrientation = Quat.rotateX(0.5);
                    e.right2.meshOrientation = Quat.rotateX(0);
                    e.right3.meshOrientation = Quat.rotateX(0);
                    e.right4.meshOrientation = Quat.rotateX(0);
                    rotateY();
                }
                if(step == 1){
                    e.left1.meshOrientation = Quat.rotateX(0.45);
                    e.left2.meshOrientation = Quat.rotateX(0.1);
                    e.left3.meshOrientation = Quat.rotateX(0);
                    e.left4.meshOrientation = Quat.rotateX(0.1);
                    e.right1.meshOrientation = Quat.rotateX(0.55);
                    e.right2.meshOrientation = Quat.rotateX(0);
                    e.right3.meshOrientation = Quat.rotateX(0.1);
                    e.right4.meshOrientation = Quat.rotateX(0);
                    rotateY();
                }
                if(step == 2){
                    e.left1.meshOrientation = Quat.rotateX(0.4);
                    e.left2.meshOrientation = Quat.rotateX(0.2);
                    e.left3.meshOrientation = Quat.rotateX(0);
                    e.left4.meshOrientation = Quat.rotateX(0.2);
                    e.right1.meshOrientation = Quat.rotateX(0.6);
                    e.right2.meshOrientation = Quat.rotateX(0);
                    e.right3.meshOrientation = Quat.rotateX(0.2);
                    e.right4.meshOrientation = Quat.rotateX(0);
                    rotateY();
                }
                if(step == 3){
                    e.left1.meshOrientation = Quat.rotateX(0.35);
                    e.left2.meshOrientation = Quat.rotateX(0.3);
                    e.left3.meshOrientation = Quat.rotateX(0);
                    e.left4.meshOrientation = Quat.rotateX(0.3);
                    e.right1.meshOrientation = Quat.rotateX(0.65);
                    e.right2.meshOrientation = Quat.rotateX(0);
                    e.right3.meshOrientation = Quat.rotateX(0.3);
                    e.right4.meshOrientation = Quat.rotateX(0);
                    rotateY();
                }
                if(step == 4){
                    e.left1.meshOrientation = Quat.rotateX(0.3);
                    e.left2.meshOrientation = Quat.rotateX(0.4);
                    e.left3.meshOrientation = Quat.rotateX(0);
                    e.left4.meshOrientation = Quat.rotateX(0.4);
                    e.right1.meshOrientation = Quat.rotateX(0.7);
                    e.right2.meshOrientation = Quat.rotateX(0);
                    e.right3.meshOrientation = Quat.rotateX(0.4);
                    e.right4.meshOrientation = Quat.rotateX(0);
                    rotateY();
                }
                if(step == 5){
                    e.left1.meshOrientation = Quat.rotateX(0.35);
                    e.left2.meshOrientation = Quat.rotateX(0.3);
                    e.left3.meshOrientation = Quat.rotateX(0);
                    e.left4.meshOrientation = Quat.rotateX(0.3);
                    e.right1.meshOrientation = Quat.rotateX(0.65);
                    e.right2.meshOrientation = Quat.rotateX(0);
                    e.right3.meshOrientation = Quat.rotateX(0.3);
                    e.right4.meshOrientation = Quat.rotateX(0);
                    rotateY();
                }
                if(step == 6){
                    e.left1.meshOrientation = Quat.rotateX(0.4);
                    e.left2.meshOrientation = Quat.rotateX(0.2);
                    e.left3.meshOrientation = Quat.rotateX(0);
                    e.left4.meshOrientation = Quat.rotateX(0.2);
                    e.right1.meshOrientation = Quat.rotateX(0.6);
                    e.right2.meshOrientation = Quat.rotateX(0);
                    e.right3.meshOrientation = Quat.rotateX(0.2);
                    e.right4.meshOrientation = Quat.rotateX(0);
                    rotateY();
                }
                if(step == 7){
                    e.left1.meshOrientation = Quat.rotateX(0.45);
                    e.left2.meshOrientation = Quat.rotateX(0.1);
                    e.left3.meshOrientation = Quat.rotateX(0);
                    e.left4.meshOrientation = Quat.rotateX(0.1);
                    e.right1.meshOrientation = Quat.rotateX(0.55);
                    e.right2.meshOrientation = Quat.rotateX(0);
                    e.right3.meshOrientation = Quat.rotateX(0.1);
                    e.right4.meshOrientation = Quat.rotateX(0);
                    rotateY();
                }
                if(step == 8){
                    e.left1.meshOrientation = Quat.rotateX(0.5);
                    e.left2.meshOrientation = Quat.rotateX(0);
                    e.left3.meshOrientation = Quat.rotateX(0);
                    e.left4.meshOrientation = Quat.rotateX(0);
                    e.right1.meshOrientation = Quat.rotateX(0.5);
                    e.right2.meshOrientation = Quat.rotateX(0);
                    e.right3.meshOrientation = Quat.rotateX(0);
                    e.right4.meshOrientation = Quat.rotateX(0);
                    rotateY();
                }
                if(step == 9){
                    e.left1.meshOrientation = Quat.rotateX(0.55);
                    e.left2.meshOrientation = Quat.rotateX(0);
                    e.left3.meshOrientation = Quat.rotateX(0.1);
                    e.left4.meshOrientation = Quat.rotateX(0);
                    e.right1.meshOrientation = Quat.rotateX(0.45);
                    e.right2.meshOrientation = Quat.rotateX(0.1);
                    e.right3.meshOrientation = Quat.rotateX(0);
                    e.right4.meshOrientation = Quat.rotateX(0.1);
                    rotateY();
                }
                if(step == 10){
                    e.left1.meshOrientation = Quat.rotateX(0.6);
                    e.left2.meshOrientation = Quat.rotateX(0);
                    e.left3.meshOrientation = Quat.rotateX(0.2);
                    e.left4.meshOrientation = Quat.rotateX(0);
                    e.right1.meshOrientation = Quat.rotateX(0.4);
                    e.right2.meshOrientation = Quat.rotateX(0.2);
                    e.right3.meshOrientation = Quat.rotateX(0);
                    e.right4.meshOrientation = Quat.rotateX(0.2);
                    rotateY();
                }
                if(step == 11){
                    e.left1.meshOrientation = Quat.rotateX(0.65);
                    e.left2.meshOrientation = Quat.rotateX(0);
                    e.left3.meshOrientation = Quat.rotateX(0.3);
                    e.left4.meshOrientation = Quat.rotateX(0);
                    e.right1.meshOrientation = Quat.rotateX(0.35);
                    e.right2.meshOrientation = Quat.rotateX(0.3);
                    e.right3.meshOrientation = Quat.rotateX(0);
                    e.right4.meshOrientation = Quat.rotateX(0.3);
                    rotateY();
                }
                if(step == 12){
                    e.left1.meshOrientation = Quat.rotateX(0.7);
                    e.left2.meshOrientation = Quat.rotateX(0);
                    e.left3.meshOrientation = Quat.rotateX(0.4);
                    e.left4.meshOrientation = Quat.rotateX(0);
                    e.right1.meshOrientation = Quat.rotateX(0.3);
                    e.right2.meshOrientation = Quat.rotateX(0.4);
                    e.right3.meshOrientation = Quat.rotateX(0);
                    e.right4.meshOrientation = Quat.rotateX(0.4);
                    rotateY();
                }
                if(step == 13){
                    e.left1.meshOrientation = Quat.rotateX(0.65);
                    e.left2.meshOrientation = Quat.rotateX(0);
                    e.left3.meshOrientation = Quat.rotateX(0.3);
                    e.left4.meshOrientation = Quat.rotateX(0);
                    e.right1.meshOrientation = Quat.rotateX(0.35);
                    e.right2.meshOrientation = Quat.rotateX(0.3);
                    e.right3.meshOrientation = Quat.rotateX(0);
                    e.right4.meshOrientation = Quat.rotateX(0.3);
                    rotateY();
                }
                if(step == 14){
                    e.left1.meshOrientation = Quat.rotateX(0.6);
                    e.left2.meshOrientation = Quat.rotateX(0);
                    e.left3.meshOrientation = Quat.rotateX(0.2);
                    e.left4.meshOrientation = Quat.rotateX(0);
                    e.right1.meshOrientation = Quat.rotateX(0.4);
                    e.right2.meshOrientation = Quat.rotateX(0.2);
                    e.right3.meshOrientation = Quat.rotateX(0);
                    e.right4.meshOrientation = Quat.rotateX(0.2);
                    rotateY();
                }
                if(step == 15){
                    e.left1.meshOrientation = Quat.rotateX(0.55);
                    e.left2.meshOrientation = Quat.rotateX(0);
                    e.left3.meshOrientation = Quat.rotateX(0.1);
                    e.left4.meshOrientation = Quat.rotateX(0);
                    e.right1.meshOrientation = Quat.rotateX(0.45);
                    e.right2.meshOrientation = Quat.rotateX(0.1);
                    e.right3.meshOrientation = Quat.rotateX(0);
                    e.right4.meshOrientation = Quat.rotateX(0.1);
                    rotateY();
                }
                if(step == 16){
                    e.left1.meshOrientation = Quat.rotateX(0.5);
                    e.left2.meshOrientation = Quat.rotateX(0);
                    e.left3.meshOrientation = Quat.rotateX(0);
                    e.left4.meshOrientation = Quat.rotateX(0);
                    e.right1.meshOrientation = Quat.rotateX(0.5);
                    e.right2.meshOrientation = Quat.rotateX(0);
                    e.right3.meshOrientation = Quat.rotateX(0);
                    e.right4.meshOrientation = Quat.rotateX(0);
                    rotateY();
                }
                function rotateY(){     
                    e.meshOrientation = Quat.rotateY(e.angle);
                    e.left1.meshOrientation = e.left1.meshOrientation.rotateY(e.angle + 0.7);
                    e.left2.meshOrientation = e.left2.meshOrientation.rotateY(e.angle + 1.5);
                    e.left3.meshOrientation = e.left3.meshOrientation.rotateY(e.angle + 2);
                    e.left4.meshOrientation = e.left4.meshOrientation.rotateY(e.angle + 2.7);
                    e.right1.meshOrientation = e.right1.meshOrientation.rotateY(e.angle - 0.7);
                    e.right2.meshOrientation = e.right2.meshOrientation.rotateY(e.angle - 1.5);
                    e.right3.meshOrientation = e.right3.meshOrientation.rotateY(e.angle - 2);
                    e.right4.meshOrientation = e.right4.meshOrientation.rotateY(e.angle - 2.7);
                    e.left1.position = e.position.add(new Box3Vector3(Math.cos(e.angle + 1),0,Math.sin(e.angle + 1)).mul(new Box3Vector3(3,0,3)));
                    e.left2.position = e.position.add(new Box3Vector3(Math.cos(e.angle + 1.5),0,Math.sin(e.angle + 1.5)).mul(new Box3Vector3(3,0,3)));
                    e.left3.position = e.position.add(new Box3Vector3(Math.cos(e.angle + 2),0,Math.sin(e.angle + 2)).mul(new Box3Vector3(3,0,3)));
                    e.left4.position = e.position.add(new Box3Vector3(Math.cos(e.angle + 2.7),0,Math.sin(e.angle + 2.5)).mul(new Box3Vector3(3,0,3)));
                    e.right1.position = e.position.add(new Box3Vector3(Math.cos(e.angle - 1),0,Math.sin(e.angle - 1)).mul(new Box3Vector3(3,0,3)));
                    e.right2.position = e.position.add(new Box3Vector3(Math.cos(e.angle - 1.5),0,Math.sin(e.angle - 1.5)).mul(new Box3Vector3(3,0,3)));
                    e.right3.position = e.position.add(new Box3Vector3(Math.cos(e.angle - 2),0,Math.sin(e.angle - 2)).mul(new Box3Vector3(3,0,3)));
                    e.right4.position = e.position.add(new Box3Vector3(Math.cos(e.angle - 2.7),0,Math.sin(e.angle - 2.5)).mul(new Box3Vector3(3,0,3)));
                }
            }
            e.addTag('monster');
            e.heavy = e.mass;
            e.onDie(async({attacker})=>{
                e.destroy();
                e.left1.destroy();
                e.left2.destroy();
                e.left3.destroy();
                e.left4.destroy();
                e.right1.destroy();
                e.right2.destroy();
                e.right3.destroy();
                e.right4.destroy();
                if(attacker && attacker.isPlayer)level_up(attacker,500);
                falling_objects('毒蛛宝箱',e.position,new Box3Vector3(0.03,0.03,0.03),'mesh/宝箱.vb');
                await sleep(300000);
                module.exports.mobs['狱魔蛛皇'].spawn(new Box3Vector3(80,10,47));
            })
            e.onVoxelContact(({force,x,y,z})=>{
                if(force.y == 0 && voxels.getVoxel(x,y + 1,z) == 0){
                    e.velocity.y = 1;
                }
            })
            e.onEntityContact(({force})=>{
                if(force.y == 0)
                e.velocity.y = 1;
            })
            Object.assign(e,{
                hp: this.hp,
                maxHp: this.hp,
                defense: this.defense,
                enableDamage: true,
                bloodLess: bloodLess,
                isHurtable: isHurtable,
                op: OP_SLEEP,
                async update()
                {
                    this.interactHint = `${Math.round(this.hp)}`;
                    this.op = this.op(this);
                    if(this.hp < this.maxHp / 2){
                        this.defenseIN = 0.5;
                        Object.assign(this,PARTICLES.particle3);
                        this.particleVelocity.y = 0.5;
                    }
                },
            })
            e.defenseIN = (1/e.defense);
            while(e.hp > 0){
                e.walk();
                step++;
                if(step > 16)
                step = 0;
                await sleep(喵);
            }
        }
    },
    //以下省略几千行
}

故此我们发现定义怪物的时候

出生方法、去世方法、活着的时候的方法

懂了?废了?

----总结-----

做肝帝图要肝帝心,不像别的题图200多行代码就可以了

天启代码1w多行,3个写代码的自行体会……………………

这种图也不容易大型更改,不然就是一堆物品作废

只能更新,不能后退!要有规划,人多力量大!


回复

上一页1 页 / 共 1下一页
化石茄子的铁镐化石茄子的铁镐

nb

点赞0


评论


SSR级学霸_拉文克劳SSR级学霸_拉文克劳

666666imgsrc="https://static.cod喵/emoji/codemao/%E7%BC%96%E7%A8%8B%E7%8C%AB_%E5%8A%A0%E6%B2%B9.gif"alt="emotion_编程猫_加油"

点赞0


评论


发飙的蜗牛a发飙的蜗牛a

OH MY GAD

点赞0


评论


代码追星人代码追星人

武器部分能讲解一下吗?

点赞0


评论


该账号已被封禁该账号已被封禁

实际上这样讲是完全错误的

天启大陆重要的不是代码是框架

框架就是对象套对象而不是你那所谓的‘格式’

再次天启的SQL机制是将一个被JSON.stringify后的对象储存在SQL表中

然后需要的时候就用JSON.parse函数重新转化为对象,再用Object.assign函数将对象中可枚举的值分放到玩家的实体作为一个一个的键

再后天启大陆最重要的几个点是moudel.exports函数和require函数以及对象的索引

主要就是MOUDEL[name].xxxxxxxx

反正就是这几个点

点赞0


评论


上次做了个没有保存机制的(连挖掘都没完善)仿MC,深有体会(代码已经2000左右了)

点赞0


评论


化石茄子的铁镐化石茄子的铁镐

发点天启特效代码(?)

点赞0


评论


难起的名字难起的名字

记得我吧(()(来不:https://box3.fun/e/98b8e1b016f8570ef606

点赞0


评论