# 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

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113

    import os
    import sfml.network as sf

    # python 2.* compatability
    try: input = raw_input
    except NameError: pass

    # choose the server address
    address = input("Enter the FTP server address: ")
    address = sf.IpAddress.from_string(address)

    # create the server object which with you will communicate
    server = sf.Ftp()

    # connect to the server
    response = server.connect(address)
    print(response)
    if not response.ok: exit()

    # ask for user name and password
    user = input("User name: ")
    password = input("Password: ")

    # login to the server
    response = server.login(user, password)
    print(response)
    if not response.ok: exit()

    # main menu
    choice = 0
    while True:
        print("===========================================================")
        print("Choose an action:")
        print("1. Print working directory")
        print("2. Print contents of working directory")
        print("3. Change directory")
        print("4. Create directory")
        print("5. Delete directory")
        print("6. Rename file")
        print("7. Remove file")
        print("8. Download file")
        print("9. Upload file")
        print("0. Disconnect\n\n")

        choice = int(input("Your choice: "))

        os.system('clear')

        if choice == 1:
            # print the current server directory
            response = server.get_working_directory()
            print(response)
            print("Current directory is {0}".format(response.get_directory()))
        elif choice == 2:
            # print the contents of the current server directory
            response = server.get_directory_listing()
            print(response)
            for filename in response.filenames:
                print(filename)
        elif choice == 3:
            # change the current directory
            directory = input("Choose a directory: ")
            response = server.change_directory(directory)
            print(response)
        elif choice == 4:
            # create a new directory
            directory = input("Name of the directory to create: ")
            response = server.create_directory(directory)
            print(response)
        elif choice == 5:
            # remove an existing directory
            directory = input("Name of the directory to remove: ")
            response = server.delete_directory(directory)
            print(response)
        elif choice == 6:
            # rename a file
            source = input("Name of the file to rename: ")
            destination = input("New name: ")
            response = server.rename_file(source, destination)
            print(response)
        elif choice == 7:
            # remove an existing directory
            filename = input("Name of the file to remove: ")
            response = server.delete_file(filename)
            print(response)
        elif choice == 8:
            # download a file from server
            filename = input("Filename of the file to download (relative to current directory): ")
            directory = input("Directory to download the file to: ")
            response = server.download(filename, directory)
            print(response)
        elif choice == 9:
            # upload a file to server
            filename = input("Path of the file to upload (absolute or relative to working directory): ")
            directory = input("Directory to upload the file to (relative to current directory): ")
            response = server.upload(filename, directory)
            print(response)
        elif choice == 0:
            break
        else:
            # wrong choice
            print("Invalid choice!")
            os.system('clear')

        if choice == 0:
            break

    # disconnect from the server
    print("Disconnecting from server...")
    response = server.disconnect()

    # wait until the user presses 'enter' key
    input("Press enter to exit...")

