Lieber Besucher, herzlich willkommen bei: RPG Studio - Make your World real. Falls dies Ihr erster Besuch auf dieser Seite ist, lesen Sie sich bitte die Hilfe durch. Dort wird Ihnen die Bedienung dieser Seite näher erläutert. Darüber hinaus sollten Sie sich registrieren, um alle Funktionen dieser Seite nutzen zu können. Benutzen Sie das Registrierungsformular, um sich zu registrieren oder informieren Sie sich ausführlich über den Registrierungsvorgang. Falls Sie sich bereits zu einem früheren Zeitpunkt registriert haben, können Sie sich hier anmelden.

1

Dienstag, 21. Februar 2012, 21:02

Licht- und Schatteneffekte

So.. in diesem Tutorial werde ich näher erläutern, wie man seine Maps mit ein paar schicken Licht- und Schatteneffekten aufwerten kann.. Ich werde mich dabei vorerst nur auf sehr einfache Effekte beschränken und mich erst einmal auf einige Grundlagen und Tricks beschränken.

Ziel dieses Tutorials ist es, aus dieser Map:
Bild

diese Map zu machen:
Bild


Benötigtes Zeug

- der RPG Maker XP und das RTP natürlich
- Photoshop (Gimp, u.Ä. dürfte auch gehen)
- mein LE Script:
Spoiler

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
#==============================================================================
# ** Lightmap Script
#------------------------------------------------------------------------------
#
# # Leif
# v1.0
# 22.12.2011
#
#-------------------------------------------------------------------------------
#
# Wie funktioniert dieses Script?
#
# Im Graphics Ordner müssen zwei neue Unterordner erstellt werden: Lightmaps und
# Shadowmaps. In diesen Ordner kann dann pro Map eine Bilddatei einfügt werden,
# welche im Spiel dann über die Map gelegt wird, um Licht und Schatteneffekte zu
# produzieren. Die Datei muss als Namen einfach die ID der Map haben. Das Bild
# Lightmaps Ordner wird auf Blend_Type Add gestellt.
# Am Ende des Scripts können weitere Einstellungen (Screentone, etc) gemacht
# werden.
# Die Dateien können auch kleiner als die Map sein, sie werden dann automatisch
# skaliert.
#
#===============================================================================
# RPG Module
#===============================================================================
module RPG
  #=============================================================================
  # RPG::Cache Module
  #=============================================================================
  module Cache
 
    #---------------------------------------------------------------------------
    # loads a bitmap
    #---------------------------------------------------------------------------
    def self.load_bitmap(folder_name, filename, hue = 0)
      begin
      path = folder_name + filename
      if not @cache.include?(path) or @cache[path].disposed?
        if filename.size > 0
          if folder_name != "Graphics/Battlers/"
            @cache[path] = Bitmap.new(path)
          else
            bitmap = Bitmap.new(path)
            w = (bitmap.width * 1.25).round
            h = (bitmap.height * 1.25).round
            @cache[path] = Bitmap.new(w, h)
            for x_ in 0..3
              for y_ in 0..1
                src_rect = Rect.new(x_*bitmap.width/4, y_*bitmap.height/2,
                                    bitmap.width/4,bitmap.height/2)
                x_diff = (w - bitmap.width) / 4
                y_diff = (h - bitmap.height) / 2
                @cache[path].blt(x_*w/4+x_diff/2,y_*h/2+y_diff,bitmap,src_rect) 
              end
            end
          end
        else
          @cache[path] = Bitmap.new(32, 32)
        end
      end
      if hue == 0
        @cache[path]
      else
        key = [path, hue]
        if not @cache.include?(key) or @cache[key].disposed?
          @cache[key] = @cache[path].clone
          @cache[key].hue_change(hue)
        end
        @cache[key]
      end
      rescue
       p path + " nicht gefunden!" if !path.include?('maps') and $DEBUG
       @cache[path] = Bitmap.new(32, 32)
      end
    end
    #---------------------------------------------------------------------------
    # cache method for the shadowmap
    #---------------------------------------------------------------------------
    def self.shadowmap(filename)
      self.load_bitmap('Graphics/Shadowmaps/', filename)
    end
    #---------------------------------------------------------------------------
    # cache method for the lightmap
    #---------------------------------------------------------------------------
    def self.lightmap(filename)
      self.load_bitmap('Graphics/Lightmaps/', filename)
    end
  end
