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

Project1

 找回密码
 注册会员
搜索

复刻FC封神榜,如何实现类似跳跃的战斗移位?难题。。。

查看数: 4272 | 评论数: 7 | 收藏 1
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2019-6-15 15:28

正文摘要:

本帖最后由 miantouchi 于 2019-6-17 20:33 编辑 如何实现类似跳跃的战斗移位? 封神榜这个游戏战斗系统人物移动这块有点怪,既不是大多数的齐动画、也不是真移位 真移位,是图片平移过去,而这个游戏是战斗图片 ...

回复

优乐美 发表于 2022-12-10 10:50:01

大佬,你能不能把之前那个跳跃战斗范例发下给我,谢谢了。
KB.Driver 发表于 2019-6-17 23:27:40


详见私信

点评

辛苦了!不管怎么把跳跃功能加到战斗里面了。  发表于 2019-6-18 06:38
全员跳中间表演..233  发表于 2019-6-18 00:17

评分

参与人数 2星屑 +250 +2 收起 理由
miantouchi + 1 认可答案
RyanBern + 250 + 1 认可答案

查看全部评分

guoxiaomi 发表于 2019-6-16 20:27:20
本帖最后由 guoxiaomi 于 2019-6-16 20:33 编辑

现成的公式在XP的跳跃处理中,XP中有一条事件指令可以让地图上的角色从一个点跳跃到另一个点,在跳跃过程中角色走的路线是抛物线。接下来分析XP是如何实现抛物线的路线的:

我们顺藤摸瓜,首先找到 Game_Character 3 的 jump 方法,在此方法里,执行了以下任务:
1. 调整角色的朝向
2. 将@x和@y设置为目标位置的值
3. 设置跳跃计时@jump_count = @jump_peak * 2

随后找到Game_Character 2 中的 update_jump 方法:
RUBY 代码复制
  1. #--------------------------------------------------------------------------
  2.   # ● 更新画面 (跳跃)
  3.   #--------------------------------------------------------------------------
  4.   def update_jump
  5.     # 跳跃计数减 1
  6.     @jump_count -= 1
  7.     # 计算新坐标
  8.     @real_x = (@real_x * @jump_count + @x * 128) / (@jump_count + 1)
  9.     @real_y = (@real_y * @jump_count + @y * 128) / (@jump_count + 1)
  10.   end

从这里可以看出,每次更新的时候,@jump_count 会减少 1,最终一直减少到 0。同时,角色的@real_x和@real_y会用此递推公式进行更新。
为了庆祝高考结束,现场解一下递推公式,暂不考虑整除的影响:
数列Sn表示角色的@real_x在第 n 帧的值,则有:@jump_count = N - n,其中 N 是 @jump_count 的初始值。代入递推公式:
S[n+1] = (S[n] * (N - n) + X) / (N - n + 1),这里用 X 代替了 @x * 128,在整个跳跃过程中是不变的。同时我们还知道 S[0] = 初始位置的 @real_x。
整理递推公式得:
S[n+1] / (N - n) - S[n] / (N - n + 1) = X / (N - n) - X / (N - n + 1)
取n=0,1,2...a - 1,代入上面的式子,左右两边分别求和消去相同的项:
S[a] / (N - a  + 1) - S[0] / N = X / (N - a + 1) - X / N
得到:
S[a] = S[0] - a * (S[0] - X) / N,是一个等差数列。在a = 0的时候,值为S[0],在a = N的时候,值为X。

上面的推导说明了,在跳跃过程中,角色的真实位置@real_x和@real_y是匀速变换到目标位置的。这个和看上去的抛物线路径并不一样,所以找到最后的地方:Game_Character 1 的 screen_y 方法:
RUBY 代码复制
  1. #--------------------------------------------------------------------------
  2.   # ● 获取画面 Y 坐标
  3.   #--------------------------------------------------------------------------
  4.   def screen_y
  5.     # 通过实际坐标和地图的显示位置来求得画面坐标
  6.     y = (@real_y - $game_map.display_y + 3) / 4 + 32
  7.     # 取跳跃计数小的 Y 坐标
  8.     if @jump_count >= @jump_peak
  9.       n = @jump_count - @jump_peak
  10.     else
  11.       n = @jump_peak - @jump_count
  12.     end
  13.     return y - (@jump_peak * @jump_peak - n * n) / 2
  14.   end

