started using level select object, added preview of animated alien

This commit is contained in:
frank 2022-01-29 17:52:14 -05:00
parent 7036ea9ed0
commit 62831ade79
4 changed files with 104 additions and 51 deletions

101
NS.py
View File

@ -1,5 +1,12 @@
# -*- coding: utf-8 -*-
#
# Scrapeboard is an arcade game in development by Frank DeMarco (@diskmem) and Blake Andrews (@snakesandrews).
# It requires custom hardware to play, but it can be tested in keyboard mode with just the code in this
# repository. For more information on setting up and running the game, see the README. For more information
# on the game in general, visit https://scrape.nugget.fun
#
import argparse
from random import randint, choice, random
from math import pi
@ -34,6 +41,13 @@ from lib.pgfw.pgfw.extension import (
from lib.pgfw.pgfw.gfx_extension import aa_filled_polygon
class NS(Game, Animation):
"""
The main game object for Scrapeboard. It initializes and manages most of the other game objects that only have a single
object like the title screen, boss manager, platform, dialog manager, screen wipe manager, main character, and more (see
the objects initialized in __init__). It initializes and manages the serial input from the Arduino, and it listens for and
responds to keyboard input. Its update method is called once per frame by the PGFW code. In its update method it calls the
update methods of its child objects.
"""
LNW, LNE, LSE, LSW = range(4)
N, NE, E, NW, S, W = range(6)
@ -130,6 +144,7 @@ class NS(Game, Animation):
ds = self.get_display_surface()
self.background = Surface(ds.get_size())
self.background.fill((0, 0, 0))
self.level_select = LevelSelect(self)
self.platform = Platform(self)
self.tony = Tony(self)
self.logo = Logo(self)
@ -202,6 +217,7 @@ class NS(Game, Animation):
self.score_hidden = False
self.idle_elapsed = 0
self.suppressing_input = False
self.level_select.reset()
self.title.reset()
if not leave_wipe_running:
self.wipe.reset()
@ -276,6 +292,7 @@ class NS(Game, Animation):
self.reset_arduino()
self.no_reset_elapsed = 0
self.title.update()
self.level_select.update()
self.ending.update()
self.boss.update()
if not self.title.active:
@ -288,6 +305,44 @@ class NS(Game, Animation):
self.reset()
class LevelSelect(GameChild):
"""
Display the available levels. Initialize a platform for each level and display each platform beneath its level glowing
with a pair of pads to press to start that level. Wait for user input, then launch the level of the pair that gets
pressed by the user.
"""
def __init__(self, parent):
GameChild.__init__(self, parent)
self.subscribe(self.respond, KEYDOWN)
def activate(self):
self.active = True
def deactivate(self):
self.active = False
def reset(self):
self.deactivate()
def respond(self, event):
if self.active:
launch_level = None
if event.key == K_1:
launch_level = 0
elif event.key == K_2:
launch_level = 1
elif event.key == K_3:
launch_level = 2
if launch_level is not None:
self.deactivate()
self.get_game().boss.start_level(launch_level)
def update(self):
if self.active:
self.get_display_surface().fill((255, 255, 0))
class Button(Sprite):
MARGIN = 2
@ -559,9 +614,13 @@ class Title(Animation):
self.halt()
def start_game(self):
"""
Turn off the title screen and display the level select. Set the most recent time to None so the most
recent high score stops blinking.
"""
self.deactivate()
self.get_game().set_most_recent_time(None)
self.get_game().boss.start_level(0)
self.get_game().level_select.activate()
def draw_scores(self):
step = 75
@ -610,19 +669,18 @@ class Title(Animation):
self.get_game().tony.set_frameset("board")
def update(self):
'''
Move title, check button presses, and draw screen
'''
"""
Scroll the background, check for button presses for the unlock pattern, handle switching between attract mode
with the GIFs active and unlocking pattern mode, and draw the screen
"""
Animation.update(self)
if self.active:
ds = self.get_display_surface()
dsr = ds.get_rect()
self.get_game().logo.update()
# advance unlock pattern
# Advance through the unlock pattern
platform = self.get_game().platform
if not self.get_game().wipe.is_playing() and platform.get_edge_pressed() == self.UNLOCK_MOVES[self.unlock_index]:
# self.first_pressed = True
# self.first_pressed_elapsed = 0
if self.unlock_index == len(self.UNLOCK_MOVES) - 1:
platform.set_glowing([])
self.get_game().wipe.start(self.start_game)
@ -631,13 +689,8 @@ class Title(Animation):
self.unlock_index += 1
platform.set_glowing(platform.get_buttons_from_edges([self.UNLOCK_MOVES[self.unlock_index]]))
self.get_audio().play_sfx("land_0")
# reset unlock pattern if idle
# if self.first_pressed:
# self.first_pressed_elapsed += self.get_game().time_filter.get_last_frame_duration()
# if self.first_pressed_elapsed > 1000 * 10:
# self.reset()
self.get_game().tony.update()
# bounce the gif around the screen
# Bounce the GIF around the screen
if self.video.location.right > dsr.right or self.video.location.left < dsr.left:
self.angle = reflect_angle(self.angle, 0)
if self.video.location.right > dsr.right:
@ -1159,11 +1212,6 @@ class Light(Animation):
shifted = []
for point in self.get_points():
shifted.append((point[0], point[1] - y))
# ratio = 1 - float(y + 1) / (self.MAX_GLOW_INDEX + 1)
# alpha = int(ratio * 255)
# color = Color(self.color.r, self.color.g, self.color.b, alpha)
# ds = self.get_display_surface()
# intermediate = Surface(ds.get_size(), SRCALPHA)
if self.position == NS.LSW:
saturation = 0
else:
@ -1179,7 +1227,6 @@ class Light(Animation):
),
True, shifted, 3
)
# ds.blit(intermediate, (0, 0))
def in_orientation(self, orientation):
if self.position == NS.LNW:
@ -1346,20 +1393,28 @@ class Boys(Meter):
class Boss(Animation):
"""
The Boss object also serves as the level object, and it is expected that only one of these objects is initialized.
Its drawing, animations, timings, etc will be determined by the level_index member variable. For example, if
level_index is 0, the kool man sprite will be drawn, but if level_index is 2, the spoopy sprite will be drawn.
"""
def __init__(self, parent):
"""
Load graphics for boss sprites, avatars, and backgrounds. Initialize boss health and swords objects. Register
animations that control attacks, effects, and dialog.
"""
Animation.__init__(self, parent)
if self.get_configuration("display", "effects"):
self.kool_man = RainbowSprite(self, load(self.get_resource("Kool_man_waah.png")).convert_alpha(), hue_shift)
self.visitor = RainbowSprite(self, load(self.get_resource("Visitor.png")).convert_alpha(), hue_shift)
self.spoopy = RainbowSprite(self, load(self.get_resource("Spoopy.png")).convert_alpha(), hue_shift)
else:
self.kool_man = Sprite(self)
self.kool_man.load_from_path("Kool_man_waah.png", True)
self.visitor = Sprite(self)
self.visitor.load_from_path("Visitor.png", True)
self.spoopy = Sprite(self)
self.spoopy.load_from_path("Spoopy.png", True)
self.visitor = Sprite(self, 42)
self.visitor.load_from_path("alienAnimations/alienBoil", True)
for sprite in self.kool_man, self.visitor, self.spoopy:
sprite.location.topleft = 100, 0
self.health = Health(self)
@ -1367,7 +1422,7 @@ class Boss(Animation):
self.register(self.brandish, self.cancel_flash, self.show_introduction_dialogue,
self.show_end_dialogue, self.end_dialogue)
self.kool_man.add_frameset([0], name="normal", switch=True)
self.visitor.add_frameset([0], name="normal", switch=True)
self.visitor.add_frameset(list(range(0, len(self.visitor.frames))), name="normal", switch=True)
self.spoopy.add_frameset([0], name="normal", switch=True)
self.kool_man_avatar = load(self.get_resource("Kool_man_avatar.png")).convert()
self.visitor_avatar = load(self.get_resource("Visitor_avatar.png")).convert()