## Pong

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177

    from __future__ import division

    from math import cos, sin, fabs, pi
    from random import randint

    from sfml import sf

    # define some constants
    game_size = sf.Vector2(800, 600)
    paddle_size = sf.Vector2(25, 100)
    ball_radius = 10.

    # create the window of the application
    w, h = game_size
    window = sf.RenderWindow(sf.VideoMode(w, h), "pySFML - Pong")
    window.vertical_synchronization = True

    # load the sounds used in the game
    ball_sound_buffer = sf.SoundBuffer.from_file("data/ball.wav")
    ball_sound = sf.Sound(ball_sound_buffer)

    # create the left paddle
    left_paddle = sf.RectangleShape()
    left_paddle.size = paddle_size - (3, 3)
    left_paddle.outline_thickness = 3
    left_paddle.outline_color = sf.Color.BLACK
    left_paddle.fill_color = sf.Color(100, 100, 200)
    left_paddle.origin = paddle_size / 2

    # create the right paddle
    right_paddle = sf.RectangleShape()
    right_paddle.size = paddle_size - (3, 3)
    right_paddle.outline_thickness = 3
    right_paddle.outline_color = sf.Color.BLACK
    right_paddle.fill_color = sf.Color(200, 100, 100)
    right_paddle.origin = paddle_size / 2

    # create the ball
    ball = sf.CircleShape()
    ball.radius = ball_radius - 3
    ball.outline_thickness = 3
    ball.outline_color = sf.Color.BLACK
    ball.fill_color = sf.Color.WHITE
    ball.origin = (ball_radius / 2, ball_radius / 2)

    # load the font
    font = sf.Font.from_file("data/sansation.ttf")

    # initialize the pause message
    pause_message = sf.Text()
    pause_message.font = font
    pause_message.character_size = 40
    pause_message.position = (170, 150)
    pause_message.color = sf.Color.WHITE
    pause_message.string = "Welcome to pySFML pong!\nPress space to start the game"

    # define the paddles properties
    ai_timer = sf.Clock()
    ai_time = sf.seconds(0.1)
    paddle_speed = 400.
    right_paddle_speed = 0.
    ball_speed = 400.
    ball_angle = 0. # to be changed later

    clock = sf.Clock()
    is_playing = False

    while window.is_open:

        # handle events
        for event in window.events:
            # window closed or escape key pressed: exit
            if type(event) is sf.CloseEvent:
                window.close()

            # space key pressed: play
            if type(event) is sf.KeyEvent and event.pressed and event.code is sf.Keyboard.SPACE:
                if not is_playing:
                    # (re)start the game
                    is_playing = True
                    clock.restart()

                    # reset the position of the paddles and ball
                    left_paddle.position = (10 + paddle_size.x / 2, game_size.y / 2)
                    right_paddle.position = (game_size.x - 10 - paddle_size.x / 2, game_size.y / 2)
                    ball.position = game_size / 2

                    # reset the ball angle
                    while True:
                        # make sure the ball initial angle is not too much vertical
                        ball_angle = (randint(0, 32767) % 360) * 2 * pi / 360
                        if not fabs(cos(ball_angle)) < 0.7: break

        if is_playing:
            delta_time = clock.restart().seconds

            # move the player's paddle
            if sf.Keyboard.is_key_pressed(sf.Keyboard.UP) and left_paddle.position.y - paddle_size.y / 2 > 5:
                left_paddle.move((0, -paddle_speed * delta_time))

            elif sf.Keyboard.is_key_pressed(sf.Keyboard.DOWN) and left_paddle.position.y + paddle_size.y / 2 < game_size.y - 5:
                left_paddle.position += (0, paddle_speed * delta_time)

            # move the computer' paddle
            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):
                right_paddle.position += (0, right_paddle_speed * delta_time)

            # update the computer's paddle direction according to the ball position
            if ai_timer.elapsed_time > ai_time:
                ai_timer.restart()
                if ball.position.y + ball_radius > right_paddle.position.y + paddle_size.y / 2:
                    right_paddle_speed = paddle_speed
                elif ball.position.y - ball_radius < right_paddle.position.y - paddle_size.y / 2:
                    right_paddle_speed = - paddle_speed
                else:
                    right_paddle_speed = 0

            # move the ball
            factor = ball_speed * delta_time
            ball.move((cos(ball_angle) * factor, sin(ball_angle) * factor))

            # check collisions between the ball and the screen
            if ball.position.x - ball_radius < 0:
                is_playing = False
                pause_message.string = "You lost!\nPress space to restart or\nescape to exit"

            if ball.position.x + ball_radius > game_size.x:
                is_playing = False
                pause_message.string = "You won !\nPress space to restart or\nescape to exit"

            if ball.position.y - ball_radius < 0:
                ball_sound.play()
                ball_angle = - ball_angle
                ball.position.y = ball_radius + 0.1

            if ball.position.y + ball_radius > game_size.y:
                ball_sound.play()
                ball_angle = - ball_angle
                ball.position.y = game_size.y - ball_radius - 0.1

            # check the collisions between the ball and the paddles
            # left paddle
            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:
                if ball.position.y > left_paddle.position.y:
                    ball_angle = pi - ball_angle + (randint(0, 32767) % 20) * pi / 180
                else:
                    ball_angle = pi - ball_angle - (randint(0, 32767) % 20) * pi / 180

                ball_sound.play()
                ball.position = (left_paddle.position.x + ball_radius + paddle_size.x / 2 + 0.1, ball.position.y)

            # right paddle
            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:
                if ball.position.y > right_paddle.position.y:
                    ball_angle = pi - ball_angle + (randint(0, 32767) % 20) * pi / 180
                else:
                    ball_angle = pi - ball_angle - (randint(0, 32767) % 20) * pi / 180

                ball_sound.play()
                ball.position = (right_paddle.position.x - ball_radius - paddle_size.x / 2 - 0.1, ball.position.y)

        window.clear(sf.Color(50, 200, 50))

        if is_playing:
            # draw the paddles and the ball
            window.draw(left_paddle)
            window.draw(right_paddle)
            window.draw(ball)

        else:
            # draw the pause message
            window.draw(pause_message)

        # display things on screen
        window.display()

