查看: 914|回复: 2

[交流讨论] rm萌旧的第一个脚本纪念。

[复制链接]
梦石
0
星屑
198
在线时间
23 小时
注册时间
2026-1-7
回帖
8
发表于 2026-1-20 09:34:11 | 显示全部楼层 |阅读模式

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

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

×

由于失业原因,贴主回想起来以前特别喜欢的rmva(都6202年了,还有人学习rgss3。 ),
然后就开始了一系列学习,并写出了人生中第一个能跑的插件。
特此发帖纪念一下。
以下是原代码。(由于是新手,注释和书写都不是很规范,请见谅。)
如果有大佬帮忙指正最好了。有需要的同学可以自取。
1.利用rm引擎自带的方法实现了一个简易的截取当前场景作为战斗背景的小插件。
# 2026/1/19 修正了战斗测试时的bug
#修正图片释放问题。
class Spriteset_Battle
  def initialize
    create_viewports
    create_battleback1
    create_enemies
    create_actors
    create_pictures
    create_timer
    update
  end
  
  def create_battleback1
    @back1_sprite=Sprite.new(@viewport1)
    @back1_sprite.bitmap= battleback1_bitmap
    @back1_sprite.z=0
    @back1_sprite.opacity=128
    center_sprite(@back1_sprite)
   end
  def create_battleback2
  end
  # ● 生成由地图画面加工而来的战场背景
  #--------------------------------------------------------------------------
  def create_blurry_background_bitmap
    if $BTEST
      p "你执行了测试战斗"
      color_bg=Color.new(0,0,0)
      bitmap=Bitmap.new(Graphics.width, Graphics.height)
      bitmap.fill_rect(0,0,Graphics.width,Graphics.height,color_bg)
      bitmap
    else
    source = SceneManager.background_bitmap
     if source
       bitmap = Bitmap.new(Graphics.width, Graphics.height)
       bitmap.stretch_blt(bitmap.rect, source, source.rect)
       bitmap.blur
       bitmap
     end
    end
  end
  def battleback1_bitmap
    create_blurry_background_bitmap
  end
   def update
    update_battleback1
    update_enemies
    update_actors
    update_pictures
    update_timer
    update_viewports
  end
    # ● 释放战场背景的精灵(墙壁)
  #--------------------------------------------------------------------------
  def dispose_battleback2
   
  end
  def dispose_battleback1
    if @back1_sprite
      p "战斗背景图释放了"
      @back1_sprite.bitmap.dispose
      @back1_sprite.dispose
    end
  end
end
2.为敌人添加了一个简易血条。(肥肠丑陋)
class Sprite_Enemy_Hp<Sprite_Base
  attr_accessor :battler
  def initialize(viewport,battler=nil)
    super(viewport)
    p "血条初始化了"
    @battler=battler
    @last_hp=nil
    draw_enemy_hpbar if @battler
  end
  #绘制血条
  def draw_enemy_hpbar
    @enemy_bitmap=Cache.battler(@battler.battler_name,@battler.battler_hue)
    if @battler.alive?
      @width=@enemy_bitmap.width
      @height=10
      self.bitmap.dispose if self.bitmap
      self.bitmap=Bitmap.new(@width,@height)
      init_visibility
      draw_real_enemy_hpbar
    end
  end
  #实际绘制血条bitmap
  
  def draw_real_enemy_hpbar
    @last_hp=@battler.hp
    puts "获取怪物最后血量了"
    color_g=Color.new(10, 255, 50)
    color_r=Color.new(255, 16, 16)
    #设置血条比例
    rate1=(@last_hp.to_f)/@battler.mhp
    #设置血条实际长度
    width_enemy_hp=(@width*rate1).to_i
    self.x=@battler.screen_x-@width/2
    self.y=@battler.screen_y+4
    self.z=200
    if @battler.alive?
    self.bitmap.fill_rect(0,0,@width,@height,Color.new(10,20,64))
    end
    self.bitmap.gradient_fill_rect(2,2,width_enemy_hp-4,@height-4,color_g,color_r)
  end
  
  #初始化可视状态
  def init_visibility
    @battler_visible=@battler.alive?
    self.opacity=0 unless @battler_visible
  end
  #刷新实时血条
  def update
    super
    refresh if @last_hp !=@battler.hp
  end
  # 有变化才更新血条绘制
  def refresh
    return unless self.bitmap
    self.bitmap.clear
    draw_real_enemy_hpbar
  end
  def dispose
      self.bitmap.dispose
      puts "图片释放了!"
      super
    end