end
#==============================================================================
# ** Spriteset_Map
#------------------------------------------------------------------------------
#  This class brings together map screen sprites, tilemaps, etc.
#  It's used within the Scene_Map class.
#==============================================================================
class Spriteset_Map
  attr_accessor :lightmap_settings
  attr_accessor :shadowmap_settings
  #--------------------------------------------------------------------------
  # * Alias
  #--------------------------------------------------------------------------
  if !method_defined?(:leifs_lightmap_script_spriteset_map_initialize)
    alias leifs_lightmap_script_spriteset_map_initialize initialize
    alias leifs_lightmap_script_spriteset_map_dispose dispose
    alias leifs_lightmap_script_spriteset_map_update update
  end
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize
    # loads settings
    load_map_settings(self)
    # Old Init
    leifs_lightmap_script_spriteset_map_initialize      
    # creates Shadowmap
    bit = RPG::Cache.shadowmap($game_map.map_id.to_s)
    if !bit.nil?
      @shadowmap = Sprite.new(@viewport1)
      @shadowmap.bitmap = Bitmap.new($game_map.width*32,$game_map.height*32)
      @shadowmap.bitmap.stretch_blt(@shadowmap.bitmap.rect, bit, bit.rect)
      @shadowmap.z = 4000
    end
    # creates Lightmap
    bit = RPG::Cache.lightmap($game_map.map_id.to_s)
    if !bit.nil?
      @lightmap = Sprite.new(@viewport1)
      @lightmap.bitmap = Bitmap.new($game_map.width*32,$game_map.height*32)
      @lightmap.bitmap.stretch_blt(@lightmap.bitmap.rect, bit, bit.rect)
      @lightmap.z = 5000
      @lightmap.blend_type = 1
    end
  end
  #--------------------------------------------------------------------------
  # * Dispose
  #--------------------------------------------------------------------------
  def dispose
    leifs_lightmap_script_spriteset_map_dispose
    @lightmap.dispose if !@lightmap.nil?
    @shadowmap.dispose if !@shadowmap.nil?
  end
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update
    leifs_lightmap_script_spriteset_map_update
    #Shadowmap update
    if !@shadowmap.nil?
      @shadowmap.ox = $game_map.display_x / 4
      @shadowmap.oy = $game_map.display_y / 4
      if !@shadowmap_settings.nil?
        if @shadowmap.opacity < @shadowmap_settings[1] 
          if @shadowmap_settings[2] > 0
            @shadowmap.opacity += @shadowmap_settings[2]
          end
        else
          @shadowmap_settings[2] *= -1
          @shadowmap.opacity = @shadowmap_settings[1] 
        end
        if @shadowmap.opacity > @shadowmap_settings[0]
          if @shadowmap_settings[2] < 0
            @shadowmap.opacity += @shadowmap_settings[2]
          end
        else
          @shadowmap_settings[2] *= -1
          @shadowmap.opacity = @shadowmap_settings[0] 
        end
      end
    end      
 
    #Lightmap update
    if !@lightmap.nil?
      @lightmap.ox = $game_map.display_x / 4
      @lightmap.oy = $game_map.display_y / 4
      if !@lightmap_settings.nil?
        if @lightmap.opacity < @lightmap_settings[1] 
          if @lightmap_settings[2] > 0
            @lightmap.opacity += @lightmap_settings[2]
          end
        else
          @lightmap_settings[2] *= -1
          @lightmap.opacity = @lightmap_settings[1] 
        end
        if @lightmap.opacity > @lightmap_settings[0]
          if @lightmap_settings[2] < 0
            @lightmap.opacity += @lightmap_settings[2]
          end
        else
          @lightmap_settings[2] *= -1
          @lightmap.opacity = @lightmap_settings[0]
        end
      end
    end  
  end
end
#==============================================================================
# ** load_map_settings
#------------------------------------------------------------------------------
# this method loads settings for the lightmaps etc
#==============================================================================
def load_map_settings(spriteset = $scene.spriteset)
  tone = nil
  t_time = 0
  spriteset.lightmap_settings = [0,0,0]
  spriteset.shadowmap_settings = [0,0,0]
 
  #--------------------------------------------------------------------------
  # Hier können weitere Optionen festgelegt werden
  #
  # tone = Tone.new(Red, Green, Blue, Grey) legt den Screentone fest
  #
  # t_time = Time legt die Fade-in Dauer des Screentones fest (sollte 0 sein)
  #
  # spriteset.lightmap_settings = [min, max, speed] Lightmap Einstellungen
  # spriteset.shadowmap_settings = [min, max, speed] Shadowmap Einstellungen
  # min ist die minimale Sichtbarkeit, max die Maximale und speed die
  # Geschwindigkeit, mit der sich die Sichtbarkeit ändern. Die Sichtbarkeit
  # schwankt immer zwischen diesen beiden Werten, um Lichterflackern o.Ä.
  # zu simulieren.
  # Für jede neue Map muss ein weiterer Eintrag der Form
  #   
  #   when MapID
  #     (Einstellungen)
  #
  # eingefügt werden
  #
  #--------------------------------------------------------------------------
  case $game_map.map_id
  when 1
    tone = Tone.new(-35, -30, -40, 100)
    t_time = 0
    spriteset.lightmap_settings = [240, 255, 2]
    spriteset.shadowmap_settings = [240, 255, 1]
  when 2
    # Einstellungen für Map 2
  when 3
    # Einstellungen für Map 3
  end
  #--------------------------------------------------------------------------
  $game_screen.start_tone_change(tone, t_time) if !tone.nil?
