设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 4052|回复: 22
打印 上一主题 下一主题

[讨论] 通过DLL发包进行的RMXP服务器联机已获得初步进展

[复制链接]

Lv4.逐梦者

梦石
5
星屑
3419
在线时间
390 小时
注册时间
2016-6-25
帖子
232
跳转到指定楼层
1
发表于 2018-2-28 06:29:34 | 只看该作者 |只看大图 回帖奖励 |正序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
RMXP的联机脚本可能这不是第一个,而且DLL扩展应该也是非常容易的
所以之前肯定有人研究过通过DLL进行的联机



本DLL采用的TCP联机,通过向服务端发送用户信息并进行匹配发包同步数据达成多终端联机
地图对象生成方面采用的是先建立默认事件再通过复制该事件到指定位置并改变一些参数
达到多个玩家同屏游玩
由于NPC移动速度和玩家移动速度并不一致的问题,数据同步会有0.2-0.8秒的延迟,由于不影响机能目前暂不解决
NPC映射方面相关代码如下
RUBY 代码复制
  1. # ▼▲▼ TCP服务器映射 ▼▲▼
  2. # by 零教授
  3. #
  4. #!需DLL和服务器支持!
  5. #==============================================================================
  6. # ■ Window_Base
  7. #==============================================================================
  8.  
  9.  
  10. $TCPput = Win32API.new('tcpforRMXP', 'tcpput', %w(i i i p), 'v')
  11. $TCPget = Win32API.new('tcpforRMXP', 'tcpget', 'v','p')
  12. $JOIN = Win32API.new('tcpforRMXP', 'join', 'v','v')
  13. $Name = KOISHI::GetPrivateProfileString("Base","Name")
  14. Map001 = load_datax(sprintf("Data/Map%03d.rxdata", 1))
  15. $other_players = {}
  16. $map_players = []
  17. $old_x = 0
  18. $old_y = 0
  19.  
  20. class Game_Map
  21.   alias setup_tcp setup
  22.   def setup(map_id)
  23.     setup_tcp(map_id)
  24.     #$map_players = []
  25.  
  26.    # for i in 0...10
  27.    #   @events[i+2000].erase if @events[i+2000] != nil
  28.    # end
  29.     #p $other_players
  30.     if $map_players.size > 0
  31.       for i in 0...$map_players.size
  32.         player = $other_players[$map_players[i]]
  33.         if player[2].to_i == map_id
  34.           #p $other_players[i][3]
  35.           @events[i+2000] = Game_Event.new(map_id, Map001.events[1])
  36.           @events[i+2000].erased = false
  37.           @events[i+2000].name = player[3]
  38.           @events[i+2000].character_hue = rand(360)
  39.           @events[i+2000].moveto(player[0].to_i,player[1].to_i)
  40.           @events[i+2000].refresh
  41.           #@events[i+2000].x = $other_players[i][0].to_i
  42.           #@events[i+2000].y = $other_players[i][1].to_i
  43.           #p @events[i+2000]
  44.         end
  45.       end
  46.     end
  47.   end
  48.  
  49.   alias update_tcp update
  50.   def update
  51.     update_tcp
  52.     #if (Graphics.frame_count % 40) == 1
  53.       if $old_x != $game_player.x or $old_y != $game_player.y
  54.         $TCPput.call($game_player.x ,$game_player.y ,@map_id ,$Name)
  55.         $old_x, $old_y = $game_player.x, $game_player.y
  56.       end
  57.       begin
  58.         string = $TCPget.call
  59.       rescue
  60.         string = ""
  61.       end
  62.      # p string
  63.       tplayer = string.split(",")
  64. if string != "" && tplayer.size == 5
  65.     if $other_players[tplayer[4]] == nil
  66.       $map_players.push(tplayer[4])
  67.     end
  68.     $other_players[tplayer[4]] = tplayer
  69.     if tplayer[2] == 0
  70.       $map_players.delete(tplayer[4])
  71.       $other_players[tplayer[4]] = nil
  72.       $game_temp.player_transferring = true
  73.       $game_temp.player_new_map_id = @map_id
  74.       $game_temp.player_new_x = $game_player.x
  75.       $game_temp.player_new_y = $game_player.y
  76.       $game_temp.player_new_direction = 5
  77.       $game_player_shock_flag = true
  78.       return
  79.     end  
  80. end
  81.       #p $other_players
  82.       #for i in 0..100-$other_players.size
  83.       #  @events[2100-i] = nil
  84.       #end  
  85.       for i in 0...$map_players.size
  86.         player = $other_players[$map_players[i]]
  87.         if player[2].to_i == @map_id
  88.           if @events[i+2000].nil? or @events[i+2000].erased
  89.             @events[i+2000] = Game_Event.new(@map_id, Map001.events[1])
  90.             @events[i+2000].erased = false
  91.             @events[i+2000].character_hue = rand(360)
  92.             @events[i+2000].moveto(player[0].to_i,player[1].to_i)
  93.             @events[i+2000].animation_id = 8
  94.             @events[i+2000].refresh
  95.           end  
  96.           eve = @events[i+2000]
  97.           #eve.moveto($other_players[i][0].to_i,$other_players[i][1].to_i)
  98.           #p $other_players[i][3]
  99.           if eve.x != player[0].to_i
  100.             if eve.x < player[0].to_i
  101.               if eve.y != player[1].to_i
  102.                 if eve.y < player[1].to_i
  103.                   eve.move_lower_right
  104.                 else
  105.                   eve.move_upper_right
  106.                 end
  107.               else
  108.                 eve.move_right
  109.               end
  110.             else
  111.               if eve.y != player[1].to_i
  112.                 if eve.y < player[1].to_i
  113.                   eve.move_lower_left
  114.                 else
  115.                   eve.move_upper_left
  116.                 end  
  117.               else
  118.                 eve.move_left
  119.               end
  120.             end
  121.           else
  122.                if eve.y != player[1].to_i
  123.                  if eve.y < player[1].to_i
  124.                    eve.move_down
  125.                  else
  126.                    eve.move_up
  127.                  end
  128.                end
  129.  
  130.           end
  131.  
  132.           #@events[i+2000].x = $other_players[i][0].to_i
  133.           #@events[i+2000].y = $other_players[i][1].to_i
  134.         #else  #不在当前地图
  135.          # @events[i+2000].erase if @events[i+2000] != nil
  136.         end #if
  137.  
  138.       end #for
  139.  
  140.       #p $other_players
  141.     #end
  142.  
  143.   end #def
  144.  
  145. end #class


