楼主: 丿梁丶小柒

[RMVA发布] 全新配套ACT系统——开创RM潜力计划~~2016.11.13更新

[复制链接]
梦石
5
星屑
3061
在线时间
613 小时
注册时间
2012-11-12
回帖
449

开拓者

发表于 2016-9-25 23:43:14 | 显示全部楼层
这个必须支持一下啊,不过游戏坑了很可惜呢。
回复

使用道具 举报

梦石
0
星屑
4623
在线时间
1207 小时
注册时间
2016-4-7
回帖
944

开拓者

发表于 2016-9-26 00:49:37 | 显示全部楼层
本帖最后由 shitake 于 2016-9-27 00:10 编辑

[pre lang="ruby"]#encoding: utf-8
#author: shitake
#data: 16-9-26

class Range
  # 判断两个范围是否相交。
  def intersects(range)
    !(self.last < range.first || self.first > range.last)
  end
end

module Math
  def self.a2r(angle)
    angle * Math::PI / 180 if angle.kind_of? Numeric
  end
end

# 表示二维坐标系上点的对象
class Point

  attr_accessor :x
  attr_accessor :y

  def initialize(x = 0, y = x)
    @x = x
    @y = y
  end

  # 二维坐标下两点距离
  def distance(point)
    Math.hypot(@x - point.x, @y - point.y)
  end

  # 二维坐标下两点解析距离
  def distance_axis(point)
    [point.x - @x,point.y - @y]
  end

  def set(x = 0, y = x)
    @x = x
    @y = y
  end

end

class Vector2

  attr_accessor :x
  attr_accessor :y

  def initialize(x, y)
    @x = x || 0
    @y = y || 0
  end

  #点乘
  def dot_product(vector2)
    @x * vector2.x + @y * vector2.y
  end

  #模
  def module
    Math.hypot(@x, @y)
  end

end

class Axes

  attr_accessor :origin
  attr_accessor :radian
  attr_reader :x
  attr_reader :y

  #origin:原点,radian:偏转弧度
  def initialize(origin, radian)
    @origin = origin
    @radian = radian
    set_axes(@radian)
  end

  def radian=(value)
    return if @radian == value
    @radian = value
    set_axes(value)
  end

  def set_axes(radian)
    @x = Vector2.new(Math.cos(radian), Math.sin(radian))
    @y = Vector2.new(-1 * Math.sin(radian), Math.cos(radian))
  end

  #返回逆坐标系
  def a_axes
    Axes.new(Point.new(- @origin.x, - @origin.y), -radian)
  end

  #返回向量在当前坐标系下的投影
  def shadow(vector2)
    x = vector2.dot_product(@x)
    y = vector2.dot_product(@y)
    Vector2.new(x, y)
  end

  #返回点在当前坐标系下的坐标
  def point(point)
    vector2 = shadow(Vector2.new(point.x - @origin.x, point.y - @origin.y))
    Point.new(vector2.x, vector2.y)
  end

end

class AABB

  attr_reader :x
  attr_reader :y
  attr_reader :width
  attr_reader :height
  attr_reader :center
  attr_reader :width_range
  attr_reader :height_range

  def initialize(x = 0, y = 0, width = 0, height = 0)
    @x = x
    @y = y
    @width = width
    @height = height
    create
  end

  def create
    @width_range = Range.new(@x, @x + @width)
    @height_range = Range.new(@y, @y + @height)
    @center = Point.new(@width_range / 2, @height_range / 2)
  end

  def points
    [
        Point.new(@x, @y), #左上
        Point.new(@x + @width, @y), #右上
        Point.new(@x, @y + @height), #左下
        Point.new(@x + @width, @y + @height) #右下
    ]
  end

  def x=(value)
    return if @x == value
    @x = value
    create
  end

  def y=(value)
    return if @y == value
    @y = value
    create
  end

  def width=(value)
    return if @width == value
    @width = value
    create
  end

  def height=(value)
    return if @height == value
    @height = value
    create
  end

  def collision(obj)
    case obj.class
      when Point
        point_collision(obj)
      when AABB
        aabb_collision(obj)
      when OBB
        obb_collision(obj)
      when Sphere
        sphere_collision(obj)
      else
        raise "TypeError:不正确类型#{obj.class}!"
    end
  end

  # point 相交测试
  def point_collision(point)
    @width_range.eql?(point.x) && @height_range.eql?(point.y)
  end

  # aabb 相交测试
  def aabb_collision(aabb)
    @width_range.intersects(aabb.width_range) && @height_range.intersects(aabb.height_range)
  end

  # obb 相交测试
  def obb_collision(obb)
    return aabb_collision(obb.obb2aabb) if obb.angle % 90 == 0
    obb.obb_collision(aabb2obb)
  end
  
  def sphere_collision(sphere)
    sphere.aabb_collision(self)
  end

  def aabb2obb
    OBB.new(@center, @width, @height, 0)
  end

  def aabb2sphere
    radius = Math.sqrt((@width / 2) ** 2 + (@height / 2) ** 2).ceil
    Sphere.new(@x, @y, radius)
  end