end
  
class Spriteset_Battle
  alias hp_initialize initialize
  def initialize
    hp_initialize
    p "【DEBUG】Spriteset_Battle 初始化,准备创建敌人血条"
    @enemy_hp_sprites=[]
    create_enemies_hp
  end
  # 敌人血条精灵生成
  def create_enemies_hp
    return unless $game_troop
    @enemy_hp_sprites=$game_troop.members.map do |enemy|
      Sprite_Enemy_Hp.new(@viewport1,enemy)
    end
    p "血条数组创建了"
  end
  alias hp_dispose dispose
  def dispose
    hp_dispose
    dispose_enemies_hp
  end
  def dispose_enemies_hp
    @enemy_hp_sprites.each{|sprite|sprite.dispose}
  end
  alias hp_update update
  def update
    hp_update
    update_enemies_hp
  end
  def update_enemies_hp
    return unless @enemy_hp_sprites
    @enemy_hp_sprites.each{|sprite|sprite.update}
  end
end
感谢大家!  

老鹰

梦石
40
星屑
37812
在线时间
7091 小时
注册时间
2012-5-26
回帖
3297

极短24评委极短23参与极短22参与极短21评委老司机慢点开短篇十吟唱者组别冠军开拓者剧作品鉴家

发表于 2026-1-20 10:46:43 | 显示全部楼层
现在可以直接问 deepseek 来撰写 RMVA 使用的脚本了,当然,还是可能会有冲突或者数据结构错误,需要自己改正,不过简单的优化应该都没问题了,你可以去试试看。

比如询问
我想将RPG Maker VX Ace中默认菜单里的状态界面的展示八维属性值,修改为展示八边型雷达图,中心点的属性值为0,且不同属性可以设置不同的最大值


