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.
[Request] Final Fantasy Style Side View Battle?

0 Members and 1 Guest are viewing this topic.

***
Rep:
Level 82
We learn by living...
So I want to mess with the X coordinates (and possibly y coordinates) of my sprites based on certain positions. This is the same as saying if I command my actor to attack the goblin, I want them to move over to the goblin, attack, and jump back into position, or similar FF1 - FF6 tactics.

There's two problems I'm running into. The first is the move animation. Namely, my sprites don't move. I micronized my battle sprite images so my battle looks like this



I made these side sprites (not my original work) by cropping their side views and shrinking them.  I set their coordinates based on front, middle, and back positions using the following change to Game_Actor:

Code: [Select]
  #--------------------------------------------------------------------------
  # * Get Battle Screen X-Coordinate
  #--------------------------------------------------------------------------
   def screen_x
    # Return after calculating x-coordinate by order of members in party
    if self.index != nil
    position = $data_classes[self.class_id].position
      return 576 - (position * -20)
    else
      return 0
    end
  end



I could do the same thing for an animated loop or to play a victory dance, cast spells, and various statuses (sick, stone, levitating, cloaked, etc.) if I knew a bit more about where to look and what to change.


I know messing with the line "self.x = @battler.screen_x"  in the following:

Code: [Select]
class Sprite_Battler
  #--------------------------------------------------------------------------
  # * Update
  #--------------------------------------------------------------------------
  def update
    super
    # If battler is nil
    if @battler == nil
      remove_battler
      return
    end
    # If file name or hue are different than current ones
    redraw_battler
    # If animation ID is different than current one
    loop_anim
    # If actor which should be displayed
    adjust_actor_opacity
    # Blink
    adjust_blink
    # If invisible
    adjust_visibility
    # If visible
    if @battler_visible
      # Escape
      sprite_escape
      # White flash
      sprite_white_flash
      # Animation
      sprite_animation
      # Damage
      sprite_damage
      # Collapse
      sprite_collapse
    end
    # Set sprite coordinates
    self.x = @battler.screen_x
    self.y = @battler.screen_y
    self.z = @battler.screen_z
  end


Changes my battler's coordinates, for example

Code: [Select]
    self.x = @battler.screen_x - 100
moves all my battlers 100 pixels closer to the monsters. What I want to be able to do is

1. move one battler at a time, rather than all of them, based on actions.

2. animate them during these moves.


If these options become available, a solid Tactics system can be created with many possibilities including variable ranges, blast area effects, touch vs. ranged spells, backstabbing, and so forth.

**
Rep:
Level 71
RMRK Junior
Firstly, are you using someone else's SBS or are you making your own? I can't really do much with the tiny bit of code you posted. SBS' generally have pages on top of pages of scripting. It's not an easy thing to make. I've actually found that event based systems are still the way to go if you don't mind spending switches and variables.

However, if you are hellbent on making your own SBS, it's going to take some serious work and I applaud you for trying.

Now on to the movement issue you're having. Assuming that you are making your own script, I highly suggest looking at Charlie Fleet's FFX SBS or Atoa's Animated SBS. Just take a glance at the movement scripts they have as far as character refreshes and what-not. It can help a lot in basing your own SBS off of. Other than that, my scripting knowledge is very limited. I hope that what I've posted has in some way helped you.

*****
Rep:
Level 84
This text is way too personal.
Bronze - GIAW 11 (Hard)Silver - GIAW Halloween
To make your guys move one by one, the simplest way would be to alter Scene_Battle 4 to change your actor's screen_x during make_basic_action_result, and to change it back at update_phase4_step4 through targetting the @active_battler variable, though first you'd have to make a way to alter an actor's screen_x. In other words:

Code: [Select]
#==============================================================================
# ** Game_Actor
#------------------------------------------------------------------------------
#  This class handles the actor. It's used within the Game_Actors class
#  ($game_actors) and refers to the Game_Party class ($game_party).
#==============================================================================

class Game_Actor < Game_Battler
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_accessor :coz_moving
  #--------------------------------------------------------------------------
  # * Setup
  #     actor_id : actor ID
  #--------------------------------------------------------------------------
  alias coz_thingy_setup setup
  def setup(actor_id)
    coz_thingy_setup(actor_id)
    @coz_moving = 0
  end
  #--------------------------------------------------------------------------
  # * Get Battle Screen X-Coordinate
  #--------------------------------------------------------------------------
   def screen_x
    # Return after calculating x-coordinate by order of members in party
    if self.index != nil
    position = $data_classes[self.class_id].position
      if @coz_moving != 0
        return @coz_moving
      else
        return 576 - (position * -20)
      end
    else
      return 0
    end
  end
end

Here we define a new variable coz_moving for the Game_Actor class, which overrides the original screen_x if it is greater than 0. Pretty straightforward.

Code: [Select]
#==============================================================================
# ** Scene_Battle (part 4)
#------------------------------------------------------------------------------
#  This class performs battle screen processing.
#==============================================================================

