right and left input, static on title screen, button prompts

This commit is contained in:
ohsqueezy 2023-01-01 11:33:34 -08:00
parent 673cf69d80
commit f0328cd5ad
3 changed files with 179 additions and 93 deletions

11
config
View File

@ -11,19 +11,23 @@ package-root = electric_sieve
init-script = electric-sieve init-script = electric-sieve
[display] [display]
caption = Electric Sieve caption = iBITFIT
#dimensions = 420, 700 #dimensions = 420, 700
dimensions = 480, 720 dimensions = 480, 720
score-font-path = font/Titan-One.ttf score-font-path = font/Titan-One.ttf
title-font-path = font/Oxygen.ttf title-font-path = font/Oxygen.ttf
scoreboard-font-path = font/terminus/Terminus.ttf scoreboard-font-path = font/terminus/Terminus-Bold.ttf
initials-font = font/terminus/Terminus-Bold.ttf initials-font = font/terminus/Terminus-Bold.ttf
show-framerate = yes show-framerate = no
rotate = no rotate = no
[mouse] [mouse]
visible = no visible = no
[input]
title-hold = 2000
initials-hold = 1000
[keys] [keys]
quit = K_ESCAPE quit = K_ESCAPE
advance = K_RETURN advance = K_RETURN
@ -39,6 +43,7 @@ path = high-scores
[audio] [audio]
title = aud/Meld.ogg title = aud/Meld.ogg
title-advance = aud/It.wav title-advance = aud/It.wav
title-fade = 30000
triangles = aud/777.ogg triangles = aud/777.ogg
hit = aud/Skinball.wav hit = aud/Skinball.wav
miss = aud/0Sj-99_Em.wav miss = aud/0Sj-99_Em.wav

View File

