Ren'Py Programming issues

Chaosborn

God of the Chaosborn
Game Developer
Jan 25, 2020
876
739
Anyone with plenty of python knowledge that could help me out? I'm editing an existing battle system in renpy, trying to add an animation function, but can't see to make it work anyone who could hit up on disc with me and have a look? Cheers!
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,318
15,208
Anyone with plenty of python knowledge that could help me out? I'm editing an existing battle system in renpy, trying to add an animation function, but can't see to make it work anyone who could hit up on disc with me and have a look?
There's no need to have plenty of python knowledge for that, since it's done 100% with Ren'Py, partly with the , that don't have Python equivalent, partly with the .

This being said, without knowing more about the code... Well, I guess that using conditioned dynamic is the answer here.

Python:
image animation1:
    "images/anims/frame1.jpg"
    pause 0.1
    "images/anims/frame2.jpg"
    pause 0.1
    [...]
    "images/anims/frameX.jpg"
    pause 0.1
    [...]
    "images/anims/frameN.jpg"

default battleAnim = None

screen battleMap():
    [...]

    if not battleAnim is None:
        add "[battleAnim]"

    [...]

init python:
    [whatever the battle engine code]
        store.battleAnim = "animation1"
If would works exactly the same if "animation1" is in fact a movie. It's just its declaration syntax that change accordingly.
 

Chaosborn

God of the Chaosborn
Game Developer
Jan 25, 2020
876
739
There's no need to have plenty of python knowledge for that, since it's done 100% with Ren'Py, partly with the , that don't have Python equivalent, partly with the .

This being said, without knowing more about the code... Well, I guess that using conditioned dynamic is the answer here.

Python:
image animation1:
    "images/anims/frame1.jpg"
    pause 0.1
    "images/anims/frame2.jpg"
    pause 0.1
    [...]
    "images/anims/frameX.jpg"
    pause 0.1
    [...]
    "images/anims/frameN.jpg"

default battleAnim = None

screen battleMap():
    [...]

    if not battleAnim is None:
        add "[battleAnim]"

    [...]

init python:
    [whatever the battle engine code]
        store.battleAnim = "animation1"
If would works exactly the same if "animation1" is in fact a movie. It's just its declaration syntax that change accordingly.
So progress until now is, I've managed to get it to work, it's showing, but... my issue right now is the positioning it's using it's showing it at the user spots always, and never on the target its being used on...
This is my code for the target selection
def asignPos():
monster_slot[0].sprite_pos = 0
monster_slot[1].sprite_pos = 256
monster_slot[2].sprite_pos = 512
monster_slot[3].sprite_pos = 768
monster_slot[4].sprite_pos = 0
monster_slot[5].sprite_pos = 256
monster_slot[6].sprite_pos = 512
monster_slot[7].sprite_pos = 768
monster_slot[0].dmg_pos = (576,320)
monster_slot[1].dmg_pos = (832,320)
monster_slot[2].dmg_pos = (1088,320)
monster_slot[3].dmg_pos = (1344,320)
monster_slot[4].dmg_pos = (576,512)
monster_slot[5].dmg_pos = (832,512)
monster_slot[6].dmg_pos = (1088,512)
monster_slot[7].dmg_pos = (1344,512)
This are the codes related to attacks

init python:
def atkAll():
renpy.show(anima_a)
renpy.pause(1.0, hard=True)
renpy.play(atk_sfx)
renpy.pause(0.2, hard=True)
renpy.hide(anima_a)
for t in battle_monsters:
if not t.dead:
if accFormula(currentplayer, t):
dmgFormula(t)
t._hp -= t.finaldmg
t._mp -= mpdmg
renpy.show_screen("monster_dmg")
renpy.with_statement(s_trans)


def atkRow():
renpy.show(anima_a)
renpy.pause(1.0, hard=True)
renpy.play(atk_sfx)
renpy.pause(0.2, hard=True)
renpy.hide(anima_a)
for t in picked_targs:
if accFormula(currentplayer, t):
dmgFormula(t)
t._hp -= t.finaldmg
t._mp -= mpdmg
renpy.show_screen("monster_dmg")
renpy.with_statement(s_trans)