end

class OBB

  attr_reader :center
  attr_reader :width
  attr_reader :height
  attr_reader :angle
  attr_reader :width_range
  attr_reader :height_range
  attr_reader :center
  attr_reader :axes

  def initialize(center, width = 0, height = 0, angle)
    @center = center
    @width = width
    @height = height
    value = angle % 360
    @angle = value > 180 ? value - 180 : value
    create
  end



  def create
    @axes = Axes.new(@center, Math.a2r(@angle))
    @width_range = Range(-@width / 2, @width / 2)
    @height_range = Range(-@height / 2, @height / 2)
  end

  def center=(value)
    return if @center == value
    @center = value
    create
  end

  def width=(value)
    return if @width == value
    @width = value
    create
  end

  def height=(value)
    return if @height == value
    @height = value
    create
  end

  def radian=(value)
    value = value % 360
    return if @angle == (value > 180 ? value - 180 : value)
    @angle = value
    create
  end

  def points
    [
        Point.new(@center.x - @width / 2, @center.y - @height / 2),
        Point.new(@center.x - @width / 2, @center.y + @height / 2),
        Point.new(@center.x + @width / 2, @center.y - @height / 2),
        Point.new(@center.x + @width / 2, @center.y + @height / 2),
    ]
  end

  def collision(obj)
    case obj.class
      when Point
        point_collision(obj)
      when AABB
        aabb_collision(obj)
      when OBB
        obb_collision(obj)
      when Sphere
        sphere_collision(obj)
      else
        raise "TypeError:不正确类型#{obj.class}!"
    end
  end

  # point 相交测试
  def point_collision(point)
    point = @axes.point(point)
    width_range.eql?(point.x) && height_range.eql?(point.y)
  end

  # aabb 相交测试
  def aabb_collision(aabb)
    aabb.obb_collision(self)
  end

  # obb 相交测试,分离轴定理
  def obb_collision(obb)
    this_in_obb_center = obb.axes.point(@center)
    obb_in_this_center = axes.point(obb.center)
    ow_range = Range.new(obb_in_this_center.x - obb.width / 2, obb_in_this_center.x + obb.width / 2)
    oh_range = Range.new(obb_in_this_center.y - obb.height / 2, obb_in_this_center.y + obb.height / 2)
    w_o_range = Range.new(this_in_obb_center.x - @width / 2, this_in_obb_center.x + @width / 2)
    h_o_range = Range.new(obb_in_this_center.y - @height / 2, obb_in_this_center.y + @height / 2)
    width_range.intersects(ow_range) && height_range.intersects(oh_range) && obb.width_range.intersects(w_o_range) && obb.height_range.intersects(h_o_range)
  end

  def sphere_collision(sphere)
    sphere.obb_collision(self)
  end
  
  def obb2aabb
    return AABB.new(@center.x - @width / 2, @center.y, @width, @height) if @radian == 0
    return AABB.new(@center.x - @height / 2, @center.y, @height, @width) if @angle == 90 && @angle == 180
    AABB.new(points.min_by(&:x), points.min_by(&:y), points.max_by(&:x), points.max_by(&:y))
  end

  def obb2sphere
    radius = Math.sqrt((@width / 2) ** 2 + (@height / 2) ** 2).ceil
    Sphere.new(@center.x, @center.y, radius)
  end

end