目前脚本和DLL都处于调试阶段,会出现诸多BUG
如下:

虽然效果上已经达到相当好的成果,但是是否能胜任网游的制作还有待考量

评分

参与人数 3星屑 +100 +3 收起 理由
水母书亚 + 1 塞糖
RyanBern + 100 + 1 精品文章
congwsbn + 1 6

查看全部评分

魔女的下午茶~~制作组募集~~有偿招募长期立绘画师~群号168579736~~多人在线RPG~~无意识Navigation,火热内测中,招内测人员~

Lv2.观梦者

梦石
0
星屑
910
在线时间
94 小时
注册时间
2005-10-22
帖子
397
10
发表于 2018-3-24 15:15:51 | 只看该作者
10多年前确实有联网的dll出现,并且连接成功了,不过,后来就没有进一步进展了,那个实现的是在线走路和聊天对话,没完成在线组队打怪。
做脚本先从修改脚本做起,我只修改自己觉得能用到的东西。
以后的任何作品都将不会进行分享。
Bilibili:https://space.bilibili.com/288814521
回复 支持 反对

使用道具 举报

头像被屏蔽

Lv2.观梦者 (禁止发言)

梦石
0
星屑
724
在线时间
918 小时
注册时间
2010-11-13
帖子
1023
9
发表于 2018-3-19 18:09:08 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
签名被屏蔽
回复 支持 反对

