Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Scrolling the map with the MouseWheel

Scrolling map with mousewheel
Version: 0.1

Introduction

Allow the map scrolling with the mousewheel

Screenshots
none...

Demo
none

Script
Code:
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
#		  Scrolling de la map, avec la molette de la souris
#  berka					0.1					Rgss2
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
#			  http://www.rpgmakervx-fr.com
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
# adaptation du script ruby de ˜aŠó		 un grand merci !
#
# molette pour les ordonnées
# Ctrl+molette pour les abcisses
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
module Berka
  module Souris
	ID_Int=1  #id de l'interrupteur a activer pour autoriser le scrolling
	Vitesse=8 #vitesse du scrolling de la map
  end
end
include Berka::Souris
class Souris
  Get_Message=Win32API.new('User32','GetMessage','plll','l')
  GetAsyncKeyState=Win32API.new("user32","GetAsyncKeyState",'i','i')
  GetKeyState=Win32API.new("user32","GetKeyState",'i','i')
  SetCursorPos=Win32API.new('user32','SetCursorPos','nn','n')
  GetCursorPo=Win32API.new('user32','GetCursorPos','p','i')
  ScreenToClient=Win32API.new('user32','ScreenToClient','lp','i')
  GetPrivateProfileStringA=Win32API.new('kernel32','GetPrivateProfileStringA','pppplp','l')
  FindWindowA=Win32API.new('user32','FindWindowA','pp','l')
  GetClientRect=Win32API.new('user32','GetClientRect','lp','i')
  GetWindowRect=Win32API.new('user32','GetWindowRect','lp','i')
  Point=Struct.new(:x,:y)
  Message=Struct.new(:message,:wparam,:lparam,:pt)
  Param=Struct.new(:x,:y,:scroll)
  Scroll=0x0000020A
  def handle
	game_name="\0"*256
	GetPrivateProfileStringA.call('Game','Title','',game_name,255,".\\Game.ini")
	game_name.delete!("\0")
	return handle=FindWindowA.call('RGSS Player',game_name)
  end
  def unpack_dword(buffer,offset=0)
	ret=buffer[offset+0]&0x000000ff
	ret|=(buffer[offset+1]<<(8*1))&0x0000ff00
	ret|=(buffer[offset+2]<<(8*2))&0x00ff0000
	ret|=(buffer[offset+3]<<(8*3))&0xff000000
	return ret
  end
  def unpack_msg(buffer)
	msg=Message.new;msg.pt=Point.new
	msg.message=unpack_dword(buffer,4*1)
	msg.wparam=unpack_dword(buffer,4*2)
	msg.lparam=unpack_dword(buffer,4*3)
	msg.pt.x=unpack_dword(buffer,4*5)
	msg.pt.y=unpack_dword(buffer,4*6)
	return msg
  end
  def wmcallback(msg)
	return unless msg.message==Scroll
	param=Param.new
	param.x=word2signed_short(loword(msg.lparam))
	param.y=word2signed_short(hiword(msg.lparam))
	param.scroll=word2signed_short(hiword(msg.wparam))
	return [param.x,param.y,param.scroll]
  end
  def hiword(dword);return ((dword&0xffff0000)>>16)&0x0000ffff;end
  def loword(dword);return dword&0x0000ffff;end
  def word2signed_short(value)
	return value if (value&0x8000)==0
	return -1*((~value&0x7fff)+1)
  end
  def click?(button);@keys.include?(button)?(return true):(return false);end  
  def press?(button);@press.include?(button)?(return true):(return false);end
  def pressed?(key);return true unless GetKeyState.call(key).between?(0,1);return false;end
  def global_pos;pos=[0,0].pack('ll');GetCursorPo.call(pos)!=0 ? (return pos.unpack('ll')):(return nil);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))
	  SetCursorPos.call(client_pos[0]+x_pos,client_pos[1]+y_pos)
	end
  end
  def update
	@pos,@keys,@press=pos,[],[]
	@keys<<1 if GetAsyncKeyState.call(1)&0x01==1
	@keys<<2 if GetAsyncKeyState.call(2)&0x01==1
	@keys<<3 if GetAsyncKeyState.call(4)&0x01==1
	@press<<1 if pressed?(1)
	@press<<2 if pressed?(2)
	@press<<3 if pressed?(4)
  end  
  def pos
	x,y=screen_to_client(*global_pos)
	width,height=client_size
	begin
	  x=0 if x<=0;y=0 if y<=0
	  x=width if x>=width;y=height if y>=height
	  return x,y
	end
  end
  def dans_player?
	return true if global_pos[0].between?(client_pos[0],client_pos[0]+client_size[0])&&
	global_pos[1].between?(client_pos[1],client_pos[1]+client_size[1])
	return false
  end
  def screen_to_client(x,y)
	return nil unless x&&y
	pos=[x,y].pack('ll')
	ScreenToClient.call(handle,pos)!=0?(return pos.unpack('ll')):(return nil)
  end
  def client_size
	rect=[0,0,0,0].pack('l4')
	GetClientRect.call(handle,rect)
	right,bottom=rect.unpack('l4')[2..3]
	return right,bottom
  end
  def client_pos
	rect=[0,0,0,0].pack('l4')
	GetWindowRect.call(handle,rect)
	left,upper=rect.unpack('l4')[0..1]
	return left+4,upper+30
  end  
  def grid
	return nil if @pos.nil?
	return [(@pos[0]+$game_map.display_x/8)/32,(@pos[1]+$game_map.display_y/8)/32]
  end
  def scroll
	msg="\0"*32;Get_Message.call(msg,0,0,0);r=wmcallback(unpack_msg(msg))
	return r if !r.nil?
  end
