Advertisement
Guest User

Demo of JumpAttackSkill for Ren'Py RPG Battle Engine

a guest
Apr 29th, 2013
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 12.81 KB | None | 0 0
  1. init python:
  2.    
  3.     # inherit from the existing AttackSkill so we can just use all that class' functionality
  4.     class JumpAttackSkill(AttackSkill):
  5.        
  6.         def __init__(self, jumpOffset=50, *params, **kwargs):
  7.             # Call the inherited AttackSkill init with all the same params and keyword arguments
  8.             # to make sure it behaves the same as AttackSkill in every respect other than our changes.
  9.             super(JumpAttackSkill, self).__init__(*params, **kwargs)
  10.            
  11.             # Make a note of the offset we choose
  12.             self._jumpOffset = jumpOffset
  13.            
  14.         def PerformAction(self, fighter, target):
  15.             # First have the character jump into a position jumpOffset away from the target
  16.             offset = self._jumpOffset
  17.             # If we're on the left of the target, we want a negative offset (to the target's left)
  18.             if (fighter.Position.X < target[0].Position.X):
  19.                 offset = offset * -1
  20.  
  21.             # Set the fighter sprite into a 'leaping' state:
  22.             fighter._battle.ChangeFighterState(fighter, "leapup")
  23.  
  24.             # We'll use a move function that already exists in the battle engine for a FF-style leap-in.
  25.             # 'period' is how many seconds the leap takes; 'height' is how many pixels upward the trajectory goes.
  26.             # If you prefer a simple run-across-the-screen, then comment out the next line and uncomment the one below.
  27.             mf = MoveJumpFunction(fighter.Position.Transform.xpos, fighter.Position.Transform.ypos, target[0].Position.Transform.xpos + offset, target[0].Position.Transform.ypos, period=0.5, height=100)
  28.             #mf = MoveFunction(fighter.Position.Transform.xpos, fighter.Position.Transform.ypos, target[0].Position.Transform.xpos + offset, target[0].Position.Transform.ypos, period=0.5)
  29.            
  30.             fighter.Show(transforms=[Transform(function=mf)])
  31.             # We need a pause here, so that we wait for the leap animation to play out before continuing.
  32.             fighter._battle.Pause(0.5)
  33.            
  34.             # We now need to set the fighter's Position to a new BattlePosition in its new place on-screen,
  35.             # so that while the attack draws, it draws in the right place. We'll keep hold of the original
  36.             # one so we can put it back later.
  37.             originalPosition = fighter.Position
  38.             fighter.Position = BattlePosition(target[0].Position.X + offset, target[0].Position.Y)
  39.             fighter.Position.SetBattle(fighter._battle)
  40.            
  41.             fighter._battle.ChangeFighterState(fighter, "default")
  42.  
  43.             # Then perform the attack using the base class's functionality
  44.             super(JumpAttackSkill, self).PerformAction(fighter, target)
  45.            
  46.             fighter._battle.ChangeFighterState(fighter, "leapup")
  47.  
  48.             # Put the fighter's old position back
  49.             fighter.Position = originalPosition
  50.            
  51.             # Then have the character jump back into their original position - the same thing, in reverse.
  52.             mf = MoveJumpFunction(target[0].Position.Transform.xpos + offset, target[0].Position.Transform.ypos, fighter.Position.Transform.xpos, fighter.Position.Transform.ypos, period=0.5, height=100)
  53.             #mf = MoveFunction(target[0].Position.Transform.xpos + offset, target[0].Position.Transform.ypos, fighter.Position.Transform.xpos, fighter.Position.Transform.ypos, period=0.5)
  54.            
  55.             fighter.Show(transforms=[Transform(function=mf)])
  56.             fighter._battle.Pause(0.5)
  57.            
  58.            
  59.    
  60. label test:
  61.  
  62.     play music "audio/battle.ogg" fadein 0.5
  63.    
  64.     python:
  65.        
  66.         JumpAttack = JumpAttackSkill(command=[('Attack', -1)], multiplier=1.2, sfx="audio/sword.wav")
  67.        
  68.         # First, we create the battle itself, and choose a schema to use.
  69.         # In this case, the schema describes an active battle - so we'll have the initiative bars deciding the order of actions, for example.
  70.         battle = Battle(ActiveSchema())
  71.  
  72.         # Next, we need to set up our battlefield - this is accomplished in three steps:
  73.        
  74.         # Step one: create a sprite for the battlefield BG.
  75.         # Note that we're just passing the name of the image defined in assets.rpy; we could equally pass a Displayable instance if we preferred.
  76.         fieldSprite = BattlefieldSprite('bg woodland')
  77.    
  78.         # Step two: create the battlefield object, in this case we're using a SimpleBattlefield (so we have the classic FF-style face-off).
  79.         battlefield = SimpleBattlefield(fieldSprite)
  80.        
  81.         # Step three: add the battlefield object to the battle, so our battle knows which one to use.
  82.         battle.SetBattlefield(battlefield)
  83.        
  84.         # (This could all be done on one line if you prefer, as in the following line of commented-out code:
  85.         # battle.SetBattlefield(SimpleBattlefield(BattlefieldSprite('bg woodland')))
  86.        
  87.         # Next, we need to add some fighters to our battle; we'll start off with the players.
  88.         # Before we can add any fighters, we have to create a faction for them to belong to:
  89.         battle.AddFaction("Player", playerFaction=True)
  90.        
  91.         # To add a fighter, first create a sprite.
  92.         # - The first parameter is the name of the image to use for that sprite.
  93.         # - The 'anchor' parameter denotes the part of the sprite (in the same way as xanchor/yanchor in
  94.         #   Ren'Py position properties) where the character's feet are found. This is the point which is placed in that fighter's position
  95.         #   on the battlefield. (This is more relevant for grid battles.)
  96.         # - The 'placeMark' parameter denotes the offset from the anchor point that should be used for giant-floating-hand-style
  97.         #   selection cursors. This is also where the bouncy damage numbers come out, if your fighters get hit.
  98.         #   Bearing in mind that Ren'Py coordinates have (0,0) in the top-left corner, this example placeMark of
  99.         #   (0, -100) means "in line with the anchor point left-to-right, but 100 pixels higher".
  100.         bobSprite = BattleSprite('bob', anchor=(0.5, 0.75), placeMark=(0,-100))
  101.        
  102.         # Next, we create Bob as a player fighter - meaning he'll be controlled by the player, who'll get to choose his moves.
  103.         # the first parameter is the fighter's name, and the 'sprite' parameter gives the sprite to use for that character;
  104.         # all other params, with names, are used for Bob's stats.
  105.         # If you don't include a particular stat in the list, then if Bob needs it to use a skill or something, it'll be added automatically
  106.         # with a reasonable default, so you only actually have to define the non-default stats.
  107.         # (Bob is a bit of a brawler, good at hand-to-hand combat but not so fast.)
  108.         bob = PlayerFighter("Bob", Speed=11, Attack=20, Defence=20, sprite=bobSprite)
  109.        
  110.         # Next, we give Bob his skills. Skills are the things that show up on the command menu when we're selecting what Bob should
  111.         # do in a turn.
  112.         # We're only going to give him 'attack' (a physical attack) and 'skip' (in case he doesn't want to attack) for now.
  113.         bob.RegisterSkill(JumpAttack)
  114.         bob.RegisterSkill(Library.Skills.Skip)
  115.  
  116.  
  117.         # Finally, we have to add Bob to the battle. He'll automatically get added to the last faction you defined (in this case, 'Player').
  118.         battle.AddFighter(bob)
  119.        
  120.         # Then we'll do much the same for Bob's compatriot Geoff. Geoff is a nimble but weak character who backs up his team-mate
  121.         # with magic attacks.
  122.         geoffSprite = BattleSprite('geoff', anchor=(0.5, 0.8), placeMark=(0,-100))
  123.         geoff = PlayerFighter("Geoff", Speed=13, Attack=7, Defence=10, MP=20, health=200, sprite=geoffSprite)
  124.         geoff.RegisterSkill(JumpAttack)
  125.         geoff.RegisterSkill(Library.Skills.Skip)
  126.         geoff.RegisterSkill(Library.Skills.Fire1)
  127.         geoff.RegisterSkill(Library.Skills.Water1)
  128.         geoff.RegisterSkill(Library.Skills.Earth1)
  129.         battle.AddFighter(geoff)
  130.        
  131.        
  132.         # Now, we have a player team, so we have to give them some opposition. We'll start out by creating a faction for the bad guys:
  133.         battle.AddFaction('Enemies', playerFaction=False)
  134.        
  135.         # For the enemies' sprites, we're adding a 'placeMark' parameter. This determines where the button to
  136.         # click to target that enemy will be drawn, relative to the point they're standing (the 'anchor' point
  137.         # described earlier). In this case we're setting it to (0, -75), which means 75 pixels directly above
  138.         # the point they're standing on.
  139.         # (We're also using a 100px-tall graphic which is mostly empty and just has a pointing hand at the top.
  140.         # That will be centred on the placeMark point, so the top of our pointing hand will be 125px above the
  141.         # anchor point (75 + (100/2)).)
  142.         banditSprite = BattleSprite('bandit', anchor=(0.5, 0.75), placeMark=(0,-75))
  143.        
  144.         # Defining enemies is much the same as defining players, except we use the 'SimpleAIFighter' class instead of 'PlayerFighter':
  145.         bandit1 = SimpleAIFighter("Bandit 1", Speed=10, Attack=15, Defence=8, sprite=banditSprite)
  146.         # When we register a skill for a SimpleAIFighter, we provide a weight - how often compared to other skills the fighter uses this one.
  147.         # Since we only have one skill, it doesn't matter what the value is. If we had two, one of which had a weight of 1 and the other of 2,
  148.         # the 2-weighted skill would be used twice as often.
  149.         bandit1.RegisterSkill(JumpAttack, 1)
  150.         battle.AddFighter(bandit1)
  151.         bandit2 = SimpleAIFighter("Bandit 2", Speed=10, Attack=15, Defence=8, sprite=banditSprite)
  152.         bandit2.RegisterSkill(JumpAttack, 1)
  153.         battle.AddFighter(bandit2)
  154.         bandit3 = SimpleAIFighter("Bandit 3", Speed=10, Attack=15, Defence=8, sprite=banditSprite)
  155.         bandit3.RegisterSkill(JumpAttack, 1)
  156.         battle.AddFighter(bandit3)
  157.        
  158.        
  159.         # Next, we add any Extras we care about. Extras are plug-in bits which add to the behaviour of the battle in some way.
  160.        
  161.         # We'll start with one for RPG damage, to show a bouncing red number when someone gets hit.
  162.         battle.AddExtra(RPGDamage())
  163.        
  164.         # Along similar lines, RPGDeath fades the fighter out when they die.
  165.         # (We could have made the sprite do this when its fighter dies, but then we'd have to replicate that
  166.         # for every sprite in the battle, it could be tedious.)
  167.         battle.AddExtra(RPGDeath())
  168.        
  169.         # Next we'll add 'ActiveDisplay', which draws a stats box for the given faction (we'll do it for the players).
  170.         # The first parameter here is the name of the faction to display.
  171.         # The second parameter is a Python dictionary telling us what to display on the stat line, and which of the fighter's stats to get the number from.
  172.         # (Mostly we're using the stat name for display, but - for example - we're showing the 'Health' stat with the label 'HP'.)
  173.         #battle.AddExtra(ActiveDisplay("Player", {"HP": "Health", "Move": "Move", "MP":"MP"}))
  174.        
  175.         battle.AddExtra(StatsDisplay("Player", [("Health", 'HP', 'ratio'), ("MP", "MP", 'ratio'), ('Priority', '', 'bar')], grid=True))
  176.        
  177.         # This one will cause any fighter performing an action to bob a bit first, so it's easy to see who's doing what.
  178.         battle.AddExtra(RPGActionBob())
  179.        
  180.         # Finally, we'll add a win condition! The engine doesn't actually decide a winner on its own at all,
  181.         # you have to add an Extra which will do it... this is because sometimes, you might want to create
  182.         # battles where one side can be wiped out but still win becuase they prevented the opponents from
  183.         # advancing for ten turns, or something like that, where a built-in win condition might make it
  184.         # difficult or impossible to code what you want.
  185.         # However, for the 99% of times when you just want to have one side hit the other side until they
  186.         # fall over, we can use 'SimpleWinConditon', which just ends the battle in favour of the last
  187.         # faction standing.
  188.         battle.AddExtra(SimpleWinCondition())
  189.        
  190.         # That's it! We're ready to go, so we just hit the 'Start()' method on our battle object, and the battle will kick off!
  191.         battle.Start()
  192.        
  193.         # After the battle concludes, we can pull the winner out from the 'Won' property on the battle object:
  194.         winner = battle.Won
  195.    
  196.     # Back in regular Ren'Py land:
  197.     if (winner == 'Player'):
  198.         #TODO: Play victory music
  199.         "Well done, you beat the bad guys."
  200.     else:
  201.         #TODO: Play failure music
  202.         "Game Over: You Died."
  203.        
  204.     jump start
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement