3D游戏大家也见过很多了,机品飞车,孤岛危机这些游戏都是,
这种效果是通过使用复杂的数学公式来产生的一种透视的效果。
由于RMXP是2D游戏引擎,因此无法做出真实的3D效果,但是通
过一些简单的数学公式也可以产生比较简单的3D透视感觉。
本人做了个仿3D的旋转菜单,以供参考:
如图:
核心代码:[code]#--------------------------------------------------------------------------# ● 仿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_3D include Math2 attr_accessor :menu_x attr_accessor :menu_y attr_accessor :disx attr_accessor :disy attr_accessor :speed attr_accessor :active attr_accessor :index def 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([sprite,0,0]) #angle, y @index=i end end def update if @isRotating == true depthArray=[] #临时的 angle = 360 / @child_num for z in 0...@child_num mc=@menu_sprite[z][0] mc.bitmap=@menu_bitmap[z] @menu_sprite[z][1] = @tempAngle + @speed + angle * z @menu_sprite[z][2] = sinD(@menu_sprite[z][1]) * @disy mc.x = (cosD(@menu_sprite[z][1]) * @disx + @menu_x).round mc.y = @menu_sprite[z][2] + @menu_y mc.visible=true depthArray[z] = [mc,@menu_sprite[z][2]] #mc, y setProp(mc,"alpha",@menu_sprite[z][2]) setProp(mc,"scaleX",@menu_sprite[z][2],0.2,1) setProp(mc,"scaleY",@menu_sprite[z][2],0.2,1) end arrange(depthArray); @speed += (@endAngle-@speed) * 0.2; if ((@speed - @endAngle).abs < 0.1) initAngle(false) if @moveDir==-1 [email protected] @index.insert(0,last) elsif @moveDir==1 [email protected] @index.push(frist) end @menu_sprite[@index[0]][0].flash(Color.new(255,255,255,255),40) @frame=0 end end if @isRotating == false @menu_sprite[@index[0]][0].update return if @active==false @frame+=1 return if @frame -180 && @endAngle < -90)? -270 - @endAngle:90 - @endAngle initAngle(true) end def dispose for i in 0...@child_num @menu_sprite[0].bitmap.dispose @menu_sprite[0].dispose end end def active=(active) @active=active if @active==true @menu_sprite[@index[0]][0].flash(Color.new(255,255,255,255),40) @frame=0 end end def initAngle(b) if (@isRotating) @tempAngle += @speed end @speed = 0 @isRotating = b end def arrange(depthArray) depthArray.sort!{|a,b|a[1]b[1]} i = depthArray.size while i>0 i-=1 depthArray[0].z=i+9990 end end def 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 end end def index return @index[0] end 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