Getting Started with 2D Games Using Pyxel (Part 12): Playing Sound Effects
Source: Dev.to
Registering a Sound
First, register a sound inside the constructor of the Game class.
The argument of pyxel.sound() specifies the sound ID.
- Sound ID – This number is used later when playing the sound.
Next, pass the following data to the set() method:
| Parameter | Description |
|---|---|
notes (score) | Specifies the pitch |
tones | Type of waveform (e.g. p = pulse wave) |
volumes | Volume |
effects | Sound effect (e.g. f = fade out) |
speed | Playback speed (lower values play faster) |
# main.py
pyxel.sound(0).set(
"c4g3",
tones="p",
volumes="76",
effects="f",
speed=20
)
Playing a Sound
With pyxel.play(), up to four sounds can be played simultaneously.
- The first argument specifies the channel number (0–3).
If the same channel is used, the new sound overwrites the previous one. - The second argument specifies the sound ID.
# main.py
pyxel.play(0, 0)
Complete Code
Below is the complete code implementing the features introduced in this article.
(The sprite.py file is the same as in the previous chapter.)
# main.py
import pyxel
import math
import random
import sprite
W, H = 160, 120
SHIP_SPD = 1.4
ASTEROID_INTERVAL = 20
ASTEROID_LIMIT = 30
ASTEROID_SPD_MIN = 1.0
ASTEROID_SPD_MAX = 2.0
ASTEROID_DEG_MIN = 30
ASTEROID_DEG_MAX = 150
BULLET_SPD = 3
# Game
class Game:
def __init__(self):
"""Constructor"""
# Game over flag
self.game_over_flg = False
# Initialize score
self.score = 0
# Initialize player
self.ship = sprite.ShipSprite(W / 2, H - 40)
deg = 0 if random.random() < 0.5 else 180
self.ship.move(SHIP_SPD, deg)
# Asteroids
self.asteroid_time = 0
self.asteroids = []
# Bullets
self.bullets = []
# Initialize Pyxel
pyxel.init(W, H, title="Hello, Pyxel!!")
pyxel.load("shooter.pyxres")
# Sound (shot)
pyxel.sound(0).set(
"c4g3",
tones="p",
volumes="76",
effects="f",
speed=20
)
# Sound (hit)
pyxel.sound(1).set(
"e4d4c4",
tones="p",
volumes="76",
effects="n",
speed=20
)
pyxel.run(self.update, self.draw)
def update(self):
"""Update process"""
# Game over
if self.game_over_flg:
return
# Update player
self.ship.update()
self.control_ship()
self.overlap_spr(self.ship)
self.check_interval() # Add asteroids
# Update asteroids
for asteroid in self.asteroids:
asteroid.update()
self.overlap_spr(asteroid)
# Collision check (asteroid × player)
if asteroid.intersects(self.ship):
self.game_over_flg = True
# Update bullets (reverse order)
for bullet in self.bullets[::-1]:
bullet.update()
# Remove if outside screen
if bullet.y < 0:
self.bullets.remove(bullet)
continue
# Collision check (bullet × asteroid)
for asteroid in self.asteroids[::-1]:
if asteroid.intersects(bullet):
self.score += 1
self.bullets.remove(bullet)
self.asteroids.remove(asteroid)
# Sound (hit)
pyxel.play(1, 1)
return
def draw(self):
"""Draw process"""
pyxel.cls(0)
# Game over
if self.game_over_flg:
msg = "GAME OVER"
pyxel.text(W / 2 - len(msg) * 2, H / 2, msg, 13)
# Draw score
pyxel.text(10, 10, f"SCORE:{self.score:04}", 12)
# Draw player
self.ship.draw()
# Draw asteroids
for asteroid in self.asteroids:
asteroid.draw()
# Draw bullets
for bullet in self.bullets:
bullet.draw()
def control_ship(self):
"""Player action"""
if pyxel.btnp(pyxel.KEY_SPACE):
self.ship.flip_x()
# Fire bullet
bullet = sprite.BulletSprite(self.ship.x, self.ship.y)
bullet.move(BULLET_SPD, 270)
self.bullets.append(bullet)
# Sound (shot)
pyxel.play(0, 0)
def overlap_spr(self, spr):
"""Wrap sprite around the screen"""
if spr.x < -spr.w:
spr.x = W
return
if W < spr.x:
spr.x = -spr.w
return
if spr.y < -spr.h:
spr.y = H
return
if H < spr.y:
spr.y = -spr.h
return
def check_interval(self):
# Asteroid spawn interval
self.asteroid_time += 1
if self.asteroid_time < ASTEROID_INTERVAL:
return
self.asteroid_time = 0
# Limit number of asteroids
if ASTEROID_LIMIT < len(self.asteroids):
return
# Add asteroid
x = random.random() * W
y = 0
spd = random.uniform(ASTEROID_SPD_MIN, ASTEROID_SPD_MAX)
deg = random.uniform(ASTEROID_DEG_MIN, ASTEROID_DEG_MAX)
asteroid = sprite.AsteroidSprite(x, y)
asteroid.move(spd, deg)
self.asteroids.append(asteroid)
# Run the game
Game()
Fullscreen Controls
- Enter fullscreen mode
- Exit fullscreen mode
Final Words
Thank you for reading this far.
I hope this series becomes a starting point for your own game development journey.
If you enjoyed it, a 👍 would mean a lot!
