# Examples

- Ftp

- Pong

- PyQt4

- Shader

- Sockets

- Sound capture

- Sound

- Voip

- Embedding

- Extending

- Spacial Music

If you downloaded a source archive or cloned pySFML from github, these examples will be located in the examples subdirectory of the project’s root. A package named ‘pysfml-examples’ is also available for Debian-based Linux distributions, which allows you to run arbitrary examples by invoking a command of the following form from a terminal:

    pysfml-<example name>

For example:

    pysfml-sound

## Ftp

      1import os
      2import sfml.network as sf
      3
      4# python 2.* compatability
      5try: input = raw_input
      6except NameError: pass
      7
      8# choose the server address
      9address = input("Enter the FTP server address: ")
     10address = sf.IpAddress.from_string(address)
     11
     12# create the server object which with you will communicate
     13server = sf.Ftp()
     14
     15# connect to the server
     16response = server.connect(address)
     17print(response)
     18if not response.ok: exit()
     19
     20# ask for user name and password
     21user = input("User name: ")
     22password = input("Password: ")
     23
     24# login to the server
     25response = server.login(user, password)
     26print(response)
     27if not response.ok: exit()
     28
     29# main menu
     30choice = 0
     31while True:
     32    print("===========================================================")
     33    print("Choose an action:")
     34    print("1. Print working directory")
     35    print("2. Print contents of working directory")
     36    print("3. Change directory")
     37    print("4. Create directory")
     38    print("5. Delete directory")
     39    print("6. Rename file")
     40    print("7. Remove file")
     41    print("8. Download file")
     42    print("9. Upload file")
     43    print("0. Disconnect\n\n")
     44
     45    choice = int(input("Your choice: "))
     46
     47    os.system('clear')
     48
     49    if choice == 1:
     50        # print the current server directory
     51        response = server.get_working_directory()
     52        print(response)
     53        print("Current directory is {0}".format(response.get_directory()))
     54    elif choice == 2:
     55        # print the contents of the current server directory
     56        response = server.get_directory_listing()
     57        print(response)
     58        for filename in response.filenames:
     59            print(filename)
     60    elif choice == 3:
     61        # change the current directory
     62        directory = input("Choose a directory: ")
     63        response = server.change_directory(directory)
     64        print(response)
     65    elif choice == 4:
     66        # create a new directory
     67        directory = input("Name of the directory to create: ")
     68        response = server.create_directory(directory)
     69        print(response)
     70    elif choice == 5:
     71        # remove an existing directory
     72        directory = input("Name of the directory to remove: ")
     73        response = server.delete_directory(directory)
     74        print(response)
     75    elif choice == 6:
     76        # rename a file
     77        source = input("Name of the file to rename: ")
     78        destination = input("New name: ")
     79        response = server.rename_file(source, destination)
     80        print(response)
     81    elif choice == 7:
     82        # remove an existing directory
     83        filename = input("Name of the file to remove: ")
     84        response = server.delete_file(filename)
     85        print(response)
     86    elif choice == 8:
     87        # download a file from server
     88        filename = input("Filename of the file to download (relative to current directory): ")
     89        directory = input("Directory to download the file to: ")
     90        response = server.download(filename, directory)
     91        print(response)
     92    elif choice == 9:
     93        # upload a file to server
     94        filename = input("Path of the file to upload (absolute or relative to working directory): ")
     95        directory = input("Directory to upload the file to (relative to current directory): ")
     96        response = server.upload(filename, directory)
     97        print(response)
     98    elif choice == 0:
     99        break
    100    else:
    101        # wrong choice
    102        print("Invalid choice!")
    103        os.system('clear')
    104
    105    if choice == 0:
    106        break
    107
    108# disconnect from the server
    109print("Disconnecting from server...")
    110response = server.disconnect()
    111
    112# wait until the user presses 'enter' key
    113input("Press enter to exit...")

