用户:
AB骉Alobok查看:0 回复:3 评论:0 创建时间:2021-05-18T18:57:40
world.onPlayerJoin(({ entity }) => {
entity.player.enable3DCursor = true // 开启方块光标
})
world.onPress(({ raycast, button }) => {
if (button === Box3ButtonType.ACTION0) {
const pos = raycast.voxelIndex // 射线指到的方块位置
voxels.setVoxel(pos.x, pos.y, pos.z, '')
}
})
world.onPlayerJoin(({ entity }) => {
entity.player.enable3DCursor = true // 开启方块光标
})
world.onPress(({ raycast, button }) => {
if (button === Box3ButtonType.ACTION0) {
const pos = raycast.voxelIndex.add(raycast.normal) // 射线指到的方块位置加上被选中的面的法线向量
voxels.setVoxel(pos.x, pos.y, pos.z, 'stone')
}
})
const voxelList = ['stone', 'dirt', 'grass', 'lava01'] // 可选方块
world.onPlayerJoin(({ entity }) => {
entity.selected = 0 // 当前选定方块的序号
entity.player.enable3DCursor = true // 开启方块光标
})
world.onPress(({ entity, raycast, button }) => {
if (button === Box3ButtonType.ACTION0) {
const vox = voxelList[entity.selected]
const pos = raycast.voxelIndex.add(raycast.normal) // 射线指到的方块位置加上被选中的面的法线向量
voxels.setVoxel(pos.x, pos.y, pos.z, vox)
}
else if (button === Box3ButtonType.ACTION1) {
entity.selected = (entity.selected + 1) % voxelList.length
const vox = voxelList[entity.selected]
entity.player.directMessage(`当前选定"${vox}"`)
}
})
world.onPlayerJoin(({ entity }) => {
entity.player.enable3DCursor = true // 开启方块光标
entity.selected = 'stone' // 玩家当前选定dirt方块
})
world.onPress(async ({ entity, raycast, button }) => {
if (button === Box3ButtonType.ACTION0) {
const pos = raycast.voxelIndex.add(raycast.normal) // 射线指到的方块位置加上被选中的面的法线向量
voxels.setVoxel(pos.x, pos.y, pos.z, entity.selected)
}
else if (button === Box3ButtonType.ACTION1) {
const selection = await entity.player.dialog({
type: Box3DialogType.SELECT,
content: '选择方块类型',
options: ['stone','dirt','grass','lava01','snow'],
})
if (selection) {
entity.selected = selection.value // 更新玩家当前选定方块
}
}
})
console.clear()
var DefaultScale = [0.0625,0.0625,0.0625];
var Quat = new Box3Quaternion(0,0,0,1);
var score = 0
function spawn(x,y,z,meshName){
if(world.entityQuota()<=0){return}//如果可分配的实体小于等于0, 就不再创建新的模型
var entity = world.createEntity({
mesh:meshName,//模型名
collides:true,//能碰撞
fixed:false,//固定
gravity:true,//受重力下落
meshScale:DefaultScale,//模型放大倍数
position:[x,y,z],//位置坐标
friction:0.5,//摩擦力
})
entity.enableDamage = true //允许公鸡受伤
entity.onVoxelContact(({x,y,z,voxel})=>{//当公鸡碰到地形方块
//当公鸡落地后, 随机改变移动速度
entity.velocity.y = 0.5 + Math.random()*0.5
entity.velocity.x = (Math.random()-0.5)*0.5
entity.velocity.z = (Math.random()-0.5)*0.5
if(voxel===voxels.id('stone')){//如果公鸡碰到了石头方块, 什么也不发生
}else if(voxel===voxels.id('lava02')){//如果公鸡碰到了岩浆
entity.hurt(40)//公鸡扣40生命
}else{
voxels.setVoxel(x,y,z,'')//公鸡可以破坏其他类型的方块
}
})
var handler = world.onTick(()=>{//计时循环, 每秒更新16次公鸡的朝向
entity.meshOrientation = Quat.rotateY(Math.atan2(entity.velocity.z,entity.velocity.x))//公鸡朝向自己的移动方向
})
entity.onDie(()=>{//当公鸡喵亡(enitity.hp<=0)
entity.destroy()//删除公鸡实体
score++;
world.say('已经收拾了 '+score+' 只公鸡')
})
entity.onDestroy(()=>{//当公鸡实体被删除
handler.cancel()//取消控制公鸡朝向的计时循环
})
return entity
}
for(var i=0;i<250;i++){//生成 250 只公鸡模型实体
spawn(63,11+i,63,'mesh/公鸡.vb')
}
world.onPlayerJoin(({entity})=>{//当有新玩家进入游戏
entity.enableDamage=true//允许玩家受伤
entity.onVoxelSeparate(({x,y,z,voxel})=>{//玩家离开方块的时候
// spawn(x+0.5,y+1.5,z+0.5,'mesh/公鸡.vb')//在离开的方块留下公鸡模型
voxels.setVoxel(x,y+1,z,'lava02')//岩浆突出到地面
})
})
world.onPlayerLeave(({entity})=>{//当有玩家离开游戏
world.say('恭送 '+entity.player.name)//世界广播
})
world.onChat(({entity, message})=>{//当有玩家在输入框发送消息
if(message==='1'){//如果那名玩家输入的是 1
//让所有实体对你说欢迎
var allEntities = world.querySelectorAll('*');
for(var e of allEntities){
if(e.isPlayer){continue}//如果实体是玩家, 就跳过
e.say('欢迎 '+entity.player.name)
}
}else if(message==='2'){
//让位置在(60,0,60)~(70,120,70)之间的实体对你说欢迎
var foundEntities = world.searchBox(new Box3Bounds3(
new Box3Vector3(60,0,60),
new Box3Vector3(70,120,70),
))
for(var e of foundEntities){
if(e.isPlayer){continue}//如果实体是玩家, 就跳过
e.say('hello '+entity.player.name)
}
}else if(message==='复活'){
entity.hp = entity.maxHp
entity.position.x = 10
entity.position.y = 50
entity.position.z = 10
}
})
console.clear()
for (const e of world.querySelectorAll('.瓶盖垃圾,.空瓶垃圾')) { //遍历每一个废品实体
e.enableInteract = true //开启交互
e.interactRadius = 2.5 //交互范围
e.interactHint = e.tags() //交互提示文本显示标签名
e.interactColor.set(0, 1, 0) //交互提示文本设为绿色
e.onInteract(({ entity }) => {
entity.junk += 1 //累加废品
e.destroy() //从地图中删除实体
//跟world.say相似, 但只对指定的玩家显示信息而不是对所有玩家广播
entity.player.directMessage(`${entity.player.name} 累计捡到${entity.junk}个废品`)
})
}
//封装成函数是因为它会被多次用到(显示玩家状态, 显示与NPC交互结果)
function textDialog(entity, content, title) {
return entity.player.dialog({ //弹出对话框
type: Box3DialogType.TEXT, //对话框类型为纯文本
content, //文本内容
title, //对话框左上角标题内容
})
}
world.onPlayerJoin(({ entity }) => {//每次玩家进入游戏都会运行
entity.money = 0 //钱
entity.junk = 0 //废品
entity.itemList = [] //口袋里的货品
loadPlayer(entity)
entity.player.onPress(async ({ button }) => { //每当有按钮被按下
if (button == Box3ButtonType.ACTION1) { //如果按钮是右键
const selection = await entity.player.dialog({
type: Box3DialogType.SELECT, //对话框类型为选择框
content: `你身上有:\n\n${entity.money}元, ${entity.junk}个废品\n道具: [${entity.itemList}]`,
options: ['保存'],
})
if (selection) { //确保对话框不是点击x关闭
if (selection.value === '保存') { //被点击的是保存按钮
await savePlayer(entity) //等待写入结束才运行下一行
textDialog(entity, '保存完毕')
}
}
}
else if (button == Box3ButtonType.ACTION0) { //如果按钮是左键
const eaten = entity.itemList.pop() //口袋列表最右边的一个物品拿出来
if (eaten) {
entity.player.directMessage(`${entity.player.name}吃掉了"${eaten}"`)
}
}
})
})
world.breakVoxelSound=world.placeVoxelSound=''
//NPC是non-player character的简称, 表示游戏里无人控制的虚构人物
for (const npc of world.querySelectorAll('.NPC')) {
npc.enableInteract = true //允许当前npc实体触发交互
npc.interactRadius = 4.5 //交互范围
npc.interactHint = npc.id //交互提示文本显示实体名字
npc.interactColor.set(0, 1, 0) //交互提示文本颜色为绿色
if (npc.id == '学生') { //如果实体名是'学生'
npc.onInteract(async ({ entity }) => { //当玩家对这个npc按E触发交互, npc对玩家打招呼
textDialog(entity, `${entity.player.name}, 你好呀~`, npc.id)
})
}
else if (npc.id == '回收处员工') { //如果实体名是'回收处员工'
npc.onInteract(async ({ entity }) => { //当玩家对这个npc按E触发交互, npc问你想卖多少废品
const amount = await entity.player.dialog({
type: Box3DialogType.INPUT, //对话框类型为输入框
content: `你有${entity.junk}废品, 想卖掉多少呢?`,
title: npc.id, //对话框左上角显示NPC名字
})
if (amount > 0 && amount <= entity.junk) { //如果持有的废品数符合输入的数值
entity.junk -= amount //交出废品
const gain = 2 * amount //废品换算成钱
entity.money += gain //钱入账到玩家
textDialog(entity, `${amount}废品卖得${gain}元`)
}
})
}
else if (npc.id == '小卖部老板') { //如果实体名是'小卖部老板'
npc.onInteract(async ({ entity }) => { //当玩家对这个npc按E触发交互, npc问你想买哪些商品
const goodsList = ['薯片', '可乐', '糖果'] //货品列表
const priceList = [7, 5, 4] //价格列表
const selection = await entity.player.dialog({
type: Box3DialogType.SELECT, //对话框类型为选择框
content: `你有${entity.money}元, 想买点什么呢?`,
title: npc.id, //对话框左上角显示NPC名字
options: ['薯片 (7元)', '可乐 (5元)', '糖果 (4元)', '离开'], //选项
})
if (selection) { //如果玩家没有点击'x'关闭对话框
const goods = goodsList[selection.index] //被选中的货物
const price = priceList[selection.index] //被选中货物的价格
if (entity.money >= price) { //如果玩家的钱足够
entity.money -= price //扣钱
entity.itemList.push(goods) //货物装进玩家口袋列表最右边
textDialog(entity, `"${goods}"入手`)
} else {
textDialog(entity, `要买"${goods}"还差${price - entity.money}元`)
}
}
})
}
}
async function savePlayer(entity) {//定义保存玩家状态的函数
if (entity.player.userKey) {//拥有userKey的玩家, 则玩家不是游客, 可以保存
await db.sql`
--尝试向player表插入一条记录, 向各个字段写入玩家身上对应的属性值
INSERT INTO player (
userName,
money,
junk,
itemList,
userKey
)
VALUES(
${entity.player.name},
${entity.money},
${entity.junk},
${JSON.stringify(entity.itemList)},--itemList是数组, 需要用JSON.stringify才能存入类型为TEXT的字段
${entity.player.userKey}
)
ON CONFLICT(userKey)--如果玩家记录已经存在, 则不需要插入, 而是更新各个字段的值
DO UPDATE SET
userName=excluded.userName,
money=excluded.money,
junk=excluded.junk,
itemList=excluded.itemList
`
}
}
async function showPlayers() {
console.clear() // 清空控制台
const playerList = await db.sql`SELECT * FROM player`
for (const p of playerList) {
console.log(JSON.stringify(p))
}
}
async function createTable() {
await db.sql`
CREATE TABLE IF NOT EXISTS player (
money INTEGER DEFAULT 0,--金钱, INTEGER类型用于存储整数
junk INTEGER DEFAULT 0,--废品, INTEGER类型用于存储整数
itemList TEXT DEFAULT '',--道具列表, TEXT类型用于存储字符串
userKey TEXT PRIMARY KEY UNIQUE DEFAULT ''--玩家的唯一识别码, TEXT类型用于存储字符串
)
`
showPlayers() //每次运行代码都能查看数据库里所有记录
}
async function loadPlayer(entity) {
const data = (await (db.sql`SELECT * FROM player WHERE userKey=${entity.player.userKey} limit 1`))[0]
if (data) { //如果存在这个玩家的存档
entity.money = data.money //恢复金钱
entity.junk = data.junk //恢复废品
entity.itemList = JSON.parse(data.itemList) //恢复道具列表, 这里的JSON.parse用于把字符串变回数组
}
}
async function showPlayers() {
console.clear() // 清空控制台
const playerList = await db.sql`SELECT * FROM player`
for (const p of playerList) {
console.log(JSON.stringify(p))
}
}
async function createTable() {
await db.sql`CREATE TABLE IF NOT EXISTS player (
userName TEXT DEFAULT '',--玩家名字
money INTEGER DEFAULT 0,--金钱
junk INTEGER DEFAULT 0,--废品
itemList TEXT DEFAULT '',--道具列表
userKey TEXT PRIMARY KEY UNIQUE DEFAULT ''--玩家的识别码
)`
showPlayers()
}
createTable()
for(let x=0; x<127; x++){
for(let z=0; z<127; z++){
const vn = Math.random()*2;
if(vn > 0.5){
voxels.setVoxel(x, 8, z, 'O')
}else{
voxels.setVoxel(x, 8, z, 'I')
}
}}
(Math.random()*20,11,Math.random()*20)
//生成一个小方块
voxels.setVoxel(喵,9,喵,'stone')
//方块变柱子
for(var y=9;y<19;y++){
voxels.setVoxel(喵,y,喵,'stone')
}
//柱子变墙
for(var y=9;y<19;y++){
for(var x=喵;x<74;x++){
voxels.setVoxel(x,y,喵,'stone')
}
}
//墙变立方体
for(var y=9;y<19;y++){
for(var x=喵;x<74;x++){
for(var z=喵;z<74;z++){
voxels.setVoxel(x,y,z,'stone')
}
}
}
//空心碉堡
function cube(sx,sy,sz,x_size,y_size,z_size,vox){ //s_x代表star_x
var ex = sx+x_size //e_x代表end_x
var ey = sy+y_size
var ez = sz+z_size
for(var x=sx;x<ex;x++){
for(var y=sy;y<ey;y++){
for(var z=sz;z<ez;z++){
voxels.setVoxel(x,y,z,vox)
}
}
}
}
cube(63,9,63,10,10,10,'stone')
cube(喵,11,喵,9,6,9,'')
(async function () {
for (let i = 0; i < 128; i++) {
for (let j = 0; j < 1; j++) {
for (let k = 0; k < 128; k++) {
voxels.setVoxel(i, j, k, 'stone')
}
}
}
for (let i = 0; i < 128; i++) {
for (let j = 1; j < 8; j++) {
for (let k = 0; k < 128; k++) {
voxels.setVoxel(i, j, k, 'dirt')
}
}
}
for (let i = 0; i < 128; i++) {
for (let j = 8; j < 9; j++) {
for (let k = 0; k < 128; k++) {
voxels.setVoxel(i, j, k, 'grass')
}
}
}
for (let i = 0; i < 128; i++) {
for (let j = 9; j < 1000; j++) {
for (let k = 0; k < 128; k++) {
voxels.setVoxel(i, j, k, 'dirt')
}
}
}
})()
(async function () {
for (let i = 0; i < 128; i++) {
for (let j = 0; j < 1; j++) {
for (let k = 0; k < 128; k++) {
voxels.setVoxel(i, j, k, 'stone')
}
}
}
for (let i = 0; i < 128; i++) {
for (let j = 1; j < 8; j++) {
for (let k = 0; k < 128; k++) {
voxels.setVoxel(i, j, k, 'dirt')
}
}
}
for (let i = 0; i < 128; i++) {
for (let j = 8; j < 9; j++) {
for (let k = 0; k < 128; k++) {
voxels.setVoxel(i, j, k, 'grass')
}
}
}
for (let i = 0; i < 128; i++) {
for (let j = 9; j < 1000; j++) {
for (let k = 0; k < 128; k++) {
voxels.setVoxel(i, j, k, 'dirt')
}
}
}
})()
抄完了看看创造怎么样!!!
你可以加代码!!!