用户:
卑微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个写代码的自行体会……………………
这种图也不容易大型更改,不然就是一堆物品作废
只能更新,不能后退!要有规划,人多力量大!
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
评论
该账号已被封禁实际上这样讲是完全错误的
天启大陆重要的不是代码是框架
框架就是对象套对象而不是你那所谓的‘格式’
再次天启的SQL机制是将一个被JSON.stringify后的对象储存在SQL表中
然后需要的时候就用JSON.parse函数重新转化为对象,再用Object.assign函数将对象中可枚举的值分放到玩家的实体作为一个一个的键
再后天启大陆最重要的几个点是moudel.exports函数和require函数以及对象的索引
主要就是MOUDEL[name].xxxxxxxx
反正就是这几个点
点赞0
评论