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.

Advanced 8-Directional Movement Script

Status
Not open for further replies.
Advanced 8-Directional Movement
Version: 3.01


Introduction

This script allows for a more extensive 8 directional movement system than comes default with RMXP. It also improves the diagonal sprite movements. This script also affects events as well as the player. It also has the option to toggle between five different methods of movement:
  • Default 4-directional Movement - Using the arrow keys and numberpad, the player can move in only four directions.
  • Default 8-directional Movement - Using the arrow keys and numberpad, the player can move in all eight directions.
  • Point and Click Movement - Using Near_Fantastica's Mouse Module along with his Pathfinding Script and Aleworks Input Module, the player may move his character with the mouse.
  • Axial Movement - The player turns 45 degrees using the left and right arrows and move forward or backward using the up or down arrow respectively.
    This is ideal for airships, boats, or other vehicles. It can also be used with numpad movement and/or mouse movement.
  • Movement Control using Numpad - The player uses the numpad to move in all 8 directions.
    This is ideal in case you wish to use the arrow keys for something other than movement or if you want to use axial movement also.
Also, character sprites now must include 8 poses: one for each direction, in the following order:
.  Lower Left
Down
Lower Right
Left
Right
Upper Left
Up
Upper Right


Screenshots

See the Demo

Demo

Available in the Download Mananger
Also available from Geocities

Script
SDK version 2.2 or greater
Alworks Input Module version 2.0 or greater
Near Fantastica's Pathfinding script Modified by me can be found in the demo.
Near Fantastica's Mouse Module version 5.0 said:
Ruby:
#==============================================================================

# ** Mouse Input Module

#------------------------------------------------------------------------------

# Near Fantastica

# Version 5

# 01.03.06

#------------------------------------------------------------------------------

# This module defines mouse input

#==============================================================================

 

#------------------------------------------------------------------------------

# * SDK Log Script

#------------------------------------------------------------------------------

SDK.log("Mouse Input", "Near Fantastica", 5, "01.03.06")

 

#------------------------------------------------------------------------------

# * Begin SDK Enable Test

#------------------------------------------------------------------------------

if SDK.state("Mouse Input") == true

 

module Mouse

  @position

  GSM = Win32API.new('user32', 'GetSystemMetrics', 'i', 'i')

  Cursor_Pos= Win32API.new('user32', 'GetCursorPos', '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', 'FindWindowA', %w(p p), 'l')

  #--------------------------------------------------------------------------  

  def Mouse.grid

    return nil if @pos == nil

    offsetx = $game_map.display_x / 4

    offsety = $game_map.display_y / 4

    x = (@pos[0] + offsetx) / 32

    y = (@pos[1] + offsety) / 32

    return [x, y]

  end

  #--------------------------------------------------------------------------  

  def Mouse.position

    return @pos == nil ? [0, 0] : @pos

  end

  #--------------------------------------------------------------------------  

  def Mouse.global_pos

    pos = [0, 0].pack('ll')

    if Cursor_Pos.call(pos) != 0

      return pos.unpack('ll')

    else

      return nil

    end

  end

  #--------------------------------------------------------------------------  

  def Mouse.pos

    x, y = Mouse.screen_to_client(*Mouse.global_pos)

    width, height = Mouse.client_size

    begin

      if (x >= 0 and y >= 0 and x < width and y < height)

        return x, y

      else

        return nil

      end

    rescue

      return nil

    end

  end

  #--------------------------------------------------------------------------  

  def Mouse.update

    @pos = Mouse.pos

  end

  #--------------------------------------------------------------------------  

  def Mouse.screen_to_client(x, y)

    return nil unless x and y

    pos = [x, y].pack('ll')

    if Scr2cli.call(Mouse.hwnd, pos) != 0

      return pos.unpack('ll')

    else

      return nil

    end

  end

  #--------------------------------------------------------------------------  

  def Mouse.hwnd

    game_name = "\0" * 256

    Readini.call('Game','Title','',game_name,255,".\\Game.ini")

    game_name.delete!("\0")

    return Findwindow.call('RGSS Player',game_name)

  end

  #--------------------------------------------------------------------------  

  def Mouse.client_size

    rect = [0, 0, 0, 0].pack('l4')

    Client_rect.call(Mouse.hwnd, rect)

    right, bottom = rect.unpack('l4')[2..3]

    return right, bottom

  end

end

 

#------------------------------------------------------------------------------

# * End SDK Enable Test

#------------------------------------------------------------------------------

end
Code:
#============================================================================

# ** Advanced 8-D Movement

#----------------------------------------------------------------------------

# Draycos Goldaryn

# Version 3.01

# 4-30-07

# SDK Version : 2.2 - Parts 1, 2, 3

#------------------------------------------------------------------------------

# This script allows for a more extensive 8 directional movement system than

# comes default with RMXP. It also improves the diagonal sprite movements.

# This script also affects events as well as the player. It also has the option

# to toggle between five different methods of movement:

#   Default 4-directional Movement

#     Using the arrow keys and numberpad, the player can move in only four 

#     directions.

#   Default 8-directional Movement

#     Using the arrow keys and numberpad, the player can move in all eight 

#     directions.

#   Point and Click Movement

#     Using Near_Fantastica's Mouse Module along with his Pathfinding Script, 

#     and Aleworks Input Module the player may move his character with the 

#     mouse.

#   Axial Movement

#     The player turns 45? using the left and right arrows and move forward or 

#     backward using the up or down arrow respectively.