它给出了
[fold=DS回复]
[pre lang="ruby"]#==============================================================================
# ** 雷达图状态窗口
#==============================================================================
class Window_Status < Window_Selectable
  # 属性索引映射
  STATS = [
    :maxhp,     # 0 - 最大HP
    :maxmp,     # 1 - 最大MP
    :atk,       # 2 - 攻击力
    :def,       # 3 - 防御力
    :mat,       # 4 - 魔法攻击
    :mdf,       # 5 - 魔法防御
    :agi,       # 6 - 敏捷
    :luk,       # 7 - 幸运
  ]
  
  # 各属性最大值配置
  STAT_MAX = {
    maxhp: 999,    # HP最大值
    maxmp: 999,    # MP最大值
    atk:   999,    # 攻击力最大值
    def:   999,    # 防御力最大值
    mat:   999,    # 魔法攻击最大值
    mdf:   999,    # 魔法防御最大值
    agi:   999,    # 敏捷最大值
    luk:   999,    # 幸运最大值
  }
  
  # 颜色配置(对应8种属性)
  STAT_COLORS = [
    Color.new(255, 50, 50),     # HP - 红色
    Color.new(50, 100, 255),    # MP - 蓝色
    Color.new(255, 150, 50),    # 攻击 - 橙色
    Color.new(100, 200, 100),   # 防御 - 绿色
    Color.new(200, 50, 200),    # 魔攻 - 紫色
    Color.new(50, 200, 200),    # 魔防 - 青色
    Color.new(255, 200, 50),    # 敏捷 - 黄色
    Color.new(200, 100, 200),   # 幸运 - 粉色
  ]
  
  # 雷达图中心位置和半径
  RADAR_CENTER_X = 180
  RADAR_CENTER_Y = 180
  RADAR_RADIUS = 80
  
  #--------------------------------------------------------------------------
  # * 绘制内容
  #--------------------------------------------------------------------------
  def draw_all_items
    draw_radar_chart
    draw_stat_values
    draw_actor_info
  end
  
  #--------------------------------------------------------------------------
  # * 绘制雷达图
  #--------------------------------------------------------------------------
  def draw_radar_chart
    contents.clear
   
    # 绘制雷达图背景
    draw_radar_background
   
    # 绘制雷达图数据区域
    draw_radar_data_area
   
    # 绘制属性标签
    draw_stat_labels
  end
  
  #--------------------------------------------------------------------------
  # * 绘制雷达图背景
  #--------------------------------------------------------------------------
  def draw_radar_background
    # 绘制同心圆
    [0.25, 0.5, 0.75, 1.0].each do |ratio|
      radius = RADAR_RADIUS * ratio
      contents.draw_circle(RADAR_CENTER_X, RADAR_CENTER_Y, radius.to_i, Color.new(100, 100, 100, 100))
    end
   
    # 绘制8条轴线
    8.times do |i|
      angle = i * Math::PI / 4
      x = RADAR_CENTER_X + RADAR_RADIUS * Math.cos(angle)
      y = RADAR_CENTER_Y + RADAR_RADIUS * Math.sin(angle)
      contents.draw_line(RADAR_CENTER_X, RADAR_CENTER_Y, x.to_i, y.to_i, Color.new(150, 150, 150))
    end
  end
  
  #--------------------------------------------------------------------------
  # * 绘制雷达图数据区域
  #--------------------------------------------------------------------------
  def draw_radar_data_area
    return unless @actor
   
    points = []
   
    # 计算每个属性在雷达图上的点
    8.times do |i|
      stat = STATS
      value = @actor.send(stat)
      max_value = STAT_MAX[stat]
      
      # 计算归一化值(0-1范围)
      normalized_value = [[value.to_f / max_value, 1.0].min, 0.0].max
      
      # 计算点在雷达图上的位置
      angle = i * Math::PI / 4 - Math::PI / 2  # 调整起始角度,使顶部为第一个属性
      radius = RADAR_RADIUS * normalized_value
      
      x = RADAR_CENTER_X + radius * Math.cos(angle)
      y = RADAR_CENTER_Y + radius * Math.sin(angle)
      
      points << [x.to_i, y.to_i]
    end
   
    # 绘制填充区域
    fill_color = Color.new(100, 150, 255, 100)
    contents.fill_polygon(points, fill_color)
   
    # 绘制边界线
    points.each_with_index do |point, i|
      next_point = points[(i + 1) % 8]
      contents.draw_line(point[0], point[1], next_point[0], next_point[1], Color.new(50, 100, 255))
    end
   
    # 绘制顶点
    points.each_with_index do |point, i|
      contents.fill_circle(point[0], point[1], 4, STAT_COLORS)
    end
  end
  
  #--------------------------------------------------------------------------
  # * 绘制属性标签
  #--------------------------------------------------------------------------
  def draw_stat_labels
    stat_names = [
      "HP", "MP", "攻击", "防御",
      "魔攻", "魔防", "敏捷", "幸运"
    ]
   
    8.times do |i|
      angle = i * Math::PI / 4 - Math::PI / 2
      # 标签位置在雷达图外侧
      label_radius = RADAR_RADIUS + 40
      x = RADAR_CENTER_X + label_radius * Math.cos(angle)
      y = RADAR_CENTER_Y + label_radius * Math.sin(angle)
      
      # 根据位置调整文本对齐方式
      align = 1  # 默认居中
      if x < RADAR_CENTER_X - 10
        align = 2  # 右对齐(左侧)
      elsif x > RADAR_CENTER_X + 10
        align = 0  # 左对齐(右侧)
      end
      
      change_color(system_color)
      contents.draw_text(x.to_i - 40, y.to_i - 12, 80, 24, stat_names, align)
    end
  end
  
  #--------------------------------------------------------------------------
  # * 绘制属性数值
  #--------------------------------------------------------------------------
  def draw_stat_values
    return unless @actor
   
    # 在雷达图下方显示具体数值
    y = RADAR_CENTER_Y + RADAR_RADIUS + 60
    x = RADAR_CENTER_X - RADAR_RADIUS - 20
   
    STATS.each_with_index do |stat, i|
      row = i / 4
      col = i % 4
      
      draw_x = x + col * 100
      draw_y = y + row * 30
      
      # 属性名
      change_color(system_color)
      contents.draw_text(draw_x, draw_y, 48, 24, STATS_NAMES[stat] || stat.to_s)
      
      # 属性值
      change_color(normal_color)
      value = @actor.send(stat)
      max_value = STAT_MAX[stat]
      contents.draw_text(draw_x + 48, draw_y, 52, 24, "#{value}/#{max_value}", 2)
    end
  end
  
  #--------------------------------------------------------------------------
  # * 绘制角色信息
  #--------------------------------------------------------------------------
  def draw_actor_info
    return unless @actor
   
    # 角色名字
    change_color(normal_color)
    contents.font.size = 20
    contents.draw_text(0, 0, contents.width, 24, @actor.name, 1)
    contents.font.size = Font.default_size
   
    # 角色职业和等级
    draw_x = RADAR_CENTER_X - RADAR_RADIUS - 20
    draw_y = RADAR_CENTER_Y - RADAR_RADIUS - 60
   
    change_color(system_color)
    contents.draw_text(draw_x, draw_y, 120, 24, "职业:")
    change_color(normal_color)
    contents.draw_text(draw_x + 40, draw_y, 80, 24, @actor.class.name)
   
    change_color(system_color)
    contents.draw_text(draw_x, draw_y + 24, 120, 24, "等级:")
    change_color(normal_color)
    contents.draw_text(draw_x + 40, draw_y + 24, 80, 24, @actor.level.to_s)
  end
  
  #--------------------------------------------------------------------------
  # * 属性显示名称
  #--------------------------------------------------------------------------
  STATS_NAMES = {
    maxhp: "HP",
    maxmp: "MP",
    atk:   "攻击",
    def:   "防御",
    mat:   "魔攻",
    mdf:   "魔防",
    agi:   "敏捷",
    luk:   "幸运"
  }