## Pong

      1from __future__ import division
      2
      3from math import cos, sin, fabs, pi
      4from random import randint
      5
      6from sfml import sf
      7
      8
      9# define some constants
     10game_size = sf.Vector2(800, 600)
     11paddle_size = sf.Vector2(25, 100)
     12ball_radius = 10.
     13
     14# create the window of the application
     15w, h = game_size
     16window = sf.RenderWindow(sf.VideoMode(w, h), "pySFML - Pong")
     17window.vertical_synchronization = True
     18
     19# load the sounds used in the game
     20ball_sound_buffer = sf.SoundBuffer.from_file("data/ball.wav")
     21ball_sound = sf.Sound(ball_sound_buffer)
     22
     23# create the left paddle
     24left_paddle = sf.RectangleShape()
     25left_paddle.size = paddle_size - (3, 3)
     26left_paddle.outline_thickness = 3
     27left_paddle.outline_color = sf.Color.BLACK
     28left_paddle.fill_color = sf.Color(100, 100, 200)
     29left_paddle.origin = paddle_size / 2
     30
     31# create the right paddle
     32right_paddle = sf.RectangleShape()
     33right_paddle.size = paddle_size - (3, 3)
     34right_paddle.outline_thickness = 3
     35right_paddle.outline_color = sf.Color.BLACK
     36right_paddle.fill_color = sf.Color(200, 100, 100)
     37right_paddle.origin = paddle_size / 2
     38
     39# create the ball
     40ball = sf.CircleShape()
     41ball.radius = ball_radius - 3
     42ball.outline_thickness = 3
     43ball.outline_color = sf.Color.BLACK
     44ball.fill_color = sf.Color.WHITE
     45ball.origin = (ball_radius / 2, ball_radius / 2)
     46
     47# load the font
     48font = sf.Font.from_file("data/sansation.ttf")
     49
     50# initialize the pause message
     51pause_message = sf.Text()
     52pause_message.font = font
     53pause_message.character_size = 40
     54pause_message.position = (170, 150)
     55pause_message.color = sf.Color.WHITE
     56pause_message.string = "Welcome to pySFML pong!\nPress space to start the game"
     57
     58# define the paddles properties
     59ai_timer = sf.Clock()
     60ai_time = sf.seconds(0.1)
     61paddle_speed = 400.
     62right_paddle_speed = 0.
     63ball_speed = 400.
     64ball_angle = 0. # to be changed later
     65
     66clock = sf.Clock()
     67is_playing = False
     68
     69while window.is_open:
     70
     71    # handle events
     72    for event in window.events:
     73        # window closed or escape key pressed: exit
     74        if type(event) is sf.CloseEvent:
     75            window.close()
     76
     77        # space key pressed: play
     78        if type(event) is sf.KeyEvent and event.pressed and event.code is sf.Keyboard.SPACE:
     79            if not is_playing:
     80                # (re)start the game
     81                is_playing = True
     82                clock.restart()
     83
     84                # reset the position of the paddles and ball
     85                left_paddle.position = (10 + paddle_size.x / 2, game_size.y / 2)
     86                right_paddle.position = (game_size.x - 10 - paddle_size.x / 2, game_size.y / 2)
     87                ball.position = game_size / 2
     88
     89                # reset the ball angle
     90                while True:
     91                    # make sure the ball initial angle is not too much vertical
     92                    ball_angle = (randint(0, 32767) % 360) * 2 * pi / 360
     93                    if not fabs(cos(ball_angle)) < 0.7: break
     94
     95    if is_playing:
     96        delta_time = clock.restart().seconds
     97
     98        # move the player's paddle
     99        if sf.Keyboard.is_key_pressed(sf.Keyboard.UP) and left_paddle.position.y - paddle_size.y / 2 > 5:
    100            left_paddle.move((0, -paddle_speed * delta_time))
    101
    102        elif sf.Keyboard.is_key_pressed(sf.Keyboard.DOWN) and left_paddle.position.y + paddle_size.y / 2 < game_size.y - 5:
    103            left_paddle.position += (0, paddle_speed * delta_time)
    104
    105        # move the computer' paddle
    106        if (right_paddle_speed < 0 and right_paddle.position.y - paddle_size.x / 2 > 5) or (right_paddle_speed > 0 and right_paddle.position.y + paddle_size.y / 2 < game_size.y - 5):
    107            right_paddle.position += (0, right_paddle_speed * delta_time)
    108
    109
    110        # update the computer's paddle direction according to the ball position
    111        if ai_timer.elapsed_time > ai_time:
    112            ai_timer.restart()
    113            if ball.position.y + ball_radius > right_paddle.position.y + paddle_size.y / 2:
    114                right_paddle_speed = paddle_speed
    115            elif ball.position.y - ball_radius < right_paddle.position.y - paddle_size.y / 2:
    116                right_paddle_speed = - paddle_speed
    117            else:
    118                right_paddle_speed = 0
    119
    120        # move the ball
    121        factor = ball_speed * delta_time
    122        ball.move((cos(ball_angle) * factor, sin(ball_angle) * factor))
    123
    124        # check collisions between the ball and the screen
    125        if ball.position.x - ball_radius < 0:
    126            is_playing = False
    127            pause_message.string = "You lost!\nPress space to restart or\nescape to exit"
    128
    129        if ball.position.x + ball_radius > game_size.x:
    130            is_playing = False
    131            pause_message.string = "You won !\nPress space to restart or\nescape to exit"
    132
    133        if ball.position.y - ball_radius < 0:
    134            ball_sound.play()
    135            ball_angle = - ball_angle
    136            ball.position.y = ball_radius + 0.1
    137
    138        if ball.position.y + ball_radius > game_size.y:
    139            ball_sound.play()
    140            ball_angle = - ball_angle
    141            ball.position.y = game_size.y - ball_radius - 0.1
    142
    143        # check the collisions between the ball and the paddles
    144        # left paddle
    145        if ball.position.x - ball_radius < left_paddle.position.x + paddle_size.x / 2 and ball.position.x - ball_radius > left_paddle.position.x and ball.position.y + ball_radius >= left_paddle.position.y - paddle_size.y / 2 and ball.position.y - ball_radius <= left_paddle.position.y + paddle_size.y / 2:
    146            if ball.position.y > left_paddle.position.y:
    147                ball_angle = pi - ball_angle + (randint(0, 32767) % 20) * pi / 180
    148            else:
    149                ball_angle = pi - ball_angle - (randint(0, 32767) % 20) * pi / 180
    150
    151            ball_sound.play()
    152            ball.position = (left_paddle.position.x + ball_radius + paddle_size.x / 2 + 0.1, ball.position.y)
    153
    154        # right paddle
    155        if ball.position.x + ball_radius > right_paddle.position.x - paddle_size.x / 2 and ball.position.x + ball_radius < right_paddle.position.x and ball.position.y + ball_radius >= right_paddle.position.y - paddle_size.y / 2 and ball.position.y - ball_radius <= right_paddle.position.y + paddle_size.y / 2:
    156            if ball.position.y > right_paddle.position.y:
    157                ball_angle = pi - ball_angle + (randint(0, 32767) % 20) * pi / 180
    158            else:
    159                ball_angle = pi - ball_angle - (randint(0, 32767) % 20) * pi / 180
    160
    161            ball_sound.play()
    162            ball.position = (right_paddle.position.x - ball_radius - paddle_size.x / 2 - 0.1, ball.position.y)
    163
    164    window.clear(sf.Color(50, 200, 50))
    165
    166    if is_playing:
    167        # draw the paddles and the ball
    168        window.draw(left_paddle)
    169        window.draw(right_paddle)
    170        window.draw(ball)
    171
    172    else:
    173        # draw the pause message
    174        window.draw(pause_message)
    175
    176    # display things on screen
    177    window.display()

