Kain Nobel
Member
Good day everybody!
During my recent revision of my test bed (which I haven't updated in months...) there's one problem in one script I've never been able to overcome. I suppose this little bug could be a big deal depending on what certain people really wanted to use the script for. The problem I'm talking about is the player can jump over X ammount of spaces (whatever the farthest space is) yet... I can't get the player to jump between objects, like so...
O O X O X
The O's 'n X's represent passability like the passabilities setup in the tileset editor. See the space between the two X's (impassable tiles), the player would be able to jump out of that spot, but if I wanted him to jump back in it wouldn't work. The method that defines this is Game_Player#jump_dist, which basically iterates from Jump::Dist downto 0 and passable spaces into an array, then returns array.first or whatever
Here's the full copy of the script, you might want to playtest it yourself 'n see if you can figure out why I'm having this problem because the code looks fine to the naked eye but perhaps there's something I'm just totally overlooking...
Setup a test map similar to this one and test it from different directions (they should all work the same, diagonals lose 1 space of distance when jumping though naturally). You'll see, based on what you set Jump::Distance to, the player can jump out but can never jump back in.
During my recent revision of my test bed (which I haven't updated in months...) there's one problem in one script I've never been able to overcome. I suppose this little bug could be a big deal depending on what certain people really wanted to use the script for. The problem I'm talking about is the player can jump over X ammount of spaces (whatever the farthest space is) yet... I can't get the player to jump between objects, like so...
O O X O X
The O's 'n X's represent passability like the passabilities setup in the tileset editor. See the space between the two X's (impassable tiles), the player would be able to jump out of that spot, but if I wanted him to jump back in it wouldn't work. The method that defines this is Game_Player#jump_dist, which basically iterates from Jump::Dist downto 0 and passable spaces into an array, then returns array.first or whatever
Code:
 #-----------------------------------------------------------------------------
 # * Jump Dist
 #-----------------------------------------------------------------------------
 def jump_dist
  spaces = Array.new
  (Jump::Distance).downto(0) do |i|
   if SDK.enabled?('Player.Run') && Object.const_defined?(:Run)
    i += Jump.run_modifier if $game_player.running?
   end
   i -= 1 if attempt_diagonal? || moving_diagonal?
   j = i + 1
   case move_direction
   when 1 ; spaces.push(j) if passable?(self.x-i, self.y+i, 0)
   when 3 ; spaces.push(j) if passable?(self.x+i, self.y+i, 0)
   when 7 ; spaces.push(j) if passable?(self.x-i, self.y-i, 0)
   when 9 ; spaces.push(j) if passable?(self.x+i, self.y-i, 0)
   end
   case @direction
   when 2 ; spaces.push(j) if passable?(self.x, self.y+i, @direction)
   when 4 ; spaces.push(j) if passable?(self.x-i, self.y, @direction)
   when 6 ; spaces.push(j) if passable?(self.x+i, self.y, @direction)
   when 8 ; spaces.push(j) if passable?(self.x, self.y-i, @direction)
   end
  end
  return spaces.empty? ? 0 : spaces.first
 end
Here's the full copy of the script, you might want to playtest it yourself 'n see if you can figure out why I'm having this problem because the code looks fine to the naked eye but perhaps there's something I'm just totally overlooking...
Code:
#===============================================================================
# ~** Character Move Test **~
#-------------------------------------------------------------------------------
# Written By : Kain Nobel
# Version  : 2.0
# Last Update : 09.02.2008
#===============================================================================
# Description
# -----------
#
#Â This is a special set of methods, that will tell you which direction a
#Â character or event is moving, and supports both 4 and 8 directional movement
#Â checking.
#
#Â When checking something like $game_map.events[1].moving_down?, you have the
#Â optional argument 'diag'. If you set this argument as 'true' and a player is
#Â moving_lower_left, then it'll return false, else it'll return true for both.
#
#Â Also, for Game_Player, we've got additional methods for checking if player
#Â is 'attempting' to move a certain direction. This is for scripts that want
#Â to know, "Is he just 'attempting' to move left, or is he 'really' moving
#Â left? So, it doesn't check for Input, rather it'll check for Movement AND
#Â Input.
#
# Methods List
# -------------
# Game_Character
#Â moving_down?
#Â moving_left?
#Â moving_right?
#Â moving_up?
#Â moving_upper_left?
#Â moving_upper_right?
#Â moving_lower_left?
#Â moving_lower_right?
#Â move_direction
#Â moving_diagonal?
#
# Game_Player (< Game_Character)
#Â attempt_down?
#Â attempt_left?
#Â attempt_right?
#Â attempt_up?
#Â attempt_upper_left?
#Â attempt_upper_right?
#Â attempt_lower_left?
#Â attempt_lower_right?
#Â attempt_moving?
#Â attempt_direction?
#Â attempt_diagonal?
#
#===============================================================================
#-------------------------------------------------------------------------------
# * SDK Log
#-------------------------------------------------------------------------------
if Object.const_defined?(:SDK)
 SDK.log('MACL::RGSS.Character.MoveTest', 'Kain Nobel', 2.0, '09.21.2008')
end
#-------------------------------------------------------------------------------
# * MACL Loading
#-------------------------------------------------------------------------------
if Object.const_defined?(:MACL)
 MACL::Loaded << 'RGSS.Character.MoveTest'
end
#===============================================================================
# ** Game_Character
#-------------------------------------------------------------------------------
#Â The parent superclass of Game_Player and Game_Event has been modified to
# return detailed information on which direction a character is moving.
#===============================================================================
class Game_Character
 #-----------------------------------------------------------------------------
 # * Moving Down?
 #-----------------------------------------------------------------------------
 def moving_down?(diag = false)
  return false if !diag && (moving_lower_left? || moving_lower_right?)
  return (self.real_y < self.y * 128)
 end
 #-----------------------------------------------------------------------------
 # * Moving Left?
 #-----------------------------------------------------------------------------
 def moving_left?(diag = false)
  return false if !diag && (moving_upper_left? || moving_lower_left?)
  return (self.real_x > self.x * 128)
 end
 #-----------------------------------------------------------------------------
 # * Moving Right?
 #-----------------------------------------------------------------------------
 def moving_right?(diag = false)
  return false if !diag && (moving_upper_right? || moving_lower_right?)
  return (self.real_x < self.x * 128)
 end
 #-----------------------------------------------------------------------------
 # * Moving Left?
 #-----------------------------------------------------------------------------
 def moving_up?(diag = false)
  return false if !diag && (moving_upper_left? || moving_upper_right?)
  return (self.real_y > self.y * 128)
 end
 #-----------------------------------------------------------------------------
 # * Moving Lower Left?
 #-----------------------------------------------------------------------------
 def moving_lower_left?
  return (self.real_y < self.y * 128) && (self.real_x > self.x * 128)
 end
 #-----------------------------------------------------------------------------
 # * Moving Lower Right?
 #-----------------------------------------------------------------------------
 def moving_lower_right?
  return (self.real_y < self.y * 128) && (self.real_x < self.x * 128)
 end
 #-----------------------------------------------------------------------------
 # * Moving Lower Left?
 #-----------------------------------------------------------------------------
 def moving_upper_left?
  return (self.real_y > self.y * 128) && (self.real_x > self.x * 128)
 end
 #-----------------------------------------------------------------------------
 # * Moving Lower Right?
 #-----------------------------------------------------------------------------
 def moving_upper_right?
  return (self.real_y > self.y * 128) && (self.real_x < self.x * 128)
 end
 #-----------------------------------------------------------------------------
 # * Move Direction?
 #-----------------------------------------------------------------------------
 def move_direction
  return 2 if moving_down? && !(moving_lower_left? || moving_lower_right?)
  return 4 if moving_left? && !(moving_lower_left? || moving_upper_left?)
  return 6 if moving_right? && !(moving_lower_right? || moving_upper_right?)
  return 8 if moving_up?  && !(moving_upper_left? || moving_upper_right?)
  return 1 if moving_lower_left?
  return 3 if moving_lower_right?
  return 7 if moving_upper_left?
  return 9 if moving_upper_right?
  return 0
 end
 #-----------------------------------------------------------------------------
 # * Moving Diagonal?
 #-----------------------------------------------------------------------------
 def moving_diagonal?
  return true if moving_upper_left? or moving_upper_right?
  return true if moving_lower_left? or moving_lower_right?
  return false
 end
 #-----------------------------------------------------------------------------
 # * Attempt Print Test
 #-----------------------------------------------------------------------------
 def moving_print_test(diag = false)
  print("Down : "+moving_down?(diag).to_s+
  "\nLeft : "+moving_left?(diag).to_s+
  "\nRight : "+moving_right?(diag).to_s+
  "\nUp : "+moving_up?(diag).to_s+
  "\nUpRight : "+moving_upper_right?.to_s+
  "\nUpLeft : "+moving_upper_left?.to_s+
  "\nDownRight : "+moving_lower_right?.to_s+
  "\nDownLeft : "+moving_lower_left?.to_s+
  "\nDirection : "+move_direction.to_s)
 end
end
#===============================================================================
# ** Game_Player
#-------------------------------------------------------------------------------
#Â The child class of Game_Character, returns user's directional input to tell
# you if they're 'attemtping' to move a certain direction.
#===============================================================================
class Game_Player < Game_Character
 #-----------------------------------------------------------------------------
 # * Attempt Down?
 #-----------------------------------------------------------------------------
 def attempt_down?(diag = false)
  unless Input.press?(Input::LEFT) || Input.press?(Input::RIGHT)
   return Input.press?(Input::DOWN)
  end ; return false
 end
 #-----------------------------------------------------------------------------
 # * Attempt Left?
 #-----------------------------------------------------------------------------
 def attempt_left?(diag = false)
  unless Input.press?(Input::UP) || Input.press?(Input::DOWN)
   return Input.press?(Input::LEFT)
  end ; return false
 end
 #-----------------------------------------------------------------------------
 # * Attempt Right?
 #-----------------------------------------------------------------------------
 def attempt_right?(diag = false)
  unless Input.press?(Input::UP) || Input.press?(Input::DOWN)
   return Input.press?(Input::RIGHT)
  end ; return false
 end
 #-----------------------------------------------------------------------------
 # * Attempt Up?
 #-----------------------------------------------------------------------------
 def attempt_up?(diag = false)
  unless Input.press?(Input::LEFT) || Input.press?(Input::RIGHT)
   return Input.press?(Input::UP)
  end ; return false
 end
 #-----------------------------------------------------------------------------
 # * Attempt Upper Left?
 #-----------------------------------------------------------------------------
 def attempt_upper_left?
  m = Input.press?(Input::UP) && Input.press?(Input::LEFT)
  if defined?(Aleworks) && !m
   return Input.press?(Input::UPPER_LEFT)
  end
  return m
 end
 #-----------------------------------------------------------------------------
 # * Attempt Upper Right?
 #-----------------------------------------------------------------------------
 def attempt_upper_right?
  m = Input.press?(Input::UP) && Input.press?(Input::RIGHT)
  if defined?(Aleworks) && !m
   return Input.press?(Input::UPPER_RIGHT)
  end
  return m
 end
 #-----------------------------------------------------------------------------
 # * Attempt Lower Left?
 #-----------------------------------------------------------------------------
 def attempt_lower_left?
  m = Input.press?(Input::DOWN) && Input.press?(Input::LEFT)
  if defined?(Aleworks) && !m
   return Input.press?(Input::LOWER_LEFT)
  end
  return m
 end
 #-----------------------------------------------------------------------------
 # * Attempt Lower Right?
 #-----------------------------------------------------------------------------
 def attempt_lower_right?
  m = Input.press?(Input::DOWN) && Input.press?(Input::RIGHT)
  if defined?(Aleworks) && !m
   return Input.press?(Input::LOWER_RIGHT)
  end
  return m
 end
 #-----------------------------------------------------------------------------
 # * Attempt Moving?
 #-----------------------------------------------------------------------------
 def attempt_moving?(diag = false)
  return true if attempt_down?(diag)
  return true if attempt_left?(diag)
  return true if attempt_right?(diag)
  return true if attempt_up?(diag)
  return attempt_diagonal?
 end
 #-----------------------------------------------------------------------------
 # * Attempt Direction
 #-----------------------------------------------------------------------------
 def attempt_direction?
  if  attempt_down?    ; return 2
  elsif attempt_left?    ; return 4
  elsif attempt_right?    ; return 6
  elsif attempt_up?     ; return 8
  elsif attempt_lower_left? ; return 1
  elsif attempt_lower_right? ; return 3
  elsif attempt_upper_left? ; return 7
  elsif attempt_upper_right? ; return 9
  else            ; return 0
  end
 end
 #-----------------------------------------------------------------------------
 # * Attempt Diagonal?
 #-----------------------------------------------------------------------------
 def attempt_diagonal?
  return true if attempt_upper_left?
  return true if attempt_upper_right?
  return true if attempt_lower_left?
  return true if attempt_lower_right?
  return false
 end
 #-----------------------------------------------------------------------------
 # * Attempt Print Test
 #-----------------------------------------------------------------------------
 def attempt_print_test(diag = false)
  print("Down : "+attempt_down?(diag).to_s+
  "\nLeft : "+attempt_left?(diag).to_s+
  "\nRight : "+attempt_right?(diag).to_s+
  "\nUp : "+attempt_up?(diag).to_s+
  "\nUpRight : "+attempt_upper_right?.to_s+
  "\nUpLeft : "+attempt_upper_left?.to_s+
  "\nDownRight : "+attempt_lower_right?.to_s+
  "\nDownLeft : "+attempt_lower_left?.to_s)
 end
end
Code:
#===============================================================================
# ** Player.Jump
#===============================================================================
#-------------------------------------------------------------------------------
# * SDK Log
#-------------------------------------------------------------------------------
SDK.log('Player.Jump', 'Kain Nobel ©', 2.0, '11.01.2008')
#-------------------------------------------------------------------------------
# * SDK Enabled Test - BEGIN
#-------------------------------------------------------------------------------
if SDK.enabled?('Player.Jump')
#===============================================================================
# ** Jump
#===============================================================================
module Jump
################################################################################
# ~** CUSTOMIZABLE CONSTANTS - BEGIN **~ #
################################################################################
#-----------------------------------------------------------------------------
# * IDs of Maps which you aren't allowed to jump
#-----------------------------------------------------------------------------
Xclude_Maps = []
#-----------------------------------------------------------------------------
# * Distance (in tiles) that you regularly jump
#-----------------------------------------------------------------------------
Distance = 3
#-----------------------------------------------------------------------------
# * Are you able to jump over objects with Counter tags on them?
#-----------------------------------------------------------------------------
Counter_Pass = false
#-----------------------------------------------------------------------------
# * Jump Bonus gained from running (If using Run Script)
#-----------------------------------------------------------------------------
Run_Modifier = 1
#-----------------------------------------------------------------------------
# * Audiofile to be played when you jump
#-----------------------------------------------------------------------------
SE_Jump = RPG::AudioFile.new("015-Jump01", 80, 90)
#-----------------------------------------------------------------------------
# * Audofile to be played when you land
#-----------------------------------------------------------------------------
SE_Land = RPG::AudioFile.new("016-Jump02", 80, 90)
#-----------------------------------------------------------------------------
# * Input/Key to be used to trigger the player to jump
#-----------------------------------------------------------------------------
Button = Keys::SHIFT
#-----------------------------------------------------------------------------
# * Does jumping repeat when you hold the Button?
#-----------------------------------------------------------------------------
Repeat = false
################################################################################
# ~** CUSTOMIZABLE CONSTANTS - END **~ #
################################################################################
#-----------------------------------------------------------------------------
# * Jump.play_audiofile
#-----------------------------------------------------------------------------
def self.play_audiofile(se)
case se.class.to_s
when "RPG::AudioFile"
unless se.name.include?("Audio/SE/")
se.name = "Audio/SE/" + se.name
end
Audio.se_play(se.name, se.volume, se.pitch)
when "String"
unless se.include?("Audio/SE/")
se = "Audio/SE/" + se
end
Audio.se_play(se, 100, 100)
when "Array"
n = se.size > 0 ? se[0] : ""
v = se.size > 1 ? se[1] : 100
p = se.size > 2 ? se[2] : 100
unless n.include?("Audio/SE/")
n = "Audio/SE/" + n
end
Audio.se_play(n, v, p)
end
return RPG::AudioFile.new
end
#-----------------------------------------------------------------------------
# * Jump.se_jump
#-----------------------------------------------------------------------------
def self.se_jump
return play_audiofile(SE_Jump)
end
#-----------------------------------------------------------------------------
# * Jump.se_land
#-----------------------------------------------------------------------------
def self.se_land
return play_audiofile(SE_Land)
end
#-----------------------------------------------------------------------------
# * Jump.xclude_map?
#-----------------------------------------------------------------------------
def self.xclude_map?
xclude = Xclude_Maps.is_a?(Array) ? Xclude_Maps : []
return xclude.include?($game_map.map_id)
end
#-----------------------------------------------------------------------------
# * Jump.run_modifier
#-----------------------------------------------------------------------------
def self.run_modifier
return Run_Modifier.is_a?(Numeric) ? Run_Modifier : 0
end
end
#===============================================================================
# ** Game_Map
#===============================================================================
class Game_Map
#-----------------------------------------------------------------------------
# * Tile Blank?
#-----------------------------------------------------------------------------
def no_tile?(x, y)
[2, 1, 0].each do |i|
return true if data[x, y, i].nil?
end
return data[x, y, 2].zero? && data[x, y, 1].zero? && data[x, y, 0].zero?
end
#-----------------------------------------------------------------------------
# * Disable Dash?
#-----------------------------------------------------------------------------
def disable_jump?
return Jump::XcludeMaps.include?(@map_id)
end
end
#===============================================================================
# ** Game_Character
#===============================================================================
class Game_Character
#-----------------------------------------------------------------------------
# * Alias Listings
#-----------------------------------------------------------------------------
alias_method :character_jump, :jump
alias_method :character_update_jump, :update_jump
alias_method :no_tile_passable?, :passable?
#-----------------------------------------------------------------------------
# * Jump
#-----------------------------------------------------------------------------
def jump(x_plus, y_plus)
Jump.se_jump
character_jump(x_plus, y_plus)
end
#-----------------------------------------------------------------------------
# * Update Jump
#-----------------------------------------------------------------------------
def update_jump
character_update_jump
if @jump_count.zero?
Jump.se_land
end
end
#-----------------------------------------------------------------------------
# * Passable?
#-----------------------------------------------------------------------------
def passable?(x, y, d)
new_x = x + (d == 6 ? 1 : d == 4 ? -1 : 0)
new_y = y + (d == 2 ? 1 : d == 8 ? -1 : 0)
return $game_map.no_tile?(new_x, new_y) ? false : no_tile_passable?(x, y, d)
end
end
#===============================================================================
# ** Game_Player
#===============================================================================
class Game_Player < Game_Character
#-----------------------------------------------------------------------------
# * Alias Listings
#-----------------------------------------------------------------------------
alias_method :jump_player_update, :update
#-----------------------------------------------------------------------------
# * Update
#-----------------------------------------------------------------------------
def update
jump_player_update
unless Jump.xclude_map? || jumping? || !jump_valid?
if Jump::Repeat ? Input.press?(Jump::Button) : Input.trigger?(Jump::Button)
case @direction
when 2 # Jump Down / Down-Left || Down-Right
if attempt_lower_left? ; jump(-(jump_dist-1), (jump_dist-1))
elsif attempt_lower_right? ; jump((jump_dist-1), (jump_dist-1))
else ; jump(0, jump_dist)
end
when 4 # Jump Left / Up-Left / Down-Left
if attempt_upper_left? ; jump(-(jump_dist-1), -(jump_dist-1))
elsif attempt_lower_left? ; jump(-(jump_dist-1), (jump_dist-1))
else ; jump(-jump_dist, 0)
end
when 6 # Jump Right / Up-Right / Down-Right
if attempt_upper_right? ; jump((jump_dist-1), -(jump_dist-1))
elsif attempt_lower_right? ; jump((jump_dist-1), (jump_dist-1))
else ; jump(jump_dist, 0)
end
when 8 # Jump Up / Up-Left / Up-Right
if attempt_upper_left? ; jump(-(jump_dist-1), -(jump_dist-1))
elsif attempt_upper_right? ; jump((jump_dist-1), -(jump_dist-1))
else ; jump(0, -jump_dist)
end
end
end
end
end
#-----------------------------------------------------------------------------
# * Jump Valid ?
#-----------------------------------------------------------------------------
def jump_valid?
return $DEBUG if Input.press?(Input::CTRL)
case move_direction
when 1
return false if self.y > $game_map.height - Jump::Distance
return false if self.x < Jump::Distance
when 3
return false if self.y > $game_map.height - Jump::Distance
return false if self.x > $game_map.width - Jump::Distance
when 7
return false if self.y < Jump::Distance
return false if self.x > $game_map.width - Jump::Distance
when 9
return false if self.y < Jump::Distance
return false if self.x < Jump::Distance
end
case @direction
when 2 ; return false if self.y > $game_map.height - Jump::Distance
when 4 ; return false if self.x < Jump::Distance
when 6 ; return false if self.x > $game_map.width - Jump::Distance
when 8 ; return false if self.y < Jump::Distance
end
unless Jump::Counter_Pass == true
0.upto(Jump::Distance) do |i|
case move_direction
when 1 ; return false if $game_map.counter?(self.x-i, self.y+i)
when 3 ; return false if $game_map.counter?(self.x+i, self.y+i)
when 7 ; return false if $game_map.counter?(self.x-i, self.y-i)
when 9 ; return false if $game_map.counter?(self.x+i, self.y-i)
end
case @direction
when 2 ; return false if $game_map.counter?(self.x, self.y+i)
when 4 ; return false if $game_map.counter?(self.x-i, self.y)
when 6 ; return false if $game_map.counter?(self.x+i, self.y)
when 8 ; return false if $game_map.counter?(self.x, self.y-i)
end
end
end
return true
end
#-----------------------------------------------------------------------------
# * Jump Dist
#-----------------------------------------------------------------------------
def jump_dist
spaces = Array.new
(Jump::Distance).downto(0) do |i|
if SDK.enabled?('Player.Run') && Object.const_defined?(:Run)
i += Jump.run_modifier if $game_player.running?
end
i -= 1 if attempt_diagonal? || moving_diagonal?
j = i + 1
case move_direction
when 1 ; spaces.push(j) if passable?(self.x-i, self.y+i, 0)
when 3 ; spaces.push(j) if passable?(self.x+i, self.y+i, 0)
when 7 ; spaces.push(j) if passable?(self.x-i, self.y-i, 0)
when 9 ; spaces.push(j) if passable?(self.x+i, self.y-i, 0)
end
case @direction
when 2 ; spaces.push(j) if passable?(self.x, self.y+i, @direction)
when 4 ; spaces.push(j) if passable?(self.x-i, self.y, @direction)
when 6 ; spaces.push(j) if passable?(self.x+i, self.y, @direction)
when 8 ; spaces.push(j) if passable?(self.x, self.y-i, @direction)
end
end
return spaces.empty? ? 0 : spaces.first
end
end
#-------------------------------------------------------------------------------
# * SDK Enabled Test - END
#-------------------------------------------------------------------------------
end
Setup a test map similar to this one and test it from different directions (they should all work the same, diagonals lose 1 space of distance when jumping though naturally). You'll see, based on what you set Jump::Distance to, the player can jump out but can never jump back in.
http://i224.photobucket.com/albums/dd288/Kain_Nobel/JumpTest.png[/img]