end

#==============================================================================
# ** 图形绘制扩展
#==============================================================================
class Bitmap
  #--------------------------------------------------------------------------
  # * 绘制圆形
  #--------------------------------------------------------------------------
  def draw_circle(cx, cy, radius, color)
    # 简化的圆形绘制
    (0...360).step(5) do |angle|
      rad = angle * Math::PI / 180
      x1 = cx + radius * Math.cos(rad)
      y1 = cy + radius * Math.sin(rad)
      x2 = cx + radius * Math.cos(rad + 0.1)
      y2 = cy + radius * Math.sin(rad + 0.1)
      draw_line(x1.to_i, y1.to_i, x2.to_i, y2.to_i, color)
    end
  end
  
  #--------------------------------------------------------------------------
  # * 填充圆形
  #--------------------------------------------------------------------------
  def fill_circle(cx, cy, radius, color)
    # 简单的实心圆绘制
    (cx - radius..cx + radius).each do |x|
      (cy - radius..cy + radius).each do |y|
        if (x - cx) ** 2 + (y - cy) ** 2 <= radius ** 2
          set_pixel(x, y, color)
        end
      end
    end
  end
  
  #--------------------------------------------------------------------------
  # * 绘制多边形
  #--------------------------------------------------------------------------
  def fill_polygon(points, color)
    return if points.size < 3
   
    # 找到多边形的边界
    min_x = points.map { |p| p[0] }.min
    max_x = points.map { |p| p[0] }.max
    min_y = points.map { |p| p[1] }.min
    max_y = points.map { |p| p[1] }.max
   
    # 简单的多边形填充(扫描线算法简化版)
    (min_y..max_y).each do |y|
      intersections = []
      
      # 计算与每条边的交点
      points.each_with_index do |point, i|
        next_point = points[(i + 1) % points.size]
        x1, y1 = point
        x2, y2 = next_point
        
        # 确保y1 <= y2
        if y1 > y2
          x1, x2 = x2, x1
          y1, y2 = y2, y1
        end
        
        # 如果y在边的高度范围内
        if y >= y1 && y <= y2 && y1 != y2
          # 计算交点x坐标
          x = x1 + (x2 - x1) * (y - y1) / (y2 - y1)
          intersections << x
        end
      end
      
      # 按x坐标排序并成对填充
      intersections.sort!
      (0...intersections.size).step(2) do |i|
        break if i + 1 >= intersections.size
        x1 = intersections.ceil
        x2 = intersections[i + 1].floor
        fill_rect(x1, y, x2 - x1 + 1, 1, color) if x2 >= x1
      end
    end
  end
end[/pre]
[/fold]

但实际运行时就发现,bitmap类没有 draw_line 方法,那继续问
补充 draw_line(x1.to_i, y1.to_i, x2.to_i, y2.to_i, color) 的具体实现