## PyQt4

     1import sys, platform
     2
     3try:
     4    import sip
     5    from PyQt4.QtCore import *
     6    from PyQt4.QtGui import *
     7except ImportError:
     8    print("Install PyQt4 and sip from Riverbank.")
     9
    10from sfml import sf
    11
    12
    13class QSFMLCanvas(QWidget):
    14    def __init__(self, parent, position, size, frameTime=0):
    15        QWidget.__init__(self, parent)
    16        self.initialized = False
    17
    18        w = size.width()
    19        h = size.height()
    20
    21        self._HandledWindow = sf.HandledWindow()
    22        self._HandledWindow.view.size = (w, h)
    23        self.__dict__['draw'] = self._HandledWindow.draw
    24        self.__dict__['clear'] = self._HandledWindow.clear
    25        self.__dict__['view'] = self._HandledWindow.view
    26        self.__dict__['display'] = self._HandledWindow.display
    27
    28        # setup some states to allow direct rendering into the widget
    29        self.setAttribute(Qt.WA_PaintOnScreen)
    30        self.setAttribute(Qt.WA_OpaquePaintEvent)
    31        self.setAttribute(Qt.WA_NoSystemBackground)
    32
    33        # set strong focus to enable keyboard events to be received
    34        self.setFocusPolicy(Qt.StrongFocus);
    35
    36        # setup the widget geometry
    37        self.move(position);
    38        self.resize(size);
    39
    40        # setup the timer
    41        self.timer = QTimer()
    42        self.timer.setInterval(frameTime)
    43
    44    def onInit(self): pass
    45
    46    def onUpdate(self): pass
    47
    48    def sizeHint(self):
    49        return self.size()
    50
    51    def paintEngine(self):
    52        # let the derived class do its specific stuff
    53        self.onUpdate()
    54
    55        # display on screen
    56        self.display()
    57
    58    def showEvent(self, event):
    59        if not self.initialized:
    60            # under X11, we need to flush the commands sent to the server
    61            # to ensure that SFML will get an updated view of the windows
    62            # create the SFML window with the widget handle
    63            if platform.system() == 'Linux':
    64                from ctypes import cdll
    65                x11 = cdll.LoadLibrary("libX11.so")
    66
    67                display = sip.unwrapinstance(QX11Info.display())
    68                x11.XFlush(display)
    69
    70            self._HandledWindow.create(self.winId())
    71
    72            # let the derived class do its specific stuff
    73            self.onInit()
    74
    75            # setup the timer to trigger a refresh at specified framerate
    76            self.connect(self.timer,SIGNAL('timeout()'), self, SLOT('repaint()'))
    77            self.timer.start()
    78
    79            self.initialized = True
    80
    81    def paintEvent(self, event):
    82        return None

