Par SephirothSpawn et Berka.
Placer ce script au dessus de "main" :
Code:
#===========================================
# Module Keyboard/Mouse
# par SephirothSpawn
#===========================================
module Keyboard
@keys = []
@pressed = []
Mouse_Left = 1
Mouse_Right = 2
State = Win32API.new("user32","GetKeyState",['i'],'i')
Key = Win32API.new("user32","GetAsyncKeyState",['i'],'i')
def Keyboard.getstate(key)
return true unless State.call(key).between?(0, 1)
return false
end
def Keyboard.testkey(key)
Key.call(key) & 0x01 == 1
end
def Keyboard.update
@keys = []
@keys.push(Keyboard::Mouse_Left) if Keyboard.testkey(Keyboard::Mouse_Left)
@keys.push(Keyboard::Mouse_Right) if Keyboard.testkey(Keyboard::Mouse_Right)
@pressed = []
@pressed.push(Keyboard::Mouse_Left) if Keyboard.getstate(Keyboard::Mouse_Left)
@pressed.push(Keyboard::Mouse_Right) if Keyboard.getstate(Keyboard::Mouse_Right)
end
def Keyboard.trigger?(key)
return true if @keys.include?(key)
return false
end
def Keyboard.pressed?(key)
return true if @pressed.include?(key)
return false
end
end
class Mouse
@mouse_menu = 0
def click?(button)
return true if @keys.include?(button)
return false
end
def press?(button)
return true if @press.include?(button)
return false
end
def area?(x, y, width=32, height=32)
return false if @pos == nil
return true if @pos[0] >= x and @pos[0] <= (x+width) and @pos[1] >= y and @pos[1] <= (y+height)
return false
end
def pixels
return @pos == nil ? [0, 0] : @pos
end
def tiles
return nil if @pos == nil
x = @pos[0] / 32
y = @pos[1] / 32
return [x, y]
end
def set_pos(x_pos=0, y_pos=0)
width, height = client_size
if (x_pos.between?(0, width) && y_pos.between?(0, height))
x = $mouse.client_pos[0] + x_pos; y = $mouse.client_pos[1] + y_pos
Win32API.new('user32', 'SetCursorPos', 'NN', 'N').call(x, y)
end
end
def update
@pos = $mouse.pos
@keys, @press = [], []
@keys.push(1) if Win32API.new("user32","GetAsyncKeyState",['i'],'i').call(1) & 0X01 == 1
@keys.push(2) if Win32API.new("user32","GetAsyncKeyState",['i'],'i').call(2) & 0X01 == 1
@keys.push(3) if Win32API.new("user32","GetAsyncKeyState",['i'],'i').call(4) & 0X01 == 1
@press.push(1) if Win32API.new("user32","GetKeyState",['i'],'i').call(1) & 0X01 == 1
@press.push(2) if Win32API.new("user32","GetKeyState",['i'],'i').call(2) & 0X01 == 1
@press.push(3) if Win32API.new("user32","GetKeyState",['i'],'i').call(4) & 0X01 == 1
end
def global_pos
pos = [0, 0].pack('ll')
if Win32API.new('user32', 'GetCursorPos', 'p', 'i').call(pos) != 0
return pos.unpack('ll')
else
return nil
end
end
def pos
@x, @y = screen_to_client(*global_pos)
width, height = @width,@height
if @x ==nil or @y== nil
return 0,0
end
if (@x >= 0 and @y >= 0)
@x = @x==nil ? 0 : @x
@y = @y==nil ? 0 : @y
return @x, @y
else
return 0,0
end
end
def screen_to_client(x, y)
return nil unless x and y
pos = [x, y].pack('ll')
if Win32API.new('user32', 'ScreenToClient', %w(l p), 'i').call(hwnd, pos) != 0
return pos.unpack('ll')
else
return nil
end
end
def hwnd
game_name = "\0" * 256
Win32API.new('kernel32', 'GetPrivateProfileStringA', %w(p p p p l p), 'l').call('Game','Title','',game_name,255,".\\Game.ini")
game_name.delete!("\0")
return Win32API.new('user32', 'FindWindowA', %w(p p), 'l').call('RGSS Player',game_name)
end
def client_size
rect = [0, 0, 0, 0].pack('l4')
Win32API.new('user32', 'GetClientRect', %w(l p), 'i').call(hwnd, rect)
right, bottom = rect.unpack('l4')[2..3]
return right, bottom
end
def client_pos
rect = [0, 0, 0, 0].pack('l4')
Win32API.new('user32', 'GetWindowRect', %w(l p), 'i').call(hwnd, rect)
left, upper = rect.unpack('l4')[0..1]
return left+4, upper+30
end
def grid
return nil if @pos == nil
offsetx = $game_map.display_x / 8
offsety = $game_map.display_y / 8
x = (@pos[0] + offsetx) / 32
y = (@pos[1] + offsety) / 32
return [x, y]
end
end
#===========================================
# Pathfinding
# par SephirothSpawn
#===========================================
class Game_Character
alias nf_pf_game_character_initialize initialize
alias nf_pf_game_character_update update
attr_accessor :map
attr_accessor :runpath
def initialize
nf_pf_game_character_initialize
@map = nil
@runpath = false
end
def update
run_path if @runpath == true
nf_pf_game_character_update
end
def run_path
return if moving?
step = @map[@x,@y]
if step == 1
@map = nil
@runpath = false
return
end
dir = rand(2)
case dir
when 0
move_right if @map[@x+1,@y] == step - 1 and step != 0
move_down if @map[@x,@y+1] == step - 1 and step != 0
move_left if @map[@x-1,@y] == step -1 and step != 0
move_up if @map[@x,@y-1] == step - 1 and step != 0
when 1
move_up if @map[@x,@y-1] == step - 1 and step != 0
move_left if @map[@x-1,@y] == step -1 and step != 0
move_down if @map[@x,@y+1] == step - 1 and step != 0
move_right if @map[@x+1,@y] == step - 1 and step != 0
end
end
def find_path(x,y)
sx, sy = @x, @y
result = setup_map(sx,sy,x,y)
@runpath = result[0]
@map = result[1]
@map[sx,sy] = result[2] if result[2] != nil
end
def clear_path
@map = nil
@runpath = false
end
def setup_map(sx,sy,ex,ey)
map = Table.new($game_map.width, $game_map.height)
map[ex,ey] = 1
old_positions = []
new_positions = []
old_positions.push([ex, ey])
depth = 2
depth.upto(100){|step|
loop do
break if old_positions[0] == nil
x,y = old_positions.shift
return [true, map, step] if x == sx and y+1 == sy
if $game_player.passable?(x, y) and map[x,y + 1] == 0
map[x,y + 1] = step
new_positions.push([x,y + 1])
end
return [true, map, step] if x-1 == sx and y == sy
if $game_player.passable?(x, y) and map[x - 1,y] == 0
map[x - 1,y] = step
new_positions.push([x - 1,y])
end
return [true, map, step] if x+1 == sx and y == sy
if $game_player.passable?(x, y) and map[x + 1,y] == 0
map[x + 1,y] = step
new_positions.push([x + 1,y])
end
return [true, map, step] if x == sx and y-1 == sy
if $game_player.passable?(x, y) and map[x,y - 1] == 0
map[x,y - 1] = step
new_positions.push([x,y - 1])
end
end
old_positions = new_positions
new_positions = []
}
return [false, nil, nil]
end
end
class Game_Map
alias pf_game_map_setup setup
def setup(map_id)
pf_game_map_setup(map_id)
$game_player.clear_path
end
end
#===========================================
# Mouvement par souris
# par berka
#===========================================
#
# clic gauche: definir le point d'arrivée
# clic droit: suivre/ne pas suivre le héros
# touche directionnelles: deplacer la map
#===========================================
Vitesse = 8 #vitesse du scroll de la map
$mouse = Mouse.new
class Scene_Map
alias scroll_update update
def update
Keyboard.update
$mouse.update
if Keyboard.trigger?(Keyboard::Mouse_Left)
$game_player.find_path($mouse.grid[0], $mouse.grid[1])
end
scroll_update
end
end
class Game_Player < Game_Character
alias scroll_init initialize
def initialize
scroll_init
@scroll = false
end
def update
last_real_x = @real_x
last_real_y = @real_y
last_moving = moving?
move_by_input
super
if Keyboard.trigger?(Keyboard::Mouse_Right)
if @scroll == false
$game_player.center($game_player.x, $game_player.y)
@scroll = true
else
@scroll = false
end
end
@scroll = false if Input.dir4 != 0
$game_player.update_scroll(last_real_x, last_real_y) if @scroll == true
update_vehicle
update_nonmoving(last_moving)
end
def move_by_input
return unless movable?
return if $game_map.interpreter.running?
case Input.dir4
when 2; $game_map.start_scroll(2, 1, Vitesse)
when 4; $game_map.start_scroll(4, 1, Vitesse)
when 6; $game_map.start_scroll(6, 1, Vitesse)
when 8; $game_map.start_scroll(8, 1, Vitesse)
end
end
end
Voila, pour confirmer le mouvement, cliquer !