option to rotate display 90 degrees

This commit is contained in:
ohsqueezy 2022-12-16 10:55:00 -05:00
parent 2e84e3d916
commit ced7540262
4 changed files with 211 additions and 78 deletions

5
config
View File

@ -1,7 +1,7 @@
[setup]
title = Electric Sieve
url = http://A-O.in/
contact-email = frank.s.demarco@gmail.com
url = https://shampoo.ooo
contact-email = mailbox@shampoo.ooo
contact-name = Frank DeMarco
summary = UFOs fracking your skull in 1920s America
version = 0.1.1
@ -18,6 +18,7 @@ title-font-path = font/Oxygen.ttf
scoreboard-font-path = font/terminus/Terminus.ttf
initials-font = font/terminus/Terminus-Bold.ttf
show-framerate = yes
rotate = no
[mouse]
visible = no

View File

@ -5,6 +5,7 @@ from random import randint, randrange, choice
from time import time
from operator import itemgetter
import pygame
from pygame import Surface, PixelArray, Rect
from pygame.draw import aalines, polygon
from pygame.font import Font
@ -14,6 +15,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.Vector import Vector
from lib.pgfw.pgfw.extension import render_box
# Import GPIO library if available
@ -36,11 +38,27 @@ class ElectricSieve(Game):
"""
# Initialize super
Game.__init__(self)
# Add type declarations for custom config entries
self.get_configuration().type_declarations.add("bool", "display", "rotate")
# Rotate the display if requested in the configuration
self.is_rotated = False
if self.get_configuration("display", "rotate"):
self.display.rotate()
self.is_rotated = True
# Initialize GPIO input and callbacks if GPIO library is loaded
if "RPi.GPIO" in sys.modules:
self.initialize_gpio()
# Create game objects
self.title = Title(self)
self.sieve = Sieve(self)
self.triangles = Triangles(self)
self.acid = Acid(self)
self.static = Static(self)
# Create a purple background
self.background = Surface(self.display.screen.get_size())
self.background.fill((255, 80, 190))
@ -81,13 +99,55 @@ class ElectricSieve(Game):
self.input.post_command("right", cancel=cancel)
self.input.post_any_command(id=pin, cancel=cancel)
def set_children(self):
Game.set_children(self)
self.title = Title(self)
self.sieve = Sieve(self)
self.triangles = Triangles(self)
self.acid = Acid(self)
self.static = Static(self)
def rotated(self):
"""
@returns True if display has been rotated, False otherwise
"""
return self.is_rotated
def orient(self, geometry, reference=None):
"""
Orient the passed pgfw.Vector, pygame.Rect, or pygame.Surface so it is rotated if necessary.
@param geometry A pgfw.Vector or pygame.Rect to rotate
@return Either a new pgfw.Vector or pygame.Rect depending on which was passed
"""
if not self.rotated():
return geometry
else:
if isinstance(geometry, Vector):
return self.rotated_point(geometry, reference)
elif isinstance(geometry, pygame.Rect):
return self.rotated_rect(geometry, reference)
elif isinstance(geometry, pygame.Surface):
return pygame.transform.rotate(geometry, 90)
def rotated_point(self, point, reference=None):
"""
Return a new pgfw.Vector with the X and Y values of a pgfw.Vector rotated 90 degrees.
@param point pgfw.Vector to rotate in place
@return rotated pgfw.Vector
"""
if reference is None:
reference = self.get_display_surface()
return Vector(reference.get_height() - point.x, point.y)
def rotated_rect(self, rect, reference=None):
"""
Return a new pygame.Rect rotated 90 degrees.
@param rect pygame.Rect to rotate in place
@return rotated pygame.Rect
"""
if reference is None:
reference = self.get_display_surface()
rotated = pygame.Rect(0, 0, 0, 0)
rotated.x = rect.y
rotated.y = reference.get_height() - rect.x + rect.w
rotated.w = rect.h
rotated.h = rect.w
return rotated
def update(self):
self.title.update()
@ -108,8 +168,8 @@ class Title(GameChild):
self.background = surface = Surface(self.display_surface.get_size())
tile = Surface((2, 2))
tile.fill(bg_color)
tile.set_at((0, 1), (220, 119, 41))
tile.set_at((1, 0), (220, 119, 41))
tile.set_at(self.get_game().orient(Vector(0, 1)), (220, 119, 41))
tile.set_at(self.get_game().orient(Vector(1, 0)), (220, 119, 41))
for y in range(0, surface.get_height(), 2):
for x in range(0, surface.get_width(), 2):
surface.blit(tile, (x, y))
@ -208,7 +268,10 @@ class Strip(Sprite):
for shift in self.hshifts:
shift.update()
if shift.time:
self.move(shift.get_change())
if not self.get_game().rotated():
self.move(shift.get_change())
else:
self.move(dy=shift.get_change())
Sprite.update(self)
@ -228,11 +291,9 @@ class Shift(GameChild):
def update(self):
least, greatest = self.nodeset[0].x, self.nodeset[-1].x
if self.active and self.time < greatest:
self.time = min(self.time + self.timer.get_last_frame_duration(),
greatest)
self.time = min(self.time + self.timer.get_last_frame_duration(), greatest)
elif not self.active and self.time > least:
self.time = max(self.time - self.timer.get_last_frame_duration(),
least)
self.time = max(self.time - self.timer.get_last_frame_duration(), least)
def get_change(self):
return self.nodeset.get_y(self.time) * self.direction
@ -275,21 +336,28 @@ class Scoreboard(GameChild):
surface.fill(self.FOREGROUND)
rect.center = surface.get_rect().center
surface.blit(score_plate, rect)
sprites[ii][1].add_frame(render_box(font, score_text, False, color,
self.BACKGROUND, self.FOREGROUND, self.BORDER, self.PADDING))
sprites[ii][0].add_frame(render_box(font, score[2], False, color,
self.BACKGROUND, self.FOREGROUND, self.BORDER, self.PADDING))
sprites[ii][1].add_frame(self.get_game().orient(
render_box(font, score_text, False, color, self.BACKGROUND, self.FOREGROUND, self.BORDER, self.PADDING)))
sprites[ii][0].add_frame(self.get_game().orient(
render_box(font, score[2], False, color, self.BACKGROUND, self.FOREGROUND, self.BORDER, self.PADDING)))
if self.most_recent_score and not blink and score[1:] == self.most_recent_score:
sprites[ii][1].add_frame(render_box(font, score_text, False, self.NEW,
self.BACKGROUND, self.FOREGROUND, self.BORDER, self.PADDING))
sprites[ii][0].add_frame(render_box(font, score[2], False, self.NEW,
self.BACKGROUND, self.FOREGROUND, self.BORDER, self.PADDING))
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)))
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)))
blink = True
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)
for sprite in sprites[ii]:
sprite.location.centery = y
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)
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)
for sprite in sprites[ii]:
sprite.location.centerx = x
def get_scores(self):
scores = []
@ -320,7 +388,12 @@ class Sieve(Strip):
Strip.__init__(self, parent)
self.delegate = self.get_game().delegate
self.electric = Electric(self)
self.add_location(offset=(self.location.w, 0))
if not self.get_game().rotated():
self.location.left = 0
self.add_location(offset=(self.location.w, 0))
else:
self.location.bottom = self.get_display_surface().get_height()
self.add_location(offset=(0, -self.location.h))
def add_frames(self):
bar_locations = []
@ -346,26 +419,46 @@ class Sieve(Strip):
for ii, frame in enumerate(frames):
frame.fill(colors[ii], (x, 0, bar_w, sh))
frame.fill(colors[ii - 1], (x + 1, 1, 1, sh - 2))
if self.get_game().rotated():
for ii, rect in enumerate(bar_rects):
bar_rects[ii] = self.get_game().orient(rect)
bar_rects[ii].move_ip(0, -6)
for frame in frames:
self.add_frame(frame)
self.add_frame(self.get_game().orient(frame))
def reset(self):
Strip.reset(self)
self.location.centerx = self.display_surface.get_rect().centerx
self.locations[1].centerx = self.location.centerx + self.location.w
if not self.get_game().rotated():
self.location.centerx = self.display_surface.get_rect().centerx
self.locations[1].centerx = self.location.centerx + self.location.w
else:
self.location.centery = self.display_surface.get_rect().centery
self.locations[1].centery = self.location.centery + self.location.h
def update(self):
if self.active:
if self.location.right < 0:
self.move(self.location.w)
if self.locations[1].left > self.display_surface.get_width():
self.move(-self.location.w)
for location in self.locations:
location.bottom = self.parent.acid.get_top()
self.electric.location.centery = self.location.centery + 13
if not self.get_game().rotated():
if self.location.right < 0:
self.move(self.location.w)
if self.locations[1].left > self.display_surface.get_width():
self.move(-self.location.w)
for location in self.locations:
location.bottom = self.parent.acid.get_top()
self.electric.location.centery = self.location.centery + 13
else:
if self.location.top > self.display_surface.get_height():
self.move(dy=-self.location.h)
if self.locations[1].bottom < 0:
self.move(dy=self.location.h)
for location in self.locations:
location.right = self.parent.acid.get_top()
self.electric.location.centerx = self.location.centerx + 13
self.electric.update()
for rect in self.bar_rects:
rect.centery = self.location.centery
if not self.get_game().rotated():
rect.centery = self.location.centery
else:
rect.centerx = self.location.centerx
Strip.update(self)
@ -377,8 +470,10 @@ class Electric(Sprite):
self.add_frames()
def add_frames(self):
surface = Surface((self.display_surface.get_width(),
self.parent.location.h - 10))
if not self.get_game().rotated():
surface = Surface((self.display_surface.get_width(), self.parent.location.h - 10))
else:
surface = Surface((self.display_surface.get_height(), self.parent.location.w - 10))
frames = surface, surface.copy()
colors = (255, 255, 0), (100, 89, 213)
pixel_arrays = PixelArray(frames[0]), PixelArray(frames[1])
@ -389,7 +484,7 @@ class Electric(Sprite):
for pixels in pixel_arrays:
del pixels
for frame in frames:
self.add_frame(frame)
self.add_frame(self.get_game().orient(frame))
class Triangles(GameChild, list):
@ -419,12 +514,21 @@ class Triangles(GameChild, list):
def populate(self):
if not self:
self.append(Triangle(self))
self[-1].location.bottom = 0
self.set_next_gap()
while self[-1].location.top > -self.display_surface.get_height():
self.append(Triangle(self))
self[-1].location.bottom = self[-2].location.top - self.next_gap
if not self.get_game().rotated():
self[-1].location.bottom = 0
else:
self[-1].location.right = 0
self.set_next_gap()
if not self.get_game().rotated():
while self[-1].location.top > -self.display_surface.get_height():
self.append(Triangle(self))
self[-1].location.bottom = self[-2].location.top - self.next_gap
self.set_next_gap()
else:
while self[-1].location.left > -self.display_surface.get_width():
self.append(Triangle(self))
self[-1].location.right = self[-2].location.left - self.next_gap
self.set_next_gap()
def set_next_gap(self):
self.next_gap = randint(500, 800)
@ -451,17 +555,17 @@ class Triangles(GameChild, list):
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
self.score += self.streak ** .8 + self.parent.acid.get_volume() * 5 + self[0].count
self.remove(self[0])
self.hit.play()
else:
for br in sieve.bar_rects:
for tr in self[0].collision_rects:
if tr.move((self[0].location.left,
0)).colliderect(br.move((sieve.location.left,
0))):
tr_offset = (self[0].location.left, 0) if not self.get_game().rotated() else \
(0, self[0].location.bottom - self.get_display_surface().get_height())
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)):
self.remove(self[0])
self.parent.static.increase()
self.streak = 0
@ -490,21 +594,33 @@ class Triangle(Sprite):
self.collision_rects = collision_rects = []
for width in widths:
x += sieve.bar_w
points = (x + margin / 2, height - 2), \
(x + width - margin / 2 - 1, height - 2), \
points = (x + margin // 2, height - 2), \
(x + width - margin // 2 - 1, height - 2), \
(x + width / 2.0, 1)
polygon(surface, (60, 255, 220), points)
collision_rects.append(Rect(points[0], (width - margin - 1, 1)))
if not self.get_game().rotated():
collision_rects.append(Rect(points[0], (width - margin - 1, 1)))
else:
collision_rects.append(Rect(height - 2 - 1, self.get_display_surface().get_height() - x - width + margin // 2 + 1, 1, width - margin - 1))
x += width - sieve.bar_w
self.add_frame(surface)
self.location.centerx = self.get_display_surface().get_rect().centerx
self.add_frame(self.get_game().orient(surface))
if not self.get_game().rotated():
self.location.centerx = self.get_display_surface().get_rect().centerx
else:
self.location.centery = self.get_display_surface().get_rect().centery
self.count = len(widths)
def update(self):
self.move(dy=9.5 * self.get_game().acid.get_volume() + 3.8 + \
self.parent.get_boost())
step = 9.5 * self.get_game().acid.get_volume() + 3.8 + self.parent.get_boost()
if not self.get_game().rotated():
self.move(dy=step)
else:
self.move(dx=step)
for rect in self.collision_rects:
rect.bottom = self.location.bottom
if not self.get_game().rotated():
rect.bottom = self.location.bottom
else:
rect.right = self.location.right
Sprite.update(self)
@ -521,11 +637,13 @@ class Acid(GameChild):
self.substance = 0
def get_top(self):
return self.display_surface.get_height() - self.get_level()
if not self.get_game().rotated():
return self.display_surface.get_height() - self.get_level()
else:
return self.display_surface.get_width() - self.get_level()
def get_level(self):
return self.get_volume() * (self.level_r[1] - self.level_r[0]) + \
self.level_r[0]
return self.get_volume() * (self.level_r[1] - self.level_r[0]) + self.level_r[0]
def get_volume(self):
return self.nodeset.get_y(self.substance)
@ -646,7 +764,6 @@ class Initials(GameChild):
PADDING = 10
ARROW_MARGIN = 40
ARROW_HEIGHT = 10
def __init__(self, parent):
GameChild.__init__(self, parent)
@ -703,22 +820,27 @@ class Initials(GameChild):
if self.active:
ds = self.get_display_surface()
for ii, letter in enumerate(self.text):
box = render_box(self.font, letter, False, self.FOREGROUND, self.BACKGROUND,
self.FOREGROUND, padding=self.PADDING)
box = self.get_game().orient(render_box(
self.font, letter, False, self.FOREGROUND, self.BACKGROUND, self.FOREGROUND, padding=self.PADDING))
rect = box.get_rect()
rect.centery = ds.get_rect().centery
rect.centerx = ii * ds.get_width() / 3 + ds.get_width() / 6
if not self.get_game().rotated():
rect.centery = ds.get_rect().centery
rect.centerx = ii * ds.get_width() / 3 + ds.get_width() / 6
else:
rect.centerx = ds.get_rect().centerx
rect.centery = (len(self.text) - 1 - ii) * ds.get_height() / 3 + ds.get_height() / 6
ds.blit(box, rect)
if ii == self.index:
margin = self.ARROW_MARGIN
if not self.get_game().rotated():
margin = self.ARROW_MARGIN
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)))
(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)))
(rect.centerx, rect.bottom + margin + self.ARROW_HEIGHT)))
class Total(Sprite):
@ -763,7 +885,7 @@ class Total(Sprite):
# polygon(surface, choice(colors), ((tr.centerx - 7, 80),
# (tr.centerx, tr.h - 1),
# (tr.centerx + 7, 80)))
self.add_frame(surface)
self.add_frame(self.get_game().orient(surface))
self.location.center = self.display_surface.get_rect().center
self.active = True

@ -1 +1 @@
Subproject commit 24b5d7c6e7c7f17ec09ddb3de2127c092aa6f874
Subproject commit 7a1652717931d49c112e8fe75919129b4906d9f4

View File

@ -134,3 +134,13 @@
1670819531.720299 203 FLA
1670819619.775536 96 ---
1670989457.377776 0 ---
1671076263.7870994 4 ---
1671076281.177432 0 ---
1671076361.7916923 20 ---
1671076398.698485 4 ---
1671076453.8790646 43 ---
1671076466.5137062 0 ---
1671076561.3319085 52 ---
1671086208.2518148 135 ---
1671161829.4724848 14 ---
1671168164.8205705 0 ---