end
$souris=Souris.new
module Input
  class<<self
	alias :update_souris :update unless Input.methods.include?("update_souris") 
	def update 
	  update_souris
	  $souris.update
	end
  end
end

class Scene_Map<Scene_Base
  alias :souris_update :update
  def update
	souris_update
	update_scroll if $souris.dans_player?&&$game_switches[ID_Int]
  end
  def update_scroll
	s=$souris.scroll;return if s.nil?
	s[2]<0 ? (Input.press?(Input::CTRL) ? d=6 : d=2) : (Input.press?(Input::CTRL) ? d=4 : d=8)
	$game_map.start_scroll(d,1,Vitesse)
  end
end
Code:
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 
#          Scrolling de la map, avec la molette de la souris 
#  berka                    0.1                    Rgss1
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 
#              http://www.rpgmakervx-fr.com 
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 
# adaptation du script ruby de ËœaŠó         un grand merci ! 
# 
# molette pour les ordonnées 
# Ctrl+molette pour les abcisses 
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 
module Berka 
  module Souris 
    ID_Int=1  #id de l'interrupteur a activer pour autoriser le scrolling 
    Vitesse=8 #vitesse du scrolling de la map 
  end 
end 

class Souris 
  Get_Message=Win32API.new('User32','GetMessage','plll','l') # reception d'un message 
  GetAsyncKeyState=Win32API.new("user32","GetAsyncKeyState",'i','i') # test d'une touche 
  GetKeyState=Win32API.new("user32","GetKeyState",'i','i') # etat d'une touche 
  SetCursorPos=Win32API.new('user32','SetCursorPos','nn','n') # positionnement du curseur 
  GetCursorPo=Win32API.new('user32','GetCursorPos','p','i') # position du curseur 
  ScreenToClient=Win32API.new('user32','ScreenToClient','lp','i') # coordonnées du handle 
  GetPrivateProfileStringA=Win32API.new('kernel32','GetPrivateProfileStringA','pppplp','l') # lecture fichier 
  FindWindowA=Win32API.new('user32','FindWindowA','pp','l') # recuperation handle d'une fenetre 
  GetClientRect=Win32API.new('user32','GetClientRect','lp','i') # recuperations dimensions ecran 
  GetWindowRect=Win32API.new('user32','GetWindowRect','lp','i') #recuperation dimensions fenetre (handle) 
  Point=Struct.new(:x,:y) # création d'une structure de symboles: coord molette 
  Message=Struct.new(:message,:wparam,:lparam,:pt) # struct de symboles: message renvoyé par la molette 
  Param=Struct.new(:x,:y,:scroll) # parametres de la molette 
  Scroll=0x0000020A # pointeur de la molette 
  def handle # recuperation du handle du rgss player 
    game_name="\0"*256 
    GetPrivateProfileStringA.call('Game','Title','',game_name,255,".\\Game.ini") 
    game_name.delete!("\0") 
    return handle=FindWindowA.call('RGSS Player',game_name) 
  end 
  def unpack_dword(buffer,offset=0) # décompactage d'integer 32bits 
    ret=buffer[offset+0]&0x000000ff 
    ret|=(buffer[offset+1] << (8*1))&0x0000ff00 
    ret|=(buffer[offset+2] << (8*2))&0x00ff0000 
    ret|=(buffer[offset+3] << (8*3))&0xff000000 
    return ret 
  end 
  def unpack_msg(buffer) # décompactage du message de la molette 
    msg=Message.new;msg.pt=Point.new 
    msg.message=unpack_dword(buffer,4*1) 
    msg.wparam=unpack_dword(buffer,4*2) 
    msg.lparam=unpack_dword(buffer,4*3) 
    msg.pt.x=unpack_dword(buffer,4*5) 
    msg.pt.y=unpack_dword(buffer,4*6) 
    return msg 
  end 
  def wmcallback(msg) 
    return unless msg.message==Scroll 
    param=Param.new 
    param.x=word2signed_short(loword(msg.lparam)) 
    param.y=word2signed_short(hiword(msg.lparam)) 
    param.scroll=word2signed_short(hiword(msg.wparam)) 
    return [param.x,param.y,param.scroll] 
  end 
  def hiword(dword);return ((dword&0xffff0000)>>16)&0x0000ffff;end # 
  def loword(dword);return dword&0x0000ffff;end 
  def word2signed_short(value) 
    return value if (value&0x8000)==0 
    return -1*((~value&0x7fff)+1) 
  end 
  def click?(button);@keys.include?(button)?(return true):(return false);end  #si clic 
  def press?(button);@press.include?(button)?(return true):(return false);end # si appui 
  def pressed?(key);return true unless GetKeyState.call(key).between?(0,1);return false;end # test appui 
  def global_pos;pos=[0,0].pack('ll');GetCursorPo.call(pos)!=0 ? (return pos.unpack('ll')):(return nil);end # pos a l'ecran 
  def set_pos(x_pos=0,y_pos=0) # positionnement 
    width,height=client_size 
    if (x_pos.between?(0,width)&&y_pos.between?(0,height)) 
      SetCursorPos.call(client_pos[0]+x_pos,client_pos[1]+y_pos) 
    end 
  end 
  def update # maj des entrees 
    @pos,@keys,@press=pos,[],[] 
    @keys << 1 if GetAsyncKeyState.call(1)&0x01==1 
    @keys << 2 if GetAsyncKeyState.call(2)&0x01==1 
    @keys << 3 if GetAsyncKeyState.call(4)&0x01==1 
    @press << 1 if pressed?(1) 
    @press << 2 if pressed?(2) 
    @press << 3 if pressed?(4) 
  end  
  def pos # recuperation position dans player 
    x,y=screen_to_client(*global_pos) 
    width,height=client_size 
    begin 
      x=0 if x<=0;y=0 if y<=0 
      x=width if x>=width;y=height if y>=height 
      return x,y 
    end 
  end 
  def dans_player? # teste si curseur est dans player 
    return true if global_pos[0].between?(client_pos[0],client_pos[0]+client_size[0])&& 
    global_pos[1].between?(client_pos[1],client_pos[1]+client_size[1]) 
    return false 
  end 
  def screen_to_client(x,y) #pos player dans ecran 
    return nil unless x&&y 
    pos=[x,y].pack('ll') 
    ScreenToClient.call(handle,pos)!=0?(return pos.unpack('ll')):(return nil) 
  end 
  def client_size # dimensions player 
    rect=[0,0,0,0].pack('l4') 
    GetClientRect.call(handle,rect) 
    right,bottom=rect.unpack('l4')[2..3] 
    return right,bottom 
  end 
  def client_pos # position player 
    rect=[0,0,0,0].pack('l4') 
    GetWindowRect.call(handle,rect) 
    left,upper=rect.unpack('l4')[0..1] 
    return left+4,upper+30 
  end  
  def grid # convertit position en position carreaux 
    return nil if @pos.nil? 
    return [(@pos[0]+$game_map.display_x/8)/32,(@pos[1]+$game_map.display_y/8)/32] 
  end 
  def scroll # retourne l'etat de la molette 
    msg="\0"*32;Get_Message.call(msg,0,0,0);r=wmcallback(unpack_msg(msg)) 
    return r if !r.nil? 
  end 
