描绘图形——描绘直线
声明:此脚本为日本著名rgss脚本个人站之一的 箱入小屋 的管理人 レベル1的脚本。欢迎转载。此系列作为中日rm界交流之用,为接触脚本做软登陆处理,由本人亲身体验,为各位想开始学脚本但是对脚本有恐惧的人所作,不要求各位都是脚本达人,但是有需要自己也可以发挥发挥。(因为美兽曾经在论坛上发过,有人误传为美兽的,所以本人特此声明,不要说我盗用美兽的脚本。个人觉得您可以不在游戏里声明使用其他人的脚本,但是请在脚本编辑器里注明作者e-mail或是网站连接。要求不高,仅此而已。不要以为加密了就看不到了。哪怕你使用FantasyDR的反破解脚本。)
前言:脚本是怎么写成的?是上来就开始class吗?刚开始学的肯定不是这样吧。这里开始介绍脚本从创意到制作到修改的过程,给您参考,如果对您有所帮助,那就是对我劳动的最大回报。
事脚本接触的最初状态,显示图片,从rmxp的自带文档中就可以学到。因而了解到脚本的基础运作形式。那么下面就开始自我设计脚本吧。脚本的开始就是图形脚本,因为他简单,可视。而且,开始从改造开始。
描绘直线
脚本是一种创造,就像原始人制造石头斧一样,正是有了不便,人才会进行改造。
不便:系统自带的class Bitmap 有对矩形进行描绘的方法,可是用这个总觉得缺点什么。
定义:首先需要定义一种方法
draw_line(x1, y1, x2, y2, color)
实现功能:点 (x1, y1) 和点 (x2, y2) 之间 用color的颜色进行连接。
脚本实现想法:用定义set_pixel 一个一个点进行描绘。可是每个点怎么设置啊,一个一个的去弄是不是太麻烦拉?嗯,麻烦,还好,有for的循环,点的x坐标可以搞定,y怎么办呢?哈哈,数学的重要性体现出来了。
初中数学应用: y - y1 = a(x - x1) 两点确定一条直线。
其斜率为a。 a = (y2 - y1)/(x2 - x1) ##提示,由于rm的显示方式,在计算数的算式中回经常使用到.to_f.to_i 这里由于a如果被系统自动取整,那有角度的直线就不能完全显示了。所以加上.to_f
a = (y2 - y1)/(x2 - x1).to_f 斜率求得完毕。
说是直线,可是我们看到的不过是640×480的区域,所以准确说是线段,那么线段就会有端点。换用数学题里的说法就是x有取值范围,即x1 ≦ x ≦ x2 ,那么对应的y也有个范围,综合上面的就是
for x in x1..x2 y = a * (x - x1) + y1 set_pixel(x, y, color) end
这样,一个直线就做成了。哈哈,高兴啊,别高兴太早,问题来了。一般人描绘的时候都是从左到右,不会有什么问题,可是就会有邪恶的人从右到左(某夏:说我吗?汗)。这就是所谓的bug,即作者考虑情况不周,人这么想理想当然,可是计算机你不告诉它,它会不知所措。所以,为了脚本可以通用,加上判别 x1, x2 的大小关系就会很重要。
if x1 < x2 for x in x1..x2 y = a * (x - x1) + y1 set_pixel(x, y, color) end elsif x1 > x2 draw_line(x2, y2, x1, y2, color) end
这种改法一般都会想到,但是为了脚本的书写效率,和为了使自己更“专业”一点(自欺欺人),for循环的那段可以写成
for x in (x1 < x2 ? x1..x2 : x2..x1)
累死拉 ,看的我都累拉。我也累啊,打了这么多! 这回终于完了吧?可是你想没有想过,当 x1 == x2(分歧判断需要两个=)的时候呢?呵呵。脚本的周密性就在于此啊。回忆当初做题求x的时候,讨论当x>0 x<0 x=0的分情况讨论…………(数学果然很重要)
当 x1 == x2的时候,a为零,即斜率为0,描绘的时候会出现意外的错误,呵呵。
更改为(脚本的出炉就是这样改来改去的)
if x1 == x2 x = x1 for y in (y1 < y2 ? y1..y2 : y2..y1) set_pixel(x, y, color) end else a = (y2 - y1)/(x2 - x1).to_f end
终于考虑到各个方面了,作为人的思考就可以结束了,可以看看自己的成果了。描绘试验看看 图片
咦?怎么会这样,角度越大,怎么线成点了?这就是想的和实际还是有区别的,为了完美,还得想为什么,找原因。 经查,由于y的值是由x的变化而变化,当倾斜增大的时候,描绘的点也就越少(垂直相交的两条线由于是单独分歧绘出来的,所以没有问题。) 因此,靠近y轴的x值应该由y确定,也就是说要增加新的分歧,既是a的取值范围-1 < a < 1和以外的情况。 if -1 < a and a < 1 for x in (x1 < x2 ? x1..x2 : x2..x1) end else for y in (y1 < y2 ? y1..y2 : y2..y1) end end
看看效果 图片
嗯,比刚才的强了。 脚本制作思路:不便→定义→想法→原理思路debug→实践→实践中debug→完成
终极脚本:(箱入小屋的管理人 レベル1) class Bitmap def draw_line(x1, y1, x2, y2, color) if x1 == x2 x = x1 for y in (y1 < y2 ? y1..y2 : y2..y1) set_pixel(x, y, color) end else a = (y2-y1)/(x2-x1).to_f if -1 < a and a < 1 for x in (x1 < x2 ? x1..x2 : x2..x1) y = a * (x - x1) + y1 set_pixel(x, y, color) end else for y in (y1 < y2 ? y1..y2 : y2..y1) x = (y - y1) / a + x1 set_pixel(x, y, color) end end end end end
这就是我前几天刚开始学脚本的过程,对我触动很深,感觉对不知如何入门的会有些帮助。
脚本扩展
有了第一个脚本之后,就可以扩展了,扩展是为了让你的功能更多。当你有能发一颗子弹的手枪的时候,你会不会想连发6颗呢?这就是扩展。
练习,使用描绘直线的脚本进行矩形的描绘(自带的有rect,请不要使用) 思路就是利用上面的脚本画四条线,这就是矩形了。 统一定义: draw_rect(x, y, width, height, color) (x, y) 是矩形左上角坐标。width矩形宽 height 矩形高 color 颜色
参考答案: class Bitmap def draw_rect(x, y, width, height, color) draw_line(x, y, x+width, y, color) draw_line(x+width, y, x+width, y+height, color) draw_line(x+width, y+height, x, y+height, color) draw_line(x, y+height, x, y, color) end end
箱入小屋的参考
class Bitmap # 矩形描画 # (x, y, width, height, color) # (rect, color) # 矩形 (x, y, width, height)またはrect(Rect)の輪郭を色color(Color)で描きます。 def draw_rect(*arg) case arg.length when 2 x = arg[0].x y = arg[0].y width = arg[0].width height = arg[0].height color = arg[1] when 5 x = arg[0] y = arg[1] width = arg[2] height = arg[3] color = arg[4] else al = arg[0].is_a?(Rect) ? '2' : '5' raise ArgumentError, "wrong # of arguments ("+al+" for "+arg.length.to_s+")", caller(1) end draw_line(x, y, x+width, y, color) draw_line(x+width, y, x+width, y+height, color) draw_line(x, y+height, x+width, y+height, color) draw_line(x, y, x, y+height, color) end end
刚到66rpg不几天,新人,但是拜读过大部分人的教程,不知道各位对此帖有何看法
太简单? 说得太详细,不需要? 不想学脚本,别写了?
欢迎各位指正
|