#     This is ideal for airships, boats, or other vehicles. It can also be used 

#     with numpad movement and/or mouse movement

#   Movement Control using Numpad

#     The player uses the numpad to move in all 8 directions according to the

#     following diagram:

#         \  |  /

#          7 8 9 

#         -4   6-

#          1 2 3

#         /  |  \

#     This is ideal in case you wish to use the arrow keys for something other

#     than movement or if you want to use axial movement also.

#

# Also, character sprites now must include 8 poses: one for each direction, in

# the following order:

#   Lower Left

#   Down

#   Lower Right

#   Left

#   Right

#   Upper Left

#   Up

#   Upper Right

#------------------------------------------------------------------------------

# Syntax:

#   To toggle the different methods of movement on, call the following scripts:

#     Default 8-directional movement  : $game_system.default_movement = true

#     Point and Click movement        : $game_system.mouse_movement = true

#     Axial Movement                  : $game_system.axial_movement = true

#     Movement Control using Numpad   : $game_system.numpad_movement = true

#

#   If you want to use only 4-directional movement, then set all the previous

#   mentioned variables to false.

#   NOTE: Triggering Axial Movement will disable both Default Movements. This

#         is to avoid conlficts between them.

#=============================================================================

 

#-----------------------------------------------------------------------------

# * SDK Log Script

#-----------------------------------------------------------------------------

SDK.log('Advanced 8-D Movement', 'Draycos Goldaryn', 3.01, '4-30-07')

SDK.check_requirements(2.20, [1, 2, 3], {'Aleworks Keys Module' => 1.10, 

                                      'Path Finding' => 1.5, 

                                      'Mouse Input' => 5})

 

#-----------------------------------------------------------------------------

# * Begin SDK Enable Test

#-----------------------------------------------------------------------------

if SDK.enabled?('Advanced 8-D Movement')

 

#-----------------------------------------------------------------------------

# * Module Input

#-----------------------------------------------------------------------------

module Input

  def Input.axial_dir8

    return 1 if Input.press?([[Keys::DOWN, Keys::LEFT]])

    return 3 if Input.press?([[Keys::DOWN, Keys::RIGHT]])

    return 7 if Input.press?([[Keys::UP, Keys::LEFT]])

    return 9 if Input.press?([[Keys::UP, Keys::RIGHT]])

    return 2 if Input.press?(Keys::DOWN)

    return 4 if Input.press?(Keys::LEFT)

    return 6 if Input.press?(Keys::RIGHT)

    return 8 if Input.press?(Keys::UP)

    0

  end

end

 

#-----------------------------------------------------------------------------

# * SDK::Scene Base

#-----------------------------------------------------------------------------

class SDK::Scene_Base

  alias_method(:advanced_8d_movement_scene_base_update, :update)

  def update

    Mouse.update

    advanced_8d_movement_scene_base_update

  end

end

 

#-----------------------------------------------------------------------------

# * Game System

#-----------------------------------------------------------------------------

class Game_System

  attr_accessor :wait

  #Setup movement input type toggles

  attr_accessor :default_movement #Toggles Default Movement

  attr_accessor :mouse_movement   #Toggles Mouse Movement

  attr_accessor :axial_movement   #Toggles Axial Movement

  attr_accessor :numpad_movement  #Toggles Numpad Movement

 

  alias_method (:advanced_8d_movement_game_system_initialize, :initialize)

  def initialize

    advanced_8d_movement_game_system_initialize

    @wait = 0

    #Set the movement input type toggles to default (true = on, false = off) 

    @default_movement = true

    @mouse_movement = false

    @axial_movement = false

    @numpad_movement = false

  end

end

 

#-----------------------------------------------------------------------------

# * Game System

#-----------------------------------------------------------------------------

