RMRK is retiring.
Registration is disabled. The site will remain online, but eventually become a read-only archive. More information.

RMRK.net has nothing to do with Blockchains, Cryptocurrency or NFTs. We have been around since the early 2000s, but there is a new group using the RMRK name that deals with those things. We have nothing to do with them.
NFTs are a scam, and if somebody is trying to persuade you to buy or invest in crypto/blockchain/NFT content, please turn them down and save your money. See this video for more information.
Module implementation

0 Members and 1 Guest are viewing this topic.

pokeball TDSOffline
***
Rep:
Level 84
-T D S-
Silver - GIAW 11 (Hard)Silver - Game In A Week VII
Well, this is not really a script for the public, but it is something I've been working on for a while.

This is just one of many modules that I am creating to speed up the creation of battle systems and other complex systems. The main idea behind them is to be able to add a lot of functions to a class like movement or effects.

I wanted to create DLL for this, but my knowledge in that are vague at best at the moment. Also something I wanted to ask is if it is possible to inject a module into a class without having to modify said class.

For example instead of going to each class and doing "include module_name", just do it with an external call like "inject_module_to_class(class_name, module_name)".

And here is the script, this is just the movement part of the script, other effects such as jumping are ready but I am not satisfied with the math.

Code: [Select]
#==============================================================================
# ** TDS Module
#    Version: 1.0
#------------------------------------------------------------------------------

#==============================================================================
# * Import to Global Hash *
#==============================================================================
($imported ||= {})[:TDS_Module] = true

module TDS
end


module TDS
  #============================================================================
  # ** Movement - (Movement Addon)
  #    Version: 1.0
  #----------------------------------------------------------------------------
  #  This Module handles object movement.
  #============================================================================
  module Movement
    #--------------------------------------------------------------------------
    # * Constants (Structs)
    #--------------------------------------------------------------------------
    # Battle Action Base
    Move_Object = Struct.new(:real_x, :real_y, :x, :y, :x_speed, :y_speed)   
    #--------------------------------------------------------------------------
    # * Object Initialization
    #--------------------------------------------------------------------------
    def initialize(*atts)
      super(*atts)
      # Initialize Moving Objects Hash
      clear_moving_objects
    end
    #--------------------------------------------------------------------------
    # * Clear All Moving Objects
    #--------------------------------------------------------------------------
    def clear_moving_objects ; @moving_objects = {} end
    #--------------------------------------------------------------------------
    # * Determine if Object can be moved
    #--------------------------------------------------------------------------
    def can_move?(obj) ; obj.is_a?(Window) or obj.is_a?(Sprite) end
    #--------------------------------------------------------------------------
    # * Determine if object is moving
    #--------------------------------------------------------------------------
    def moving_object?(obj)
      # Return false if Moving Objects Hash does not include
      return false if !@moving_objects.has_key?(obj)
      # Get Moving Object Destination Properties
      dest = @moving_objects[obj]
      # If Object Real X & Y is not equal to Destination X & Y
      return (dest.real_x != dest.x or dest.real_y != dest.y)
    end
    #--------------------------------------------------------------------------
    # * Remove Moving Object
    #--------------------------------------------------------------------------
    def remove_moving_object(obj) ; @moving_objects.delete(obj) end
    #--------------------------------------------------------------------------
    # * Finish Object Movement (Instant Move)
    #--------------------------------------------------------------------------
    def finish_object_movement(obj)
      # Return if Moving Objects hash does not include object
      return if !@moving_objects.has_key?(obj)
      # Get Moving Object Destination Properties & Set Object X and Y Positions
      dest = @moving_objects[obj] ; obj.x = dest.real_x = dest.x ; obj.y = dest.real_y = dest.y
    end     
    #--------------------------------------------------------------------------
    # * Object Initialization
    #     speed : movement speed [X, Y] (Array or Integer (Set both speeds))
    #--------------------------------------------------------------------------
    def move_obj_to(obj, x, y, speed, appr = false)
      # Return if Object cannot be moved
      return if !can_move?(obj)
      # Create Speed Array for X & Y Speeds if it's a single integer
      speed = [speed, speed] if speed.is_a?(Numeric)
      # Destination Properties
      dest = Move_Object.new(obj.x, obj.y, x, y, speed.at(0), speed.at(1))
      # If Approximation flag is true
      if appr
        # Set Destination Approximated X & Y Speed Speed
        dest.x_speed = (obj.x - x).abs.to_f / speed.at(0) ; dest.y_speed = (obj.y - y).abs.to_f / speed.at(1)
      end
      # Set Moving Objects Destination Properties
      @moving_objects[obj] = dest
      # Finish Object Movement if Speed is 0
      finish_object_movement(obj) if speed.reduce(:+) == 0
    end     
    #--------------------------------------------------------------------------
    # * Move Object towards coordinates
    #     x     : x amout to move towards
    #     y     : y amount to move towards
    #     dur   : movement duration
    #     appr  : if false duration is treated as speed
    #--------------------------------------------------------------------------
    def move_obj_towards(obj, x, y, dur, appr = true)
      # Move To Coordinates
      move_obj_to(obj, obj.x + x, obj.y + y, dur, appr)
    end
    #--------------------------------------------------------------------------
    # * Frame Update
    #--------------------------------------------------------------------------
    def update(*args, &block)
      # Update Super if Defined
      super(*args, &block) if defined?(super)     
      # Update Moving Objects
      @moving_objects.each {|obj, dest| update_moving_objects(obj, dest)}
    end
    #--------------------------------------------------------------------------
    # * Update Moving Objects
    #     obj  : moving object
    #     dest : destination properties
    #--------------------------------------------------------------------------
    def update_moving_objects(obj, dest)
      # Return if Destination Properties are not for Object Movement
      return if !dest.is_a?(Move_Object)
      # Left & Right Movement
      obj.x = dest.real_x = [dest.real_x - dest.x_speed, dest.x].max if dest.x < dest.real_x
      obj.x = dest.real_x = [dest.real_x + dest.x_speed, dest.x].min if dest.x > dest.real_x
      # Up & Down Movement
      obj.y = dest.real_y = [dest.real_y - dest.y_speed, dest.y].max if dest.y < dest.real_y
      obj.y = dest.real_y = [dest.real_y + dest.y_speed, dest.y].min if dest.y > dest.real_y
      # Remove Moving Object if it's not moving anymore
      remove_moving_object(obj) if !moving_object?(obj)
    end
  end