它再回复
[fold=DS回复]
[pre lang="ruby"]#==============================================================================
# ** Bitmap图形绘制扩展
#==============================================================================
class Bitmap
  #--------------------------------------------------------------------------
  # * 绘制直线(Bresenham算法)
  #--------------------------------------------------------------------------
  def draw_line(x1, y1, x2, y2, color)
    # 确保起点和终点的整数坐标
    x1, y1 = x1.to_i, y1.to_i
    x2, y2 = x2.to_i, y2.to_i
   
    # 使用Bresenham直线算法
    dx = (x2 - x1).abs
    dy = (y2 - y1).abs
   
    # 确定步进方向
    sx = x1 < x2 ? 1 : -1
    sy = y1 < y2 ? 1 : -1
   
    err = dx - dy
   
    loop do
      # 绘制当前像素(确保在边界内)
      set_pixel(x1, y1, color) if in_bounds?(x1, y1)
      
      # 到达终点
      break if x1 == x2 && y1 == y2
      
      e2 = 2 * err
      
      if e2 > -dy
        err -= dy
        x1 += sx
      end
      
      if e2 < dx
        err += dx
        y1 += sy
      end
    end
  end
  
  #--------------------------------------------------------------------------
  # * 绘制圆形轮廓(中点圆算法)
  #--------------------------------------------------------------------------
  def draw_circle(cx, cy, radius, color)
    cx, cy, radius = cx.to_i, cy.to_i, radius.to_i
   
    x = radius
    y = 0
    err = 0
   
    while x >= y
      # 绘制8个对称点
      draw_circle_points(cx, cy, x, y, color)
      
      y += 1
      err += 1 + 2 * y
      
      if 2 * (err - x) + 1 > 0
        x -= 1
        err += 1 - 2 * x
      end
    end
  end
  
  #--------------------------------------------------------------------------
  # * 绘制圆形的8个对称点
  #--------------------------------------------------------------------------
  def draw_circle_points(cx, cy, x, y, color)
    # 八个对称点
    points = [
      [cx + x, cy + y], [cx - x, cy + y],
      [cx + x, cy - y], [cx - x, cy - y],
      [cx + y, cy + x], [cx - y, cy + x],
      [cx + y, cy - x], [cx - y, cy - x]
    ]
   
    points.each do |px, py|
      set_pixel(px, py, color) if in_bounds?(px, py)
    end
  end
  
  #--------------------------------------------------------------------------
  # * 填充圆形(扫描线填充)
  #--------------------------------------------------------------------------
  def fill_circle(cx, cy, radius, color)
    cx, cy, radius = cx.to_i, cy.to_i, radius.to_i
   
    # 确保半径为正
    return if radius <= 0
   
    # 扫描线填充
    (-radius..radius).each do |y|
      # 计算当前扫描线的x范围
      x_span = Math.sqrt(radius * radius - y * y).to_i
      next if x_span <= 0
      
      # 绘制水平线
      x1 = cx - x_span
      x2 = cx + x_span
      
      # 确保在边界内
      x1 = 0 if x1 < 0
      x2 = width - 1 if x2 >= width
      y_pos = cy + y
      
      # 绘制扫描线
      if y_pos >= 0 && y_pos < height
        fill_rect(x1, y_pos, x2 - x1 + 1, 1, color)
      end
    end
  end
  
  #--------------------------------------------------------------------------
  # * 绘制矩形轮廓
  #--------------------------------------------------------------------------
  def draw_rect(x, y, width, height, color)
    x, y = x.to_i, y.to_i
    width, height = width.to_i, height.to_i
   
    # 上边
    fill_rect(x, y, width, 1, color) if height > 0
    # 下边
    fill_rect(x, y + height - 1, width, 1, color) if height > 0
    # 左边
    fill_rect(x, y, 1, height, color) if width > 0
    # 右边
    fill_rect(x + width - 1, y, 1, height, color) if width > 0
  end
  
  #--------------------------------------------------------------------------
  # * 绘制多边形轮廓
  #--------------------------------------------------------------------------
  def draw_polygon(points, color)
    return if points.size < 2
   
    # 绘制多边形的每条边
    points.each_with_index do |point, i|
      next_point = points[(i + 1) % points.size]
      draw_line(point[0], point[1], next_point[0], next_point[1], color)
    end
  end
  
  #--------------------------------------------------------------------------
  # * 填充多边形(扫描线算法)
  #--------------------------------------------------------------------------
  def fill_polygon(points, color)
    return if points.size < 3
   
    # 找到多边形的边界
    min_y = points.map { |p| p[1].to_i }.min
    max_y = points.map { |p| p[1].to_i }.max
   
    # 对每条扫描线处理
    min_y.upto(max_y) do |scan_y|
      intersections = []
      
      # 检查每条边与扫描线的交点
      points.each_with_index do |point, i|
        next_point = points[(i + 1) % points.size]
        x1, y1 = point[0].to_i, point[1].to_i
        x2, y2 = next_point[0].to_i, next_point[1].to_i
        
        # 确保y1 <= y2
        if y1 > y2
          x1, x2 = x2, x1
          y1, y2 = y2, y1
        end
        
        # 检查扫描线是否与边相交
        if scan_y >= y1 && scan_y <= y2
          # 排除水平线
          if y1 != y2
            # 计算交点x坐标
            x_intersect = x1 + (scan_y - y1) * (x2 - x1).to_f / (y2 - y1)
            intersections << x_intersect
          end
        end
      end
      
      # 排序交点
      intersections.sort!
      
      # 成对填充
      (0...intersections.size).step(2) do |i|
        break if i + 1 >= intersections.size
        
        x_start = intersections.ceil
        x_end = intersections[i + 1].floor
        
        # 确保在边界内
        x_start = 0 if x_start < 0
        x_end = self.width - 1 if x_end >= self.width
        
        # 绘制扫描线段
        if scan_y >= 0 && scan_y < self.height && x_end >= x_start
          fill_rect(x_start, scan_y, x_end - x_start + 1, 1, color)
        end
      end
    end
  end
  
  #--------------------------------------------------------------------------
  # * 绘制带圆角的矩形
  #--------------------------------------------------------------------------
  def draw_rounded_rect(x, y, width, height, radius, color)
    x, y = x.to_i, y.to_i
    width, height = width.to_i, height.to_i
    radius = radius.to_i
   
    # 限制圆角半径不超过矩形尺寸的一半
    radius = [radius, width / 2, height / 2].min
   
    # 绘制四个圆角
    draw_circle_arc(x + radius, y + radius, radius, 180, 270, color)  # 左上
    draw_circle_arc(x + width - radius, y + radius, radius, 270, 360, color)  # 右上
    draw_circle_arc(x + width - radius, y + height - radius, radius, 0, 90, color)  # 右下
    draw_circle_arc(x + radius, y + height - radius, radius, 90, 180, color)  # 左下
   
    # 绘制四条直线
    # 上边
    fill_rect(x + radius, y, width - 2 * radius, 1, color) if width > 2 * radius
    # 下边
    fill_rect(x + radius, y + height - 1, width - 2 * radius, 1, color) if width > 2 * radius
    # 左边
    fill_rect(x, y + radius, 1, height - 2 * radius, color) if height > 2 * radius
    # 右边
    fill_rect(x + width - 1, y + radius, 1, height - 2 * radius, color) if height > 2 * radius
  end
  
  #--------------------------------------------------------------------------
  # * 绘制圆弧
  #--------------------------------------------------------------------------
  def draw_circle_arc(cx, cy, radius, start_angle, end_angle, color)
    cx, cy, radius = cx.to_i, cy.to_i, radius.to_i
   
    # 角度转弧度
    start_rad = start_angle * Math::PI / 180
    end_rad = end_angle * Math::PI / 180
   
    # 确保结束角度大于起始角度
    if end_rad < start_rad
      end_rad += 2 * Math::PI
    end
   
    # 步长根据半径调整
    step = 1.0 / radius
   
    # 绘制圆弧
    theta = start_rad
    while theta <= end_rad
      x = (cx + radius * Math.cos(theta)).to_i
      y = (cy + radius * Math.sin(theta)).to_i
      
      set_pixel(x, y, color) if in_bounds?(x, y)
      
      theta += step
    end
  end
  
  #--------------------------------------------------------------------------
  # * 绘制三角形
  #--------------------------------------------------------------------------
  def draw_triangle(x1, y1, x2, y2, x3, y3, color)
    points = [[x1, y1], [x2, y2], [x3, y3]]
    draw_polygon(points, color)
  end
  
  #--------------------------------------------------------------------------
  # * 填充三角形
  #--------------------------------------------------------------------------
  def fill_triangle(x1, y1, x2, y2, x3, y3, color)
    points = [[x1, y1], [x2, y2], [x3, y3]]
    fill_polygon(points, color)
  end
  
  #--------------------------------------------------------------------------
  # * 绘制贝塞尔曲线(二次)
  #--------------------------------------------------------------------------
  def draw_bezier_curve(x1, y1, x2, y2, cx, cy, color, segments = 20)
    # 二次贝塞尔曲线公式: B(t) = (1-t)²P₀ + 2(1-t)tP₁ + t²P₂
    segments.times do |i|
      t1 = i.to_f / segments
      t2 = (i + 1).to_f / segments
      
      # 计算点
      px1 = (1 - t1) * (1 - t1) * x1 + 2 * (1 - t1) * t1 * cx + t1 * t1 * x2
      py1 = (1 - t1) * (1 - t1) * y1 + 2 * (1 - t1) * t1 * cy + t1 * t1 * y2
      
      px2 = (1 - t2) * (1 - t2) * x1 + 2 * (1 - t2) * t2 * cx + t2 * t2 * x2
      py2 = (1 - t2) * (1 - t2) * y1 + 2 * (1 - t2) * t2 * cy + t2 * t2 * y2
      
      # 绘制线段
      draw_line(px1.to_i, py1.to_i, px2.to_i, py2.to_i, color)
    end
  end
  
  #--------------------------------------------------------------------------
  # * 绘制虚线
  #--------------------------------------------------------------------------
  def draw_dashed_line(x1, y1, x2, y2, color, dash_length = 4, gap_length = 4)
    # 计算线段总长度和方向
    dx = x2 - x1
    dy = y2 - y1
    length = Math.sqrt(dx * dx + dy * dy)
   
    # 单位向量
    ux = dx / length
    uy = dy / length
   
    # 绘制虚线
    current_length = 0
    while current_length < length
      # 线段的起始和结束
      seg_start = current_length
      seg_end = [current_length + dash_length, length].min
      
      # 计算实际坐标
      sx1 = x1 + ux * seg_start
      sy1 = y1 + uy * seg_start
      sx2 = x1 + ux * seg_end
      sy2 = y1 + uy * seg_end
      
      # 绘制实线段
      draw_line(sx1.to_i, sy1.to_i, sx2.to_i, sy2.to_i, color)
      
      # 移动到下一段
      current_length = seg_end + gap_length
    end
  end
  
  #--------------------------------------------------------------------------
  # * 检查坐标是否在边界内
  #--------------------------------------------------------------------------
  def in_bounds?(x, y)
    x >= 0 && x < self.width && y >= 0 && y < self.height
  end
  
  #--------------------------------------------------------------------------
  # * 绘制带箭头的线
  #--------------------------------------------------------------------------
  def draw_arrow_line(x1, y1, x2, y2, color, arrow_size = 6)
    # 绘制主线段
    draw_line(x1, y1, x2, y2, color)
   
    # 计算箭头方向
    dx = x2 - x1
    dy = y2 - y1
    angle = Math.atan2(dy, dx)
   
    # 箭头角度
    arrow_angle1 = angle + Math::PI - Math::PI / 6
    arrow_angle2 = angle + Math::PI + Math::PI / 6
   
    # 计算箭头顶点
    ax1 = x2 + arrow_size * Math.cos(arrow_angle1)
    ay1 = y2 + arrow_size * Math.sin(arrow_angle1)
    ax2 = x2 + arrow_size * Math.cos(arrow_angle2)
    ay2 = y2 + arrow_size * Math.sin(arrow_angle2)
   
    # 绘制箭头
    draw_line(x2, y2, ax1.to_i, ay1.to_i, color)
    draw_line(x2, y2, ax2.to_i, ay2.to_i, color)
  end
end[/pre][/fold]

基于以上,我修改后就获得了一个可以通用的雷达图绘制方法,一是形状绘制,二是雷达图绘制,比以前效率高出不少。

也因此,挺推荐新人尝试在编写独立功能插件时,先问问AI。
回复

使用道具 举报

梦石
0
星屑
198
在线时间
23 小时
注册时间
2026-1-7
回帖
8
 楼主| 发表于 2026-1-20 11:08:47 | 显示全部楼层
百里_飞柳 发表于 2026-1-20 10:46
现在可以直接问 deepseek 来撰写 RMVA 使用的脚本了,当然,还是可能会有冲突或者数据结构错误,需要自己改 ...

好的,感谢大佬
回复

使用道具 举报

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

本版积分规则

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

在本版发帖返回顶部