一派护法 十九级 |
#克蓝娜德 CNGAMES =begin 把下面的字符加到你的地图名里面 [W3D] - 使用伪3D 如果你不填的话 就木有效果 [#XX] - XX = 叉叉范围是0-89之间 惯例用了我给你的伪3D看到这个是不是有违和感 [-X] - X = 这个X的范围是0或者1 0为显示两面墙 1为仅显示 法线正面的墙(只是个概念伪3D肿么会有法线,也就是正面朝着你的墙) 如果你不写[#XX]或者[-X]就会使用默认的 默认参数为: [#XX] = [#45] [-X] = [-1] =end class Game_System alias initialize_W3D initialize attr_reader :factor attr_reader :correct attr_reader :scroll_y attr_reader :distance attr_reader :angle attr_reader :height attr_reader :columns attr_reader :filter attr_reader :zoom attr_accessor :new_zoom attr_accessor :hidewalls attr_accessor :hide attr_accessor :new_angle attr_accessor :need_refresh attr_accessor :coord def initialize initialize_W3D @zoom = 1.00 @scroll_y = 256#相机与角色的距离 @height = 1 #地图原件的高度,建议不要改 除非你做特殊效果 @columns = 16 #伪3D图块的质量,值为8或者16。如果场景不大可以用16。 #针对纵面 8的话图块边缘锯齿比较大,流畅。16边缘锯齿较小,卡。 @filter = 2*32 #纵向墙的高度设定(如果增加高度 不要忘了在上面加上标志) @hidewalls = 1 #这个就是默认的双面还是单面墙显示的值,值为0或1。 @distance = 480#焦距 玩过相机的人都知道 值不要太低,默认为480,不要低于256。 #焦距值越高看到纵面的墙壁面积就越少,越低看到的墙壁面积就越多。 @hide = 0#角色与原件距离的Y坐标的值,用于遮挡角色时半透明。 #一个原件为32像素所以值至少为33 不然低于33 你脸贴到墙上墙都不会管你。 self.angle = 45 #摄像机角度 #以上属性均可在游戏中更改,用事件页第三页的脚本调用 格式为: #$game_system.(属性) = value(值) #举个例子: #$game_system.zoom = 1.5 #(1.5为放大150%) #或者 #$game_system.columns = 8 #以下为内部使用,请勿随意更改 @new_angle = false @need_refresh = false @new_zoom = false @coord = nil end #部分脚本基于Neo Mode07。 def zoom=(n) if @zoom != n @new_zoom = true end @zoom = n end def refresh(x,y) @coord = [x,y] end def screen2W3D_y(y) y *= @zoom return @scroll_y + (@cd * y) / (@distance - y * @sinus) end def screen2map_y(y) return ((@distance * (@scroll_y - y) / @zoom / (@dif - y * @sinus) + @scroll_y)) end def screen2zoom(y) return (y * @factor + @correct) * @zoom end def angle=(n) @angle = n @cosinus = Math.cos(Math::PI * (@angle / 180.0)) @sinus = Math.sin(Math::PI * (@angle / 180.0)) @cd = @cosinus * @distance @ys = @scroll_y * @sinus @dif = @ys - @cd z0 = @distance / (@distance + @scroll_y * @sinus) h0 = (-@distance * @scroll_y * @cosinus) / (@distance + @scroll_y * @sinus) + @scroll_y @factor = (1.0 - z0) / (@scroll_y - h0) @correct = 1.0 - @scroll_y * @factor @new_angle = true end def distance=(n) @distance = n self.angle = @angle end def height=(n) @height = n @need_refresh = true end def columns=(n) @columns = n @need_refresh = true end end $data_maps = load_data("Data/MapInfos.rxdata") class W3DTilemap attr_reader :autotiles attr_accessor :tileset attr_accessor :priorities def initialize(vp) @viewport = vp @horizontal = {} @vertical = {} @tileset = nil @map_data = nil @priorities = nil @bitmap = Bitmap.new(1,1) @sprites = [] @autotiles = [] refresh end def refresh(sprites=true) @height = $game_system.height @columns = $game_system.columns @scroll_y = $game_system.scroll_y @filter = $game_system.filter @ox = -1 @oy = -1 if sprites w = nil @sprites.each{ |w| w.dispose} @sprites = [] for i in 0...(@scroll_y / @height) @sprites[i] = Sprite.new(@viewport) @sprites[i].y = i * @height end for i in (@scroll_y / @height)...(((480-@scroll_y) / 2 + @scroll_y) / @height) @sprites[i] = Sprite.new(@viewport) @sprites[i].y = i * @height * 2 - @scroll_y end end @sprites.each {|w| w.zoom_x = $game_system.screen2zoom(w.y+1) if w.zoom_x > 1 w.zoom_y = w.zoom_x end w.x = 320 } if sprites unless @map_data.nil? refresh_bitmap end end end def terrain=(n) @terrain = n end def tileset=(bitmap) @tileset = bitmap end def ox=(n) return if @ox == n @ox = n dif = (@oy + @scroll_y) ox = n + 320 w = nil i = nil a = nil z = nil erase = nil @sprites.each{ |w| w.ox = ox} @horizontal.each{ |i, a| new_y = $game_system.screen2W3D_y(i - dif) z = $game_system.screen2zoom(new_y) erase = (a[0].y - 256).between?(1,$game_system.hide) a.each{ |w| w.x = 320 + z * (w.map_x - ox) if erase and 28 >= (ox - w.map_x).abs w.opacity = 100 else w.opacity = 255 end } } @vertical.each{ |i, a| new_y = $game_system.screen2W3D_y(i - dif) z = $game_system.screen2zoom(new_y) erase = (a[0].map_y % 6 != 0) a.each{ |w| if erase and (w.map_x - ox).abs < @filter w.jump = true w.visible = false next end w.jump = false if w.visible if w.visible = (ox*w.side >= w.map_x*w.side) w.x = 320 + z * (w.map_x - ox) end elsif w.visible = (ox*w.side >= w.map_x*w.side) w.y = new_y w.x = 320 + z * (w.map_x - ox) w.zoom_y = z end } } end def oy=(n) return if @oy == n @oy = n ox320 = @ox + 320 dif = (n + @scroll_y) w = nil i = nil a = nil z = nil mz = nil new_y = nil erase = nil @sprites.each{ |w| w.src_rect.y = $game_system.screen2map_y(w.y+1).round + @oy } @horizontal.each{ |i, a| new_y = $game_system.screen2W3D_y(i - dif) z = $game_system.screen2zoom(new_y) erase = (a[0].y - 256).between?(1,$game_system.hide) a.each{ |w| w.y = new_y w.x = 320 + (z * (w.map_x - ox320)) w.zoom_x = (w.zoom_y = z + 0.04) if erase and 28 >= (ox320 - w.map_x).abs w.opacity = 100 else w.opacity = 255 end } } @vertical.each{ |i, a| new_y = $game_system.screen2W3D_y(i - dif) z = $game_system.screen2zoom(new_y) mz = [z,1].max a.each { |w| if w.visible w.y = new_y w.x = 320 + z * (w.map_x - ox320) w.zoom_y = z w.zoom_x = mz end } } end def map_data=(data) @map_data = data refresh_bitmap end def refresh_bitmap @terrain = $game_map.terrain_tags if @terrain.nil? @horizontal.each{ |i, c| c.each{ |w| w.dispose}} @vertical.each{ |i, c| c.each{ |w| w.dispose}} @horizontal.clear @vertical.clear @bitmap.dispose @bitmap = Bitmap.new(@map_data.xsize*32,@map_data.ysize*32) rect = Rect.new(0,0,32,32) source = Rect.new(0,0,32,32) i = 0 x = 0 y = 0 z = 0 data = nil wall = nil for x in 0...@map_data.xsize for y in 0...@map_data.ysize rect.x = x*32 rect.y = y*32 source.x = ((@map_data[x,y,0] - 384) % 8) * 32 source.y = ((@map_data[x,y,0] - 384) / 8) * 32 @bitmap.stretch_blt(rect,@tileset,source) for z in 0..2 data = @map_data[x,y,z] if @terrain[data] == 2 if @terrain[@map_data[[x+1,@map_data.xsize-1].min,y,z].to_i] != 2 for i in 0...@columns wall = SWall.new(@viewport,@columns) wall.map_x = x * 32 + 32 wall.map_y = y * 32 + (@columns-i) * 32 / @columns wall.bitmap = @tileset wall.z = wall.map_y wall.side = 1 * $game_system.hidewalls wall.set_src(@terrain, data, i) wall.ox = 32 / @columns / 2 - 1 if @vertical.key?(wall.map_y) @vertical[wall.map_y].push(wall) else @vertical[wall.map_y] = [wall] end end end if @terrain[@map_data[[x-1,0].max,y,z].to_i] != 2 for i in 0...@columns wall = SWall.new(@viewport,@columns) wall.map_x = x * 32 wall.map_y = y * 32 + (@columns-i) * 32 / @columns wall.bitmap = @tileset wall.mirror = true wall.set_src(@terrain, data, i) wall.z = wall.map_y wall.side = -1 * $game_system.hidewalls wall.ox = 32 / @columns / 2 if @vertical.key?(wall.map_y) @vertical[wall.map_y].push(wall) else @vertical[wall.map_y] = [wall] end end end end if @terrain[data] == 1 and (y+1 == @map_data.ysize or @map_data[x,y+1,z] != data + 8) wall = Wall.new(@viewport,1,@map_data) wall.map_x = x * 32 + 16 wall.map_y = y * 32 + 32 + 1 wall.real_y = y wall.bitmap = @tileset wall.set_src(@terrain, data) wall.ox = 15 wall.z = wall.map_y if @horizontal.key?(wall.map_y) @horizontal[wall.map_y].push(wall) else @horizontal[wall.map_y] = [wall] end end end end end for i in 0...@sprites.size @sprites[i].bitmap = @bitmap @sprites[i].src_rect.set(0,i,@bitmap.width,@height) if i >= @scroll_y / @height @sprites[i].src_rect.height *= 2 end end end def update if $game_system.coord x = $game_system.coord[0] y = $game_system.coord[1] source = Rect.new(0,0,32,32) rect = Rect.new(x*32,y*32,32,32) for z in 0..2 if not [1,2].include?(@terrain[@map_data[x,y,z]]) source.x = ((@map_data[x,y,z] - 384) % 8) * 32 source.y = ((@map_data[x,y,z] - 384) / 8) * 32 @bitmap.stretch_blt(rect,@tileset,source) end end $game_system.coord = nil end if $game_system.need_refresh $game_system.new_angle = false $game_system.need_refresh = false refresh return end if $game_system.new_zoom $game_system.new_zoom = false refresh(false) return end if $game_system.new_angle @sprites.each {|w| w.zoom_x = $game_system.screen2zoom(w.y+1) if w.zoom_x > 1 w.zoom_y = w.zoom_x end w.x = 320 } x = @ox y = @oy @ox += 1 @oy += 1 self.ox = x self.oy = y $game_system.new_angle = false end end def dispose @horizontal.each{ |i, c| c.each{ |w| w.dispose}} @vertical.each{ |i, c| c.each{ |w| w.dispose}} @sprites.each{ |w| w.dispose} @bitmap.dispose end end class Wall < Sprite attr_accessor :map_x attr_accessor :map_y attr_accessor :real_y attr_accessor :side attr_accessor :jump attr_accessor :height def initialize(vp,spalten,data=nil) super(vp) @data = data @spalten = spalten @jump = false @real_y = 0 @map_x = 0 @map_y = 0 @side = 0 self.x = 320 self.z = 100 @blick = true end def set_src(terrain,tile,i=0) height = 1 while terrain[tile - height * 8].to_i == 1 height += 1 end self.src_rect.set( ((tile % 8) * 32) + 32 / @spalten * i, ((tile - 384) / 8 - height + 1) * 32, 32 / @spalten, 32 * height) self.oy = height * 32 - 1 @height = height end end class SWall < Wall def set_src(terrain,tile,i) super self.src_rect.height -= 32 self.oy -= 32 end end class Game_Map attr_reader :W3D alias scroll_down_W3D scroll_down alias scroll_left_W3D scroll_left alias scroll_right_W3D scroll_right alias scroll_up_W3D scroll_up alias setup_W3D setup def scroll_down(distance) if $game_map.W3D @display_y += distance else scroll_down_W3D(distance) end end def scroll_left(distance) if $game_map.W3D @display_x -= distance else scroll_left_W3D(distance) end end def scroll_right(distance) if $game_map.W3D @display_x += distance else scroll_right_W3D(distance) end end def scroll_up(distance) if $game_map.W3D @display_y -= distance else scroll_up_W3D(distance) end end def name return $data_maps[@map_id].name end def setup(id) setup_W3D(id) @W3D = false for part in self.name.split("[") case part when /#(.*)\]/ $game_system.angle = $1.to_i when "W3D]" @W3D = true when /-(.*)\]/ $game_system.hidewalls = $1.to_i end end end end class Game_Character alias screen_z_W3D screen_z def screen_z(height = 0) if $game_map.W3D if @always_on_top return $game_map.height * 32 + 10 end return @real_y / 4 + 33 else screen_z_W3D(height) end end end class Game_Player alias center_W3D center def center(x, y) if $game_map.W3D $game_map.display_x = x * 128 - CENTER_X $game_map.display_y = y * 128 - CENTER_Y else center_W3D(x, y) end end end class Sprite_Character alias update_W3D update def update update_W3D return unless $game_map.W3D self.y = $game_system.screen2W3D_y(self.y - $game_system.scroll_y) self.zoom_x = self.zoom_y = $game_system.screen2zoom(self.y) self.x = 320 + (self.zoom_x * (self.x - 320)) end end class Spriteset_Map def initialize @viewport1 = Viewport.new(0, 0, 640, 480) @viewport2 = Viewport.new(0, 0, 640, 480) @viewport3 = Viewport.new(0, 0, 640, 480) @viewport2.z = 200 @viewport3.z = 5000 if $game_map.W3D @tilemap = W3DTilemap.new(@viewport1) @tilemap.terrain = $game_map.terrain_tags else @tilemap = Tilemap.new(@viewport1) end @tilemap.tileset = RPG::Cache.tileset($game_map.tileset_name) for i in 0..6 autotile_name = $game_map.autotile_names[i] @tilemap.autotiles[i] = RPG::Cache.autotile(autotile_name) end @tilemap.map_data = $game_map.data @tilemap.priorities = $game_map.priorities @panorama = Plane.new(@viewport1) @panorama.z = -1000 @fog = Plane.new(@viewport1) @fog.z = 3000 @character_sprites = [] for i in $game_map.events.keys.sort sprite = Sprite_Character.new(@viewport1, $game_map.events[i]) @character_sprites.push(sprite) end @character_sprites.push(Sprite_Character.new(@viewport1, $game_player)) @weather = RPG::Weather.new(@viewport1) @picture_sprites = [] for i in 1..50 @picture_sprites.push(Sprite_Picture.new(@viewport2, $game_screen.pictures[i])) end @timer_sprite = Sprite_Timer.new update end ###########重定义update 更改远景图更新速度 直接复制默认的 顺着箭头往下走 def update # 远景与现在的情况有差异发生的情况下 ↓ if @panorama_name != $game_map.panorama_name or# ↓ @panorama_hue != $game_map.panorama_hue# ↓ @panorama_name = $game_map.panorama_name# ↓ @panorama_hue = $game_map.panorama_hue# ↓ if @panorama.bitmap != nil# ↓ @panorama.bitmap.dispose# ↓ @panorama.bitmap = nil# ↓ end if @panorama_name != ""# ↓ @panorama.bitmap = RPG::Cache.panorama(@panorama_name, @panorama_hue) end Graphics.frame_reset# ↓ end # 雾与现在的情况有差异的情况下 ↓ if @fog_name != $game_map.fog_name or @fog_hue != $game_map.fog_hue# ↓ @fog_name = $game_map.fog_name# ↓ @fog_hue = $game_map.fog_hue# ↓ if @fog.bitmap != nil# ↓ @fog.bitmap.dispose# ↓ @fog.bitmap = nil# ↓ end if @fog_name != "" @fog.bitmap = RPG::Cache.fog(@fog_name, @fog_hue)# ↓ end Graphics.frame_reset# ↓ end # 刷新元件地图 @tilemap.ox = $game_map.display_x / 4# ↓ @tilemap.oy = $game_map.display_y / 4# ↓ @tilemap.update # 刷新远景平面# ↓ @panorama.ox = $game_map.display_x / 8 #这里更改X速度 ← @panorama.oy = $game_map.display_y * 0 #这里更改Y速度 ← # 刷新雾平面 @fog.zoom_x = $game_map.fog_zoom / 100.0 @fog.zoom_y = $game_map.fog_zoom / 100.0 @fog.opacity = $game_map.fog_opacity @fog.blend_type = $game_map.fog_blend_type @fog.ox = $game_map.display_x / 4 + $game_map.fog_ox @fog.oy = $game_map.display_y / 4 + $game_map.fog_oy @fog.tone = $game_map.fog_tone # 刷新角色活动块 for sprite in @character_sprites sprite.update end # 刷新天候图形 @weather.type = $game_screen.weather_type @weather.max = $game_screen.weather_max @weather.ox = $game_map.display_x / 4 @weather.oy = $game_map.display_y / 4 @weather.update # 刷新图片 for sprite in @picture_sprites sprite.update end # 刷新计时器块 @timer_sprite.update # 设置画面的色调与震动位置 @viewport1.tone = $game_screen.tone @viewport1.ox = $game_screen.shake # 设置画面的闪烁色 @viewport3.color = $game_screen.flash_color # 刷新显示端口 @viewport1.update @viewport3.update end end
|