使用道具 举报

Lv5.捕梦者 (管理员)

老黄鸡

梦石
0
星屑
42448
在线时间
7603 小时
注册时间
2009-7-6
帖子
13506

开拓者贵宾

8
发表于 2018-2-28 23:24:46 | 只看该作者
guoxiaomi 发表于 2018-2-28 12:44
如果有好的异步的tcp通讯就很棒了~其实我更感兴趣的是分辨率怎么扩大的?我写的联机,数据传输是走的http r ...

如果郭兄有需要我这里倒是可以糊一个突破限制的tilemap

点评

雷霆那边好像有把VA的图块改成48*48的方法  发表于 2018-3-1 19:20
暂时倒是不需要的  发表于 2018-3-1 01:48

评分

参与人数 1星屑 +20 收起 理由
RyanBern + 20 非常醋

查看全部评分

RGDirect - DirectX驱动的RGSS,点我了解.
RM全系列成套系统定制请联系QQ1213237796
不接受对其他插件维护的委托
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
2724
在线时间
227 小时
注册时间
2016-3-27
帖子
576
7
发表于 2018-2-28 19:11:22 | 只看该作者
联机其实这个想法很多人都有想过
也有人付诸过实际行动
但是这方面最大的问题就在于服务器
有谁会愿意做一个免费的RM去开服务器给大家玩呢???
现在服务器又那么贵
除非是自己的经济来源来自于机房,然后可以分一小块,供RM使用
要不就得用RM做高品质的游戏,来吸引玩家一次性购买/内购
不过RM做高品质限制还是很多的
话说回来楼主还是 挺厉害的
加油吧

点评

好像很有道理  发表于 2018-3-1 17:43
你还需要一个非常宝贵的公网ip  发表于 2018-3-1 09:13
主要是真的会有人无偿开发游戏并且用服务器做online吗...qwq  发表于 2018-2-28 22:42
服务器就买来放在自己家里,电费和宽带费交着就不会感到压力,除非你要拿服务器去挖矿  发表于 2018-2-28 19:15

评分

参与人数 1星屑 +30 收起 理由
RyanBern + 30 可以去租vps 并不贵

查看全部评分

现在还能改名吗qwq
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
5
星屑
3419
在线时间
390 小时
注册时间
2016-6-25
帖子
232
6
 楼主| 发表于 2018-2-28 17:18:38 | 只看该作者
本帖最后由 零教授 于 2018-2-28 17:24 编辑
guoxiaomi 发表于 2018-2-28 12:44
如果有好的异步的tcp通讯就很棒了~其实我更感兴趣的是分辨率怎么扩大的?我写的联机,数据传输是走的http r ...


分辨率WIN32AI是用论坛的
光修改分辨率非常容易,但是要修改地图图块元件和人物元件,以及场景窗口就需要自适应
除开修改分辨率外还必须修改Scene_Battle、Spriteset_Battle、Scene_Map、Spriteset_Map、Game_Battler、Sprite_Battler、RPG::Weather这些主要的图片处理的类