在跳跃过程中,y值有一个修正项:y = y0 - 1/2 * (N*N - n*n),在这里用 N 表示 @jump_peak。
注意在跳跃过程中,@jump_count 的值从 @jump_peak * 2 逐步减少到 0,对应 n 的变化范围正好是从 -N 到 N,所以 screen_y 增量从 0 逐渐增大最后回落到 0。
实际显示的角色位置,是一个在 y 方向上与时间呈二次方关系的运动,叠加上角色本身的匀速运动,这是一条抛物线。

最终结论是,直接用XP自带的跳跃功能就行了。

点评

最近没空呀  发表于 2019-6-17 23:05
做一回伸手党了,抱歉  发表于 2019-6-17 20:37
我把简单的战斗范例传到主楼了,麻烦帮我整合一下吧,确实不太会把Game_Character整合到战斗场景里面。  发表于 2019-6-17 20:32
系统默认的是需要自己输入x,y数值,现在要自动计算,我先试试,不行发工程帮我弄弄哈。  发表于 2019-6-17 13:30
我在战斗里面调用,需要修改代码吧  发表于 2019-6-17 13:07
KB.Driver 发表于 2019-6-16 20:09:41
本帖最后由 KB.Driver 于 2019-6-16 20:13 编辑

瞎写的玩意,感觉有不少问题,不太追求完美就自己改改参数凑合着用吧
RUBY 代码复制
  1. Velocity = Struct.new(:x, :y)
  2.  
  3. class Sprite
  4.  
  5.   #--------------------------------------------------------------------------
  6.   # ● 设置跳跃
  7.   #     x_inc - X坐标增量
  8.   #     y_inc - Y坐标增量
  9.   #     duration - 总体时间
  10.   #     top_inc  - 跳跃高度(可选)
  11.   #--------------------------------------------------------------------------
  12.   def set_jump(x_inc, y_inc, duration, top_inc = [y_inc, 0].max + 20)
  13.     new_x = self.x + x_inc
  14.     new_y = self.y - y_inc
  15.     top_y = self.y - top_inc
  16.     set_jump_xy(new_x, new_y, top_y, duration)
  17.   end
  18.  
  19.   def set_jump_xy(new_x, new_y, top_y, duration)
  20.     raise "set_jump: top_y should not be smaller than new_y" if top_y > new_y
  21.  
  22.     t = duration / 2
  23.     ay = 2 * (top_y - self.y).abs / (t * t).to_f
  24.     vx = (new_x - self.x) / t.to_f
  25.     vy = (top_y - self.y).abs / t.to_f + 0.5 * ay * t
  26.  
  27.     @v = Velocity.new(vx, vy)
  28.     @ay = ay
  29.     @t = 0
  30.     @new_x, @new_y, @top_y = new_x, new_y, top_y
  31.     @real_x, @real_y = self.x, self.y
  32.     @duration = duration
  33.     @jump_state = :up
  34.   end
  35.  
  36.   def update_jump
  37.     return if !jumping?
  38.  
  39.     @real_x += @v.x
  40.     @real_y -= @v.y
  41.  
  42.     @v.y -= @ay
  43.     if @jump_state == :up
  44.       @real_y = [@real_y, @top_y].max
  45.       if @v.y <= 0 || @real_y == @top_y
  46.         #@v.y = 0
  47.         @jump_state = :down
  48.       end
  49.     else # down
  50.       @real_y = [@real_y, @new_y].min
  51.     end
  52.  
  53.     self.x, self.y = @real_x, @real_y
  54.  
  55.     if @t == @duration || self.y == @new_y
  56.       clear_jump
  57.     else
  58.       @t += 1
  59.     end
  60.   end
  61.  
  62.   def clear_jump
  63.     @v = nil
  64.     @ay = nil
  65.     @t = nil
  66.     @new_x = @new_y = @top_y = nil
  67.     @real_x = @real_y = nil
  68.     @duration = nil
  69.     @jump_state = nil
  70.   end
  71.  
  72.   def jumping?
  73.     !@jump_state.nil?
  74.   end
  75. end


