【JS球球大作战项目实战】+在线体验

这篇具有很好参考价值的文章主要介绍了【JS球球大作战项目实战】+在线体验。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【JS球球大作战项目实战】+在线体验,python 小游戏,javascript,notepad++,开发语言



个人名片:

【JS球球大作战项目实战】+在线体验,python 小游戏,javascript,notepad++,开发语言


🐼作者简介:一名大三在校生,喜欢AI编程🎋
🐻‍❄️个人主页🥇:落798.
🐼个人WeChat:hmmwx53
🕊️系列专栏:🖼️

  • 零基础学Java——小白入门必备🔥
  • 重识C语言——复习回顾🔥
  • 计算机网络体系———深度详讲
  • HCIP数通工程师-刷题与实战🔥🔥🔥
  • 微信小程序开发——实战开发🔥
  • HarmonyOS 4.0 应用开发实战——实战开发🔥🔥🔥
  • Redis快速入门到精通——实战开发🔥🔥🔥
  • RabbitMQ快速入门🔥
    🐓每日一句:🍭我很忙,但我要忙的有意义!
    欢迎评论 💬点赞👍🏻 收藏 📂加关注+



BallBattle

简介

《球球大作战》是一款由巨人网络Superpop&Lollipop工作室自主研发,并且免费(不包括道具)的手机网络游戏。2015年5月27日由巨人网络在中国大陆发行。

【JS球球大作战项目实战】+在线体验,python 小游戏,javascript,notepad++,开发语言

游戏以玩家间的实时互动PK为设计宗旨,通过简单的规则将玩家操作直接转化为游戏策略,体验智谋碰撞的战斗乐趣。在这个球球的世界里,每个人都化身为一颗独特的球球,大球吃小球,努力生存下来就是唯一的目标。

线上体验

背景设定

在宇宙深处一片遍布着荆棘之花的神秘星云中,生活着一群名叫“波拉哩”(译名“球球”)的奇特生物。他们外表萌萌,却有着勇敢的心。他们是天生的战斗种族,为战斗而生,为战斗而亡。

传说中,这群波拉哩的共同祖先是一只叫“塔坦”的超级波拉哩,塔坦的职责就是守护宇宙瑰宝“荆棘之花”,它拥有强大的能量,会分出分身,变化万物,唯一的弱点就是贪吃。

一天,塔坦终于禁不住诱惑,偷食了“荆棘之花”,结果身体爆裂,成为了数以亿计的小波拉哩。从此,波拉哩的族群就受到了贪食的诅咒,只能在这片星云中无休止的战斗,如果停止战斗,生命便会流失,消亡在茫茫的星空之中。在漫漫的历史长河里,只有最强大的波拉哩才能冲过这片黑暗星云,打破命运的枷锁,去寻找那传说中的光明与和平。

为了那甜蜜的希望,波拉哩们战斗着。他们必须奋力奔跑,让自己变大变大再变大,才能对抗比自己更强的存在。哪怕经历无数失败也必须重新凝聚力量,直到成为最强壮的那个。

【JS球球大作战项目实战】+在线体验,python 小游戏,javascript,notepad++,开发语言

玩法

输入房间 ID,加入房间(如果没有此房间,则创建)。
用户 ID 随机生成。
使用 ⬆️⬇️⬅️➡️ 或 WSAD 来控制小球移动,吃掉场景中的食物(三角形,方形,六边形)则会增长体重(并减少速度);遇到其他球(玩家),碰撞之后,体重较大者获胜,较小者将会死亡并重生。
右侧面板显示当前房间的玩家体重排行榜。

主要功能

匹配对战

最基础的房间 ID 匹配。

更多关于房间匹配文档

属性同步与保存

这个 demo 使用的是 Master Client 机制,但由于 Master Client 可能存在掉线等异常情况,所以需要将房间和玩家的部分数据保存至 Room Properties 和 Player Properties。

更多关于属性同步文档

房间属性
  • 房间用时
  • 战场的食物列表
  • 食物最大 ID

食物:

/**
 * 食物
 */
cc.Class({
  extends: cc.Component,

  properties: {
    id: 0,
    type: 0
  },

  getProperties() {
    const id = this.id;
    const type = this.type;
    const { x, y } = this.node.position;
    return {
      id,
      type,
      x,
      y
      // 可能还会有能量值
    };
  }
});
玩家属性
  • 位置
  • 体重
  • 速度

球:

const Constants = require("Constants");
const Food = require("./Food");

/**
 * 球
 */
