11/8/24 Blog Post

MAKING (still) A BEAT MAKER IN PYTHON WHOO!!!!

FULL CODE(so far)

import pygame as py

from pygame import mixer
py.init()

WIDTH, HEIGHT = 1400, 800

black = (0,0,0)
white = (255,255,255)
grey = (128, 128, 128)
green = (0, 255, 0)
gold = (212, 175, 55)
blue = (0, 255, 255)


screen = py.display.set_mode([WIDTH, HEIGHT])
py.display.set_caption("Beat Maker")
label_font = py.font.Font('Roboto-Bold.ttf', 32)

FPS = 60
timer = py.time.Clock()
beats = 8
instrumnents = 6
boxes = []
clicked = [[-1 for _ in range(beats)] for _ in range(instrumnents)]
bpm = 240
playing = True
active_length = 0
active_beat = 1
beat_changed = True

# ---------Sounds---------#
hi_hat = mixer.Sound('sounds\hi hat.WAV')
snare = mixer.Sound('sounds\snare.WAV')
clap = mixer.Sound('sounds\clap.wav')
kick = mixer.Sound('sounds\kick.WAV')
crash = mixer.Sound('sounds\crash.wav')
tom = mixer.Sound('sounds\\tom.WAV')
py.mixer.set_num_channels(instrumnents * 3)
# ------------------------#


def play_notes():
    '''plays the sound of the instrument'''
    for i in range(len(clicked)):
        if clicked[i][active_beat] == 1:
            if  i == 0:
                hi_hat.play()
            if  i == 1:
                snare.play()
            if  i == 2:
                kick.play()
            if  i == 3:
                crash.play()
            if  i == 4:
                clap.play()
            if  i == 5:
                tom.play()


