[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] Timing question (newbie)



I've attached some very rough, proof of concept code I wrote for my students. It wants 2 command line arguments. The first is a sound file (mp3 or wav). The second has the times in seconds at which beats occur. I generated mine with aubiotrack. You feed it a wav file and it prints out times of the detected beat.

The program draws a little graph showing how close your key, mouse, or ddr pad presses are to the beat.

Very rough. It was just a test to see if this was even possible. I've got a team of students working on an accessible version of DDR for kids who are blind. They'll do a better job I'm sure.

gb

Miguel Sicart wrote:
Hi all,
I have a question about timing - I want to make a little game based on
rhythm input, a bit like dance dance revolution, patapon, or similar. The
idea is that the player has to press a key within a specific time, getting
more points the better the timing. And I have little idea how to do it.
I am thinking creating uservents, and the matching them to key input, but I
am a bit clueless about the timing thing. Any help is welcome!


Thanks a bunch!

M

HIT_TOL = 0.200
BEAT_TOL = 0.033

import sys
import os
import pygame
music = pygame.mixer.music
from bisect import bisect

pygame.mixer.pre_init(44100,-16,2,1024*2)
pygame.init()

songfile = sys.argv[1]
timefile = sys.argv[2]

music.load(songfile)

times = [ float(t.strip()) for t in file(timefile, 'rt') ]
def GetDelta(t):
    n = bisect(times, t)
    d1 = t - times[n-1]
    d2 = times[n] - t
    if d1 < d2:
        return -d1
    else:
        return d2

size = width, height = 320, 240
origin = height/2
scale = height/2
bar_w = 16
bar_n = width/bar_w

screen = pygame.display.set_mode(size, pygame.DOUBLEBUF | pygame.HWSURFACE)

try:
    joystick = pygame.joystick.Joystick(0)
    joystick.init()
except pygame.error:
    pass

music.play()

errors = []

run = True
while run:
    t = music.get_pos() * 0.001
    dt = GetDelta(t)
    hit = False
    for event in pygame.event.get():
        if event.type == pygame.QUIT: 
            run = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                run = False
            f = max(-1, min(1, (dt / HIT_TOL)))
            hit = abs(f) < 0.5
            errors.append(f)
        if event.type == pygame.JOYBUTTONDOWN or event.type == pygame.MOUSEBUTTONDOWN:
            f = max(-1, min(1, (dt / HIT_TOL)))
            hit = abs(f) < 0.5
            errors.append(f)
    else:
        pygame.time.wait(2)

    if abs(dt) < BEAT_TOL:
        screen.fill((255,255,255))
    else:
        screen.fill((0,0,0))
    for i,f in enumerate(errors[-bar_n:]):
        x1 = i*bar_w
        w = bar_w
        if f < 0:
            y1 = origin + f * scale
        else:
            y1 = origin
        h = abs(f) * scale
        if f < 0:
            c = (255,0,0)
        else:
            c = (0,255,0)
        screen.fill(c, pygame.Rect(x1, y1, w, h))
    pygame.display.flip()

print 'exiting'