RUBY 代码复制
  1. #==============================================================================
  2. # 本脚本来自[url]www.66RPG.com[/url],使用和转载请保留此信息
  3. #==============================================================================
  4. # ————————————————————————————————————
  5. # 本脚本来自[url]www.66rpg.com[/url],转载请保留此信息
  6. # ————————————————————————————————————
  7.  
  8. #ウィンドウサイズの変更(v1.00)
  9. module THNDJ
  10.   GAME_INI_FILE = ".\\Game.ini"
  11.   #--------------------------------------------------------------------------
  12.   # ● 读取配置文件
  13.   #--------------------------------------------------------------------------
  14.   def THNDJ.GetPrivateProfileString(section, key)
  15.      val = "\0"*256
  16.      gps = Win32API.new('kernel32', 'GetPrivateProfileString',%w(p p p p l p), 'l')
  17.      gps.call(section, key, "", val, 256, GAME_INI_FILE)
  18.      val.delete!("\0")
  19.      return val
  20.   end
  21.  
  22.   #--------------------------------------------------------------------------
  23.   # ● 写入配置文件
  24.   #--------------------------------------------------------------------------
  25.   def THNDJ.WritePrivateProfileString(section, key, val)
  26.      gps = Win32API.new('kernel32', 'WritePrivateProfileString',%w(p p p p), 'i')
  27.      return gps.call(section, key, val.to_s , GAME_INI_FILE)
  28.    end
  29.  
  30.  
  31.  
  32.  
  33.   #--------------------------------------------------------------------------
  34.   #--------------------------------------------------------------------------
  35.   def THNDJ.FindWindow(class_name, title)
  36.     fw = Win32API.new('user32', 'FindWindow', %(p, p), 'i')
  37.     hWnd = fw.call(class_name, title)
  38.     return hWnd
  39.   end
  40.  
  41.   HWND_TOP     = 0
  42.   HWND_TOPMOST = -1
  43.   SWP_NOMOVE   = 0
  44.  
  45.   #--------------------------------------------------------------------------
  46.   #--------------------------------------------------------------------------
  47.   def THNDJ.SetWindowPos(hWnd, w, h)
  48.     system_metrics = Win32API.new('user32', 'GetSystemMetrics', %(i), 'i')
  49.     sw = system_metrics.call(0)
  50.     sh = system_metrics.call(1)
  51.    # if sw <= 800 or sh <=600
  52.   #    return false
  53.   #  end
  54.     x_alias = (sw - w)/2
  55.     y_alias = (sh - h)/2
  56.     swp = Win32API.new('user32', 'SetWindowPos', %(l, l, i, i, i, i, i), 'i')
  57.     ok = swp.call(hWnd, HWND_TOP, x_alias, y_alias, w, h, SWP_NOMOVE)
  58.     # 下の行を有効にすると、常に前面に表示されるウィンドウになる。
  59.     #ok = swp.call(hWnd, HWND_TOPMOST, 0, 0, w, h, SWP_NOMOVE)
  60.  
  61.     #SetWindowPos(const CWnd* pWndInsertAfter, int x, int y, int cx, int cy, UINT nFlags );
  62.     #参数1是在屏幕显示的层次优先级(最上最下);后四个决定窗口四个角的坐标;最后一个指定显示的状态。具体可以参阅MSDN.
  63.     return ok
  64.   end
  65. end
  66.  
  67. title = THNDJ.GetPrivateProfileString("THNDJ", "NormalTitle")
  68. $hWnd = THNDJ.FindWindow("RGSS Player", title)
  69.  
  70. def resize_window
  71.  
  72.   # 幅320、高さ480に変更
  73.   $width = [[THNDJ.GetPrivateProfileString("THNDJ","$width").to_i,640].max,1280].min
  74.   $height = [[THNDJ.GetPrivateProfileString("THNDJ","$height").to_i,480].max,960].min
  75.   ok = THNDJ.SetWindowPos($hWnd, $width, $height)
  76.   $XRXS65AX = ($width-546)/2
  77.   $XRXS65AY = $height-90
  78.   if(ok == 0)
  79.     p "サイズ変更失敗"
  80.     $width = 640
  81.     $height = 480
  82.     $XRXS65AX = ($width-546)/2
  83.     $XRXS65AY = $height-90
  84.     return false
  85.   end
  86.   return true
  87. end
  88.  
  89. module KOISHI
  90.   @player_id = THNDJ.GetPrivateProfileString("THNDJ", "player_id")
  91.   KOISHI_FILE = ".\\"+@player_id+".ini"
  92.   #--------------------------------------------------------------------------
  93.   # ● 读取配置文件
  94.   #--------------------------------------------------------------------------
  95.   def KOISHI.GetPrivateProfileString(section, key)
  96.      val = "\0"*256
  97.      gps = Win32API.new('kernel32', 'GetPrivateProfileString',%w(p p p p l p), 'l')
  98.      gps.call(section, key, "", val, 256, KOISHI_FILE)
  99.      val.delete!("\0")
  100.      return val
  101.   end
  102.  
  103.   #--------------------------------------------------------------------------
  104.   # ● 写入配置文件
  105.   #--------------------------------------------------------------------------
  106.   def KOISHI.WritePrivateProfileString(section, key, val)
  107.      gps = Win32API.new('kernel32', 'WritePrivateProfileString',%w(p p p p), 'i')
  108.      return gps.call(section, key, val.to_s , KOISHI_FILE)
  109.    end
  110.  
  111. end
  112. #==============================================================================
  113. # 本脚本来自[url]www.66RPG.com[/url],使用和转载请保留此信息
  114. #==============================================================================