class Scene_Battle
  #--------------------------------------------------------------------------
  # * Make Basic Action Results
  #--------------------------------------------------------------------------
  def make_basic_action_result
    # If attack
    if @active_battler.current_action.basic == 0
      # Set anaimation ID
      @animation1_id = @active_battler.animation1_id
      @animation2_id = @active_battler.animation2_id
      # If action battler is enemy
      if @active_battler.is_a?(Game_Enemy)
        if @active_battler.restriction == 3
          target = $game_troop.random_target_enemy
        elsif @active_battler.restriction == 2
          target = $game_party.random_target_actor
        else
          index = @active_battler.current_action.target_index
          target = $game_party.smooth_target_actor(index)
        end
      end
      # If action battler is actor
      if @active_battler.is_a?(Game_Actor)
        if @active_battler.restriction == 3
          target = $game_party.random_target_actor
        elsif @active_battler.restriction == 2
          target = $game_troop.random_target_enemy
        else
          index = @active_battler.current_action.target_index
          target = $game_troop.smooth_target_enemy(index)
        end
        @active_battler.coz_moving = target.screen_x     # Added this in
      end
      # Set array of targeted battlers
      @target_battlers = [target]
      # Apply normal attack results
      for target in @target_battlers
        target.attack_effect(@active_battler)
      end
      return
    end
    # If guard
    if @active_battler.current_action.basic == 1
      # Display "Guard" in help window
      @help_window.set_text($data_system.words.guard, 1)
      return
    end
    # If escape
    if @active_battler.is_a?(Game_Enemy) and
       @active_battler.current_action.basic == 2
      # Display "Escape" in help window
      @help_window.set_text("Escape", 1)
      # Escape
      @active_battler.escape
      return
    end
    # If doing nothing
    if @active_battler.current_action.basic == 3
      # Clear battler being forced into action
      $game_temp.forcing_battler = nil
      # Shift to step 1
      @phase4_step = 1
      return
    end
  end
  #--------------------------------------------------------------------------
  # * Frame Update (main phase step 4 : animation for target)
  #--------------------------------------------------------------------------
  def update_phase4_step4
    # Animation for target
    for target in @target_battlers
      target.animation_id = @animation2_id
      target.animation_hit = (target.damage != "Miss")
    end
    # Animation has at least 8 frames, regardless of its length
    @wait_count = 8
    # -- Added this in --
    if @active_battler.is_a?(Game_Actor)
      @active_battler.coz_moving = 0
    end
    # -- End Added this in --
    # Shift to step 5
    @phase4_step = 5
  end
end

The parts I added in are the only parts that I changed, and again they are pretty straight forward; however, the placement of those two may be a little odd. The first one means that once all the actions in the menu have finished, the active battler will begin to move towards the target enemy's screen_x. The other one means that once the animation has finished, the active battler will return to his original place, but only if the active battler is an actor, secured by checking with a simple .is_a? statement. Notice that I have not changed the screen_y values, but it generally follows the same pattern.

Adding animations are a bit trickier, as well as movement, not just making a sprite disappear from one place to the next, but it follows the same pattern, except that you might have to do some altering of Sprite_Battler. I hope that clears up most of your problems.

***
Rep:
Level 82
We learn by living...
the coordinate system is going to be a blast to mess with, and I recently figured out I could mimic the initial positions and ranges (soon to be) available to actors for enemies, by doing a quick comparison of their agility, intelligence, and strength, and then checking what their default weapon/attacks are. Thus the wizardly imp with a high int will be in the far back with long range, while the high agility goblin would be in the middle, and the huge guy with massive strength would be in front. If a bunch of stats are all the same, it would default them to the middle position.

First I have to get the actor coordinate system working. Then I can add "step/move" actions, and weirdness from there.

***
Rep:
Level 82
We learn by living...


I noticed you directed to me to phase 4 step 4, but I saw this in step 3...
Code: [Select]
  #--------------------------------------------------------------------------
  # * Frame Update (main phase step 3 : animation for action performer)
  #--------------------------------------------------------------------------
  def update_phase4_step3
    # Animation for action performer (if ID is 0, then white flash)
    if @animation1_id == 0
      @active_battler.white_flash = true
    else
      @active_battler.animation_id = @animation1_id
      @active_battler.animation_hit = true
    end
    # Shift to step 4
    @phase4_step = 4
  end



before going into step 4:

Code: [Select]
  #--------------------------------------------------------------------------
  # * Frame Update (main phase step 4 : animation for target)
  #--------------------------------------------------------------------------
  def update_phase4_step4
    # Animation for target
    for target in @target_battlers
      target.animation_id = @animation2_id
      target.animation_hit = (target.damage != "Miss")
    end
    # Animation has at least 8 frames, regardless of its length
    @wait_count = 8
    # Shift to step 5
    @phase4_step = 5
  end

Wouldn't it make some sense for the movement of an attacker to occur during step 3?

*****
Rep:
Level 84
This text is way too personal.
Bronze - GIAW 11 (Hard)Silver - GIAW Halloween
Depends if you want the actor to move after the enemy flashes or after the animation for the enemy is finished.

***
Rep:
Level 82
We learn by living...
Depends if you want the actor to move after the enemy flashes or after the animation for the enemy is finished.

I just input it, and it ran into this error:


Quote from: evil computer

Script SDK Part III line 3780: NoMethodError occurred.

undefined method 'coz_moving=' for #<Game_Enemy:0xxbb9bf60>

in reference to this line
Code: [Select]
       @active_battler.coz_moving = target.screen_x     # Added this in

so I moved this thing you gave me:

Code: [Select]

#==============================================================================
# ** Game_Actor
#------------------------------------------------------------------------------
#  This class handles the actor. It's used within the Game_Actors class
#  ($game_actors) and refers to the Game_Party class ($game_party).
#==============================================================================

class Game_Actor < Game_Battler
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_accessor :coz_moving
  #--------------------------------------------------------------------------
  # * Setup
  #     actor_id : actor ID
  #--------------------------------------------------------------------------
  alias coz_thingy_setup setup
  def setup(actor_id)
    coz_thingy_setup(actor_id)
    @coz_moving = 0
  end
  #--------------------------------------------------------------------------
  # * Get Battle Screen X-Coordinate
  #--------------------------------------------------------------------------
   def screen_x
    # Return after calculating x-coordinate by order of members in party
    if self.index != nil
    position = $data_classes[self.class_id].position
      if @coz_moving != 0
        return @coz_moving
      else
        return 576 - (position * -20)
      end
    else
      return 0
    end
  end
end

Above the SDK set, and it worked... This is where I wasn't too careful though, because I then tried to move the stuff in step 4 to step 3, and when I ran it, I got the same error at the top of this post. So I switched it back, but the same error appeared again.

So this is what I have concluded... I need to ask: How/Where do I stick the "attr_accessor :coz_moving" and Alias stuff? (I know very little about aliases so I normally stick them above Main).

Also, from the flow of the animation when it did work (which is what I would like to fix first), I get the feeling I can take the two animations, in step 3, and step 4, and instead of a flash,

could have one be a walking animation, and in place of the weapon attack on the monster, I could have an attacker animation. (this stuff should come later).