cc.Class({
  extends: cc.Component,

  properties: {
    nameLabel: {
      type: cc.Label,
      default: null
    },
    infoLabel: {
      type: cc.Label,
      default: null
    }
  },

  init(player) {
    this.player = player;
  },

  eat() {
    // 计算尺寸
    const { weight } = this.player.customProperties;
    const scale = Math.sqrt(weight) / Constants.BORN_SIZE;
    this.node.scale = cc.v2(scale, scale);
  },

  reborn() {
    // 计算尺寸
    const { weight, pos } = this.player.customProperties;
    const scale = Math.sqrt(weight) / Constants.BORN_SIZE;
    this.node.scale = cc.v2(scale, scale);
    // 位置
    const { x, y } = pos;
    this.node.position = cc.v2(x, y);
  },

  getId() {
    return this.player.actorId;
  },

  getSpeed() {
    const { speed } = this.player.customProperties;
    return speed;
  },

  getWeight() {
    const collider = this.node.getComponent(cc.CircleCollider);
    const { radius } = collider;
    const { scaleX, scaleY } = this.node;
    return Constants.PI * Math.pow(radius, 2) * scaleX * scaleY;
  },

  // LIFE-CYCLE CALLBACKS:

  start() {
    this.nameLabel.string = this.player.userId;
  },

  update(dt) {
    const { x, y } = this.node;
    this.infoLabel.string = `(${parseInt(x)}, ${parseInt(y)})`;
  },

  // 碰撞
  onCollisionEnter(other, self) {
    const { group: otherGroup } = other.node;
    if (otherGroup === Constants.FOOD_GROUP) {
      this._onCollideFood(other, self);
    } else if (otherGroup === Constants.BALL_GROUP) {
      this._onCollideBall(other, self);
    }
  },

  _onCollideFood(other, self) {
    // 球碰食物,客户端模拟
    const { node: foodNode } = other;
    const { x, y } = self.node.position;
    cc.log(`collide food: (${x}, ${y})`);
    const food = foodNode.getComponent(Food);
    foodNode.active = false;
    // 交由 Master 处理
    const event = new cc.Event.EventCustom(
      Constants.BALL_AND_FOOD_COLLISION_EVENT,
      true
    );
    event.detail = {
      ball: this,
      food
    };
    this.node.dispatchEvent(event);
  },

  _onCollideBall(other, self) {
    const { node: b1Node } = other;
    const { node: b2Node } = self;
    const event = new cc.Event.EventCustom(
      Constants.BALL_AND_BALL_COLLISION_EVENT,
      true
    );
    event.detail = {
      b1Node,
      b2Node
    };
    this.node.dispatchEvent(event);
  }
});

自定义事件

  • 玩家出生:对于当前玩家,执行战场初始化逻辑;对于其他玩家,执行增加玩家逻辑。
  • 吃食物:客户端移除内存中的食物节点,同步玩家体重。
  • 杀死玩家:用于同步节点间碰撞事件。
  • 玩家重生:用于重新初始化玩家数据。
  • 生成食物:同步房间内的食物数据。
  • 玩家离开:用于移除场景和 UI 对应节点。
  • 游戏结束:用于返回主菜单场景。

其他功能

消息处理控制

由于从主场景加载到战斗场景,存在异步的资源加载过程,所以需要暂停 / 恢复消息队列的处理。流程如下:

  • 加入房间
  • 暂停消息处理
  • 加载战斗场景
  • 初始化战场
  • 恢复消息队列。
移动同步

移动同步实现思路是玩家在运动状态改变时,将当前运动状态同步给其他客户端,其他客户端对玩家行为进行模拟。而在运动过程中,并不同步移动数据。

运动状态包括:

  • 位置
  • 移动方向
  • 时间戳

模拟步骤:

  • 在收到运动状态改变时,根据运动改变时的位置,方向,以及当前时间戳与运动改变时的时间戳的差值,计算出当前应该所在的位置 p0
  • 玩家节点当前实际所在位置 p1,p0 - p1(向量减法),即为校正后的运动路径
  • 对路径进行模拟,直至下次运动状态改变

球控制器,当前客户端需要添加组件,由用户输入直接移动,并触发移动同步

const Ball = require("Ball");
const Constants = require("../Constants");
const LeanCloud = require("../LeanCloud");

const { getClient } = LeanCloud;

/**
 * 球控制器,当前客户端需要添加组件,由用户输入直接移动,并触发移动同步
 */
