Main Menu
  • Welcome to The RPG Maker Resource Kit.

[Request] Final Fantasy Style Side View Battle?

Started by shintashi, May 31, 2011, 10:58:28 PM

0 Members and 2 Guests are viewing this topic.

shintashi

#25
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.

shintashi

#26
So I tested

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...


    @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.

shintashi

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.

cozziekuns

Referencing through Game_Actor is probably the easiest way to do things.

shintashi

Quote from: cozziekuns on July 18, 2011, 03:11:01 PM
Referencing through Game_Actor is probably the easiest way to do things.

so if I wanted to say something like


    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?

cozziekuns

@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.

shintashi

Quote from: cozziekuns on July 18, 2011, 03:55:09 PM
@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]
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
 
[/spoiler]

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


    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

shintashi

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.

cozziekuns

Hint: You'll proabably want to read up on ox and oy values.

shintashi

Quote from: cozziekuns on July 19, 2011, 04:31:58 AM
Hint: You'll proabably want to read up on ox and oy values.

that and something like this

    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.

shintashi

I think I want to try cloning this next:

#--------------------------------------------------------------------------
  # * 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... :(

shintashi

#36
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

shintashi

so I was thinking about this


      # 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.

shintashi

#38
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:


        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.

cozziekuns

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.

shintashi

#40
Quote from: cozziekuns on July 31, 2011, 01:56:13 AM
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?

shintashi

I think I get what you are saying now, but where do I stick the loop? its a for loop right?

TDS

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.


# 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.


shintashi

I actually can't wait to start messing with that code, TDS, it looks fantastic!

shintashi

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.



   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.