class Game_Character

  #--------------------------------------------------------------------------

  # * SDK Log Overwritten Methods

  #--------------------------------------------------------------------------

  SDK.log_overwrite(:Game_Character, :move_lower_left)

  SDK.log_overwrite(:Game_Character, :move_lower_right)

  SDK.log_overwrite(:Game_Character, :move_upper_left)

  SDK.log_overwrite(:Game_Character, :move_upper_right)

  SDK.log_overwrite(:Game_Character, :move_random)

  SDK.log_overwrite(:Game_Character, :move_forward)

  SDK.log_overwrite(:Game_Character, :move_backward)

  SDK.log_overwrite(:Game_Character, :move_toward_player)

  SDK.log_overwrite(:Game_Character, :move_away_from_player)

  SDK.log_overwrite(:Game_Character, :jump)

  SDK.log_overwrite(:Game_Character, :turn_right_90)

  SDK.log_overwrite(:Game_Character, :turn_left_90)

  SDK.log_overwrite(:Game_Character, :turn_180)

  SDK.log_overwrite(:Game_Character, :turn_right_or_left_90)

  SDK.log_overwrite(:Game_Character, :turn_random)

  SDK.log_overwrite(:Game_Character, :turn_toward_player)

  SDK.log_overwrite(:Game_Character, :turn_away_from_player)

  #--------------------------------------------------------------------------

  # * Move Lower Left

  #--------------------------------------------------------------------------

  def move_lower_left(turn_enabled = true)

    # Turn up

    if turn_enabled

      turn_lower_left

    end

    # When a down to left or a left to down course is passable

    if (passable?(@x, @y, 2) and passable?(@x, @y + 1, 4)) or

       (passable?(@x, @y, 4) and passable?(@x - 1, @y, 2))

      # Update coordinates

      @x -= 1

      @y += 1

      # Increase steps

      increase_steps

    # If impassable

    else

      # Determine if touch event is triggered

      check_event_trigger_touch(@x-1, @y+1)

    end

  end

  #--------------------------------------------------------------------------

  # * Move Lower Right

  #--------------------------------------------------------------------------

  def move_lower_right(turn_enabled = true)

    # Turn up

    if turn_enabled

      turn_lower_right

    end

    # When a down to right or a right to down course is passable

    if (passable?(@x, @y, 2) and passable?(@x, @y + 1, 6)) or

       (passable?(@x, @y, 6) and passable?(@x + 1, @y, 2))

      # Update coordinates

      @x += 1

      @y += 1

      # Increase steps

      increase_steps

    # If impassable

    else

      # Determine if touch event is triggered

      check_event_trigger_touch(@x+1, @y+1)

    end

  end

  #--------------------------------------------------------------------------

  # * Move Upper Left

  #--------------------------------------------------------------------------

  def move_upper_left(turn_enabled = true)

    # Turn up

    if turn_enabled

      turn_upper_left

    end

    # When an up to left or a left to up course is passable

    if (passable?(@x, @y, 8) and passable?(@x, @y - 1, 4)) or

       (passable?(@x, @y, 4) and passable?(@x - 1, @y, 8))

      # Update coordinates

      @x -= 1

      @y -= 1

      # Increase steps

      increase_steps

    # If impassable

    else

      # Determine if touch event is triggered

      check_event_trigger_touch(@x-1, @y-1)

    end

  end

  #--------------------------------------------------------------------------

  # * Move Upper Right

  #--------------------------------------------------------------------------

  def move_upper_right(turn_enabled = true)

    # Turn up

    if turn_enabled

      turn_upper_right

    end

    # When an up to right or a right to up course is passable

    if (passable?(@x, @y, 8) and passable?(@x, @y - 1, 6)) or

       (passable?(@x, @y, 6) and passable?(@x + 1, @y, 8))

      # Update coordinates

      @x += 1

      @y -= 1

      # Increase steps

      increase_steps

    # If impassable

    else

      # Determine if touch event is triggered

      check_event_trigger_touch(@x+1, @y-1)

    end

  end

  #--------------------------------------------------------------------------

  # * Move at Random

  #--------------------------------------------------------------------------

  def move_random

    case rand(8)

    when 0  # Move down

      move_down

    when 1  # Move left

      move_left

    when 2  # Move right

      move_right

    when 3  # Move up

      move_up

    when 4

      move_lower_left

    when 5

      move_lower_right

    when 6

      move_upper_left

    when 7

      move_upper_right

    end

  end

  #--------------------------------------------------------------------------

  # * Move toward Player

  #--------------------------------------------------------------------------

  def move_toward_player

    # Get difference in player coordinates

    sx = @x - $game_player.x

    sy = @y - $game_player.y

    # If coordinates are equal

    if sx == 0 and sy == 0

      return

    end

    # Get absolute value of difference

    abs_sx = sx.abs

    abs_sy = sy.abs

    #get diagonal differences

    sh = (abs_sx / 2) - abs_sy

    sv = (abs_sy / 2) - abs_sx

    # Is the player more towards a 45? angle?

    if abs_sx == abs_sy || (sv < 0 and sh < 0)

      if $game_player.y > @y

        #if the player is lower left

        if $game_player.x < @x

          move_lower_left

        #If the player is lower right

        else

          move_lower_right

        end

      else

        #if the player is upper left

        if $game_player.x < @x

          move_upper_left

        #if the player is upper right

        else

          move_upper_right

        end

      end

    # If horizontal distance is longer

    elsif abs_sx > abs_sy

      # Move towards player, prioritize left and right directions

      sx > 0 ? move_left : move_right

      if not moving? and sy != 0

        sy > 0 ? move_up : move_down

      end

    # If vertical distance is longer

    else

      # Move towards player, prioritize up and down directions

      sy > 0 ? move_up : move_down

      if not moving? and sx != 0

        sx > 0 ? move_left : move_right

      end

    end

  end

  #--------------------------------------------------------------------------

  # * Move away from Player

  #--------------------------------------------------------------------------

  def move_away_from_player

    # Get difference in player coordinates

    sx = @x - $game_player.x

    sy = @y - $game_player.y

    # If coordinates are equal

    if sx == 0 and sy == 0

      return

    end

    # Get absolute value of difference

    abs_sx = sx.abs

    abs_sy = sy.abs

    #get diagonal differences

    sh = (abs_sx / 2) - abs_sy

    sv = (abs_sy / 2) - abs_sx

    # Is the player more towards a 45? angle?

    if abs_sx == abs_sy || (sv < 0 and sh < 0)

      if $game_player.y > @y

        #if the player is lower left

        if $game_player.x < @x

          move_upper_right

        #If the player is lower right

        else

          move_upper_left

        end

      else

        #if the player is upper left

        if $game_player.x < @x

          move_lower_right

        #if the player is upper right

        else

          move_lower_left

        end

      end

    # If horizontal distance is longer

    elsif abs_sx > abs_sy

      # Move away from player, prioritize left and right directions

      sx > 0 ? move_right : move_left

      if not moving? and sy != 0

        sy > 0 ? move_down : move_up

      end

    # If vertical distance is longer

    else

      # Move away from player, prioritize up and down directions

      sy > 0 ? move_down : move_up

      if not moving? and sx != 0

        sx > 0 ? move_right : move_left

      end

    end

  end

  #--------------------------------------------------------------------------

  # * 1 Step Forward

  #--------------------------------------------------------------------------

  def move_forward

    case @direction

    when 2

      move_down(false)

    when 4

      move_left(false)

    when 6

      move_right(false)

    when 8

      move_up(false)

    when 1 #lower left

      move_lower_left(false)

    when 3 #lower right

      move_lower_right(false)

    when 7 #upper left

      move_upper_left(false)

    when 9 #upper right

      move_upper_right(false)

    end

  end

  #--------------------------------------------------------------------------

  # * 1 Step Backward

  #--------------------------------------------------------------------------

  def move_backward

    # Remember direction fix situation

    last_direction_fix = @direction_fix

    # Force directino fix

    @direction_fix = true

    # Branch by direction

    case @direction

    when 2  # Down

      move_up(false)

    when 4  # Left

      move_right(false)

    when 6  # Right

      move_left(false)

    when 8  # Up

      move_down(false)

    when 1 #lower left

      move_upper_right(false)

    when 3 #lower right

      move_upper_left(false)

    when 7 #upper left

      move_lower_right(false)

    when 9 #upper right

      move_lower_left(false)

    end

    # Return direction fix situation back to normal

    @direction_fix = last_direction_fix

  end

  #--------------------------------------------------------------------------

  # * Jump

  #     x_plus : x-coordinate plus value

  #     y_plus : y-coordinate plus value

  #--------------------------------------------------------------------------

  def jump(x_plus, y_plus)

    # If plus value is not (0,0)

    if x_plus != 0 or y_plus != 0

      # If horizontal distnace is longer

      if x_plus.abs > y_plus.abs

        # Change direction to left or right

        x_plus < 0 ? turn_left : turn_right

      # If vertical distance is longer

      elsif x_plus.abs < y_plus.abs

        # Change direction to up or down

        y_plus < 0 ? turn_up : turn_down

      # if distances are equal

      else

        if x_plus < 0

          if y_plus < 0

            turn_upper_left

          else

            turn_lower_left

          end

        else

          if y_plus < 0

            turn_upper_right

          else

            turn_lower_right

          end

        end

      end

    end

    # Calculate new coordinates

    new_x = @x + x_plus

    new_y = @y + y_plus

    # If plus value is (0,0) or jump destination is passable

    if (x_plus == 0 and y_plus == 0) or passable?(new_x, new_y, 0)

      # Straighten position

      straighten

      # Update coordinates

      @x = new_x

      @y = new_y

      # Calculate distance

      distance = Math.sqrt(x_plus * x_plus + y_plus * y_plus).round

      # Set jump count

      @jump_peak = 10 + distance - @move_speed

      @jump_count = @jump_peak * 2

      # Clear stop count

      @stop_count = 0

    end

  end

  #--------------------------------------------------------------------------

  # * Turn Lower Left

  #--------------------------------------------------------------------------

  def turn_lower_left

    unless @direction_fix

      @direction = 1

      @stop_count = 0

    end

  end

  #--------------------------------------------------------------------------

  # * Turn Lower Right

  #--------------------------------------------------------------------------

  def turn_lower_right

    unless @direction_fix

      @direction = 3

      @stop_count = 0

    end

  end

  #--------------------------------------------------------------------------

  # * Turn Upper Left

  #--------------------------------------------------------------------------

  def turn_upper_left

    unless @direction_fix

      @direction = 7

      @stop_count = 0

    end

  end

  #--------------------------------------------------------------------------

  # * Turn Upper Right

  #--------------------------------------------------------------------------

  def turn_upper_right

    unless @direction_fix

      @direction = 9

      @stop_count = 0

    end

  end

  #--------------------------------------------------------------------------

  # * Turn 90? Right

  #--------------------------------------------------------------------------

  def turn_right_90

    case @direction

    when 2

      turn_left

    when 4

      turn_up

    when 6

      turn_down

    when 8

      turn_right

    when 1

      turn_upper_left

    when 3

      turn_lower_left

    when 7

      turn_upper_right

    when 9

      turn_lower_right

    end

  end

  #--------------------------------------------------------------------------

  # * Turn 90? Left

  #--------------------------------------------------------------------------

  def turn_left_90

    case @direction

    when 2

      turn_right

    when 4

      turn_down

    when 6

      turn_up

    when 8

      turn_left

    when 1

      turn_upper_right

    when 3

      turn_upper_left

    when 7

      turn_lower_right

    when 9

      turn_lower_left

    end

  end

  #--------------------------------------------------------------------------

  # * Turn 180?

  #--------------------------------------------------------------------------

  def turn_180

    case @direction

    when 2

      turn_up

    when 4

      turn_right

    when 6

      turn_left

    when 8

      turn_down

    when 1

      turn_upper_left

    when 3

      turn_lower_left

    when 7

      turn_upper_right

    when 9

      turn_lower_right

    end

  end

  #--------------------------------------------------------------------------

  # * Turn 90? Right or Left

  #--------------------------------------------------------------------------

  def turn_right_or_left_90

    if rand(2) == 0

      turn_right_90

    else

      turn_left_90

    end

  end

  #--------------------------------------------------------------------------

  # * Turn at Random

  #--------------------------------------------------------------------------

  def turn_random

    case rand(8)

    when 0

      turn_up

    when 1

      turn_right

    when 2

      turn_left

    when 3

      turn_down

    when 4

      turn_lower_left

    when 5

      turn_lower_right

    when 6

      turn_upper_left

    when 7

      turn_upper_right

    end

  end

  #--------------------------------------------------------------------------

  # * Turn 45? Right

  #--------------------------------------------------------------------------

  def turn_right_45

    case @direction

    when 2

      turn_lower_left

    when 4

      turn_upper_left

    when 6

      turn_lower_right

    when 8

      turn_upper_right

    when 1

      turn_left

    when 3

      turn_down

    when 7

      turn_up

    when 9

      turn_right

    end

  end

  #--------------------------------------------------------------------------

  # * Turn 45? Left

  #--------------------------------------------------------------------------

  def turn_left_45

    case @direction

    when 2

      turn_lower_right

    when 4

      turn_lower_left

    when 6

      turn_upper_right

    when 8

      turn_upper_left

    when 1

      turn_down

    when 3

      turn_right

    when 7

      turn_left

    when 9

      turn_up

    end

  end

  #--------------------------------------------------------------------------

  # * Turn 45? Right or Left

  #--------------------------------------------------------------------------

  def turn_right_or_left_45

    if rand(2) == 0

      turn_right_45

    else

      turn_left_45

    end

  end

  #--------------------------------------------------------------------------

  # * Turn Forward Right

  #--------------------------------------------------------------------------

  def turn_forward_right

    turn_right_45

    move_forward

  end

  #--------------------------------------------------------------------------

  # * Turn Forward Left

  #--------------------------------------------------------------------------

  def turn_forward_left

    turn_left_45

    move_forward

  end

  #--------------------------------------------------------------------------

  # * Turn Backward Right

  #--------------------------------------------------------------------------

  def turn_backward_right

    turn_right_45

    move_backward

  end

  #--------------------------------------------------------------------------

  # * Turn Backward Left

  #--------------------------------------------------------------------------

  def turn_backward_left

    turn_left_45

    move_backward

  end

  #--------------------------------------------------------------------------

  # * Turn Towards Player

  #--------------------------------------------------------------------------

  def turn_toward_player

    # Get difference in player coordinates

    sx = @x - $game_player.x

    sy = @y - $game_player.y

    # If coordinates are equal

    if sx == 0 and sy == 0

      return

    end

    # Get absolute value of difference

    abs_sx = sx.abs

    abs_sy = sy.abs

    #get diagonal differences

    sh = (abs_sx / 2) - abs_sy

    sv = (abs_sy / 2) - abs_sx

    # If the diagonal distance is equal

    if (sh == 0 or sv == 0) && 

       ((abs_sx != 1 and abs_sy != 0) or (abs_sx != 0 and abs_sy != 1))

      return

    end

    # Is the player more towards a 45? angle?

    if abs_sx == abs_sy || (sv < 0 and sh < 0)

      if $game_player.y > @y

        #if the player is lower left

        if $game_player.x < @x

          turn_lower_left

        #If the player is lower right

        else

          turn_lower_right

        end

      else

        #if the player is upper left

        if $game_player.x < @x

          turn_upper_left

        #if the player is upper right

        else

          turn_upper_right

        end

      end

    # If horizontal distance is longer

    elsif abs_sx > abs_sy

      # Turn to the right or left toward player

      sx > 0 ? turn_left : turn_right

    # If vertical distance is longer

    else

      # Turn up or down toward player

      sy > 0 ? turn_up : turn_down

    end

  end

  #--------------------------------------------------------------------------

  # * Turn Away from Player

  #--------------------------------------------------------------------------

  def turn_away_from_player

    # Get difference in player coordinates

    sx = @x - $game_player.x

    sy = @y - $game_player.y

    # If coordinates are equal

    if sx == 0 and sy == 0

      return

    end

    # Get absolute value of difference

    abs_sx = sx.abs

    abs_sy = sy.abs

    #get diagonal differences

    sh = (abs_sx / 2) - abs_sy

    sv = (abs_sy / 2) - abs_sx

    # If the diagonal distance is equal

    if (sh == 0 or sv == 0) && 

       ((abs_sx != 1 and abs_sy != 0) or (abs_sx != 0 and abs_sy != 1))

      return

    end

    # Is the player more towards a 45? angle?

    if abs_sx == abs_sy || (sv < 0 and sh < 0)

      if $game_player.y > @y

        #if the player is lower left

        if $game_player.x < @x

          turn_upper_right

        #If the player is lower right

        else

          turn_upper_left

        end

      else

        #if the player is upper left

        if $game_player.x < @x

          turn_lower_right

        #if the player is upper right

        else

          turn_lower_left

        end

      end

    # If horizontal distance is longer

    elsif abs_sx > abs_sy

      # Turn to the right or left away from player

      sx > 0 ? turn_right : turn_left

    # If vertical distance is longer

    else

      # Turn up or down away from player

      sy > 0 ? turn_down : turn_up

    end

  end

