PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Hab ein kleines Problem mit einem Ruby-Script...



Skorp
10.12.2008, 06:01
Hey...ich hab zwei Skripte die sich nicht miteinander vertragen...das Mirror- und das Quicksaveskript. Sobald ich einen Quicksave machen will stürzt das Spiel mit der unten genannten Fehlermeldung ab. Vielleicht kann mir ja einer helfen?

MirrorSkript:



# NOT YET UPDATED !

#==============================================================================
# ■ Sprite_Mirror
# Based on Sprite_Shadow, modified by Rataime
#==============================================================================

class Sprite_Mirror < RPG::Sprite

attr_accessor :character
attr_accessor :events
attr_accessor :event_y

def initialize(viewport=nil)
super(viewport)
@character = $game_player
@events=0
@event_y=0
self.opacity=0
update
end

def update
super
if @tile_id != @character.tile_id or
@character_name != @character.character_name or
@character_hue != @character.character_hue
@tile_id = @character.tile_id
@character_name = @character.character_name
@character_hue = @character.character_hue
if @tile_id >= 384
self.bitmap = RPG::Cache.tile($game_map.tileset_name,
@tile_id, @character.character_hue)
self.src_rect.set(0, 0, 32, 32)
self.ox = 16
self.oy = 32
else
self.bitmap = RPG::Cache.character(@character.character_name,
@character.character_hue)
@cw = bitmap.width / 4 # HIER EDITIEREN !!!!
@ch = bitmap.height / 4
self.ox = @cw / 2
self.oy = @ch
end
end
self.visible = (not @character.transparent)
if @tile_id == 0
sx = (@character.pattern) * @cw
sy = (@character.direction - 2) / 2 * @ch
if @character.direction==8
sy = 0 * @ch
end
if @character.direction==2
sy = 3 * @ch
end
self.src_rect.set(sx, sy, @cw, @ch)
end
self.x = @character.screen_x
self.y = self.event_y-($game_player.screen_y-self.event_y).abs+30
self.z = 10
self.blend_type = @character.blend_type
self.bush_depth = @character.bush_depth
if @character.animation_id != 0
animation = $data_animations[@character.animation_id]
animation(animation, true)
@character.animation_id = 0
end
end
end

#===================================================
# ▼ CLASS Sprite_Character edit
#===================================================

class Sprite_Character < RPG::Sprite
alias mirror_initialize initialize

def initialize(viewport, character = nil)
@character = character
super(viewport)
if character.is_a?(Game_Player)
$game_map.mirror=Sprite_Mirror.new(viewport)
end
mirror_initialize(viewport, @character)
end

alias mirror_update update

def update
mirror_update
if (@mirror!=nil and character.is_a?(Game_Event) and character.list!=nil and character.list[0].code == 108 and character.list[0].parameters == ["m"])
if $game_player.screen_y-self.y<80 and self.y<$game_player.screen_y and ($game_player.screen_x-self.x).abs<17
if (character.list[1]!=nil and character.list[1].code == 108)
@mirror.opacity=character.list[1].parameters[0].to_f
else
@mirror.opacity=104
end
@mirror.events=self.id
@mirror.event_y=self.y
else
if @mirror.events==self.id
@mirror.events=0
else
if @mirror.events==0
@mirror.opacity=0
end
end
end
end
@mirror=$game_map.mirror
if character.is_a?(Game_Player)
@mirror.update
end
end

end

#===================================================
# ▼ CLASS Scene_Save edit
#===================================================
class Scene_Save < Scene_File

alias mirror_write_save_data write_save_data

def write_save_data(file)
$game_map.mirror = nil
mirror_write_save_data(file)
end
end

#===================================================
# ▼ CLASS Game_Map edit
#===================================================
class Game_Map
attr_accessor :mirror
end

#===================================================
# ▼ CLASS Scene_Map edit
#===================================================
class Spriteset_Map

alias mirror_map_initialize initialize

def initialize
$game_map.mirror=nil
mirror_map_initialize
end
end

Quicksave:


class Quicksave