## PyQt4

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82

    import sys, platform

    try:
        import sip
        from PyQt4.QtCore import *
        from PyQt4.QtGui import *
    except ImportError:
        print("Install PyQt4 and sip from Riverbank.")

    from sfml import sf

    class QSFMLCanvas(QWidget):
        def __init__(self, parent, position, size, frameTime=0):
            QWidget.__init__(self, parent)
            self.initialized = False

            w = size.width()
            h = size.height()

            self._HandledWindow = sf.HandledWindow()
            self._HandledWindow.view.size = (w, h)
            self.__dict__['draw'] = self._HandledWindow.draw
            self.__dict__['clear'] = self._HandledWindow.clear
            self.__dict__['view'] = self._HandledWindow.view
            self.__dict__['display'] = self._HandledWindow.display

            # setup some states to allow direct rendering into the widget
            self.setAttribute(Qt.WA_PaintOnScreen)
            self.setAttribute(Qt.WA_OpaquePaintEvent)
            self.setAttribute(Qt.WA_NoSystemBackground)

            # set strong focus to enable keyboard events to be received
            self.setFocusPolicy(Qt.StrongFocus);

            # setup the widget geometry
            self.move(position);
            self.resize(size);

            # setup the timer
            self.timer = QTimer()
            self.timer.setInterval(frameTime)

        def onInit(self): pass

        def onUpdate(self): pass

        def sizeHint(self):
            return self.size()

        def paintEngine(self):
            # let the derived class do its specific stuff
            self.onUpdate()

            # display on screen
            self.display()

        def showEvent(self, event):
            if not self.initialized:
                # under X11, we need to flush the commands sent to the server
                # to ensure that SFML will get an updated view of the windows
                # create the SFML window with the widget handle
                if platform.system() == 'Linux':
                    from ctypes import cdll
                    x11 = cdll.LoadLibrary("libX11.so")

                    display = sip.unwrapinstance(QX11Info.display())
                    x11.XFlush(display)

                self._HandledWindow.create(self.winId())

                # let the derived class do its specific stuff
                self.onInit()

                # setup the timer to trigger a refresh at specified framerate
                self.connect(self.timer,SIGNAL('timeout()'), self, SLOT('repaint()'))
                self.timer.start()

                self.initialized = True

        def paintEvent(self, event):
            return None