But for now, before getting my head in the clouds, I'd just like to fix the first error.
« Last Edit: June 12, 2011, 06:06:47 PM by shintashi »

***
Rep:
Level 82
We learn by living...
first error fixed. I moved all the actor stuff into the actual Game Actor, and then fixed a mistake I made in placing this line:

@active_battler.coz_moving = target.screen_x     # Added this in

Above the "end" rather than below. It was probably displaced when I was looking for a way to trigger the effect during step 3, and then moved it back to the wrong line. Now that that is fixed, the idea of animation in the motion can be tested, plus variable distances.

For example, if I can divide the map into discrete units, representing step/dash/archer ranges, then I can have some pretty interesting tactics. Before I do this, an animation engine needs to be in place. I've also noticed from one of the Final Fantasy games, the characters are actually arranged at an angle, with the top actors being the most left, and the bottom actors being most to the right. I think this effect if done subtler would mean better interface with respect to the background images of things like caves and bridges.


edit: figured out how to add the diagonal line to the actors. The alignment is still somewhat debatable, but it's gone from a programmatic to cosmetic issue of finding the right mix of angles and distribution. Which means I can focus more on the animation issue, vs. the 'walking/dashing' issue.

Code: [Select]
  def screen_x
    # Return after calculating x-coordinate by order of members in party
    if self.index != nil
      #position definition is new, by shintashi from Ambrosia via roulette
    position = $data_classes[self.class_id].position
    modx = self.index * 20 - 90
      # return self.index * 160 + 80 # edited out by shintashi
      if @coz_moving != 0
        return @coz_moving #idea by coziekuns
      else
      #number = distance to right
      return 576 - (position * -24) + modx
      end
    else
      return 0
    end
  end
      #    return self.index * 160 + 80
  #--------------------------------------------------------------------------
  # * Get Battle Screen Y-Coordinate
  #--------------------------------------------------------------------------
   def screen_y
   # return 464 # edited by shintashi; 1st number = spacing, 2nd = from base
    return self.index * 58 + 136 #was 68+112
  end
« Last Edit: June 12, 2011, 06:23:43 PM by shintashi »

***
Rep:
Level 82
We learn by living...
So I've included some modifications I'm thinking of doing with respect to Movement during combat, and here's some different pseudo-screenshots I've whipped up displaying different options. I'm looking for advice, btw. Warning, these are incredibly boring windows. Not animations. Not eye candy.

Basic Unmodified
Spoiler for:


Dash option
Spoiler for:


Move option - presumably loads several move options or direction arrows
Spoiler for:


Lots of options window: you begin with one or two, but based on class/level/training, you can have more.
Spoiler for:


***
Rep:
Level 82
We learn by living...
ok, so I've added a y coordinate and building off Coziekun's coordinate system, made the following:

Code: [Select]
  def screen_x
    if self.index != nil
    position = $data_classes[self.class_id].position
    modx = self.index * 20 - 90
      if @coz_moving_x != 0
        return @coz_moving_x
      else
      return 576 - (position * -24) + modx
      end
    else
      return 0
    end
  end
 


   def screen_y
       if @coz_moving_y != 0
        return @coz_moving_y
      else
   return self.index * 58 + 136
   end
  end

modx is designed to give characters an angle instead of a straight line. I might create something like a mod_y for levitation/float effects, although I'm not sure about the bobbing up and down. I haven't figured out how to do the animation from one point to the next, but since we have both x and y coordinates now, a lot more can be done.

***
Rep:
Level 82
We learn by living...
So I've rewritten the coordinate system for actors, along the lines of a perspective grid, as follows:

Code: [Select]
  #--------------------------------------------------------------------------
  # * Get Battle Screen X-Coordinate
  #--------------------------------------------------------------------------
   def screen_x
    # Return after calculating x-coordinate by order of members in party
    if self.index != nil
    position = $data_classes[self.class_id].position
    modx = (self.index + 1) * 13 - 190
      if @coz_moving_x != 0
        return @coz_moving_x
      else
      #number = distance to right
    if self.index == 0 #because the top actor's coordinates don't process the same way;
     
      if position == 0
      return 576 - ((self.index + 1) * position * -23) + modx
      end
      if position == 1
      return 576 - (2 * -21) + modx
      end
      if position == 2
      return 576 - (4 * -21) + modx
      end
     
    else
      return 576 - ((self.index + 1) * position * -23) + modx
    end
      end
    else
      return 0
    end
  end
  #--------------------------------------------------------------------------
  # * Get Battle Screen Y-Coordinate
  #--------------------------------------------------------------------------
   def screen_y
       if @coz_moving_y != 0
        return @coz_moving_y
      else
      #number = distance from top -> down
   return (self.index + 1) * (self.index + 1) * 5.25 + 205 #higher = to ground 
   end
  end
  #--------------------------------------------------------------------------
  # * Get Battle Screen Z-Coordinate
  #--------------------------------------------------------------------------
  def screen_z
    # Return after calculating z-coordinate by order of members in party
    if self.index != nil
      return self.index + 1 #was 4 - self.index
    else
      return 0
    end
  end

As you can see, I've changed the layering of the z axis, have a front, middle, and rear position, and the actors line up askew to match the perspective of the maps, on the right side of a 3x4 grid.

Next I want to see if I can set them up with "mirror" display, so they can be surprised. I might also try sticking them on the left side of the map to illustrate being followed or attacked from behind.

***
Rep:
Level 82
We learn by living...
So I've created a coordinate system for the Enemies, and given enemies "position". I will later create a "@position" attribute that can be exploited during the tactical portion of battle. Right now, high str is in front line, high agility is in middle, and high int is in the rear positions.


Code: [Select]
 
#--------------------------------------------------------------------------
  # * Get Battle Screen X-Coordinate
  #--------------------------------------------------------------------------
  def screen_x
    # n = $data_troops[@troop_id].members[@member_index].x - 80
    #return n
   
    if base_str >= base_agi && base_str >= base_int
      position = 0
    elsif base_agi > base_str && base_agi >= base_int
      position = 1
    else
      position = 2
    end

    modx = (@member_index + 1) * -11
    slide = 240 #slide could be the coziekun mod, and use @member_index