end


module TDS
  #============================================================================
  # ** Movement - (Movement Addon)
  #    Version: 1.0
  #----------------------------------------------------------------------------
  #  This Module handles object movement.
  #============================================================================
  module Movement
    #--------------------------------------------------------------------------
    # * Determine if moving
    #--------------------------------------------------------------------------
    def moving? ; moving_object?(self) end
    #--------------------------------------------------------------------------
    # * Move to Coordinates
    #--------------------------------------------------------------------------
    def move_to(x, y, speed, appr = false) ; move_obj_to(self, x, y, speed, appr) end     
    #--------------------------------------------------------------------------
    # * Finish Movement (Instant Move)
    #--------------------------------------------------------------------------
    def finish_movement ; finish_object_movement(self) end     
  end
end

And here is an example that can tested with any game, just go to any menu and press the CTRL key.

Code: [Select]
#==============================================================================
# ** Scene_Base
#------------------------------------------------------------------------------
#  This is a super class of all scenes within the game.
#==============================================================================

class Scene_Base
  #--------------------------------------------------------------------------
  # * Included Modules
  #--------------------------------------------------------------------------
  include TDS::Movement 
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update
    super
    update_basic
    # If Input Trigger CTRL
    if Input.trigger?(:CTRL)
      instance_variables.each do |varname|
        ivar = instance_variable_get(varname)
        # If Instance Variable is a window or sprite
        if ivar.is_a?(Window) or ivar.is_a?(Sprite)
          x = rand(Graphics.width - ivar.width)
          y = rand(Graphics.height - ivar.height)
          move_obj_to(ivar, x, y, 15 + rand(15), true)
        end       
      end
    end
  end
end