## Shader

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281

    from __future__ import division

    from random import randint
    from math import cos

    from sfml import sf

    class Effect(sf.Drawable):
        def __init__(self, name):
            sf.Drawable.__init__(self)

            self._name = name
            self.is_loaded = False

        def _get_name(self):
            return self._name

        def load(self):
            self.is_loaded = sf.Shader.is_available() and self.on_load()

        def update(self, time, x, y):
            if self.is_loaded:
                self.on_update(time, x, y)

        def draw(self, target, states):
            if self.is_loaded:
                self.on_draw(target, states)
            else:
                error = sf.Text("Shader not\nsupported")
                error.font = sf.Font.from_file("data/sansation.ttf")
                error.position = (320, 200)
                error.character_size = 36
                target.draw(error, states)

        name = property(_get_name)

    class Pixelate(Effect):
        def __init__(self):
            Effect.__init__(self, 'pixelate')

        def on_load(self):
            try:
                # load the texture and initialize the sprite
                self.texture = sf.Texture.from_file("data/background.jpg")
                self.sprite = sf.Sprite(self.texture)

                # load the shader
                self.shader = sf.Shader.from_file(fragment="data/pixelate.frag")
                self.shader.set_parameter("texture")

            except IOError as error:
                print("An error occured: {0}".format(error))
                exit(1)

            return True

        def on_update(self, time, x, y):
            self.shader.set_parameter("pixel_threshold", (x + y) / 30)

        def on_draw(self, target, states):
            states.shader = self.shader
            target.draw(self.sprite, states)

    class WaveBlur(Effect):
        def __init__(self):
            Effect.__init__(self, 'wave + blur')

        def on_load(self):
            with open("data/text.txt") as file:
                self.text = sf.Text(file.read())
                self.text.font = sf.Font.from_file("data/sansation.ttf")
                self.text.character_size = 22
                self.text.position = (30, 20)

            try:
                # load the shader
                self.shader = sf.Shader.from_file("data/wave.vert", "data/blur.frag")

            except IOError as error:
                print("An error occured: {0}".format(error))
                exit(1)

            return True

        def on_update(self, time, x, y):
            self.shader.set_parameter("wave_phase", time)
            self.shader.set_parameter("wave_amplitude", x * 40, y * 40)
            self.shader.set_parameter("blur_radius", (x + y) * 0.008)

        def on_draw(self, target, states):
            states.shader = self.shader
            target.draw(self.text, states)

    class StormBlink(Effect):
        def __init__(self):
            Effect.__init__(self, 'storm + blink')

            self.points = sf.VertexArray()

        def on_load(self):
            # create the points
            self.points.primitive_type = sf.PrimitiveType.POINTS

            for i in range(40000):
                x = randint(0, 32767) % 800
                y = randint(0, 32767) % 600
                r = randint(0, 32767) % 255
                g = randint(0, 32767) % 255
                b = randint(0, 32767) % 255
                self.points.append(sf.Vertex(sf.Vector2(x, y), sf.Color(r, g, b)))

            try:
                # load the shader
                self.shader = sf.Shader.from_file("data/storm.vert", "data/blink.frag")

            except IOError as error:
                print("An error occured: {0}".format(error))
                exit(1)

            return True

        def on_update(self, time, x, y):
            radius = 200 + cos(time) * 150
            self.shader.set_parameter("storm_position", x * 800, y * 600)
            self.shader.set_parameter("storm_inner_radius", radius / 3)
            self.shader.set_parameter("storm_total_radius", radius)
            self.shader.set_parameter("blink_alpha", 0.5 + cos(time*3) * 0.25)

        def on_draw(self, target, states):
            states.shader = self.shader
            target.draw(self.points, states)

    class Edge(Effect):
        def __init__(self):
            Effect.__init__(self, "edge post-effect")

        def on_load(self):
            # create the off-screen surface
            self.surface = sf.RenderTexture(800, 600)
            self.surface.smooth = True

            # load the textures
            self.background_texture = sf.Texture.from_file("data/sfml.png")
            self.background_texture.smooth = True

            self.entity_texture = sf.Texture.from_file("data/devices.png")
            self.entity_texture.smooth = True

            # initialize the background sprite
            self.background_sprite = sf.Sprite(self.background_texture)
            self.background_sprite.position = (135, 100)

            # load the moving entities
            self.entities = []

            for i in range(6):
                sprite = sf.Sprite(self.entity_texture, (96 * i, 0, 96, 96))
                self.entities.append(sprite)

            # load the shader
            self.shader = sf.Shader.from_file(fragment="data/edge.frag")
            self.shader.set_parameter("texture")

            return True

        def on_update(self, time, x, y):
            self.shader.set_parameter("edge_threshold", 1 - (x + y) / 2)

            # update the position of the moving entities
            for i, entity in enumerate(self.entities):
                x = cos(0.25 * (time * i + (len(self.entities) - i))) * 300 + 350
                y = cos(0.25 * (time * (len(self.entities) - i) + i)) * 200 + 250
                entity.position = (x, y)

            # render the updated scene to the off-screen surface
            self.surface.clear(sf.Color.WHITE)
            self.surface.draw(self.background_sprite)

            for entity in self.entities:
                self.surface.draw(entity)

            self.surface.display()

        def on_draw(self, target, states):
            states.shader = self.shader
            target.draw(sf.Sprite(self.surface.texture), states)

    if __name__ == "__main__":
        # create the main window
        window = sf.RenderWindow(sf.VideoMode(800, 600), "pySFML - Shader")
        window.vertical_synchronization = True

        # create the effects
        effects = (Pixelate(), WaveBlur(), StormBlink(), Edge())
        current = 0

        # initialize them
        for effect in effects: effect.load()

        # create the message background
        try:
            text_background_texture = sf.Texture.from_file("data/text-background.png")

        except IOError as error:
            print("An error occured: {0}".format(error))
            exit(1)

        text_background = sf.Sprite(text_background_texture)
        text_background.position = (0, 520)
        text_background.color = sf.Color(255, 255, 255, 200)

        # load the messages font
        try:
            font = sf.Font.from_file("data/sansation.ttf")

        except IOError as error:
            print("An error occured: {0}".format(error))
            exit(1)

        # create the description text
        description = sf.Text("Current effect: {0}".format(effects[current].name), font, 20)
        description.position = (10, 530)
        description.color = sf.Color(80, 80, 80)

        # create the instructions text
        instructions = sf.Text("Press left and right arrows to change the current shader", font, 20)
        instructions.position = (280, 555)
        instructions.color = sf.Color(80, 80, 80)

        clock = sf.Clock()

        # start the game loop
        while window.is_open:

            # update the current example
            x, y = sf.Mouse.get_position(window) / window.size
            effects[current].update(clock.elapsed_time.seconds, x, y)

            # process events
            for event in window.events:

                # close window: exit
                if type(event) is sf.CloseEvent:
                    window.close()

                if type(event) is sf.KeyEvent and event.pressed:
                    # escapte key: exit
                    if event.code == sf.Keyboard.ESCAPE:
                        window.close()

                    # left arrow key: previous shader
                    elif event.code is sf.Keyboard.LEFT:
                        if current == 0: current = len(effects) - 1
                        else: current -= 1

                        description.string = "Current effect: {0}".format(effects[current].name)

                    # right arrow key: next shader
                    elif event.code is sf.Keyboard.RIGHT:
                        if current == len(effects) - 1: current = 0
                        else: current += 1

                        description.string = "Current effect: {0}".format(effects[current].name)

            # clear the window
            window.clear(sf.Color(255, 128, 0))

            # draw the current example
            window.draw(effects[current])

            # draw the text
            window.draw(text_background)
            window.draw(instructions)
            window.draw(description)

            # finally, display the rendered frame on screen
            window.display()

