Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: bydariogamer/beatgame
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v1.0.6
Choose a base ref
...
head repository: bydariogamer/beatgame
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref

Commits on Apr 27, 2021

  1. Copy the full SHA
    cab4e41 View commit details
  2. Copy the full SHA
    332cc32 View commit details
  3. Copy the full SHA
    280ae90 View commit details
  4. Copy the full SHA
    a6fe8be View commit details
  5. added contributor

    I hope you like to see your name into the title screen ;)
    bydariogamer committed Apr 27, 2021
    Copy the full SHA
    e455d86 View commit details

Commits on Jun 22, 2022

  1. Copy the full SHA
    63e524c View commit details
  2. run black

    bydariogamer committed Jun 22, 2022
    Copy the full SHA
    783d77a View commit details

Commits on Jul 5, 2022

  1. reformatted main.py

    bydariogamer committed Jul 5, 2022
    Copy the full SHA
    bb40e61 View commit details

Commits on Jul 6, 2022

  1. Copy the full SHA
    fceaf0f View commit details
  2. Copy the full SHA
    a8d81cc View commit details
  3. remove old font

    bydariogamer committed Jul 6, 2022
    Copy the full SHA
    df377c5 View commit details
  4. update CREDITS.md

    bydariogamer committed Jul 6, 2022
    Copy the full SHA
    0845f04 View commit details

Commits on Jul 22, 2022

  1. BASE_FPS is integer

    bydariogamer committed Jul 22, 2022
    Copy the full SHA
    a1253d0 View commit details
  2. Copy the full SHA
    7fa6fb7 View commit details
  3. Copy the full SHA
    3deb457 View commit details
  4. Copy the full SHA
    5d279da View commit details

Commits on Jul 26, 2022

  1. Copy the full SHA
    bdc247e View commit details
  2. Copy the full SHA
    26b16ba View commit details
  3. Copy the full SHA
    659fa76 View commit details
  4. make title lower

    bydariogamer committed Jul 26, 2022
    Copy the full SHA
    796303e View commit details

Commits on Jul 27, 2022

  1. run black

    bydariogamer committed Jul 27, 2022
    Copy the full SHA
    84ebf7e View commit details

Commits on Dec 22, 2022

  1. Copy the full SHA
    5655476 View commit details
  2. update requirements.txt

    bydariogamer committed Dec 22, 2022
    Copy the full SHA
    3cf43d4 View commit details
  3. Copy the full SHA
    e128291 View commit details
  4. Copy the full SHA
    f108f45 View commit details
  5. Copy the full SHA
    97d609e View commit details
  6. Copy the full SHA
    8719d02 View commit details

Commits on Dec 24, 2022

  1. fix highscore saving

    bydariogamer committed Dec 24, 2022
    Copy the full SHA
    7089b21 View commit details

Commits on Dec 25, 2022

  1. update dogica.ttf

    bydariogamer committed Dec 25, 2022
    Copy the full SHA
    71d8f8c View commit details
  2. Copy the full SHA
    8d149bd View commit details
  3. Copy the full SHA
    b8e3efa View commit details
  4. Copy the full SHA
    b34ad6c View commit details

Commits on Dec 26, 2022

  1. Copy the full SHA
    d540f95 View commit details

Commits on Dec 27, 2022

  1. Copy the full SHA
    9874f95 View commit details
  2. improve code style

    bydariogamer committed Dec 27, 2022
    Copy the full SHA
    383577f View commit details

Commits on Dec 28, 2022

  1. Copy the full SHA
    31255ea View commit details
  2. fix ducked up physics

    bydariogamer committed Dec 28, 2022
    Copy the full SHA
    47c485a View commit details
  3. Copy the full SHA
    a4f6e45 View commit details

Commits on Jan 2, 2023

  1. remove unused variable

    bydariogamer committed Jan 2, 2023
    Copy the full SHA
    735d05d View commit details

Commits on Jan 6, 2023

  1. improve drawing system

    bydariogamer committed Jan 6, 2023
    Copy the full SHA
    518c387 View commit details
  2. Copy the full SHA
    79ca300 View commit details