## Shader

      1from __future__ import division
      2
      3from random import randint
      4from math import cos
      5
      6from sfml import sf
      7
      8class Effect(sf.Drawable):
      9    def __init__(self, name):
     10        sf.Drawable.__init__(self)
     11
     12        self._name = name
     13        self.is_loaded = False
     14
     15    def _get_name(self):
     16        return self._name
     17
     18    def load(self):
     19        self.is_loaded = sf.Shader.is_available() and self.on_load()
     20
     21    def update(self, time, x, y):
     22        if self.is_loaded:
     23            self.on_update(time, x, y)
     24
     25    def draw(self, target, states):
     26        if self.is_loaded:
     27            self.on_draw(target, states)
     28        else:
     29            error = sf.Text("Shader not\nsupported")
     30            error.font = sf.Font.from_file("data/sansation.ttf")
     31            error.position = (320, 200)
     32            error.character_size = 36
     33            target.draw(error, states)
     34
     35    name = property(_get_name)
     36
     37class Pixelate(Effect):
     38    def __init__(self):
     39        Effect.__init__(self, 'pixelate')
     40
     41    def on_load(self):
     42        try:
     43            # load the texture and initialize the sprite
     44            self.texture = sf.Texture.from_file("data/background.jpg")
     45            self.sprite = sf.Sprite(self.texture)
     46
     47            # load the shader
     48            self.shader = sf.Shader.from_file(fragment="data/pixelate.frag")
     49            self.shader.set_parameter("texture")
     50
     51        except IOError as error:
     52            print("An error occured: {0}".format(error))
     53            exit(1)
     54
     55        return True
     56
     57    def on_update(self, time, x, y):
     58        self.shader.set_parameter("pixel_threshold", (x + y) / 30)
     59
     60    def on_draw(self, target, states):
     61        states.shader = self.shader
     62        target.draw(self.sprite, states)
     63
     64
     65class WaveBlur(Effect):
     66    def __init__(self):
     67        Effect.__init__(self, 'wave + blur')
     68
     69    def on_load(self):
     70        with open("data/text.txt") as file:
     71            self.text = sf.Text(file.read())
     72            self.text.font = sf.Font.from_file("data/sansation.ttf")
     73            self.text.character_size = 22
     74            self.text.position = (30, 20)
     75
     76        try:
     77            # load the shader
     78            self.shader = sf.Shader.from_file("data/wave.vert", "data/blur.frag")
     79
     80        except IOError as error:
     81            print("An error occured: {0}".format(error))
     82            exit(1)
     83
     84        return True
     85
     86    def on_update(self, time, x, y):
     87        self.shader.set_parameter("wave_phase", time)
     88        self.shader.set_parameter("wave_amplitude", x * 40, y * 40)
     89        self.shader.set_parameter("blur_radius", (x + y) * 0.008)
     90
     91    def on_draw(self, target, states):
     92        states.shader = self.shader
     93        target.draw(self.text, states)
     94
     95
     96class StormBlink(Effect):
     97    def __init__(self):
     98        Effect.__init__(self, 'storm + blink')
     99
    100        self.points = sf.VertexArray()
    101
    102    def on_load(self):
    103        # create the points
    104        self.points.primitive_type = sf.PrimitiveType.POINTS
    105
    106        for i in range(40000):
    107            x = randint(0, 32767) % 800
    108            y = randint(0, 32767) % 600
    109            r = randint(0, 32767) % 255
    110            g = randint(0, 32767) % 255
    111            b = randint(0, 32767) % 255
    112            self.points.append(sf.Vertex(sf.Vector2(x, y), sf.Color(r, g, b)))
    113
    114        try:
    115            # load the shader
    116            self.shader = sf.Shader.from_file("data/storm.vert", "data/blink.frag")
    117
    118        except IOError as error:
    119            print("An error occured: {0}".format(error))
    120            exit(1)
    121
    122        return True
    123
    124    def on_update(self, time, x, y):
    125        radius = 200 + cos(time) * 150
    126        self.shader.set_parameter("storm_position", x * 800, y * 600)
    127        self.shader.set_parameter("storm_inner_radius", radius / 3)
    128        self.shader.set_parameter("storm_total_radius", radius)
    129        self.shader.set_parameter("blink_alpha", 0.5 + cos(time*3) * 0.25)
    130
    131    def on_draw(self, target, states):
    132        states.shader = self.shader
    133        target.draw(self.points, states)
    134
    135class Edge(Effect):
    136    def __init__(self):
    137        Effect.__init__(self, "edge post-effect")
    138
    139    def on_load(self):
    140        # create the off-screen surface
    141        self.surface = sf.RenderTexture(800, 600)
    142        self.surface.smooth = True
    143
    144        # load the textures
    145        self.background_texture = sf.Texture.from_file("data/sfml.png")
    146        self.background_texture.smooth = True
    147
    148        self.entity_texture = sf.Texture.from_file("data/devices.png")
    149        self.entity_texture.smooth = True
    150
    151        # initialize the background sprite
    152        self.background_sprite = sf.Sprite(self.background_texture)
    153        self.background_sprite.position = (135, 100)
    154
    155        # load the moving entities
    156        self.entities = []
    157
    158        for i in range(6):
    159            sprite = sf.Sprite(self.entity_texture, (96 * i, 0, 96, 96))
    160            self.entities.append(sprite)
    161
    162        # load the shader
    163        self.shader = sf.Shader.from_file(fragment="data/edge.frag")
    164        self.shader.set_parameter("texture")
    165
    166        return True
    167
    168    def on_update(self, time, x, y):
    169        self.shader.set_parameter("edge_threshold", 1 - (x + y) / 2)
    170
    171        # update the position of the moving entities
    172        for i, entity in enumerate(self.entities):
    173            x = cos(0.25 * (time * i + (len(self.entities) - i))) * 300 + 350
    174            y = cos(0.25 * (time * (len(self.entities) - i) + i)) * 200 + 250
    175            entity.position = (x, y)
    176
    177        # render the updated scene to the off-screen surface
    178        self.surface.clear(sf.Color.WHITE)
    179        self.surface.draw(self.background_sprite)
    180
    181        for entity in self.entities:
    182            self.surface.draw(entity)
    183
    184        self.surface.display()
    185
    186    def on_draw(self, target, states):
    187        states.shader = self.shader
    188        target.draw(sf.Sprite(self.surface.texture), states)
    189
    190
    191if __name__ == "__main__":
    192    # create the main window
    193    window = sf.RenderWindow(sf.VideoMode(800, 600), "pySFML - Shader")
    194    window.vertical_synchronization = True
    195
    196    # create the effects
    197    effects = (Pixelate(), WaveBlur(), StormBlink(), Edge())
    198    current = 0
    199
    200    # initialize them
    201    for effect in effects: effect.load()
    202
    203    # create the message background
    204    try:
    205        text_background_texture = sf.Texture.from_file("data/text-background.png")
    206
    207    except IOError as error:
    208        print("An error occured: {0}".format(error))
    209        exit(1)
    210
    211    text_background = sf.Sprite(text_background_texture)
    212    text_background.position = (0, 520)
    213    text_background.color = sf.Color(255, 255, 255, 200)
    214
    215    # load the messages font
    216    try:
    217        font = sf.Font.from_file("data/sansation.ttf")
    218
    219    except IOError as error:
    220        print("An error occured: {0}".format(error))
    221        exit(1)
    222
    223    # create the description text
    224    description = sf.Text("Current effect: {0}".format(effects[current].name), font, 20)
    225    description.position = (10, 530)
    226    description.color = sf.Color(80, 80, 80)
    227
    228    # create the instructions text
    229    instructions = sf.Text("Press left and right arrows to change the current shader", font, 20)
    230    instructions.position = (280, 555)
    231    instructions.color = sf.Color(80, 80, 80)
    232
    233    clock = sf.Clock()
    234
    235    # start the game loop
    236    while window.is_open:
    237
    238        # update the current example
    239        x, y = sf.Mouse.get_position(window) / window.size
    240        effects[current].update(clock.elapsed_time.seconds, x, y)
    241
    242        # process events
    243        for event in window.events:
    244
    245            # close window: exit
    246            if type(event) is sf.CloseEvent:
    247                window.close()
    248
    249            if type(event) is sf.KeyEvent and event.pressed:
    250                # escapte key: exit
    251                if event.code == sf.Keyboard.ESCAPE:
    252                    window.close()
    253
    254                # left arrow key: previous shader
    255                elif event.code is sf.Keyboard.LEFT:
    256                    if current == 0: current = len(effects) - 1
    257                    else: current -= 1
    258
    259                    description.string = "Current effect: {0}".format(effects[current].name)
    260
    261                # right arrow key: next shader
    262                elif event.code is sf.Keyboard.RIGHT:
    263                    if current == len(effects) - 1: current = 0
    264                    else: current += 1
    265
    266                    description.string = "Current effect: {0}".format(effects[current].name)
    267
    268
    269        # clear the window
    270        window.clear(sf.Color(255, 128, 0))
    271
    272        # draw the current example
    273        window.draw(effects[current])
    274
    275        # draw the text
    276        window.draw(text_background)
    277        window.draw(instructions)
    278        window.draw(description)
    279
    280        # finally, display the rendered frame on screen
    281        window.display()

