Examples

If you downloaded a source archive or cloned pySFML2 from github, these examples will be located in the examples subdirectory of the project’s root. A package named ‘pysfml2-examples’ is also available for Debian-based Linux distributions, which allows you to run arbitrary examples by envoking 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

import sfml as 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.")

import sfml as 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

import sfml as 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
import sfml as 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
import sfml as 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
import sfml as 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
import sfml as 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
import sfml as 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
import sfml as 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
import sfml as 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
import sfml as 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")

Table Of Contents

Previous topic

Getting started

Next topic

Tutorials

This Page