@ -14,7 +14,7 @@ from pygame.locals import *
from lib.pgfw.pgfw.Game import Game from lib.pgfw.pgfw.Game import Game
from lib.pgfw.pgfw.GameChild import GameChild from lib.pgfw.pgfw.GameChild import GameChild
from lib.pgfw.pgfw.Sprite import Sprite from lib.pgfw.pgfw.Sprite import Sprite, BlinkingSprite
from lib.pgfw.pgfw.Vector import Vector from lib.pgfw.pgfw.Vector import Vector
from lib.pgfw.pgfw.extension import render_box from lib.pgfw.pgfw.extension import render_box
@ -47,6 +47,14 @@ class ElectricSieve(Game):
{ {
"bool": "rotate" "bool": "rotate"
}, },
"input":
{
"int": ["title-hold", "initials-hold"]
},
"audio":
{
"int": "title-fade"
},
"land": "land":
{ {
"int": ["gradient", "height", "x-step"], "int": ["gradient", "height", "x-step"],
@ -163,35 +171,35 @@ class ElectricSieve(Game):
return rotated return rotated
def update(self): def update(self):
self.title.update()
# Test if the level is being played # Test if the level is being played
if self.triangles.active: if self.triangles.active:
# Draw grid effect # Draw grid effect
self.land.update() self.land.update()
# Set the background alpha low to create a trail effect on the triangles.
#self.background.set_alpha(255 * 0.1)
# Draw the alpha background only to the trail effect surface. This will partially erase the previous drawings of the triangles.
#self.trail_effect.blit(self.background, (0, 0))
# Draw triangles onto the trail effect surface, update position # Draw triangles onto the trail effect surface, update position
self.triangles.update() self.triangles.update()
# Set alpha back to full for drawing the bottom layer background if not self.title.active:
#self.background.set_alpha(255) # Draw bottom layer background
self.get_display_surface().blit(self.background, (0, 0)) self.get_display_surface().blit(self.background, (0, 0))
# Draw static behind objects on title screen
if self.title.active:
self.static.update()
# Draw the triangles to the screen, using the intermediate trail effect surface # Draw the triangles to the screen, using the intermediate trail effect surface
self.get_display_surface().blit(self.trail_effect, (0, 0)) self.get_display_surface().blit(self.trail_effect, (0, 0))
self.title.update()
# Draw the sieve # Draw the sieve
self.sieve.update() self.sieve.update()
# Draw the static if not self.title.active:
self.static.update()
# Draw the static
self.static.update()
class Title(GameChild): class Title(GameChild):
@ -232,6 +240,13 @@ class Title(GameChild):
# cx = self.display_surface.get_rect().centerx # cx = self.display_surface.get_rect().centerx
# captions[0].location.center = cx, 301 # captions[0].location.center = cx, 301
# captions[1].location.center = cx, 398 # captions[1].location.center = cx, 398
self.button_prompt = BlinkingSprite(self, 500)
font = pygame.font.Font(self.get_resource("terminus/Terminus.ttf"), 32)
self.button_prompt.add_frame(self.get_game().orient(font.render("HOLD LEFT OR RIGHT TO PLAY", True, pygame.Color(0, 0, 0), pygame.Color(255, 255, 255))))
if not self.get_game().rotated:
self.button_prompt.location.midbottom = self.get_display_surface().get_rect().midbottom
else:
self.button_prompt.location.midright = self.get_display_surface().get_rect().midright
self.scoreboard = Scoreboard(self) self.scoreboard = Scoreboard(self)
self.music = Sound(self.get_resource("audio", "title")) self.music = Sound(self.get_resource("audio", "title"))
self.advance = Sound(self.get_resource("audio", "title-advance")) self.advance = Sound(self.get_resource("audio", "title-advance"))
@ -239,17 +254,27 @@ class Title(GameChild):
def respond(self, event): def respond(self, event):
if self.active: if self.active:
if self.delegate.compare(event, "advance"): self.idle_time = 0
self.deactivate() if not self.music.get_num_channels():
self.parent.triangles.activate() self.music.play(-1, 0, 1000)
self.parent.sieve.activate() self.get_game().static.noise.fadeout(1000)
self.parent.static.activate() if self.delegate.compare(event, "left", cancel=False) or self.delegate.compare(event, "right", cancel=False):
self.advance.play() self.holding_button = True
self.get_display_surface().blit(self.get_game().background, (0, 0)) elif self.delegate.compare(event, "left", cancel=True) or self.delegate.compare(event, "right", cancel=True):
self.holding_button = False
self.holding_button_elapsed = 0
def activate(self): def activate(self):
self.active = True self.active = True
self.holding_button = False
self.holding_button_elapsed = 0
self.idle_time = 0
self.music.play(-1) self.music.play(-1)
self.get_game().static.activate()
self.get_game().static.full()
self.get_game().static.noise.stop()
self.get_game().sieve.activate()
self.get_game().triangles.activate(music=False)
def deactivate(self): def deactivate(self):
self.active = False self.active = False
@ -257,10 +282,39 @@ class Title(GameChild):
def update(self): def update(self):
if self.active: if self.active:
self.display_surface.blit(self.background, (0, 0)) if self.holding_button_elapsed > self.get_configuration("input", "title-hold"):
# for caption in self.captions: self.deactivate()
# caption.update() self.parent.triangles.reset()
self.scoreboard.update() while self.parent.triangles:
self.parent.triangles.pop()
self.parent.triangles.activate()
self.parent.sieve.activate()
self.parent.static.reset()
self.parent.static.activate()
self.advance.play()
self.get_game().trail_effect.fill(Color(0, 0, 0, 0))
self.get_display_surface().blit(self.get_game().background, (0, 0))
else:
if self.idle_time > self.get_configuration("audio", "title-fade"):
self.music.fadeout(5000)
if not self.get_game().static.noise.get_num_channels():
self.get_game().static.noise.set_volume(0.25)
self.get_game().static.noise.play(-1, 0, 5000)
else:
self.idle_time += self.get_game().time_filter.get_last_frame_duration()
if self.holding_button:
self.holding_button_elapsed += self.get_game().time_filter.get_last_frame_duration()
logo = Sprite(self)
font = pygame.font.Font(self.get_resource("terminus/TerminusItalic.ttf"),
62 + int(self.holding_button_elapsed / self.get_configuration("input", "title-hold") * 72))
logo.add_frame(self.get_game().orient(font.render("iBITFIT", True, pygame.Color(0, 0, 0), pygame.Color(255, 255, 255))))
if not self.get_game().rotated:
logo.location.midtop = self.get_display_surface().get_rect().midtop
else:
logo.location.midleft = self.get_display_surface().get_rect().midleft
logo.update()
self.button_prompt.update()
self.scoreboard.update()
class Strip(Sprite): class Strip(Sprite):
@ -346,12 +400,13 @@ class Scoreboard(GameChild):
BACKGROUND = 255, 255, 255 BACKGROUND = 255, 255, 255
FOREGROUND = 27, 27, 27 FOREGROUND = 27, 27, 27
NEW = 27, 27, 27 NEW = 27, 27, 27
SPACING = 70 SPACING = 45
MARGIN = 30 MARGIN = 0
BLINK_INTERVAL = 400 BLINK_INTERVAL = 400
PADDING = 6 PADDING = 0
BORDER = 1 BORDER = 1
SCORE_COUNT = 9 SCORE_COUNT = 11
SIZES = [32, 28, 24, 22, 22, 20, 20, 20, 18, 18, 18]
def __init__(self, parent): def __init__(self, parent):
GameChild.__init__(self, parent) GameChild.__init__(self, parent)
@ -363,41 +418,39 @@ class Scoreboard(GameChild):
def load(self): def load(self):
self.sprites = sprites = [] self.sprites = sprites = []
font_path = self.get_resource("display", "scoreboard-font-path") font_path = self.get_resource("display", "scoreboard-font-path")
sizes = [24] * self.SCORE_COUNT
blink = False blink = False
for ii, score in enumerate(self.get_scores()[:len(sizes)]): for ii, score in enumerate(self.get_scores()[:len(self.SIZES)]):
font = Font(font_path, sizes[ii]) font = Font(font_path, self.SIZES[ii])
sprites.append((Sprite(self, self.BLINK_INTERVAL), sprites.append((Sprite(self, self.BLINK_INTERVAL), Sprite(self, self.BLINK_INTERVAL)))
Sprite(self, self.BLINK_INTERVAL)))
score_text = str(score[1]) score_text = str(score[1])
color = self.BACKGROUND if (self.most_recent_score and not blink and score[1:] == \ color = self.BACKGROUND if (self.most_recent_score and not blink and score[1:] == self.most_recent_score) else self.FOREGROUND
self.most_recent_score) else self.FOREGROUND
score_plate = font.render(score_text, False, color, self.BACKGROUND) score_plate = font.render(score_text, False, color, self.BACKGROUND)
rect = score_plate.get_rect() rect = score_plate.get_rect()
surface = Surface(rect.inflate((2, 2)).size) surface = Surface(rect.inflate((2, 2)).size)
surface.fill(self.FOREGROUND) surface.fill(self.FOREGROUND)
rect.center = surface.get_rect().center rect.center = surface.get_rect().center
surface.blit(score_plate, rect) surface.blit(score_plate, rect)
width = 80
sprites[ii][1].add_frame(self.get_game().orient( sprites[ii][1].add_frame(self.get_game().orient(
render_box(font, score_text, False, color, self.BACKGROUND, self.FOREGROUND, self.BORDER, self.PADDING))) render_box(font, score_text, True, color, self.BACKGROUND, (0, 0, 0), padding=self.PADDING, width=width)))
sprites[ii][0].add_frame(self.get_game().orient( sprites[ii][0].add_frame(self.get_game().orient(
render_box(font, score[2], False, color, self.BACKGROUND, self.FOREGROUND, self.BORDER, self.PADDING))) render_box(font, score[2], True, color, self.BACKGROUND, (0, 0, 0), padding=self.PADDING, width=width)))
if self.most_recent_score and not blink and score[1:] == self.most_recent_score: if self.most_recent_score and not blink and score[1:] == self.most_recent_score:
sprites[ii][1].add_frame(self.get_game().orient( sprites[ii][1].add_frame(self.get_game().orient(
render_box(font, score_text, False, self.NEW, self.BACKGROUND, self.FOREGROUND, self.BORDER, self.PADDING))) render_box(font, score_text, True, self.NEW, self.BACKGROUND, (0, 0, 0), padding=self.PADDING, width=width)))
sprites[ii][0].add_frame(self.get_game().orient( sprites[ii][0].add_frame(self.get_game().orient(
render_box(font, score[2], False, self.NEW, self.BACKGROUND, self.FOREGROUND, self.BORDER, self.PADDING))) render_box(font, score[2], True, self.NEW, self.BACKGROUND, (0, 0, 0), padding=self.PADDING, width=width)))
blink = True blink = True
if not self.get_game().rotated: if not self.get_game().rotated:
sprites[ii][0].location.left = self.MARGIN sprites[ii][0].location.left = self.MARGIN
sprites[ii][1].location.right = self.get_display_surface().get_rect().right - self.MARGIN sprites[ii][1].location.right = self.get_display_surface().get_rect().right - self.MARGIN
y = self.get_display_surface().get_rect().centery + self.SPACING * (ii - len(sizes) / 2) y = self.get_display_surface().get_rect().centery + self.SPACING * (ii - len(self.SIZES) / 2)
for sprite in sprites[ii]: for sprite in sprites[ii]:
sprite.location.centery = y sprite.location.centery = y
else: else:
sprites[ii][0].location.bottom = self.get_display_surface().get_height() - self.MARGIN sprites[ii][0].location.bottom = self.get_display_surface().get_height() - self.MARGIN
sprites[ii][1].location.top = self.MARGIN sprites[ii][1].location.top = self.MARGIN
x = self.get_display_surface().get_rect().centerx + self.SPACING * (ii - len(sizes) / 2) x = self.get_display_surface().get_rect().centerx + self.SPACING * (ii - len(self.SIZES) / 2)
for sprite in sprites[ii]: for sprite in sprites[ii]:
sprite.location.centerx = x sprite.location.centerx = x
@ -588,9 +641,10 @@ class Triangles(GameChild, list):
def get_boost(self): def get_boost(self):
return self.booster.get_change() return self.booster.get_change()
def activate(self): def activate(self, music=True):
self.active = True self.active = True
self.music.play(-1, 0, 500) if music:
self.music.play(-1, 0, 500)
def update(self): def update(self):
if self.active: if self.active:
@ -600,9 +654,10 @@ class Triangles(GameChild, list):
sieve = self.parent.sieve sieve = self.parent.sieve
removed = False removed = False
if self[0].location.colliderect(sieve.electric.location): if self[0].location.colliderect(sieve.electric.location):
self.parent.acid.increase() if not self.get_game().title.active:
self.streak += 1 self.parent.acid.increase()
self.score += self.streak ** .8 + self.parent.acid.get_volume() * 5 + self[0].count self.streak += 1
self.score += self.streak ** .8 + self.parent.acid.get_volume() * 5 + self[0].count
self.remove(self[0]) self.remove(self[0])
self.hit.play() self.hit.play()
removed = True removed = True
@ -614,9 +669,10 @@ class Triangles(GameChild, list):
br_offset = (sieve.location.left, 0) if not self.get_game().rotated else \ br_offset = (sieve.location.left, 0) if not self.get_game().rotated else \
(0, sieve.location.bottom - self.get_display_surface().get_height()) (0, sieve.location.bottom - self.get_display_surface().get_height())
if tr.move(tr_offset).colliderect(br.move(br_offset)): if tr.move(tr_offset).colliderect(br.move(br_offset)):
if not self.get_game().title.active:
self.parent.static.increase()
self.streak = 0
self.remove(self[0]) self.remove(self[0])
self.parent.static.increase()
self.streak = 0
self.miss.play() self.miss.play()
removed = True removed = True
break break
@ -768,13 +824,14 @@ class Static(Sprite):
def respond(self, event): def respond(self, event):
if self.active and self.complete and not self.initials.active: if self.active and self.complete and not self.initials.active:
if self.delegate.compare(event, "advance"): if self.delegate.compare(event, "left") or self.delegate.compare(event, "right"):
if self.get_game().triangles.score > \ if self.get_game().triangles.score > self.get_game().title.scoreboard.get_scores()[Scoreboard.SCORE_COUNT - 1][1]:
self.get_game().title.scoreboard.get_scores()[Scoreboard.SCORE_COUNT - 1][1]:
self.total.deactivate() self.total.deactivate()
self.initials.activate() self.initials.activate()
else: else:
self.finish(wipe=True) self.finish(wipe=True)
self.get_delegate().cancel_propagation()
self.get_game().suppress_input_temporarily(500)
def finish(self, text="---", wipe=False): def finish(self, text="---", wipe=False):
if wipe: if wipe:
@ -796,26 +853,30 @@ class Static(Sprite):
if self.increaser.time >= self.increaser.nodeset[-1].x + 5000: if self.increaser.time >= self.increaser.nodeset[-1].x + 5000:
self.increaser.time = self.increaser.nodeset[-1].x + 5000 self.increaser.time = self.increaser.nodeset[-1].x + 5000
def full(self):
self.intensity = 1
def activate(self): def activate(self):
self.active = True self.active = True
self.noise.play(-1) self.noise.play(-1)
def update(self): def update(self):
if self.active: if self.active:
if not self.complete and self.intensity >= .65: if not self.get_game().title.active:
self.complete = True if not self.complete and self.intensity >= .65:
self.parent.sieve.deactivate() self.complete = True
self.parent.triangles.deactivate() self.parent.sieve.deactivate()
self.set_alpha(255) self.parent.triangles.deactivate()
self.noise.fadeout(6000) self.set_alpha(255)
self.end.play(-1, 0, 4000) self.noise.fadeout(6000)
self.total.load() self.end.play(-1, 0, 4000)
elif not self.complete: self.total.load()
self.set_alpha(min(150, int(self.intensity * 1.15 * 255))) elif not self.complete:
if self.intensity > 0: self.set_alpha(min(150, int(self.intensity * 1.15 * 255)))
self.intensity *= .998 if self.intensity > 0:
self.increaser.update() self.intensity *= .998
self.noise.set_volume(self.intensity) self.increaser.update()
self.noise.set_volume(self.intensity)
if self.intensity > .1: if self.intensity > .1:
Sprite.update(self) Sprite.update(self)
self.total.update() self.total.update()
@ -828,11 +889,18 @@ class Initials(GameChild):
FOREGROUND = 27, 27, 27 FOREGROUND = 27, 27, 27
BACKGROUND = 255, 255, 255 BACKGROUND = 255, 255, 255
PADDING = 10 PADDING = 10
ARROW_MARGIN = 40 ARROW_MARGIN = 20
ARROW_HEIGHT = 10 ARROW_HEIGHT = 10
def __init__(self, parent): def __init__(self, parent):
GameChild.__init__(self, parent) GameChild.__init__(self, parent)
self.button_prompt = BlinkingSprite(self, 500)
font = pygame.font.Font(self.get_resource("terminus/Terminus.ttf"), 32)
self.button_prompt.add_frame(self.get_game().orient(font.render("HOLD RIGHT TO ENTER", True, pygame.Color(0, 0, 0), pygame.Color(255, 255, 255))))
if not self.get_game().rotated:
self.button_prompt.location.midbottom = self.get_display_surface().get_rect().midbottom
else:
self.button_prompt.location.midright = self.get_display_surface().get_rect().midright
self.reset() self.reset()
self.deactivate() self.deactivate()
self.font = Font(self.get_resource("display", "initials-font"), self.LETTER_SIZE) self.font = Font(self.get_resource("display", "initials-font"), self.LETTER_SIZE)
@ -841,6 +909,8 @@ class Initials(GameChild):
def reset(self): def reset(self):
self.text = "---" self.text = "---"
self.index = 0 self.index = 0
self.holding_button = False
self.holding_button_elapsed = 0
def deactivate(self): def deactivate(self):
self.active = False self.active = False
@ -848,21 +918,15 @@ class Initials(GameChild):
def respond(self, event): def respond(self, event):
if self.active: if self.active:
compare = self.get_game().delegate.compare compare = self.get_game().delegate.compare
if compare(event, "right") or compare(event, "advance"): if compare(event, "right", cancel=False):
self.index += 1 self.holding_button = True
if self.index == len(self.text): elif compare(event, "right", cancel=True):
self.index = 0 self.holding_button = False
if compare(event, "advance"): self.holding_button_elapsed = 0
self.deactivate() if compare(event, "right", cancel=True) or compare(event, "left", cancel=True):
self.parent.finish(self.text) if compare(event, "right", cancel=True):
elif compare(event, "left"):
self.index -= 1
if self.index == -1:
self.index = len(self.text) - 1
elif compare(event, "up") or compare(event, "down"):
if compare(event, "up"):
increment = 1 increment = 1
elif compare(event, "down"): elif compare(event, "left", cancel=True):
increment = -1 increment = -1
letter = self.text[self.index] letter = self.text[self.index]
if letter == '-': if letter == '-':
@ -885,6 +949,19 @@ class Initials(GameChild):
def update(self): def update(self):
if self.active: if self.active:
ds = self.get_display_surface() ds = self.get_display_surface()
self.button_prompt.update()
if self.holding_button:
self.holding_button_elapsed += self.get_game().time_filter.get_last_frame_duration()
if self.holding_button_elapsed > self.get_configuration("input", "initials-hold"):
self.index += 1
if self.index == len(self.text):
self.deactivate()
self.parent.finish(self.text)
self.reset()
else:
self.holding_button = False
self.holding_button_elapsed = 0
self.get_game().suppress_input_temporarily(500)
for ii, letter in enumerate(self.text): for ii, letter in enumerate(self.text):
box = self.get_game().orient(render_box( box = self.get_game().orient(render_box(
self.font, letter, False, self.FOREGROUND, self.BACKGROUND, self.FOREGROUND, padding=self.PADDING)) self.font, letter, False, self.FOREGROUND, self.BACKGROUND, self.FOREGROUND, padding=self.PADDING))
@ -897,16 +974,19 @@ class Initials(GameChild):
rect.centery = (len(self.text) - 1 - ii) * ds.get_height() / 3 + ds.get_height() / 6 rect.centery = (len(self.text) - 1 - ii) * ds.get_height() / 3 + ds.get_height() / 6
ds.blit(box, rect) ds.blit(box, rect)
if ii == self.index: if ii == self.index:
hold_offset = self.holding_button_elapsed / self.get_configuration("input", "initials-hold") * 10
if not self.get_game().rotated: if not self.get_game().rotated:
margin = self.ARROW_MARGIN x = rect.left - self.ARROW_MARGIN
left_points = ((x, rect.top), (x, rect.bottom), (x - self.ARROW_HEIGHT, rect.centery))
x = rect.right + self.ARROW_MARGIN + hold_offset
right_points = ((x, rect.top), (x, rect.bottom), (x + self.ARROW_HEIGHT, rect.centery))
else: else:
margin = self.ARROW_MARGIN // 2 y = rect.top - self.ARROW_MARGIN - hold_offset
polygon(ds, (0, 255, 0), ((rect.left, rect.top - margin), left_points = ((rect.left, y), (rect.right, y), (rect.centerx, y - self.ARROW_HEIGHT))
(rect.right, rect.top - margin), y = rect.bottom + self.ARROW_MARGIN
(rect.centerx, rect.top - margin - self.ARROW_HEIGHT))) right_points = ((rect.left, y), (rect.right, y), (rect.centerx, y + self.ARROW_HEIGHT))
polygon(ds, (0, 255, 0), ((rect.left, rect.bottom + margin), pygame.draw.polygon(ds, pygame.Color(0, 0, 0), left_points)
(rect.right, rect.bottom + margin), pygame.draw.polygon(ds, pygame.Color(0, 0, 0), right_points)
(rect.centerx, rect.bottom + margin + self.ARROW_HEIGHT)))
class Total(Sprite): class Total(Sprite):

View File

@ -1,3 +1,5 @@
1398631170.296798 140 FIT
1398631170.296798 100 FIT
1398631170.296798 80 FIT 1398631170.296798 80 FIT
1398631170.296798 60 FIT 1398631170.296798 60 FIT
1398631170.296798 50 FIT 1398631170.296798 50 FIT
@ -7,4 +9,3 @@
1398635792.99 20 FIT 1398635792.99 20 FIT
1398635792.99 15 FIT 1398635792.99 15 FIT
1398635792.99 10 FIT 1398635792.99 10 FIT
1672460647.69491 211 ---