class Sphere

  attr_reader :x
  attr_reader :y
  attr_reader :radius
  attr_reader :center
  attr_reader :width_range
  attr_reader :height_range

  def initialize(x, y, radius)
    @x = x
    @y = y
    @radius = radius
    create
  end

  def x=(value)
    return if @x == value
    @x = value
    create
  end

  def y=(value)
    return if @y == value
    @y = value
    create
  end

  def radius=(value)
    return if @radius == value
    @radius = value
    create
  end

  def create
    @center = Point.new(@x, @y)
    @width_range = Range.new(@x - @radius, @x + @radius)
    @height_range = Range.new(@y - @radius, @y + @radius)
  end

  def collision(obj)
    case obj.class
      when Point
        point_collision(obj)
      when AABB
        aabb_collision(obj)
      when OBB
        obb_collision(obj)
      when Sphere
        sphere_collision(obj)
      else
        raise "TypeError:不正确类型#{obj.class}!"
    end
  end

  def point_collision(point)
    (point.x - @x) ** 2 + (point.y - @y) ** 2 <= @radius ** 2
  end

  def sphere_collision(sphere)
    point_collision(sphere.point)
  end

  def aabb_collision(aabb)
    # http://www.zhihu.com/question/24251545/answer/27184960
    vx, vy = (@x - aabb.center.x).abs,(@y - aabb.center.y).abs
    hx, hy = (aabb.points[1].x - aabb.center.x).abs, (aabb.points[1].y - aabb.center.y).abs
    ux = vx - hx > 0 ? vx - hx : 0
    uy = vy - hy > 0 ? vy - hy : 0
    ux ** 2 + uy ** 2 <= @radius ** 2
  end

  def obb_collision(obb)
    point = obb.axes.point(@center)
    vx, vy = point.x.abs, point.y.abs
    hx, hy = obb.width / 2, obb.height / 2
    ux = vx - hx > 0 ? vx - hx : 0
    uy = vy - hy > 0 ? vy - hy : 0
    ux ** 2 + uy ** 2 <= @radius ** 2
  end

  def sphere2aabb
    AABB.new(@x - @radius, @y - @radius, @radius * 2, @radius * 2)
  end

  def sphere2obb
    sphere2aabb.aabb2obb
  end

end[/pre]
2D的aabb和obb的简单实现ORZ
碰撞检测部分可略做参考


9.27 更新 添加 Sphere

点评