Sprite#update_jump没有写进Sprite#update里面,需要你在对应场景的update中添加
一个使用范例(插入Main以上)

RUBY 代码复制
  1. sprite = Sprite.new
  2. sprite.bitmap = Bitmap.new("Graphics/Characters/001-Fighter01")
  3. sprite.src_rect.set(0, 0, sprite.bitmap.width / 4, sprite.bitmap.height / 4)
  4. sprite.x = 640 / 2
  5. sprite.y = 480 / 2
  6.  
  7. sprite.set_jump(50, 50, 30)
  8. while sprite.jumping? do
  9.   sprite.update_jump
  10.   Graphics.update
  11. end
  12.  
  13. sprite.set_jump(-50, -50, 30)
  14. while sprite.jumping? do
  15.   sprite.update_jump
  16.   Graphics.update
  17. end


gif:



点评

我把战斗工程上传主楼了,不太会整合你的脚本,麻烦做个范例。里面有战斗图和跳跃时候的图片  发表于 2019-6-17 20:31
谢谢,等我研究研究,不会再呼叫你  发表于 2019-6-16 20:58
芯☆淡茹水 发表于 2019-6-15 22:56:52
本帖最后由 芯☆淡茹水 于 2019-6-15 23:01 编辑

两点(站位点和怪面前点)
跳跃持续时间(帧数)
确定跳跃幅度并计算每帧xy移动量。
抛物线算法本人不会,当然如果硬憋,憋一天估计会写出一个不是太好的算法。

点评

能实现效果就行,有现成的公式能写出来吗?  发表于 2019-6-16 13:08
hyrious 发表于 2019-6-15 18:41:47
我觉得他是事先算好了 y 轴写死的……
以角色待机状态坐标为原点,向上为正数,y 轴变化依次是:-4 55 112 130 100 53(肉眼量的,你可以自己调整x
然后根据抛物线,x 轴平移即可

点评

查表大法好( ̄▽ ̄)  发表于 2019-6-16 21:03
能否写出?我是没这个水平。  发表于 2019-6-16 13:07
灯笼菜刀王 发表于 2019-6-15 15:53:25
本帖最后由 灯笼菜刀王 于 2019-6-15 15:58 编辑

这个就是真位移了, 一样是每帧改变精灵坐标, 只不过是点和点之间用抛物线移动而不是直线移动

至于怎么做, 你写个公式来让精灵的坐标呈抛物线刷新就可以了, 别问我抛物线公式怎么写, 我只会四则运算


其实复刻又不一定要照搬, 我觉得用RM的素材和模式做出"换汤版"更有味道, 毕竟要FC的那种画面直接去玩原版就好了何必玩你的作品呢~

看看SE, 人家炒个十年前的冷饭都至少也是来个高清版加几个葱花再拿出来捞钱呢

点评

我人生中玩的第一款RPG游戏,改画质的画,实在是找不着感觉了。  发表于 2019-6-15 16:02
复刻这个像素游戏,就是个人情怀吧。打算把像素风格完成后,再制作一些画质好的游戏。  发表于 2019-6-15 16:01
还需要找一个算术好的。  发表于 2019-6-15 15:58
哈,我现在用的真移位,匀速直线运动,傻傻的,平拖图片感觉。  发表于 2019-6-15 15:57
拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

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

GMT+8, 2024-11-1 08:13

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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