def draw_grid(clicks, beat):
    # Making the boxes for the interface
    left_box = py.draw.rect(screen, grey, [0, 0, 200, HEIGHT - 200], 5)
    bottom_box = py.draw.rect(screen, grey, [0, HEIGHT - 200, WIDTH, 200], 5)
    boxes = []
    colors = [grey, white, grey]
    # Making the names of all the instruments
    hi_hat_text = label_font.render('Hi-hat', True, white)
    screen.blit(hi_hat_text, (30, 30))
    snare_text = label_font.render('Snare', True, white)
    screen.blit(snare_text, (30, 130))
    kick_text = label_font.render('Kick', True, white)
    screen.blit(kick_text, (30, 230))
    crash_text = label_font.render('Crash', True, white)
    screen.blit(crash_text, (30, 330))
    clap_text = label_font.render('Clap', True, white)
    screen.blit(clap_text, (30, 430))
    floor_tom_text = label_font.render('Floor Tom', True, white)
    screen.blit(floor_tom_text, (30, 530))
    # draw some lines between the instrument names
    for i in range(instrumnents):
        py.draw.line(screen, grey, (0, (i * 100) + 100), (200, (i * 100) + 100), 5)
    # check how many boxes there are for each instrument
    for i in range(beats):
        for j in range(instrumnents):
            if clicks[j][i] == -1:
                color = grey
            else:
                color = green
                # Making a tri-color effect with rects
            rect = py.draw.rect(screen, color, 
            [i * ((WIDTH - 200) // beats) + 205, (j * 100) + 5, ((WIDTH - 200) // beats) - 10, 
            ((HEIGHT- 200)// instrumnents) - 10], 0, 3)
            # Blank/ NOT colorful rect
            py.draw.rect(screen, gold, 
            [i * ((WIDTH - 200) // beats) + 200, (j * 100), ((WIDTH - 200) // beats), 
             ((HEIGHT- 200)// instrumnents)], 5, 5)
            py.draw.rect(screen, black, 
            [i * ((WIDTH - 200) // beats) + 200, (j * 100), ((WIDTH - 200) // beats), 
             ((HEIGHT- 200)// instrumnents)], 2, 5)
            boxes.append((rect, (i, j)))
        active = py.draw.rect(screen, blue, [beat * ((WIDTH-200)//beats) + 200, 0, 
                ((WIDTH-200)//beats), instrumnents*100], 5, 3)
    return boxes


# main loop
run = True
while run:
    timer.tick(FPS)
    screen.fill(black)
    boxes = draw_grid(clicked, active_beat)
    if beat_changed:
        play_notes()
        beat_changed = False

    for event in py.event.get():
        if event.type == py.QUIT:
            run = False
        if event.type == py.MOUSEBUTTONDOWN:
            for i in range(len(boxes)):
                if boxes[i][0].collidepoint(event.pos):
                    coords = boxes[i][1]
                    clicked[coords[1]][coords[0]] *= -1

    beat_length = 3600 // bpm

    if playing:
       if active_length < beat_length:
           active_length += 1
       else:
           active_length = 0
           if active_beat < beats - 1:
               active_beat += 1
               beat_changed = True
           else:
               active_beat  = 0
               beat_changed = True

    py.display.flip()
py.quit()

What it does so far:

Adding later: Different kits, a menu to select the kits, bpm change, and more.

def play_notes does as the name says… it plays the notes.

def draw_grid just makes the interface and puts them on the screen. It shows the names and the initial design of the program.

def draw_grid:

def draw_grid(clicks, beat):
    # Making the boxes for the interface
    left_box = py.draw.rect(screen, grey, [0, 0, 200, HEIGHT - 200], 5)
    bottom_box = py.draw.rect(screen, grey, [0, HEIGHT - 200, WIDTH, 200], 5)
    boxes = []
    colors = [grey, white, grey]
    # Making the names of all the instruments
    hi_hat_text = label_font.render('Hi-hat', True, white)
    screen.blit(hi_hat_text, (30, 30))
    snare_text = label_font.render('Snare', True, white)
    screen.blit(snare_text, (30, 130))
    kick_text = label_font.render('Kick', True, white)
    screen.blit(kick_text, (30, 230))
    crash_text = label_font.render('Crash', True, white)
    screen.blit(crash_text, (30, 330))
    clap_text = label_font.render('Clap', True, white)
    screen.blit(clap_text, (30, 430))
    floor_tom_text = label_font.render('Floor Tom', True, white)
    screen.blit(floor_tom_text, (30, 530))
    # draw some lines between the instrument names
    for i in range(instrumnents):
        py.draw.line(screen, grey, (0, (i * 100) + 100), (200, (i * 100) + 100), 5)
    # check how many boxes there are for each instrument
    for i in range(beats):
        for j in range(instrumnents):
            if clicks[j][i] == -1:
                color = grey
            else:
                color = green
                # Making a tri-color effect with rects
            rect = py.draw.rect(screen, color, 
            [i * ((WIDTH - 200) // beats) + 205, (j * 100) + 5, ((WIDTH - 200) // beats) - 10, 
            ((HEIGHT- 200)// instrumnents) - 10], 0, 3)
            # Blank/ NOT colorful rect
            py.draw.rect(screen, gold, 
            [i * ((WIDTH - 200) // beats) + 200, (j * 100), ((WIDTH - 200) // beats), 
             ((HEIGHT- 200)// instrumnents)], 5, 5)
            py.draw.rect(screen, black, 
            [i * ((WIDTH - 200) // beats) + 200, (j * 100), ((WIDTH - 200) // beats), 
             ((HEIGHT- 200)// instrumnents)], 2, 5)
            boxes.append((rect, (i, j)))
        active = py.draw.rect(screen, blue, [beat * ((WIDTH-200)//beats) + 200, 0, 
                ((WIDTH-200)//beats), instrumnents*100], 5, 3)
    return boxes

Author: Zende_

From PA. EHS 2025. Does computer programming and such. That's really it.

Leave a Reply

Your email address will not be published. Required fields are marked *