じ☆ve冰风 发表于 2024-4-19 20:51:01

仿3D旋转菜单

3D游戏大家也见过很多了,机品飞车,孤岛危机这些游戏都是,
这种效果是通过使用复杂的数学公式来产生的一种透视的效果。
由于RMXP是2D游戏引擎,因此无法做出真实的3D效果,但是通
过一些简单的数学公式也可以产生比较简单的3D透视感觉。
本人做了个仿3D的旋转菜单,以供参考:
如图:




核心代码:#--------------------------------------------------------------------------# ● 仿3D旋转菜单效果# 制作者小飞侠_shoed#---------------------------------------------------------------------------module Math2#角度转弧度def angleToRadian(angle)    return angle*(Math::PI/180)end#弧度转角度def radianToAngle(radian)    return radian*(180/Math::PI)end    #计算正弦值def sinD(angle)    return Math.sin(angleToRadian(angle))end    #计算余弦值def cosD(angle)    return Math.cos(angleToRadian(angle))end#计算反正切def atan2D(y, x)    return radianToAngle(Math.atan2(y, x))endendclass RotateMenu_3Dinclude Math2    attr_accessor :menu_xattr_accessor :menu_yattr_accessor :disxattr_accessor :disyattr_accessor :speedattr_accessor :activeattr_accessor :indexdef initialize    @active=false    @menu_x=400    @menu_y=240      @disx=180    @disy=10    @speed=0      @endAngle=90    @tempAngle=0    @isRotating=true      backImage=RPG::Cache.picture("back")      @child_num=$game_party.actors.size    @menu_sprite=[]    @menu_bitmap=[]    @index=[]    for i in 0...$game_party.actors.size      @menu_bitmap=Bitmap.new(backImage.width,backImage.height)      @menu_bitmap.blt(0,0,backImage,Rect.new(0,0,backImage.width,backImage.height))            sprite=Sprite.new      sprite.bitmap=@menu_bitmap            sprite.ox=@menu_bitmap.width/2      sprite.oy=@menu_bitmap.height/2      sprite.visible=false      sprite.z=i+9990            set_actor($game_party.actors,sprite)            @menu_sprite.push() #angle, y            @index=i          endend    def update    if @isRotating == true      depthArray=[] #临时的      angle = 360 / @child_num      for z in 0...@child_num      mc=@menu_sprite      mc.bitmap=@menu_bitmap                @menu_sprite = @tempAngle + @speed + angle * z      @menu_sprite = sinD(@menu_sprite) * @disy      mc.x = (cosD(@menu_sprite) * @disx + @menu_x).round      mc.y = @menu_sprite + @menu_y      mc.visible=true                depthArray = ] #mc, y      setProp(mc,"alpha",@menu_sprite)      setProp(mc,"scaleX",@menu_sprite,0.2,1)         setProp(mc,"scaleY",@menu_sprite,0.2,1)       end            arrange(depthArray);      @speed += (@endAngle-@speed) * 0.2;      if ((@speed - @endAngle).abs < 0.1)      initAngle(false)                if @moveDir==-1                    @index.insert(0,last)      elsif @moveDir==1                    @index.push(frist)      end                @menu_sprite[@index].flash(Color.new(255,255,255,255),40)      @frame=0      end    end    if @isRotating == false      @menu_sprite[@index].update            return if @active==false             @frame+=1      return if @frame -180 && @endAngle < -90)? -270 - @endAngle:90 - @endAngle    initAngle(true)enddef dispose    for i in 0...@child_num      @menu_sprite.bitmap.dispose      @menu_sprite.dispose    endend    def active=(active)    @active=active    if @active==true      @menu_sprite[@index].flash(Color.new(255,255,255,255),40)      @frame=0    endend    def initAngle(b)            if (@isRotating)                  @tempAngle += @speed    end    @speed = 0    @isRotating = benddef arrange(depthArray)    depthArray.sort!{|a,b|ab}    i = depthArray.size    while i>0      i-=1      depthArray.z=i+9990    endenddef setProp(mc,prop,sy,n1=0.5,n2=1)    if prop=="alpha"      opacity = ((sy + 2 * @disy) / @disy - 1) / 2 * (n2 - n1) + n1      mc.opacity=opacity*255    elsif prop=="scaleX"      mc.zoom_x = ((sy + 2 * @disy) / @disy - 1) / 2 * (n2 - n1) + n1    elsif prop=="scaleY"      mc.zoom_y = ((sy + 2 * @disy) / @disy - 1) / 2 * (n2 - n1) + n1    endenddef index    return @indexend    def set_actor(actor,sprite)      bitmap = RPG::Cache.battler(actor.battler_name, actor.battler_hue)    src_rect=Rect.new(0,0,bitmap.width,bitmap.height)    sprite.bitmap.blt(10, 10, bitmap, src_rect)    sprite.bitmap.font.size=18      sprite.bitmap.font.color = Color.new(192, 224, 255, 255)    sprite.bitmap.draw_text(128, 10, 24, 24, "Lv")    sprite.bitmap.font.color = Color.new(255, 255, 255, 255)    sprite.bitmap.draw_text(128 + 24, 10, 24, 24, actor.level.to_s, 2)      sprite.bitmap.draw_text(128, 36, 120, 24, actor.name)      sprite.bitmap.draw_text(128, 62, 120, 24, actor.class_name)            text = make_battler_state_text(actor, 120, true)    if actor.hp == 0      sprite.bitmap.font.color = Color.new(255, 64, 0)    else      sprite.bitmap.font.color = Color.new(255, 255, 255, 255)    end    sprite.bitmap.draw_text(128, 88, 120, 24, text)            sprite.bitmap.draw_text(16, 190, 24, 24, $data_system.words.hp)    if actor.hp == 0      sprite.bitmap.font.color = Color.new(255, 64, 0)    elsif actor.hp
页: [1]
查看完整版本: 仿3D旋转菜单