end

 

#-----------------------------------------------------------------------------

# * Game Player

#-----------------------------------------------------------------------------

class Game_Player < Game_Character

  #--------------------------------------------------------------------------

  # * SDK Log Overwritten and Aliased Methods

  #--------------------------------------------------------------------------

  SDK.log_overwrite(:Game_Player, :check_event_trigger_there)

  alias_method(:advanced_8d_movement_game_player_update_player_movement,

               :update_player_movement)

  #--------------------------------------------------------------------------

  # * Front Event Starting Determinant

  #--------------------------------------------------------------------------

  def check_event_trigger_there(triggers)

    result = false

    # If event is running

    if $game_system.map_interpreter.running?

      return result

    end

    # Calculate front event coordinates

    new_x = @x + (@direction == 6 ? 1 : @direction == 4 ? -1 :

                  @direction == 1 ? -1 : @direction == 3 ? +1 : @direction == 7 ? -1 :

                  @direction == 9 ? +1 : 0)

    new_y = @y + (@direction == 2 ? 1 : @direction == 8 ? -1 :

                  @direction == 1 ? +1 : @direction == 3 ? +1 : @direction == 7 ? -1 :

                  @direction == 9 ? -1 : 0)

    # All event loops

    for event in $game_map.events.values

      # If event coordinates and triggers are consistent

      if event.x == new_x and event.y == new_y and

         triggers.include?(event.trigger)

        # If starting determinant is front event (other than jumping)

        if not event.jumping? and not event.over_trigger?

          event.start

          result = true

        end

      end

    end

    # If fitting event is not found

    if result == false

      # If front tile is a counter

      if $game_map.counter?(new_x, new_y)

        # Calculate 1 tile inside coordinates

        new_x += (@direction == 6 ? 1 : @direction == 4 ? -1 :

                  @direction == 1 ? -1 : @direction == 3 ? +1 : @direction == 7 ? -1 :

                  @direction == 9 ? +1 : 0)

        new_y += (@direction == 2 ? 1 : @direction == 8 ? -1 :

                  @direction == 1 ? +1 : @direction == 3 ? +1 : @direction == 7 ? -1 :

                  @direction == 9 ? -1 : 0)

        # All event loops

        for event in $game_map.events.values

          # If event coordinates and triggers are consistent

          if event.x == new_x and event.y == new_y and

             triggers.include?(event.trigger)

            # If starting determinant is front event (other than jumping)

            if not event.jumping? and not event.over_trigger?

              event.start

              result = true

            end

          end

        end

      end

    end

    return result

  end

  #--------------------------------------------------------------------------

  # * Frame Update : Player Movement

  #--------------------------------------------------------------------------

  def update_player_movement

    #if none of the movement input types are toggled

    unless $game_system.default_movement || $game_system.mouse_movement || 

           $game_system.axial_movement || $game_system.numpad_movement ||

      #use the standard four directional movement

      advanced_8d_movement_game_player_update_player_movement

    end

    # Turn player using left/right and forward/backward using up/down

    if $game_system.axial_movement

      case Input.axial_dir8

      when 1

        turn_backward_right

      when 2

        move_backward

      when 3

        turn_backward_left

      when 4

        turn_left_45

        $game_system.wait = 5

      when 6

        turn_right_45

        $game_system.wait = 5

      when 7

        turn_forward_left

      when 8

        move_forward

      when 9

        turn_forward_right

      end

    #Use the default 8-directional movement method

    elsif $game_system.default_movement

      case Input.dir8

      when 2

        move_down

      when 4

        move_left

      when 6

        move_right

      when 8

        move_up

      when 1

        move_lower_left

      when 3

        move_lower_right

      when 7

        move_upper_left

      when 9

        move_upper_right

      end

    end

    # Move player using the Mouse

    if $game_system.mouse_movement

      if Input.press?(Keys::MOUSE_LEFT) 

        unless Mouse.pos == nil

          if Mouse.pos[0].between?(-1, 640) && Mouse.pos[1].between?(-1, 480)

            x =  Mouse.grid[0] 

            y =  Mouse.grid[1] 

            # checks to see if an event occupies the map tile

            while $game_map.check_event(x,y).is_a?(Numeric)

              return #does nothing | can edit this later to do something else

            end

            $game_player.find_path(x,y) # moves the player if there is no event

          end

        end

      end

    end

    # Move player using the numpad

    if $game_system.numpad_movement

      if Input.press?(Keys::NUMPAD1)

        move_lower_left

      end

      if Input.press?(Keys::NUMPAD2)

        move_down

      end

      if Input.press?(Keys::NUMPAD3)

        move_lower_right

      end

      if Input.press?(Keys::NUMPAD4)

        move_left

      end

      if Input.press?(Keys::NUMPAD6)

        move_right

      end

      if Input.press?(Keys::NUMPAD7)

        move_upper_left

      end

      if Input.press?(Keys::NUMPAD8)

        move_up

      end

      if Input.press?(Keys::NUMPAD9)

        move_upper_right

      end

    end

  end

