console.clear() var test = world.querySelector('#6') test.meshOrientation = new Box3Quaternion(0, 0, 0, 1).rotateX(Math.PI).rotateY(Math.PI) /*(async function () { await sleep(100) var quat = test.meshOrientation for (let i = 0; ; i += 0.1) { test.meshOrientation = quat.rotateX(i) if (world.querySelectorAll('player')[0].player.action0Button) { world.say(i % Math.PI) break; } await sleep(100) } })()*/ function getPosition(angle = 0, up = 0, position = new Box3Vector3(0, 0, 0), radius = 0) { var pos = new Box3Vector3(0, 0, 0) pos.copy(position) pos.x += Math.cos(angle) * Math.cos(up) * radius pos.y += Math.sin(up) * radius pos.z += Math.sin(angle) * Math.cos(up) * radius return pos } let admin = ['jmd123456']; world.onChat(({ entity, message }) => { if (admin.includes(entity.player.boxId)) { if (message.startsWith('$')) { var code = message.slice(1) try { entity.player.directMessage(`~> ${eval(code)}`) } catch (e) { entity.player.directMessage(e) } } } }) /*测试内容 var a = world.querySelector('#a'); var b = world.querySelector('#b'); (async function () { var x = 0; var y = 0; var z = 0; var radius = b.position.x - a.position.x var height = b.position.y - a.position.y while (1) { var angle = Math.atan2(z, x) var up = Math.atan2(y, Math.sqrt(x ** 2 + z ** 2)) var pos = getPosition(angle, up + Math.PI / 2, getPosition(angle, up, a.position, radius), height) b.position.copy(pos) b.meshOrientation = new Box3Quaternion(0, 0, 0, 1).rotateX(up).rotateY(angle) a.meshOrientation.copy(b.meshOrientation) await sleep(100) } })() */ const tanks = { '虎式坦克': { parts: [], '炮塔': { hp: 800, fangyu: 150, fangyuReload: 2, zwXiShu: 0.1, '高爆弹': { fireRandom: 0.1,//被高爆弹打中起火几率 damage: [120, 25],//100基础伤害,50随机伤害 intoDamage: [2.5, 3],//击穿装甲后的伤害随机倍率 reload: 5, }, '穿甲弹': { damage: 150, damageUp: 50, reload: 5, }, }, '车身': { hp: 1500, fangyu: 300,//装甲 fangyuReload: 5,//每五秒恢复多少防御 }, '履带': { hp: 400, fangyu: 50, fangyuReload: 1, speed: 0.5,//速度,越大越快 zwXiShu: 0.05,//转弯系数 jump: 1,//越野系数,越大越好 } } } for (let i in tanks) { world.querySelectorAll('*').forEach((e) => { if (e.hasTag(`*${i}`)) { tanks[i].parts.push(e) } }) } function changeState(player = new Box3Entity, state = '驾驶') { if (state == '驾驶') { player.player.spectator = true player.player.invisible = true player.player.canFly = true player.player.showName = false } else if (state == '行走') { player.player.spectator = false; player.player.invisible = false; player.player.canFly = false; player.player.showName = true; } } function createTank(position = new Box3Vector3(0, 0, 0), name = '虎式坦克', entity = new Box3Entity, team = '') { changeState(entity, '驾驶') var tanksx = tanks[name] if (!tanksx) return; var partList = {} for (let i of tanksx.parts) { if (i.tags()[1] != undefined) { if (tanksx[i.tags()[1]] != undefined) { var e = world.createEntity({ mesh: i.mesh, meshScale: i.meshScale, collides: false, gravity: false, position: position, fixed: true, }); e.before = i e.addTag('坦克部分') e.own = entity var partName = i.tags()[1] var partsx = tanksx[i.tags()[1]] for (let az in partsx) { e[az] = partsx[az] } e.enableDamage = true; e.maxHp = e.hp e.part = partName e.addTag(e.part) if (!Array.isArray(partList[partName])) { partList[partName] = [e] } else { partList[partName].push(e) } if (partName == '炮塔') { entity.player.cameraEntity = e e.angle = 0; e.direction = 0; } if (partName == '车身') { var contactBound = world.createEntity({//碰撞箱生成 mesh: 'mesh/单元方块.vb', meshScale: new Box3Vector3(0.0625 * i.bounds.x, 0.0625 * i.bounds.y, 0.0625 * i.bounds.z), collides: true, gravity: 0, position: position, }) if (!Array.isArray(partList['碰撞箱'])) { partList['碰撞箱'] = [contactBound] } else { partList['碰撞箱'].push(contactBound) } contactBound.addTag('坦克碰撞箱') contactBound.direction = 0; contactBound.angle = 0; contactBound.up = 0 contactBound.speedState = 0;//0~100 contactBound.meshInvisible = true; contactBound.own = entity } if (partName == '履带') { e.meshInvisible = true; } } } } var tag = world.createEntity({ mesh: 'mesh/旗帜.vb', meshScale: new Box3Vector3(0.0625, 0.0625, 0.0625), position: position.add(new Box3Vector3(0, 3, 0)), collides: false, gravity: false, fixed: true, }) tag.meshColor = getColor(team) tag.own = entity tag.part = '队伍标识' partList['队伍标识'] = [tag] tag.addTag('队伍标识') entity.tank = partList checkTankPartPosition(entity.tank) } function checkTankPartPosition(parts = []) {//以碰撞箱为主单位的组合运动代码 //parts的组合方式:{'碰撞箱':[xxx],'车身':[xxx]...} // parts['碰撞箱'][0].meshOrientation = parts['车身'][0].before.meshOrientation.rotateY(parts['碰撞箱'][0].angle) var speed = 0; var own = new Box3Entity own = parts['碰撞箱'][0].own if (parts['履带'] != undefined) { speed = parts['履带'][0].speed * parts['碰撞箱'][0].speedState / 100 parts['碰撞箱'][0].direction = Math.atan2(own.player.facingDirection.z, own.player.facingDirection.x) if (own.player.walkButton) { getAngle(parts['碰撞箱'][0], parts['履带'][0].zwXiShu * parts['碰撞箱'][0].speedState / 100, parts['炮塔'][0]) parts['碰撞箱'][0].meshOrientation = parts['车身'][0].before.meshOrientation.rotateY(parts['碰撞箱'][0].angle) } } parts['碰撞箱'][0].velocity.set( Math.cos(parts['碰撞箱'][0].angle) * Math.cos(parts['碰撞箱'][0].up) * speed, Math.sin(parts['碰撞箱'][0].up) * speed - 0.1, Math.sin(parts['碰撞箱'][0].angle) * Math.cos(parts['碰撞箱'][0].up) * speed ) for (let i in parts) { for (let a in parts[i]) { var part = parts[i][a] var partName = part.part if (partName == '队伍标识') { part.position.copy(parts['碰撞箱'][0].position.add(new Box3Vector3(0, 5, 0))) } if (partName == '车身') { part.position.copy(parts['碰撞箱'][0].position) part.meshOrientation = new Box3Quaternion(0, 0, 0, 1).rotateX(parts['碰撞箱'][0].up).rotateY(parts['碰撞箱'][0].angle) } if (partName == '炮塔') { if (!own.player.walkButton) { part.direction = Math.atan2(own.player.facingDirection.z, own.player.facingDirection.x) getAngle(part, part.zwXiShu) } var pos = getPosition(parts['碰撞箱'][0].angle, (parts['碰撞箱'][0].up + Math.PI / 2), getPosition(part.angle, parts['碰撞箱'][0].up, parts['碰撞箱'][0].position, part.before.position.x - parts['车身'][0].before.position.x) , part.before.position.y - parts['车身'][0].before.position.y) part.position.copy(pos) var quat = new Box3Quaternion(0, 0, 0, 1) part.meshOrientation = quat.rotateY(part.angle).rotateX(parts['碰撞箱'][0].up * Math.cos(parts['碰撞箱'][0].angle) ).rotateZ(parts['碰撞箱'][0].up * Math.sin(parts['碰撞箱'][0].angle)) /*记录数据:往右侧的垂直的炮管:-pi/2 往左侧的垂直炮管:pi/2 (up-(angle1-angle2)) */ } if (partName == '履带') { var pos1 = getPosition(parts['碰撞箱'][0].angle, parts['碰撞箱'][0].up, parts['碰撞箱'][0].position, part.before.position.x - parts['车身'][0].before.position.x) pos1 = getPosition(parts['碰撞箱'][0].angle, parts['碰撞箱'][0].up + Math.PI / 2, pos1, part.before.position.y - parts['车身'][0].before.position.y) pos1 = getPosition(parts['碰撞箱'][0].angle + Math.PI / 2, parts['碰撞箱'][0].up, pos1, part.before.position.z - parts['车身'][0].before.position.z) part.position.copy(pos1) part.meshOrientation.copy(parts['车身'][0].meshOrientation) var angle = parts['碰撞箱'][0].angle var up = parts['碰撞箱'][0].up var raycast = world.raycast(part.position, new Box3Vector3( Math.cos(angle) * Math.cos(up), Math.sin(up), Math.sin(angle) * Math.cos(up) ), { ignoreEntities: true, maxDistance: parts['碰撞箱'][0].bounds.z * 3 }) var raycast1 = world.raycast(part.position, new Box3Vector3( 0, -1, 0 ), { ignoreEntities: true, maxDistance: parts['碰撞箱'][0].bounds.y * 3 }) if (raycast.hitVoxel != 0 && raycast1.hitVoxel != 0) { parts['碰撞箱'][0].up += 0.3; } else { if (raycast1.hitVoxel == 0) { parts['碰撞箱'][0].up -= 0.1 } else { if (raycast.hitVoxel == 0) { parts['碰撞箱'][0].up *= 0.95; } } } if (Math.abs(parts['碰撞箱'][0].up) < 0.03) { parts['碰撞箱'][0].up = 0; } if (parts['碰撞箱'][0].up > 1.2) { parts['碰撞箱'][0].up = 1.2 } if (parts['碰撞箱'][0].up < -Math.PI / 2 + 0.1) { parts['碰撞箱'][0].up = -Math.PI / 2 + 0.1 } } } } } function getAngle(entity, num, followEntity = new Box3Entity) {//目标方向,目前方向,旋转角度(单次) let angle1 = entity.direction; if (angle1 < 0) { angle1 = Math.PI * 2 + angle1; } if (entity.angle < 0) { entity.angle = Math.PI * 2 + entity.angle; } entity.angle %= Math.PI * 2; const angle2 = entity.angle; if (Math.min(Math.abs(angle1 - angle2), Math.abs(Math.PI * 2 - angle1 + angle2)) < num) { entity.angle = entity.direction; } else { if (angle1 > angle2) { if (angle1 - angle2 < Math.PI) { entity.angle += num; if (followEntity.angle) { followEntity.angle += num } } else { entity.angle -= num; if (followEntity.angle) { followEntity.angle -= num } } } else { if (angle1 + (Math.PI * 2 - angle2) < Math.PI) { entity.angle += num; if (followEntity.angle) { followEntity.angle += num } } else { entity.angle -= num; if (followEntity.angle) { followEntity.angle -= num } } } } } function getColor(name = '') { var color = new Box3RGBAColor(0, 0, 0, 255) if (name == '红队' || name == '红') { color = new Box3RGBAColor(255, 0, 0, 255) } if (name == '蓝队' || name == '蓝') { color = new Box3RGBAColor(0, 255, 0, 255) } return color } world.onPlayerJoin(({ entity }) => { entity.position.set(128, 20, 128) entity.player.cameraDistance = 20; createTank(entity.position, '虎式坦克', entity, '红队')//开坦克 }); world.onPress(async ({ entity, button }) => { if (entity.tank != undefined) { var speedState = entity.tank['碰撞箱'][0].speedState if (button == "jump") { while (entity.player.jumpButton) { if (speedState < 100) { speedState += 10 entity.player.directMessage(`目前速度:${speedState}/100格`) } else { break; } await sleep(200) } } if (button == "crouch") { while (entity.player.crouchButton) { if (speedState > -50) { speedState -= 10 entity.player.directMessage(`目前速度:${speedState}/100格`) } else { break; } await sleep(200) } } entity.tank['碰撞箱'][0].speedState = speedState } }) function getMoren(num = 0, moren = 0, cannot = undefined) {//获取默认值,防止undefined if (num == cannot) { return moren } else { return num } }; (async function () {//主循环 world.time = 0; for (; ;) { await sleep(100); world.time += 1; for (let e of world.querySelectorAll('player')) { if (e.tank != undefined) { checkTankPartPosition(e.tank) e.position.copy(e.tank['碰撞箱'][0].position) } } } })()