PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Mausfunktionalität



chrisblue
21.07.2008, 22:16
Es geht um folgendes Script:


#==============================================================================
#
# 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

Ich will das der Cursor auf die Makerfelder zugreift (32 x 32 px) Allerdings soll sich der Cursor trotzdem noch nach pixeln bewegen. Ich will nämlich für einen längeren button keine 3072 Conditional Branches machen. (96 x 32 = 3072)
Ich wäre ziemlich dankbar.

makenshi
21.07.2008, 23:25
Inwiefern soll er auf die Felder zugreifen?
Das musst du genauer beschreiben.

Ansonsten kannst du ja die Pixelkoordinaten des Mauszeigers auf Makerkoordinaten umrechnen. Einfach jewals die X und Y Koordinaten durch 32 teilen.

Du brauchst für einen längeren Button auch nicht soviele Forks machen. Du kannst ja auch simpel abfragen ob sich der Mauszeiger innerhalb eines Bereiches befindet. Wenn der Button z.B. von den X Koordinaten 32 bis 64 geht und von der Y-Koordinate 12 bis 30 geht, dann stellst du denn Fork einfach so ein das er überprüft ob die X Koordinate über 32 ist. Natürlich muss dann auch ein Fork folgen der abfragt ob die X Koordinate noch unter 64 ist.
Das gleiche auch bei Y-Koordinate.

Estelyen
28.09.2008, 22:29
Genauso hab ich es in meinem Projekt gemacht. Hab mir ein eigenes Hauptmenü zusammengebastelt, da sind jetzt momentan 5 Buttons übereinander. Einer der Menüpunkte zeigt kurz einen Vorspann und springt dann ins Menü zurück (ist bisher der einzige Menüpunkt der funktioniert:p) Geht auch sehr gut, allerings hab ich festgestellt dass er weiterhin die Position des Zeigers und Mausklicks speichert, obwohl das Menü-Event (in dem ist Mouse.update() drin) gar nicht läuft. Wenn er dann ins Menü zurück kehrt, führt er augenblicklich alle Mausbewegungen/Mausklicks durch die während des Vorspanns gemacht wurden... Ich würde gern für die Dauer des Vorspanns das Mausscript "abschalten" und Mouse.disableSaveToGame() hilft da leider nicht... ich kenne mich mit Ruby leider nicht so gut aus, gibt es eine Art "Gegenbefehl" zum Mouse.initSystem(), also einen Befehl der das Mausscript wieder abschaltet?

Ascare
29.09.2008, 08:39
Ich würde gern für die Dauer des Vorspanns das Mausscript "abschalten" und Mouse.disableSaveToGame() hilft da leider nicht...
In der Script-Demo funktioniert es aber, oder?

Estelyen
29.09.2008, 11:47
Nein, da ist so ziemlich das selbe Problem vorhanden. Bei der Scriptdemo läuft das so ab:
Ich klicke auf den Bildschirm.
Ein Textfenster geht auf um zu zeigen wohin ich geklickt habe.
Ich klicke nochmal auf den Bildschirm, BEVOR ich das Fenster mit "Enter" schließe.
Ich schließe das Fenster.
Sofort geht ein neues Fenster auf um mir die Koordinaten des zweiten Klicks anzuzeigen.

Aber egal, ich hab das Problem inzwischen mit ner Vereinfachung der ganzen Prozedur beheben können:
Bisher hatte ich die ganzen Scriptbefehle (Mouse.initSystem und Mouse.update) in das Menü mit eingebunden. Jetzt habe ich ein Common Event nur für die Mausunterstützung angelegt, das Parallel läuft wenn ich den Switch 0002 aktiviere:


@>Script: Mouse.initSystem((Mouse::INIT_CURSOR | Mouse::INIT_SAVE), 'cursorweiß', 1, 2)
@>Loop
@>Wait: 1 frame(s)
@>Script: Mouse.update()
@>Conditional Branch: Script: Mouse.pressed?(Mouse::MOUSE_LEFT)
@>Control Switches: [0003: Maus Links] = ON
@>Wait: 1 frame(s)
@>Control Switches: [0003: Maus Links] = OFF
@>
: Branch End
@>Conditional Branch: Script: Mouse.pressed?(Mouse::MOUSE_RIGHT)
@>Control Switches: [0004: Maus Rechts] = ON
@>Wait: 1 frame(s)
@>Control Switches: [0004: Maus Rechts] = OFF
@>
: Branch End
@>Conditional Branch: Switch [0002: Maus an] == OFF
@>Break Loop
@>
: Branch End
@>
: Repeat Above
@>

So läuft die Mausunterstützung stets parallel nebenher und in den Menü-Events muss ich nur noch per Switches 3 und 4 überprüfen ob geklickt wurde. Dadurch dass der jeweilige Switch auch nach einem Frame bereits wieder ausgeschaltet wird hab ich auch ein anderes Problem behoben dass ich heute morgen entdeckt hab: Ich hab für die fünf Buttons in meinem Menü ja einen "möglichen Klickbereich" festgelegt. Wenn der Cursor nun außerhalb des Bereichs liegt und ich klicke, dann wurde dieser Klick ausgeführt sobald ich den Cursor auf den Button bewegt hab, aber wie gesagt: Jetzt ist das behoben xD