end

 

#-----------------------------------------------------------------------------

# * Sprite Character

#-----------------------------------------------------------------------------

class Sprite_Character < RPG::Sprite

  SDK.log_overwrite(:Sprite_Character, :update)

  def update

    super

    # If tile ID, file name, or hue are different from current ones

    if @tile_id != @character.tile_id or

       @character_name != @character.character_name or

       @character_hue != @character.character_hue

      # Remember tile ID, file name, and hue

      @tile_id = @character.tile_id

      @character_name = @character.character_name

      @character_hue = @character.character_hue

      # If tile ID value is valid

      if @tile_id >= 384

        self.bitmap = RPG::Cache.tile($game_map.tileset_name,

                                      @tile_id, @character.character_hue)

        self.src_rect.set(0, 0, 32, 32)

        self.ox = 16

        self.oy = 32

      # If tile ID value is invalid

      else

        self.bitmap = RPG::Cache.character(@character.character_name,

                                           @character.character_hue)

        @cw = bitmap.width / 4

        @ch = bitmap.height / 8

        self.ox = @cw / 2

        self.oy = @ch

      end

    end

    # Set visible situation

    self.visible = (not @character.transparent)

    # If graphic is character

    if @tile_id == 0

      # Set rectangular transfer

      sx = @character.pattern * @cw

      if @character.direction >= 6

        sy = (@character.direction - 2 ) * @ch

      else

        sy = (@character.direction - 1 ) * @ch

      end

      self.src_rect.set(sx, sy, @cw, @ch)

    end

    # Set sprite coordinates

    self.x = @character.screen_x

    self.y = @character.screen_y

    self.z = @character.screen_z(@ch)

    # Set opacity level, blend method, and bush depth

    self.opacity = @character.opacity

    self.blend_type = @character.blend_type

    self.bush_depth = @character.bush_depth

    # Animation

    if @character.animation_id != 0

      animation = $data_animations[@character.animation_id]

      animation(animation, true)

      @character.animation_id = 0

    end

  end

