(Formatierungstemplate von rmxp.net)


Mouse script
Version: 1.0

Intro

Das ganze ist nur ein etwas größerer Edit von cybersams Maus-Skript. Es beinhaltet nun ein automatisches Cursor-Skript und es ist nun einfacher die Mauskoordinaten in game-variablen abzulegen. Daneben ist es generell einfacher zu benutzen als das orginalskript, zumindest ist das meine Meinung. Achja und sauberer ist der Code IMO auch =).

Features
[*]Automatisches Cursorskript (kann an und aus-geschaltet werden)
[*]Automatisches Speichern der Mauskoordinaten in game-variablen (kann an und aus-geschaltet werden)

Screenshots

Machen hier nicht wirklich Sinn..

Demo

Demolink: Maus-Script
Danke an Kai für das Hosten der Demo. Das englische RTP (1.02) wird benötigt.

Script

Code:
#==============================================================================
#
# Mouse Script 1.0                                      created by: cybersam
#                                                       edited by: MagicMagor
#
#==============================================================================
#
# (got rid of cybersams explanation here, because it isn't true for this module)
#                                                       MagicMagor
#==============================================================================

#==============================================================================
# I have edited cybersams script, to fit my needs and my personal style of
# coding. I have also extended the script and got rid of several bugs. 
# If you use this, give credit to cybersam and me.
#------------------------------------------------------------------------------
# MagicMagor
#==============================================================================