end
zum Lesen den Text mit der Maus markieren

- mein Map Save Script:
Spoiler

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
#==============================================================================
# ** Save Map Script
#------------------------------------------------------------------------------
#
# # Leif
# v1.1
# 30.07.2011
#
#-------------------------------------------------------------------------------
#
# Was tut dieses Script?
# Dieses Script speichert die gesamte Map (inklusive Events) in eine png-Datei
#
#-------------------------------------------------------------------------------
#
# Wie benutze ich dieses Script?
#
# über Main einfügen, Antilag Scripts deaktivieren
#
# Mit dem Scriptbefehl Map::save('dateiname') wird die Map gespeichert
#
#==============================================================================
# Scene_Map class
#==============================================================================
class Scene_Map
  attr_reader :spriteset
end
#==============================================================================
# Sprite Character class
#==============================================================================
class Sprite_Character
  attr_reader :tile_id
end
#==============================================================================
# Spriteset Map class
#==============================================================================
class Spriteset_Map
  attr_reader :tilemap
  attr_reader :character_sprites
end
#==============================================================================
# Map module
#==============================================================================
module Map
  # For Autotiles
  INDEX  = 
  [
    26, 27, 32, 33,    4 , 27, 32, 33,    26,   5, 32, 33,      4,   5, 32, 33,
    26, 27, 32, 11,    4 , 27, 32, 11,    26,   5, 32, 11,      4,   5, 32, 11,
    26, 27, 10, 33,     4 , 27, 10, 33,    26,   5, 10, 33,    4,   5, 10, 33,
    26, 27, 10, 11,    4 , 27, 10, 11,    26,   5, 10, 11,      4,   5, 10, 11,
    24, 25, 30, 31,    24,  5, 30, 31,    24, 25, 30, 11,     24,  5, 30, 11,   
    14, 15, 20, 21,     14, 15, 20, 11,   14, 15, 10, 21,     14, 15, 10, 11, 
    28, 29, 34, 35,    28, 29, 10, 35,    4, 29, 34, 35,     4, 29, 10, 35,
    38, 39, 44, 45,     4, 39, 44, 45,     38, 5, 44, 45,      4, 5, 44, 45,
    24, 29, 30, 35,    14, 15, 44, 45,    12, 13, 18 ,19,    12, 13, 18, 11,
    16, 17, 22, 23,     16, 17, 10, 23,   40, 41, 46, 47,    4, 41, 46, 47,
    36, 37, 42, 43,     36,  5, 42, 43,    12, 17, 18, 23,    12, 13, 42, 43,
    36, 41, 42, 47,     16, 17, 46, 47,   12, 17, 42, 47,    0, 1, 6, 7
  ]
  X = [0, 1, 0, 1]
  Y = [0, 0, 1, 1]
  #--------------------------------------------------------------------------
  # * saves the map
  #--------------------------------------------------------------------------
  def self.save(name)
    tilemap = $scene.spriteset.tilemap
    bitmap = Bitmap.new($game_map.width * 32, $game_map.height * 32)
    tiles = []
    tiles[0] = tilemap.tileset
    characters = $scene.spriteset.character_sprites
 
    # creates Autotiles
    for i in 0..6
      autotile = tilemap.autotiles[i]
      if autotile != nil and autotile.width >= 96
        id = tiles.length
        scroll = []
        frame = []
        scroll[id] = 0
        frame[id] = autotile.width / 96
        width = 8 * 32 * frame[id]
        height = 6 * 32
        tiles[id] = Bitmap.new(width, height)  
        for f in 0...frame[id]
          for pos in 0...48
            for corner in [0, 1, 2, 3]
              h = 4 * pos + corner
              yy = INDEX[h] / 6 
              xx = INDEX[h] % 6 + f * 6 
              y = pos / 8
              x = pos % 8 + f * 8
              src_rect = Rect.new(xx * 16 , yy * 16 , 16, 16 )
              tiles[id].blt(x * 32 + X[corner] * 16, 
                            y * 32  + Y[corner] * 16 ,  autotile, src_rect)
            end  # end for corner    
          end      
        end
      else
        tiles[tiles.length] =  Bitmap.new(32 * 8, 32 * 6)
        if @minimap_collision
          tiles[tiles.length - 1].fill_rect(tiles[tiles.length - 1].rect, 
                                            Color.new(255, 255,255))  
        end
      end
    end
 
    # draws map
    for x in 0...$game_map.width
      for y in 0...$game_map.height
        data = []
        for i in 0..2
          data.push(tilemap.map_data[x,y,i])
        end
        data.sort! do |a, b|
          tilemap.priorities[a] <=> tilemap.priorities[b]
        end
        chars_drawn = []
        data.each do |id|
          nr = nil
          pos = id
          pos = 0 if pos == nil
          data = id
          dest_rect = Rect.new(x * 32, y * 32, 32, 32)
          if pos >= 384  
            nr = 0
            pos  -= 384                         
          elsif pos >= 48
            nr = pos / 48
            pos = pos % 48
          end
          # draws characters
          characters.each do |sprite|
            if sprite.tile_id == 0
              if sprite.character.is_a?(Game_Player) or 
              !sprite.character.always_on_top
                pr = 0
              else
                pr = 5
              end
            else
              pr = tilemap.priorities[sprite.tile_id]
            end
            next if tilemap.priorities[id] <= pr
            next if chars_drawn.include?(characters.index(sprite))
            next if sprite.nil? or sprite.bitmap.nil?
            next if sprite.character.y != y or sprite.character.x != x
            chars_drawn.push(characters.index(sprite))
            x_ = sprite.x - sprite.ox + $game_map.display_x / 4
            y_ = sprite.y - sprite.oy + $game_map.display_y / 4
            dest_rect_ = Rect.new(x_, y_, sprite.src_rect.width, 
                                 sprite.src_rect.height)
            bitmap.stretch_blt(dest_rect_, sprite.bitmap, sprite.src_rect)
          end
          if nr != nil
            src_rect = Rect.new((pos % 8) * 32, (pos / 8) * 32, 32, 32)
            bitmap.stretch_blt(dest_rect, tiles[nr], src_rect) 
          end
        end
        characters.each do |sprite|
          next if chars_drawn.include?(characters.index(sprite))
          next if sprite.nil? or sprite.bitmap.nil?
          next if sprite.character.y != y or sprite.character.x != x
          x_ = sprite.x - sprite.ox + $game_map.display_x / 4
          y_ = sprite.y - sprite.oy + $game_map.display_y / 4
          dest_rect_ = Rect.new(x_, y_, sprite.src_rect.width, 
                               sprite.src_rect.height)
          bitmap.stretch_blt(dest_rect_, sprite.bitmap, sprite.src_rect)
        end
      end
    end
 
    # saves bitmap
    bitmap.make_png(name)
  end