end

 

#-----------------------------------------------------------------------------

# * Scene Map

#-----------------------------------------------------------------------------

class Scene_Map

  alias_method (:advanced_8d_movement_scene_map_update, :update)

  def update

    if $game_system.wait > 0

      $game_system.wait -= 1

      return

    end

    advanced_8d_movement_scene_map_update

  end

end

 

#-----------------------------------------------------------------------------

# * Window Base

#-----------------------------------------------------------------------------

class Window_Base

  #--------------------------------------------------------------------------

  # * Draw Graphic

  #     actor : actor

  #     x     : draw spot x-coordinate

  #     y     : draw spot y-coordinate

  #--------------------------------------------------------------------------

  def draw_actor_graphic(actor, x, y)

    bitmap = RPG::Cache.character(actor.character_name, actor.character_hue)

    cw = bitmap.width / 4

    ch = bitmap.height / 8

    #set which direction to draw(draws down by default)

    dir = 2

    #interprets direction to frame

    if dir >= 6

      sy = (dir - 2 ) * ch

    else

      sy = (dir - 1 ) * ch

    end

    #draws the actor

    src_rect = Rect.new(0, sy, cw, ch)

    self.contents.blt(x - cw / 2, y - ch, bitmap, src_rect)

  end

end

 

#-----------------------------------------------------------------------------

