forum

osu! python edition

posted
Total Posts
18
Topic Starter
superloach
I've very recently started work on an osu! client written in python3, using the pygame and tkinter libraries.
It's nothing much so far, mostly because it's also my first time using those libraries. :P

So far, it has:
  • intro screen
  • file picker if not passed as argument (python3 osu.py <...>.osz)
  • warnings for various errors (not a zip, missing osu files, etc.)
  • song name, artist, etc. detection from map filename, not metadata section
  • list difficulties and choose
  • list map section headers
code (sorry it's sloppy and uses some unreadable backwards workarounds):
#!/usr/bin/python3

fps = 60
size = (500,500)

import sys,os,zipfile,shutil
from math import *

try:
import tkinter as tk
from tkinter import filedialog
from tkinter import simpledialog as easy
from tkinter import messagebox
except:
print("Sorry, you need tkinter to choose a file.\nIf you want, you can just run `python3 osu.py <filename>` for now.")
sys.exit()
else:
root = tk.Tk()
root.withdraw()

try:
import pygame
except:
messagebox.showerror("missing library","Sorry, you need pygame to play.",type="ok")
sys.exit()

def col(a):return pygame.Color(str(a))

curdir = os.path.dirname(os.path.abspath(__file__))
impath = os.path.realpath((sys.argv+[""])[1])
tmpdir = os.path.join(curdir,"tmp",'')
mapdir = os.path.join(curdir,"maps",'')
fntdir = os.path.join(curdir,"fonts",'')

a='retry'
if os.path.isdir(impath):
while a == 'retry':
impath = filedialog.askopenfilename(initialdir=mapdir,title="Select Map")
if len(impath) == 0:
a=messagebox.showerror("cancellation","File selection cancelled.",type="retrycancel")
if a == 'cancel':
sys.exit()
else:
a = 'other thing'
try:
with zipfile.ZipFile(impath,'r') as osz:
osz.extractall(tmpdir)
except zipfile.BadZipFile:
messagebox.showerror("format error","Not even a valid zip file. Sad.")
a='retry'

files = os.listdir(tmpdir)

maps = []
hasbg = False
hassong = False
hasmap = False
for file in files:
if file[-3:] == "png" or file[-3:] == "jpg" or file[-4:] == "jpeg":
hasbg = True
if file[-3:] == "mp3" or file[-3:] == "wav":
hassong = True
if file[-3:] == "osu":
hasmap = True
maps = maps + [tmpdir+file]

if hasbg == False or hassong == False or hasmap == False:
messagebox.showerror("format error","Not a valid osz. Missing a song, background, and/or map file(s).")
sys.exit()

name = os.path.split(maps[0])[-1].split('.')[0].split('[')[0]
artist = name.split(' - ')[0]
songname = name.split(' - ')[1].split(' (')[0]
creator = name.split(' (')[1].split(') ')[0]

#print('name: '+name)
#print('artist: '+artist)
#print('song name: '+songname)
#print('creator: '+creator)

diffs = []
for mapname in maps:
diffs = diffs+[os.path.split(mapname)[-1].split('.')[0].split('[')[1].split(']')[0]]

pygame.init()
screen = pygame.display.set_mode(size)
pygame.display.set_caption("osu! python edition")
clock = pygame.time.Clock()

lilfont = pygame.font.Font(os.path.join(fntdir,'lil.ttf'),25)
bigfont = pygame.font.Font(os.path.join(fntdir,'big.ttf'),90)
tinfont = pygame.font.Font(os.path.join(fntdir,'lil.ttf'),11)

logo = pygame.transform.scale(pygame.image.load(os.path.join(curdir,"icon.png")),(3*size[0]//4,3*size[1]//4))
pygame.display.set_icon(pygame.transform.scale(logo,(32,32)))

done = False
ticks = 0
truefps = 0
secs = 0
chosendiff = ""
page = 0
sections = []
content = ""
version = ""
sectitles = []
keys = [pygame.K_1,pygame.K_2,pygame.K_3,pygame.K_4,pygame.K_5,pygame.K_6,pygame.K_7,pygame.K_8,pygame.K_9,pygame.K_0]
chosendiff = None
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
a=messagebox.askquestion(" ","Really leave osu! python edition?",type="yesno")
if a == 'yes':
done = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
done = True

if page == 0:
screen.fill(col('magenta'))
screen.blit(logo,(size[0]//8,size[1]//8))

if page == 1:
screen.fill(col('pink'))

text=lilfont.render("artist - "+artist,True,col('cyan'))
screen.blit(text,(10,10))

text=lilfont.render("song name - "+songname,True,col('orange'))
screen.blit(text,(10,40))

text=lilfont.render("creator - "+creator,True,col('green'))
screen.blit(text,(10,70))

pygame.display.set_caption(songname)

text = lilfont.render("Difficulties:",True,col('black'))
screen.blit(text,(10,120))

i = 0
for diff in diffs:
text = lilfont.render(str(int(i+1))+") "+diff,True,col('black'))
screen.blit(text,(25,30*i+150))
i = i + 1

pygame.display.flip()

if chosendiff == None:
chosendiff = easy.askinteger(" ","Pick a map \N{number sign}:")
else:
page = 2

if page == 2:
screen.fill(col('white'))
pygame.display.set_caption(songname + " - " + diffs[chosendiff-1])
map = maps[chosendiff-1]

if len(content) == 0:
content = open(map,'r').read()

if len(sections) == 0:
sections = content.split('\n\n')
i = 0
for sect in sections:
lines = sect.split('\n')
if not lines[0].startswith('[') and len(version) == 0:
version = lines[0]

if lines[0].startswith('[') and lines[0].endswith(']'):
sectitles = sectitles + [lines[0][1:-1]]

i = i + 1

text = tinfont.render('['+'], ['.join(sectitles)+']',True,col('blue'))
screen.blit(text,(10,45))

text = lilfont.render(version,True,col('black'))
screen.blit(text,(10,10))

if round(ticks/fps,0) == ticks/fps and round(ticks/fps,0) > 0:
truefps = int(ticks//round(ticks/fps,0))

if secs > 2.5 and page == 0:page = 1

text = lilfont.render(str(truefps)+" fps",True,col('yellow'))
screen.blit(text,(10,size[1]-45))

secs = ticks//fps
clock.tick(fps)
ticks = ticks + 1
pygame.display.flip()

pygame.quit()
shutil.rmtree(tmpdir)

I saw mention in a thread about a JS/HTML5 port (https://osu.ppy.sh/forum/t/36805) that peppy would be willing to give advice on parsing mapfiles... hope I can get some of those tips! :D
Topic Starter
superloach
here's a link to a zip with all necessary files in it:
https://nofile.io/f/1Sm32xb6fyQ/osu!py.zip

yes, I found the logo font, but didn't use it. fight me. >:( :P
ZeroxPlaysOsu
If you're going to work on such a big project, I would give you the following advice

1-Don't put all your code in one file, be modular and divide in multiple files
2-Use a source control system like github or bitbucket that way you always have an older version to go back to if ever something terrible were to happen (I'm assuming you aren't using any since you posted your code directly in your post)

Good luck ;)
Kondou-Shinichi
but why???
ZeroxPlaysOsu

Kondou-Shinichi wrote:

but why???
I'm guessing just to hone his/her programming skills
anu
Github is a really good idea.

People can look at the code and offer help.
Jamu
hot
fxolin5
Very cool. I saw someone remake it in java as well which is great for portability without having to compile it each time for different systems.
TicClick

P o n y wrote:

how the fuck am i supposed to install "pygame", never heard of it, and why the fuck did they make it hell to install

https://docs.python.org/3/tutorial/venv.html
https://www.pygame.org/wiki/GettingStarted
abraker

P o n y wrote:

how the fuck am i supposed to install "pygame", never heard of it, and why the fuck did they make it hell to install

you must not be familiar with python... pygame is a popular library for python used to make games with

pygame can be download using pip via console command
pip install pygame
Mr Sonic
Sorry, but I will not install pygame just to look at how is your progress, where are the screenshots?
FireRedz

Mr Sonic wrote:

Sorry, but I will not install pygame just to look at how is your progress, where are the screenshots?


it takes less than 10 minutes to install python and pygame
abraker

Mr Sonic wrote:

Sorry, but I will not install pygame just to look at how is your progress, where are the screenshots?
Yes screenshot would be good, but also....



FireRedz wrote:

Mr Sonic wrote:

Sorry, but I will not install pygame just to look at how is your progress, where are the screenshots?


it takes less than 10 minutes to install python and pygame
KnownError
As others have said here, you should definitely use a open-source version control hosting service like GitHub or GitLab.

There have been a few people complaining about installation, and honestly while Python and Pygame are relatively easy to install, for most people that's too complicated. The solution is to use PyInstaller to create a Windows EXE.

pip install pyinstaller
pyinstaller --onefile code.py
./dist myprog
jawabomber09
nice
brobeast
I won't go that far
and good luck
Exiled_

superloach wrote:

here's a link to a zip with all necessary files in it:
https://nofile.io/f/1Sm32xb6fyQ/osu!py.zip

yes, I found the logo font, but didn't use it. fight me. >:( :P
Just wondering is this still downloadable?
krafi
And I have created osu with pyqt5 and tkinter 🤣🤣 sadly no one showing interest
community/forums/topics/1829687?n=1

I wish, osu form should have "haha" reacts...
I was thinking 🤔 making OSU client with pygame is like mission impossible, intended we should try Godot (python engine 🚂)
And why the hell the link is removed?! Are you trying to make close source 😤 ,
Please sign in to reply.

New reply