end
 
#==============================================================================
# ** Game_Event
#------------------------------------------------------------------------------
#  This class deals with events. It handles functions including event page 
#  switching via condition determinants, and running parallel process events.
#  It's used within the Game_Map class.
#==============================================================================
 
class Game_Event < Game_Character
  attr_reader   :always_on_top
end
 
#==============================================================================
#           本脚本出自www.66rpg.com,转载请注明。
#==============================================================================
=begin
==============================================================================
                    Bitmap to PNG By 轮回者
==============================================================================
 
 对Bitmap对象直接使用
 
 bitmap_obj.make_png(name[, path])
 
 name:保存文件名
 path:保存路径
 
 感谢66、夏娜、金圭子的提醒和帮助!
 
==============================================================================
=end
 
module Zlib
  class Png_File < GzipWriter
#--------------------------------------------------------------------------
# ● 主处理
#--------------------------------------------------------------------------
def make_png(bitmap_Fx,mode)
  @mode = mode
  @bitmap_Fx = bitmap_Fx
  self.write(make_header)
  self.write(make_ihdr)
  self.write(make_idat)
  self.write(make_iend)
end
#--------------------------------------------------------------------------
# ● PNG文件头数据块
#--------------------------------------------------------------------------
def make_header
  return [0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a].pack("C*")
end
#--------------------------------------------------------------------------
# ● PNG文件情报头数据块(IHDR)
#--------------------------------------------------------------------------
def make_ihdr
  ih_size = [13].pack("N")
  ih_sign = "IHDR"
  ih_width = [@bitmap_Fx.width].pack("N")
  ih_height = [@bitmap_Fx.height].pack("N")
  ih_bit_depth = [8].pack("C")
  ih_color_type = [6].pack("C")
  ih_compression_method = [0].pack("C")
  ih_filter_method = [0].pack("C")
  ih_interlace_method = [0].pack("C")
  string = ih_sign + ih_width + ih_height + ih_bit_depth + ih_color_type +
           ih_compression_method + ih_filter_method + ih_interlace_method
  ih_crc = [Zlib.crc32(string)].pack("N")
  return ih_size + string + ih_crc
end
#--------------------------------------------------------------------------
# ● 生成图像数据(IDAT)
#--------------------------------------------------------------------------
def make_idat
  header = "\x49\x44\x41\x54"
  case @mode # 请54~
  when 1
    data = make_bitmap_data#1
  else
    data = make_bitmap_data
  end
  data = Zlib::Deflate.deflate(data, 8)
  crc = [Zlib.crc32(header + data)].pack("N")
  size = [data.length].pack("N")
  return size + header + data + crc