## Sockets

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137

    import sfml.network as sf

    # python 2.* compatability
    try: input = raw_input
    except NameError: pass

    def run_tcp_server():
        """ Launch a server. The server waits for an incoming connection,
        sends a message and waits for the answer. """

        try:
            # create a server socket to accept new connections
            listener = sf.TcpListener()

            # listen to the given port for incoming connections
            listener.listen(PORT)

            print("Server is listening to port {0}, waiting for connections...".format(PORT))

            # wait for a connection
            socket = listener.accept()
            print("Client connected: {0}".format(socket.remote_address))

            # send a message to the connected client
            message = "Hi, I'm the server"
            socket.send(message.encode('utf-8'))
            print("Message sent to the client: {0}".format(message))

            # recieve a message back from the client
            answer = socket.receive(128).decode('utf-8')
            print("Answer received from the client: {0}".format(answer))

        except sf.SocketException as error:
            print("An error occured!")
            print(error)
            return

    def run_tcp_client():
        """ Create a client. The client is connected to a server, displays
        the welcome message and sends an answer. """

        server = input("Type the address or name of the server to connect to: ")
        server = sf.IpAddress.from_string(server)

        # create a socket for communicating with the server
        socket = sf.TcpSocket()

        # connect to the server
        try:
            socket.connect(server, PORT)
            print("Connected to server {0}".format(server))

            # receive a message from the server
            message = socket.receive(128).decode('utf-8')
            print("Message received from the server: {0}".format(message))

            # send an answer to the server
            answer = "Hi, I'm a client"
            socket.send(answer.encode('utf-8'))
            print("Message sent to the server: {0}".format(answer))

        except sf.SocketException as error:
            print("An error occured!")
            print(error)
            return

    def run_udp_server():
        """ Launch a server. The server waits for a message then sends an
        answer. """

        # create a socket to receive a message from anyone
        socket = sf.UdpSocket()

        try:
            # listen to messages on the specified port
            socket.bind(PORT)
            print("Server is listening to port {0}, waiting for message...".format(PORT))

            # wait for a message
            message, ip, port = socket.receive(128)
            print("Message received from client {0}: {1}".format(ip, message.decode('utf-8')))

            # send an answer to the client
            answer = "Hi, I'm the server"
            socket.send(answer.encode('utf-8'), ip, port)
            print("Message sent to the client: {0}".format(answer))

        except sf.SocketException as error:
            print("An error occured!")
            print(error)
            return

    def run_udp_client():
        """ Send a message to the server, wait for the answer. """

        # ask for the server address
        server = input("Type the address or name of the server to connect to: ")
        server = sf.IpAddress.from_string(server)

        # create a socket for communicating with the server
        socket = sf.UdpSocket()

        try:
            # send a message to the server
            message = "Hi, I'm a client"
            socket.send(message.encode('utf-8'), server, PORT)
            print("Message sent to the server: {0}".format(message))

            # receive an answer from anyone (but most likely from the server)
            answer, ip, port = socket.receive(128)
            print("Message received from {0}: {1}".format(ip, answer.decode('utf-8')))

        except sf.SocketException as error:
            print("An error occured!")
            print(error)
            return

    if __name__ == "__main__":
        # choose an arbitrary port for opening sockets
        PORT = 50001

        # TCP or UDP ?
        print("Do you want to use TCP (t) or UDP (u) ?")
        protocol = input()

        # client or server ?
        print("Do you want to be a server (s) or a client (c) ?")
        who = input()

        if protocol == 't':
            if who == 's': run_tcp_server()
            else: run_tcp_client()
        else:
            if who == 's': run_udp_server()
            else: run_udp_client()

        input("Press any key to exit...")