# * Window SaveFile

#-----------------------------------------------------------------------------

class Window_SaveFile < Window_Base

  #--------------------------------------------------------------------------

  # * Refresh

  #--------------------------------------------------------------------------

  def refresh

    self.contents.clear

    # Draw file number

    self.contents.font.color = normal_color

    name = "File#{@file_index + 1}"

    self.contents.draw_text(4, 0, 600, 32, name)

    @name_width = contents.text_size(name).width

    # If save file exists

    if @file_exist

      # Draw character

      for i in [email=0...@characters.size]0...@characters.size[/email]

        bitmap = RPG::Cache.character(@characters[i][0], @characters[i][1])

        cw = bitmap.rect.width / 4

        ch = bitmap.rect.height / 8

        #set which direction to draw(draws down by default)

        dir = 2

        #interprets direction to frame

        if dir >= 6

          sy = (dir - 2 ) * ch

        else

          sy = (dir - 1 ) * ch

        end

        src_rect = Rect.new(0, sy, cw, ch)

        x = 300 - @characters.size * 32 + i * 64 - cw / 2

        self.contents.blt(x, 68 - ch, bitmap, src_rect)

      end

      # Draw play time

      hour = @total_sec / 60 / 60

      min = @total_sec / 60 % 60

      sec = @total_sec % 60

      time_string = sprintf("%02d:%02d:%02d", hour, min, sec)

      self.contents.font.color = normal_color

      self.contents.draw_text(4, 8, 600, 32, time_string, 2)

      # Draw timestamp

      self.contents.font.color = normal_color

      time_string = @time_stamp.strftime("%Y/%m/%d %H:%M")

      self.contents.draw_text(4, 40, 600, 32, time_string, 2)

    end

  end

end

 

#-----------------------------------------------------------------------------

# * End SDK Enable Test

#-----------------------------------------------------------------------------

end

Instructions

To toggle the various methods of movement, use the following call scripts:
Default 8-directional movement : $game_system.default_movement = true
Point and Click movement : $game_system.mouse_movement = true
Axial Movement : $game_system.axial_movement = true
Numpad Movement : $game_system.numpad_movement = true

If you want to use only 4-directional movement, then set all the previous metioned variables to false.
You will also need new character spritesheets with all eight directions. here is the one used in the demo:

rock-point.PNG


Compatibility

No known compatablity issues as of yet, though three other scripts are required. They can be found within the demo.
(Note: Near's Pathfinding Script in the demo has been modified by me. The modified version is what is required.)

This script will not work with 4 directional sprites. The following spoiler will contain links to templates, and/or sprites that will work with this system. If you know of any others, feel free to post a link here and I will add it to the list.
BREEZE 8-Directional Template by Lei (based on the original Breeze template by GreenRaven)

Credits and Thanks

Thanks to Near_Fantastica for his pathfinding script and superior mouse module. Also thanks to vgvgf(Aleworks) for his input module which made editing the input module for axial movement much easier. And to the SDK team.

Author's Notes

Changes made in version 3.01:
  • Axial movement can now turn while moving
  • Improved event movement toward and away from player
  • Uses Aleworks Input Module instead of Near's Keyboard
  • fixes clash between axial and default or numpad movement
  • fixed bug with turn toward/away from player
  • fixed draw_actor bug in menus
  • can now jump in eight directions
  • fixed draw_actor bug in the save and load menus.
Version 3.20 will feature a faster, more versatile, bug free pathfinding script. Keep an eye out, it will be coming soon. It will also no longer require any of Near's scripts, but that is to come at a later date.

If you find any bugs, or have any suggestions, feel free to leave your comments.
 
Uhh wow another scripter actually uploaded a demo to the Download Manager :)