end
#--------------------------------------------------------------------------
# ● 从Bitmap对象中生成图像数据 mode 1(请54~)
#--------------------------------------------------------------------------
def make_bitmap_data1
  w = @bitmap_Fx.width
  h = @bitmap_Fx.height
  data = []
  for y in 0...h
    data.push(0)
    for x in 0...w
      color = @bitmap_Fx.get_pixel(x, y)
      red = color.red
      green = color.green
      blue = color.blue
      alpha = color.alpha
      data.push(red)
      data.push(green)
      data.push(blue)
      data.push(alpha)
    end
  end
  return data.pack("C*")
end
#--------------------------------------------------------------------------
# ● 从Bitmap对象中生成图像数据 mode 0
#--------------------------------------------------------------------------
def make_bitmap_data
  gz = Zlib::GzipWriter.open('hoge.gz')
  t_Fx = 0
  w = @bitmap_Fx.width
  h = @bitmap_Fx.height
  data = []
  for y in 0...h
    data.push(0)
    for x in 0...w
      t_Fx += 1
      if t_Fx % 10000 == 0
        Graphics.update
      end
      if t_Fx % 100000 == 0
        s = data.pack("C*")
        gz.write(s)
        data.clear
        #GC.start
      end
      color = @bitmap_Fx.get_pixel(x, y)
      red = color.red
      green = color.green
      blue = color.blue
      alpha = color.alpha
      data.push(red)
      data.push(green)
      data.push(blue)
      data.push(alpha)
    end
  end
  s = data.pack("C*")
  gz.write(s)
  gz.close   
  data.clear
  gz = Zlib::GzipReader.open('hoge.gz')
  data = gz.read
  gz.close
  File.delete('hoge.gz')
  return data
end
#--------------------------------------------------------------------------
# ● PNG文件尾数据块(IEND)
#--------------------------------------------------------------------------
def make_iend
  ie_size = [0].pack("N")
  ie_sign = "IEND"
  ie_crc = [Zlib.crc32(ie_sign)].pack("N")
  return ie_size + ie_sign + ie_crc
end
  end
end
#==============================================================================
# â–  Bitmap
#------------------------------------------------------------------------------
#  关联到Bitmap。
#==============================================================================
class Bitmap
  #--------------------------------------------------------------------------
  # ● 关联
  #--------------------------------------------------------------------------
  def make_png(name="like", path="",mode=0)
make_dir(path) if path != ""
Zlib::Png_File.open("temp.gz") {|gz|
  gz.make_png(self,mode)
}
Zlib::GzipReader.open("temp.gz") {|gz|
  $read = gz.read
}
f = File.open(path + name + ".png","wb")
f.write($read)
f.close
File.delete('temp.gz')
end
  #--------------------------------------------------------------------------
  # ● 生成保存路径
  #--------------------------------------------------------------------------
  def make_dir(path)
dir = path.split("/")
for i in 0...dir.size
  unless dir == "."
    add_dir = dir[0..i].join("/")
    begin
      Dir.mkdir(add_dir)
    rescue
    end
  end
end
  end
end
#==============================================================================
#           本脚本出自www.66rpg.com,转载请注明。
#==============================================================================
zum Lesen den Text mit der Maus markieren