#position 0, n = 320... approximates frontline of battle   
    if @member_index == 0
      if position == 0
      n = slide - 5 + modx
      end
      if position == 1
      n = slide - (2 * 21) + modx
      end
      if position == 2
      n = slide - (4 * 21) + modx
      end
    elsif @member_index <= 3 && @member_index > 0
   
      if position == 0
      n = 8 + slide - ((@member_index + 1 + position) * 7) + modx
      end
      if position == 1
      n = 8 + slide - ((@member_index + 1 + position) * 23) + modx
      end
      if position == 2
      n = 38 + slide - ((@member_index + 1 + position) * 37) + modx
      end
    else
      n = 72 + slide + ((@member_index - 2) * position * -23) + modx
    end
   
    return n
   end
  #--------------------------------------------------------------------------
  # * Get Battle Screen Y-Coordinate (self.index <=> @member_index)
  #--------------------------------------------------------------------------
  def screen_y
    if @member_index <= 3 #4 or less opponents
    n = @member_index
  else
    n = @member_index - 3 # 5-8 opponents
  end
  #return $data_troops[@troop_id].members[@member_index].y
    return (n + 1) * (n + 1) * 5.25 + 205
  end

***
Rep:
Level 82
We learn by living...
by adding +/- 30 to the X coordinates, I've made it so the attackers don't land directly on the enemies, but instead, in front of the enemies. I've also added the X and Y coordinate movement to the enemies, so they jump at the players and attack as well. I'm thinking of using a different set of battlers for the battle map, with the exception of some very large or important monsters, although I haven't decided yet, since final fantasy 2 monsters were disproportionately larger than the sprites, with the exception of mind controlled characters like Kain.

***
Rep:
Level 82
We learn by living...
been thinking of having the larger creatures occupy more than 1 index slot and setting it up so there's small, medium, and large icons, with small as default. I could also make use of the position slots to rearrange the coordinates of large creatures, but for now, I've got to focus on the animations.

***
Rep:
Level 82
We learn by living...
so I've been making some progress with figuring out how the map sprite animation system works. I think it loops AND takes into account direction. There's also this X/4, y/4 thing going on that prevents the whole sprite from displaying.

If I can crack the pattern used and the origins, I can import that code directly onto the battle map, and create custom animation patterns and loops.

edit: what ive got so far:

Code: [Select]
what is the def for “move_down” ?

  def move_down(turn_enabled = true) #turn enabled?
    # Turn down
    if turn_enabled
      turn_down
    end
    # If passable #what does this correlate to? Forcefield? Block?
    if passable?(@x, @y, 2)
      # Turn down
      turn_down
      # Update coordinates
      @y += 1
      # Increase steps
      increase_steps
    # If impassable
    else
      # Determine if touch event is triggered
      check_event_trigger_touch(@x, @y+1)
    end
end

000000

simplified

def move_down
     turn_down #no matter what)
      @y += 1
      increase_steps
end


so what are ‘turn_down’ and ‘increase_steps’ ?

  def turn_down
    unless @direction_fix
      @direction = 2
      @stop_count = 0
    end
  end

and

  def increase_steps
    # Clear stop count
    @stop_count = 0
  end

simplified

  def turn_down
      @direction = 2
      @stop_count = 0
  end

so what are ‘@direction’ and ‘@stop_count’ ?
‘stop_count = 0’ seems important

Note:    if @stop_count > (40 - @move_frequency * 2) * (6 - @move_frequency)
And :      @stop_count += 1 #which matches     @anime_count += 1

While directions = ?

@direction = 2 (base)
  #     d          : direction (0,2,4,6,8,10)
  #                  *  0,10 = determine if all directions are impassable


I am only beginning to understand some of this.
« Last Edit: July 02, 2011, 12:24:06 AM by shintashi »

***
Rep:
Level 82
We learn by living...
so this is something I figured out for swapping in the sprite sheet for the battler. This is of course in a rather clean test program.
Spoiler for:


I accomplished this by messing with Sprite_Battler:

Code: [Select]
      # Get and set bitmap
      @battler_name = @battler.battler_name
      @battler_hue = @battler.battler_hue
      self.bitmap = RPG::Cache.battler(@battler_name, @battler_hue)
   
      if @battler.is_a?(Game_Actor)
      @battler_name = battler.character_name
      @battler_hue = battler.character_hue
 self.bitmap = RPG::Cache.character(@battler_name, @battler_hue)
      end

The hardest part was figuring out how to address character_name. From here, I should be able to mess with this stuff:

Code: [Select]
    @cw = bitmap.width / 4 #base 4, ratio of x character map
        @ch = bitmap.height / 4 #base 4, ratio of y character map
        self.ox = @cw / 2 #base 2
        self.oy = @ch

edit:

ok, so I messed with stuff:

Code: [Select]
      if @battler.is_a?(Game_Actor)
      @battler_name = battler.character_name
      @battler_hue = battler.character_hue
 self.bitmap = RPG::Cache.character(@battler_name, @battler_hue)
        @cw = bitmap.width / 4 #was 4, ratio of x character map
        @ch = bitmap.height / 4 #was 4, ratio of y character map
        self.ox = @cw / 2 #was 2, doesn't appear to do anything
        self.oy = @ch
        @pattern = 0
        @direction = 4
        sx = @pattern * @cw #shintashi says start here.
        sy = (@direction - 2) / 2 * @ch
        self.src_rect.set(sx, sy, @cw, @ch)
      end

and that produced this image:

Spoiler for:


As you can see, only one of the 16 sprites shows up with this cropping modification. In theory, I should be able to mimic the changes in X/Y coordinates to line it up properly, then by looping similar patterns to the sprite, create an effect similar to walking.
« Last Edit: July 08, 2011, 03:57:17 AM by shintashi »

*****
Rep:
Level 84
This text is way too personal.
Bronze - GIAW 11 (Hard)Silver - GIAW Halloween
Your on the right track. Changing the src_rect and creating a loop will make a walking effect. You can check out Game_Character for more information. If I'm not mistaken, @pattern refers to index of the spritesheet.