Wow pretty need but I don't agree with your use of global variables they would have been better suited as an instance variable of game system (if you do this then your edits to the Save and Load Scenes are not needed as Game_System is saved with the save data)

also if you need any help converting this to be SDK compliant then get in touch with me and I'll help, because in this scripts current state it is overwriting a few of the methods SDK splits up which is not good
 
@ chaos_prime: What type of errors? Do you have the other scripts by Near_Fantastica that are needed?

@Trickster: Thank you. I'm still new and trying to learn. your help would be appreciated. I'll send a PM in your direction shortly.
 
Dont you think the spritesheet is too small... The spritesheet is smaller then the default sprite (001-hero001)....Can you edit it and let it become bigger sprite?

And I found out a few bug! When press start and see the hero status....The sprite is 2 rock ball...I mean this:http://img185.imageshack.us/img185/8322/untitledkp8.png[/IMG]

The second bug is: When I talk with the event isometricly...The event won't turn towards player...
 
@OmegaGrouden: I edited the rock02 charactersprite. I left it the same size as it was, just added arrows so you can see which direction it faced. I did notice that first bug you pointed out, It just didn't occur to me. I will look into it deeper and fix it. As for the second bug, I realized that after I had "finished" it, and if you look at the first post, it is already included in the list of things to do. turn_towards_player

@Neonyo: Make sure, when you turn on axial movement, you turn off default movement.

$game_system.default_movement = false[/FONT]

That should fix it.
 
oh, I see. In that case, near the end of my script, in the Sprite_Character class just before Game_Map, find this bit of code:
Code:
        @cw = bitmap.width / 4
        @ch = bitmap.height / 8
        self.ox = @cw / 2
        self.oy = @ch

@cw defines how many frames per pose. change the 4 to 9. you may also have to change
self.ox = @cw / 2
but since I'm not at home right now, I can't tell you what it would need to be changed to. I won't be able to do anything to the script itself until Tuesday.

EDIT: I noticed you have a standing pose at the begining and 8 frame walking poses. Doing it the way I just said will probably include the standing frame along with the walking frames. I will look into a way to have the script use the standing frame when standing and loop frames 2-9 when walking, since that is probably what you want. It will take me some time, since i only get about one to three hours on the computer at home during the weekdays, and work all day on the weekends. Plus, my son has a doctor's appointment on Monday, so i won't be able to get on the home computer until Tuesday. I'll let you know what i can find.
 
I don't know. I don't have rmxp at work and won't be able to look into it until Tuesday. Try to edit it the way I said for now, see what happens, then fiddle with that number at the end of self.ox and see what happens until you find the right one for your purpose. That's the best i can offer right now.
 
There is an update. The following methods were redefined:
  • Move toward player
  • Move Away from player
  • Turn toward player
  • Turn away from player
  • Jump
The bug where two frames of the actor graphic would be drawn in the menus has been fixed.

If you find any other bugs or have suggestions for improvement, leave your comments here. As far as I'm concerned, this script is at it's final version, unless there are bugfixes in the future.

If you want more than four frame animation, I suggest using another script as this one is designed for only four frames of animation.
 
DraycosGoldaryn;196276":1w66jkvc said:
As far as I'm concerned, this script is at it's final version, unless there are bugfixes in the future.

I lied... Introducing Version 3.00!!

Axial movement has improved, a few other bugs were fixed, and aleworks input module has replaced near's keyboard module (this allowed better editing of the input module to do allow numpad movement to work with axial movement.).

As always, if you have any suggestions or questions or if you find any bugs, post it here.

Thank you.
 
Hey draycos! I had a small request, and I hope someone thinks this is a good idea... It's about dashing. Your script works wonders for me, and I love it to death. Sure, I do not need the point and click thingy, and a couple few more things, but besides that, your script is awsome. There is one thing though, that I still need... spritesheet changing for the dash. What I mean is, could you implement a function in your script, that given I press X key for the dash, the charset will change to a dashing charset? Something like

if 'x' is pressed then
charset.sprite=charset.sprite+"_dash"

I know this is not programming language, it's just the idea for the thing. I'm still quite n00bish when it comes to RGSS. I'm learning, but I still have a long way to go.
Of course, this could be another of those functions we could activate / deactivate when moving towards the end of your script. And perhaps, for just those who want to change the charset, you could also implement a choice in the script for us to choose if this function would be applied to the dashing function, or simply changing the charset... I think you get what I mean, right?

If you could do this, you would so much be my hero!
 

CERU

Member

Heyyy, resident evil style movement! Coooooool.

Except, I can't see how axial movement would be really useful without prerendered backgrounds or sudden camera changes.
 

arev

Sponsor

Guys, please, make an effort of looking at the last post's date. And when you do, and realize it's been sent long time ago - find another topic to post :]
 
Status
Not open for further replies.

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