## Sockets

      1import sfml.network as sf
      2
      3# python 2.* compatability
      4try: input = raw_input
      5except NameError: pass
      6
      7def run_tcp_server():
      8    """ Launch a server. The server waits for an incoming connection,
      9    sends a message and waits for the answer. """
     10
     11    try:
     12        # create a server socket to accept new connections
     13        listener = sf.TcpListener()
     14
     15        # listen to the given port for incoming connections
     16        listener.listen(PORT)
     17
     18        print("Server is listening to port {0}, waiting for connections...".format(PORT))
     19
     20        # wait for a connection
     21        socket = listener.accept()
     22        print("Client connected: {0}".format(socket.remote_address))
     23
     24        # send a message to the connected client
     25        message = "Hi, I'm the server"
     26        socket.send(message.encode('utf-8'))
     27        print("Message sent to the client: {0}".format(message))
     28
     29        # recieve a message back from the client
     30        answer = socket.receive(128).decode('utf-8')
     31        print("Answer received from the client: {0}".format(answer))
     32
     33    except sf.SocketException as error:
     34        print("An error occured!")
     35        print(error)
     36        return
     37
     38def run_tcp_client():
     39    """ Create a client. The client is connected to a server, displays
     40    the welcome message and sends an answer. """
     41
     42    server = input("Type the address or name of the server to connect to: ")
     43    server = sf.IpAddress.from_string(server)
     44
     45    # create a socket for communicating with the server
     46    socket = sf.TcpSocket()
     47
     48    # connect to the server
     49    try:
     50        socket.connect(server, PORT)
     51        print("Connected to server {0}".format(server))
     52
     53        # receive a message from the server
     54        message = socket.receive(128).decode('utf-8')
     55        print("Message received from the server: {0}".format(message))
     56
     57        # send an answer to the server
     58        answer = "Hi, I'm a client"
     59        socket.send(answer.encode('utf-8'))
     60        print("Message sent to the server: {0}".format(answer))
     61
     62    except sf.SocketException as error:
     63        print("An error occured!")
     64        print(error)
     65        return
     66
     67def run_udp_server():
     68    """ Launch a server. The server waits for a message then sends an
     69    answer. """
     70
     71    # create a socket to receive a message from anyone
     72    socket = sf.UdpSocket()
     73
     74    try:
     75        # listen to messages on the specified port
     76        socket.bind(PORT)
     77        print("Server is listening to port {0}, waiting for message...".format(PORT))
     78
     79        # wait for a message
     80        message, ip, port = socket.receive(128)
     81        print("Message received from client {0}: {1}".format(ip, message.decode('utf-8')))
     82
     83        # send an answer to the client
     84        answer = "Hi, I'm the server"
     85        socket.send(answer.encode('utf-8'), ip, port)
     86        print("Message sent to the client: {0}".format(answer))
     87
     88    except sf.SocketException as error:
     89        print("An error occured!")
     90        print(error)
     91        return
     92
     93def run_udp_client():
     94    """ Send a message to the server, wait for the answer. """
     95
     96    # ask for the server address
     97    server = input("Type the address or name of the server to connect to: ")
     98    server = sf.IpAddress.from_string(server)
     99
    100    # create a socket for communicating with the server
    101    socket = sf.UdpSocket()
    102
    103    try:
    104        # send a message to the server
    105        message = "Hi, I'm a client"
    106        socket.send(message.encode('utf-8'), server, PORT)
    107        print("Message sent to the server: {0}".format(message))
    108
    109        # receive an answer from anyone (but most likely from the server)
    110        answer, ip, port = socket.receive(128)
    111        print("Message received from {0}: {1}".format(ip, answer.decode('utf-8')))
    112
    113    except sf.SocketException as error:
    114        print("An error occured!")
    115        print(error)
    116        return
    117
    118if __name__ == "__main__":
    119    # choose an arbitrary port for opening sockets
    120    PORT = 50001
    121
    122    # TCP or UDP ?
    123    print("Do you want to use TCP (t) or UDP (u) ?")
    124    protocol = input()
    125
    126    # client or server ?
    127    print("Do you want to be a server (s) or a client (c) ?")
    128    who = input()
    129
    130    if protocol == 't':
    131        if who == 's': run_tcp_server()
    132        else: run_tcp_client()
    133    else:
    134        if who == 's': run_udp_server()
    135        else: run_udp_client()
    136
    137    input("Press any key to exit...")