## Sound capture

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62

    from sfml import sf

    # python 2.* compatability
    try: input = raw_input
    except NameError: pass

    def main():
        # check that the device can capture audio
        if not sf.SoundRecorder.is_available():
            print("Sorry, audio capture is not supported by your system")
            return

        # choose the sample rate
        sample_rate = int(input("Please choose the sample rate for sound capture (44100 is CD quality): "))

        # wait for user input...
        input("Press enter to start recording audio")

        # here we'll use an integrated custom recorder, which saves the captured data into a sf.SoundBuffer
        recorder = sf.SoundBufferRecorder()

        # audio capture is done in a separate thread, so we can block the main thread while it is capturing
        recorder.start(sample_rate)
        input("Recording... press enter to stop")
        recorder.stop()

        # get the buffer containing the captured data
        buffer = recorder.buffer

        # display captured sound informations
        print("Sound information:")
        print("{0} seconds".format(buffer.duration))
        print("{0} samples / seconds".format(buffer.sample_rate))
        print("{0} channels".format(buffer.channel_count))

        # choose what to do with the recorded sound data
        choice = input("What do you want to do with captured sound (p = play, s = save) ? ")

        if choice == 's':
            # choose the filename
            filename = input("Choose the file to create: ")

            # save the buffer
            buffer.to_file(filename);
        else:
            # create a sound instance and play it
            sound = sf.Sound(buffer)
            sound.play();

            # wait until finished
            while sound.status == sf.Sound.PLAYING:
                # leave some CPU time for other threads
                sf.sleep(sf.milliseconds(100))

        # finished !
        print("Done !")

        # wait until the user presses 'enter' key
        input("Press enter to exit...")

    if __name__ == "__main__":
        main()

## Sound

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44

    from sfml import sf

    def play_sound():
        # load a sound buffer from a wav file
        buffer = sf.SoundBuffer.from_file("data/canary.wav")

        # display sound informations
        print("canary.wav:")
        print("{0} seconds".format(buffer.duration))
        print("{0} samples / sec".format(buffer.sample_rate))
        print("{0} channels".format(buffer.channel_count))

        # create a sound instance and play it
        sound = sf.Sound(buffer)
        sound.play();

        # loop while the sound is playing
        while sound.status == sf.Sound.PLAYING:
            # leave some CPU time for other processes
            sf.sleep(sf.milliseconds(100))

    def play_music():
        # load an ogg music file
        music = sf.Music.from_file("data/orchestral.ogg")

        # display music informations
        print("orchestral.ogg:")
        print("{0} seconds".format(music.duration))
        print("{0} samples / sec".format(music.sample_rate))
        print("{0} channels".format(music.channel_count))

        # play it
        music.play();

        # loop while the music is playing
        while music.status == sf.Music.PLAYING:
            # leave some CPU time for other processes
            sf.sleep(sf.milliseconds(100))

    if __name__ == "__main__":
        play_sound()
        play_music()

        input("Press enter to exit...")