Ich hab für das Tutorial Photoshop benutzt. Das LE Script wird später dazu benutzt, um eure Lightmaps ins Projekt einzufügen, ihr müsst sie also nicht per Picture anzeigen lassen. Außerdem bietet es die Möglichkeit, für jede Map einen Screentone festzulegen, welcher somit nicht per Event auf jeder Map geändert werden muss.
Das Map Save Script speichert komplette Maps als Datei ab, somit müssen größere Maps nicht mühsam per Screenshot zusammengefügt werden, um sie weiterzuverarbeiten. Es funktioniert nicht ganz einwandfrei, für unsere Zwecke reicht es allerdings. Nähere Beschreibungen befinden sich jeweils innerhalb der Scripts.. (;


Allgemeines
Meine Effekte setzen sich meistens aus mehreren Komponenten zusammen:

Screentone: Natürlich ganz wichtig, um überhaupt erstmal die passende Grundfärbung in den Screen zu bringen und meistens auch, um den hohen Kontrast des RTPs abzuschwächen..
Fog: Auf den meisten Maps möchte man zwar keinen dichten Nebel, mit Hilfe des sandstorm Fogs aus dem RTP kann man jedoch die Map plastischer wirken lassen (siehe unten)
Lightmap: Lichteffekte, welche die Map erhellen (Blendtype: Add)
Shadowmap: Schatteneffekte o.Ä., ein Bild das einfach so über die Map gelegt wird

Früher hatte ich immer das Problem, dass ich zwar die Effekte schön in Photoshop basteln konnte, allerdings erst alles speichern musste, um dann im Maker zu schauen, wie das Ganze zusammen mit dem Screentone denn nun aussieht. Irgendwann hab ich dann herausgefunden, dass sich der Screentone (eben so wie die Blendeffekte Add/Sub) mit Photoshop imitieren lassen.

Blendtype "Add": Die Grafik müsst ihr als neue Ebene einfügen und als Füllmethode für die Ebene "Linear Abwedeln" wählen, um diesen Effekt zu erhalten.
[b[Blendtype "Sub":[/b] "Linear Nachbelichten" hat denselben Effekt, allerdings müsst ihr die Ebene vorher noch invertieren (STRG+I)
Screentone: Grayscale FIlter: Eine neue, mit weiß gefüllte Ebene und der Füllmethode "Farbton" kann als Graufilter fungieren. Die Sichtbarkeit der Ebene regelt die Stärke des Effekts (100% Sichtbarkeit entspricht im Maker einem Wert von 255, (x * 100 / 255) % entspricht einem Wert von x. (zB: 20% entspricht einem Wert von 50)
Screentone: RGB, Positive Werte: Genau wie beim Blendtype "Add" müsst ihr eine neue Ebene erstellen und die Füllmethode auf "Linear Abwedeln" stellen. Die Ebene wird mit den Werten des Screentones gefüllt (wenn der Tone zB 20, 20, 30 ist, dann füllt ihr die Ebene mit der Farbe 20, 20, 30)
Screentone: RGB, Negative Werte: Genau wie beim Blendtype "Sub" müsst ihr eine neue Ebene erstellen und die Füllmethode auf "Linear Nachbelichten" stellen. Die Ebene wird mit den Werten des Screentones gefüllt (wenn der Tone zB 20, 20, 30 ist, dann füllt ihr die Ebene mit der Farbe 20, 20, 30), und danach mit STRG+I invertiert.

Problematisch wird es bei transparenten Grafiken, da ist das Ergebnis im Maker leider etwas anders..


Die eigentlichen Licht-/Schatteneffekte

Zu Beginn starten wir mit der normalen Map:
Bild


1. Fog

Der sandstorm Fog sorgt dafür, dass eure Map etwas plastischer wirkt. Im Maker kann er über die Database für jedes Tileset neu festgelegt werden, wichtig ist eine geringe Sichtbarkeit (hier: 50) und der Blendtype "Sub", Zoom auf 200%

In Photoshop könnt ihr den Fog als neue Ebene einfügen, als Füllmethode "Linear nachbelichten" wählen und die Ebene invertieren (STRG+I), Die Sichtbarkeit muss auf 20% gestellt werden.
Bild

Um das Bild nicht zig Mal vergrößern zu müssen, habe ich für große Maps eine entsprechend größere Version gespeichert:
Bild


2. Screentone
Für den Screentone habe ich mal die Werte -35, -30, -40 und 100 gewählt. Im Maker könnt ihr mein Script dazu benutzen, in Photoshop braucht ihr zwei neue Ebenen:
Die erste Ebene wird mit weiß gefüllt, auf 39% Sichtbarkeit gestellt und als Füllmethode wird "Farbton" gewählt. Die zweite Ebene wird mit der Farbe 35, 30, 40 gefüllt, invertiert und auf "Linear nachbelichten" gestellt
Bild
Der Screentone dunkelt die Höhle etwas ab.


3. Lightmap & Shadowmap
Jetzt kommt langsam der eigentlich interessante Teil.. zunächst müssen zwei neue Ebenensets erstellt werden, eins für die Lightmap, eins für die Shadowmap. Ersteres wird auf "Linear abwedeln" gesetzt. Beide Sets erhalten eine Maske, welche die dunkle Umrandung der Höhle ausblendet, damit hier später keine Lichtkegel o.Ä. sichtbar sind.
Bild

Die Maske könnt ihr am einfachsten erstellen, indem ihr erst die unterste Eben, also die Map, dupliziert und dann den Kontrast um +100 erhöht (über Bild->Anpassen->Helligkeit/Kontrast). Nun könnt ihr die schwarzen Bereiche an den Rändern mit dem Zauberstab auswählen (Toleranz: 50, Benachbart). Sobald die Auswahl steht, könnt ihr die duplizierte Ebene wieder löschen und die Auswahl in einer der beiden Masken schwarz füllen. Die Kanten des schwarzen Bereiches sind noch etwas pixelig, was ihr mit dem Filter "Helligkeit interpolieren" (Filter->Störungsfilter->Helligkeit interpolieren, Radius: 1Px) beheben könnt. Zuletzt noch etwas weichzeichnen (Filter->Weichzeichnungsfilter->Weichzeichnen) und fertig ist die Maske. Sie muss natürlich noch in die Maske des anderen Ebenensets kopiert werden.


4. Lichteffekte
Zunächst bekommen die Kristalle einen dezenten Leuchteffekte spendiert. Erstellt hierzu eine neue Ebene in dem Lightmap Ebenenset. Gezeichnet wird nun mit dem Pinselwerkzeug. Wählt eine Standardpinselspitze aus und stellt die Kantenschärfe auf 0%. Als Fabre habe ich einen hellen bläulichen Ton gewählt (202 / 236 / 255). Mit einer Pinselgröße von 200Px und einer Sichtbarkeit von 5% müsst ihr nun über alle Kristalle einen Pinselklecks zeichnen (einmal die linke Maustaste anklicken reicht). Wiederholt dies mit einer Pinselgröße von 100Px. Zuletzt wählt eine Pinselgröße von 15Px und eine Sichtbarkeit von 40%. Hiermit könnt ihr dann ein paar (2-3) Glanzlichter auf die Kristalle setzen.
Als nächstes bekommt die Fackel einen Lichtschein. Erstellte eine weitere neue Ebene in der Lightmap, wählt dann wieder den Pinsel mit Kantenschärfe 0% aus. Über der Fackel müsst ihr nun verschiedene Farbkleckse mit einer Deckkraft von 10% malen:

Pinselgröße / Farbe
270Px / 214 0 0
200Px / 214 76 0
130Px / 229 145 0
70Px / 255 246 0

Das Zentrum des Pinsels sollte dabei immer die Flamme sein. Der Effekt ist noch ein wenig schwach, dupliziert also die Ebene, stellt ihre Sichtbarkeit auf 50% und verschiebt sie in das Ebenenset der Shadowmap.

Als letztes könnt ihr, wenn ihr wollt, das Gras noch leicht Leuchten lassen. Erstellt eine dritte Ebene in der Lightmap. Mit dem Pinsel (0% Kantenschärfe, 10% Sichtbarkeit, 150Px Pinselgröße und als Farbe 141 / 255 / 141) malt ihr nun einmal über alle Bereiche, in denen Gras wächst. Dabei dürft ihr, nachdem ihr den Pinsel einmal abgesetzt habt, nicht noch einmal über denselben Bereich malen, da diese Bereiche sonst zu hell werden.

Das Ergebnis sieht nun so aus:
Bild

Wie euch sicher auffällt, sind diese Effekt nur schwach zu erkennen. Generell finde ich solche dezenten Effekte viel angenehmer, da sie sich besser einfügen und nicht so hervorstechen. Ich hab schon häufig regelrechte "Lichtballen" bei ähnlichen Effekten gesehen.. Schön sieht das aber nicht mehr aus wie ich finde..


5. Abdunkeln
Die Höhle ist immer noch ein wenig hell. Wir könnten nun am Screentone drehen, was allerdings auch unsere Lichter dunkler machen würde. Stattdessen erstellt nun ein neues Ebenenset in der Shadowmap und erstellt in diesem Set auch gleich eine neue Ebene. füllt sie mit schwarzer Farbe und stellt die Sichtbarkeit auf 40%. Erstellt für diese Ebene eine Maske und wendet auf diese Maske einmal den Wolkenfilter mit den Farben schwarz und weiß an (Filter->Rendering-Filter->Wolken).
Als Ergebnis bekommen wir nun eine stellenweise abgedunkelte Map
Bild

Leider ist nun auch unser Fackelschein abgedunkelt, doch das können wir beheben. Erstellt für das Ebenenset eine Maske. Wählt nun noch einmal die Ebene aus, die den Fackelschein enthält und dupliziert diese. Die Kopie färbt ihr nun schwarz ein (STRG+U, Lab-Helligkeit auf -100). Dupliziert diese Ebene weitere 4 Mal, sodass ihr 5 Ebenen mit schwarzem Fackelschein habt. Fügt diese Ebenen dann zusammen. (STRG+E) Erstellt nun unter dieser Ebene eine neue Ebene, füllt sie mit weißer Farbe und fügt sie mit der Ebene, die den schwarzen Fackelschein enthält zusammen. Ihr solltet nun eine schwarz/weiß Ebene haben (welche allerdings möglicherweise nicht als solche angezeigt wird, da ihr sie ja in dem Lightmap Ebenenset erstellt habt). Schneidet sie aus und kopiert sie in die Ebenenmaske des Abdunklungs Ebenenset. Wendet zuletzt noch den Gaußschen Weichzeichner darauf an (Filter->Weichzeichnungsfilter->Gaußscher Weichzeichner, Radius 1,0Px). Eure Ebenenmaske sollte nun etwas so aussehen:
Bild

Dadurch ist der Bereich um die Fackel nun wieder heller:
Bild


6. Schatten
Auf die Schatten einzelner Objekte werde ich hier nicht eingehen, da ich darauf meistens verzichte, oder sie nur leicht andeute. Es ist furchtbar schwer, perspektivisch korrekte Schatten zu zeichnen, darum kann sich ja vllt mal wer anders kümmern.. (;
Ich dunkel aber Bereiche, die etwas weiter von entfernt von den Lichtquellen sind, gerne ab. Erstellt eine neue Ebene in der Shadowmap, färbt sie schwarz, stellt die Deckkraft auf 20% und gebt ihr eine schwarze Ebenenmaske. Die Ebene ist also im Moment unsichtbar. Wählt nun wider das Pinselwerkzeug, mit einer Kantenschärfe von 0% und einer Pinselgröße von 150%. Sichtbarkeit 100%, Farbe weiß. Malt damit nun alle Bereiche auf der Ebenenmaske aus, die weiter von der Fackelentfernt sind. Diese Bereiche werden dadurch abgedunkelt.

Letztendlich erhalten wir dieses Ergebnis:
Bild
Wie ihr seht, ist dieses Bild direkt aus Photoshop aufgenommen, es weicht allerdings nur geringfügig von dem Originalscreenshot aus dem Maker (ganz oben) ab. (Lediglich der Fog ist anders, weil dieser transparent ist und sich hier "Linear nachbelichten" aus Photoshop anders verhält, als der Blendtype "Sub" im Maker..

Jetzt müssen die Bilder nur noch entsprechend gespeichert werden, um sie auch verwenden zu können. Löscht dazu alles bis auf die beiden Ebenensets für Lightmap und Shadowmap. Wenn ihr Speicherplatz sparen wollt, könnt ihr das Bild noch auf 50% verkleinern (Bild->Bildgröße).
Löscht nun die Shadowmap und speichert die Lightmap in entsprechenden Ordner eures Projektes ab (Dateiname: "MapID".png). Macht dann dasselbe umgekehrt mit der Shadowmap.

Ich habe nochmal ein kleines Beispielprojekt vorbereitet, in dem ihr euch das in Aktion anschauen könnt:
Lightmap Script.rar

Zu Anfang ist es sehr aufwendig, diese Effekte zu erstellen, aber mit der Zeit werdet ihr das immer schneller hinkriegen, vor allem, wenn ihr wiederkehrende Elemente speichert.. Ich habe beispielsweise eine extra Datei, in der ich verschiedene Lichteffekte (zB den Fackelschein) gespeichert habe, sodass ich sie nur kopieren muss. Wenn ich mehrere Maps aus ein und demselben Gebiet habe (eine Höhle mit mehreren Abschnitten), kopiere ich meistens Teile der Effekte der einen Map (vorzugsweise der größten Map), auf die anderen Maps und kann mir so eine Menge Arbeit sparen..
Ganz abgesehen davon, hab ich hier auf diese Map jetzt einfach mal alles Mögliche reingepackt.. man kann davon sicher einige weglassen^^


So.. ich hoffe, das Tutorial hilft den einem oder anderem weiter.. Falls Unklarheiten sind oder so, meldet euch am besten hier, dann verbesser ich das.. Ist schließlich mein erster Tutorial ^^
ehem. Leif

[Download] Nachtzeit Prolog (Entwicklung eingestellt)

2

Dienstag, 21. Februar 2012, 22:41

Vielen Dank für dieses ausführliche Tutorial, ich denke einigen wird das hier sicherlich weiter helfen :).

Meine persönliche Meinung dazu ist, dass der Aufwand den du betrieben hast nicht dem Ergebnis gerecht wird. Das soll nicht heißen, dass es mieß aussieht (im gegenteil) aber für mich persönlich wär das zu viel gefriemel :D. Klar, wie du auch gesagt hast, geht das sicherlich schneller von der Hand mit der Zeit und mit fertigen kopien von manchen Dingen kann man zusätzlich den Prozess schneller machen aber insgesamt finde ich, einfach zu viel Aufwand. MMn rentiert sich diese LightMap Gestaltung erst, wenn man konsequenterweise richtige Schattenwürfe mit einbaut etc.

Ach ja, Bei GIMP können die ADD und SUB Methoden einfach mit der Ebenen einstellung Addition (für ADD) und Abziehen (für SUB) gemacht werden. Es gibt bei Gimp auch die Einstellungen Nachblichten und Abwedeln, diese sind aber nicht die korrekten um ADD bzw. SUB zu simulieren (was vllt. manche denken). Man muss auch nicht, wie hier bei Photoshop, die Ebenen invertieren. Nur mal so zur vollständigkeit, weil einige (wie ich ^^) sicherlich auch Gimp nutzen.

greetz

3

Sonntag, 26. Februar 2012, 19:11

Dankeschön :) Genau wonach ich gesucht hatte.
Belichtung war schon immer etwas was mich an meinen Maps gestört hat

Grüße, Ramon
Am Grund der Seele, in meinen Träumen
Ist Schönheit Stille, nichts als Wind in alten Bäumen.
Über den Lärm der Städte, das weite Land
Gewinnt das Lied der Blätter die Oberhand.

Social Bookmarks