first commit
154
venv/lib/python3.11/site-packages/pygame/examples/README.rst
Normal file
|
@ -0,0 +1,154 @@
|
|||
These examples are a good introduction to various Pygame modules and
|
||||
techniques. They are beginner-friendly with source code in the public
|
||||
domain that can be adapted for your projects.
|
||||
|
||||
|
||||
aacircles.py
|
||||
An example of using the gfxdraw module to drawing anti-aliased circles.
|
||||
|
||||
aliens.py
|
||||
An arcade-style space shooter game that showcases various common and
|
||||
important Pygame modules and techniques.
|
||||
|
||||
arraydemo.py
|
||||
Showcases the use of Numpy with Pygame to perform efficient
|
||||
pixel manipulation.
|
||||
|
||||
audiocapture.py
|
||||
Use the mixer module to record sound from a microphone, and
|
||||
play back the recorded sound.
|
||||
|
||||
blend_fill.py
|
||||
Demonstrates how to perform surface blending and filling
|
||||
with Pygame.
|
||||
|
||||
blit_blends.py
|
||||
Uses blit functions to showcase some of Pygame's different
|
||||
blending modes.
|
||||
|
||||
camera.py
|
||||
Basic image capturing and display using pygame.camera
|
||||
|
||||
chimp.py
|
||||
A simple game featuring a chimp that showcases the use of
|
||||
common and important Pygame modules and techniques.
|
||||
|
||||
cursors.py
|
||||
Demonstrates the creation of custom cursors with Pygame.
|
||||
|
||||
dropevent.py
|
||||
Drag and drop files using the following events:
|
||||
DROPBEGIN, DROPCOMPLETE, DROPTEXT, DROPFILE
|
||||
|
||||
eventlist.py
|
||||
A utility for displaying and logging real-time Pygame events,
|
||||
useful for debugging.
|
||||
|
||||
font_viewer.py
|
||||
Demonstrates how to display all available fonts in a
|
||||
scrolling window.
|
||||
|
||||
fonty.py
|
||||
A simple application demonstrating the different ways
|
||||
to render fonts with the font module
|
||||
|
||||
freetype_misc.py
|
||||
Shows how to use the freetype module to perform font
|
||||
rendering and manipulation.
|
||||
|
||||
glcube.py
|
||||
Using PyOpenGL and Pygame, this creates a spinning 3D multicolored cube.
|
||||
|
||||
go_over_there.py
|
||||
Demonstrates the important Vector.move_towards() function.
|
||||
|
||||
grid.py
|
||||
A simple example of grid-based movement.
|
||||
|
||||
headless_no_windows_needed.py
|
||||
Shows how to run Pygame in scripts.
|
||||
|
||||
joystick.py
|
||||
Shows how to integrate joysticks or game controllers into Pygame.
|
||||
|
||||
liquid.py
|
||||
Demonstrates how to create a simple liquid effect in an image.
|
||||
|
||||
mask.py
|
||||
Showcases how to use masks for collision detection and sprite
|
||||
interaction.
|
||||
|
||||
midi.py
|
||||
Demonstrates how to use MIDI I/O using the midi module.
|
||||
|
||||
moveit.py
|
||||
Illustrates how to accomplish sprite movement and animation.
|
||||
|
||||
music_drop_fade.py
|
||||
Showcases dropping music files into Pygame, and how to
|
||||
apply a fade effect to music playback.
|
||||
|
||||
pixelarray.py
|
||||
Manipulation of individual pixels using the PixelArray module.
|
||||
|
||||
playmus.py
|
||||
Uses the mixer module to play music files with CLI.
|
||||
|
||||
prevent_display_stretching.py
|
||||
Illustrates how to maintain aspect ratio when resizing a window
|
||||
in Pygame.
|
||||
|
||||
resizing_new.py
|
||||
Showcases various window resizing events and how to fit graphics
|
||||
to new dimensions.
|
||||
|
||||
scaletest.py
|
||||
Showcases the scaling of Surfaces.
|
||||
|
||||
scrap_clipboard.py
|
||||
Shows how to implement clipboard interaction with Pygame's scrap module.
|
||||
|
||||
scroll.py
|
||||
An example that implements smooth scrolling backgrounds for side-scrolling
|
||||
games or parallax effects.
|
||||
|
||||
setmodescale.py
|
||||
Handles mouse scaling and selection of a good sized window depending
|
||||
on the display.
|
||||
|
||||
sound.py
|
||||
Illustrates how to implement sound effects and music using Pygame.
|
||||
|
||||
sound_array_demos.py
|
||||
Showcases echo, delay and other array based processing of sounds.
|
||||
|
||||
sprite_texture.py
|
||||
Demonstrates how to use textured sprites in Pygame.
|
||||
|
||||
stars.py
|
||||
A simple starfield implementation in which the perspective can be
|
||||
changed by a mouse click.
|
||||
|
||||
testsprite.py
|
||||
Showcases the basics of sprite handling, namely collision
|
||||
detection and animation.
|
||||
|
||||
textinput.py
|
||||
A little "console" where you can write in text.
|
||||
Shows how to use the TEXTEDITING and TEXTINPUT events.
|
||||
|
||||
vgrade.py
|
||||
Shows how to apply vertical gradients to surfaces using Pygame.
|
||||
|
||||
video.py
|
||||
Showcases the movie module, including the display of playback
|
||||
controls.
|
||||
|
||||
data/
|
||||
Directory with the resources for the examples.
|
||||
|
||||
|
||||
More examples can be found on the Pygame website and GitHub.
|
||||
We're always looking for new examples and/or example requests. Examining
|
||||
code such as this is a great way to get started with Python-based
|
||||
game development.
|
|
@ -0,0 +1,41 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
"""Proof of concept gfxdraw example"""
|
||||
|
||||
import pygame
|
||||
import pygame.gfxdraw
|
||||
|
||||
|
||||
def main():
|
||||
pygame.init()
|
||||
screen = pygame.display.set_mode((500, 500))
|
||||
screen.fill((255, 0, 0))
|
||||
s = pygame.Surface(screen.get_size(), pygame.SRCALPHA, 32)
|
||||
pygame.draw.line(s, (0, 0, 0), (250, 250), (250 + 200, 250))
|
||||
|
||||
width = 1
|
||||
for a_radius in range(width):
|
||||
radius = 200
|
||||
pygame.gfxdraw.aacircle(s, 250, 250, radius - a_radius, (0, 0, 0))
|
||||
|
||||
screen.blit(s, (0, 0))
|
||||
|
||||
pygame.draw.circle(screen, "green", (50, 100), 10)
|
||||
pygame.draw.circle(screen, "black", (50, 100), 10, 1)
|
||||
|
||||
pygame.display.flip()
|
||||
try:
|
||||
while True:
|
||||
event = pygame.event.wait()
|
||||
if event.type == pygame.QUIT:
|
||||
break
|
||||
if event.type == pygame.KEYDOWN:
|
||||
if event.key == pygame.K_ESCAPE or event.unicode == "q":
|
||||
break
|
||||
pygame.display.flip()
|
||||
finally:
|
||||
pygame.quit()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
395
venv/lib/python3.11/site-packages/pygame/examples/aliens.py
Normal file
|
@ -0,0 +1,395 @@
|
|||
#!/usr/bin/env python
|
||||
""" pygame.examples.aliens
|
||||
|
||||
Shows a mini game where you have to defend against aliens.
|
||||
|
||||
What does it show you about pygame?
|
||||
|
||||
* pg.sprite, the difference between Sprite and Group.
|
||||
* dirty rectangle optimization for processing for speed.
|
||||
* music with pg.mixer.music, including fadeout
|
||||
* sound effects with pg.Sound
|
||||
* event processing, keyboard handling, QUIT handling.
|
||||
* a main loop frame limited with a game clock from pg.time.Clock
|
||||
* fullscreen switching.
|
||||
|
||||
|
||||
Controls
|
||||
--------
|
||||
|
||||
* Left and right arrows to move.
|
||||
* Space bar to shoot
|
||||
* f key to toggle between fullscreen.
|
||||
|
||||
"""
|
||||
|
||||
import os
|
||||
import random
|
||||
from typing import List
|
||||
|
||||
# import basic pygame modules
|
||||
import pygame as pg
|
||||
|
||||
# see if we can load more than standard BMP
|
||||
if not pg.image.get_extended():
|
||||
raise SystemExit("Sorry, extended image module required")
|
||||
|
||||
|
||||
# game constants
|
||||
MAX_SHOTS = 2 # most player bullets onscreen
|
||||
ALIEN_ODDS = 22 # chances a new alien appears
|
||||
BOMB_ODDS = 60 # chances a new bomb will drop
|
||||
ALIEN_RELOAD = 12 # frames between new aliens
|
||||
SCREENRECT = pg.Rect(0, 0, 640, 480)
|
||||
SCORE = 0
|
||||
|
||||
main_dir = os.path.split(os.path.abspath(__file__))[0]
|
||||
|
||||
|
||||
def load_image(file):
|
||||
"""loads an image, prepares it for play"""
|
||||
file = os.path.join(main_dir, "data", file)
|
||||
try:
|
||||
surface = pg.image.load(file)
|
||||
except pg.error:
|
||||
raise SystemExit(f'Could not load image "{file}" {pg.get_error()}')
|
||||
return surface.convert()
|
||||
|
||||
|
||||
def load_sound(file):
|
||||
"""because pygame can be compiled without mixer."""
|
||||
if not pg.mixer:
|
||||
return None
|
||||
file = os.path.join(main_dir, "data", file)
|
||||
try:
|
||||
sound = pg.mixer.Sound(file)
|
||||
return sound
|
||||
except pg.error:
|
||||
print(f"Warning, unable to load, {file}")
|
||||
return None
|
||||
|
||||
|
||||
# Each type of game object gets an init and an update function.
|
||||
# The update function is called once per frame, and it is when each object should
|
||||
# change its current position and state.
|
||||
#
|
||||
# The Player object actually gets a "move" function instead of update,
|
||||
# since it is passed extra information about the keyboard.
|
||||
|
||||
|
||||
class Player(pg.sprite.Sprite):
|
||||
"""Representing the player as a moon buggy type car."""
|
||||
|
||||
speed = 10
|
||||
bounce = 24
|
||||
gun_offset = -11
|
||||
images: List[pg.Surface] = []
|
||||
|
||||
def __init__(self, *groups):
|
||||
pg.sprite.Sprite.__init__(self, *groups)
|
||||
self.image = self.images[0]
|
||||
self.rect = self.image.get_rect(midbottom=SCREENRECT.midbottom)
|
||||
self.reloading = 0
|
||||
self.origtop = self.rect.top
|
||||
self.facing = -1
|
||||
|
||||
def move(self, direction):
|
||||
if direction:
|
||||
self.facing = direction
|
||||
self.rect.move_ip(direction * self.speed, 0)
|
||||
self.rect = self.rect.clamp(SCREENRECT)
|
||||
if direction < 0:
|
||||
self.image = self.images[0]
|
||||
elif direction > 0:
|
||||
self.image = self.images[1]
|
||||
self.rect.top = self.origtop - (self.rect.left // self.bounce % 2)
|
||||
|
||||
def gunpos(self):
|
||||
pos = self.facing * self.gun_offset + self.rect.centerx
|
||||
return pos, self.rect.top
|
||||
|
||||
|
||||
class Alien(pg.sprite.Sprite):
|
||||
"""An alien space ship. That slowly moves down the screen."""
|
||||
|
||||
speed = 13
|
||||
animcycle = 12
|
||||
images: List[pg.Surface] = []
|
||||
|
||||
def __init__(self, *groups):
|
||||
pg.sprite.Sprite.__init__(self, *groups)
|
||||
self.image = self.images[0]
|
||||
self.rect = self.image.get_rect()
|
||||
self.facing = random.choice((-1, 1)) * Alien.speed
|
||||
self.frame = 0
|
||||
if self.facing < 0:
|
||||
self.rect.right = SCREENRECT.right
|
||||
|
||||
def update(self, *args, **kwargs):
|
||||
self.rect.move_ip(self.facing, 0)
|
||||
if not SCREENRECT.contains(self.rect):
|
||||
self.facing = -self.facing
|
||||
self.rect.top = self.rect.bottom + 1
|
||||
self.rect = self.rect.clamp(SCREENRECT)
|
||||
self.frame = self.frame + 1
|
||||
self.image = self.images[self.frame // self.animcycle % 3]
|
||||
|
||||
|
||||
class Explosion(pg.sprite.Sprite):
|
||||
"""An explosion. Hopefully the Alien and not the player!"""
|
||||
|
||||
defaultlife = 12
|
||||
animcycle = 3
|
||||
images: List[pg.Surface] = []
|
||||
|
||||
def __init__(self, actor, *groups):
|
||||
pg.sprite.Sprite.__init__(self, *groups)
|
||||
self.image = self.images[0]
|
||||
self.rect = self.image.get_rect(center=actor.rect.center)
|
||||
self.life = self.defaultlife
|
||||
|
||||
def update(self, *args, **kwargs):
|
||||
"""called every time around the game loop.
|
||||
|
||||
Show the explosion surface for 'defaultlife'.
|
||||
Every game tick(update), we decrease the 'life'.
|
||||
|
||||
Also we animate the explosion.
|
||||
"""
|
||||
self.life = self.life - 1
|
||||
self.image = self.images[self.life // self.animcycle % 2]
|
||||
if self.life <= 0:
|
||||
self.kill()
|
||||
|
||||
|
||||
class Shot(pg.sprite.Sprite):
|
||||
"""a bullet the Player sprite fires."""
|
||||
|
||||
speed = -11
|
||||
images: List[pg.Surface] = []
|
||||
|
||||
def __init__(self, pos, *groups):
|
||||
pg.sprite.Sprite.__init__(self, *groups)
|
||||
self.image = self.images[0]
|
||||
self.rect = self.image.get_rect(midbottom=pos)
|
||||
|
||||
def update(self, *args, **kwargs):
|
||||
"""called every time around the game loop.
|
||||
|
||||
Every tick we move the shot upwards.
|
||||
"""
|
||||
self.rect.move_ip(0, self.speed)
|
||||
if self.rect.top <= 0:
|
||||
self.kill()
|
||||
|
||||
|
||||
class Bomb(pg.sprite.Sprite):
|
||||
"""A bomb the aliens drop."""
|
||||
|
||||
speed = 9
|
||||
images: List[pg.Surface] = []
|
||||
|
||||
def __init__(self, alien, explosion_group, *groups):
|
||||
pg.sprite.Sprite.__init__(self, *groups)
|
||||
self.image = self.images[0]
|
||||
self.rect = self.image.get_rect(midbottom=alien.rect.move(0, 5).midbottom)
|
||||
self.explosion_group = explosion_group
|
||||
|
||||
def update(self, *args, **kwargs):
|
||||
"""called every time around the game loop.
|
||||
|
||||
Every frame we move the sprite 'rect' down.
|
||||
When it reaches the bottom we:
|
||||
|
||||
- make an explosion.
|
||||
- remove the Bomb.
|
||||
"""
|
||||
self.rect.move_ip(0, self.speed)
|
||||
if self.rect.bottom >= 470:
|
||||
Explosion(self, self.explosion_group)
|
||||
self.kill()
|
||||
|
||||
|
||||
class Score(pg.sprite.Sprite):
|
||||
"""to keep track of the score."""
|
||||
|
||||
def __init__(self, *groups):
|
||||
pg.sprite.Sprite.__init__(self, *groups)
|
||||
self.font = pg.font.Font(None, 20)
|
||||
self.font.set_italic(1)
|
||||
self.color = "white"
|
||||
self.lastscore = -1
|
||||
self.update()
|
||||
self.rect = self.image.get_rect().move(10, 450)
|
||||
|
||||
def update(self, *args, **kwargs):
|
||||
"""We only update the score in update() when it has changed."""
|
||||
if SCORE != self.lastscore:
|
||||
self.lastscore = SCORE
|
||||
msg = f"Score: {SCORE}"
|
||||
self.image = self.font.render(msg, 0, self.color)
|
||||
|
||||
|
||||
def main(winstyle=0):
|
||||
# Initialize pygame
|
||||
if pg.get_sdl_version()[0] == 2:
|
||||
pg.mixer.pre_init(44100, 32, 2, 1024)
|
||||
pg.init()
|
||||
if pg.mixer and not pg.mixer.get_init():
|
||||
print("Warning, no sound")
|
||||
pg.mixer = None
|
||||
|
||||
fullscreen = False
|
||||
# Set the display mode
|
||||
winstyle = 0 # |FULLSCREEN
|
||||
bestdepth = pg.display.mode_ok(SCREENRECT.size, winstyle, 32)
|
||||
screen = pg.display.set_mode(SCREENRECT.size, winstyle, bestdepth)
|
||||
|
||||
# Load images, assign to sprite classes
|
||||
# (do this before the classes are used, after screen setup)
|
||||
img = load_image("player1.gif")
|
||||
Player.images = [img, pg.transform.flip(img, 1, 0)]
|
||||
img = load_image("explosion1.gif")
|
||||
Explosion.images = [img, pg.transform.flip(img, 1, 1)]
|
||||
Alien.images = [load_image(im) for im in ("alien1.gif", "alien2.gif", "alien3.gif")]
|
||||
Bomb.images = [load_image("bomb.gif")]
|
||||
Shot.images = [load_image("shot.gif")]
|
||||
|
||||
# decorate the game window
|
||||
icon = pg.transform.scale(Alien.images[0], (32, 32))
|
||||
pg.display.set_icon(icon)
|
||||
pg.display.set_caption("Pygame Aliens")
|
||||
pg.mouse.set_visible(0)
|
||||
|
||||
# create the background, tile the bgd image
|
||||
bgdtile = load_image("background.gif")
|
||||
background = pg.Surface(SCREENRECT.size)
|
||||
for x in range(0, SCREENRECT.width, bgdtile.get_width()):
|
||||
background.blit(bgdtile, (x, 0))
|
||||
screen.blit(background, (0, 0))
|
||||
pg.display.flip()
|
||||
|
||||
# load the sound effects
|
||||
boom_sound = load_sound("boom.wav")
|
||||
shoot_sound = load_sound("car_door.wav")
|
||||
if pg.mixer:
|
||||
music = os.path.join(main_dir, "data", "house_lo.wav")
|
||||
pg.mixer.music.load(music)
|
||||
pg.mixer.music.play(-1)
|
||||
|
||||
# Initialize Game Groups
|
||||
aliens = pg.sprite.Group()
|
||||
shots = pg.sprite.Group()
|
||||
bombs = pg.sprite.Group()
|
||||
all = pg.sprite.RenderUpdates()
|
||||
lastalien = pg.sprite.GroupSingle()
|
||||
|
||||
# Create Some Starting Values
|
||||
alienreload = ALIEN_RELOAD
|
||||
clock = pg.time.Clock()
|
||||
|
||||
# initialize our starting sprites
|
||||
global SCORE
|
||||
player = Player(all)
|
||||
Alien(
|
||||
aliens, all, lastalien
|
||||
) # note, this 'lives' because it goes into a sprite group
|
||||
if pg.font:
|
||||
all.add(Score(all))
|
||||
|
||||
# Run our main loop whilst the player is alive.
|
||||
while player.alive():
|
||||
# get input
|
||||
for event in pg.event.get():
|
||||
if event.type == pg.QUIT:
|
||||
return
|
||||
if event.type == pg.KEYDOWN and event.key == pg.K_ESCAPE:
|
||||
return
|
||||
if event.type == pg.KEYDOWN:
|
||||
if event.key == pg.K_f:
|
||||
if not fullscreen:
|
||||
print("Changing to FULLSCREEN")
|
||||
screen_backup = screen.copy()
|
||||
screen = pg.display.set_mode(
|
||||
SCREENRECT.size, winstyle | pg.FULLSCREEN, bestdepth
|
||||
)
|
||||
screen.blit(screen_backup, (0, 0))
|
||||
else:
|
||||
print("Changing to windowed mode")
|
||||
screen_backup = screen.copy()
|
||||
screen = pg.display.set_mode(
|
||||
SCREENRECT.size, winstyle, bestdepth
|
||||
)
|
||||
screen.blit(screen_backup, (0, 0))
|
||||
pg.display.flip()
|
||||
fullscreen = not fullscreen
|
||||
|
||||
keystate = pg.key.get_pressed()
|
||||
|
||||
# clear/erase the last drawn sprites
|
||||
all.clear(screen, background)
|
||||
|
||||
# update all the sprites
|
||||
all.update()
|
||||
|
||||
# handle player input
|
||||
direction = keystate[pg.K_RIGHT] - keystate[pg.K_LEFT]
|
||||
player.move(direction)
|
||||
firing = keystate[pg.K_SPACE]
|
||||
if not player.reloading and firing and len(shots) < MAX_SHOTS:
|
||||
Shot(player.gunpos(), shots, all)
|
||||
if pg.mixer and shoot_sound is not None:
|
||||
shoot_sound.play()
|
||||
player.reloading = firing
|
||||
|
||||
# Create new alien
|
||||
if alienreload:
|
||||
alienreload = alienreload - 1
|
||||
elif not int(random.random() * ALIEN_ODDS):
|
||||
Alien(aliens, all, lastalien)
|
||||
alienreload = ALIEN_RELOAD
|
||||
|
||||
# Drop bombs
|
||||
if lastalien and not int(random.random() * BOMB_ODDS):
|
||||
Bomb(lastalien.sprite, all, bombs, all)
|
||||
|
||||
# Detect collisions between aliens and players.
|
||||
for alien in pg.sprite.spritecollide(player, aliens, 1):
|
||||
if pg.mixer and boom_sound is not None:
|
||||
boom_sound.play()
|
||||
Explosion(alien, all)
|
||||
Explosion(player, all)
|
||||
SCORE = SCORE + 1
|
||||
player.kill()
|
||||
|
||||
# See if shots hit the aliens.
|
||||
for alien in pg.sprite.groupcollide(aliens, shots, 1, 1).keys():
|
||||
if pg.mixer and boom_sound is not None:
|
||||
boom_sound.play()
|
||||
Explosion(alien, all)
|
||||
SCORE = SCORE + 1
|
||||
|
||||
# See if alien bombs hit the player.
|
||||
for bomb in pg.sprite.spritecollide(player, bombs, 1):
|
||||
if pg.mixer and boom_sound is not None:
|
||||
boom_sound.play()
|
||||
Explosion(player, all)
|
||||
Explosion(bomb, all)
|
||||
player.kill()
|
||||
|
||||
# draw the scene
|
||||
dirty = all.draw(screen)
|
||||
pg.display.update(dirty)
|
||||
|
||||
# cap the framerate at 40fps. Also called 40HZ or 40 times per second.
|
||||
clock.tick(40)
|
||||
|
||||
if pg.mixer:
|
||||
pg.mixer.music.fadeout(1000)
|
||||
pg.time.wait(1000)
|
||||
|
||||
|
||||
# call the "main" function if running this script
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
pg.quit()
|
120
venv/lib/python3.11/site-packages/pygame/examples/arraydemo.py
Normal file
|
@ -0,0 +1,120 @@
|
|||
#!/usr/bin/env python
|
||||
""" pygame.examples.arraydemo
|
||||
|
||||
Welcome to the arraydemo!
|
||||
|
||||
Use the numpy array package to manipulate pixels.
|
||||
|
||||
This demo will show you a few things:
|
||||
|
||||
* scale up, scale down, flip,
|
||||
* cross fade
|
||||
* soften
|
||||
* put stripes on it!
|
||||
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
import pygame as pg
|
||||
from pygame import surfarray
|
||||
|
||||
main_dir = os.path.split(os.path.abspath(__file__))[0]
|
||||
|
||||
|
||||
def surfdemo_show(array_img, name):
|
||||
"displays a surface, waits for user to continue"
|
||||
screen = pg.display.set_mode(array_img.shape[:2], 0, 32)
|
||||
surfarray.blit_array(screen, array_img)
|
||||
pg.display.flip()
|
||||
pg.display.set_caption(name)
|
||||
while True:
|
||||
e = pg.event.wait()
|
||||
# Force application to only advance when main button is released
|
||||
if e.type == pg.MOUSEBUTTONUP and e.button == pg.BUTTON_LEFT:
|
||||
break
|
||||
elif e.type == pg.KEYDOWN and e.key == pg.K_s:
|
||||
pg.image.save(screen, name + ".png")
|
||||
elif e.type == pg.QUIT:
|
||||
pg.quit()
|
||||
raise SystemExit()
|
||||
|
||||
|
||||
def main():
|
||||
"""show various surfarray effects"""
|
||||
import numpy as np
|
||||
from numpy import int32, uint
|
||||
|
||||
pg.init()
|
||||
|
||||
print("Using Numpy")
|
||||
print("Press the left mouse button to advance image.")
|
||||
print('Press the "s" key to save the current image.')
|
||||
|
||||
# allblack
|
||||
allblack = np.zeros((128, 128), int32)
|
||||
surfdemo_show(allblack, "allblack")
|
||||
|
||||
# striped
|
||||
# the element type is required for np.zeros in numpy else
|
||||
# an array of float is returned.
|
||||
striped = np.zeros((128, 128, 3), int32)
|
||||
striped[:] = (255, 0, 0)
|
||||
striped[:, ::3] = (0, 255, 255)
|
||||
surfdemo_show(striped, "striped")
|
||||
|
||||
# rgbarray
|
||||
imagename = os.path.join(main_dir, "data", "arraydemo.bmp")
|
||||
imgsurface = pg.image.load(imagename)
|
||||
rgbarray = surfarray.array3d(imgsurface)
|
||||
surfdemo_show(rgbarray, "rgbarray")
|
||||
|
||||
# flipped
|
||||
flipped = rgbarray[:, ::-1]
|
||||
surfdemo_show(flipped, "flipped")
|
||||
|
||||
# scaledown
|
||||
scaledown = rgbarray[::2, ::2]
|
||||
surfdemo_show(scaledown, "scaledown")
|
||||
|
||||
# scaleup
|
||||
# the element type is required for np.zeros in numpy else
|
||||
# an #array of floats is returned.
|
||||
shape = rgbarray.shape
|
||||
scaleup = np.zeros((shape[0] * 2, shape[1] * 2, shape[2]), int32)
|
||||
scaleup[::2, ::2, :] = rgbarray
|
||||
scaleup[1::2, ::2, :] = rgbarray
|
||||
scaleup[:, 1::2] = scaleup[:, ::2]
|
||||
surfdemo_show(scaleup, "scaleup")
|
||||
|
||||
# redimg
|
||||
redimg = np.array(rgbarray)
|
||||
redimg[:, :, 1:] = 0
|
||||
surfdemo_show(redimg, "redimg")
|
||||
|
||||
# soften
|
||||
# having factor as an array forces integer upgrade during multiplication
|
||||
# of rgbarray, even for numpy.
|
||||
factor = np.array((8,), int32)
|
||||
soften = np.array(rgbarray, int32)
|
||||
soften[1:, :] += rgbarray[:-1, :] * factor
|
||||
soften[:-1, :] += rgbarray[1:, :] * factor
|
||||
soften[:, 1:] += rgbarray[:, :-1] * factor
|
||||
soften[:, :-1] += rgbarray[:, 1:] * factor
|
||||
soften //= 33
|
||||
surfdemo_show(soften, "soften")
|
||||
|
||||
# crossfade (50%)
|
||||
src = np.array(rgbarray)
|
||||
dest = np.zeros(rgbarray.shape) # dest is float64 by default.
|
||||
dest[:] = 20, 50, 100
|
||||
diff = (dest - src) * 0.50
|
||||
xfade = src + diff.astype(uint)
|
||||
surfdemo_show(xfade, "xfade")
|
||||
|
||||
# all done
|
||||
pg.quit()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -0,0 +1,78 @@
|
|||
#!/usr/bin/env python
|
||||
""" pygame.examples.audiocapture
|
||||
|
||||
A pygame 2 experiment.
|
||||
|
||||
* record sound from a microphone
|
||||
* play back the recorded sound
|
||||
"""
|
||||
import pygame as pg
|
||||
import time
|
||||
|
||||
from pygame._sdl2 import (
|
||||
get_audio_device_names,
|
||||
AudioDevice,
|
||||
AUDIO_F32,
|
||||
AUDIO_ALLOW_FORMAT_CHANGE,
|
||||
)
|
||||
from pygame._sdl2.mixer import set_post_mix
|
||||
|
||||
|
||||
pg.mixer.pre_init(44100, 32, 2, 512)
|
||||
pg.init()
|
||||
|
||||
# init_subsystem(INIT_AUDIO)
|
||||
names = get_audio_device_names(True)
|
||||
print(names)
|
||||
|
||||
sounds = []
|
||||
sound_chunks = []
|
||||
|
||||
|
||||
def callback(audiodevice, audiomemoryview):
|
||||
"""This is called in the sound thread.
|
||||
|
||||
Note, that the frequency and such you request may not be what you get.
|
||||
"""
|
||||
# print(type(audiomemoryview), len(audiomemoryview))
|
||||
# print(audiodevice)
|
||||
sound_chunks.append(bytes(audiomemoryview))
|
||||
|
||||
|
||||
def postmix_callback(postmix, audiomemoryview):
|
||||
"""This is called in the sound thread.
|
||||
|
||||
At the end of mixing we get this data.
|
||||
"""
|
||||
print(type(audiomemoryview), len(audiomemoryview))
|
||||
print(postmix)
|
||||
|
||||
|
||||
set_post_mix(postmix_callback)
|
||||
|
||||
audio = AudioDevice(
|
||||
devicename=names[0],
|
||||
iscapture=True,
|
||||
frequency=44100,
|
||||
audioformat=AUDIO_F32,
|
||||
numchannels=2,
|
||||
chunksize=512,
|
||||
allowed_changes=AUDIO_ALLOW_FORMAT_CHANGE,
|
||||
callback=callback,
|
||||
)
|
||||
# start recording.
|
||||
audio.pause(0)
|
||||
|
||||
print(audio)
|
||||
|
||||
print(f"recording with '{names[0]}'")
|
||||
time.sleep(5)
|
||||
|
||||
|
||||
print("Turning data into a pg.mixer.Sound")
|
||||
sound = pg.mixer.Sound(buffer=b"".join(sound_chunks))
|
||||
|
||||
print("playing back recorded sound")
|
||||
sound.play()
|
||||
time.sleep(5)
|
||||
pg.quit()
|
114
venv/lib/python3.11/site-packages/pygame/examples/blend_fill.py
Normal file
|
@ -0,0 +1,114 @@
|
|||
#!/usr/bin/env python
|
||||
""" pygame.examples.blend_fill
|
||||
|
||||
BLEND_ing colors in different ways with Surface.fill().
|
||||
|
||||
Keyboard Controls:
|
||||
|
||||
* Press R, G, B to increase the color channel values,
|
||||
* 1-9 to set the step range for the increment,
|
||||
* A - ADD, S- SUB, M- MULT, - MIN, + MAX to change the blend modes
|
||||
|
||||
"""
|
||||
import os
|
||||
import pygame as pg
|
||||
from pygame import K_1, K_2, K_3, K_4, K_5, K_6, K_7, K_8, K_9
|
||||
|
||||
|
||||
def usage():
|
||||
print("Press R, G, B to increase the color channel values,")
|
||||
print("1-9 to set the step range for the increment,")
|
||||
print("A - ADD, S- SUB, M- MULT, - MIN, + MAX")
|
||||
print(" to change the blend modes")
|
||||
|
||||
|
||||
main_dir = os.path.split(os.path.abspath(__file__))[0]
|
||||
data_dir = os.path.join(main_dir, "data")
|
||||
|
||||
|
||||
def main():
|
||||
color = [0, 0, 0]
|
||||
changed = False
|
||||
blendtype = 0
|
||||
step = 5
|
||||
|
||||
pg.init()
|
||||
screen = pg.display.set_mode((640, 480), 0, 32)
|
||||
screen.fill((100, 100, 100))
|
||||
|
||||
image = pg.image.load(os.path.join(data_dir, "liquid.bmp")).convert()
|
||||
blendimage = pg.image.load(os.path.join(data_dir, "liquid.bmp")).convert()
|
||||
screen.blit(image, (10, 10))
|
||||
screen.blit(blendimage, (200, 10))
|
||||
|
||||
pg.display.flip()
|
||||
pg.key.set_repeat(500, 30)
|
||||
usage()
|
||||
|
||||
going = True
|
||||
while going:
|
||||
for event in pg.event.get():
|
||||
if event.type == pg.QUIT:
|
||||
going = False
|
||||
|
||||
if event.type == pg.KEYDOWN:
|
||||
usage()
|
||||
|
||||
if event.key == pg.K_ESCAPE:
|
||||
going = False
|
||||
|
||||
if event.key == pg.K_r:
|
||||
color[0] += step
|
||||
if color[0] > 255:
|
||||
color[0] = 0
|
||||
changed = True
|
||||
|
||||
elif event.key == pg.K_g:
|
||||
color[1] += step
|
||||
if color[1] > 255:
|
||||
color[1] = 0
|
||||
changed = True
|
||||
|
||||
elif event.key == pg.K_b:
|
||||
color[2] += step
|
||||
if color[2] > 255:
|
||||
color[2] = 0
|
||||
changed = True
|
||||
|
||||
elif event.key == pg.K_a:
|
||||
blendtype = pg.BLEND_ADD
|
||||
changed = True
|
||||
elif event.key == pg.K_s:
|
||||
blendtype = pg.BLEND_SUB
|
||||
changed = True
|
||||
elif event.key == pg.K_m:
|
||||
blendtype = pg.BLEND_MULT
|
||||
changed = True
|
||||
elif event.key == pg.K_PLUS:
|
||||
blendtype = pg.BLEND_MAX
|
||||
changed = True
|
||||
elif event.key == pg.K_MINUS:
|
||||
blendtype = pg.BLEND_MIN
|
||||
changed = True
|
||||
|
||||
elif event.key in (K_1, K_2, K_3, K_4, K_5, K_6, K_7, K_8, K_9):
|
||||
step = int(event.unicode)
|
||||
|
||||
if changed:
|
||||
screen.fill((100, 100, 100))
|
||||
screen.blit(image, (10, 10))
|
||||
blendimage.blit(image, (0, 0))
|
||||
# blendimage.fill (color, (0, 0, 20, 20), blendtype)
|
||||
blendimage.fill(color, None, blendtype)
|
||||
screen.blit(blendimage, (200, 10))
|
||||
print(
|
||||
f"Color: {tuple(color)}, Pixel (0,0): {[blendimage.get_at((0, 0))]}"
|
||||
)
|
||||
changed = False
|
||||
pg.display.flip()
|
||||
|
||||
pg.quit()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
197
venv/lib/python3.11/site-packages/pygame/examples/blit_blends.py
Normal file
|
@ -0,0 +1,197 @@
|
|||
#!/usr/bin/env python
|
||||
""" pygame.examples.blit_blends
|
||||
|
||||
Blending colors in different ways with different blend modes.
|
||||
|
||||
It also shows some tricks with the surfarray.
|
||||
Including how to do additive blending.
|
||||
|
||||
|
||||
Keyboard Controls
|
||||
-----------------
|
||||
|
||||
* R, G, B - add a bit of Red, Green, or Blue.
|
||||
* A - Add blend mode
|
||||
* S - Subtractive blend mode
|
||||
* M - Multiply blend mode
|
||||
* = key BLEND_MAX blend mode.
|
||||
* - key BLEND_MIN blend mode.
|
||||
* 1, 2, 3, 4 - use different images.
|
||||
|
||||
"""
|
||||
import os
|
||||
import pygame as pg
|
||||
import time
|
||||
|
||||
main_dir = os.path.split(os.path.abspath(__file__))[0]
|
||||
data_dir = os.path.join(main_dir, "data")
|
||||
|
||||
try:
|
||||
import pygame.surfarray
|
||||
import numpy
|
||||
except ImportError:
|
||||
print("no surfarray for you! install numpy")
|
||||
|
||||
|
||||
def main():
|
||||
pg.init()
|
||||
pg.mixer.quit() # remove ALSA underflow messages for Debian squeeze
|
||||
screen = pg.display.set_mode((640, 480))
|
||||
|
||||
im1 = pg.Surface(screen.get_size())
|
||||
# im1= im1.convert()
|
||||
im1.fill((100, 0, 0))
|
||||
|
||||
im2 = pg.Surface(screen.get_size())
|
||||
im2.fill((0, 50, 0))
|
||||
# we make a srcalpha copy of it.
|
||||
# im3= im2.convert(SRCALPHA)
|
||||
im3 = im2
|
||||
im3.set_alpha(127)
|
||||
|
||||
images = {}
|
||||
images[pg.K_1] = im2
|
||||
images[pg.K_2] = pg.image.load(os.path.join(data_dir, "chimp.png"))
|
||||
images[pg.K_3] = pg.image.load(os.path.join(data_dir, "alien3.gif"))
|
||||
images[pg.K_4] = pg.image.load(os.path.join(data_dir, "liquid.bmp"))
|
||||
img_to_blit = im2.convert()
|
||||
iaa = img_to_blit.convert_alpha()
|
||||
|
||||
blits = {}
|
||||
blits[pg.K_a] = pg.BLEND_ADD
|
||||
blits[pg.K_s] = pg.BLEND_SUB
|
||||
blits[pg.K_m] = pg.BLEND_MULT
|
||||
blits[pg.K_EQUALS] = pg.BLEND_MAX
|
||||
blits[pg.K_MINUS] = pg.BLEND_MIN
|
||||
|
||||
blitsn = {}
|
||||
blitsn[pg.K_a] = "BLEND_ADD"
|
||||
blitsn[pg.K_s] = "BLEND_SUB"
|
||||
blitsn[pg.K_m] = "BLEND_MULT"
|
||||
blitsn[pg.K_EQUALS] = "BLEND_MAX"
|
||||
blitsn[pg.K_MINUS] = "BLEND_MIN"
|
||||
|
||||
screen.blit(im1, (0, 0))
|
||||
pg.display.flip()
|
||||
clock = pg.time.Clock()
|
||||
print("one pixel is:%s:" % [im1.get_at((0, 0))])
|
||||
|
||||
going = True
|
||||
while going:
|
||||
clock.tick(60)
|
||||
|
||||
for event in pg.event.get():
|
||||
if event.type == pg.QUIT:
|
||||
going = False
|
||||
if event.type == pg.KEYDOWN:
|
||||
usage()
|
||||
|
||||
if event.type == pg.KEYDOWN and event.key == pg.K_ESCAPE:
|
||||
going = False
|
||||
|
||||
elif event.type == pg.KEYDOWN and event.key in images.keys():
|
||||
img_to_blit = images[event.key]
|
||||
iaa = img_to_blit.convert_alpha()
|
||||
|
||||
elif event.type == pg.KEYDOWN and event.key in blits.keys():
|
||||
t1 = time.time()
|
||||
# blits is a dict keyed with key -> blit flag. eg BLEND_ADD.
|
||||
im1.blit(img_to_blit, (0, 0), None, blits[event.key])
|
||||
t2 = time.time()
|
||||
print("one pixel is:%s:" % [im1.get_at((0, 0))])
|
||||
print(f"time to do:{t2 - t1}:")
|
||||
|
||||
elif event.type == pg.KEYDOWN and event.key in [pg.K_t]:
|
||||
for bkey in blits.keys():
|
||||
t1 = time.time()
|
||||
|
||||
for x in range(300):
|
||||
im1.blit(img_to_blit, (0, 0), None, blits[bkey])
|
||||
|
||||
t2 = time.time()
|
||||
|
||||
# show which key we're doing...
|
||||
onedoing = blitsn[bkey]
|
||||
print(f"time to do :{onedoing}: is :{t2 - t1}:")
|
||||
|
||||
elif event.type == pg.KEYDOWN and event.key in [pg.K_o]:
|
||||
t1 = time.time()
|
||||
# blits is a dict keyed with key -> blit flag. eg BLEND_ADD.
|
||||
im1.blit(iaa, (0, 0))
|
||||
t2 = time.time()
|
||||
print("one pixel is:%s:" % [im1.get_at((0, 0))])
|
||||
print(f"time to do:{t2 - t1}:")
|
||||
|
||||
elif event.type == pg.KEYDOWN and event.key == pg.K_SPACE:
|
||||
# this additive blend without clamp two surfaces.
|
||||
# im1.set_alpha(127)
|
||||
# im1.blit(im1, (0,0))
|
||||
# im1.set_alpha(255)
|
||||
t1 = time.time()
|
||||
|
||||
im1p = pygame.surfarray.pixels2d(im1)
|
||||
im2p = pygame.surfarray.pixels2d(im2)
|
||||
im1p += im2p
|
||||
del im1p
|
||||
del im2p
|
||||
t2 = time.time()
|
||||
print("one pixel is:%s:" % [im1.get_at((0, 0))])
|
||||
print(f"time to do:{t2 - t1}:")
|
||||
|
||||
elif event.type == pg.KEYDOWN and event.key in [pg.K_z]:
|
||||
t1 = time.time()
|
||||
im1p = pygame.surfarray.pixels3d(im1)
|
||||
im2p = pygame.surfarray.pixels3d(im2)
|
||||
im1p16 = im1p.astype(numpy.uint16)
|
||||
im2p16 = im1p.astype(numpy.uint16)
|
||||
im1p16 += im2p16
|
||||
im1p16 = numpy.minimum(im1p16, 255)
|
||||
pygame.surfarray.blit_array(im1, im1p16)
|
||||
|
||||
del im1p
|
||||
del im2p
|
||||
t2 = time.time()
|
||||
print("one pixel is:%s:" % [im1.get_at((0, 0))])
|
||||
print(f"time to do:{t2 - t1}:")
|
||||
|
||||
elif event.type == pg.KEYDOWN and event.key in [pg.K_r, pg.K_g, pg.K_b]:
|
||||
# this adds one to each pixel.
|
||||
colmap = {}
|
||||
colmap[pg.K_r] = 0x10000
|
||||
colmap[pg.K_g] = 0x00100
|
||||
colmap[pg.K_b] = 0x00001
|
||||
im1p = pygame.surfarray.pixels2d(im1)
|
||||
im1p += colmap[event.key]
|
||||
del im1p
|
||||
print("one pixel is:%s:" % [im1.get_at((0, 0))])
|
||||
|
||||
elif event.type == pg.KEYDOWN and event.key == pg.K_p:
|
||||
print("one pixel is:%s:" % [im1.get_at((0, 0))])
|
||||
|
||||
elif event.type == pg.KEYDOWN and event.key == pg.K_f:
|
||||
# this additive blend without clamp two surfaces.
|
||||
|
||||
t1 = time.time()
|
||||
im1.set_alpha(127)
|
||||
im1.blit(im2, (0, 0))
|
||||
im1.set_alpha(255)
|
||||
|
||||
t2 = time.time()
|
||||
print("one pixel is:%s:" % [im1.get_at((0, 0))])
|
||||
print(f"time to do:{t2 - t1}:")
|
||||
|
||||
screen.blit(im1, (0, 0))
|
||||
pg.display.flip()
|
||||
|
||||
pg.quit()
|
||||
|
||||
|
||||
def usage():
|
||||
print("press keys 1-5 to change image to blit.")
|
||||
print("A - ADD, S- SUB, M- MULT, - MIN, + MAX")
|
||||
print("T - timing test for special blend modes.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
usage()
|
||||
main()
|
121
venv/lib/python3.11/site-packages/pygame/examples/camera.py
Normal file
|
@ -0,0 +1,121 @@
|
|||
#!/usr/bin/env python
|
||||
""" pygame.examples.camera
|
||||
|
||||
Basic image capturing and display using pygame.camera
|
||||
|
||||
Keyboard controls
|
||||
-----------------
|
||||
|
||||
- 0, start camera 0.
|
||||
- 1, start camera 1.
|
||||
- 9, start camera 9.
|
||||
- 10, start camera... wait a minute! There's not 10 key!
|
||||
"""
|
||||
import pygame as pg
|
||||
import pygame.camera
|
||||
|
||||
|
||||
class VideoCapturePlayer:
|
||||
size = (640, 480)
|
||||
|
||||
def __init__(self, **argd):
|
||||
self.__dict__.update(**argd)
|
||||
super().__init__(**argd)
|
||||
|
||||
# create a display surface. standard pygame stuff
|
||||
self.display = pg.display.set_mode(self.size)
|
||||
self.init_cams(0)
|
||||
|
||||
def init_cams(self, which_cam_idx):
|
||||
# gets a list of available cameras.
|
||||
self.clist = pygame.camera.list_cameras()
|
||||
|
||||
# ensure a camera exists
|
||||
if not self.clist:
|
||||
raise ValueError("Sorry, no cameras detected.")
|
||||
|
||||
# check to see if the camera id exists. If not, default to the first one in the list.
|
||||
try:
|
||||
cam_id = self.clist[which_cam_idx]
|
||||
except IndexError:
|
||||
cam_id = self.clist[0]
|
||||
|
||||
# creates the camera of the specified size and in RGB colorspace
|
||||
self.camera = pygame.camera.Camera(cam_id, self.size, "RGB")
|
||||
|
||||
# starts the camera
|
||||
self.camera.start()
|
||||
|
||||
self.clock = pg.time.Clock()
|
||||
|
||||
# create a surface to capture to. for performance purposes, you want the
|
||||
# bit depth to be the same as that of the display surface.
|
||||
self.snapshot = pg.surface.Surface(self.size, 0, self.display)
|
||||
# return the name of the camera being used, to be included in the window name
|
||||
return cam_id
|
||||
|
||||
def get_and_flip(self):
|
||||
# if you don't want to tie the framerate to the camera, you can check and
|
||||
# see if the camera has an image ready. note that while this works
|
||||
# on most cameras, some will never return true.
|
||||
|
||||
self.snapshot = self.camera.get_image(self.display)
|
||||
|
||||
# if 0 and self.camera.query_image():
|
||||
# # capture an image
|
||||
|
||||
# self.snapshot = self.camera.get_image(self.snapshot)
|
||||
|
||||
# if 0:
|
||||
# self.snapshot = self.camera.get_image(self.snapshot)
|
||||
# # self.snapshot = self.camera.get_image()
|
||||
|
||||
# # blit it to the display surface. simple!
|
||||
# self.display.blit(self.snapshot, (0, 0))
|
||||
# else:
|
||||
|
||||
# self.snapshot = self.camera.get_image(self.display)
|
||||
# # self.display.blit(self.snapshot, (0,0))
|
||||
|
||||
pg.display.flip()
|
||||
|
||||
def main(self):
|
||||
# get the camera list. If there are no cameras, raise a value error.
|
||||
clist = pygame.camera.list_cameras()
|
||||
if not clist:
|
||||
raise ValueError("Sorry, no cameras detected.")
|
||||
# get the first camera, as this is the default. We want the display to contain the name of the camera.
|
||||
camera = clist[0]
|
||||
|
||||
# create a list of options for the user to easily understand.
|
||||
print(
|
||||
"\nPress the associated number for the desired camera to see that display!"
|
||||
)
|
||||
print("(Selecting a camera that does not exist will default to camera 0)")
|
||||
for index, cam in enumerate(clist):
|
||||
print(f"[{index}]: {cam}")
|
||||
|
||||
going = True
|
||||
while going:
|
||||
events = pg.event.get()
|
||||
for e in events:
|
||||
if e.type == pg.QUIT or (e.type == pg.KEYDOWN and e.key == pg.K_ESCAPE):
|
||||
going = False
|
||||
if e.type == pg.KEYDOWN:
|
||||
if e.key in range(pg.K_0, pg.K_0 + 10):
|
||||
camera = self.init_cams(e.key - pg.K_0)
|
||||
|
||||
self.get_and_flip()
|
||||
self.clock.tick()
|
||||
pygame.display.set_caption(f"{camera} ({self.clock.get_fps():.2f} FPS)")
|
||||
|
||||
|
||||
def main():
|
||||
pg.init()
|
||||
pygame.camera.init()
|
||||
VideoCapturePlayer().main()
|
||||
pg.quit()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
203
venv/lib/python3.11/site-packages/pygame/examples/chimp.py
Normal file
|
@ -0,0 +1,203 @@
|
|||
#!/usr/bin/env python
|
||||
""" pygame.examples.chimp
|
||||
|
||||
This simple example is used for the line-by-line tutorial
|
||||
that comes with pygame. It is based on a 'popular' web banner.
|
||||
Note there are comments here, but for the full explanation,
|
||||
follow along in the tutorial.
|
||||
"""
|
||||
|
||||
|
||||
# Import Modules
|
||||
import os
|
||||
import pygame as pg
|
||||
|
||||
if not pg.font:
|
||||
print("Warning, fonts disabled")
|
||||
if not pg.mixer:
|
||||
print("Warning, sound disabled")
|
||||
|
||||
main_dir = os.path.split(os.path.abspath(__file__))[0]
|
||||
data_dir = os.path.join(main_dir, "data")
|
||||
|
||||
|
||||
# functions to create our resources
|
||||
def load_image(name, colorkey=None, scale=1):
|
||||
fullname = os.path.join(data_dir, name)
|
||||
image = pg.image.load(fullname)
|
||||
image = image.convert()
|
||||
|
||||
size = image.get_size()
|
||||
size = (size[0] * scale, size[1] * scale)
|
||||
image = pg.transform.scale(image, size)
|
||||
|
||||
if colorkey is not None:
|
||||
if colorkey == -1:
|
||||
colorkey = image.get_at((0, 0))
|
||||
image.set_colorkey(colorkey, pg.RLEACCEL)
|
||||
return image, image.get_rect()
|
||||
|
||||
|
||||
def load_sound(name):
|
||||
class NoneSound:
|
||||
def play(self):
|
||||
pass
|
||||
|
||||
if not pg.mixer or not pg.mixer.get_init():
|
||||
return NoneSound()
|
||||
|
||||
fullname = os.path.join(data_dir, name)
|
||||
sound = pg.mixer.Sound(fullname)
|
||||
|
||||
return sound
|
||||
|
||||
|
||||
# classes for our game objects
|
||||
class Fist(pg.sprite.Sprite):
|
||||
"""moves a clenched fist on the screen, following the mouse"""
|
||||
|
||||
def __init__(self):
|
||||
pg.sprite.Sprite.__init__(self) # call Sprite initializer
|
||||
self.image, self.rect = load_image("fist.png", -1)
|
||||
self.fist_offset = (-235, -80)
|
||||
self.punching = False
|
||||
|
||||
def update(self):
|
||||
"""move the fist based on the mouse position"""
|
||||
pos = pg.mouse.get_pos()
|
||||
self.rect.topleft = pos
|
||||
self.rect.move_ip(self.fist_offset)
|
||||
if self.punching:
|
||||
self.rect.move_ip(15, 25)
|
||||
|
||||
def punch(self, target):
|
||||
"""returns true if the fist collides with the target"""
|
||||
if not self.punching:
|
||||
self.punching = True
|
||||
hitbox = self.rect.inflate(-5, -5)
|
||||
return hitbox.colliderect(target.rect)
|
||||
|
||||
def unpunch(self):
|
||||
"""called to pull the fist back"""
|
||||
self.punching = False
|
||||
|
||||
|
||||
class Chimp(pg.sprite.Sprite):
|
||||
"""moves a monkey critter across the screen. it can spin the
|
||||
monkey when it is punched."""
|
||||
|
||||
def __init__(self):
|
||||
pg.sprite.Sprite.__init__(self) # call Sprite initializer
|
||||
self.image, self.rect = load_image("chimp.png", -1, 4)
|
||||
screen = pg.display.get_surface()
|
||||
self.area = screen.get_rect()
|
||||
self.rect.topleft = 10, 90
|
||||
self.move = 18
|
||||
self.dizzy = False
|
||||
|
||||
def update(self):
|
||||
"""walk or spin, depending on the monkeys state"""
|
||||
if self.dizzy:
|
||||
self._spin()
|
||||
else:
|
||||
self._walk()
|
||||
|
||||
def _walk(self):
|
||||
"""move the monkey across the screen, and turn at the ends"""
|
||||
newpos = self.rect.move((self.move, 0))
|
||||
if not self.area.contains(newpos):
|
||||
if self.rect.left < self.area.left or self.rect.right > self.area.right:
|
||||
self.move = -self.move
|
||||
newpos = self.rect.move((self.move, 0))
|
||||
self.image = pg.transform.flip(self.image, True, False)
|
||||
self.rect = newpos
|
||||
|
||||
def _spin(self):
|
||||
"""spin the monkey image"""
|
||||
center = self.rect.center
|
||||
self.dizzy = self.dizzy + 12
|
||||
if self.dizzy >= 360:
|
||||
self.dizzy = False
|
||||
self.image = self.original
|
||||
else:
|
||||
rotate = pg.transform.rotate
|
||||
self.image = rotate(self.original, self.dizzy)
|
||||
self.rect = self.image.get_rect(center=center)
|
||||
|
||||
def punched(self):
|
||||
"""this will cause the monkey to start spinning"""
|
||||
if not self.dizzy:
|
||||
self.dizzy = True
|
||||
self.original = self.image
|
||||
|
||||
|
||||
def main():
|
||||
"""this function is called when the program starts.
|
||||
it initializes everything it needs, then runs in
|
||||
a loop until the function returns."""
|
||||
# Initialize Everything
|
||||
pg.init()
|
||||
screen = pg.display.set_mode((1280, 480), pg.SCALED)
|
||||
pg.display.set_caption("Monkey Fever")
|
||||
pg.mouse.set_visible(False)
|
||||
|
||||
# Create The Background
|
||||
background = pg.Surface(screen.get_size())
|
||||
background = background.convert()
|
||||
background.fill((170, 238, 187))
|
||||
|
||||
# Put Text On The Background, Centered
|
||||
if pg.font:
|
||||
font = pg.font.Font(None, 64)
|
||||
text = font.render("Pummel The Chimp, And Win $$$", True, (10, 10, 10))
|
||||
textpos = text.get_rect(centerx=background.get_width() / 2, y=10)
|
||||
background.blit(text, textpos)
|
||||
|
||||
# Display The Background
|
||||
screen.blit(background, (0, 0))
|
||||
pg.display.flip()
|
||||
|
||||
# Prepare Game Objects
|
||||
whiff_sound = load_sound("whiff.wav")
|
||||
punch_sound = load_sound("punch.wav")
|
||||
chimp = Chimp()
|
||||
fist = Fist()
|
||||
allsprites = pg.sprite.RenderPlain((chimp, fist))
|
||||
clock = pg.time.Clock()
|
||||
|
||||
# Main Loop
|
||||
going = True
|
||||
while going:
|
||||
clock.tick(60)
|
||||
|
||||
# Handle Input Events
|
||||
for event in pg.event.get():
|
||||
if event.type == pg.QUIT:
|
||||
going = False
|
||||
elif event.type == pg.KEYDOWN and event.key == pg.K_ESCAPE:
|
||||
going = False
|
||||
elif event.type == pg.MOUSEBUTTONDOWN:
|
||||
if fist.punch(chimp):
|
||||
punch_sound.play() # punch
|
||||
chimp.punched()
|
||||
else:
|
||||
whiff_sound.play() # miss
|
||||
elif event.type == pg.MOUSEBUTTONUP:
|
||||
fist.unpunch()
|
||||
|
||||
allsprites.update()
|
||||
|
||||
# Draw Everything
|
||||
screen.blit(background, (0, 0))
|
||||
allsprites.draw(screen)
|
||||
pg.display.flip()
|
||||
|
||||
pg.quit()
|
||||
|
||||
|
||||
# Game Over
|
||||
|
||||
|
||||
# this calls the 'main' function when this script is executed
|
||||
if __name__ == "__main__":
|
||||
main()
|
259
venv/lib/python3.11/site-packages/pygame/examples/cursors.py
Normal file
|
@ -0,0 +1,259 @@
|
|||
#!/usr/bin/env python
|
||||
""" pygame.examples.cursors
|
||||
Click a button and the cursor will change.
|
||||
This example will show you:
|
||||
*The different types of cursors that exist
|
||||
*How to create a cursor
|
||||
*How to set a cursor
|
||||
*How to make a simple button
|
||||
"""
|
||||
|
||||
import pygame as pg
|
||||
import os
|
||||
|
||||
|
||||
# Create a system cursor
|
||||
|
||||
system_cursor1 = pg.SYSTEM_CURSOR_CROSSHAIR
|
||||
system_cursor2 = pg.SYSTEM_CURSOR_HAND
|
||||
system_cursor3 = pg.SYSTEM_CURSOR_IBEAM
|
||||
|
||||
|
||||
# Create a color cursor
|
||||
|
||||
surf = pg.Surface((40, 40))
|
||||
surf.fill((120, 50, 50))
|
||||
color_cursor = pg.cursors.Cursor((20, 20), surf)
|
||||
|
||||
|
||||
# Create a color cursor with an image surface
|
||||
|
||||
main_dir = os.path.split(os.path.abspath(__file__))[0]
|
||||
image_name = os.path.join(main_dir, "data", "cursor.png")
|
||||
image = pg.image.load(image_name)
|
||||
image_cursor = pg.cursors.Cursor(
|
||||
(image.get_width() // 2, image.get_height() // 2), image
|
||||
)
|
||||
|
||||
|
||||
# Create a bitmap cursor from simple strings
|
||||
|
||||
# sized 24x24
|
||||
thickarrow_strings = (
|
||||
"XX ",
|
||||
"XXX ",
|
||||
"XXXX ",
|
||||
"XX.XX ",
|
||||
"XX..XX ",
|
||||
"XX...XX ",
|
||||
"XX....XX ",
|
||||
"XX.....XX ",
|
||||
"XX......XX ",
|
||||
"XX.......XX ",
|
||||
"XX........XX ",
|
||||
"XX........XXX ",
|
||||
"XX......XXXXX ",
|
||||
"XX.XXX..XX ",
|
||||
"XXXX XX..XX ",
|
||||
"XX XX..XX ",
|
||||
" XX..XX ",
|
||||
" XX..XX ",
|
||||
" XX..XX ",
|
||||
" XXXX ",
|
||||
" XX ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
)
|
||||
|
||||
bitmap_cursor1 = pg.cursors.Cursor(
|
||||
(24, 24),
|
||||
(0, 0),
|
||||
*pg.cursors.compile(thickarrow_strings, black="X", white=".", xor="o"),
|
||||
)
|
||||
|
||||
|
||||
# Create a bitmap cursor from premade simple strings
|
||||
|
||||
bitmap_cursor2 = pg.cursors.diamond
|
||||
|
||||
|
||||
# Calculate if mouse position is inside circle
|
||||
def check_circle(mouse_pos_x, mouse_pos_y, center_x, center_y, radius):
|
||||
return (mouse_pos_x - center_x) ** 2 + (mouse_pos_y - center_y) ** 2 < radius**2
|
||||
|
||||
|
||||
def main():
|
||||
pg.init()
|
||||
pg.display.set_caption("Cursors Example")
|
||||
|
||||
pg.font.init()
|
||||
font = pg.font.Font(None, 30)
|
||||
font1 = pg.font.Font(None, 24)
|
||||
|
||||
bg = pg.display.set_mode((500, 400))
|
||||
bg.fill((183, 201, 226))
|
||||
|
||||
# Initialize circles
|
||||
radius1 = 40
|
||||
radius2 = 40
|
||||
radius3 = 40
|
||||
radius4 = 40
|
||||
radius5 = 40
|
||||
radius6 = 40
|
||||
radius7 = 40
|
||||
|
||||
pos_x1 = 82
|
||||
pos_x2 = 138
|
||||
pos_x3 = 194
|
||||
pos_x4 = 250
|
||||
pos_x5 = 306
|
||||
pos_x6 = 362
|
||||
pos_x7 = 418
|
||||
|
||||
pos_y1 = 140
|
||||
pos_y2 = 220
|
||||
pos_y3 = 140
|
||||
pos_y4 = 220
|
||||
pos_y5 = 140
|
||||
pos_y6 = 220
|
||||
pos_y7 = 140
|
||||
|
||||
circle1 = pg.draw.circle(bg, (255, 255, 255), (pos_x1, pos_y1), radius1)
|
||||
circle2 = pg.draw.circle(bg, (255, 255, 255), (pos_x2, pos_y2), radius2)
|
||||
circle3 = pg.draw.circle(bg, (255, 255, 255), (pos_x3, pos_y3), radius3)
|
||||
circle4 = pg.draw.circle(bg, (255, 255, 255), (pos_x4, pos_y4), radius4)
|
||||
circle5 = pg.draw.circle(bg, (255, 255, 255), (pos_x5, pos_y5), radius5)
|
||||
circle6 = pg.draw.circle(bg, (255, 255, 255), (pos_x6, pos_y6), radius6)
|
||||
circle7 = pg.draw.circle(bg, (255, 255, 255), (pos_x7, pos_y7), radius7)
|
||||
|
||||
# Initialize button
|
||||
button_text = font1.render("Click here to change cursor", True, (0, 0, 0))
|
||||
button = pg.draw.rect(
|
||||
bg,
|
||||
(180, 180, 180),
|
||||
(139, 300, button_text.get_width() + 5, button_text.get_height() + 50),
|
||||
)
|
||||
button_text_rect = button_text.get_rect(center=button.center)
|
||||
bg.blit(button_text, button_text_rect)
|
||||
|
||||
pg.display.update()
|
||||
|
||||
cursors = [
|
||||
system_cursor1,
|
||||
color_cursor,
|
||||
system_cursor2,
|
||||
image_cursor,
|
||||
system_cursor3,
|
||||
bitmap_cursor1,
|
||||
bitmap_cursor2,
|
||||
]
|
||||
|
||||
index = 0
|
||||
pg.mouse.set_cursor(cursors[index])
|
||||
|
||||
pressed = False
|
||||
clock = pg.time.Clock()
|
||||
|
||||
while True:
|
||||
clock.tick(50)
|
||||
|
||||
mouse_x, mouse_y = pg.mouse.get_pos()
|
||||
|
||||
# Check if mouse is inside a circle to change its color
|
||||
if check_circle(mouse_x, mouse_y, circle1.centerx, circle1.centery, radius1):
|
||||
circle1 = pg.draw.circle(bg, (255, 0, 0), (pos_x1, pos_y1), radius1)
|
||||
else:
|
||||
circle1 = pg.draw.circle(bg, (255, 255, 255), (pos_x1, pos_y1), radius1)
|
||||
|
||||
if check_circle(mouse_x, mouse_y, circle2.centerx, circle2.centery, radius2):
|
||||
circle2 = pg.draw.circle(bg, (255, 127, 0), (pos_x2, pos_y2), radius2)
|
||||
else:
|
||||
circle2 = pg.draw.circle(bg, (255, 255, 255), (pos_x2, pos_y2), radius2)
|
||||
|
||||
if check_circle(mouse_x, mouse_y, circle3.centerx, circle3.centery, radius3):
|
||||
circle3 = pg.draw.circle(bg, (255, 255, 0), (pos_x3, pos_y3), radius3)
|
||||
else:
|
||||
circle3 = pg.draw.circle(bg, (255, 255, 255), (pos_x3, pos_y3), radius3)
|
||||
|
||||
if check_circle(mouse_x, mouse_y, circle4.centerx, circle4.centery, radius3):
|
||||
circle4 = pg.draw.circle(bg, (0, 255, 0), (pos_x4, pos_y4), radius4)
|
||||
else:
|
||||
circle4 = pg.draw.circle(bg, (255, 255, 255), (pos_x4, pos_y4), radius4)
|
||||
|
||||
if check_circle(mouse_x, mouse_y, circle5.centerx, circle5.centery, radius4):
|
||||
circle5 = pg.draw.circle(bg, (0, 0, 255), (pos_x5, pos_y5), radius5)
|
||||
else:
|
||||
circle5 = pg.draw.circle(bg, (255, 255, 255), (pos_x5, pos_y5), radius5)
|
||||
|
||||
if check_circle(mouse_x, mouse_y, circle6.centerx, circle6.centery, radius6):
|
||||
circle6 = pg.draw.circle(bg, (75, 0, 130), (pos_x6, pos_y6), radius6)
|
||||
else:
|
||||
circle6 = pg.draw.circle(bg, (255, 255, 255), (pos_x6, pos_y6), radius6)
|
||||
|
||||
if check_circle(mouse_x, mouse_y, circle7.centerx, circle7.centery, radius7):
|
||||
circle7 = pg.draw.circle(bg, (148, 0, 211), (pos_x7, pos_y7), radius7)
|
||||
else:
|
||||
circle7 = pg.draw.circle(bg, (255, 255, 255), (pos_x7, pos_y7), radius7)
|
||||
|
||||
bg.fill((183, 201, 226), (0, 15, bg.get_width(), 50))
|
||||
text1 = font.render(
|
||||
(f"This is a {pg.mouse.get_cursor().type} cursor"), True, (0, 0, 0)
|
||||
)
|
||||
text_rect1 = text1.get_rect(center=(bg.get_width() / 2, 40))
|
||||
bg.blit(text1, text_rect1)
|
||||
|
||||
button = pg.draw.rect(
|
||||
bg,
|
||||
(100, 149, 240),
|
||||
(139, 300, button_text.get_width() + 5, button_text.get_height() + 50),
|
||||
)
|
||||
bg.blit(button_text, button_text_rect)
|
||||
|
||||
# Check if button was clicked and change cursor
|
||||
if button.collidepoint(mouse_x, mouse_y):
|
||||
button = pg.draw.rect(
|
||||
bg,
|
||||
(60, 100, 255),
|
||||
(
|
||||
139,
|
||||
300,
|
||||
button_text.get_width() + 5,
|
||||
button_text.get_height() + 50,
|
||||
),
|
||||
)
|
||||
bg.blit(button_text, button_text_rect)
|
||||
|
||||
if pg.mouse.get_pressed()[0] == 1 and pressed is False:
|
||||
button = pg.draw.rect(
|
||||
bg,
|
||||
(0, 0, 139),
|
||||
(
|
||||
139,
|
||||
300,
|
||||
button_text.get_width() + 5,
|
||||
button_text.get_height() + 50,
|
||||
),
|
||||
)
|
||||
bg.blit(button_text, button_text_rect)
|
||||
index += 1
|
||||
index %= len(cursors)
|
||||
pg.mouse.set_cursor(cursors[index])
|
||||
pg.display.update()
|
||||
pg.time.delay(40)
|
||||
|
||||
if pg.mouse.get_pressed()[0] == 1:
|
||||
pressed = True
|
||||
elif pg.mouse.get_pressed()[0] == 0:
|
||||
pressed = False
|
||||
|
||||
for event in pg.event.get():
|
||||
if event.type == pg.QUIT:
|
||||
pg.quit()
|
||||
raise SystemExit
|
||||
|
||||
pg.display.update()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
BIN
venv/lib/python3.11/site-packages/pygame/examples/data/BGR.png
Normal file
After Width: | Height: | Size: 244 B |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 3 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 75 KiB |
After Width: | Height: | Size: 578 B |
After Width: | Height: | Size: 8.9 KiB |
3076
venv/lib/python3.11/site-packages/pygame/examples/data/black.ppm
Normal file
BIN
venv/lib/python3.11/site-packages/pygame/examples/data/blue.gif
Normal file
After Width: | Height: | Size: 84 B |
BIN
venv/lib/python3.11/site-packages/pygame/examples/data/blue.mpg
Normal file
BIN
venv/lib/python3.11/site-packages/pygame/examples/data/bomb.gif
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
venv/lib/python3.11/site-packages/pygame/examples/data/boom.wav
Normal file
BIN
venv/lib/python3.11/site-packages/pygame/examples/data/brick.png
Normal file
After Width: | Height: | Size: 170 B |
BIN
venv/lib/python3.11/site-packages/pygame/examples/data/chimp.png
Normal file
After Width: | Height: | Size: 826 B |
BIN
venv/lib/python3.11/site-packages/pygame/examples/data/city.png
Normal file
After Width: | Height: | Size: 143 B |
|
@ -0,0 +1,5 @@
|
|||
P6
|
||||
# CREATOR: GIMP PNM Filter Version 1.1
|
||||
32 32
|
||||
255
|
||||
ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<ワ<
|
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 6.4 KiB |
BIN
venv/lib/python3.11/site-packages/pygame/examples/data/fist.png
Normal file
After Width: | Height: | Size: 84 KiB |
BIN
venv/lib/python3.11/site-packages/pygame/examples/data/green.pcx
Normal file
1028
venv/lib/python3.11/site-packages/pygame/examples/data/grey.pgm
Normal file
After Width: | Height: | Size: 253 B |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 3.4 KiB |
BIN
venv/lib/python3.11/site-packages/pygame/examples/data/punch.wav
Normal file
|
@ -0,0 +1,36 @@
|
|||
/* XPM */
|
||||
static char * C:\Users\Kristof\Documents\purple_xpm[] = {
|
||||
"32 32 1 1",
|
||||
" c #FF00FF",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "};
|
BIN
venv/lib/python3.11/site-packages/pygame/examples/data/red.jpg
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
venv/lib/python3.11/site-packages/pygame/examples/data/sans.ttf
Normal file
After Width: | Height: | Size: 82 B |
BIN
venv/lib/python3.11/site-packages/pygame/examples/data/shot.gif
Normal file
After Width: | Height: | Size: 129 B |
After Width: | Height: | Size: 1.2 KiB |
|
@ -0,0 +1,9 @@
|
|||
<svg width="32" height="32" xmlns="http://www.w3.org/2000/svg">
|
||||
<title>teal</title>
|
||||
|
||||
<g>
|
||||
<title>Layer 1</title>
|
||||
<rect fill="#fff" stroke="#000" x="0" y="0" width="32" height="32" id="svg_1"/>
|
||||
<rect stroke-width="0" id="svg_2" height="32" width="32" y="0" x="0" stroke="#000" fill="#008080"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 313 B |
BIN
venv/lib/python3.11/site-packages/pygame/examples/data/whiff.wav
Normal file
After Width: | Height: | Size: 3 KiB |
|
@ -0,0 +1,72 @@
|
|||
#!/usr/bin/env python
|
||||
""" pygame.examples.dropfile
|
||||
|
||||
Drag and drop an image on here.
|
||||
|
||||
Uses these events:
|
||||
|
||||
* DROPBEGIN
|
||||
* DROPCOMPLETE
|
||||
* DROPTEXT
|
||||
* DROPFILE
|
||||
"""
|
||||
import pygame as pg
|
||||
|
||||
|
||||
def main():
|
||||
pg.init()
|
||||
|
||||
going = True
|
||||
surf = pg.display.set_mode((640, 480))
|
||||
font = pg.font.SysFont("Arial", 24)
|
||||
clock = pg.time.Clock()
|
||||
|
||||
spr_file_text = font.render("Drag and drop a file or image!", 1, (255, 255, 255))
|
||||
spr_file_text_rect = spr_file_text.get_rect()
|
||||
spr_file_text_rect.center = surf.get_rect().center
|
||||
|
||||
spr_file_image = None
|
||||
spr_file_image_rect = None
|
||||
|
||||
while going:
|
||||
for ev in pg.event.get():
|
||||
if ev.type == pg.QUIT:
|
||||
going = False
|
||||
elif ev.type == pg.DROPBEGIN:
|
||||
print(ev)
|
||||
print("File drop begin!")
|
||||
elif ev.type == pg.DROPCOMPLETE:
|
||||
print(ev)
|
||||
print("File drop complete!")
|
||||
elif ev.type == pg.DROPTEXT:
|
||||
print(ev)
|
||||
spr_file_text = font.render(ev.text, 1, (255, 255, 255))
|
||||
spr_file_text_rect = spr_file_text.get_rect()
|
||||
spr_file_text_rect.center = surf.get_rect().center
|
||||
elif ev.type == pg.DROPFILE:
|
||||
print(ev)
|
||||
spr_file_text = font.render(ev.file, 1, (255, 255, 255))
|
||||
spr_file_text_rect = spr_file_text.get_rect()
|
||||
spr_file_text_rect.center = surf.get_rect().center
|
||||
|
||||
# Try to open the file if it's an image
|
||||
filetype = ev.file[-3:]
|
||||
if filetype in ["png", "bmp", "jpg"]:
|
||||
spr_file_image = pg.image.load(ev.file).convert()
|
||||
spr_file_image.set_alpha(127)
|
||||
spr_file_image_rect = spr_file_image.get_rect()
|
||||
spr_file_image_rect.center = surf.get_rect().center
|
||||
|
||||
surf.fill((0, 0, 0))
|
||||
surf.blit(spr_file_text, spr_file_text_rect)
|
||||
if spr_file_image and spr_file_image_rect is not None:
|
||||
surf.blit(spr_file_image, spr_file_image_rect)
|
||||
|
||||
pg.display.flip()
|
||||
clock.tick(30)
|
||||
|
||||
pg.quit()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
194
venv/lib/python3.11/site-packages/pygame/examples/eventlist.py
Normal file
|
@ -0,0 +1,194 @@
|
|||
#!/usr/bin/env python
|
||||
""" pygame.examples.eventlist
|
||||
|
||||
Learn about pygame events and input.
|
||||
|
||||
At the top of the screen are the state of several device values,
|
||||
and a scrolling list of events are displayed on the bottom.
|
||||
|
||||
"""
|
||||
|
||||
usage = """
|
||||
Mouse Controls
|
||||
==============
|
||||
|
||||
- 1st button on mouse (left click) to toggle events 'grabed'.
|
||||
- 3rd button on mouse (right click) to toggle mouse visible.
|
||||
- The window can be resized.
|
||||
- Mouse the mouse around to see mouse events.
|
||||
- If events grabbed and mouse invisible show virtual mouse coords.
|
||||
|
||||
|
||||
Keyboard Joystick Controls
|
||||
==========================
|
||||
|
||||
- press keys up an down to see events.
|
||||
- you can see joystick events if any are plugged in.
|
||||
- press "c" to toggle events generated by controllers.
|
||||
"""
|
||||
|
||||
from typing import List
|
||||
import pygame as pg
|
||||
|
||||
import pygame._sdl2.controller
|
||||
|
||||
|
||||
img_on_off: List[pg.Surface] = []
|
||||
font: pg.font.Font
|
||||
last_key = None
|
||||
|
||||
# these are a running counter of mouse.get_rel() calls.
|
||||
virtual_x = 0
|
||||
virtual_y = 0
|
||||
|
||||
|
||||
def showtext(win, pos, text, color, bgcolor):
|
||||
textimg = font.render(text, 1, color, bgcolor)
|
||||
win.blit(textimg, pos)
|
||||
return pos[0] + textimg.get_width() + 5, pos[1]
|
||||
|
||||
|
||||
def drawstatus(win):
|
||||
global virtual_x, virtual_y
|
||||
bgcolor = 50, 50, 50
|
||||
win.fill(bgcolor, (0, 0, 640, 120))
|
||||
win.blit(font.render("Status Area", 1, (155, 155, 155), bgcolor), (2, 2))
|
||||
|
||||
pos = showtext(win, (10, 30), "Mouse Focus", (255, 255, 255), bgcolor)
|
||||
win.blit(img_on_off[pg.mouse.get_focused()], pos)
|
||||
|
||||
pos = showtext(
|
||||
win, (pos[0] + 50, pos[1]), "Mouse visible", (255, 255, 255), bgcolor
|
||||
)
|
||||
win.blit(img_on_off[pg.mouse.get_visible()], pos)
|
||||
|
||||
pos = showtext(win, (330, 30), "Keyboard Focus", (255, 255, 255), bgcolor)
|
||||
win.blit(img_on_off[pg.key.get_focused()], pos)
|
||||
|
||||
pos = showtext(win, (10, 60), "Mouse Position(rel)", (255, 255, 255), bgcolor)
|
||||
rel = pg.mouse.get_rel()
|
||||
virtual_x += rel[0]
|
||||
virtual_y += rel[1]
|
||||
|
||||
mouse_data = tuple(list(pg.mouse.get_pos()) + list(rel))
|
||||
p = "%s, %s (%s, %s)" % mouse_data
|
||||
showtext(win, pos, p, bgcolor, (255, 255, 55))
|
||||
|
||||
pos = showtext(win, (330, 60), "Last Keypress", (255, 255, 255), bgcolor)
|
||||
if last_key:
|
||||
p = "%d, %s" % (last_key, pg.key.name(last_key))
|
||||
else:
|
||||
p = "None"
|
||||
showtext(win, pos, p, bgcolor, (255, 255, 55))
|
||||
|
||||
pos = showtext(win, (10, 90), "Input Grabbed", (255, 255, 255), bgcolor)
|
||||
win.blit(img_on_off[pg.event.get_grab()], pos)
|
||||
|
||||
is_virtual_mouse = pg.event.get_grab() and not pg.mouse.get_visible()
|
||||
pos = showtext(win, (330, 90), "Virtual Mouse", (255, 255, 255), bgcolor)
|
||||
win.blit(img_on_off[is_virtual_mouse], pos)
|
||||
if is_virtual_mouse:
|
||||
p = f"{virtual_x}, {virtual_y}"
|
||||
showtext(win, (pos[0] + 50, pos[1]), p, bgcolor, (255, 255, 55))
|
||||
|
||||
|
||||
def drawhistory(win, history):
|
||||
img = font.render("Event History Area", 1, (155, 155, 155), (0, 0, 0))
|
||||
win.blit(img, (2, 132))
|
||||
ypos = 450
|
||||
h = list(history)
|
||||
h.reverse()
|
||||
for line in h:
|
||||
r = win.blit(line, (10, ypos))
|
||||
win.fill(0, (r.right, r.top, 620, r.height))
|
||||
ypos -= font.get_height()
|
||||
|
||||
|
||||
def draw_usage_in_history(history, text):
|
||||
lines = text.split("\n")
|
||||
for line in lines:
|
||||
if line == "" or "===" in line:
|
||||
continue
|
||||
img = font.render(line, 1, (50, 200, 50), (0, 0, 0))
|
||||
history.append(img)
|
||||
|
||||
|
||||
def main():
|
||||
pg.init()
|
||||
pygame._sdl2.controller.init()
|
||||
|
||||
print(usage)
|
||||
|
||||
win = pg.display.set_mode((640, 480), pg.RESIZABLE)
|
||||
pg.display.set_caption("Mouse Focus Workout. h key for help")
|
||||
|
||||
global font
|
||||
font = pg.font.Font(None, 26)
|
||||
|
||||
global img_on_off
|
||||
img_on_off.append(font.render("Off", 1, (0, 0, 0), (255, 50, 50)))
|
||||
img_on_off.append(font.render("On", 1, (0, 0, 0), (50, 255, 50)))
|
||||
|
||||
# stores surfaces of text representing what has gone through the event queue
|
||||
history = []
|
||||
|
||||
# let's turn on the joysticks just so we can play with em
|
||||
for x in range(pg.joystick.get_count()):
|
||||
if pygame._sdl2.controller.is_controller(x):
|
||||
c = pygame._sdl2.controller.Controller(x)
|
||||
txt = "Enabled controller: " + c.name
|
||||
else:
|
||||
j = pg.joystick.Joystick(x)
|
||||
txt = "Enabled joystick: " + j.get_name()
|
||||
|
||||
img = font.render(txt, 1, (50, 200, 50), (0, 0, 0))
|
||||
history.append(img)
|
||||
if not pg.joystick.get_count():
|
||||
img = font.render("No Joysticks to Initialize", 1, (50, 200, 50), (0, 0, 0))
|
||||
history.append(img)
|
||||
|
||||
going = True
|
||||
while going:
|
||||
for e in pg.event.get():
|
||||
if e.type == pg.KEYDOWN:
|
||||
if e.key == pg.K_ESCAPE:
|
||||
going = False
|
||||
else:
|
||||
global last_key
|
||||
last_key = e.key
|
||||
if e.key == pg.K_h:
|
||||
draw_usage_in_history(history, usage)
|
||||
if e.key == pg.K_c:
|
||||
current_state = pygame._sdl2.controller.get_eventstate()
|
||||
pygame._sdl2.controller.set_eventstate(not current_state)
|
||||
|
||||
if e.type == pg.MOUSEBUTTONDOWN and e.button == 1:
|
||||
pg.event.set_grab(not pg.event.get_grab())
|
||||
|
||||
if e.type == pg.MOUSEBUTTONDOWN and e.button == 3:
|
||||
pg.mouse.set_visible(not pg.mouse.get_visible())
|
||||
|
||||
if e.type != pg.MOUSEMOTION:
|
||||
txt = f"{pg.event.event_name(e.type)}: {e.dict}"
|
||||
img = font.render(txt, 1, (50, 200, 50), (0, 0, 0))
|
||||
history.append(img)
|
||||
history = history[-13:]
|
||||
|
||||
if e.type == pg.VIDEORESIZE:
|
||||
win = pg.display.set_mode(e.size, pg.RESIZABLE)
|
||||
|
||||
if e.type == pg.QUIT:
|
||||
going = False
|
||||
|
||||
drawstatus(win)
|
||||
drawhistory(win, history)
|
||||
|
||||
pg.display.flip()
|
||||
pg.time.wait(10)
|
||||
|
||||
pg.quit()
|
||||
raise SystemExit
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
278
venv/lib/python3.11/site-packages/pygame/examples/font_viewer.py
Normal file
|
@ -0,0 +1,278 @@
|
|||
#!/usr/bin/env python
|
||||
""" pygame.examples.font_viewer
|
||||
Scroll through your system fonts from a list of surfaces or one huge buffer.
|
||||
|
||||
This example exhibits:
|
||||
* iterate over available fonts using font.get_fonts and font.SysFont()
|
||||
* click and drag using mouse input
|
||||
* scrolling with the scroll wheel
|
||||
* save a surface to disk
|
||||
* work with a very large surface
|
||||
* simple mouse and keyboard scroll speed acceleration
|
||||
|
||||
By default this example uses the fonts returned by pygame.font.get_fonts()
|
||||
and opens them using pygame.font.SysFont().
|
||||
Alternatively, you may pass a path to the command line. The TTF files found
|
||||
in that directory will be used instead.
|
||||
|
||||
Mouse Controls:
|
||||
* Use the mouse wheel or click and drag to scroll
|
||||
|
||||
Keyboard Controls:
|
||||
* Press up or down to scroll
|
||||
* Press escape to exit
|
||||
"""
|
||||
import sys
|
||||
import os
|
||||
|
||||
import pygame as pg
|
||||
|
||||
use_big_surface = False # draw into large buffer and save png file
|
||||
|
||||
|
||||
class FontViewer:
|
||||
"""
|
||||
This example is encapsulated by the fontviewer class
|
||||
It initializes the pygame window, handles input, and draws itself
|
||||
to the screen.
|
||||
"""
|
||||
|
||||
KEY_SCROLL_SPEED = 10
|
||||
MOUSE_SCROLL_SPEED = 50
|
||||
|
||||
def __init__(self):
|
||||
pg.init()
|
||||
|
||||
# create a window that uses 80 percent of the screen
|
||||
info = pg.display.Info()
|
||||
w = info.current_w
|
||||
h = info.current_h
|
||||
pg.display.set_mode((int(w * 0.8), int(h * 0.8)))
|
||||
self.font_size = h // 20
|
||||
|
||||
self.clock = pg.time.Clock()
|
||||
self.y_offset = 0
|
||||
self.grabbed = False
|
||||
self.render_fonts("&N abcDEF789")
|
||||
|
||||
if use_big_surface or "big" in sys.argv:
|
||||
self.render_surface()
|
||||
self.display_surface()
|
||||
self.save_png()
|
||||
else:
|
||||
self.display_fonts()
|
||||
|
||||
def get_font_list(self):
|
||||
"""
|
||||
Generate a font list using font.get_fonts() for system fonts or
|
||||
from a path from the command line.
|
||||
"""
|
||||
path = ""
|
||||
if len(sys.argv) > 1 and os.path.exists(sys.argv[1]):
|
||||
path = os.path.join(sys.argv[1], "")
|
||||
if os.path.exists(path):
|
||||
fonts = [font for font in os.listdir(path) if font.endswith(".ttf")]
|
||||
else:
|
||||
fonts = pg.font.get_fonts()
|
||||
return fonts, path
|
||||
|
||||
def render_fonts(self, text="A display of font &N"):
|
||||
"""
|
||||
Build a list that includes a surface and the running total of their
|
||||
height for each font in the font list. Store the largest width and
|
||||
other variables for later use.
|
||||
"""
|
||||
font_size = self.font_size
|
||||
color = (255, 255, 255)
|
||||
instruction_color = (255, 255, 0)
|
||||
self.back_color = (0, 0, 0)
|
||||
|
||||
fonts, path = self.get_font_list()
|
||||
font_surfaces = []
|
||||
total_height = 0
|
||||
max_width = 0
|
||||
|
||||
load_font = pg.font.Font if path else pg.font.SysFont
|
||||
|
||||
# display instructions at the top of the display
|
||||
font = pg.font.SysFont(pg.font.get_default_font(), font_size)
|
||||
lines = (
|
||||
"Use the scroll wheel or click and drag",
|
||||
"to scroll up and down.",
|
||||
"Fonts that don't use the Latin Alphabet",
|
||||
"might render incorrectly.",
|
||||
f"Here are your {len(fonts)} fonts",
|
||||
"",
|
||||
)
|
||||
for line in lines:
|
||||
surf = font.render(line, 1, instruction_color, self.back_color)
|
||||
font_surfaces.append((surf, total_height))
|
||||
total_height += surf.get_height()
|
||||
max_width = max(max_width, surf.get_width())
|
||||
|
||||
# render all the fonts and store them with the total height
|
||||
for name in sorted(fonts):
|
||||
try:
|
||||
font = load_font(path + name, font_size)
|
||||
except OSError:
|
||||
continue
|
||||
line = text.replace("&N", name)
|
||||
try:
|
||||
surf = font.render(line, 1, color, self.back_color)
|
||||
except pg.error as e:
|
||||
print(e)
|
||||
break
|
||||
|
||||
max_width = max(max_width, surf.get_width())
|
||||
font_surfaces.append((surf, total_height))
|
||||
total_height += surf.get_height()
|
||||
|
||||
# store variables for later usage
|
||||
self.total_height = total_height
|
||||
self.max_width = max_width
|
||||
self.font_surfaces = font_surfaces
|
||||
self.max_y = total_height - pg.display.get_surface().get_height()
|
||||
|
||||
def display_fonts(self):
|
||||
"""
|
||||
Display the visible fonts based on the y_offset value(updated in
|
||||
handle_events) and the height of the pygame window.
|
||||
"""
|
||||
pg.display.set_caption("Font Viewer")
|
||||
display = pg.display.get_surface()
|
||||
clock = pg.time.Clock()
|
||||
center = display.get_width() // 2
|
||||
|
||||
while True:
|
||||
# draw visible surfaces
|
||||
display.fill(self.back_color)
|
||||
for surface, top in self.font_surfaces:
|
||||
bottom = top + surface.get_height()
|
||||
if (
|
||||
bottom >= self.y_offset
|
||||
and top <= self.y_offset + display.get_height()
|
||||
):
|
||||
x = center - surface.get_width() // 2
|
||||
display.blit(surface, (x, top - self.y_offset))
|
||||
# get input and update the screen
|
||||
if not self.handle_events():
|
||||
break
|
||||
pg.display.flip()
|
||||
clock.tick(30)
|
||||
|
||||
def render_surface(self):
|
||||
"""
|
||||
Note: this method uses twice the memory and is only called if
|
||||
big_surface is set to true or big is added to the command line.
|
||||
|
||||
Optionally generates one large buffer to draw all the font surfaces
|
||||
into. This is necessary to save the display to a png file and may
|
||||
be useful for testing large surfaces.
|
||||
"""
|
||||
|
||||
large_surface = pg.surface.Surface(
|
||||
(self.max_width, self.total_height)
|
||||
).convert()
|
||||
large_surface.fill(self.back_color)
|
||||
print("scrolling surface created")
|
||||
|
||||
# display the surface size and memory usage
|
||||
byte_size = large_surface.get_bytesize()
|
||||
total_size = byte_size * (self.max_width * self.total_height)
|
||||
print(
|
||||
"Surface Size = {}x{} @ {}bpp: {:,.3f}mb".format(
|
||||
self.max_width, self.total_height, byte_size, total_size / 1000000.0
|
||||
)
|
||||
)
|
||||
|
||||
y = 0
|
||||
center = int(self.max_width / 2)
|
||||
for surface, top in self.font_surfaces:
|
||||
w = surface.get_width()
|
||||
x = center - int(w / 2)
|
||||
large_surface.blit(surface, (x, y))
|
||||
y += surface.get_height()
|
||||
self.max_y = large_surface.get_height() - pg.display.get_surface().get_height()
|
||||
self.surface = large_surface
|
||||
|
||||
def display_surface(self, time=10):
|
||||
"""
|
||||
Display the large surface created by the render_surface method. Scrolls
|
||||
based on the y_offset value(set in handle_events) and the height of the
|
||||
pygame window.
|
||||
"""
|
||||
screen = pg.display.get_surface()
|
||||
|
||||
# Create a Rect equal to size of screen. Then we can just change its
|
||||
# top attribute to draw the desired part of the rendered font surface
|
||||
# to the display surface
|
||||
rect = pg.rect.Rect(
|
||||
0,
|
||||
0,
|
||||
self.surface.get_width(),
|
||||
min(self.surface.get_height(), screen.get_height()),
|
||||
)
|
||||
|
||||
x = int((screen.get_width() - self.surface.get_width()) / 2)
|
||||
going = True
|
||||
while going:
|
||||
if not self.handle_events():
|
||||
going = False
|
||||
screen.fill(self.back_color)
|
||||
rect.top = self.y_offset
|
||||
screen.blit(self.surface, (x, 0), rect)
|
||||
pg.display.flip()
|
||||
self.clock.tick(20)
|
||||
|
||||
def save_png(self, name="font_viewer.png"):
|
||||
pg.image.save(self.surface, name)
|
||||
file_size = os.path.getsize(name) // 1024
|
||||
print(f"font surface saved to {name}\nsize: {file_size:,}Kb")
|
||||
|
||||
def handle_events(self):
|
||||
"""
|
||||
This method handles user input. It returns False when it receives
|
||||
a pygame.QUIT event or the user presses escape. The y_offset is
|
||||
changed based on mouse and keyboard input. display_fonts() and
|
||||
display_surface() use the y_offset to scroll display.
|
||||
"""
|
||||
events = pg.event.get()
|
||||
for e in events:
|
||||
if e.type == pg.QUIT:
|
||||
return False
|
||||
elif e.type == pg.KEYDOWN:
|
||||
if e.key == pg.K_ESCAPE:
|
||||
return False
|
||||
elif e.type == pg.MOUSEWHEEL:
|
||||
self.y_offset += e.y * self.MOUSE_SCROLL_SPEED * -1
|
||||
elif e.type == pg.MOUSEBUTTONDOWN:
|
||||
# enter dragging mode on mouse down
|
||||
self.grabbed = True
|
||||
pg.event.set_grab(True)
|
||||
elif e.type == pg.MOUSEBUTTONUP:
|
||||
# exit drag mode on mouse up
|
||||
self.grabbed = False
|
||||
pg.event.set_grab(False)
|
||||
|
||||
# allow simple accelerated scrolling with the keyboard
|
||||
keys = pg.key.get_pressed()
|
||||
if keys[pg.K_UP]:
|
||||
self.key_held += 1
|
||||
self.y_offset -= int(self.KEY_SCROLL_SPEED * (self.key_held // 10))
|
||||
elif keys[pg.K_DOWN]:
|
||||
self.key_held += 1
|
||||
self.y_offset += int(self.KEY_SCROLL_SPEED * (self.key_held // 10))
|
||||
else:
|
||||
self.key_held = 20
|
||||
|
||||
# set the y_offset for scrolling and keep it between 0 and max_y
|
||||
y = pg.mouse.get_rel()[1]
|
||||
if y and self.grabbed:
|
||||
self.y_offset -= y
|
||||
|
||||
self.y_offset = min((max(self.y_offset, 0), self.max_y))
|
||||
return True
|
||||
|
||||
|
||||
viewer = FontViewer()
|
||||
pg.quit()
|