--- a/monsterz.py +++ b/monsterz.py @@ -12,6 +12,8 @@ http://sam.zoy.org/projects/COPYING.WTFPL for more details. """ +import asyncio +import time import pygame from pygame.locals import * from random import randint @@ -106,58 +108,38 @@ return y[2] - x[2] def semi_grayscale(surf): - try: - pixels = pygame.surfarray.pixels3d(surf) - alpha = pygame.surfarray.pixels_alpha(surf) - except: - pass - else: - # Convert to semi-grayscale - for y, line in enumerate(pixels): - for x, p in enumerate(line): - r, g, b = p - M = int(max(r, g, b)) - m = int(min(r, g, b)) - val = (2 * M + r + g + b) // 5 - p[0] = (val + r) // 2 - p[1] = (val + g) // 2 - p[2] = (val + b) // 2 - if alpha[y][x] >= 250: - alpha[y][x] = 255 - (M - m) * 3 // 4 - del pixels - del alpha - surf.unlock() + # Convert to semi-grayscale (pixel by pixel: the numpy-based pygame.surfarray is not available on the web) + for x in range(surf.get_width()): + for y in range(surf.get_height()): + r, g, b, a = surf.get_at((x, y)) + M = max(r, g, b) + m = min(r, g, b) + val = (2 * M + r + g + b) // 5 + if a >= 250: + a = 255 - (M - m) * 3 // 4 + surf.set_at((x, y), ((val + r) // 2, (val + g) // 2, (val + b) // 2, a)) def semi_transp(surf): - try: - # Convert to semi-transparency - pixels = pygame.surfarray.pixels3d(surf) - alpha = pygame.surfarray.pixels_alpha(surf) - except: - # If it did not work, make it empty - surf.fill((0, 0, 0, 0)) - else: - for y, line in enumerate(pixels): - for x, p in enumerate(line): - r, g, b = p - M = int(max(r, g, b)) - m = int(min(r, g, b)) - p[0] = (m + r) // 2 - p[1] = (m + g) // 2 - p[2] = (m + b) // 2 - if alpha[y][x] >= 250: - alpha[y][x] = 255 - M * 2 // 3 - del pixels - del alpha - surf.unlock() + # Convert to semi-transparency + for x in range(surf.get_width()): + for y in range(surf.get_height()): + r, g, b, a = surf.get_at((x, y)) + M = max(r, g, b) + m = min(r, g, b) + if a >= 250: + a = 255 - M * 2 // 3 + surf.set_at((x, y), ((m + r) // 2, (m + g) // 2, (m + b) // 2, a)) def username(): if platform == 'win32': from os import environ return environ.get('USER') or environ.get('USERNAME') or 'You' - from pwd import getpwuid - from os import geteuid - return getpwuid(geteuid())[0] + try: + from pwd import getpwuid + from os import geteuid + return getpwuid(geteuid())[0] + except Exception: + return 'You' # no user database in a browser class Settings: def __init__(self, scorefile, outfd): @@ -171,6 +153,9 @@ configdir = join(tmp, 'monsterz') else: configdir = join(dirname(argv[0]), 'settings') + elif isdir('/saves'): + # on the web the page keeps the /saves folder in the browser + configdir = '/saves/monsterz' else: configdir = join(expanduser('~'), '.monsterz') # Make sure our directory exists @@ -317,7 +302,7 @@ for s in ['click', 'grunt', 'ding', 'whip', 'pop', 'duh', \ 'boing', 'applause', 'laugh', 'warning']: self.wav[s] = pygame.mixer.Sound(join(dir, 'sound', s + '.wav')) - pygame.mixer.music.load(join(dir, 'sound', 'music.s3m')) + pygame.mixer.music.load(join(dir, 'sound', 'music.ogg')) pygame.mixer.music.set_volume(0.9) # Play immediately pygame.mixer.music.play(-1, 0.0) @@ -1268,8 +1253,9 @@ self.clock = pygame.time.Clock() self.timer = 0 - def go(self): + async def go(self): while True: + frame_start = time.time() if self.status == STATUS_MENU: self.marea = None iterator = self.iterate_menu @@ -1283,15 +1269,15 @@ elif self.status == STATUS_SCORES: iterator = self.iterate_scores elif self.status == STATUS_QUIT: - break + # nothing to quit to on a web page: back to the menu + self.status = STATUS_MENU + continue self.status = None iterator() system.flip() self.timer += 1 - self.clock.tick(12) - # Close the display, but give time to hear the last sample - pygame.display.quit() - self.clock.tick(2) + # 12 frames per second, without keeping the browser busy + await asyncio.sleep(max(0.0, 1.0 / 12 - (time.time() - frame_start))) def copyright_draw(self): scroll = pygame.Surface((406, 40)).convert_alpha() @@ -1352,13 +1338,6 @@ c = list(map(lambda a, b: b - (b - a) * self.gsat[1] // 255, r, color)) system.blit(led, (440, 408)) system.blit(fonter.render('MUSIC', 30, c), (470, 406)) - if settings.get('fullscreen'): - led, color = data.led_on, (255, 255, 255) - else: - led, color = data.led_off, (180, 150, 127) - c = list(map(lambda a, b: b - (b - a) * self.gsat[2] // 255, r, color)) - system.blit(led, (440, 438)) - system.blit(fonter.render('FULLSCREEN', 30, c), (470, 436)) for x in range(3): if self.gsat[x]: self.gsat[x] = self.gsat[x] * 8 // 10 @@ -1367,9 +1346,6 @@ if event.type == QUIT: self.status = STATUS_QUIT return True - elif event.type == KEYDOWN and event.key == K_f: - system.toggle_fullscreen() - return True if system.have_sound: if event.type == KEYDOWN and event.key == K_s: system.toggle_sfx() @@ -1386,9 +1362,6 @@ elif 440 < x < 440 + 180 and 408 < y < 408 + 24: system.toggle_music() return True - if 440 < x < 440 + 180 and 438 < y < 438 + 24: - system.toggle_fullscreen() - return True return False wander_monster=randint(0,ITEMS-1) @@ -1986,12 +1959,12 @@ print() print('Report bugs or suggestions to .') -def main(): +async def main(): from getopt import getopt, GetoptError global system, data, settings, fonter, monsterz override = {} scorefile = None - sharedir = dirname(argv[0]) + sharedir = '.' # the game folder is the working directory outfd = None try: long = ['help', 'version', 'music', 'sound', 'fullscreen', @@ -2035,10 +2008,9 @@ raise fonter = Fonter() monsterz = Monsterz() - monsterz.go() + await monsterz.go() settings.save() - exit() if __name__ == '__main__': - main() + asyncio.run(main())