呸 说错,obb是分离轴定理(SAT这个也能做多边形凸包,只不过运算时间随边数是指数级增长的)  发表于 2016-9-27 00:15
更复杂的还有GJK,方法更通用(任意多边形凸包)只不过我一直没太搞懂support函数(http://www.dyn4j.org/2010/04/gjk-gilbert-johnson-keerthi/)  发表于 2016-9-27 00:05
方法的话AABB和你的应该一样,obb就是简单的轴向分离法(http://www.cnblogs.com/iamzhanglei/archive/2012/06/07/2539751.html)  发表于 2016-9-27 00:04
已更新,添加Sphere。代码长一是因为面向对象,接口实现就得写不少。二是多了一些东西(比如vector2/axes等)  发表于 2016-9-27 00:02
不过也谢谢你的意见啦,以后有意见还请多多提出来,我会参考每个人的意见来做这个系统的。  发表于 2016-9-26 11:08

评分

参与人数 1星屑 +260 收起 理由
丿梁丶小柒 + 260 我很赞同

查看全部评分

附庸的附庸不是我的附庸,女儿的女儿还是我的女儿。CK2沉迷ing
回复 1 0

使用道具 举报

梦石
0
星屑
287
在线时间
1580 小时
注册时间
2010-6-17
回帖
2818

开拓者贵宾

发表于 2016-9-27 08:54:31 | 显示全部楼层
说实话,这个真的不如Unity自带的2d横版好用,反正都要写脚本

点评

好像现在大家都去玩Unity3D了?!  发表于 2016-10-15 15:27
某些地方可能比不上,但是有些地方还是可以比的上的  发表于 2016-9-27 09:24
你觉得RM和Unity能比吗?  发表于 2016-9-27 09:06
快来点我一下,你会豁然开朗的
喵Kano特制
←开发中……

←暂时弃坑 电脑上资源全没
回复

使用道具 举报

梦石
0
星屑
55
在线时间
461 小时
注册时间
2014-7-23
回帖
178
发表于 2016-9-30 11:56:42 | 显示全部楼层
哦~o ~哦~更新了呢,好样的,期待呀,继续吧加油骚年!
回复

使用道具 举报

梦石
0
星屑
4230
在线时间
2671 小时
注册时间
2012-3-1
回帖
680
发表于 2016-10-6 20:50:44 | 显示全部楼层

很久沒來6R了……
回复

使用道具 举报

梦石
0
星屑
3105
在线时间
741 小时
注册时间
2015-2-28
回帖
784

开拓者

发表于 2016-10-7 17:49:03 | 显示全部楼层
很像一位国外大神做的横版物理系统呢 可惜已经不被维护了
楼主加油~
器识为先,文艺其从。
回复

使用道具 举报

永无止境的旅程<

梦石
0
星屑
537
在线时间
1554 小时
注册时间
2012-6-19
回帖
1162

开拓者贵宾

 楼主| 发表于 2016-10-9 19:17:55 | 显示全部楼层
本周已经更新,表示国庆跑去浪了。没做多少
然后浪回来之后我的安卓课程已经进入高级阶段,任务繁多,这个月更新的估计就有点慢了。
慢慢来吧
[url=https://rpg.blue/thread-389697-1-1.html]https://rpg.blue/https://rpg.blue/data/attachment/forum/201602/26/220128cfbxxs47xth4xkz4.jpg[/url]
&lt;font size=&quot;5&quot;&gt;[color=Green][url=https://rpg.blue/forum.php?mod=viewthread&amp;tid=396208&amp;extra=page%3D1][color=DeepSkyBlue]全新配套ACT系统,每周末一大更新,尽请期待。[/color][/url][/color]
回复 1 0

使用道具 举报

脚本白痴

梦石
0
星屑
422
在线时间
903 小时
注册时间
2007-7-9
回帖
1259
发表于 2016-10-9 19:34:50 | 显示全部楼层
虽然我不会用VA,但是用这个和VA就没关系了嘛~ 好像很考验美工的说,还好我是美工

点评

其实……这很考验自己的素材积累量,只要画的总量够多,不出稀奇古怪敌人,同类型敌人或者人物,素材通用啊!越往后越舒服。一起加油吧~  发表于 2016-10-14 08:43

正统向RPG-大雄的高井山奇谈
https://rpg.blue/thread-369758-1-1.html
哆啦A梦RTP风格素材
https://rpg.blue/forum.php?mod=viewthread&tid=394608
回复

使用道具 举报

梦石
0
星屑
35248
在线时间
4171 小时
注册时间
2007-12-15
回帖
9489
发表于 2016-10-13 11:08:27 | 显示全部楼层
本帖最后由 89444640 于 2016-10-13 11:11 编辑

希望作者能在教程中就实现角色的下蹲、站立上中下三段攻击,下蹲上中下三段攻击,滑铲、瞬间前回避,瞬间后回避,5倍身高高跳,防御、反击、当身(架招)、版边反弹、普通投技、指令投、飞行等能力的写法。
能力方面,怒气槽是要有的,
(嗯,常见的act能力应该全了)
小动作诸如按上方向键但是不按跳跃就会抬头,待机一段时间以后随机播放角色小动作动画。等等细节也要~
当然,重力翻转,水中慢动作等场景特效也是我们喜闻乐见的XD

希望成品用脚本,我这种脚本盲能看懂怎么用- -b
图像角色方面应该问题不大,但是主要难点是在敌人,实在做不来就拿各色妖精或者毛玉远程弹幕轰炸- -b
是不是act的类型,敌人用子弹攻击,比敌我都是近身攻击要容易些。弹幕不算,那个完全不知道知道什么公式弄出来的。

控制器方面,能否直接支持街机摇杆,和手柄,否则只能键盘映射,键盘错招困难啊。
回复

使用道具 举报

梦石
0
星屑
14802
在线时间
1014 小时
注册时间
2014-10-24
回帖
325
发表于 2016-10-13 12:14:28 | 显示全部楼层
支持一下
回复

使用道具 举报

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

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部