***
Rep:
Level 82
We learn by living...
Your on the right track. Changing the src_rect and creating a loop will make a walking effect. You can check out Game_Character for more information. If I'm not mistaken, @pattern refers to index of the spritesheet.

Definitely... I was about to comment

Code: [Select]
  @pattern = 0 #0,1,2,3 => walk sequence
  @direction = 4 #2south,4west,6east,8north

Thing is, the walk sequence thing still makes my head hurt. I'm having difficulty with the stuff in Game_Character 2.

I feel like this is important:
Code: [Select]
# Update pattern
        @pattern = (@pattern + 1) % 4

but I'm not sure how to get it to refresh.

***
Rep:
Level 82
We learn by living...
ok so what I've figured out so far is the   "@pattern = (@pattern + 1) % 4" doesn't do anything because there's nothing to refresh it once it is instantiated. Since I'm not sure how to tie script to the frame rate or refresh rate, I have no idea how to mess with this.

I will see if I can make an attr_accessor called @pattern and then refresh it remotely. (In other words, I don't have a clue what I'm doing).

edit:

So I figured out some stuff, but I haven't fully implemented it yet:

Code: [Select]
def update
update_move
if @anime_count > 18 - @move_speed * 2
@pattern = (@pattern + 1) % 4
end
@anime_count = 0
end


def update_move
@anime_count += 1 #units higher than 1 are faster rates
end


If this was used, in theory, if I knew where to put the update, It might cause my sprites to look like they are walking in place.
« Last Edit: July 09, 2011, 06:20:27 PM by shintashi »

*****
Rep:
Level 84
This text is way too personal.
Bronze - GIAW 11 (Hard)Silver - GIAW Halloween
A simple way to time your refresh statements is to add the if statement:

Code: [Select]
if (Graphics.frame_count % frames == 0)

Where frames is the amount of frames you want to wait before re-refreshing.
 


***
Rep:
Level 82
We learn by living...
A simple way to time your refresh statements is to add the if statement:

Code: [Select]
if (Graphics.frame_count % frames == 0)

Where frames is the amount of frames you want to wait before re-refreshing.
 

it didn't recognize "frames".

meanwhile, my attempt to create update_move and all that stuff also failed. It looked nice though XD

*****
Rep:
Level 84
This text is way too personal.
Bronze - GIAW 11 (Hard)Silver - GIAW Halloween
frames is supposed to be an integer, like 2. The higher the frame the slower the sprite will refresh. Sorry for not making it clearer earlier.

***
Rep:
Level 82
We learn by living...
frames is supposed to be an integer, like 2. The higher the frame the slower the sprite will refresh. Sorry for not making it clearer earlier.

got the frame thing working with stuff like 'p "test" ' but it doesn't seem to like to refresh the sprites once instantiated. I have the same problem with sprites in my main battle system. For instance, I don't think I can mirror or move sprites once they have been created in the battle map.

***
Rep:
Level 82
We learn by living...
so this is where I'm stuck:


the script:

Code: [Select]
    if (Graphics.frame_count % 4 == 0)
        if @pattern < 4
          @pattern += 1
        else
          @pattern = 0
        end
    end

doesn't seem to change @pattern, because the sprites aren't changing on the screen. If I manually change the pattern to something like 1 or 3, the pattern initializes in that form only.


Code: [Select]

class Sprite_Battler < RPG::Sprite
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_accessor :battler                  # battler
  attr_accessor :pattern                  # animation pattern added by shintashi
  #--------------------------------------------------------------------------
  # * Object Initialization
  #     viewport : viewport
  #     battler  : battler (Game_Battler)
  #--------------------------------------------------------------------------
  def initialize(viewport, battler = nil)
    super(viewport)
    @battler = battler
    @battler_visible = false
    @pattern = 0
  end
  #--------------------------------------------------------------------------
  # * Dispose
  #--------------------------------------------------------------------------
  def dispose
    if self.bitmap != nil
      self.bitmap.dispose
    end
    super
  end
 
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update

   
    if (Graphics.frame_count % 4 == 0)
        if @pattern < 4
          @pattern += 1
        else
          @pattern = 0
        end
    end

   
    super
    # If battler is nil
    if @battler == nil
      self.bitmap = nil
      loop_animation(nil)
      return
    end
    # If file name or hue are different than current ones
    if @battler.battler_name != @battler_name or
       @battler.battler_hue != @battler_hue
      # Get and set bitmap (standard below)
      @battler_name = @battler.battler_name
      @battler_hue = @battler.battler_hue
      self.bitmap = RPG::Cache.battler(@battler_name, @battler_hue)
    #modified sprite by shintashi (affects actors only)
      if @battler.is_a?(Game_Actor)
      @battler_name = battler.character_name
      @battler_hue = battler.character_hue
 self.bitmap = RPG::Cache.character(@battler_name, @battler_hue)
        @cw = bitmap.width / 4 #was 4, ratio of x character map
        @ch = bitmap.height / 4 #was 4, ratio of y character map
        self.ox = @cw / 2 #was 2, doesn't appear to do anything
        self.oy = @ch
        @direction = 4 #2south,4west,6east,8north
        sx = @pattern * @cw
        sy = (@direction - 2) / 2 * @ch
        self.src_rect.set(sx, sy, @cw, @ch)
      end
 
      @width = bitmap.width
      @height = bitmap.height
      self.ox = @width / 2
      self.oy = @height
      # Change opacity level to 0 when dead or hidden
      if @battler.dead? or @battler.hidden
        self.opacity = 0
      end
    end
    # If animation ID is different than current one
#=================================================
#etc. the rest is normal from here down 
end




*
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 Use of Avatar and Signature Space2011 Best RPG Maker User (Scripting)2011 Most Mature Member2011 Favourite Staff Member2011 Best Veteran2010 Most Mature Member2010 Favourite Staff Member
I'd say your problem is in how you are trying to update your battler - the @pattern variable is likely changing, but you have no way to make that affect anything:

