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

Project1

 找回密码
 注册会员
搜索
楼主: 八云紫
打印 上一主题 下一主题

[RMVX发布] 新手教程--从0开始学RGSS2(2013-09-21 修复索引地址)

  [复制链接]

Lv1.梦旅人

梦石
0
星屑
50
在线时间
28 小时
注册时间
2011-1-12
帖子
42
121
发表于 2011-5-12 22:10:25 | 只看该作者
回复 苏小脉 的帖子

網絡協議 也算是 API 这个真没想到, 不过算是接口的话, 可以理解.

教程对象是 Ruby , 所以就使用了 狭隘的定义 .  > <
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
50
在线时间
27 小时
注册时间
2011-2-6
帖子
10
122
发表于 2011-5-12 23:51:33 | 只看该作者
更新了!!
回复 支持 反对

使用道具 举报

Lv1.梦旅人

风之塞尔达

梦石
0
星屑
50
在线时间
57 小时
注册时间
2005-10-22
帖子
2492

贵宾

123
发表于 2011-5-13 00:14:51 | 只看该作者
本帖最后由 link006007 于 2011-5-13 00:17 编辑

lz说道了API的好处,没说坏处。。
(1)使用API,将会使得你的游戏过分依赖于API的运行环境。例如某个API依赖一些普通系统上不常使用的库。而且,ruby只对原生的C函数有最好的亲和力。其他的语言API,很多估计还要以C做媒介。。。
(2)使用API将会使得你的代码是去托管能力,如果你使用了非托管资源,那么你最好知道你在做什么。
(3)使用API,你将很难知道你的程序是怎么死的,除非API库提供良好的coredump。ruby错误回溯无法查找其他语言的错误。你很可能只会收到你的游戏未响应,或者是一行内存地址异常,然后退出。
在程序里延续塞尔达的传说, 在画板上勾勒塞尔达的轮廓!!
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
50
在线时间
28 小时
注册时间
2011-1-12
帖子
42
124
发表于 2011-5-13 12:37:04 | 只看该作者
回复 link006007 的帖子

坏处啥的, 真还没有说. 抱歉.

对于 1), 咱是使用 C 来写 dll 的, 所以对 其他语言 不太熟悉. 本身使用了 API , 就会对系统产生依赖性是对的. 那个无能为力.

2) 托管啥的, 真心了解不多 = =

3) WIndow API 可以使用 GetLastError 来获取错误. Window API 本身出现 内存冲突的几率比自己写的 dll 要少的多. 如果是自己写 dll 的话, 这些错误想改还不是难事. 至少咱是经常出现这堆错误.

4) 事物都有两面性.
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
110
在线时间
953 小时
注册时间
2007-4-25
帖子
805
125
发表于 2011-5-13 19:48:39 | 只看该作者
爱丽丝·玛格特罗依德 发表于 2011-5-13 12:37
回复 link006007 的帖子

坏处啥的, 真还没有说. 抱歉.

我感觉 123 楼说的托管可能是指垃圾回收,而不是 CLR。
设计良好的 API 确实应该在高层就把错误捕获并返回给用户,而不是留给 OS 处理。
[email protected]:~> repeat 1 fortune
Matz is nice, so we are nice.
回复 支持 反对

使用道具 举报

Lv3.寻梦者

弓箭手?剑兰

梦石
0
星屑
4854
在线时间
833 小时
注册时间
2010-11-17
帖子
1140
126
发表于 2011-5-14 09:14:59 | 只看该作者
在使用麻烦的Ruby API的时候有些参数也要用麻烦的pack和unpack。
(甚有些函数至应该不能用= =)
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
50
在线时间
36 小时
注册时间
2008-2-22
帖子
35
127
发表于 2011-5-14 11:12:13 | 只看该作者
本帖最后由 芙兰朵露·斯卡雷特 于 2011-5-14 15:54 编辑

Array#pack , String#unpack and Win32API


1. Array#pack and String#unpack
       无论是什么编程语言, 总是把需要的数据或者正在使用的数据放进内存里, 给 CPU 调用. 内存的结构, 从 ASM 的初级使用者来说(其实就是咱了 > <) 是一维的, 数据总是连接成像字符串一样的结构.
       那么, 如果把 Array 看成是 C 里的结构体, 也就是每个元素都是一个成员的话, Array#pack 方法就可以看成是将 Ruby 的 Array 转换成 C 里的结构体. 中间作为过渡的, 就是 内存 了.
       String#unpack 的功能刚好和 Array#pack 相反.
       举个简单的例子:
C 代码:
  1. struct CStruct
  2. {
  3.     int x;
  4.     long y;
  5. };
复制代码
定义一个有 int 的成员变量 x 和 long 的成员变量 y
        如果我们要从 RGSS2 的角度来创建这个结构体的话, 那么, 就需要使用 Array#pack:
RGSS2 代码:

  1. cstruct = [10, 20].pack("il")
复制代码
是的, 就是这样, pack 后面的参数告诉编译器, 将第一个 10 格式化成 C 里的 int (就是那个 "i"), 20 格式化成 long (就是 "l"). 这样 ,返回的结果就是 C 里的结构体的内存映像, 这个代码等价于:
C 代码:

  1. CStruct cstruct;
  2. cstruct.x = 10;
  3. cstruct.y = 20l;
复制代码
这两者的 内存映像 是相同的.

