【无标题】神器代码岛,枪战代码

一个神器代码岛的枪战代码

console.clear()

console.clear()

// ------------配置------------

const DEFAULT_WEAPON = '步枪'; // 初始武器

// 队伍配置

const TEAM_CONFIG = {

    '蓝队': {

        spawnPoint: '蓝队出生点', // 出生点实体名称

        color: new GameRGBColor(1, 0, 0), // 颜色

    },

    '黄队': {

        spawnPoint: '黄队出生点',

        color: new GameRGBColor(1, 1, 0),

    },

};

// 武器配置

const WEAPON = {

    '散弹枪': {

        damage: 30, // 伤害

        distance: 10, // 射程距离

        interval: 30, // 发射间隔(数值越大, 射速越慢)

        sound: `audio/霰弹枪.mp3`,

    },

    '步枪': {

        damage: 10,

        distance: 30,

        interval: 5,

        sound: `audio/步枪.mp3`,

    },

    '狙击枪': {

        damage: 25,

        distance: 50,

        interval: 40,

        sound: `audio/狙击枪.mp3`,

    },

};

// 头部穿戴配置

const HEAD_WEARABLE_CONFIG = {

    bodyPart: GameBodyPart.HEAD,

    orientation: new GameQuaternion(0, 0, 0, 1), // 调整方向

    scale: new GameVector3(0.7, 0.7, 0.7), // 调整大小

    offset: new GameVector3(0, 0.2, 0), //调整位置

};

// 武器穿戴配置

const WEAPON_WEARABLE_CONFIG = {

    bodyPart: GameBodyPart.TORSO,

    orientation: new GameQuaternion(0, 0, 0, 1), // 装备方向

    scale: new GameVector3(0.9, 0.9, 0.9), // 调整大小

    offset: new GameVector3(0, 0.1, 0.9), //调整位置

};

// 枪口火焰配置

const MUZZLE_FLASH_CONFIG = {

    bodyPart: GameBodyPart.TORSO,

    orientation: new GameQuaternion(0, 0, 0, 1), // 装备方向

    scale: new GameVector3(0.9, 0.9, 0.9), // 调整大小

    offset: new GameVector3(-0.2, 0.3, 2.1), //调整位置

    mesh: `mesh/火花效果.vb`

};

const Quat = new GameQuaternion(0,0,0,1);

const GAME_END_TIME = 60; // 游戏结束时间, 单位秒

const GAME_END_SCORE = 10; // 游戏结束分数

const MIN_GAME_PLAYER_NUM = 2; // 最小游戏人数

const GAME_HALFTIME = 5; // 两局游戏间隔时间, 单位秒

// ----------------------------

const spawnPoint = objectMap(TEAM_CONFIG, ({spawnPoint}, team) => {

    const e = world.querySelector('#' + spawnPoint);

    return e.position.clone(); // 返回出生点位置

});

const defaultWeaponMesh = world.querySelector('#' + DEFAULT_WEAPON).mesh;

let playerState = {}; // 玩家状态

let teamScore = {}; // 队伍分数

let teamNum = {}; // 队伍人数

let gameEndResolve; // 用于结束游戏的函数

// 主函数

(async function main() {

    // 打印开始时间的日志

    console.log(`-------[${new Date().toISOString()}]--------`)

    setup(); // 初始化

    // 主循环, 不断检测并开始新的游戏

    for(;;await sleep(GAME_HALFTIME * 1000)) {

        // 检测人数

        if (world.querySelectorAll('player').length < MIN_GAME_PLAYER_NUM) {

            world.say(`当前人数不足${MIN_GAME_PLAYER_NUM}人, 无法开始游戏!`);

            continue;

        }

        // 倒计时

        world.say(`游戏即将开始!`);

        for (let i = 0; i > 0; i--) {

            await sleep(1000);

            world.say(`${i}...`);

        }

        // 开始新的一局游戏

        await start();

    }

})();

// 开始游戏