end 
$souris=Souris.new # lancement de la classe souris 
module Input 
  class << self 
    alias :update_souris :update unless Input.methods.include?("update_souris") 
    def update 
      update_souris 
      $souris.update # maj souris 
    end 
  end 
end 

class Scene_Map 
  alias :souris_update :update 
  def update 
    souris_update 
    update_scroll if $souris.dans_player?&&$game_switches[Berka::Souris::ID_Int] 
  end 
  def update_scroll 
    s=$souris.scroll;return if s.nil? 
    s[2]<0 ? (Input.press?(Input::CTRL) ? d=6 : d=2) : (Input.press?(Input::CTRL) ? d=4 : d=8) 
    $game_map.start_scroll(d,1,Berka::Souris::Vitesse) # lance le scroll dans la direction d 
  end 
end

Instructions
place this script above main
Active the switch[1] to run the scroll system

FAQ
mousewheel: y
ctrl+mousewheel: x

Compatibility
I don't really know

Credits and Thanks
˜aŠó in: mousewheel reader

Terms and Conditions
free but credits are required
 
Sweet. I really like your scripts Berka. Something tells me you'll soon come up with a full RTS system. :)
One thing, you should add more comments to your script. It would look more organized and would help people who aren't familiar with ruby to understand what's going on in the script.

Once again, good job man! :thumb:
 
I haven't tested this yet, But this could be really really helpful for my game. Can you limit to how far you can allow them to scroll?
 
sorry... but I don't understand your question...

each scrollwheel input scrolls the map with one tile (32px)
to limit the range of scroll...

I've not time to think about it... today, but you could try to compare player coords and display coords
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top