【从零开始学Skynet】实战篇《球球大作战》(十二):场景代码设计(上)

这篇具有很好参考价值的文章主要介绍了【从零开始学Skynet】实战篇《球球大作战》(十二):场景代码设计(上)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        场景服务会处理绝大部分的游戏逻辑。新建service/scene/init.lua,开始编写相关代码。

1、Ball类

   场景中包含小球和食物这两种对象,先看看小球的实现。代码如下所示:
--球
local balls = {} --[playerid] = ball

function ball()
    local m = {
        playerid = nil,
        node = nil,
        agent = nil,
        x = math.random( 0, 100),
        y = math.random( 0, 100),
        size = 2,
        speedx = 0,
        speedy = 0,
    }
    return m
end
  • 首先定义ballsballballs会以玩家id为索引,保存战场中各个小球的信息;
  • 小球与玩家关联,它会记录玩家id(playerid、 代理服务(agentid、代理服务所在的节点node
  • 每个球都包含x坐标、y坐标和尺寸这三种属性x, y, size,以及移动速度speedxspeedy;
  • 玩家进入战场会新建ball对象,并为其赋予随机的坐标

 下图展示了ball一些属性的含义

 【从零开始学Skynet】实战篇《球球大作战》(十二):场景代码设计(上)

   定义辅助方法balllist_msg,代码如下所示:
--球列表
local function balllist_msg()
    local msg = {"balllist"}
    for i, v in pairs(balls) do
        table.insert( msg, v.playerid )
        table.insert( msg, v.x )
        table.insert( msg, v.y )
        table.insert( msg, v.size )
    end
    return msg
end

  它会收集战场中的所有小球,并构建balllist协议。

2、Food类 

  完成了小球类,再看看食物类。定义如下代码 所示的 foods 表和 food类。
local foods = {} --[id] = food
local food_maxid = 0
local food_count = 0

--食物
function food()
    local m = {
        id = nil,
        x = math.random( 0, 100),
        y = math.random( 0, 100),
    }
    return m
end
  • 食物类food包含idx坐标y坐标这三种属性;
  • foods会以食物id为索引,保存战场中各食物的信息;
  • 为给食物赋予唯一id,定义变量food_maxid,其初始值为0,每创建一个食物,给food_maxid1
  • 变量food_count用于记录战场中食物数量,以限制食物总量。

  定义辅助方法foodlist_msg,代码如下所示:

--食物列表
local function foodlist_msg()
    local msg = {"foodlist"}
    for i, v in pairs(foods) do
        table.insert( msg, v.id )
        table.insert( msg, v.x )
        table.insert( msg, v.y )
    end
    return msg
end

   它会收集战场中的所有食物,并构建foodlist协议

 3、进入战斗

       下图 展示了进入战斗的流程, agent 收到 enter 协议(开始比赛, 图中阶段① )后,随机选择一个 scene 服务,给它发送 enter 消息(稍后实现,见图中阶段② )。 scene 和客户端的所有交互,都以 agent 作为中介。

 【从零开始学Skynet】实战篇《球球大作战》(十二):场景代码设计(上)

 现在看看scene服务的内容,定义的enter远程调用。代码如下所示:

--进入
s.resp.enter = function(source, playerid, node, agent)
    if balls[playerid] then
        return false
    end
    local b = ball()
    b.playerid = playerid
    b.node = node
    b.agent = agent
    --广播
    local entermsg = {"enter", playerid, b.x, b.y, b.size}
    broadcast(entermsg)
    --记录
    balls[playerid] = b
    --回应
    local ret_msg = {"enter",0,"进入成功"}
    s.send(b.node, b.agent, "send", ret_msg)
    --发战场信息
    s.send(b.node, b.agent, "send", balllist_msg())
    s.send(b.node, b.agent, "send", foodlist_msg())
    return true
end
  • 参数playerid指玩家id
  • 参数agentnode指玩家对应的代理服务id及其所在的节点;
  • 参数source是消息的发送方,它等同于agent
   

 实现了如下几项功能:

(1)判定能否进入战斗场景:如果玩家已在战场内,不可再次进入,返回失败信息(false)。

(2)创建ball对象:创建玩家对应的ball对象,并给各个属性赋值。

(3)向战场内的其他玩家广播enter协议,说明新的玩家到来 (broadcast方法稍后实现)。

(4)ball对象存入balls表。

(5)向玩家回应成功进入的信息(enter协议),此处使 用“s.send(....,"send"....agent发送消息,agent相关处理会稍后实现。

(6)向玩家发送战场信息(涉及balllist协议和foodlist协议)。

   定义 辅助方法 broadcast ,代码如下:
--广播
function broadcast(msg)
    for i, v in pairs(balls) do
        s.send(v.node, v.agent, "send", msg)
    end
end

   用于广播协议。它会遍历balls,把消息发送给每个玩家。

4、退出战斗 

        当玩家掉线时,agent 会远程调用 scene 服务的 leave 方法(稍后实现)。leave 远程调用方法,代码如下所示:
--退出
s.resp.leave = function(source, playerid)
    if not balls[playerid] then
        return false
    end
    balls[playerid] = nil

    local leavemsg = {"leave", playerid}
    broadcast(leavemsg)
end

 它会删除与玩家对应的小球(设置balls列表对应id为空),并广播leave协议。

 5、操作移动

        当玩家要改变移动方向时,客户端会发送shift 协议,经由 agent 转发(稍后实现),调用scene shift 方法。实现 shift 远程调用方法,代码如下所示:
--改变速度
s.resp.shift = function(source, playerid, x, y)
    local b = balls[playerid]
	if not b then
        return false
    end
    b.speedx = x
    b.speedy = y
end

 它根据参数playerid找到与玩家对应的小球,并设置它的速度。

完整代码下载:https://gitee.com/frank-yangyu/ball-server文章来源地址https://www.toymoban.com/news/detail-420060.html

到了这里,关于【从零开始学Skynet】实战篇《球球大作战》(十二):场景代码设计(上)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【从零开始学Skynet】基础篇(三):服务模块常用API

              Skynet提供了开启服务和发送消息的API,必须要先掌握它们。列出了Skynet中8个最重要的API,PingPong程序会用到它们。 Lua API 说明 newservice(name, ...) 启动一个名为 name 的新服务,并返回服务的地址。 start(func)         用 func 函数初始化服务,并将消息处理函数注

    2023年04月12日
    浏览(64)
  • 【从零开始学Skynet】工具篇(二):虚拟机文件的复制粘贴

            大家在Linux系统下开发的时候肯定会遇到虚拟机与主机间无法复制粘贴的问题,现在我们就来解决这样的问题,方便我们的开发。 我们可以系统界面的菜单栏点击“控制”,然后打开“设置”;  也可以在VirtualBox界面打开“设置”,效果都是一样的;  打开“设

    2023年04月19日
    浏览(36)
  • Python球球大作战

    安装pygame的命令: 《球球大作战》是一款简单易上手、充满趣味性和竞技性的休闲手游。游戏的核心玩法可以用一句话概括:“大球吃小球,努力生存并成为最大的球。” 游戏规则与操作 : 在《球球大作战》的世界里,每位玩家操控一个可自由移动的小球球。通过滑动屏幕

    2024年04月17日
    浏览(33)
  • 从零开始:手写 JavaScript 代码应用于实际场景

    ​🌈个人主页:前端青山 🔥系列专栏:JavaScript篇 🔖 人终将被年少不可得之物困其一生 依旧 青山 ,本期给大家带来JavaScript篇专栏内容:JavaScript-场景应用 目录 三、场景应用 1. 循环打印红黄绿 (1)用 callback 实现 (2)用 promise 实现 (3)用 async/await 实现 2. 实现每隔一秒打

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

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

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

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

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

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

    2024年02月12日
    浏览(132)
  • 【从零开始学习JAVA | 第二十二篇】BigInteger

    目录  前言:  BigInterger: BigInteger常见的方法: 总结:         本篇我们将介绍BigInteger这个比较实用一点的API,这个API在我们实际写项目中都是很实用的API,因此大家应该对这个API有更加熟练的掌握。 在Java中,整数类型int和long的取值范围是有限的,超出该范围的整数无法

    2024年02月15日
    浏览(64)
  • 【区块链 | 预言机】从零开始使用Chainlink预言机(2)- 智能合约中使用更安全的随机数-代码实战

    Chainlink最近推出一款革命性的产品,VRF—Verifiable Random Function可验证随机数,给智能合约带来了真正安全的随机数。本文我们就来介绍一下如何在智能合约中使用VRF吧。 我们先简要介绍一下Chainlink VFR的工作流程。 首先,智能合约应用,也就是我们的Dapp,需要先发起一个获取

    2024年02月02日
    浏览(49)
  • 【从零开始学习C++ | 第二十二篇】C++新增特性(下)

    目录 前言: 类型推导: constexpr: 初始化列表: 基于范围的for循环: 智能指针之unique ptr Lambda表达式: 总结:         本文我们将继续介绍   C++ 11 新增十大特性的剩余六个,如果没有看过介绍前四个特性的小伙伴的可以点进我C++的专栏就可以看到。 类型推导(

    2024年02月14日
    浏览(59)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包