cc.Class({
  extends: cc.Component,

  properties: {},

  // LIFE-CYCLE CALLBACKS:

  onLoad() {
    cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this._onKeyDown, this);
    cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, this._onKeyUp, this);
    this._ball = this.node.getComponent(Ball);
    this._direction = cc.Vec2.ZERO;
  },

  onDestroy() {
    cc.systemEvent.off(
      cc.SystemEvent.EventType.KEY_DOWN,
      this._onKeyDown,
      this
    );
    cc.systemEvent.off(cc.SystemEvent.EventType.KEY_UP, this._onKeyUp, this);
  },

  start() {
    this._cameraNode = cc.find("Canvas/Main Camera");
  },

  update(dt) {
    const speed = this._ball.getSpeed();
    const delta = this._direction.normalize().mul(speed * dt);
    const position = this.node.position.add(delta);
    const { x, y } = position;
    const { LEFT, RIGHT, TOP, BOTTOM } = Constants;
    const newPosition = cc.v2(
      Math.min(Math.max(x, LEFT), RIGHT),
      Math.min(Math.max(y, BOTTOM), TOP)
    );
    this.node.position = newPosition;
    // 设置摄像机跟随
    this._cameraNode.position = this.node.position;
  },

  _onKeyDown(event) {
    this.running = true;
    let dir = this._direction.clone();
    switch (event.keyCode) {
      case cc.macro.KEY.a:
      case cc.macro.KEY.left:
        dir.x = -1;
        break;
      case cc.macro.KEY.d:
      case cc.macro.KEY.right:
        dir.x = 1;
        break;
      case cc.macro.KEY.w:
      case cc.macro.KEY.up:
        dir.y = 1;
        break;
      case cc.macro.KEY.s:
      case cc.macro.KEY.down:
        dir.y = -1;
        break;
      default:
        break;
    }
    this._synchMove(dir.normalize());
  },

  _onKeyUp(event) {
    let dir = this._direction.clone();
    switch (event.keyCode) {
      case cc.macro.KEY.a:
      case cc.macro.KEY.left:
      case cc.macro.KEY.d:
      case cc.macro.KEY.right:
        dir.x = 0;
        break;
      case cc.macro.KEY.w:
      case cc.macro.KEY.up:
      case cc.macro.KEY.s:
      case cc.macro.KEY.down:
        dir.y = 0;
        break;
      default:
        break;
    }
    this._synchMove(dir.normalize());
  },

  _synchMove(dir) {
    if (dir.fuzzyEquals(this._direction, 0.01)) {
      return;
    }
    this._direction = dir;
    const { x, y } = this.node.position;
    const { x: dx, y: dy } = this._direction;
    const client = getClient();
    client.player.setCustomProperties({
      move: { p: { x, y }, d: { x: dx, y: dy }, t: Date.now() }
    });
  }
});

项目结构

├── Animation 动画目录
├── Prefabs 预制目录,主要存放球,食物预制体
├── Scene 场景目录,主菜单场景,战斗场景
├── Script 脚本目录
│   ├── Battle 战斗相关脚本目录
│   │    ├── Ball.js 球节点控制脚本
│   │    ├── BallController.js 玩家控制球脚本,生成移动数据同步给其他客户端
│   │    ├── BallSimulator.js 玩家运动模拟脚本,根据玩家运动数据,模拟运动行为
│   │    ├── Battle.js 战场节点总控制器,用于接收并解析战斗中的自定义事件,驱动场景节点及 UI 节点变化
│   │    ├── BattleHelper.js 战场工具脚本
│   │    ├── Food.js 食物节点控制脚本
│   │    ├── Master.js 游戏逻辑脚本,用于区分 Master 客户端与普通客户端,Master 组件用于生成房间数据及逻辑判断,只有 Master 的客户端才拥有这个组件,包括最初的房间的创建者和切换后的新房主。
│   │    ├── PlayerInfoItem.js 玩家信息 UI 节点控制脚本
│   │    └── UI.js UI 控制脚本
│   ├── Menu主菜单相关脚本目录
│   │    └── Menu.js 主菜单脚本
│   ├── Constants.js 游戏中用到的常量
│   └── LeanCloud.js 全局存放 LeanCloud SDK 对象的脚本
├── Texture 素材资源目录
└── play.js LeanCloud 实时对战服务 SDK

添加wx/微信公众回复球球大作战获取完整代码

在线体验链接


欢迎评论 💬点赞👍🏻 收藏 📂加关注+



【JS球球大作战项目实战】+在线体验,python 小游戏,javascript,notepad++,开发语言

欢迎添加微信,加入我的核心小队,请备注来意

👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇文章来源地址https://www.toymoban.com/news/detail-845426.html

到了这里,关于【JS球球大作战项目实战】+在线体验的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【开源游戏】Legends-Of-Heroes 基于ET 7.2的双端C#(.net7 + Unity3d)多人在线英雄联盟风格的球球大作战游戏。

    FlameskyDexive/Legends-Of-Heroes: A battle of balls game, lol style. 基于ET 7.2的双端C#(.net7 + Unity3d)多人在线英雄联盟风格的球球大作战。 (github.com)  一个LOL风格的球球大作战游戏,基于ET7.2,使用状态同步  基于C#双端框架[ET7.2],同步到ET主干详情请看日志。(https://github.com/egametang/ET) 注意:

    2024年02月03日
    浏览(59)
  • 【C++/C 实现球球大作战】

    这篇文章主要为大家详细介绍了C语言实现——《球球大作战项目》,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。 游戏介绍: 这是一个大球吃小球的世界,玩家的目标是要努力吃成最大的球球。在游戏一开始,玩家出现在地图上随机

    2024年02月09日
    浏览(31)
  • 基于C++的简易版《球球大作战》游戏设计

    全套资料下载地址:https://download.csdn.net/download/sheziqiong/85602628 全套资料下载地址:https://download.csdn.net/download/sheziqiong/85602628 《球球大作战》虽然在玩法上类似于大球吃小球的模式看起来很单薄。但是在游戏过程中会出现无数种意外情况,这就需要玩家运用一系列策略来达到

    2024年02月10日
    浏览(43)
  • 球球大作战 旋转合球脚本 - 用于蓝蝶模拟器(blueStacks5)

    键位截图 JS代码 下面是生成好的蓝蝶脚本代码,仅供参考

    2024年02月12日
    浏览(144)
  • 【C/C++小游戏】2048 大作战!(基于Easyx图形窗口实现)

    写在前面 游戏简介 Easyx 图形库 编写游戏 预编译代码 第一步:初始化棋盘 第二步:绘制棋盘 第三步:用户操作 第四步:封装函数 完整代码 效果展示 大家好! 本人是一个12岁六年级小学生,今年9月开始学习C++,曾经学过1年Python。 这是我的第一篇博客,决定分享一个游戏

    2024年02月10日
    浏览(45)
  • pygame小游戏之飞机拼音大作战( 送给娃学拼音的礼物,星际旅行)

    二娃再过一年就该上一年级了,但现阶段的拼音咋都学不进去。买了拼音挂图贴在墙上,拉都拉不到旁边。突发奇想,何不用python的pygame做个小游戏?在玩中也能学习,让学变得有趣!这对搞编程的来说小菜一碟,于是说干就干,两个晚上就成型啦,这里总结分享给有需要的

    2024年02月09日
    浏览(45)
  • 端午节安康,佬们都了解端午节的哪些知识呢(附粽子大作战小游戏)

    前言: 端午节假期, 首先祝各位小伙伴儿们端午节安康 。参考了一些资料,本篇文章将和大家分享关于端午节的由来,习俗,以及关于端午节的一个代码小游戏–粽子大作战。 希望大家看完此篇文章能对端午节有收获,也希望小伙伴儿们在这个特殊的节日里包括以后开开心

    2024年02月10日
    浏览(46)
  • C语言实战项目-贪吃蛇小游戏

    1.定义蛇对象、食物对象 2.初始化蛇、初始化食物 3.控制流程: ( 1)蛇头和墙壁的碰撞 (2)蛇头和蛇身体碰撞 (3)蛇头和食物碰撞 (4)移动速度增大 4.游戏效果: ( 1)蛇身增长 (2)食物消失 -- 新食物产生 (3)分数累加 (4)移动速度增大 (5)蛇的移动 (6)显示分

    2024年02月19日
    浏览(48)
  • C/C++项目实战-推箱子小游戏

    2024年02月08日
    浏览(52)
  • C语言结课实战项目_贪吃蛇小游戏

    ✨✨所属专栏:C语言✨✨ ✨✨作者主页:嶔某✨✨ 游戏源代码链接: function/贪吃蛇 · 钦某/c-language-learning - 码云 - 开源中国 (gitee.com) • 贪吃蛇地图绘制 • 蛇吃⻝物的功能(上、下、左、右⽅向键控制蛇的动作) • 蛇撞墙死亡 • 蛇撞⾃⾝死亡 • 计算得分 • 蛇⾝加速、

    2024年04月26日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包