module Mouse

  MOUSE_LEFT    = 0x01        # left mouse button
  MOUSE_RIGHT   = 0x02        # right mouse button

  attr_reader :MOUSE_LEFT, :MOUSE_RIGHT

  # Flags
  
  INIT_CURSOR = 0x01
  INIT_SAVE = 0x02
  INIT_TYPE = 0x03

  CURSOR_PIC = 0x01
  CURSOR_ROOT = 0x02
  CURSOR_BITMAP = 0x03
  
  attr_reader :INIT_CURSOR, :INIT_SAVE, :INIT_TYPE,
              :CURSOR_PIC, :CURSOR_ROOT, :CURSOR_BITMAP


  @getCursorPos = Win32API.new('user32', 'GetCursorPos', 'p', 'i')
  @getWindowRect = Win32API.new('user32', 'GetWindowRect', ['p', 'p'], 'i')
  @scr2cli = Win32API.new('user32', 'ScreenToClient', %w(l p), 'i')
  @client_rect = Win32API.new('user32', 'GetClientRect', %w(l p), 'i')
  @readini = Win32API.new('kernel32', 'GetPrivateProfileStringA', %w(p p p p l p), 'l')
  @findwindow = Win32API.new('user32', 'FindWindow', %w(p p), 'l')
  @getKeyState = Win32API.new("user32","GetAsyncKeyState",['i'],'i')
    
  #---------------------------------------------------------------------------
  # Initialize the mouse-system, with given arguments. Is automaticly called
  # if needed.
  #---------------------------------------------------------------------------
  def Mouse.initSystem(*args)
    @init = true
    @handle = self.getHandle()
    @cursor = Sprite.new()
    if args.length >= 1
      flags = args[0]
      @showCursor  = (flags & INIT_CURSOR)
      @saveToGame = (flags & INIT_SAVE)
      withType = (flags & INIT_TYPE)
      if (@showCursor != 0)
        @showCursor = true
      else
        @showCursor = false
      end
      if (@saveToGame != 0)
        @saveToGame = true
      else
        @saveToGame = false
      end
      @cursor.visible = @showCursor
      @originX = 0
      @originY = 0
      if (@saveToGame)
        @gameX = args[-2]
        @gameY = args[-1]
      end
      if (@showCursor)
        if (withType)
          self.setCursor(args[1], args[2])
        else
          self.setCursor(args[1])
        end
      end
    end
    return nil
  end
  
  #---------------------------------------------------------------------------
  # Checks if key was pressed.
  #---------------------------------------------------------------------------  
  def Mouse.pressed?(key)
   return ((@getKeyState.call(key) & 0x01) == 1)
  end

  #---------------------------------------------------------------------------
  # Returns true if saving mouse positions to game-variables is enabled
  #---------------------------------------------------------------------------  
  def Mouse.saveToGame?()
    if !(@init)
      self.initSystem(nil)
    end
    return @saveToGame
  end
  
  #---------------------------------------------------------------------------
  # Enables saving the mouse positions to game-variables
  #---------------------------------------------------------------------------  
  def Mouse.enableSaveToGame(game_x = nil, game_y = nil )
    if !(@init)
      self.initSystem(nil)
    end
    @saveToGame = true
    if (game_x != nil)
      @gameX = game_x
    end
    if (game_y != nil)
      @gameY = game_y
    end
    return nil
  end
  
  #---------------------------------------------------------------------------
  # Disables saving the mouse positions to game-variables
  #---------------------------------------------------------------------------  
  def Mouse.disableSaveToGame()
    if !(@init)
      self.initSystem(nil)
    end
    @saveToGame = false
    return nil
  end

  #---------------------------------------------------------------------------
  # Sets the variable-ID in which the X position is saved
  #---------------------------------------------------------------------------  
  def Mouse.setGameX(game_x)
    if !(@init)
      self.initSystem(nil)
    end
    @gameX = game_x
    return nil
  end
  
  #---------------------------------------------------------------------------
  # Sets the variable-ID in which the Y position is saved
  #---------------------------------------------------------------------------  
  def Mouse.setGameY(game_y)
   if !(@init)
      self.initSystem(nil)
    end
   @gameY = game_y
   return nil
  end
  
  #---------------------------------------------------------------------------
  # Returns the variable-ID in which the X position is saved
  #---------------------------------------------------------------------------  
  def Mouse.gameX
    return @gameX
  end  

  #---------------------------------------------------------------------------
  # Returns the variable-ID in which the Y position is saved
  #---------------------------------------------------------------------------  
  def Mouse.gameY
    return @gameY
  end

  #---------------------------------------------------------------------------
  # Returns X-Value of mouse positions
  #---------------------------------------------------------------------------    
  def Mouse.x()
    if !(@init)
      self.initSystem(nil)
    end
    x, y = Mouse.mousePos()
    return x
  end

  #---------------------------------------------------------------------------
  # Returns Y-Value of mouse positions
  #---------------------------------------------------------------------------    
  def Mouse.y()
    if !(@init)
      self.initSystem(nil)
    end
    x, y = Mouse.mousePos()
    return y
  end
    
  #---------------------------------------------------------------------------
  # Returns TRUE when the mouse-cursor is shown.
  #---------------------------------------------------------------------------    
  def Mouse.shown?()
    if !(@init)
      self.initSystem(nil)
    end
    return @showCursor
  end

  #---------------------------------------------------------------------------
  # Enables showing of the mouse-cursor.
  #---------------------------------------------------------------------------    
  def Mouse.enableShow()
    if !(@init)
      self.initSystem(nil)
    end
    @showCursor = true
    @cursor.visible = true
    return nil
  end
    
  #---------------------------------------------------------------------------
  # Disable showing of the mouse-cursor.
  #---------------------------------------------------------------------------    
  def Mouse.disableShow()
    if !(@init)
      self.initSystem(nil)
    end
    @showCursor = false
    @cursor.visible = false
    return nil
  end

  #---------------------------------------------------------------------------
  # Sets a new bitmap for the cursor.
  #---------------------------------------------------------------------------    

  def Mouse.setCursor(filename, type = CURSOR_PIC, originX = 0, originY = 0)
    if !(@init)
      self.initSystem(nil)
    end
    @originX = originX
    @originY = originY
    case type
    when CURSOR_PIC
      @cursor.bitmap = RPG::Cache.picture(filename)
      @cursor.z = 999    
      return nil
    when CURSOR_ROOT
      @cursor.bitmap = Bitmap.new(filename)
      @cursor.z = 999
      return nil
    when CURSOR_BITMAP
      @cursor.bitmap = filename
      @cursor.z = 999
      return nil
    end
  end
  
  #---------------------------------------------------------------------------
  # Sets the x-coordinate of the cursor-picture origin.
  #---------------------------------------------------------------------------    
  def Mouse.setOriginX(originX)
    if !(@init)
      self.initSystem(nil)
    end
    @originX = originX
    return nil
  end
    
  #---------------------------------------------------------------------------
  # Sets the y-coordinate of the cursor-picture origin.
  #---------------------------------------------------------------------------    
  def Mouse.setOriginY(originY)
    if !(@init)
      self.initSystem(nil)
    end
    @originY = originY
    return nil
  end

  #---------------------------------------------------------------------------
  # Updates the position of the mouse-cursor on screen.
  #---------------------------------------------------------------------------    
  def Mouse.update()
    if !(@init)
      self.initSystem(nil)
    end
    if (@showCursor)
      if Mouse.x() != nil
        @cursor.x = Mouse.x() - @originX
      end
      if Mouse.y() != nil
        @cursor.y = Mouse.y() - @originY
      end
    end
    if ((@saveToGame) && (@gameX != nil) && (@gameY != nil))
      $game_variables[@gameX] = Mouse.x()
      $game_variables[@gameY] = Mouse.y()
    end
    return nil
  end
  