Code: [Select]

    # If file name or hue are different than current ones
    if @battler.battler_name != @battler_name or
       @battler.battler_hue != @battler_hue
      # Get and set bitmap (standard below)
      @battler_name = @battler.battler_name
      @battler_hue = @battler.battler_hue
      self.bitmap = RPG::Cache.battler(@battler_name, @battler_hue)
    #modified sprite by shintashi (affects actors only)
      if @battler.is_a?(Game_Actor)
      @battler_name = battler.character_name
      @battler_hue = battler.character_hue
 self.bitmap = RPG::Cache.character(@battler_name, @battler_hue)
        @cw = bitmap.width / 4 #was 4, ratio of x character map
        @ch = bitmap.height / 4 #was 4, ratio of y character map
        self.ox = @cw / 2 #was 2, doesn't appear to do anything
        self.oy = @ch
        @direction = 4 #2south,4west,6east,8north
        sx = @pattern * @cw
        sy = (@direction - 2) / 2 * @ch
        self.src_rect.set(sx, sy, @cw, @ch)
      end

All of that code is inside
Code: [Select]
    if @battler.battler_name != @battler_name or
       @battler.battler_hue != @battler_hue
    end

So it only ever runs when you change the battler graphic or hue - it doesn't run at all simply by changing the pattern. The update method should instead be something like (just edited in this post, not in-game, so I may have made errors, but it should give you the idea):

Code: [Select]

 #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update

    super
    # If battler is nil
    if @battler == nil
      self.bitmap = nil
      loop_animation(nil)
      return
    end
   
    pattern_changed = false
    if (Graphics.frame_count % 4 == 0)
        if @pattern < 4
          @pattern += 1
        else
          @pattern = 0
        end
        pattern_changed = true
    end
 
    if @battler.battler_name != @battler_name ||
       @battler.battler_hue != @battler_hue
      if @battler.is_a? (Game_Actor)
        @battler_name = battler.character_name
        @battler_hue = battler.character_hue
        self.bitmap = RPG::Cache.character(@battler_name, @battler_hue)
        @cw = bitmap.width / 4 #was 4, ratio of x character map
        @ch = bitmap.height / 4 #was 4, ratio of y character map
        pattern_changed = true
      else
        # Get and set bitmap (standard below)
        @battler_name = @battler.battler_name
        @battler_hue = @battler.battler_hue
        self.bitmap = RPG::Cache.battler(@battler_name, @battler_hue)
      end
      @width = bitmap.width
      @height = bitmap.height
      self.ox = @width / 2
      self.oy = @height
      # Change opacity level to 0 when dead or hidden
      if @battler.dead? or @battler.hidden
        self.opacity = 0
      end
    end
   
    if @battler.is_a? (Game_Actor) && pattern_changed
      self.ox = @cw / 2 #was 2, doesn't appear to do anything
      self.oy = @ch
      @direction = 4 #2south,4west,6east,8north
      sx = @pattern * @cw
      sy = (@direction - 2) / 2 * @ch
      self.src_rect.set(sx, sy, @cw, @ch)
    end
    # The rest of the method
  end

***
Rep:
Level 82
We learn by living...
MA - Excellent!

I was able to reintegrate it. Much thanks!

I'll see if I can access patterns from outside the class. I'm only certain @battler.pattern wouldn't make any sense because it would effect all the actors.
« Last Edit: July 16, 2011, 11:15:11 PM by shintashi »

***
Rep:
Level 82
We learn by living...
So I tested
Code: [Select]
p self.id

to see if I could address the battlers separately, and it spat out some really long numbers, but they were all reliably repeated when the loop cycled. The last couple of digits were the only ones that changed. I'm not sure what these numbers represent, or why they are so large.

My current goal is to see if I can have the "running in place" effect only active while the battler is selected, such as during command phase. Isolating individual battlers, and then being able to start and stop their animations is the objective.

I think this is a starting point...

Code: [Select]
    @action_battlers = []
    for enemy in $game_troop.enemies
      @action_battlers.push(enemy)
    for actor in $game_party.actors
      @action_battlers.push(actor)
    for battler in @action_battlers
      battler.make_action_speed
    @action_battlers.sort! {|a,b|
      b.current_action.speed - a.current_action.speed }


but addressing them seems blocked from all the nil results I'm getting.
« Last Edit: July 16, 2011, 11:18:23 PM by shintashi »

***
Rep:
Level 82
We learn by living...
so ive been thinking about creating some attr accessors for the battler that can be used to select movement modes, like direction, and 0/1 multipliers that can turn the move animation on and off. If I could access the direction variable directly, making a secondary modifier wouldn't be necessary. Right now I'm having trouble figuring out how to address battler variables outside the sprite_battler class, otherwise, I'd probably be much further ahead.

*****
Rep:
Level 84
This text is way too personal.
Bronze - GIAW 11 (Hard)Silver - GIAW Halloween
Referencing through Game_Actor is probably the easiest way to do things.

***
Rep:
Level 82
We learn by living...
Referencing through Game_Actor is probably the easiest way to do things.

so if I wanted to say something like

Code: [Select]
    pattern_changed = false
    if (Graphics.frame_count % 4 == 0)
        if @pattern < 3
          @pattern += 1 * @game_actor.walking
        else
          @pattern = 0
        end
        pattern_changed = true
    end

and set up "walking = 1" during the actor's turn, and "walking = 0" when some other actor or enemy is active (perhaps inside scene battle 3 or 4), how can I do this?

*****
Rep:
Level 84
This text is way too personal.
Bronze - GIAW 11 (Hard)Silver - GIAW Halloween
@game_actor.walking should be $game_actor.walking, as Game_Actor is a class of its own that's referenced by the global variable $game_actor. Just make an attr_accessor for walking in Game_Actor, and then modify it however you like.

***
Rep:
Level 82
We learn by living...
@game_actor.walking should be $game_actor.walking, as Game_Actor is a class of its own that's referenced by the global variable $game_actor. Just make an attr_accessor for walking in Game_Actor, and then modify it however you like.