Here is another example, this one is to display the use of the module within a class like a window instead of the whole scene like the one above.

Code: [Select]
#==============================================================================
# ** Scene_Menu
#------------------------------------------------------------------------------
#  This class performs the menu screen processing.
#==============================================================================

Window_Base.send(:include, TDS::Movement)

class Scene_Menu < Scene_MenuBase
  #--------------------------------------------------------------------------
  # * Post-Start Processing
  #--------------------------------------------------------------------------
  def post_start
    # Move Windows outside of screen
    @command_window.move_to(-@command_window.width, @command_window.y, 0)
    @gold_window.move_to(-@gold_window.width, @gold_window.y, 0)
    @status_window.move_to(Graphics.width + @status_window.width, @status_window.y, 0)
    # Deactivate Command Window
    @command_window.deactivate
    super
    # Move Windows into screen
    @command_window.move_to(0, 0, 15, true)   
    @gold_window.move_to(0, @gold_window.y, 15, true)
    @status_window.move_to(@command_window.width, @status_window.y, 15, true)   
    # Get Windows
    windows = [@command_window, @gold_window, @status_window]   
    # While Windows are Moving
    while windows.any? {|w| w.moving?}
      # Update Basic Components
      update_basic
      # Go Through Basic Input (Cancel/Confirm)
      [:C, :B].each {|input|
        # Finish Window Movement If Input Trigger
        windows.each {|w| w.finish_movement} if Input.trigger?(input)
      }
    end
    # Activate Command Window
    @command_window.activate
  end 
end
« Last Edit: October 26, 2012, 10:15:53 PM by TDS »

*****
Rep:
Level 84
This text is way too personal.
Bronze - GIAW 11 (Hard)Silver - GIAW Halloween
For example instead of going to each class and doing "include module_name", just do it with an external call like "inject_module_to_class(class_name, module_name)".

You can easily do that with the extend method, though I don't know if there are any differences between extend and include.

Example:

Code: [Select]
module TDS
  def do_something
    p "something"
  end
end

class Cozziekuns
end

Cozziekuns.do_something   # Error

Cozziekuns.extend(TDS)
Cozziekuns.do_something   # "something"

Haven't looked at your script yet, I'll do it when I get the time. Looks good so far though; a module like yours would be really helpful!

pokeball TDSOffline
***
Rep:
Level 84
-T D S-
Silver - GIAW 11 (Hard)Silver - Game In A Week VII
Thanks Cozziekuns, extend seems to work for injecting the methods of a module into a class, but it does not pass it onto the classes that inherit from it. I used extend on Window_Base, but it did not seem to work like the include method does, the methods did seemed to have been passed onto the new classes, but I could not use them.

*
*crack*
Rep:
Level 64
2012 Best Newbie2012 Most Unsung MemberFor frequently finding and reporting spam and spam bots
This goes a little out of what I know. But is there a way to check every class name in an entire project?
if there is, a 'for' loop making a list of every class name could be used to use that extend method?

Going out on a limb here :-\
All of my scripts are totally free to use for commercial use. You don't need to ask me for permission. I'm too lazy to update every single script post I ever made with this addendum. So ignore whatever "rule" I posted there. :)

All scripts can be found at: https://pastebin.com/u/diamondandplatinum3

*
Rep:
Level 97
2014 Most Unsung Member2014 Best RPG Maker User - Engine2013 Best RPG Maker User (Scripting)2012 Best Member2012 Best RPG Maker User (Scripting)2012 Favorite Staff Member2012 Most Mature MemberSecret Santa 2012 ParticipantProject of the Month winner for July 20092011 Best Veteran2011 Favourite Staff Member2011 Most Mature Member2011 Best RPG Maker User (Scripting)2011 Best Use of Avatar and Signature Space2010 Most Mature Member2010 Favourite Staff Member
I will look at the main script soon, but just to address the current issue: you don't need to go beyond include, in my opinion; extend adds the methods to the singleton class for the instance. So, if you had:

Code: [Select]
module Cardboard
  def foldable?
    true
  end
end

a = Box.new
b = Box.new
a.extend(Cardboard)

