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
[display]
caption = Electric Sieve
caption = iBITFIT
#dimensions = 420, 700
dimensions = 480, 720
score-font-path = font/Titan-One.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
show-framerate = yes
show-framerate = no
rotate = no
[mouse]
visible = no
[input]
title-hold = 2000
initials-hold = 1000
[keys]
quit = K_ESCAPE
advance = K_RETURN
@ -39,6 +43,7 @@ path = high-scores
[audio]
title = aud/Meld.ogg
title-advance = aud/It.wav
title-fade = 30000
triangles = aud/777.ogg
hit = aud/Skinball.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.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.extension import render_box
@ -47,6 +47,14 @@ class ElectricSieve(Game):
{
"bool": "rotate"
},
"input":
{
"int": ["title-hold", "initials-hold"]
},
"audio":
{
"int": "title-fade"
},
"land":
{
"int": ["gradient", "height", "x-step"],
@ -163,35 +171,35 @@ class ElectricSieve(Game):
return rotated
def update(self):
self.title.update()
# Test if the level is being played
if self.triangles.active:
# Draw grid effect
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
self.triangles.update()
# Set alpha back to full for drawing the bottom layer background
#self.background.set_alpha(255)
self.get_display_surface().blit(self.background, (0, 0))
if not self.title.active:
# Draw bottom layer background
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
self.get_display_surface().blit(self.trail_effect, (0, 0))
self.title.update()
# Draw the sieve
self.sieve.update()
# Draw the static
self.static.update()
if not self.title.active:
# Draw the static
self.static.update()
class Title(GameChild):
@ -232,6 +240,13 @@ class Title(GameChild):
# cx = self.display_surface.get_rect().centerx
# captions[0].location.center = cx, 301
# 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.music = Sound(self.get_resource("audio", "title"))
self.advance = Sound(self.get_resource("audio", "title-advance"))
@ -239,17 +254,27 @@ class Title(GameChild):
def respond(self, event):
if self.active:
if self.delegate.compare(event, "advance"):
self.deactivate()
self.parent.triangles.activate()
self.parent.sieve.activate()
self.parent.static.activate()
self.advance.play()
self.get_display_surface().blit(self.get_game().background, (0, 0))
self.idle_time = 0
if not self.music.get_num_channels():
self.music.play(-1, 0, 1000)
self.get_game().static.noise.fadeout(1000)
if self.delegate.compare(event, "left", cancel=False) or self.delegate.compare(event, "right", cancel=False):
self.holding_button = True
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):
self.active = True
self.holding_button = False
self.holding_button_elapsed = 0
self.idle_time = 0
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):
self.active = False
@ -257,10 +282,39 @@ class Title(GameChild):
def update(self):
if self.active:
self.display_surface.blit(self.background, (0, 0))
# for caption in self.captions:
# caption.update()
self.scoreboard.update()
if self.holding_button_elapsed > self.get_configuration("input", "title-hold"):
self.deactivate()
self.parent.triangles.reset()
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):
@ -346,12 +400,13 @@ class Scoreboard(GameChild):
BACKGROUND = 255, 255, 255
FOREGROUND = 27, 27, 27
NEW = 27, 27, 27
SPACING = 70
MARGIN = 30
SPACING = 45
MARGIN = 0
BLINK_INTERVAL = 400
PADDING = 6
PADDING = 0
BORDER = 1
SCORE_COUNT = 9
SCORE_COUNT = 11
SIZES = [32, 28, 24, 22, 22, 20, 20, 20, 18, 18, 18]
def __init__(self, parent):
GameChild.__init__(self, parent)
@ -363,41 +418,39 @@ class Scoreboard(GameChild):
def load(self):
self.sprites = sprites = []
font_path = self.get_resource("display", "scoreboard-font-path")
sizes = [24] * self.SCORE_COUNT
blink = False
for ii, score in enumerate(self.get_scores()[:len(sizes)]):
font = Font(font_path, sizes[ii])
sprites.append((Sprite(self, self.BLINK_INTERVAL),
Sprite(self, self.BLINK_INTERVAL)))
for ii, score in enumerate(self.get_scores()[:len(self.SIZES)]):
font = Font(font_path, self.SIZES[ii])
sprites.append((Sprite(self, self.BLINK_INTERVAL), Sprite(self, self.BLINK_INTERVAL)))
score_text = str(score[1])
color = self.BACKGROUND if (self.most_recent_score and not blink and score[1:] == \
self.most_recent_score) else self.FOREGROUND
color = self.BACKGROUND if (self.most_recent_score and not blink and score[1:] == self.most_recent_score) else self.FOREGROUND
score_plate = font.render(score_text, False, color, self.BACKGROUND)
rect = score_plate.get_rect()
surface = Surface(rect.inflate((2, 2)).size)
surface.fill(self.FOREGROUND)
rect.center = surface.get_rect().center
surface.blit(score_plate, rect)
width = 80
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(
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:
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(
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
if not self.get_game().rotated:
sprites[ii][0].location.left = 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]:
sprite.location.centery = y
else:
sprites[ii][0].location.bottom = self.get_display_surface().get_height() - 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]:
sprite.location.centerx = x
@ -588,9 +641,10 @@ class Triangles(GameChild, list):
def get_boost(self):
return self.booster.get_change()
def activate(self):
def activate(self, music=True):
self.active = True
self.music.play(-1, 0, 500)
if music:
self.music.play(-1, 0, 500)
def update(self):
if self.active:
@ -600,9 +654,10 @@ class Triangles(GameChild, list):
sieve = self.parent.sieve
removed = False
if self[0].location.colliderect(sieve.electric.location):
self.parent.acid.increase()
self.streak += 1
self.score += self.streak ** .8 + self.parent.acid.get_volume() * 5 + self[0].count
if not self.get_game().title.active:
self.parent.acid.increase()
self.streak += 1
self.score += self.streak ** .8 + self.parent.acid.get_volume() * 5 + self[0].count
self.remove(self[0])
self.hit.play()
removed = True
@ -614,9 +669,10 @@ class Triangles(GameChild, list):
br_offset = (sieve.location.left, 0) if not self.get_game().rotated else \
(0, sieve.location.bottom - self.get_display_surface().get_height())
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.parent.static.increase()
self.streak = 0
self.miss.play()
removed = True
break
@ -768,13 +824,14 @@ class Static(Sprite):
def respond(self, event):
if self.active and self.complete and not self.initials.active:
if self.delegate.compare(event, "advance"):
if self.get_game().triangles.score > \
self.get_game().title.scoreboard.get_scores()[Scoreboard.SCORE_COUNT - 1][1]:
if self.delegate.compare(event, "left") or self.delegate.compare(event, "right"):
if self.get_game().triangles.score > self.get_game().title.scoreboard.get_scores()[Scoreboard.SCORE_COUNT - 1][1]:
self.total.deactivate()
self.initials.activate()
else:
self.finish(wipe=True)
self.get_delegate().cancel_propagation()
self.get_game().suppress_input_temporarily(500)
def finish(self, text="---", wipe=False):
if wipe:
@ -796,26 +853,30 @@ class Static(Sprite):
if 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):
self.active = True
self.noise.play(-1)
def update(self):
if self.active:
if not self.complete and self.intensity >= .65:
self.complete = True
self.parent.sieve.deactivate()
self.parent.triangles.deactivate()
self.set_alpha(255)
self.noise.fadeout(6000)
self.end.play(-1, 0, 4000)
self.total.load()
elif not self.complete:
self.set_alpha(min(150, int(self.intensity * 1.15 * 255)))
if self.intensity > 0:
self.intensity *= .998
self.increaser.update()
self.noise.set_volume(self.intensity)
if not self.get_game().title.active:
if not self.complete and self.intensity >= .65:
self.complete = True
self.parent.sieve.deactivate()
self.parent.triangles.deactivate()
self.set_alpha(255)
self.noise.fadeout(6000)
self.end.play(-1, 0, 4000)
self.total.load()
elif not self.complete:
self.set_alpha(min(150, int(self.intensity * 1.15 * 255)))
if self.intensity > 0:
self.intensity *= .998
self.increaser.update()
self.noise.set_volume(self.intensity)
if self.intensity > .1:
Sprite.update(self)
self.total.update()
@ -828,11 +889,18 @@ class Initials(GameChild):
FOREGROUND = 27, 27, 27
BACKGROUND = 255, 255, 255
PADDING = 10
ARROW_MARGIN = 40
ARROW_MARGIN = 20
ARROW_HEIGHT = 10
def __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.deactivate()
self.font = Font(self.get_resource("display", "initials-font"), self.LETTER_SIZE)
@ -841,6 +909,8 @@ class Initials(GameChild):
def reset(self):
self.text = "---"
self.index = 0
self.holding_button = False
self.holding_button_elapsed = 0
def deactivate(self):
self.active = False
@ -848,21 +918,15 @@ class Initials(GameChild):
def respond(self, event):
if self.active:
compare = self.get_game().delegate.compare
if compare(event, "right") or compare(event, "advance"):
self.index += 1
if self.index == len(self.text):
self.index = 0
if compare(event, "advance"):
self.deactivate()
self.parent.finish(self.text)
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"):
if compare(event, "right", cancel=False):
self.holding_button = True
elif compare(event, "right", cancel=True):
self.holding_button = False
self.holding_button_elapsed = 0
if compare(event, "right", cancel=True) or compare(event, "left", cancel=True):
if compare(event, "right", cancel=True):
increment = 1
elif compare(event, "down"):
elif compare(event, "left", cancel=True):
increment = -1
letter = self.text[self.index]
if letter == '-':
@ -885,6 +949,19 @@ class Initials(GameChild):
def update(self):
if self.active:
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):
box = self.get_game().orient(render_box(
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
ds.blit(box, rect)
if ii == self.index:
hold_offset = self.holding_button_elapsed / self.get_configuration("input", "initials-hold") * 10
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:
margin = self.ARROW_MARGIN // 2
polygon(ds, (0, 255, 0), ((rect.left, rect.top - margin),
(rect.right, rect.top - margin),
(rect.centerx, rect.top - margin - self.ARROW_HEIGHT)))
polygon(ds, (0, 255, 0), ((rect.left, rect.bottom + margin),
(rect.right, rect.bottom + margin),
(rect.centerx, rect.bottom + margin + self.ARROW_HEIGHT)))
y = rect.top - self.ARROW_MARGIN - hold_offset
left_points = ((rect.left, y), (rect.right, y), (rect.centerx, y - self.ARROW_HEIGHT))
y = rect.bottom + self.ARROW_MARGIN
right_points = ((rect.left, y), (rect.right, y), (rect.centerx, y + self.ARROW_HEIGHT))
pygame.draw.polygon(ds, pygame.Color(0, 0, 0), left_points)
pygame.draw.polygon(ds, pygame.Color(0, 0, 0), right_points)
class Total(Sprite):

View File

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