Learning pySFML from a C++ SFML background¶
Naming convention¶
This module follows the style guide for Python code as much as possible. To give you an idea, here is a list of attribute naming examples:
- Classes:
RenderWindow
,Texture
. - Methods and attributes:
default_view
,load_from_file()
. - Constants:
CLOSED
,KEY_PRESSED
,BLEND_ALPHA
.
Namespaces normally follow the same nesting as in C++,
e.g. sf::Event::Closed
becomes sfml.Event.CLOSED
. Events
are an exception, see Events.
Object initialization with class methods¶
C++ SFML has a general pattern for creating objects when their initialization may fail:
- Allocate an “empty” object.
- Call a method that will initialize the object, e.g.
loadFromFile()
. - If this method returned
false
, handle the error.
In pySFML, you typically just have to call a class method,
e.g. Texture.load_from_file()
. If you want to handle possible
errors at this point, you write an except
block (see
Error handling). Otherwise, the exception will propagate
to the next handler.
In some cases, class methods are the only way to initialize an
object. In that case, the constructor will raise
NotImplementedError
if you call it. In other cases, the
constructors peform some kind of default initialization, while class
methods do more specific work.
Properties¶
Generally speaking, set*()/get*()
methods are replaced by
properties. For example,
RenderWindow.getSize()/RenderWindow.setSize()
becomes a
RenderWindow.size
property which behaves like a normal
attribute. I tend to create properties when the user can safely ignore
that he’s not dealing with an actual attribute, i.e. when the property
doesn’t do anything non-obvious and is fast to execute.
In some cases, it’s not that straightforward. Some properties only
have a getter or a setter, even though they should have both (for
example, RenderWindow.key_repeat_enabled
). The reason is that
C++ SFML doesn’t provide the missing set/get method. This has been
pointed out to SFML’s author, who is going to fix it someday. I could
fix it myself, but it would require to add quite a lot of boilerplate
that I will need to remove when SFML gets the missing methods. The
reason why these methods are missing in the first place is that’s
they’re not very useful, so I consider that to be a decent trade-off.
I tend to use a method instead of an attribute when I feel like a
get*()
method involves some kind of computation. For example,
View.get_inverse_transform()
is a method instead of a property
because I somehow feel like it involves something heavier than simply
looking up an attribute. Admittedly, this is subjective, and it’s
difficult to be consistent with this kind of choice as well.
Events¶
pySFML objects only feature the attributes that they actually
need. For example, event.key.code
in C++ becomes event.code
.
Accessing an attribute that doesn’t make sense for this event will
raise an exception, because the object event doesn’t have it at all.
As you can see in the Event types reference, there is some
overlap, so theoretically you could confuse a MOUSE_WHEEL_MOVED
event for a MOUSE_MOVED
event, access the x
or y
attribute, without raising any exception.
Instead of using RenderWindow.poll_event()
, events are usually
retrieved in for
loop with RenderWindow.iter_event()
:
for event in window.iter_events():
if event.type == sfml.Event.CLOSED:
...
Error handling¶
Unlike C++ SFML, there are no boolean return values to indicate
success or failure. Anytime SFML returns False
, typically, when a
file can’t be opened, pySFML raises PySFMLException
. Please
read the description of this exception for more information.
I’d like to add more specific exceptions, but since SFML only returns
True
or False
, I can’t tell if the source of the failure is a
non existant file, an invalid file content, an internal library
failure, or anything else. SFML’s author wants to improve error
handling in a future release. At this point, more specific exceptions
will probably be possible to implement.
Creating your own drawables¶
Unlike in C++ SFML, you don’t have to inherit a Drawable
class. This is covered in Creating your own
drawables.
Time¶
Time values are created with Time
‘s constructor using keyword
arguments, instead of calling a global function. For example,
sf::milliseconds(200)
becomes sfml.Time(milliseconds=200)
.
“Missing” features¶
Vector2f
has been ported, but tuples are used instead of
Vector2i
and Vector3f
. These classes are used so sparsely that
it doesn’t seem worth porting them. Note that you can pass tuples
instead of Vector2f
objects.
The network and threading parts of SFML aren’t ported in this module,
since similar features are already provided by the standard library.
For UDP and TCP connections, you should look into the socket
module. threading
is the general, high-level module for threading
stuff. For URL retrieval, urllib
and urllib2
are provided.
You may also want to check out non standard libraries such as Twisted or requests.
Most streaming features are also currently missing.