async function start() {

    console.log(`[${new Date().toISOString()}]开始新的一局游戏`);

    // 清空分数和队伍人数

    teamScore = objectMap(TEAM_CONFIG, () => 0);

    teamNum = objectMap(TEAM_CONFIG, () => 0);

    // 获取队伍名称

    const teamNames = Object.keys(TEAM_CONFIG);

    // 打乱所有玩家并执行队伍分配

    arrayShuffle(world.querySelectorAll('player')).forEach((entity, i) => {

        const teamName = teamNames[i % teamNames.length];

        joinTeam(entity, teamName);

        entity.player.directMessage(`你被分配到了${teamName}`);

    });

    // 等待游戏结束

    await new Promise(async (resolve) => {

        gameEndResolve = resolve; // 设置游戏结束函数

        await sleep(GAME_END_TIME * 1000); // 等待GAME_END_TIME秒

        resolve(); // 如果游戏没有提前结束, 就会由于到时间而结束

    });

    // 广播获胜队伍

    const winner = getMaxScore();

    world.say(`${winner}胜利, 总分: ${teamScore[winner]}`);

    let maxKd = 0; // 最高的kd

    let maxKdPlayer; // 最高kd的玩家

    // 计算每个玩家的KD并记录最高值

    for (const name in playerState) {

        const { entity, k, d } = playerState[name];

        const kd = k / (d + 1); // 计算公式: 击杀数/(死亡数+1)

        // 告知每个玩家本局的kd

        entity.player.directMessage(`你本场游戏的评分为${kd.toFixed(2)}`);

        // 更新最大kd

        if (kd > maxKd) {

            maxKd = kd;

            maxKdPlayer = name;

        }

        // 把玩家设置为非游戏状态

        entity.enableDamage = false;

        entity.player.color.set(1, 1, 1);

        removeSuit(entity);

    }

    // 广播MVP(kd最高者)

    world.say(`本场游戏MVP为@${maxKdPlayer}, 评分是${maxKd.toFixed(2)}`);

    // 清空玩家状态和结束函数

    playerState = {};

    gameEndResolve = undefined;

}

// 加入队伍

function joinTeam(entity, team) {

    teamNum[team]++; // 队伍人数+1

    // 设置玩家属性

    entity.enableDamage = true;

    // 初始化玩家状态

    playerState[entity.player.name] = {

        team,

        entity,

        weapon: DEFAULT_WEAPON,

        shootTick: 0,

        k: 0,

        d: 0,

    };

    // 装备武器

    wearSuit(entity, team, DEFAULT_WEAPON);

    // 设置出生点, 随机增加y的偏移, 避免多个玩家相撞

    const point = spawnPoint[team].add(new GameVector3(0, 10 + Math.random() * 20, 0));

    entity.player.spawnPoint.copy(point);

    entity.player.forceRespawn(); // 传送到队伍的出生点

}

// 判断是否是游戏中的玩家

function isPlayer(entity) {

    return entity && entity.isPlayer && entity.player.name in playerState;

}

// 获取最高分的队伍名称

function getMaxScore() {

    let num = 0;

    let team;

    for (const key in teamScore) {

        if (teamScore[key] > num) {

            team = key;

            num = teamScore[key];

        }

    }

    return team;

}

// 获取最低分的队伍名称

function getMinTeam() {

    let num = Infinity;

    let team;

    for (const key in teamNum) {

        if (teamNum[key] < num) {

            team = key;

            num = teamNum[key];

        }

    }

    return team;

}

// 需要隐藏的身体部件

let invisiblePart = ['head', 'torso', 'leftUpperArm', 'leftLowerArm', 'leftHand', 'rightUpperArm', 'rightLowerArm', 'rightHand'];

// 玩家部件穿戴

function wearSuit(entity, team, weapon) {

    // 隐藏指定身体部件

    for (const bodyPart of invisiblePart) {

        entity.player.skinInvisible[bodyPart] = true;

    }

    // 头部穿戴

    entity.player.addWearable({...HEAD_WEARABLE_CONFIG, mesh:`mesh/${team}头部.vb`});

    // 身体穿戴

    entity.player.addWearable({...WEAPON_WEARABLE_CONFIG, mesh:`mesh/${team}持枪胸部${weapon}.vb`});

}

// 玩家部件移除