评分

参与人数 2星屑 +50 +1 收起 理由
guoxiaomi + 1 我很赞同
RyanBern + 50 赞认真的回复

查看全部评分

魔女的下午茶~~制作组募集~~有偿招募长期立绘画师~群号168579736~~多人在线RPG~~无意识Navigation,火热内测中,招内测人员~
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
9280
在线时间
2504 小时
注册时间
2011-5-20
帖子
15389

开拓者

5
发表于 2018-2-28 14:19:18 | 只看该作者
图中的全部都是玩家?还是大部分是npc
如果其中一个玩家用了物品,使用物品的音效其他玩家可以听到吗?

点评

因为是频道制度,玩家一旦改变数据(显示动画、移动位置)就会发包给同房间的人,然后在他们自己本地的游戏里就能显示变化了  发表于 2018-2-28 17:39
做个吃鸡也有可能了  发表于 2018-2-28 16:02
感觉这个应该看游戏类型来定···(如果你可以完全收到附近玩家使用物品/技能时产生的动画和音效,可能会崩掉吧···)不过最好是能做到,这样的话   发表于 2018-2-28 16:01
通常的道具,定期同步 animation_id 就行啦  发表于 2018-2-28 14:56
[img]http://service.t.sina.com.cn/widget/qmd/5339802982/c02e16bd/7.png
回复 支持 反对

使用道具 举报

Lv5.捕梦者 (版主)

梦石
1
星屑
23999
在线时间
3339 小时
注册时间
2011-7-8
帖子
3926

开拓者

4
发表于 2018-2-28 12:44:23 | 只看该作者
如果有好的异步的tcp通讯就很棒了~其实我更感兴趣的是分辨率怎么扩大的?我写的联机,数据传输是走的http request而不是用tcp socket,但是客户端拿到数据后如何处理,这些是通用的,有兴趣可以去看看。

https://gitee.com/rmxp/rgss_server

点评

啊对了,有一件事情忘记问了,您知不知道有什么API可以让RM打开游戏的窗口自动转化为无边缘窗口,这两天一直在找  发表于 2018-3-5 04:27
嗯,服务端的一些多线程优化处理还有加密解密操作是目前需要学习的  发表于 2018-2-28 17:47

评分

参与人数 1星屑 +30 收起 理由
RyanBern + 30 赞认真的回复

查看全部评分

熟悉rgss和ruby,xp区版主~
正在填坑:《膜拜组传奇》讲述膜拜组和学霸们的故事。
已上steam:与TXBD合作的Reformers《变革者》
* 战斗调用公共事件 *
* RGSOS 网络脚本 *
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
2386
在线时间
660 小时
注册时间
2017-10-13
帖子
53
3
发表于 2018-2-28 12:29:25 | 只看该作者
牛的一笔
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
127
在线时间
14 小时
注册时间
2015-3-19
帖子
19
2
发表于 2018-2-28 08:53:44 | 只看该作者
回复一下,
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-11-27 18:49

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表