## Sound capture

     1from sfml import sf
     2
     3# python 2.* compatability
     4try: input = raw_input
     5except NameError: pass
     6
     7def main():
     8    # check that the device can capture audio
     9    if not sf.SoundRecorder.is_available():
    10        print("Sorry, audio capture is not supported by your system")
    11        return
    12
    13    # choose the sample rate
    14    sample_rate = int(input("Please choose the sample rate for sound capture (44100 is CD quality): "))
    15
    16    # wait for user input...
    17    input("Press enter to start recording audio")
    18
    19    # here we'll use an integrated custom recorder, which saves the captured data into a sf.SoundBuffer
    20    recorder = sf.SoundBufferRecorder()
    21
    22    # audio capture is done in a separate thread, so we can block the main thread while it is capturing
    23    recorder.start(sample_rate)
    24    input("Recording... press enter to stop")
    25    recorder.stop()
    26
    27    # get the buffer containing the captured data
    28    buffer = recorder.buffer
    29
    30    # display captured sound informations
    31    print("Sound information:")
    32    print("{0} seconds".format(buffer.duration))
    33    print("{0} samples / seconds".format(buffer.sample_rate))
    34    print("{0} channels".format(buffer.channel_count))
    35
    36    # choose what to do with the recorded sound data
    37    choice = input("What do you want to do with captured sound (p = play, s = save) ? ")
    38
    39    if choice == 's':
    40        # choose the filename
    41        filename = input("Choose the file to create: ")
    42
    43        # save the buffer
    44        buffer.to_file(filename);
    45    else:
    46        # create a sound instance and play it
    47        sound = sf.Sound(buffer)
    48        sound.play();
    49
    50        # wait until finished
    51        while sound.status == sf.Sound.PLAYING:
    52            # leave some CPU time for other threads
    53            sf.sleep(sf.milliseconds(100))
    54
    55    # finished !
    56    print("Done !")
    57
    58    # wait until the user presses 'enter' key
    59    input("Press enter to exit...")
    60
    61if __name__ == "__main__":
    62    main()

## Sound

     1from sfml import sf
     2
     3def play_sound():
     4    # load a sound buffer from a wav file
     5    buffer = sf.SoundBuffer.from_file("data/canary.wav")
     6
     7    # display sound informations
     8    print("canary.wav:")
     9    print("{0} seconds".format(buffer.duration))
    10    print("{0} samples / sec".format(buffer.sample_rate))
    11    print("{0} channels".format(buffer.channel_count))
    12
    13    # create a sound instance and play it
    14    sound = sf.Sound(buffer)
    15    sound.play();
    16
    17    # loop while the sound is playing
    18    while sound.status == sf.Sound.PLAYING:
    19        # leave some CPU time for other processes
    20        sf.sleep(sf.milliseconds(100))
    21
    22def play_music():
    23    # load an ogg music file
    24    music = sf.Music.from_file("data/orchestral.ogg")
    25
    26    # display music informations
    27    print("orchestral.ogg:")
    28    print("{0} seconds".format(music.duration))
    29    print("{0} samples / sec".format(music.sample_rate))
    30    print("{0} channels".format(music.channel_count))
    31
    32    # play it
    33    music.play();
    34
    35    # loop while the music is playing
    36    while music.status == sf.Music.PLAYING:
    37        # leave some CPU time for other processes
    38        sf.sleep(sf.milliseconds(100))
    39
    40if __name__ == "__main__":
    41    play_sound()
    42    play_music()
    43
    44    input("Press enter to exit...")