function removeSuit(entity) {

    for (const bodyPart of invisiblePart) {

        entity.player.skinInvisible[bodyPart] = false;

    }

    for (const wearble of entity.player.wearables()) {

        entity.player.removeWearable(wearble);

    }

}

// 发射子弹

async function fireBullet(position, direction) {

    const dir = direction.clone()

    let dist = Math.sqrt(dir.x * dir.x + dir.z * dir.z)

    const rotx = Math.atan2(dir.y, dist)

    // 子弹模型本身需要旋转Math.PI / 2,在这个基础上围绕X与Y轴旋转到指定方向

    let result = Quat.rotateY(Math.PI / 2).rotateX(rotx).rotateY(Math.atan2(dir.z, dir.x))

    // 创建子弹实体

    world.createEntity({

        mesh: `mesh/子弹.vb`,

        tags: [`bullet`],

        position: position.add(new GameVector3(0, 0.65, 0)),

        collides: true,

        gravity: false,

        meshScale: new GameVector3(1 / 32 , 1 / 32 , 1 / 32 ),

        meshOrientation: result,

        velocity: dir.scale(4), // 设置子弹飞行速度

    })

}

// 展示枪口火焰(并隐藏)

async function showMuzzleFlash(entity) {

    const wearble = entity.player.addWearable(MUZZLE_FLASH_CONFIG);

    await sleep(100);

    entity.player.removeWearable(wearble);

}

// 初始化

function setup() {

    // 处理死亡

    world.onDie(async({entity, attacker}) => {

        if (!attacker || !isPlayer(entity)) return; // 不处理出无击杀者的死亡和非玩家的死亡

        // 获取死亡玩家名称和击杀者名称

        const { name } = entity.player;

        const killerName = attacker.isPlayer ? attacker.player.name : attacker.id;

        playerState[name].d++; // 死亡数+1

       

        // 如果击杀者是玩家

        if (attacker.isPlayer) {

            playerState[killerName].k++; // 击杀数+1

            teamScore[playerState[killerName].team]++; // 队伍分数+1

            // 广播死亡情况

            world.say(`@${killerName}击败了@${name}, 当前比分${Object.keys(teamScore).map((name) => `${name}:${teamScore[name]}`).join(', ')}`);

            // 判断是否达到比赛结束的比分

            if (teamScore[playerState[killerName].team] >= GAME_END_SCORE) gameEndResolve();

        }

        //3秒后复活

        await sleep(3 * 1000)

        if (entity.player.dead) {

            entity.player.forceRespawn()

        }

    });

    // 初始化玩家

    world.onPlayerJoin(({ entity }) => {

        if (gameEndResolve) {

            // 游戏已经开始, 则加入人数组少的队伍

            const team = getMinTeam()

            joinTeam(entity, team);

            world.say(`玩家@${entity.player.name}加入${team}`);

        }

        // 处理玩家鼠标点击

        entity.player.onPress(({ tick, entity, button, raycast: { hitEntity, direction, distance } }) => {

            if (entity.player.dead) return

            // 判断是否是鼠标左键, 击中实体是否是玩家, 以及击中的玩家是否死亡

            if (button === 'action0' && isPlayer(entity)) {

                // 获取双方的状态

                const state = playerState[entity.player.name];

               

                const weapon = WEAPON[state.weapon]; // 获取武器信息

                if (state.shootTick + weapon.interval > tick) return; // 小于武器间隔事件不处理

                state.shootTick = tick; // 更新射击时间(tick)

                const fireSound = {

                    'sample': weapon.sound,

                    'radius': 32,

                    'gain': 1,

                    'pitch': 1,

                    'gainRange': 0,

                    'pitchRange': 0,

                };

                // 播放发射子弹音效

                entity.sound(fireSound);

                // 发射子弹

                fireBullet(entity.position, direction);

                showMuzzleFlash(entity);

                if (isPlayer(hitEntity)) {

                    const otherState = playerState[hitEntity.player.name];

                    if (hitEntity.dead) return // 已死亡玩家不处理

                    if (state.team === otherState.team) return; // 相同队伍不处理

                    // 设置击中效果

                    hitEntity.velocity.x += direction.x;

                    hitEntity.velocity.z += direction.z;

                    // 计算伤害并应用

                    const basicDamage = Math.max(1, weapon.damage * Math.min(1, weapon.distance / distance));

                    const damage = Math.ceil(basicDamage * (1 + Math.random() * 0.3));

                    hitEntity.hurt(damage, { attacker: entity });

                }

            }

        });

    });

   

    // 收到伤害的通知

    world.onTakeDamage(({entity, damage, attacker}) => {

        if (!entity.isPlayer) return;

        const attackerName = attacker.isPlayer ? attacker.player.name : attacker.id;

        entity.player.directMessage(`[剩余HP: ${entity.hp}]: 你受到了${damage}点来自@${attackerName}的伤害`);

    });

    // 获取武器

    world.querySelectorAll('.武器').forEach((weapon)=>{

        weapon.enableInteract = true;

        weapon.interactRadius = 5;

        weapon.onInteract(({ entity }) => {

            if (isPlayer(entity) && weapon.id in WEAPON) {

                const state = playerState[entity.player.name]; // 获取玩家状态

                state.weapon = weapon.id; // 设置武器

                entity.player.directMessage(`你获得了${weapon.id}`); // 通知玩家

                // 更新装备

                removeSuit(entity);

                wearSuit(entity, state.team, weapon.id);

            }

        })

    })

    // 忽略玩家与子弹碰撞

    world.addCollisionFilter(`.bullet`, `player`);

    // 清理与实体碰撞的子弹

    world.onEntityContact(({entity, other})=>{

        if (entity.hasTag('bullet')) entity.destroy();

        if (other.hasTag('bullet')) other.destroy();

    })

    // 清理碰到方块的子弹

    world.onVoxelContact(({entity})=>{

        if (entity.hasTag('bullet')) entity.destroy();

    })

    // 清理超出地图空间的子弹

    const area = world.addZone({

        selector: '.bullet',

        bounds: {

            lo: [0, 0, 0],

            hi: [128, 64, 128],

        },

    });

    area.onLeave(({ entity }) => {

        if (entity.hasTag('bullet')) {

            entity.destroy();

        }

    });

}