2. Array#pack and String#unpack 的参数
       这个方法参数有非常的多, 具体的可以查看: http://rpg.blue/manual/ruby/pack_template_string.html
       个人的看法, 这个参数的值, 可以看成是将元素依次的格式化成一个含有类型的值. 比如上面说到的, "i" 其实就是等价于 C 里的 int , "l" 等价于 long , "C" 等价于 unsigned char 一样.

3. Array#pack , String#unpack and Win32API
       以上都是废话, 接下来才是福利.
       pack 和 unpack 和 Win32API 这个类关系密切. 我们从一个例子中说明这个的用法.
       一个简单的例子:
       假设我们需要获取 VX 窗口相对于桌面的坐标和 VX 窗口的长度, 高度, 那么, 我们就需要查询一个有这个功能的 API . 于是百度到这个:
函数功能:该函数返回指定窗口的边框矩形的尺寸。该尺寸以相对于屏幕坐标左上角的屏幕坐标给出。
函数原型:BOOL GetWindowRect(HWND hWnd,LPRECT lpRect);
速查:Windows NT:3.1以上版本:Windows:95以上版本;Windows CE:1.0以上版本;头文件:Winuser.h;库文件:User32.lib。

      
        这样我们就知道了这个 API 的大部分信息, 于是开始创建 Win32API 的一个实例.

  1.     get_window_rect = Win32API.new("user32.dll", "GetWindowRect",
  2.            "pp", # 第二个参数是一个结构体, 只能传递一个地址, 也就是 "p" 给它.
  3.            "i")
复制代码
那么, 如何调用这个 API 呢? 第一个参数是窗口句柄, 这个难度不大. 第二个参数是什么? 于是我们继续百度, 结果如下:
typedef struct tagRECT
{
LONG left;
LONG top;
LONG right;
LONG bottom;
} RECT, *PRECT, NEAR *NPRECT, FAR *LPRECT;

       显而易见的, 它是一个结构体, 里面的成员变量都是  long 类型的, 于是, 我们需要先创建一个这个结构体的实例:

RGSS2 代码:

  1. lpRect = [0, 0, 0, 0].pack("llll")
复制代码
我们也可以这么写:

  1. lpRect = [0, 0, 0, 0].pack("l4")
复制代码
这样, 参数都知道了, 于是调用这个 API :
RGSS2 代码:

  1. lpRect = [0, 0, 0, 0].pack("llll")
  2. get_window_rect.call($hwnd, lpRect);
复制代码
不过要注意一点, 现在的 lpRect 只是一个字符串, LPRECT 结构的内存映像, 那么, 我们需要 unpack 成我们需要的数组:
RGSS2 代码:

  1. rect = lpRect.unpack("l4")
复制代码
这样就获取了, 窗口的左上和右下的坐标. 这里需要注意的是, WIndow 的矩形的定义和 RGSS2 的矩形是不一样的. 于是进一步的转换:
RGSS2 代码:

  1. rect = lpRect.unpack("l4")
  2. vx_window_rect = Rect.new(rect[0], rect[1], rect[2] - rect[0], rect[3] - rect[1])
复制代码
这样就获取了 VX 窗口的矩形了, 包含了窗口左上角的坐标和窗口的长宽.
回复 支持 反对

使用道具 举报

Lv2.观梦者 (管理员)

八云紫的式神

梦石
0
星屑
549
在线时间
1243 小时
注册时间
2008-1-1
帖子
4282

烫烫烫

128
发表于 2011-5-14 11:20:44 | 只看该作者
矩形那个示例GJ,原来结构体成员是名字无关顺序有关的....之前一直理解错了
rm for linux(wine)制作中,期待夏娜SAMA能实现到webrm上
回复 支持 反对

使用道具 举报

Lv3.寻梦者

弓箭手?剑兰

梦石
0
星屑
4854
在线时间
833 小时
注册时间
2010-11-17
帖子
1140
129
发表于 2011-5-14 11:38:03 | 只看该作者
貌似已经很齐了,要不要说一下"l*"的"*"代表的"所有长度"的意思呢?
或者说一下pack和unpack的其他用途,比如16进制字符交换...
或者可能解释一下pack以后"\xxx"是一个字符、一个byte什么的
或者说一下为什么pack以后会有字母、符号、"\n\r"这些...

点评

不过你会的C结构体pack我之前含糊= =不清楚是否顺序有关...  发表于 2011-5-14 15:59
说起来很无奈, pack 咱只会这个 = =  发表于 2011-5-14 15:55
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
6645
在线时间
1666 小时
注册时间
2008-10-29
帖子
6710

贵宾

130
发表于 2011-5-14 13:54:23 | 只看该作者
芙兰朵露·斯卡雷特 发表于 2011-5-14 11:12
Array#pack , String#unpack and Win32API

1. Array#pack and String#unpack

最后一段代码在计算rect width和height的时候是不是写错了. rect[3] rect[4]

点评

嗯啊.一般传句柄都用的l.= = 至少我是这样的.  发表于 2011-5-14 15:56
好吧, 理所当然的数着 1 2 3 4,然后就悲剧了  发表于 2011-5-14 15:55
的确应该改成rect[2] rect[3],那里的API参数平常是传"lp"而不是"pp"的吧.  发表于 2011-5-14 14:36











你知道得太多了

回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2024-5-5 23:06

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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