in sprite, it's called battler, in other places its called active_battler, but the attr_accessor definitely works.
Spoiler for:
Quote
def phase3_next_actor
    # Loop
    begin
      # Actor blink effect OFF
      if @active_battler != nil
        @active_battler.blink = false
        @active_battler.walking = 0 #added by shintashi
      end
      # If last actor
      if @actor_index == $game_party.actors.size-1
        # Start main phase
        start_phase4
        return
      end
      # Advance actor index
      @actor_index += 1
      @active_battler = $game_party.actors[@actor_index]
      @active_battler.blink = true
      @active_battler.walking = 1  #added by shintashi
    # Once more if actor refuses command input
    end until @active_battler.inputable?
    # Set up actor command window
    phase3_setup_command_window
  end
  #--------------------------------------------------------------------------
  # * Go to Command Input of Previous Actor
  #--------------------------------------------------------------------------
  def phase3_prior_actor
    # Loop
    begin
      # Actor blink effect OFF
      if @active_battler != nil
        @active_battler.blink = false
        @active_battler.walking = 0 #added by shintashi
      end
      # If first actor
      if @actor_index == 0
        # Start party command phase
        start_phase2
        return
      end
      # Return to actor index
      @actor_index -= 1
      @active_battler = $game_party.actors[@actor_index]
      @active_battler.blink = true
      @active_battler.walking = 1  #added by shintashi
    # Once more if actor refuses command input
    end until @active_battler.inputable?
    # Set up actor command window
    phase3_setup_command_window
  end
 

In red you can see the places I added it in Scene_Battle 3. This works with this line of script:

Code: [Select]
    pattern_changed = false
    if (Graphics.frame_count % 4 == 0)
        if @pattern < 3
          if @battler.is_a? (Game_Actor)
            @pattern += battler.walking
          end
        else
          @pattern = 0
        end
        pattern_changed = true
    end

This is about as far as I wanted to get this weekend. My next goal is creating motion patterns, such as moving the sprites along the X-Y coordinates while walking in animation. I will probably have to create another attr_accessor to modify direction, but I think it will be worth it. The hardest part for me is knowing when to use:

 @active_battler.walking vs. battler.walking vs. $game_actor.walking

***
Rep:
Level 82
We learn by living...
I managed to overwrite the direction through game actor, and now the actor sprite directions can be changed from outside the Sprite Battler class, and the animation can be turned on and off. I haven't figured out how to create the movement without teleporting, but I'll be looking into  that next.

*****
Rep:
Level 84
This text is way too personal.
Bronze - GIAW 11 (Hard)Silver - GIAW Halloween
Hint: You'll proabably want to read up on ox and oy values.

***
Rep:
Level 82
We learn by living...
Hint: You'll proabably want to read up on ox and oy values.

that and something like this
Code: [Select]
    distance = 2 ** @move_speed

I figure move_speed is a variable typically ranging from 3-6, but I could be off by one. I believe "4" is the standard so 8 pixels per ...something unit is the transition.

I'm just going to guess the ticks between frame changes correspond to the movement ticks, so something like every 4 frames = +/- 8 pixels along the x or y axis.

Since my battle map is pseudo-3D, the closer to the top of the screen, the smaller the X and Y values become. But before I go off and adjust for the awesomness of 16 bit 3D strategy, I need to get the sprites running back and forth generically.

***
Rep:
Level 82
We learn by living...
I think I want to try cloning this next:
Code: [Select]
#--------------------------------------------------------------------------
  # * Move to Designated Position
  #     x : x-coordinate
  #     y : y-coordinate
  #--------------------------------------------------------------------------
  def moveto(x, y)
    @x = x % $game_map.width
    @y = y % $game_map.height
    @real_x = @x * 128
    @real_y = @y * 128
    @prelock_direction = 0
  end
  #--------------------------------------------------------------------------
  # * Get Screen X-Coordinates
  #--------------------------------------------------------------------------
  def screen_x
    # Get screen coordinates from real coordinates and map display position
    return (@real_x - $game_map.display_x + 3) / 4 + 16
  end
  #--------------------------------------------------------------------------
  # * Get Screen Y-Coordinates
  #--------------------------------------------------------------------------
  def screen_y
    # Get screen coordinates from real coordinates and map display position
    y = (@real_y - $game_map.display_y + 3) / 4 + 32
    # Make y-coordinate smaller via jump count
 