# a.foldable? # true
# b.foldable? # NoMethod Error

The methods of Cardboard are only added to the a instance. When you use it on the class object itself, then you are actually adding the methods to the Class object for Box, so if you have:

Code: [Select]
Box.extend(Cardboard)

a = Box.new
b = Box.new

# a.foldable? # NoMethod Error
# b.foldable? # NoMethod Error
# Box.foldable? # true

Anyway, I believe the method you are looking for if you want to add the methods to every instance of the same object is actually include itself, but since it is a private method you might need to do the following:

Code: [Select]
Box.send(:include, Cardboard)

a = Box.new
b = Box.new

# a.foldable? # true
# b.foldable? # true
# Box.foldable? # NoMethod Error
« Last Edit: October 26, 2012, 07:54:15 PM by modern algebra »

*****
my name is Timothy what's yours
Rep:
Level 79
Hello
2014 Most Missed Member2014 Zero to Hero2014 Best IRC Quote2012 Zero To HeroSecret Santa 2012 ParticipantContestant - GIAW 9For frequently finding and reporting spam and spam bots2011 Zero to Hero
I'd just like to say I've always loved the classes and whatnot MA uses when explaining a function. Thank you. That will be all from me for the time being.
it's like a metaphor or something i don't know

pokeball TDSOffline
***
Rep:
Level 84
-T D S-
Silver - GIAW 11 (Hard)Silver - Game In A Week VII
It worked like a charm modern algebra.

I've updated the module to handle self methods as well and here is another example or the method implementation into the scene_menu.

Code: [Select]
#==============================================================================
# ** Scene_Menu
#------------------------------------------------------------------------------
#  This class performs the menu screen processing.
#==============================================================================

Window_Base.send(:include, TDS::Movement)

class Scene_Menu < Scene_MenuBase
  #--------------------------------------------------------------------------
  # * Post-Start Processing
  #--------------------------------------------------------------------------
  def post_start
    # Move Windows outside of screen
    @command_window.move_to(-@command_window.width, @command_window.y, 0)
    @gold_window.move_to(-@gold_window.width, @gold_window.y, 0)
    @status_window.move_to(Graphics.width + @status_window.width, @status_window.y, 0)
    # Deactivate Command Window
    @command_window.deactivate
    super
    # Move Windows into screen
    @command_window.move_to(0, 0, 15, true)   
    @gold_window.move_to(0, @gold_window.y, 15, true)
    @status_window.move_to(@command_window.width, @status_window.y, 15, true)   
    # Get Windows
    windows = [@command_window, @gold_window, @status_window]   
    # While Windows are Moving
    while windows.any? {|w| w.moving?}
      # Update Basic Components
      update_basic
      # Go Through Basic Input (Cancel/Confirm)
      [:C, :B].each {|input|
        # Finish Window Movement If Input Trigger
        windows.each {|w| w.finish_movement} if Input.trigger?(input)
      }
    end
    # Activate Command Window
    @command_window.activate
  end 
end

All it does is move the windows outside of the screen, then it moves them back into the screen.

*
Rep:
Level 97
2014 Most Unsung Member2014 Best RPG Maker User - Engine2013 Best RPG Maker User (Scripting)2012 Best Member2012 Best RPG Maker User (Scripting)2012 Favorite Staff Member2012 Most Mature MemberSecret Santa 2012 ParticipantProject of the Month winner for July 20092011 Best Veteran2011 Favourite Staff Member2011 Most Mature Member2011 Best RPG Maker User (Scripting)2011 Best Use of Avatar and Signature Space2010 Most Mature Member2010 Favourite Staff Member
I have some thoughts, but don't have the time to prepare them right at this moment. I will get back to you soon though.

pokeball TDSOffline
***
Rep:
Level 84
-T D S-
Silver - GIAW 11 (Hard)Silver - Game In A Week VII
That's great, I was hoping to see more activity though. Also more information about module use from other scripters and their experience working with it.

When I started this I was using a hash with symbols like @move_mod[:real_x], @move_mod[:real_y], etc that basically did the same thing as the struct, but I wasn't sure if it was slower or faster.