def atkEnemy():
for t in picked_targs:
renpy.show(anima_a)
renpy.pause(1.0, hard=True)
renpy.play(atk_sfx)
renpy.pause(0.2, hard=True)
renpy.hide(anima_a)
if accFormula(currentplayer, t):
dmgFormula(t)
t._hp -= t.finaldmg
t._mp -= mpdmg
renpy.show_screen("monster_dmg")
renpy.with_statement(s_trans)
afterFX(b_skill, t)

I need to figure out how to link them together...
renpy.show(anima_a)
is the animation code
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,318
15,208
I need to figure out how to link them together...
Well, since it's an "existing combat system", what is there to figure out ? The different parts are already linked together.


renpy.show(anima_a)
is the animation code
What the code you provided show as being used where it have to be. The only thing missing is the position, that you define with the at_list as implied by .
 

Chaosborn

God of the Chaosborn
Game Developer
Jan 25, 2020
876
739
Well, since it's an "existing combat system", what is there to figure out ? The different parts are already linked together.




What the code you provided show as being used where it have to be. The only thing missing is the position, that you define with the at_list as implied by .
Well I tried adding those I had to edit stuff, and add stuff to the original cause it didn't support animations,; and while I have that fixed now, I've tried implementing the position thing ,but cant seem to figure it out
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,318
15,208
Well I tried adding those I had to edit stuff, and add stuff to the original cause it didn't support animations,; and while I have that fixed now, I've tried implementing the position thing ,but cant seem to figure it out
If you (or the combat system, I don't know) were going with the flow, instead of trying to twist Ren'Py to your desires, it wouldn't be a problem.

Basically speaking, a combat system should looks like this:
Python:
init python:
    class Fighter( renpy.python.RevertableObject ):
        # Whatever attributes and code you need to define a member of the MC party or an enemy.

        @property
        def sprite( self ):
            # Return the idle sprite or animation corresponding to the current state.

        @property
        def pos( self ):
            # Return the position where to display this character.


default enemy1 = Fighter( [whatever is needed by the class definition] )
default enemy2 = Fighter( [whatever is needed by the class definition] )
default player = Fighter( [whatever is needed by the class definition] )
default healer = Fighter( [whatever is needed by the class definition] )
default tank = Fighter( [whatever is needed by the class definition] )

#  Will host the Figther objects representing the party members,
# for the enemy team,
default enemyParty = []
# and for the player party.
default allyParty = []

screen battleScreen( char ):

    # whatever background and global UI you want/need.

    # Here's the sprite (idle or animation) representing the character.
    add char.sprite  pos char.pos

label battle:
    # Compose the enemy party
    $ enemyParty.append( enemy1 )
    $ enemyParty.append( enemy2 )

    # Compose player's party
    $ playerParty.append( player )
    $ playerParty.append( healer )
    $ playerParty.append( tank )

    # Continue until the player win or loose.
    while [condition still at least someone living in both party]:
        python:
            # proceed each member of player's party.
            for c in playerParty:
                call screen battleScreen( c )
                # proceed the selected action for this character.
                if _return == whatever:
                    [whatever]
                elif _return == whateverElse:
                    [whatever]
            # proceed each enemy.
            for c in enemyParty:
                # put the enemy AI here
It's obviously a basic definition, but doing a RPG Maker-like combat system don't need really more than this.
And if you want a map based combat system, it's the same logic, with almost no changes:
Python:
screen battleScreen( char ):

    # whatever background and global UI you want/need.

    # For each character involved in the combat.
    for char in playerParty + enemyParty:
        # Unless he's dead.
        if not char.isDead:
            # place it where he's expected to be
            fixed:
                pos char.pos
                # Firstly the sprite (idle or animation)
                add char.sprite
                #  And put on top an fully transparent image button to select it,
                # if it's an ally.
                if char.isAlly:
                    imagebutton:
                        idle Solid( "#000000000" )
                        action Return( "select", char )

    # Put here the UI specific to the selected character

label battle:
    # Compose the enemy party
    $ enemyParty.append( enemy1 )
    $ enemyParty.append( enemy2 )

    # Compose player's party
    $ playerParty.append( player )
    $ playerParty.append( healer )
    $ playerParty.append( tank )

    # No character selected by default  
    $ char = None

    while [condition still at least someone living in both party]:
        call screen battleScreen( char )
        # change the selected character.
        if _return[0] == "select":
            $ char = _return[1]
        elif _return == whatever:
            # whatever
        elif _return == "end turn":
            # put the enemy AI here
once again, it's just the basis, but once again it don't really need more than this.
 

Chaosborn

God of the Chaosborn
Game Developer
Jan 25, 2020
876
739
If you (or the combat system, I don't know) were going with the flow, instead of trying to twist Ren'Py to your desires, it wouldn't be a problem.

Basically speaking, a combat system should looks like this:
Python:
init python:
    class Fighter( renpy.python.RevertableObject ):
        # Whatever attributes and code you need to define a member of the MC party or an enemy.

        @property
        def sprite( self ):
            # Return the idle sprite or animation corresponding to the current state.

        @property
        def pos( self ):
            # Return the position where to display this character.


default enemy1 = Fighter( [whatever is needed by the class definition] )
default enemy2 = Fighter( [whatever is needed by the class definition] )
default player = Fighter( [whatever is needed by the class definition] )
default healer = Fighter( [whatever is needed by the class definition] )
default tank = Fighter( [whatever is needed by the class definition] )

#  Will host the Figther objects representing the party members,
# for the enemy team,
default enemyParty = []
# and for the player party.
default allyParty = []

screen battleScreen( char ):

    # whatever background and global UI you want/need.

    # Here's the sprite (idle or animation) representing the character.
    add char.sprite  pos char.pos

label battle:
    # Compose the enemy party
    $ enemyParty.append( enemy1 )
    $ enemyParty.append( enemy2 )

    # Compose player's party
    $ playerParty.append( player )
    $ playerParty.append( healer )
    $ playerParty.append( tank )

    # Continue until the player win or loose.
    while [condition still at least someone living in both party]:
        python:
            # proceed each member of player's party.
            for c in playerParty:
                call screen battleScreen( c )
                # proceed the selected action for this character.
                if _return == whatever:
                    [whatever]
                elif _return == whateverElse:
                    [whatever]
            # proceed each enemy.
            for c in enemyParty:
                # put the enemy AI here
It's obviously a basic definition, but doing a RPG Maker-like combat system don't need really more than this.
And if you want a map based combat system, it's the same logic, with almost no changes:
Python:
screen battleScreen( char ):

    # whatever background and global UI you want/need.

    # For each character involved in the combat.
    for char in playerParty + enemyParty:
        # Unless he's dead.
        if not char.isDead:
            # place it where he's expected to be
            fixed:
                pos char.pos
                # Firstly the sprite (idle or animation)
                add char.sprite
                #  And put on top an fully transparent image button to select it,
                # if it's an ally.
                if char.isAlly:
                    imagebutton:
                        idle Solid( "#000000000" )
                        action Return( "select", char )

    # Put here the UI specific to the selected character

label battle:
    # Compose the enemy party
    $ enemyParty.append( enemy1 )
    $ enemyParty.append( enemy2 )

    # Compose player's party
    $ playerParty.append( player )
    $ playerParty.append( healer )
    $ playerParty.append( tank )

    # No character selected by default 
    $ char = None

    while [condition still at least someone living in both party]:
        call screen battleScreen( char )
        # change the selected character.
        if _return[0] == "select":
            $ char = _return[1]
        elif _return == whatever:
            # whatever
        elif _return == "end turn":
            # put the enemy AI here
once again, it's just the basis, but once again it don't really need more than this.
I see thank you, If I can't figure it out, I'll try using this and create some, thank you!