[Ok, I warn first, I really risk to be really grumpy... So, I'll start by a big "what the fucking fuck", and hope it will calm me enough.]
I'll come back on your question below, but first this person is teaching something that she clearly don't know. If she've even read the documentation, she clearly haven't understood it ; but my guess is that she never read it.
Do
not learn through her tutorials. I'm sure that she have only good intentions, and I recognize her one thing, I like the way she solve her problems. But, because there's a really big "but", it's also problem that she created by herself due to her lack of knowledge regarding Ren'Py ; she's going for a very long screen that should need a dozen of lines or something like this.
In no specific order:
- She rely on two variables, one for the idle icon, one for the hover icon.
Ren'Py
You must be registered to see the links
documentation:
auto
Used to automatically define the images used by this button. This should be a string that contains %s in it. If it is, and one of the image properties is omitted, %s is replaced with the name of that property, and the value is used as the default for that property.
- She's adding an
index
attribute to each entry in the list !!!
Python:
for i in range( 0, grid_size): # the 0 is implicit in her code
list.append( [...]
list[-1].index = i
What is the interest to give an index value to something that is already indexed since put in a list ? You want to know what is the index of an entry of your list ? Assuming that this entry is temporarily stored in a variable named "whatever", just write this: index = list.index( whatever )
.
No need for an attribute for this.
- She declared the screen with
screen nameOfTheScreen:
.
I can't quickly find it back in the documentation, but it's clearly said that, a screen have to be declared with an arguments list even if there's no arguments ; therefore screen nameOfTheScreen():
.
This for backward compatibility reasons (so it can change with the 8.x branch). Without the arguments list, Ren'Py will not proceed the screen in the best way, and since they are Ren'Py's bottleneck, it's really not something you want for your game.
- What she's doing in the "setup_icons" label should be done in an init block.
It's constant values, they'll not change during the game, and they have absolutely no reason to be saved.
- Positive point, she realized mid tutorial that what she initially did wouldn't works.
She started to declare the icons using the "icons/[randValue].png"
form, that wouldn't works the way she deal with the icons. Then she change it into "icons/{}.png".format( randValue )
, that works the way she deal with the icons.
- She create her constants in the "start" label.
Code:
label start:
$ grid_size = 100
$ icon_size = 50
[...]
She should have use define
instead (since it's constants).
Code:
define grid_size = 100
define icon_size = 50
- She don't know that the
You must be registered to see the links
screen statement exist.
She put on her screen:
Code:
for i in range( grid_size ):
$ xp = [computation]
$ yp = [computation]
image "whatever" xpos xp ypos yp
python:
if [row overflowing condition]:
[pass to the next row]
The exact same could have been done with:
Code:
grid 10 10:
for i in range( 0, 100 ):
image "whatever"
- She use a screen statement outdated since I don't even know how many years but it's more than 5.
She used image
, this statement have been removed from the documentation years ago, and replaced by
You must be registered to see the links
. It still works because Ren'Py is good at backward compatibility, but it doesn't mean that one should use it ; I'm not sure that the 8.x branch will effectively by backward compatible back to the first version of the screen language.
Well, I'll not do it all, there's nothing right in the two parts of her tutorial that I watched.
The screen she's building should be limited to those lines:
Code:
screen sameGame():
grid 10 10:
for i in range( 0, 100 ):
fixed:
add "background image for the cell"
if tileMap:
imagebutton:
auto "icons/[i]_%s.png"
action [whatever]
It need a bit more to effectively reach the behavior she's trying to have, but I guess that something like this should be near to do it:
Now for your question...
In Python, everything is an object, and objects have attributes. So far, it's like most Object Oriented Languages.
But Python add a particularity, objects are not static, they are dynamic. You can at anytime change their behavior by updating their definition. Not at class level, but really at object level.
And it's what she's doing here. She's just adding two attributes to the "Transform" object she created one line ago.
Demonstration code:
Python:
label start:
$ regList = [ "a", "b", "c" ]
$ altList = [ "d", "e", "f" ]
$ altList.pickaboo = "Boo !"
if not hasattr( regList, "pickaboo" ):
"No, this is a regular list, it don't have an extra attribute."
$ t = type( regList )
"Type of regList is [t]"
if hasattr( altList, "pickaboo" ):
"[altList.pickaboo]"
$ t = type( altList )
"Type of altList is [t]"
$ altList.pickaboo = "Bee"
if altList.pickaboo == "Bee":
"Is it a 'pickabee' now ?"
"END"
Both list have the same type (a subclass of
list
defined by Ren'Py), but only one have an extra attribute. And this extra attribute can be addressed like any other attribute can.
Edit: Sorry, the list mess with the formatting in code blocks
Second Edit: Noticed a small typo in the full game code.