Defining and calling user-defined functions?
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
- Rosstin
- Veteran
- Posts: 368
- Joined: Mon Jan 31, 2011 5:43 pm
- Completed: Rex Rocket, Kitty Love, King's Ascent
- Projects: Road Redemption, Queen At Arms
- Organization: Aqualuft Games
- Contact:
Defining and calling user-defined functions?
So, I'm writing a game in Renpy that includes a battle system. My problem is that I want to be able to call and return functions, which will perform certain actions and then return to the label they originated from and then continue.
From what I understand of labels, labels act as a sort of "GOTO". After the label finishes executing, it simply jumps to the next label it is given, rather than returning to the label that called it.
For example, I want the LABEL- BATTLE 1 to execute, call a function that displays the main character's attack menu, then call a function for the enemy that the main character is fighting.
Is there a way I can define and call user-defined functions in Renpy? Is it user-friendly? If not, what is a sensible alternative to what I am trying to do?
From what I understand of labels, labels act as a sort of "GOTO". After the label finishes executing, it simply jumps to the next label it is given, rather than returning to the label that called it.
For example, I want the LABEL- BATTLE 1 to execute, call a function that displays the main character's attack menu, then call a function for the enemy that the main character is fighting.
Is there a way I can define and call user-defined functions in Renpy? Is it user-friendly? If not, what is a sensible alternative to what I am trying to do?
-
- Miko-Class Veteran
- Posts: 829
- Joined: Sun Feb 20, 2005 8:45 pm
- Projects: NaNoRenO 2016, Ren'Py tutorial series
- Location: USA
- Contact:
Re: Defining and calling user-defined functions?
Okay, bear with me on this one, there's a handful of answers for this:
First off, Ren'Py is Python-based. all Python statements outside of a python: block must be preceded with the $ character. You CAN define actual functions inside Python blocks (I advise using init python: blocks for these). You can call functions either as normal in python blocks or outside them by preceding them with the $ character.
Secondly, Labels can act as GOTO or CALL, depending on what command you use to get to the label.
Jump <label> will go to the label. Under most circumstances, you will not use the return command on a label you jump to.
while Call <label> will go to the label AS A SUBROUTINE, and the return command will bring you back to where the call was done. If you have a called label and you jump from that label to another one, you can STILL use the return command as if you had not jumped.
So, if you're somewhere in label Label_A...
...and you CALL Label_B...
...and then JUMP to Label_C...
...and then use the RETURN command in Label_C...
...you will be back NOT in Label_B but in Label_A, since that's where the last call occurred from.
Fair bit of warning: if you have not done a Call Label command, the Return command will end the game and bring you back to the main menu.
in other words, yes, you can also fake a function definition using labels and the Ren'Py call command. I'd advise going the first route (actual Python) if you're familiar enough with the language to do so (and most of us will help if you're not).
First off, Ren'Py is Python-based. all Python statements outside of a python: block must be preceded with the $ character. You CAN define actual functions inside Python blocks (I advise using init python: blocks for these). You can call functions either as normal in python blocks or outside them by preceding them with the $ character.
Secondly, Labels can act as GOTO or CALL, depending on what command you use to get to the label.
Jump <label> will go to the label. Under most circumstances, you will not use the return command on a label you jump to.
while Call <label> will go to the label AS A SUBROUTINE, and the return command will bring you back to where the call was done. If you have a called label and you jump from that label to another one, you can STILL use the return command as if you had not jumped.
So, if you're somewhere in label Label_A...
...and you CALL Label_B...
...and then JUMP to Label_C...
...and then use the RETURN command in Label_C...
...you will be back NOT in Label_B but in Label_A, since that's where the last call occurred from.
Fair bit of warning: if you have not done a Call Label command, the Return command will end the game and bring you back to the main menu.
in other words, yes, you can also fake a function definition using labels and the Ren'Py call command. I'd advise going the first route (actual Python) if you're familiar enough with the language to do so (and most of us will help if you're not).
~Kitsune Zeta
- Rosstin
- Veteran
- Posts: 368
- Joined: Mon Jan 31, 2011 5:43 pm
- Completed: Rex Rocket, Kitty Love, King's Ascent
- Projects: Road Redemption, Queen At Arms
- Organization: Aqualuft Games
- Contact:
Re: Defining and calling user-defined functions?
Oh, beautiful! Thank you for the prompt and helpful answer! I'll investigate both of those options.
I'm all for getting deeper into Python-- I'll probably have to use it for work later anyway. I just want to be careful I don't stray too far from Renpy's design philosophy.
I'm all for getting deeper into Python-- I'll probably have to use it for work later anyway. I just want to be careful I don't stray too far from Renpy's design philosophy.
- Rosstin
- Veteran
- Posts: 368
- Joined: Mon Jan 31, 2011 5:43 pm
- Completed: Rex Rocket, Kitty Love, King's Ascent
- Projects: Road Redemption, Queen At Arms
- Organization: Aqualuft Games
- Contact:
Re: Defining and calling user-defined functions?
OK, two more questions.
How can I define something like a STRUCT? For character data, for example.
And also: what do you recommend as a good database for Python/Renpy questions? I'm aware of the cookbook and other easy-to-find Renpy resources; is there something I'm missing? Actually, what would be really nice to find would be a clear, open-source example of a Renpy battle system. I'm not trying to do anything particularly complicated-- having an example to crib from would be wonderful.
Thanks so much!
How can I define something like a STRUCT? For character data, for example.
And also: what do you recommend as a good database for Python/Renpy questions? I'm aware of the cookbook and other easy-to-find Renpy resources; is there something I'm missing? Actually, what would be really nice to find would be a clear, open-source example of a Renpy battle system. I'm not trying to do anything particularly complicated-- having an example to crib from would be wonderful.
Thanks so much!
-
- Miko-Class Veteran
- Posts: 829
- Joined: Sun Feb 20, 2005 8:45 pm
- Projects: NaNoRenO 2016, Ren'Py tutorial series
- Location: USA
- Contact:
Re: Defining and calling user-defined functions?
In C++ (which I assume you're referring to with the struct question), a struct was a class with all members implicitly public (whereas a class has all of its members implicitly private), but in all other regards, the two are identical. In Python, a struct refers to something completely different (which I don't understand myself), but a class in Python is roughly equivalent to a struct in C++ (although the syntax for declaring one is different)
Questions regarding how to do things in Ren'Py do belong in this subforum. I'm not quite familiar enough with the language to get a sample battle system up (if someone else reads this and is comfortable enough to do a simple one, by all means, do so).
Questions regarding how to do things in Ren'Py do belong in this subforum. I'm not quite familiar enough with the language to get a sample battle system up (if someone else reads this and is comfortable enough to do a simple one, by all means, do so).
~Kitsune Zeta
- Rosstin
- Veteran
- Posts: 368
- Joined: Mon Jan 31, 2011 5:43 pm
- Completed: Rex Rocket, Kitty Love, King's Ascent
- Projects: Road Redemption, Queen At Arms
- Organization: Aqualuft Games
- Contact:
Re: Defining and calling user-defined functions?
Sorry to keep buggin' you-- I'm learning though. I've got a pretty kicking little demo of my battle system up.
I'm trying to figure out if there's a way to include multiple possibilities as triggers for an if statement right now.
IE: right now I have this little thing
Later the character gets an attack named "brassknuckle" which is nearly identical. So I want to say...
Of course, that doesn't execute properly. Is there a way to do this without working around it? I figure at some point I will want to be able to use || type of statements.
I guess, like you were saying, I should probably just be working in straight python more.
I'm trying to figure out if there's a way to include multiple possibilities as triggers for an if statement right now.
IE: right now I have this little thing
Code: Select all
if moll_currentattack is "facepunch":
(do stuff)
Code: Select all
if moll_currentattack is "facepunch" or "brassknuckle":
(do stuff)
I guess, like you were saying, I should probably just be working in straight python more.
- SleepKirby
- Veteran
- Posts: 255
- Joined: Mon Aug 09, 2010 10:02 pm
- Projects: Eastern Starlight Romance, Touhou Mecha
- Organization: Dai-Sukima Dan
- Location: California, USA
- Contact:
Re: Defining and calling user-defined functions?
Does that work if you make itasterazul wrote:Code: Select all
if moll_currentattack is "facepunch" or "brassknuckle": (do stuff)
Code: Select all
if moll_currentattack is "facepunch" or moll_currentattack is "brassknuckle":
My thinking is that "brassknuckle" alone can't be an operand to a boolean operator like or.
Also, if you want to experiment with Python more, you could download a Python shell. You may be able to test simple Python code much more quickly this way, as opposed to having to run and re-run Ren'Py. More details here: http://lemmasoft.renai.us/forums/viewto ... 79#p117179
- KeyboardSan
- Regular
- Posts: 26
- Joined: Sun Oct 05, 2014 5:38 am
- Completed: A Sweet Meeting, SRZ, Flower Field
- Contact:
Re: Defining and calling user-defined functions?
Hey, I have made a small battle engine. I guess you can put it in 'python:' block inn ren'py code but you have to do something else to print the messages. I hope it helps.
Code: Select all
import random #import files for random numbers
print("Battle System"); #print 'Battle System'
##########################################################
#define a player object
class player(object):
def __init__(self,name):
self.name = name;
self.health = 100;
self.power = 50;
self.xp = 20;
self.weapon = "fist";
self.luck = 2;
##########################################################
#define a monster object
class monster(object):
def __init__(self,health,power,name,luck):
self.name = name;
self.health = health;
self.power = power;
self.luck = luck;
###########################################################
#create a function for a battle to happen between player and monster
def battle(pl,mon):
while(mon.health>0): #battle loop while monster remains alive
print("What will you do?"); #print message
print("1.Attack 2.Do nothing"); #print choices
x = input(">"); #take input
if(x==1): #check choices if choice is to attack then>
print("You used "+pl.weapon+" to attack the "+mon.name+"."); #print a message
#now in this if statement I am just using my own method to check the
#luck of the frog. You can use anyother method to check it :)
if(random.randint(0,(20-mon.luck))<7): #check luck
print(mon.name+" dodged your attack."); #monster dodged
else:
print(mon.name+" is hit."); #monster is hit
mon.health-=pl.power/mon.luck; #decrease monster's health
if(mon.health<=0): #check if monster has died due to attack
print(mon.name+" died");
break; #break the while loop if monster has died
else: #else if choice is to do nothing or anything else then>
print("You stood and did nothing");
print(mon.name+" attacked you."); #now monster is attacking it will
#always attack you no checking required. ;)
if(random.randint(0,(20-pl.luck))<7):#checking player's luck
print("You dodged.");
else:
print("You are hit.");
pl.health-=mon.power; #if hit then reduce player's health
if(pl.health<=0): #check to see if player has died
print("You died.");
break; #if player has died then break the while loop
#######################################################
#create a player object. I named my player 'law'
law = player("law"); #player(self,name)
#create a monster object. I created a frog
frog = monster(30,20,"frog",2); #monster(self,health,power,name,luck)
print("Would you like to battle?"); #print message
print("1.Yes 2.No"); #print choices
x = input(">"); #take input from user
if(x==1): #check input
print("Battle begins!");
battle(law,frog); #battle begins function is called if choice is 1.
else:
print("No battle happens."); #no battle happens if choice is something else
#############################################################
Who is online
Users browsing this forum: No registered users