#===============================================================================  
# Private methods start here
# Do not call them directly.
# Edit them only if you know what you are doing.
#===============================================================================  
  
  #---------------------------------------------------------------------------
  # Calculates mouse position inside the programms window.
  #---------------------------------------------------------------------------  
  def Mouse.mousePos(catch_anywhere = false)
    x, y = Mouse.screenToClient(*Mouse.getPos)
    width, height = Mouse.clientSize()
    if ((x == nil) || (y == nil))
      return nil
    end
    if ((catch_anywhere) || ((x >= 0) && (y >= 0) && (x < width) && (y < height)))
      return x, y
    else
      return nil
    end
  end
  
  #---------------------------------------------------------------------------
  # Gets mouse position from OS.
  #---------------------------------------------------------------------------  
  def Mouse.getPos()
    if !(@init)
      Mouse.initSystem(nil)
    end
    pos = [0, 0].pack('ll')
    if @getCursorPos.call(pos) != 0
      return pos.unpack('ll')
    else
      return nil
    end
  end
  
  #---------------------------------------------------------------------------
  # Transforms screen-coordinates in client-coordinates.
  #---------------------------------------------------------------------------    
  def Mouse.screenToClient(x, y)
    if !(@init)
      self.initSystem(nil)
    end
    return nil unless x and y
    pos = [x, y].pack('ll')
    if @scr2cli.call(@handle, pos) != 0
      return pos.unpack('ll')
    else
      return nil
    end
  end
  
  #---------------------------------------------------------------------------
  # Gets the client size from OS.
  #---------------------------------------------------------------------------    
  def Mouse.clientSize()
    if !(@init)
      self.initSystem(nil)
    end
    rect = [0, 0, 0, 0].pack('l4')
    @client_rect.call(@handle, rect)
    right, bottom = rect.unpack('l4')[2..3]
    return right, bottom
  end
  
  #---------------------------------------------------------------------------
  # Gets the windows handle from OS.
  #---------------------------------------------------------------------------    
  def Mouse.getHandle()
    if !(@init)
      self.initSystem(nil)
    end
    gameName = "\0" * 256
    @readini.call('Game', 'Title', '', gameName, 255, ".\\Game.ini")
    gameName.delete!("\0")
    if ($DEBUG)
      # Only one RGSS Player should be open
      result = @findwindow.call('RGSS Player', 0) 
    else
      result = @findwindow.call('RGSS Player', gameName)
    end
    return result
  end    

end
Anweisungen

Das ganze Skript wird über "Call Script"-Befehle gesteuert.
Wenn ihr das integrierte Cursor-Skript benutzen wollt, müßt ihr einmal folgendes aufrufen:
Code:
Mouse.setCursor(filename[, type, originX, originY])
type, originX and originY können weggelassen werden. filename ist der Name der Datei die als Cursor-Bild verwendet wird. Sie muss dabei als Picture ins Spiel importiert worden sein. origin ist der Punkt auf dem Sprite, der exakt auf den Mauskoordinaten liegt. Standard ist die linke obere Ecke (0/0). Wenn das Sprite einen anderen Punkt benötigt (ein Fadenkreuz zB.), müßt ihr den origin entsprechend setzen. Entweder direkt über setCursor oder mittels dieser beiden Methoden:
Code:
Mouse.setOriginX(originX) # Sets the x-coordinate of the origin
Mouse.setOriginY(originY) # Sets the y-coordinate of the origin
Der Typ (type) des cursors sagt dem Skript wo es nach dem Cursor-Bild suchen soll. Diese Werte sind möglich:
Mouse:URSOR_PIC
Die Datei ist als Picture importiert und demnach im Picture-Ordner zu finden. filename beinhaltet nur den Dateinamen.
Mouse:URSOR_ROOT
Die Datei ist nicht als Picture importiert sondern liegt woanders. filename beinhaltet den gesamten Pfad zur Datei, wobei "./" den Spieleordner repräsentiert (der wo die exe drin liegt).
Mouse:URSOR_BITMAP
Der Cursor wird nicht aus einer Datei geladen. Stattdessen ist filename bereits ein Bitmap-Objekt, das als Cursor verwendet wird.