48 changes: 27 additions & 21 deletions CREDITS.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
# SONGS
# [SONGS](assets/songs)

The following /assets/songs are from this package from Alexander Ehlers:
The following songs are from this package from Alexander Ehlers:
https://opengameart.org/content/free-music-pack
- doomed.ogg
- flags.ogg
- great mission.ogg
- spacetime.ogg
- twists.ogg
- waking the devil.ogg
- warped.ogg

The following /assets/songs are from this game from Peter Pserwylo:
https://github.com/beat-feet/beat-feet
- courtyard.ogg
- exercise_room.ogg
- laundry_room.ogg
- the_ballroom.ogg
- vivaldi.ogg (this is from Vivaldi obviously)
- [doomed.ogg](assets/songs/doomed.ogg)
- [flags.ogg](assets/songs/flags.ogg)
- [great_mission.ogg](assets/songs/great_mission.ogg)
- [spacetime.ogg](assets/songs/spacetime.ogg)
- [twists.ogg](assets/songs/twists.ogg)
- [waking_the_devil.ogg](assets/songs/waking_the_devil.ogg)
- [warped.ogg](assets/songs/warped.ogg)

The following songs are from [beat-feet](https://github.com/beat-feet/beat-feet)
by Peter Pserwylo:
- [courtyard.ogg](assets/songs/courtyard.ogg)
- [exercise_room.ogg](assets/songs/exercise_room.ogg)
- [laundry_room.ogg](assets/songs/laundry_room.ogg)
- [the_ballroom.ogg](assets/songs/the_ballroom.ogg)
- [vivaldi.ogg](assets/songs/vivaldi.ogg) (this one is from Vivaldi obviously)

The following song was made by [bydariogamer](https://github.com/bydariogamer):
- piloting waves.ogg
- [piloting_waves.ogg](assets/songs/piloting_waves.ogg)

The following song was made by [Sogolumbo](https://github.com/sogolumbo):
- metronome.ogg
- [metronome.ogg](assets/songs/metronome.ogg)

I am not actually sure about the license of the songs took from beatfeet,
I am not actually sure about the license of the songs took from beat-feet,
but I use them under the GPL license that applies to the game. If you want
to use them in other context check license in the repository linked above.
Most of them are under public domain as the metadata commentaries state.
@@ -34,9 +34,15 @@ The songs by bydariogamer and Sogolumbo are distributed under the Creative
Commons Attribution-ShareAlike 3.0 License (CC BY-SA 3.0).
Check CC BY-SA 3.0 at https://creativecommons.org/licenses/by-sa/3.0/

# IMAGES
# [IMAGES](assets/images)

All images in /assets/images were made by [bydariogamer](https://github.com/bydariogamer)
The images by bydariogamer are distributed under the Creative Commons
Attribution-ShareAlike 3.0 License (CC BY-SA 3.0).
Check CC BY-SA 3.0 at https://creativecommons.org/licenses/by-sa/3.0/

# [FONTS](assets/fonts)

The game font is [dogica](assets/fonts/dogica.ttf) and it is under the
SIL Open Font License (SIL OFL).
Check SIL OFL at https://scripts.sil.org/ofl/
Binary file removed assets/fonts/8bitOperatorPlus-Bold.ttf
Binary file not shown.
Binary file added assets/fonts/dogica.ttf
Binary file not shown.
File renamed without changes
File renamed without changes.
File renamed without changes.
File renamed without changes.
186 changes: 121 additions & 65 deletions bpm_finder.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import numpy as np
import config

if config.DEBUG_SHOW_LEVEL or config.DEBUG_BPM_FINDER:
from matplotlib import pyplot as plt

@@ -27,113 +28,168 @@ def argmax(signal):
# ignore maxima at the beginning and the end
a = 0
b = 0
while max_index == a or max_index == length-1-b:
while max_index == a or max_index == length - 1 - b:
if max_index == a:
a += 1
else:
b += 1
if length - a - b > 1:
max_index = np.argmax(signal[a:length-1-b]) + a
max_index = np.argmax(signal[a : length - 1 - b]) + a
else:
print('The only possible maximum is not fully in range!')
print("The only possible maximum is not fully in range!")
a = 0
b = 0
max_index = np.argmax(signal)
break
if a+b > 0:
print('Maximum at the beginning (', a, ') or end (', b, ') ignored')
if a + b > 0:
print("Maximum at the beginning (", a, ") or end (", b, ") ignored")
return max_index


def findBPMinRange(corrected_autocorrelation, minBPM, maxBPM, duration, fineAdjustRecursion=3):
def find_bpm_in_range(
corrected_autocorrelation, min_bpm, max_bpm, duration, fine_adjust_recursion=3
):
length = len(corrected_autocorrelation)
firstOffset = int(60/maxBPM/duration*length)
firstIndex = length//2 + firstOffset
lastOffset = int(60/minBPM/duration*length)
lastIndex = length//2 + lastOffset

interestingPart = corrected_autocorrelation[firstIndex:lastIndex]
n = 1 # uneven integer, not choosing one leads to worse results
ddinterestingPart = np.concatenate([np.zeros(n), np.diff(np.diff(interestingPart, n), n), np.zeros(n)])/(n**2) # dd is the second derivative

indexBeatLength = argmax(interestingPart) + firstOffset
indexBeatLength_dd = argmax(-ddinterestingPart) + firstOffset
BPM = length/indexBeatLength*60/duration
BPM_dd = length/indexBeatLength_dd*60/duration

def temposAreSimilar(a, b):
if abs(a - b) <= 1:
return True
if abs(2 * a - b) <= 1:
return True
if abs(a - 2 * b) <= 1:
return True
return False

first_offset = int(60 / max_bpm / duration * length)
first_index = length // 2 + first_offset
last_offset = int(60 / min_bpm / duration * length)
last_index = length // 2 + last_offset

interesting_part = corrected_autocorrelation[first_index:last_index]
n = 1 # uneven integer, not choosing one leads to worse results
dd_interesting_part = np.concatenate(
[np.zeros(n), np.diff(np.diff(interesting_part, n), n), np.zeros(n)]
) / (
n**2
) # dd is the second derivative

index_beat_length = argmax(interesting_part) + first_offset
index_beat_length_dd = argmax(-dd_interesting_part) + first_offset
bpm = length / index_beat_length * 60 / duration
bpm_dd = length / index_beat_length_dd * 60 / duration

def tempos_are_similar(a, b):
return abs(a - b) <= 1 or abs(2 * a - b) <= 1 or abs(a - 2 * b) <= 1

if config.DEBUG_BPM_FINDER:
xRange = range(firstOffset, lastOffset)
plt.plot(xRange, interestingPart)
plt.plot(xRange, -ddinterestingPart)
xRange = range(lastOffset)
plt.plot(xRange, corrected_autocorrelation[length//2: length//2 + lastOffset])
plt.scatter(indexBeatLength, interestingPart[indexBeatLength - firstOffset], label=str(BPM) + ' bpm')
plt.scatter(indexBeatLength_dd, -ddinterestingPart[indexBeatLength_dd - firstOffset], label=str(BPM_dd) + ' bpm')
x_range = range(first_offset, last_offset)
plt.plot(x_range, interesting_part)
plt.plot(x_range, -dd_interesting_part)
x_range = range(last_offset)
plt.plot(
x_range, corrected_autocorrelation[length // 2 : length // 2 + last_offset]
)
plt.scatter(
index_beat_length,
interesting_part[index_beat_length - first_offset],
label=str(bpm) + " bpm",
)
plt.scatter(
index_beat_length_dd,
-dd_interesting_part[index_beat_length_dd - first_offset],
label=str(bpm_dd) + " bpm",
)
plt.legend()
plt.show()

if not temposAreSimilar(indexBeatLength, indexBeatLength_dd):
if not tempos_are_similar(index_beat_length, index_beat_length_dd):
# Compare the quality of the findings by comparing the autocorrelation for 2, 3 and 4 beats
beats = np.array([2, 3, 4])
scores = np.zeros(len(beats))
scores_dd = np.zeros(len(beats))
for i, n in enumerate(beats):
scores[i] = corrected_autocorrelation[length//2 + n*indexBeatLength]
scores_dd[i] = corrected_autocorrelation[length//2 + n*indexBeatLength_dd]

scores[i] = corrected_autocorrelation[length // 2 + n * index_beat_length]
scores_dd[i] = corrected_autocorrelation[
length // 2 + n * index_beat_length_dd
]

if sum(scores) > sum(scores_dd):
rough_BPM = BPM
rough_bpm = bpm
else:
rough_BPM = BPM_dd
rough_bpm = bpm_dd

if config.DEBUG_BPM_FINDER:
print(' Non-trivial rhythm')
print(' index:', indexBeatLength, indexBeatLength_dd)
print(' bpm:', BPM, BPM_dd)

xRange = range(lastOffset*2)
plt.plot(xRange, corrected_autocorrelation[length//2: length//2 + lastOffset*2])
plt.scatter(indexBeatLength, interestingPart[indexBeatLength - firstOffset], label=str(BPM) + ' bpm')
plt.scatter(indexBeatLength_dd, -ddinterestingPart[indexBeatLength_dd - firstOffset], label=str(BPM_dd) + ' bpm')
plt.scatter(beats*indexBeatLength, scores, label=str(BPM) + ' bpm beats')
plt.scatter(beats*indexBeatLength_dd, scores_dd, label=str(BPM_dd) + ' bpm beats')
print(" Non-trivial rhythm")
print(" index:", index_beat_length, index_beat_length_dd)
print(" bpm:", bpm, bpm_dd)

x_range = range(last_offset * 2)
plt.plot(
x_range,
corrected_autocorrelation[length // 2 : length // 2 + last_offset * 2],
)
plt.scatter(
index_beat_length,
interesting_part[index_beat_length - first_offset],
label=str(bpm) + " bpm",
)
plt.scatter(
index_beat_length_dd,
-dd_interesting_part[index_beat_length_dd - first_offset],
label=str(bpm_dd) + " bpm",
)
plt.scatter(
beats * index_beat_length, scores, label=str(bpm) + " bpm beats"
)
plt.scatter(
beats * index_beat_length_dd,
scores_dd,
label=str(bpm_dd) + " bpm beats",
)
plt.legend()
plt.show()
else:
rough_BPM = BPM
rough_bpm = bpm
if config.DEBUG_BPM_FINDER:
print(' Tempos match: ', BPM, BPM_dd)
print(" Tempos match: ", bpm, bpm_dd)

if fineAdjustRecursion and (60/rough_BPM < duration/5):
if fine_adjust_recursion and (60 / rough_bpm < duration / 5):
variation = 0.08
if config.DEBUG_BPM_FINDER:
print('', fineAdjustRecursion, 'BPM-Range', rough_BPM*0.5*(1-variation), rough_BPM*0.5*(1+variation))
return 2*findBPMinRange(corrected_autocorrelation, rough_BPM*0.5*0.95, rough_BPM*0.5*1.05, duration, fineAdjustRecursion-1)
print(
"",
fine_adjust_recursion,
"bpm-Range",
rough_bpm * 0.5 * (1 - variation),
rough_bpm * 0.5 * (1 + variation),
)
return 2 * find_bpm_in_range(
corrected_autocorrelation,
rough_bpm * 0.5 * 0.95,
rough_bpm * 0.5 * 1.05,
duration,
fine_adjust_recursion - 1,
)
else:
return rough_BPM
return rough_bpm


def getBPM(song, duration):
def get_bpm(song, duration):
# Simplify signal
mono_signal= np.mean(song, 1)
mono_signal = np.mean(song, 1)
# subsample
len_subsampled = len(mono_signal) // config.BPM_FINDER_SUBSAMPLING
subsampled = np.zeros(len_subsampled)
for i in range(len_subsampled):
subsampled[i] = np.mean(np.abs(mono_signal[i*config.BPM_FINDER_SUBSAMPLING:(i+1)*config.BPM_FINDER_SUBSAMPLING]))
subsampled[i] = np.mean(
np.abs(
mono_signal[
i
* config.BPM_FINDER_SUBSAMPLING : (i + 1)
* config.BPM_FINDER_SUBSAMPLING
]
)
)
# tempo / autocorrelation
autocorrelation = np.correlate(subsampled, subsampled, 'same')
autocorrelation = np.correlate(subsampled, subsampled, "same")
corrected_autocorr = correct_autocorrelation(autocorrelation, len_subsampled)
BPM = findBPMinRange(corrected_autocorr, config.BPM_FINDER_MINIMUM, config.BPM_FINDER_MAXIMUM, duration, fineAdjustRecursion=3)
bpm = find_bpm_in_range(
corrected_autocorr,
config.BPM_FINDER_MINIMUM,
config.BPM_FINDER_MAXIMUM,
duration,
fine_adjust_recursion=3,
)
if config.DEBUG_BPM_FINDER:
print('BPM:', BPM)
return BPM
print("bpm:", bpm)
return bpm
31 changes: 21 additions & 10 deletions button.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import pygame

import config


class Button:
def __init__(self, color, x, y, width, height, outcolor=None, image=None):
@@ -24,19 +26,28 @@ def draw(self, window):
pygame.draw.rect(window, self.outcolor, self.rect)
if self.image:
if self.image_w < self.rect.w:
window.blit(self.image, (self.rect.x + (self.rect.w - self.image_w)/2, self.rect.y + (self.rect.h - self.image_h)/2))
window.blit(
self.image,
(
self.rect.x + (self.rect.w - self.image_w) / 2,
self.rect.y + (self.rect.h - self.image_h) / 2,
),
)
else:
window.blit(self.image, (self.rect.x + 1, self.rect.y + (self.rect.h - self.image_h) / 2))
window.blit(
self.image,
(self.rect.x + 1, self.rect.y + (self.rect.h - self.image_h) / 2),
)

def mouseover(self, resize=None):
if resize:
if self.rect.collidepoint(pygame.mouse.get_pos()[0]/resize[0], pygame.mouse.get_pos()[1]/resize[1]):
def mouseover(self):
if config.resize:
if self.rect.collidepoint(
pygame.mouse.get_pos()[0] / config.resize[0],
pygame.mouse.get_pos()[1] / config.resize[1],
):
return True
elif self.rect.collidepoint(pygame.mouse.get_pos()):
return True

def mouseclic(self, resize=None):
if self.mouseover(resize=resize) and pygame.mouse.get_pressed(num_buttons=3)[0]:
return True
else:
return False
def mouseclick(self):
return self.mouseover() and pygame.mouse.get_pressed(num_buttons=3)[0]
28 changes: 11 additions & 17 deletions colors.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
neon = {
'yellow': (0xFA, 0xED, 0x27),
'green': (0x39, 0xFF, 0x14),
'fucsia': (0xFE, 0x41, 0x64),
'red': (0xFD, 0x15, 0x32),
'cyan': (0xE0, 0xFF, 0xFF),
'blue': (0x40, 0xF2, 0xFE),
'orange': (0xFF, 0x5F, 0x1F),
'purple': (0xA1, 0x17, 0xF2)
}
metal = {
'gold': (0xD5, 0xBA, 0x4A),
'silver': (0xE3, 0xE4, 0xE5)
}
"yellow": (0xFA, 0xED, 0x27),
"green": (0x39, 0xFF, 0x14),
"fucsia": (0xFE, 0x41, 0x64),
"red": (0xFD, 0x15, 0x32),
"cyan": (0xE0, 0xFF, 0xFF),
"blue": (0x40, 0xF2, 0xFE),
"orange": (0xFF, 0x5F, 0x1F),
"purple": (0xA1, 0x17, 0xF2),
}
metal = {"gold": (0xD5, 0xBA, 0x4A), "silver": (0xE3, 0xE4, 0xE5)}

planets = {
'moon': (194, 197, 204),
'mars': (0xFE, 0x87, 0x5F)
}
planets = {"moon": (194, 197, 204), "mars": (0xFE, 0x87, 0x5F)}
Loading