Examples

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")