Although I have Finals Week right now... :(

***
Rep:
Level 82
We learn by living...
ran into some technical difficulties. I noticed when trying to integrate the new code into my main program, only part of it worked. The direction code works, the pattern looping did not. Its in SDK, and I think that's the primary problem. People say to use SDK, But I don't think I want to use it in my next project - it seems like more trouble than it's worth.

edit; got animation thing working in the SDK. basically whatever you do in normal script is split up all over the place in SDK. For example, some stuff still has to go into files like Game Actor, but other stuff has to be placed into obscure portions of SDK II, III, or IV, depending on where everything was moved.

I'm now ready to start moving forward... except for that final exam I have tomorrow afternoon  :P
« Last Edit: July 28, 2011, 02:48:15 AM by shintashi »

***
Rep:
Level 82
We learn by living...
so I was thinking about this

Code: [Select]
      # If action battler is actor
      if @active_battler.is_a?(Game_Actor)
        if @active_battler.restriction == 3
          target = $game_party.random_target_actor
        elsif @active_battler.restriction == 2
          target = $game_troop.random_target_enemy
        else
          index = @active_battler.current_action.target_index
          target = $game_troop.smooth_target_enemy(index)
        end
@active_battler.coz_moving_x = target.screen_x     # Added this for Actors
@active_battler.coz_moving_y = target.screen_y
      end

and where it says:

@active_battler.coz_moving_x = target.screen_x     # Added this for Actors
@active_battler.coz_moving_y = target.screen_y
 

I thought something like

@active_battler.coz_moving_x = target.screen_x - fade_x
@active_battler.coz_moving_y = target.screen_y - fade_y

might work...if 'fade_x' were something like a variable that starts off at "t minus 0" distance = Math.absoluteValue(actor_x - enemy_x) ((that's some badly written metacode))

Then something like "for every 4 ticks/frames, fade_x = fade_x_max - 24 pixels" ((more lame metacode))
Then something that asks "if frames changed % 4... then animation pattern +1.." ((my final piece of crap code)).

This doesn't yet integrate direction changes, but it animates a sprite from point A to the enemy.

***
Rep:
Level 82
We learn by living...
i cant for the life of me figure out how animations can be triggered to show more than one frame of action, and still be listed as instantaneous.

trying to take this:

Code: [Select]
        distance_x = target.screen_x - @active_battler.coz_moving_x
         # p distance_x
        distance_y = target.screen_y - @active_battler.coz_moving_y
         # p distance_y
         
@active_battler.coz_moving_x = target.screen_x     # Added actor move
@active_battler.coz_moving_y = target.screen_y

and setting it up so there's multiple frames each 24 pixels apart is the the real problem. That, and synchronizing the animations to go off simultaneously.

looking into Game_Player and something called "real_x" next.
« Last Edit: July 31, 2011, 01:35:11 AM by shintashi »

*****
Rep:
Level 84
This text is way too personal.
Bronze - GIAW 11 (Hard)Silver - GIAW Halloween
Logically, it's actually pretty easy to make moving battlers. Here's a simple algorithm that I used for one of my battle systems:

  • Compare the character and target's positions, (i.e subtracting target.x and target.y for active_battler.x and active_battler.y), and then divide by the amount of frames you want for them to move.
  • Make a loop checking if the character's position is equal to the target's position. If it is, stop and display whatever animation you want. If it's not, continue adding or subtracting x values.
  • Move the character back to the original position after you have parsed everything.

Of course in practice it's not that simple. A number of complications can occur, like when using floating point numbers and your results are off by the tiniest margin. But this is probably the easiest way to create moving battlers that can also be easily explained and understood.

***
Rep:
Level 82
We learn by living...
Logically, it's actually pretty easy to make moving battlers. Here's a simple algorithm that I used for one of my battle systems:

  • Compare the character and target's positions, (i.e subtracting target.x and target.y for active_battler.x and active_battler.y), and then divide by the amount of frames you want for them to move.
  • Make a loop checking if the character's position is equal to the target's position. If it is, stop and display whatever animation you want. If it's not, continue adding or subtracting x values.
  • Move the character back to the original position after you have parsed everything.

Of course in practice it's not that simple. A number of complications can occur, like when using floating point numbers and your results are off by the tiniest margin. But this is probably the easiest way to create moving battlers that can also be easily explained and understood.


what I'm having difficulty with is the instant vs. frames issue.

I tried something very close to (pseudo code below)

steps = 8
distance = targetsprite._x - mysprite._x

while steps > 1
steps -= 1
mysprite._x = targetsprite._x + (distance/8 * steps)
play_animation = true
else
play_animation = false
end

But I couldn't get the number to change more than once. I'll see if I can get something like your algorithm working next weekend, but I have to ask, should I make any new definitions or is everything I need already in there?
« Last Edit: July 31, 2011, 08:56:25 PM by shintashi »

***
Rep:
Level 82
We learn by living...
I think I get what you are saying now, but where do I stick the loop? its a for loop right?

pokeball TDSOffline
***
Rep:
Level 84
-T D S-
Silver - GIAW 11 (Hard)Silver - Game In A Week VII
Well the loop should go where you intend to move the sprite.

This is a simple example to expand a bit from what cooziekuns was saying about floating points.

Code: [Select]
# Player Test Sprite
player_sprite = Sprite.new
player_sprite.x = 400
player_sprite.y = 200
player_sprite.bitmap = Bitmap.new(32, 32)
player_sprite.bitmap.fill_rect(player_sprite.bitmap.rect, Color.new(255, 255, 255))

# Opponent Sprite
opponent_sprite = Sprite.new
opponent_sprite.x = 100
opponent_sprite.y = 200
opponent_sprite.bitmap = Bitmap.new(32, 32)
opponent_sprite.bitmap.fill_rect(player_sprite.bitmap.rect, Color.new(255, 0, 0))

# Duration of Frames for the Sprite to move
move_duration = 20
# Stop Position for Player
dest_stop = opponent_sprite.x + opponent_sprite.width
# Movement Speed for Player Sprite
move_speed = (player_sprite.x - dest_stop).to_f / move_duration
# Return Position for Player Sprite
return_pos = player_sprite.x

loop do

  # Update by Amount of Move Duration (Move Towards Opponent)
  (move_duration).times do
    # Update Screen
    Graphics.update
    player_sprite.x = [player_sprite.x - move_speed, dest_stop].max
  end

  # Action here (Just a wait example here)
  (30).times do ; Graphics.update ; end

  # Update by Amount of Move Duration (Move back to original position)
  (move_duration).times do
    # Update Screen
    Graphics.update
    player_sprite.x = [player_sprite.x + move_speed, return_pos].min
  end
 
  # Little Wait for example
  (30).times do ; Graphics.update ; end 
end

Just a simple example showing how to move one sprite from one side to another and then back without going over a limit using floating points. Thanks to modern algebra for the original example.


***
Rep:
Level 82
We learn by living...
I actually can't wait to start messing with that code, TDS, it looks fantastic!

***
Rep:
Level 82
We learn by living...
update:
this snippet for Game_Actor y coordinates took me a while of tinkering with this morning, Because my roommate noticed the bottom actor was significantly lower than the other three. Only recently did I realize the distance from 0 on the y axis is based on the total height of the spritesheet used for the actors. That's like 192 pixels, not 40-64 you'd expect from the apparent chibis on the screen. so before I had jumps of 40-64, now the differences are much finer, so the actors line up nicely.


Code: [Select]
   return (self.index + 7) * (self.index + 8) * 2.5 + 180 #higher = to ground


I still have to figure out a way to get them to sort of 'run' at the enemy and run back, and "hold" position. Also need to figure out how to shut off movement when wielding ranged weapons. Been thinking of doing a weapons check, and if the weapon check matches up with a number higher than X, or fits in an array, it ignores the movement action.