## Voip

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20

    from sfml import sf
    import client, server

    # python 2.* compatability
    try: input = raw_input
    except NameError: pass

    # choose a random port for opening sockets (ports < 1024 are reserved)
    PORT = 2435

    # client or server ?
    print("Do you want to be a server (s) or a client (c) ?")
    who = input()

    if who == 's':
        server.do_server(PORT)
    else:
        client.do_client(PORT)

    input("Press any key to exit...")

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63

    from sfml import sf
    from struct import pack
    from random import randint

    # python 2.* compatability
    try: input = raw_input
    except NameError: pass

    AUDIO_DATA, END_OF_STREAM = list(range(1, 3))

    class NetworkRecorder(sf.SoundRecorder):
        def __init__(self, host, port):
            sf.SoundRecorder.__init__(self)

            self.host = host # address of the remote host
            self.port = port # remote port
            self.socket = sf.TcpSocket() # socket used to communicate with the server

        def on_start(self):
            try: self.socket.connect(self.host, self.port)
            except sf.SocketException as error: return False

            return True

        def on_process_samples(self, chunk):
            # pack the audio samples
            data = pack("B", AUDIO_DATA)
            data += pack("I", len(chunk.data))
            data += chunk.data

            # send the audio packet
            try: self.socket.send(data)
            except sf.SocketException: return False

            return True

        def on_stop(self):
            # send a "end-of-stream" signal
            self.socket.send(bytes(END_OF_STREAM))

            # close the socket
            self.socket.disconnect()

    def do_client(port):
        # check that the device can capture audio
        if not sf.SoundRecorder.is_available():
            print("Sorry, audio capture is not supported by your system")
            return

        # ask for server address
        server = input("Type address or name of the server to connect to: ")
        server = sf.IpAddress.from_string(server)

        # create an instance of our custom recorder
        recorder = NetworkRecorder(server, port)

        # wait for the user input...
        input("Press enter to start recording audio")

        # start capturing audio data
        recorder.start(44100)
        input("Recording... press enter to stop")
        recorder.stop()

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124

    import threading
    from time import sleep
    from sfml import sf
    from struct import unpack

    # python 2.* compatability
    try: input = raw_input
    except NameError: pass

    AUDIO_DATA, END_OF_STREAM = list(range(1, 3))

    class NetworkAudioStream(sf.SoundStream):
        def __init__(self):
            sf.SoundStream.__init__(self)

            self.offset = 0
            self.has_finished = False
            self.listener = sf.TcpListener()
            self.samples = sf.Chunk()

            # set the sound parameters
            self.initialize(1, 44100)

        def start(self, port):
            if not self.has_finished:
                try:
                    # listen to the given port for incoming connections
                    self.listener.listen(port)
                    print("Server is listening to port {0}, waiting for connections... ".format(port))

                    # wait for a connection
                    self.client = self.listener.accept()
                    print("Client connected: {0}".format(self.client.remote_address))

                except sf.SocketException: return

                # start playback
                self.play()

                # start receiving audio data
                self.receive_loop()

            else:
                # start playback
                self.play()

        def on_get_data(self, chunk):
            # we have reached the end of the buffer and all audio data have been played : we can stop playback
            if self.offset >= len(self.samples) and self.has_finished:
                return False

            # no new data has arrived since last update : wait until we get some
            while self.offset >= len(self.samples) and not self.has_finished:
                sf.sleep(sf.milliseconds(10))

            # don't forget to lock as we run in two separate threads
            lock = threading.Lock()
            lock.acquire()

            # fill audio data to pass to the stream
            chunk.data = self.samples.data[self.offset*2:]

            # update the playing offset
            self.offset += len(chunk)

            lock.release()

            return True

        def on_seek(self, time_offset):
            self.offset = time_offset.milliseconds * self.sample_rate * self.channel_count // 1000

        def receive_loop(self):
            lock = threading.RLock()

            while not self.has_finished:
                # get waiting audio data from the network
                data = self.client.receive(1)

                # extract the id message
                id = unpack("B", data)[0]

                if id == AUDIO_DATA:
                    # extract audio samples from the packet, and append it to our samples buffer
                    data = self.client.receive(4)
                    sample_count = unpack("I", data)[0]

                    samples = self.client.receive(sample_count)

                    # don't forget the other thread can access the sample array at any time
                    lock.acquire()
                    self.samples.data += samples
                    lock.release()

                elif id == END_OF_STREAM:
                    # end of stream reached : we stop receiving audio data
                    print("Audio data has been 100% received!")
                    self.has_finished = True

                else:
                    # something's wrong...
                    print("Invalid data received...")
                    self.has_finished = True

    def do_server(port):
        # build an audio stream to play sound data as it is received through the network
        audio_stream = NetworkAudioStream()
        audio_stream.start(port)

        # loop until the sound playback is finished
        while audio_stream.status != sf.SoundStream.STOPPED:
            # leave some CPU time for other threads
            sf.sleep(sf.milliseconds(100))

        # wait until the user presses 'enter' key
        input("Press enter to replay the sound...")

        # replay the sound (just to make sure replaying the received data is OK)
        audio_stream.play();

        # loop until the sound playback is finished
        while audio_stream.status != sf.SoundStream.STOPPED:
            sf.sleep(sf.milliseconds(100))

## Embedding

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48

    // Including Python.h first is mandatory!
    #include <Python.h>

    #include <unistd.h>
    #include <iostream>

    // Make sure to include the SFML headers before the pySFML ones
    #include <SFML/Graphics.hpp>
    #include <pysfml/graphics_api.h>

    int main(int argc, char *argv[])
    {
        // Initialization (mandatory stuff)
        Py_SetProgramName(argv[0]);
        Py_Initialize();

        // Add the current path to sys.path to find our script
        char cwd[1024];
        if (!getcwd(cwd, sizeof(cwd))) {
            std::cout << "Couldn't get the current path" << std::endl;
            return EXIT_FAILURE; }
        PyObject *sys = PyImport_ImportModule("sys");
        PyObject *path = PyObject_GetAttrString(sys, "path");
        PyList_Append(path, PyString_FromString(cwd));

        // Import our script that creates a texture
        PyObject* script = PyImport_ImportModule("script");
        if(!script)
            PyErr_Print();

        // Retrieve the texture
        PyTextureObject *texture;
        texture = (PyTextureObject*)PyObject_GetAttrString(script, "texture");

        // Create a window and display the texture for five seconds
        sf::RenderWindow window(sf::VideoMode(640, 480), "pySFMl - Embedding Python");

        window.clear();
        window.draw(sf::Sprite(*texture->p_this));
        window.display();

        sf::sleep(sf::seconds(5));

        // Then, terminate properly...
        Py_Finalize();

        return EXIT_SUCCESS;
    }

    1
    2
    3

    from sfml import sf

    texture = sf.Texture.from_file("image.jpg")