## Voip

     1from sfml import sf
     2import client, server
     3
     4# python 2.* compatability
     5try: input = raw_input
     6except NameError: pass
     7
     8# choose a random port for opening sockets (ports < 1024 are reserved)
     9PORT = 2435
    10
    11# client or server ?
    12print("Do you want to be a server (s) or a client (c) ?")
    13who = input()
    14
    15if who == 's':
    16    server.do_server(PORT)
    17else:
    18    client.do_client(PORT)
    19
    20input("Press any key to exit...")

     1from sfml import sf
     2from struct import pack
     3from random import randint
     4
     5# python 2.* compatability
     6try: input = raw_input
     7except NameError: pass
     8
     9AUDIO_DATA, END_OF_STREAM = list(range(1, 3))
    10
    11class NetworkRecorder(sf.SoundRecorder):
    12    def __init__(self, host, port):
    13        sf.SoundRecorder.__init__(self)
    14
    15        self.host = host # address of the remote host
    16        self.port = port # remote port
    17        self.socket = sf.TcpSocket() # socket used to communicate with the server
    18
    19    def on_start(self):
    20        try: self.socket.connect(self.host, self.port)
    21        except sf.SocketException as error: return False
    22
    23        return True
    24
    25    def on_process_samples(self, chunk):
    26        # pack the audio samples
    27        data = pack("B", AUDIO_DATA)
    28        data += pack("I", len(chunk.data))
    29        data += chunk.data
    30
    31        # send the audio packet
    32        try: self.socket.send(data)
    33        except sf.SocketException: return False
    34
    35        return True
    36
    37    def on_stop(self):
    38        # send a "end-of-stream" signal
    39        self.socket.send(bytes(END_OF_STREAM))
    40
    41        # close the socket
    42        self.socket.disconnect()
    43
    44def do_client(port):
    45    # check that the device can capture audio
    46    if not sf.SoundRecorder.is_available():
    47        print("Sorry, audio capture is not supported by your system")
    48        return
    49
    50    # ask for server address
    51    server = input("Type address or name of the server to connect to: ")
    52    server = sf.IpAddress.from_string(server)
    53
    54    # create an instance of our custom recorder
    55    recorder = NetworkRecorder(server, port)
    56
    57    # wait for the user input...
    58    input("Press enter to start recording audio")
    59
    60    # start capturing audio data
    61    recorder.start(44100)
    62    input("Recording... press enter to stop")
    63    recorder.stop()

      1import threading
      2from time import sleep
      3from sfml import sf
      4from struct import unpack
      5
      6# python 2.* compatability
      7try: input = raw_input
      8except NameError: pass
      9
     10AUDIO_DATA, END_OF_STREAM = list(range(1, 3))
     11
     12class NetworkAudioStream(sf.SoundStream):
     13    def __init__(self):
     14        sf.SoundStream.__init__(self)
     15
     16        self.offset = 0
     17        self.has_finished = False
     18        self.listener = sf.TcpListener()
     19        self.samples = sf.Chunk()
     20
     21        # set the sound parameters
     22        self.initialize(1, 44100)
     23
     24    def start(self, port):
     25        if not self.has_finished:
     26            try:
     27                # listen to the given port for incoming connections
     28                self.listener.listen(port)
     29                print("Server is listening to port {0}, waiting for connections... ".format(port))
     30
     31                # wait for a connection
     32                self.client = self.listener.accept()
     33                print("Client connected: {0}".format(self.client.remote_address))
     34
     35            except sf.SocketException: return
     36
     37            # start playback
     38            self.play()
     39
     40            # start receiving audio data
     41            self.receive_loop()
     42
     43        else:
     44            # start playback
     45            self.play()
     46
     47    def on_get_data(self, chunk):
     48        # we have reached the end of the buffer and all audio data have been played : we can stop playback
     49        if self.offset >= len(self.samples) and self.has_finished:
     50            return False
     51
     52        # no new data has arrived since last update : wait until we get some
     53        while self.offset >= len(self.samples) and not self.has_finished:
     54            sf.sleep(sf.milliseconds(10))
     55
     56        # don't forget to lock as we run in two separate threads
     57        lock = threading.Lock()
     58        lock.acquire()
     59
     60        # fill audio data to pass to the stream
     61        chunk.data = self.samples.data[self.offset*2:]
     62
     63        # update the playing offset
     64        self.offset += len(chunk)
     65
     66        lock.release()
     67
     68        return True
     69
     70    def on_seek(self, time_offset):
     71        self.offset = time_offset.milliseconds * self.sample_rate * self.channel_count // 1000
     72
     73    def receive_loop(self):
     74        lock = threading.RLock()
     75
     76        while not self.has_finished:
     77            # get waiting audio data from the network
     78            data = self.client.receive(1)
     79
     80            # extract the id message
     81            id = unpack("B", data)[0]
     82
     83            if id == AUDIO_DATA:
     84                # extract audio samples from the packet, and append it to our samples buffer
     85                data = self.client.receive(4)
     86                sample_count = unpack("I", data)[0]
     87
     88                samples = self.client.receive(sample_count)
     89
     90                # don't forget the other thread can access the sample array at any time
     91                lock.acquire()
     92                self.samples.data += samples
     93                lock.release()
     94
     95            elif id == END_OF_STREAM:
     96                # end of stream reached : we stop receiving audio data
     97                print("Audio data has been 100% received!")
     98                self.has_finished = True
     99
    100            else:
    101                # something's wrong...
    102                print("Invalid data received...")
    103                self.has_finished = True
    104
    105def do_server(port):
    106    # build an audio stream to play sound data as it is received through the network
    107    audio_stream = NetworkAudioStream()
    108    audio_stream.start(port)
    109
    110    # loop until the sound playback is finished
    111    while audio_stream.status != sf.SoundStream.STOPPED:
    112        # leave some CPU time for other threads
    113        sf.sleep(sf.milliseconds(100))
    114
    115
    116    # wait until the user presses 'enter' key
    117    input("Press enter to replay the sound...")
    118
    119    # replay the sound (just to make sure replaying the received data is OK)
    120    audio_stream.play();
    121
    122    # loop until the sound playback is finished
    123    while audio_stream.status != sf.SoundStream.STOPPED:
    124        sf.sleep(sf.milliseconds(100))