// 随机打乱数组

function arrayShuffle (array) {

    for (let i = 1; i < array.length; ++i) {

        const temp = array[i];

        const x = (Math.random() * (i + 1)) | 0;

        array[i] = array[x];

        array[x] = temp;

    }

    return array;

}

// 为对象实现类似数组的map功能

function objectMap(obj, func) {

    const o = {};

    for (const key in obj) {

        o[key] = func(obj[key], key);

    }

    return o;

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
用vb做一个简单的射击游戏 Option Explicit Dim RandX As Single Dim RandY As Single Dim Score As Single Dim Thisscore As Single Dim Average As Single Dim Shot As Integer Dim Appear As Boolean Dim Distance As Single Private Sub Command1_Click() Timer1.Enabled = True Command3.Enabled = True If Command1.Enabled = True Then Command3.Caption = "暂停" End If Command4.Enabled = True End Sub Private Sub Command2_Click() If Command4.Enabled = True Then MsgBox "请先结束游戏", 48, "警告" Else End End If End Sub Private Sub Command3_Click() Command1.Enabled = False Command3.Caption = "继续" Timer1.Enabled = Not Timer1.Enabled If Timer1.Enabled = True Then Command3.Caption = "暂停" End If End Sub Private Sub Command4_Click() Timer1.Enabled = False Command3.Enabled = False Command1.Enabled = True Picture1.Cls Label1.Caption = "射击:" Label2.Caption = "平均得分:" Label3.Caption = "环数:" Label4.Caption = "总分:" Command4.Enabled = False Command3.Caption = "暂停" End Sub Private Sub Form_Load() Appear = False Timer1.Enabled = False Thisscore = 0 Score = 0 Shot = 0 End Sub Private Sub Picture1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single) Beep Shot = Shot + 1 Picture1.DrawWidth = 4 Picture1.PSet (X, Y), RGB(255, 0, 0) Distance = Sqr((X - RandX) * (X - RandX) + (Y - RandY) * (Y - RandY)) If Appear And Timer1.Enabled Then Thisscore = 5 - Int(Distance / 10) If Thisscore <= 0 Then Thisscore = 0 End If Score = Score + Thisscore Average = Int((Score / Shot) * 100) / 100 Label1.Caption = "射击:" + Str(Shot) + "发" Label2.Caption = "平均得分:" & Format(Average, "0.00") & "环" Label3.Caption = "环数:" + Str(Thisscore) + "环" Label4.Caption = "总分:" + Str(Score) + "环" End If End Sub Private Sub Timer1_Timer() Dim i As Integer Appear = Appear Xor True RandX = 500 * Rnd() RandY = 370 * Rnd() If Appear Then Form1.Picture1.AutoRedraw = True Picture1.DrawWidth = 1 Picture1.DrawStyle = 0 For i = 10 To 50 Step 10 Picture1.Circle (RandX, RandY), i, RGB(0, 0, 255) Next i Picture1.Line (RandX - 60, RandY)-(RandX + 60, RandY) Picture1.Line (RandX, RandY - 60)-(RandX, RandY + 60) Else Picture1.Cls End If End Sub
### 回答1: 代码无bug错误祈祷神器、电子木鱼以及HTML源文件是编程和网页开发中常用的工具和文件。 代码无bug错误祈祷神器通常是指编写代码时期望没有错误出现的心理暗示,类似于幽默的说法。在实际的编程过程中,我们需要仔细编写代码,对可能出现的错误进行预防和排查。然而,由于复杂的编程逻辑和不可预测的环境因素,很难保证代码没有任何错误。因此,无论是使用祈祷神器还是有效的编程实践,如测试、代码审查等,都是为了减少和解决代码错误的存在。 电子木鱼是一种电子设备,通常与传统的佛教音乐仪式中的木鱼有着相似的功能。它用来产生特定的声音,用于冥想、舒缓情绪等目的。在编程中,人们可能长时间专注于代码的编写和调试,容易产生疲劳和焦虑。使用电子木鱼等类似的工具,可以帮助人们放松身心,减轻压力,提高工作效率。 HTML源文件是网页开发中的一种文件类型,是网页内容的原始文件。HTML(超文本标记语言)是一种用于描述网页结构和内容的标记语言。在网页开发过程中,我们需要编写HTML源文件来定义网页的结构、样式和内容。通过编辑HTML代码,我们可以创建各种富有内容和交互性的网页。 总而言之,代码无bug错误祈祷神器、电子木鱼和HTML源文件是编程和网页开发中常见的工具和文件,用于减少错误、增加效率和创建优秀的网页。尽管代码是复杂和容易出错的,但通过严谨的编码实践和适当的工具,我们可以提高代码的质量和开发效率。 ### 回答2: 代码无 bug 错误祈祷神器是指一种工具或方法,可以帮助程序员在开发代码时尽可能地减少或避免出现 bug 或错误。它通常具有各种功能,包括自动化测试、代码质量检查、静态分析等,能够帮助程序员发现潜在的问题并进行修复。 电子木鱼是一种用于传统佛教念诵和冥想的设备,它通过敲击木鱼的声音和节奏来帮助修行者集中注意力、净化心灵。电子木鱼则是一种电子设备,通过模拟传统木鱼的声音和韵律,来帮助用户进行冥想。它通常可以通过电池供电,并具有不同的设置选项,例如音量调节、不同的敲击声音等。 HTML 源文件是指一个网页的原始代码文件,其中包含了网页的结构、布局和内容。HTML 是一种标记语言,用于描述和定义网页的结构和内容。通过编辑和修改 HTML 源文件,可以改变网页的外观、布局和功能。通常,使用文本编辑器或专业的 HTML 编辑器来创建和编辑 HTML 源文件。 综上所述,代码无 bug 错误祈祷神器是指一种工具或方法,帮助程序员发现和修复代码中的错误。电子木鱼是一种电子设备,通过模拟传统木鱼声音和韵律,帮助用户进行冥想。HTML 源文件是指网页的原始代码文件,用于描述和定义网页的结构和内容。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值