## Extending

    1
    2
    3
    4
    5
    6

    cimport libcpp.sfml as sf
    from pysfml.graphics cimport Image

    def flip_image(Image image):
        image.p_this.flipHorizontally()
        image.p_this.flipVertically()

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17

    from sfml import sf

    import pyximport; pyximport.install()
    import extension

    window = sf.RenderWindow(sf.VideoMode(640, 480), "sfml")

    image = sf.Image.from_file("image.jpg")
    extension.flip_image(image)

    texture = sf.Texture.from_image(image)

    window.clear()
    window.draw(sf.Sprite(texture))
    window.display()

    sf.sleep(sf.seconds(5))

## Spacial Music

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109

    from sfml import sf

    def main(song):
    	window = sf.RenderWindow(sf.VideoMode(600, 600), "pySFML - Spacial Music")
    	window.framerate_limit = 60

    	# load one font, one song and two textures
    	try:
    		font = sf.Font.from_file("data/sansation.ttf")
    		music = sf.Music.from_file(song)

    		texture = sf.Texture.from_file("data/speaker.gif")
    		speaker = sf.Sprite(texture)
    		speaker.position = -texture.size // 2

    		texture = sf.Texture.from_file("data/head_kid.png")
    		hears = sf.Sprite(texture)
    		hears.origin = texture.size // 2

    	except IOError:
    		exit(1)

    	# create a text that display instructions
    	instructions = "Up/Down        Move hears along Y axis\n"
    	instructions += "Left/Right       Move hears along X axis\n"
    	instructions += "Plus/Minus     Move hears along Z axis"
    	instructions = sf.Text(instructions, font, 12)
    	instructions.position = (70, 250)
    	instructions.color = sf.Color.BLACK

    	# make sure the song is monothread so it can be spacialized
    	if music.channel_count != 1:
    		print("Only sounds with one channel (mono sounds) can be spatialized.")
    		print("This song ({0}) has {1} channels.".format(SONG, music.channels_count))
    		exit(1)

    	# setup the music properties
    	music.relative_to_listener = False
    	music.min_distance = 200
    	music.attenuation = 1

    	# initialize some values before entering the main loop
    	position = sf.Vector3(-250, -250, 0)
    	sf.Listener.set_position(position)

    	x, y, _ = position
    	hears.position = (x, y)

    	running = True

    	# move the view to make coord (0, 0) appears on the center of the screen
    	window.default_view.move(-300, -300)

    	# start the music before entering the main loop
    	music.loop = True
    	music.play()

    	# start the main loop
    	while running:
    		for event in window.events:
    			if type(event) is sf.CloseEvent:
    				running = False

    			elif type(event) is sf.KeyEvent and event.pressed:
    				if event.code is sf.Keyboard.UP:
    					position.y -= 5

    				elif event.code is sf.Keyboard.DOWN:
    					position.y += 5

    				elif event.code is sf.Keyboard.LEFT:
    					position.x -= 5

    				elif event.code is sf.Keyboard.RIGHT:
    					position.x += 5

    				elif event.code is sf.Keyboard.ADD:
    					if position.z < 400:
    						position.z += 5

    				elif event.code is sf.Keyboard.SUBTRACT:
    					if position.z > -400:
    						position.z -= 5

    				# update the listener and the hears position
    				sf.Listener.set_position(position)

    				x, y, z = position
    				hears.position = (x, y)
    				hears.ratio = (1, 1) + sf.Vector2(z, z)/400.

    		# clear screen, draw images and text and display them
    		window.clear(sf.Color.WHITE)

    		if position.z >= 0:
    			window.draw(speaker)
    			window.draw(hears)
    		else:
    			window.draw(hears)
    			window.draw(speaker)

    		window.draw(instructions)
    		window.display()

    	window.close()

    if __name__ == "__main__":
        main("data/mario.flac")