--------------------------------

Um die Koordinaten in Game-Variablen abzulegen müsst ihr einmal diese Methode aufrufen:
Code:
Mouse.enableSaveToGame(gameX, gameY)
gameX und gameY sind die IDs der Variablen in denen die Koordinaten ablegt werden. Das Skript prüft nicht ob die angegeben Werte korrekt sind (zwischen 1 und 5000), sind sie es nicht, wird das Skript mit einer Fehlermeldung abbrechen. Wenn gameX und gameY bereits mit sinnvollen Werten gefüllt sind, können diese Werte bei dieser Methode auch weggelassen werden.

Wenn ihr das Cursor-Skript oder das Abspeichern der Koordinaten in Game-Variablen benutzt müßt ihr "Mouse.update()" jeden Frame aufrufen. Es reicht den Aufruf in ein PP zu packen.

Um Platz zu sparen kann man einige oder alle Features des Skript durch korrekte Initilaisierung des Skriptes anschalten:
Code:
Mouse.initSystem(flags[additonial arguments])
# The first arguments are the flags, telling the script which features to activate
# Mouse::INIT_CURSOR
# Activates the cursor. The next argument of initSystem is the same as "filename" in setCursor.
# Uses CURSOR_PIC as cursor-type, unless specified
# Mouse::INIT_TYPE
# Specifies which cursor-type (see setCursor) is used. The third argument of initSystem is now the cursor-type
# Mouse::INIT_SAVE
# Activates saving the coordinates to game-variables. The last two arguments of initSystem are gameX and gameY
# Flags are combined with '|', see the demo for an example.
(Zu faul zum übersetzen atm)

Um zu überprüfen ob eine Maustaste gedrückt wurde könnt ihr folgendes verwenden (Conditional Branch Seite4 Script):
Code:
Mouse.pressed?(key)
key hat zwei gültige Werte, Mouse::MOUSE_LEFT und Mouse::MOUSE_RIGHT, für die linke und die rechte Maustaste.

Für weitere Methoden, die verwendet werden können guckt in die Demo oder im Skript selber. Jede Methode hat einen Kommentar-Header, der erklärt was die Methode macht.

FAQ

Nüx..

Kompabilität

Das Skript ist nicht SDK-konform, zumindest momentan nicht, kann sich in der Zukunft ändern. Solange ihr aber kein anderes Skript benutzt, das ein Modul oder eine Klasse mit dem Namen "Mouse" benutzt, sollte dieses Skript hier mit allen anderen zusammen laufen.
Vermeidet es zwei oder mehr Spiele, die dieses Skript benutzen gleichzeitig im Testmodus zu starten. Obwohl ich es mit 2 gleichzeitig laufenden Spielen ohne Probleme getestet habe, kann ich nicht garantieren, daß das Skript unter diesen Umständen funktioniert.

Credits

Hier geht ein Danke Schön an cybersam, der das Skript überhaupt anfangs geschrieben hat und die Koordinaten auch im Fenstermodus korrekt berechnen konnte. Ein weiteres Danke geht an Kai fürs Hosten der Demo.

Anmerkungen

Ich hoffe ihr findet dieses Skript, ebenso wie ich, einfacher zu benutzen als das Orginale. Ich habe ausserdem das entfernt, was ich "schlechten Programmierstil" nennen würde, wie jede Menge globale Variablen zu benutzen, wo es überhaupt nicht notwendig ist. Ich ermutige also jeden von diesem Skript etwas zu lernen. Sei es Ruby, RGSS oder einfach nur vernünftiger Programmierstil =).

Das Skript darf auch in kommerziellen (Shareware) oder verschlüsselten Spielen verwendet werden, sofern Credits gegeben werden (cybersam und mir), das ist jedenfalls meine Stellung dazu. Zur Sicherheit sollte man da aber vielleicht bei cybersam nochmal nachfragen.