def Quicksave.save
file = File.open("quicksave.sav", "wb")
Scene_Save.new.write_save_data(file)
file.close
end
#----------
def Quicksave.load
return unless FileTest.exist?("quicksave.sav")
file = File.open("quicksave.sav", "rb")
Scene_Load.new.read_save_data(file)
file.close
Graphics.freeze
sprite = Sprite.new
sprite.bitmap = Bitmap.new(640, 480)
sprite.bitmap.fill_rect(0, 0, 640, 480, Color.new(0, 0, 0))
Graphics.transition(10)
$scene = Scene_Map.new
end
end

Error:
Script `mirror effect` line112: NoMethod Error occurred
undefined method ´update´for nil:NilClass

Die Zeile 112 hab ich im Mirrorskript mal fett markiert und unterstrichen ^^

-KD-
10.12.2008, 12:57
Hmpf, liegt am Mirrorscript. Eigentlich gibt es im Maker 'ne strikte Trennung zwischen Grafik und Spielmechanik. Das Mirrorscript hält diese Trennung nicht ein, was zu dem Fehler führt.

Das Problem ist, denke ich, folgendes:
- Das Mirrorscript schreibt eine variable mirror in die $game_map Objekt. Diese Variable mirror zeigt auf eine Grafik (und das ist, wie oben bereits gesagt, ziemlich schlechter Skriptingstil. Grafiken gehören in Klassen die Grafiken kontrollieren, z.B. Spriteset_Map)
- Beim Abspeichern wird auch $game_map Objekt abgespeichert. Hier das Problem: Man darf keine Grafiken abspeichern (wäre ja auch reichlich sinnlos. Stell dir vor dein Projekt würde beim Speichern sämtliche Sound- und Grafikdateien mit abspeichern. Dann wäre jeder Spielstand nochmal so groß wie das ganze Projekt). Darum sorgt das Mirror-Script dafür, dass das mirror Objekt wieder entfernt wird
- Nach Abspeichern existiert das Mirrorobjekt nicht mehr --> Fehlermeldung
- normalerweise speicherst du in einem Extra Speichermenü ab. Dort wird, nach beenden des Menüs, das Mirrorobjekt sowieso wieder neu erzeugt. Das ist hier eben nicht der Fall.

Die sinnigste Lösung wäre natürlich, dass Mirror-Script so umzuschreiben, dass die mirror-Variable nicht mehr in der Game_Map Klasse liegt. Nun weiß ich nicht ob du das ganze Mirror-Script gepostet hast, oder da noch was fehlt. Es ist schwer einzuschätzen was für Auswirkungen eine solche Änderung hätte. Eine etwas leichtgewichtigere Änderung wäre:


class Spriteset_Map
# HIER gehört das Mirror Objekt rein *rolleyes*
attr_reader :mirror
alias update_without_mirror update
def update
@mirror ||= Sprite_Mirror.new(@viewport1)
update_without_mirror
end

alias dispose_mirror dispose
def dispose
@mirror.dispose
dispose_mirror
end
end
class Sprite_Character
# lösche den Unsinn der vorher dastand
alias initialize mirror_initialize
remove_method :mirror_initialize
end
class Scene_Save < Scene_File
# lösche den Unsinn der vorher dastand
alias write_save_data mirror_write_save_data
remove_method :mirror_write_save_data
end
class Spriteset_Map
# lösche den Unsinn der vorher dastand
alias initialize mirror_map_initialize
remove_method :mirror_map_initialize
end
class Game_Map
# blöder Hack um das halbwegs zu bereinigen, ohne das
# Script umschreiben zu müssen
def mirror
if $scene.kind_of?(Scene_Map) then
$scene.instance_variable_get(:@spriteset).mirror
else
nil
end
end
remove_method :mirror=
end
Unter das Mirror-Script einfügen und hoffen das es funktioniert.

Skorp
10.12.2008, 22:34
Das Skript ist so komplett, ja...
Nur hab ich jetzt nicht ganz verstanden wo ich das alles hinmachen muss... Ws ich genau löschen soll? Das Skript ist aber so komplett, ja.

Ascare
14.12.2008, 12:22
Schreib mal in der Zeile 112 anstatt

@mirror.update
einfach

mirror_update
Mit "Script..." kannst du dann per Quicksave.save und Quicksave.load den Schnellspeicherstand nutzen.