View File

@ -1,33 +1,19 @@
#!/usr/bin/env python3
from os import environ, execvp, chdir, getcwd
from os.path import exists, join, dirname
from sys import version_info, argv
#
# Scrapeboard is an arcade game in development by Frank DeMarco (@diskmem) and Blake Andrews (@snakesandrews).
# It requires custom hardware to play, but it can be tested in keyboard mode with just the code in this
# repository. For more information on setting up and running the game, see the README. For more information
# on the game in general, visit https://scrape.nugget.fun
#
# This is the launcher script that creates a main game object and runs it. If you're running Python 3 with
# the pygame module installed, you should be able to run this script with the --no-serial flag to get it
# running even without the custom hardware:
#
# ./OPEN-GAME --no-serial
#
def can_import(module_name):
try:
__import__(module_name)
except ImportError:
return False
else:
return True
def is_python_3():
return version_info[0] >= 3
def is_current_version(file_name):
version = map(int, file_name.replace("python", "").split("."))
return version == list(version_info)[:2]
def launch_alternative(alternatives):
for alternative in alternatives:
if not is_current_version(alternative):
for root in environ["PATH"].split(":"):
if exists(join(root, alternative)):
execvp(alternative, [alternative] + argv)
def move_to_executable():
chdir(dirname(argv[0]))
from sys import argv
if "--go-to-dir" in argv:
move_to_executable()

12
config
View File

@ -1,3 +1,15 @@
#
# Scrapeboard is an arcade game in development by Frank DeMarco (@diskmem) and Blake Andrews (@snakesandrews).
# It requires custom hardware to play, but it can be tested in keyboard mode with just the code in this
# repository. For more information on setting up and running the game, see the README. For more information
# on the game in general, visit https://scrape.nugget.fun
#
# This file contains configurable values that can adjust things like visual effects, performance, and audio.
# A lot of these values are closely tied to how the game is expected to run (for example, the screen resolution),
# but they can still be played around with. There are also a lot of values currently hardcoded in NS.py that
# should be moved into here eventually.
#
[setup]
license = Public Domain
title = Scrapeboard

@ -1 +1 @@
Subproject commit 285181d23b789492b4b0186be1cacf160e89672a
Subproject commit 6693ca45140aa67df7a6b0622a98d8d5b59079a3