## Embedding

     1// Including Python.h first is mandatory!
     2#include <Python.h>
     3
     4#include <unistd.h>
     5#include <iostream>
     6
     7// Make sure to include the SFML headers before the pySFML ones
     8#include <SFML/Graphics.hpp>
     9#include <pysfml/graphics_api.h>
    10
    11int main(int argc, char *argv[])
    12{
    13    // Initialization (mandatory stuff)
    14    Py_SetProgramName(argv[0]);
    15    Py_Initialize();
    16
    17    // Add the current path to sys.path to find our script
    18    char cwd[1024];
    19    if (!getcwd(cwd, sizeof(cwd))) {
    20        std::cout << "Couldn't get the current path" << std::endl;
    21        return EXIT_FAILURE; }
    22    PyObject *sys = PyImport_ImportModule("sys");
    23    PyObject *path = PyObject_GetAttrString(sys, "path");
    24    PyList_Append(path, PyString_FromString(cwd));
    25
    26    // Import our script that creates a texture
    27    PyObject* script = PyImport_ImportModule("script");
    28    if(!script)
    29        PyErr_Print();
    30
    31    // Retrieve the texture
    32    PyTextureObject *texture;
    33    texture = (PyTextureObject*)PyObject_GetAttrString(script, "texture");
    34
    35    // Create a window and display the texture for five seconds
    36    sf::RenderWindow window(sf::VideoMode(640, 480), "pySFMl - Embedding Python");
    37
    38    window.clear();
    39    window.draw(sf::Sprite(*texture->p_this));
    40    window.display();
    41
    42    sf::sleep(sf::seconds(5));
    43
    44    // Then, terminate properly...
    45    Py_Finalize();
    46
    47    return EXIT_SUCCESS;
    48}

    1from sfml import sf
    2
    3texture = sf.Texture.from_file("image.jpg")

## Extending

    1cimport libcpp.sfml as sf
    2from pysfml.graphics cimport Image
    3
    4def flip_image(Image image):
    5    image.p_this.flipHorizontally()
    6    image.p_this.flipVertically()

     1from sfml import sf
     2
     3import pyximport; pyximport.install()
     4import extension
     5
     6window = sf.RenderWindow(sf.VideoMode(640, 480), "sfml")
     7
     8image = sf.Image.from_file("image.jpg")
     9extension.flip_image(image)
    10
    11texture = sf.Texture.from_image(image)
    12
    13window.clear()
    14window.draw(sf.Sprite(texture))
    15window.display()
    16
    17sf.sleep(sf.seconds(5))

## Spacial Music

      1from sfml import sf
      2
      3def main(song):
      4	window = sf.RenderWindow(sf.VideoMode(600, 600), "pySFML - Spacial Music")
      5	window.framerate_limit = 60
      6
      7	# load one font, one song and two textures
      8	try:
      9		font = sf.Font.from_file("data/sansation.ttf")
     10		music = sf.Music.from_file(song)
     11
     12		texture = sf.Texture.from_file("data/speaker.gif")
     13		speaker = sf.Sprite(texture)
     14		speaker.position = -texture.size // 2
     15
     16		texture = sf.Texture.from_file("data/head_kid.png")
     17		hears = sf.Sprite(texture)
     18		hears.origin = texture.size // 2
     19
     20	except IOError:
     21		exit(1)
     22
     23	# create a text that display instructions
     24	instructions = "Up/Down        Move hears along Y axis\n"
     25	instructions += "Left/Right       Move hears along X axis\n"
     26	instructions += "Plus/Minus     Move hears along Z axis"
     27	instructions = sf.Text(instructions, font, 12)
     28	instructions.position = (70, 250)
     29	instructions.color = sf.Color.BLACK
     30
     31	# make sure the song is monothread so it can be spacialized
     32	if music.channel_count != 1:
     33		print("Only sounds with one channel (mono sounds) can be spatialized.")
     34		print("This song ({0}) has {1} channels.".format(SONG, music.channels_count))
     35		exit(1)
     36
     37	# setup the music properties
     38	music.relative_to_listener = False
     39	music.min_distance = 200
     40	music.attenuation = 1
     41
     42	# initialize some values before entering the main loop
     43	position = sf.Vector3(-250, -250, 0)
     44	sf.Listener.set_position(position)
     45
     46	x, y, _ = position
     47	hears.position = (x, y)
     48
     49	running = True
     50
     51	# move the view to make coord (0, 0) appears on the center of the screen
     52	window.default_view.move(-300, -300)
     53
     54	# start the music before entering the main loop
     55	music.loop = True
     56	music.play()
     57
     58	# start the main loop
     59	while running:
     60		for event in window.events:
     61			if type(event) is sf.CloseEvent:
     62				running = False
     63
     64			elif type(event) is sf.KeyEvent and event.pressed:
     65				if event.code is sf.Keyboard.UP:
     66					position.y -= 5
     67
     68				elif event.code is sf.Keyboard.DOWN:
     69					position.y += 5
     70
     71				elif event.code is sf.Keyboard.LEFT:
     72					position.x -= 5
     73
     74				elif event.code is sf.Keyboard.RIGHT:
     75					position.x += 5
     76
     77				elif event.code is sf.Keyboard.ADD:
     78					if position.z < 400:
     79						position.z += 5
     80
     81				elif event.code is sf.Keyboard.SUBTRACT:
     82					if position.z > -400:
     83						position.z -= 5
     84
     85				# update the listener and the hears position
     86				sf.Listener.set_position(position)
     87
     88				x, y, z = position
     89				hears.position = (x, y)
     90				hears.ratio = (1, 1) + sf.Vector2(z, z)/400.
     91
     92		# clear screen, draw images and text and display them
     93		window.clear(sf.Color.WHITE)
     94
     95		if position.z >= 0:
     96			window.draw(speaker)
     97			window.draw(hears)
     98		else:
     99			window.draw(hears)
    100			window.draw(speaker)
    101
    102		window.draw(instructions)
    103		window.display()
    104
    105	window.close()
    106
    107
    108if __name__ == "__main__":
    109    main("data/mario.flac")