Compare commits
10 commits
6c9033bcd5
...
de1001dd57
| Author | SHA1 | Date | |
|---|---|---|---|
| de1001dd57 | |||
|
|
f55c2fe32b | ||
| 8b1dfad72a | |||
|
|
db4f2ae64b | ||
| d691f1a5ec | |||
| 21b631ec2a | |||
| a2ffbd4123 | |||
| 96f1f6b3c2 | |||
| 3f5a10f090 | |||
| db22a7a168 |
1
.gitignore
vendored
|
|
@ -956,3 +956,4 @@ FodyWeavers.xsd
|
||||||
# Additional files built by Visual Studio
|
# Additional files built by Visual Studio
|
||||||
|
|
||||||
# End of https://www.toptal.com/developers/gitignore/api/vim,node,data,emacs,python,pycharm,executable,sublimetext,visualstudio,visualstudiocode
|
# End of https://www.toptal.com/developers/gitignore/api/vim,node,data,emacs,python,pycharm,executable,sublimetext,visualstudio,visualstudiocode
|
||||||
|
.null-ls_574349_tetris.py
|
||||||
|
|
|
||||||
108
aforest.py
Normal file
|
|
@ -0,0 +1,108 @@
|
||||||
|
import math
|
||||||
|
|
||||||
|
import noise
|
||||||
|
import pygame
|
||||||
|
|
||||||
|
# set up pygame
|
||||||
|
pygame.init()
|
||||||
|
|
||||||
|
# set up the window
|
||||||
|
screen_width, screen_height = 1280, 800
|
||||||
|
screen = pygame.display.set_mode((screen_width, screen_height))
|
||||||
|
# set up the noise surface
|
||||||
|
noise_width, noise_height = 1280, 800
|
||||||
|
noise_scale = 10
|
||||||
|
noise_width = int(screen_width / noise_scale)
|
||||||
|
noise_height = int(screen_height / noise_scale)
|
||||||
|
# noise_width, noise_height = round(1280 / 10), round(800 / 10)
|
||||||
|
noise_surface = pygame.Surface((noise_width, noise_height))
|
||||||
|
# set up the colors
|
||||||
|
BLACK = (0, 0, 0)
|
||||||
|
GREEN = (0, 255, 0)
|
||||||
|
BLUE = (0, 0, 255)
|
||||||
|
colors = [(0, 128, 0), (0, 64, 0), (0, 32, 0)]
|
||||||
|
# set up the noise
|
||||||
|
octaves = 1
|
||||||
|
freq = 256 * octaves
|
||||||
|
# generate the noise
|
||||||
|
noise_map = [
|
||||||
|
[
|
||||||
|
noise.pnoise2(x / freq, y / freq, octaves, repeatx=3024, repeaty=3024)
|
||||||
|
for x in range(screen_width)
|
||||||
|
]
|
||||||
|
for y in range(screen_height)
|
||||||
|
]
|
||||||
|
# set up the clock
|
||||||
|
clock = pygame.time.Clock()
|
||||||
|
# set up the animation
|
||||||
|
frame = 0
|
||||||
|
# set up the noise surface cache
|
||||||
|
noise_surface_cache = []
|
||||||
|
# set up the noise surface cache index
|
||||||
|
noise_surface_cache_index = 0
|
||||||
|
# set up the noise surface cache size
|
||||||
|
noise_surface_cache_size = 120
|
||||||
|
# set up the noise surface cache
|
||||||
|
for i in range(noise_surface_cache_size):
|
||||||
|
|
||||||
|
print(f"caching {i} of {noise_surface_cache_size}")
|
||||||
|
# draw the background
|
||||||
|
for y in range(noise_height):
|
||||||
|
for x in range(noise_width):
|
||||||
|
color = colors[2]
|
||||||
|
if (
|
||||||
|
noise_map[y * noise_scale][x * noise_scale]
|
||||||
|
+ math.sin(i * (3.14 / noise_surface_cache_size))
|
||||||
|
> 0.2
|
||||||
|
):
|
||||||
|
color = colors[1]
|
||||||
|
elif (
|
||||||
|
noise_map[y * noise_scale][x * noise_scale]
|
||||||
|
+ math.sin(i * (3.14 / noise_surface_cache_size))
|
||||||
|
< 0.15
|
||||||
|
):
|
||||||
|
color = colors[0]
|
||||||
|
noise_surface.set_at((x, y), color)
|
||||||
|
# cache the noise surface
|
||||||
|
|
||||||
|
noise_surface_scaled = pygame.transform.scale(
|
||||||
|
noise_surface, (screen_width, screen_height)
|
||||||
|
)
|
||||||
|
# noise_surface_scaled_pil = Image.frombytes(
|
||||||
|
# "RGB",
|
||||||
|
# (screen_width, screen_height),
|
||||||
|
# pygame.image.tostring(noise_surface_scaled, "RGB", False),
|
||||||
|
# )
|
||||||
|
|
||||||
|
# noise_surface_scaled_pil = noise_surface_scaled_pil.filter(
|
||||||
|
# ImageFilter.GaussianBlur(radius=20)
|
||||||
|
# )
|
||||||
|
# noise_surface_scaled = pygame.image.fromstring(
|
||||||
|
# noise_surface_scaled_pil.tobytes(), (screen_width, screen_height), "RGB"
|
||||||
|
# )
|
||||||
|
noise_surface_cache.append(noise_surface_scaled)
|
||||||
|
|
||||||
|
noise_surface_cache.extend([n for n in noise_surface_cache[::-1]])
|
||||||
|
# main loop
|
||||||
|
running = True
|
||||||
|
print("running")
|
||||||
|
while running:
|
||||||
|
# keep loop running at the right speed
|
||||||
|
clock.tick(60)
|
||||||
|
# process events
|
||||||
|
for event in pygame.event.get():
|
||||||
|
if event.type == pygame.QUIT:
|
||||||
|
running = False
|
||||||
|
# increment the frame
|
||||||
|
frame += 0.2
|
||||||
|
if frame > noise_surface_cache_size - 1:
|
||||||
|
frame = 0
|
||||||
|
# draw the noise surface onto the screen
|
||||||
|
screen.blit(noise_surface_cache[int(frame)], (0, 0))
|
||||||
|
|
||||||
|
# display the fps on the screen
|
||||||
|
pygame.display.set_caption(str(clock.get_fps()))
|
||||||
|
# update the display
|
||||||
|
pygame.display.flip()
|
||||||
|
|
||||||
|
pygame.quit()
|
||||||
180
camera.py
Normal file
|
|
@ -0,0 +1,180 @@
|
||||||
|
"""Basic showcase on how the transform property on SpaceDebugDrawOptions can
|
||||||
|
be used as a camera to allow panning. Use arrows to move the camera.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__docformat__ = "reStructuredText"
|
||||||
|
|
||||||
|
import random
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import pygame
|
||||||
|
import pymunk.pygame_util
|
||||||
|
from pymunk.vec2d import Vec2d
|
||||||
|
|
||||||
|
random.seed(0)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
pygame.init()
|
||||||
|
screen = pygame.display.set_mode((600, 600))
|
||||||
|
clock = pygame.time.Clock()
|
||||||
|
running = True
|
||||||
|
font = pygame.font.Font(None, 16)
|
||||||
|
text = font.render(
|
||||||
|
"Use Arrows (up, down, left, right) to move the camera, "
|
||||||
|
"a and z to zoom in / out and s and x to rotate.",
|
||||||
|
True,
|
||||||
|
pygame.Color("black"),
|
||||||
|
)
|
||||||
|
|
||||||
|
### Physics stuff
|
||||||
|
space = pymunk.Space()
|
||||||
|
space.gravity = Vec2d(0.0, 900.0)
|
||||||
|
draw_options = pymunk.pygame_util.DrawOptions(screen)
|
||||||
|
|
||||||
|
## Balls
|
||||||
|
balls = []
|
||||||
|
|
||||||
|
body = pymunk.Body()
|
||||||
|
body.position = pymunk.Vec2d(407, 354)
|
||||||
|
s1 = pymunk.Segment(body, Vec2d(-300, -30), Vec2d(0, 0), 1.0)
|
||||||
|
s2 = pymunk.Segment(body, Vec2d(0, 0), Vec2d(0, -100), 1.0)
|
||||||
|
s1.density = 0.1
|
||||||
|
s2.density = 0.1
|
||||||
|
s1.friction = 1
|
||||||
|
s2.friction = 1
|
||||||
|
space.add(body, s1, s2)
|
||||||
|
|
||||||
|
c1 = pymunk.constraints.DampedSpring(
|
||||||
|
space.static_body,
|
||||||
|
body,
|
||||||
|
(427, 200),
|
||||||
|
(0, -100),
|
||||||
|
Vec2d(407, 254).get_distance((427, 200)),
|
||||||
|
2000,
|
||||||
|
100,
|
||||||
|
)
|
||||||
|
|
||||||
|
c2 = pymunk.constraints.DampedSpring(
|
||||||
|
space.static_body,
|
||||||
|
body,
|
||||||
|
(87, 200),
|
||||||
|
(-300, -30),
|
||||||
|
Vec2d(107, 324).get_distance((87, 200)),
|
||||||
|
2000,
|
||||||
|
100,
|
||||||
|
)
|
||||||
|
space.add(c1, c2)
|
||||||
|
|
||||||
|
# extra to show how constraints are drawn when very small / large
|
||||||
|
body = pymunk.Body(1, 100)
|
||||||
|
body.position = 450, 305
|
||||||
|
c3 = pymunk.constraints.DampedSpring(
|
||||||
|
space.static_body, body, (450, 300), (0, 0), 5, 1000, 100
|
||||||
|
)
|
||||||
|
space.add(body, c3)
|
||||||
|
body = pymunk.Body(1, 100)
|
||||||
|
body.position = 500, 2025
|
||||||
|
c3 = pymunk.constraints.DampedSpring(
|
||||||
|
space.static_body, body, (500, 25), (0, 0), 2000, 1000, 100
|
||||||
|
)
|
||||||
|
space.add(body, c3)
|
||||||
|
|
||||||
|
ticks_to_next_ball = 10
|
||||||
|
|
||||||
|
translation = pymunk.Transform()
|
||||||
|
scaling = 1
|
||||||
|
rotation = 0
|
||||||
|
|
||||||
|
while running:
|
||||||
|
for event in pygame.event.get():
|
||||||
|
if (
|
||||||
|
event.type == pygame.QUIT
|
||||||
|
or event.type == pygame.KEYDOWN
|
||||||
|
and event.key == pygame.K_ESCAPE
|
||||||
|
):
|
||||||
|
running = False
|
||||||
|
elif event.type == pygame.KEYDOWN and event.key == pygame.K_p:
|
||||||
|
pygame.image.save(screen, "camera.png")
|
||||||
|
|
||||||
|
keys = pygame.key.get_pressed()
|
||||||
|
left = int(keys[pygame.K_LEFT])
|
||||||
|
up = int(keys[pygame.K_UP])
|
||||||
|
down = int(keys[pygame.K_DOWN])
|
||||||
|
right = int(keys[pygame.K_RIGHT])
|
||||||
|
|
||||||
|
zoom_in = int(keys[pygame.K_a])
|
||||||
|
zoom_out = int(keys[pygame.K_z])
|
||||||
|
rotate_left = int(keys[pygame.K_s])
|
||||||
|
rotate_right = int(keys[pygame.K_x])
|
||||||
|
|
||||||
|
translate_speed = 10
|
||||||
|
translation = translation.translated(
|
||||||
|
translate_speed * left - translate_speed * right,
|
||||||
|
translate_speed * up - translate_speed * down,
|
||||||
|
)
|
||||||
|
|
||||||
|
zoom_speed = 0.1
|
||||||
|
scaling *= 1 + (zoom_speed * zoom_in - zoom_speed * zoom_out)
|
||||||
|
|
||||||
|
rotation_speed = 0.1
|
||||||
|
rotation += rotation_speed * rotate_left - rotation_speed * rotate_right
|
||||||
|
|
||||||
|
# to zoom with center of screen as origin we need to offset with
|
||||||
|
# center of screen, scale, and then offset back
|
||||||
|
draw_options.transform = (
|
||||||
|
pymunk.Transform.translation(300, 300)
|
||||||
|
@ pymunk.Transform.scaling(scaling)
|
||||||
|
@ translation
|
||||||
|
@ pymunk.Transform.rotation(rotation)
|
||||||
|
@ pymunk.Transform.translation(-300, -300)
|
||||||
|
)
|
||||||
|
|
||||||
|
ticks_to_next_ball -= 1
|
||||||
|
if ticks_to_next_ball <= 0:
|
||||||
|
ticks_to_next_ball = 100
|
||||||
|
mass = 10
|
||||||
|
radius = 25
|
||||||
|
inertia = pymunk.moment_for_circle(mass, 0, radius, (0, 0))
|
||||||
|
body = pymunk.Body(mass, inertia)
|
||||||
|
x = random.randint(115, 350)
|
||||||
|
body.position = x, 100
|
||||||
|
if random.random() > 0.5:
|
||||||
|
shape = pymunk.Circle(body, radius)
|
||||||
|
else:
|
||||||
|
shape = pymunk.Poly.create_box(
|
||||||
|
body, size=(radius * 2, radius * 2), radius=2
|
||||||
|
)
|
||||||
|
shape.friction = 1
|
||||||
|
space.add(body, shape)
|
||||||
|
balls.append(shape)
|
||||||
|
|
||||||
|
### Clear screen
|
||||||
|
screen.fill(pygame.Color("white"))
|
||||||
|
|
||||||
|
### Draw stuff
|
||||||
|
space.debug_draw(draw_options)
|
||||||
|
|
||||||
|
balls_to_remove = []
|
||||||
|
for ball in balls:
|
||||||
|
if ball.body.position.y > 500:
|
||||||
|
balls_to_remove.append(ball)
|
||||||
|
|
||||||
|
for ball in balls_to_remove:
|
||||||
|
space.remove(ball, ball.body)
|
||||||
|
balls.remove(ball)
|
||||||
|
|
||||||
|
screen.blit(text, (5, 5))
|
||||||
|
|
||||||
|
### Update physics
|
||||||
|
dt = 1.0 / 60.0
|
||||||
|
space.step(dt)
|
||||||
|
|
||||||
|
### Flip screen
|
||||||
|
pygame.display.flip()
|
||||||
|
clock.tick(50)
|
||||||
|
pygame.display.set_caption("fps: " + str(clock.get_fps()))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
||||||
250
constraints.py
Normal file
|
|
@ -0,0 +1,250 @@
|
||||||
|
"""
|
||||||
|
Pymunk constraints demo. Showcase of all the constraints included in Pymunk.
|
||||||
|
|
||||||
|
Adapted from the Chipmunk Joints demo:
|
||||||
|
https://github.com/slembcke/Chipmunk2D/blob/master/demo/Joints.c
|
||||||
|
"""
|
||||||
|
|
||||||
|
import inspect
|
||||||
|
import math
|
||||||
|
|
||||||
|
import pygame
|
||||||
|
import pymunk.pygame_util
|
||||||
|
from pymunk.vec2d import Vec2d
|
||||||
|
|
||||||
|
pygame.init()
|
||||||
|
screen = pygame.display.set_mode((1200, 600))
|
||||||
|
clock = pygame.time.Clock()
|
||||||
|
font = pygame.font.Font(None, 24)
|
||||||
|
|
||||||
|
|
||||||
|
help_txt = font.render(
|
||||||
|
"Pymunk constraints demo. Use mouse to drag/drop. Hover to see descr.",
|
||||||
|
True,
|
||||||
|
pygame.Color("darkgray"),
|
||||||
|
)
|
||||||
|
|
||||||
|
space = pymunk.Space()
|
||||||
|
space.gravity = (0.0, 900.0)
|
||||||
|
draw_options = pymunk.pygame_util.DrawOptions(screen)
|
||||||
|
|
||||||
|
# containers
|
||||||
|
box_size = 200
|
||||||
|
w = screen.get_width()
|
||||||
|
h = screen.get_height()
|
||||||
|
for i in range(6):
|
||||||
|
sw = pymunk.Segment(space.static_body, (0, i * box_size), (w, i * box_size), 1)
|
||||||
|
sw.friction = 1
|
||||||
|
sw.elasticity = 1
|
||||||
|
sh = pymunk.Segment(
|
||||||
|
space.static_body, (i * box_size, 0), (i * box_size, h - box_size), 1
|
||||||
|
)
|
||||||
|
sh.friction = 1
|
||||||
|
sh.elasticity = 1
|
||||||
|
space.add(sw, sh)
|
||||||
|
|
||||||
|
|
||||||
|
def add_ball(space, pos, box_offset):
|
||||||
|
body = pymunk.Body()
|
||||||
|
body.position = Vec2d(*pos) + box_offset
|
||||||
|
shape = pymunk.Circle(body, 20)
|
||||||
|
shape.mass = 1
|
||||||
|
shape.friction = 0.7
|
||||||
|
space.add(body, shape)
|
||||||
|
return body
|
||||||
|
|
||||||
|
|
||||||
|
def add_bar(space, pos, box_offset):
|
||||||
|
body = pymunk.Body()
|
||||||
|
body.position = Vec2d(*pos) + box_offset
|
||||||
|
shape = pymunk.Segment(body, (0, 40), (0, -40), 6)
|
||||||
|
shape.mass = 2
|
||||||
|
shape.friction = 0.7
|
||||||
|
space.add(body, shape)
|
||||||
|
return body
|
||||||
|
|
||||||
|
|
||||||
|
def add_lever(space, pos, box_offset):
|
||||||
|
body = pymunk.Body()
|
||||||
|
body.position = pos + Vec2d(*box_offset) + (0, -20)
|
||||||
|
shape = pymunk.Segment(body, (0, 20), (0, -20), 5)
|
||||||
|
shape.mass = 1
|
||||||
|
shape.friction = 0.7
|
||||||
|
space.add(body, shape)
|
||||||
|
return body
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
txts = {}
|
||||||
|
|
||||||
|
box_offset = 0, 0
|
||||||
|
b1 = add_ball(space, (50, 60), box_offset)
|
||||||
|
b2 = add_ball(space, (150, 60), box_offset)
|
||||||
|
c: pymunk.Constraint = pymunk.PinJoint(b1, b2, (20, 0), (-20, 0))
|
||||||
|
txts[box_offset] = inspect.getdoc(c)
|
||||||
|
space.add(c)
|
||||||
|
|
||||||
|
box_offset = box_size, 0
|
||||||
|
b1 = add_ball(space, (50, 60), box_offset)
|
||||||
|
b2 = add_ball(space, (150, 60), box_offset)
|
||||||
|
c = pymunk.SlideJoint(b1, b2, (20, 0), (-20, 0), 40, 80)
|
||||||
|
txts[box_offset] = inspect.getdoc(c)
|
||||||
|
space.add(c)
|
||||||
|
|
||||||
|
box_offset = box_size * 2, 0
|
||||||
|
b1 = add_ball(space, (50, 60), box_offset)
|
||||||
|
b2 = add_ball(space, (150, 60), box_offset)
|
||||||
|
c = pymunk.PivotJoint(b1, b2, Vec2d(*box_offset) + (100, 60))
|
||||||
|
txts[box_offset] = inspect.getdoc(c)
|
||||||
|
space.add(c)
|
||||||
|
|
||||||
|
box_offset = box_size * 3, 0
|
||||||
|
b1 = add_ball(space, (50, 60), box_offset)
|
||||||
|
b2 = add_ball(space, (150, 60), box_offset)
|
||||||
|
c = pymunk.GrooveJoint(b1, b2, (50, 50), (50, -50), (-50, 0))
|
||||||
|
txts[box_offset] = inspect.getdoc(c)
|
||||||
|
space.add(c)
|
||||||
|
|
||||||
|
box_offset = box_size * 4, 0
|
||||||
|
b1 = add_ball(space, (50, 60), box_offset)
|
||||||
|
b2 = add_ball(space, (150, 60), box_offset)
|
||||||
|
c = pymunk.DampedSpring(b1, b2, (30, 0), (-30, 0), 20, 5, 0.3)
|
||||||
|
txts[box_offset] = inspect.getdoc(c)
|
||||||
|
space.add(c)
|
||||||
|
|
||||||
|
box_offset = box_size * 5, 0
|
||||||
|
b1 = add_bar(space, (50, 80), box_offset)
|
||||||
|
b2 = add_bar(space, (150, 80), box_offset)
|
||||||
|
# Add some joints to hold the circles in place.
|
||||||
|
space.add(pymunk.PivotJoint(b1, space.static_body, (50, 80) + Vec2d(*box_offset)))
|
||||||
|
space.add(pymunk.PivotJoint(b2, space.static_body, (150, 80) + Vec2d(*box_offset)))
|
||||||
|
c = pymunk.DampedRotarySpring(b1, b2, 0, 3000, 60)
|
||||||
|
txts[box_offset] = inspect.getdoc(c)
|
||||||
|
space.add(c)
|
||||||
|
|
||||||
|
box_offset = 0, box_size
|
||||||
|
b1 = add_lever(space, (50, 100), box_offset)
|
||||||
|
b2 = add_lever(space, (150, 100), box_offset)
|
||||||
|
# Add some joints to hold the circles in place.
|
||||||
|
space.add(pymunk.PivotJoint(b1, space.static_body, (50, 100) + Vec2d(*box_offset)))
|
||||||
|
space.add(pymunk.PivotJoint(b2, space.static_body, (150, 100) + Vec2d(*box_offset)))
|
||||||
|
# Hold their rotation within 90 degrees of each other.
|
||||||
|
c = pymunk.RotaryLimitJoint(b1, b2, math.pi / 2, math.pi / 2)
|
||||||
|
txts[box_offset] = inspect.getdoc(c)
|
||||||
|
space.add(c)
|
||||||
|
|
||||||
|
box_offset = box_size, box_size
|
||||||
|
b1 = add_lever(space, (50, 100), box_offset)
|
||||||
|
b2 = add_lever(space, (150, 100), box_offset)
|
||||||
|
# Add some pin joints to hold the circles in place.
|
||||||
|
space.add(pymunk.PivotJoint(b1, space.static_body, (50, 100) + Vec2d(*box_offset)))
|
||||||
|
space.add(pymunk.PivotJoint(b2, space.static_body, (150, 100) + Vec2d(*box_offset)))
|
||||||
|
# Ratchet every 90 degrees
|
||||||
|
c = pymunk.RatchetJoint(b1, b2, 0, math.pi / 2)
|
||||||
|
txts[box_offset] = inspect.getdoc(c)
|
||||||
|
space.add(c)
|
||||||
|
|
||||||
|
box_offset = box_size * 2, box_size
|
||||||
|
b1 = add_bar(space, (50, 100), box_offset)
|
||||||
|
b2 = add_bar(space, (150, 100), box_offset)
|
||||||
|
# Add some pin joints to hold the circles in place.
|
||||||
|
space.add(pymunk.PivotJoint(b1, space.static_body, (50, 100) + Vec2d(*box_offset)))
|
||||||
|
space.add(pymunk.PivotJoint(b2, space.static_body, (150, 100) + Vec2d(*box_offset)))
|
||||||
|
# Force one to sping 2x as fast as the other
|
||||||
|
c = pymunk.GearJoint(b1, b2, 0, 2)
|
||||||
|
txts[box_offset] = inspect.getdoc(c)
|
||||||
|
space.add(c)
|
||||||
|
|
||||||
|
box_offset = box_size * 3, box_size
|
||||||
|
b1 = add_bar(space, (50, 100), box_offset)
|
||||||
|
b2 = add_bar(space, (150, 100), box_offset)
|
||||||
|
# Add some pin joints to hold the circles in place.
|
||||||
|
space.add(pymunk.PivotJoint(b1, space.static_body, (50, 100) + Vec2d(*box_offset)))
|
||||||
|
space.add(pymunk.PivotJoint(b2, space.static_body, (150, 100) + Vec2d(*box_offset)))
|
||||||
|
# Make them spin at 1/2 revolution per second in relation to each other.
|
||||||
|
c = pymunk.SimpleMotor(b1, b2, math.pi)
|
||||||
|
txts[box_offset] = inspect.getdoc(c)
|
||||||
|
space.add(c)
|
||||||
|
|
||||||
|
# TODO add one or two advanced constraints examples, such as a car or rope
|
||||||
|
|
||||||
|
mouse_joint = None
|
||||||
|
mouse_body = pymunk.Body(body_type=pymunk.Body.KINEMATIC)
|
||||||
|
|
||||||
|
# Build rendered help texts
|
||||||
|
box_texts = {}
|
||||||
|
for k in txts:
|
||||||
|
l = 0
|
||||||
|
box_texts[k] = []
|
||||||
|
# Only take the first 5 lines.
|
||||||
|
for line in txts[k].splitlines()[:5]:
|
||||||
|
txt = font.render(line, True, pygame.Color("black"))
|
||||||
|
box_texts[k].append(txt)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
for event in pygame.event.get():
|
||||||
|
if event.type == pygame.QUIT:
|
||||||
|
exit()
|
||||||
|
elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
|
||||||
|
exit()
|
||||||
|
elif event.type == pygame.MOUSEBUTTONDOWN:
|
||||||
|
if mouse_joint is not None:
|
||||||
|
space.remove(mouse_joint)
|
||||||
|
mouse_joint = None
|
||||||
|
|
||||||
|
p = Vec2d(*event.pos)
|
||||||
|
hit = space.point_query_nearest(p, 5, pymunk.ShapeFilter())
|
||||||
|
if hit is not None and hit.shape.body.body_type == pymunk.Body.DYNAMIC:
|
||||||
|
shape = hit.shape
|
||||||
|
# Use the closest point on the surface if the click is outside
|
||||||
|
# of the shape.
|
||||||
|
if hit.distance > 0:
|
||||||
|
nearest = hit.point
|
||||||
|
else:
|
||||||
|
nearest = p
|
||||||
|
mouse_joint = pymunk.PivotJoint(
|
||||||
|
mouse_body,
|
||||||
|
shape.body,
|
||||||
|
(0, 0),
|
||||||
|
shape.body.world_to_local(nearest),
|
||||||
|
)
|
||||||
|
mouse_joint.max_force = 50000
|
||||||
|
mouse_joint.error_bias = (1 - 0.15) ** 60
|
||||||
|
space.add(mouse_joint)
|
||||||
|
|
||||||
|
elif event.type == pygame.MOUSEBUTTONUP:
|
||||||
|
if mouse_joint is not None:
|
||||||
|
space.remove(mouse_joint)
|
||||||
|
mouse_joint = None
|
||||||
|
|
||||||
|
screen.fill(pygame.Color("white"))
|
||||||
|
|
||||||
|
screen.blit(help_txt, (5, screen.get_height() - 20))
|
||||||
|
|
||||||
|
mouse_pos = pygame.mouse.get_pos()
|
||||||
|
|
||||||
|
# Display help message
|
||||||
|
x = mouse_pos[0] // box_size * box_size
|
||||||
|
y = mouse_pos[1] // box_size * box_size
|
||||||
|
|
||||||
|
if (x, y) in box_texts:
|
||||||
|
txts = box_texts[(x, y)]
|
||||||
|
i = 0
|
||||||
|
for txt in txts:
|
||||||
|
pos = (5, box_size * 2 + 10 + i * 20)
|
||||||
|
screen.blit(txt, pos)
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
mouse_body.position = mouse_pos
|
||||||
|
|
||||||
|
space.step(1.0 / 60)
|
||||||
|
|
||||||
|
space.debug_draw(draw_options)
|
||||||
|
pygame.display.flip()
|
||||||
|
|
||||||
|
clock.tick(60)
|
||||||
|
pygame.display.set_caption(f"fps: {clock.get_fps()}")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
# SPDX-FileCopyrightText: 2023-present Waylon S. Walker <waylon@waylonwalker.com>
|
# SPDX-FileCopyrightText: 2023-present Waylon S. Walker <waylon@waylonwalker.com>
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: MIT
|
# SPDX-License-Identifier: MIT
|
||||||
__version__ = '9.0.0'
|
__version__ = '11.0.0'
|
||||||
|
|
|
||||||
0
creeper_adventure/assets/bee/idle/1.png
Executable file → Normal file
|
Before Width: | Height: | Size: 630 B After Width: | Height: | Size: 630 B |
0
creeper_adventure/assets/creeper/idle/1.png
Executable file → Normal file
|
Before Width: | Height: | Size: 769 B After Width: | Height: | Size: 769 B |
0
creeper_adventure/assets/creeper/idle/2.png
Executable file → Normal file
|
Before Width: | Height: | Size: 769 B After Width: | Height: | Size: 769 B |
0
creeper_adventure/assets/creeper/idle/3.png
Executable file → Normal file
|
Before Width: | Height: | Size: 769 B After Width: | Height: | Size: 769 B |
0
creeper_adventure/assets/creeper/idle/4.png
Executable file → Normal file
|
Before Width: | Height: | Size: 769 B After Width: | Height: | Size: 769 B |
0
creeper_adventure/assets/creeper/idle/5.png
Executable file → Normal file
|
Before Width: | Height: | Size: 776 B After Width: | Height: | Size: 776 B |
0
creeper_adventure/assets/leaf.png
Executable file → Normal file
|
Before Width: | Height: | Size: 599 B After Width: | Height: | Size: 599 B |
0
creeper_adventure/assets/oak_trees/1.png
Executable file → Normal file
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
0
creeper_adventure/assets/oak_trees/2.png
Executable file → Normal file
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
0
creeper_adventure/assets/oak_trees/4.png
Executable file → Normal file
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
0
creeper_adventure/assets/oak_trees/5.png
Executable file → Normal file
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
BIN
creeper_adventure/assets/plank-bottom.png
Normal file
|
After Width: | Height: | Size: 9.6 KiB |
BIN
creeper_adventure/assets/plank-top.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
0
creeper_adventure/assets/spotlight.png
Executable file → Normal file
|
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 2 KiB |
270
creeper_adventure/creeper.py
Executable file → Normal file
|
|
@ -1,16 +1,52 @@
|
||||||
import random
|
|
||||||
from copy import copy
|
from copy import copy
|
||||||
from itertools import cycle, repeat
|
from itertools import cycle, repeat
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
import random
|
||||||
|
from typing import List, Optional
|
||||||
|
|
||||||
import pygame
|
|
||||||
from more_itertools import flatten
|
from more_itertools import flatten
|
||||||
|
from pydantic import BaseModel
|
||||||
|
import pygame
|
||||||
|
|
||||||
from creeper_adventure.game import Game
|
from creeper_adventure.game import Game
|
||||||
|
|
||||||
ASSETS = Path(__file__).parent / "assets"
|
ASSETS = Path(__file__).parent / "assets"
|
||||||
|
|
||||||
|
|
||||||
|
class Button:
|
||||||
|
def __init__(self, game, surf, text, x, y, w, h, on_click=lambda: ...):
|
||||||
|
self.game = game
|
||||||
|
self.surf = surf
|
||||||
|
self.text = text
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
self.w = w
|
||||||
|
self.h = h
|
||||||
|
self.on_click = on_click
|
||||||
|
self.font = pygame.font.SysFont(None, 32)
|
||||||
|
|
||||||
|
def draw(self):
|
||||||
|
pygame.draw.rect(self.surf, (255, 255, 255), (self.x, self.y, self.w, self.h))
|
||||||
|
label = self.font.render(self.text, True, (0, 0, 0))
|
||||||
|
label_rect = label.get_rect()
|
||||||
|
label_rect.center = (self.x + self.w / 2, self.y + self.h / 2)
|
||||||
|
self.surf.blit(label, label_rect)
|
||||||
|
for event in self.game.events:
|
||||||
|
if event.type == pygame.MOUSEBUTTONDOWN:
|
||||||
|
if self.is_clicked(event.pos):
|
||||||
|
self.on_click()
|
||||||
|
# elif quit_button.is_clicked(event.pos):
|
||||||
|
# running = False
|
||||||
|
# if self.is_clicked:
|
||||||
|
# self.on_click()
|
||||||
|
|
||||||
|
def is_clicked(self, pos):
|
||||||
|
if pos[0] > self.x and pos[0] < self.x + self.w:
|
||||||
|
if pos[1] > self.y and pos[1] < self.y + self.h:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
class MouseSprite:
|
class MouseSprite:
|
||||||
def __init__(self, game, surf, hotbar):
|
def __init__(self, game, surf, hotbar):
|
||||||
self.game = game
|
self.game = game
|
||||||
|
|
@ -40,7 +76,7 @@ class MouseSprite:
|
||||||
if self.hotbar.selected.type is None:
|
if self.hotbar.selected.type is None:
|
||||||
pygame.draw.rect(self.surf, (255, 0, 0), self.rect)
|
pygame.draw.rect(self.surf, (255, 0, 0), self.rect)
|
||||||
else:
|
else:
|
||||||
self.img = self.game.get_img(self.hotbar.selected.type)
|
self.img = self.game.get_img(self.hotbar.selected.type).convert()
|
||||||
self.surf.blit(
|
self.surf.blit(
|
||||||
pygame.transform.scale(self.img, (64, 64)),
|
pygame.transform.scale(self.img, (64, 64)),
|
||||||
self.get_nearest_block_pos(),
|
self.get_nearest_block_pos(),
|
||||||
|
|
@ -178,6 +214,7 @@ class HotBarItem:
|
||||||
self.selected = False
|
self.selected = False
|
||||||
self.surf.fill((0, 0, 0))
|
self.surf.fill((0, 0, 0))
|
||||||
self.type = None
|
self.type = None
|
||||||
|
self.font = pygame.font.SysFont(None, self.scale)
|
||||||
|
|
||||||
def draw(self):
|
def draw(self):
|
||||||
self.surf.fill((0, 0, 0, 60))
|
self.surf.fill((0, 0, 0, 60))
|
||||||
|
|
@ -193,9 +230,8 @@ class HotBarItem:
|
||||||
),
|
),
|
||||||
(self.pos * self.scale + self.margin, self.margin),
|
(self.pos * self.scale + self.margin, self.margin),
|
||||||
)
|
)
|
||||||
font = pygame.font.SysFont(None, self.scale)
|
|
||||||
qty = str(self.game.inventory[self.type])
|
qty = str(self.game.inventory[self.type])
|
||||||
img = font.render(qty, True, (255, 255, 255))
|
img = self.font.render(qty, True, (255, 255, 255))
|
||||||
self.ui.blit(
|
self.ui.blit(
|
||||||
pygame.transform.scale(img, (self.scale * 0.6, self.scale * 0.6)),
|
pygame.transform.scale(img, (self.scale * 0.6, self.scale * 0.6)),
|
||||||
(self.pos * self.scale + self.margin, self.margin),
|
(self.pos * self.scale + self.margin, self.margin),
|
||||||
|
|
@ -222,10 +258,12 @@ class Menu:
|
||||||
self.scale = scale
|
self.scale = scale
|
||||||
self.margin = margin
|
self.margin = margin
|
||||||
self.alpha = alpha
|
self.alpha = alpha
|
||||||
|
self.font = pygame.font.SysFont(None, 20)
|
||||||
|
self.surf = pygame.Surface(self.game.screen.get_size()).convert_alpha()
|
||||||
|
|
||||||
def draw(self):
|
def draw(self):
|
||||||
if self.is_open:
|
if self.is_open:
|
||||||
self.surf = pygame.Surface(self.game.screen.get_size()).convert_alpha()
|
# self.surf = pygame.Surface(self.game.screen.get_size()).convert_alpha()
|
||||||
self.surf.fill((0, 0, 0, self.alpha))
|
self.surf.fill((0, 0, 0, self.alpha))
|
||||||
font = pygame.font.SysFont(None, self.scale)
|
font = pygame.font.SysFont(None, self.scale)
|
||||||
img = font.render(self.title, True, (255, 255, 255))
|
img = font.render(self.title, True, (255, 255, 255))
|
||||||
|
|
@ -245,7 +283,6 @@ class Menu:
|
||||||
class DebugMenu(Menu):
|
class DebugMenu(Menu):
|
||||||
def __init__(self, game):
|
def __init__(self, game):
|
||||||
super().__init__(title="Debug Menu", game=game, alpha=0)
|
super().__init__(title="Debug Menu", game=game, alpha=0)
|
||||||
self.font = pygame.font.SysFont(None, 20)
|
|
||||||
|
|
||||||
def _draw(self):
|
def _draw(self):
|
||||||
self.surf.blit(
|
self.surf.blit(
|
||||||
|
|
@ -284,6 +321,46 @@ class DebugMenu(Menu):
|
||||||
),
|
),
|
||||||
(10, 95),
|
(10, 95),
|
||||||
)
|
)
|
||||||
|
self.surf.blit(
|
||||||
|
self.font.render(
|
||||||
|
f"fullscreen: {pygame.FULLSCREEN}",
|
||||||
|
True,
|
||||||
|
(255, 255, 255),
|
||||||
|
),
|
||||||
|
(10, 110),
|
||||||
|
)
|
||||||
|
self.surf.blit(
|
||||||
|
self.font.render(
|
||||||
|
f"elapsed: {self.game.elapsed}",
|
||||||
|
True,
|
||||||
|
(255, 255, 255),
|
||||||
|
),
|
||||||
|
(10, 125),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class MainMenu(Menu):
|
||||||
|
def __init__(self, game, title):
|
||||||
|
super().__init__(game=game, title=title)
|
||||||
|
self.set_button_text()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def start_button(self):
|
||||||
|
w = 200
|
||||||
|
h = 50
|
||||||
|
x = self.game.screen.get_size()[0] / 2 - w / 2
|
||||||
|
y = 300
|
||||||
|
return Button(self.game, self.surf, self.button_text, x, y, w, h, self.toggle)
|
||||||
|
|
||||||
|
def set_button_text(self):
|
||||||
|
self.button_text = "Start Game" if self.game.frames < 100 else "Continue"
|
||||||
|
|
||||||
|
def toggle(self):
|
||||||
|
self.set_button_text()
|
||||||
|
self.is_open = not self.is_open
|
||||||
|
|
||||||
|
def _draw(self):
|
||||||
|
self.start_button.draw()
|
||||||
|
|
||||||
|
|
||||||
class LightSource:
|
class LightSource:
|
||||||
|
|
@ -304,10 +381,11 @@ class Leaf:
|
||||||
self.sx, self.sy = center
|
self.sx, self.sy = center
|
||||||
self.img = pygame.transform.scale(
|
self.img = pygame.transform.scale(
|
||||||
self.game.get_img("leaf"), (4, 4)
|
self.game.get_img("leaf"), (4, 4)
|
||||||
).convert_alpha()
|
) # .convert_alpha()
|
||||||
self.lifespan = lifespan
|
self.lifespan = lifespan
|
||||||
self.r = random.randint(0, 360)
|
self.r = random.randint(0, 360)
|
||||||
self.x, self.y = [int(i) + random.randint(-8, 8) for i in self.center]
|
self.x, self.y = [int(i) + random.randint(-8, 8) for i in self.center]
|
||||||
|
self.speed = 3
|
||||||
self.restart()
|
self.restart()
|
||||||
|
|
||||||
def restart(self):
|
def restart(self):
|
||||||
|
|
@ -323,13 +401,13 @@ class Leaf:
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.y < self.sy + 40:
|
if self.y < self.sy + 40:
|
||||||
self.y += random.randint(0, 5) / 4
|
self.y += random.randint(0, 5) / 4 * self.speed * self.game.elapsed
|
||||||
self.x += random.randint(-15, 5) / 10
|
self.x += random.randint(-15, 5) / 10 * self.speed * self.game.elapsed
|
||||||
self.r += random.randint(-10, 10)
|
self.r += random.randint(-10, 10) * self.speed / 3 * self.game.elapsed
|
||||||
elif self.y < self.sy + 45:
|
elif self.y < self.sy + 45:
|
||||||
self.y += random.randint(-2, 5) / 10
|
self.y += random.randint(-2, 5) / 10 * self.speed * self.game.elapsed
|
||||||
self.x += random.randint(-18, 2) / 10
|
self.x += random.randint(-18, 2) / 10 * self.speed * self.game.elapsed
|
||||||
self.r += random.randint(-10, 25)
|
self.r += random.randint(-10, 25) * self.speed * self.game.elapsed
|
||||||
else:
|
else:
|
||||||
self.restart()
|
self.restart()
|
||||||
if self.x > self.sx + 100:
|
if self.x > self.sx + 100:
|
||||||
|
|
@ -357,16 +435,19 @@ class Bee:
|
||||||
class Creeper(Game):
|
class Creeper(Game):
|
||||||
def __init__(self, debug=False):
|
def __init__(self, debug=False):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.inventory = {}
|
self.inventory = {"plank-bottom": 1, "plank-top": 1}
|
||||||
|
self._imgs = {}
|
||||||
|
self.blocks = {}
|
||||||
self.camera = (0, 0)
|
self.camera = (0, 0)
|
||||||
self.day_len = 1000 * 60
|
self.day_len = 1000 * 60
|
||||||
self.background = pygame.Surface(self.screen.get_size())
|
self.background = pygame.Surface(self.screen.get_size())
|
||||||
self.foreground = pygame.Surface(self.screen.get_size())
|
self.foreground = pygame.Surface(self.screen.get_size())
|
||||||
self.build = pygame.Surface(self.screen.get_size())
|
self.build = pygame.Surface(self.screen.get_size())
|
||||||
self.darkness = pygame.Surface(self.screen.get_size()).convert_alpha()
|
# self.darkness = pygame.Surface(self.screen.get_size())
|
||||||
self.axe_sound = pygame.mixer.Sound(ASSETS / "sounds/axe.mp3")
|
self.axe_sound = pygame.mixer.Sound(ASSETS / "sounds/axe.mp3")
|
||||||
self.walking_sound = pygame.mixer.Sound(ASSETS / "sounds/walking.mp3")
|
self.walking_sound = pygame.mixer.Sound(ASSETS / "sounds/walking.mp3")
|
||||||
self.walking_sound_is_playing = False
|
self.walking_sound_is_playing = False
|
||||||
|
self.speed = 5
|
||||||
|
|
||||||
self.background.fill((0, 255, 247))
|
self.background.fill((0, 255, 247))
|
||||||
self.x, self.y = [i / 2 for i in self.screen.get_size()]
|
self.x, self.y = [i / 2 for i in self.screen.get_size()]
|
||||||
|
|
@ -395,20 +476,21 @@ class Creeper(Game):
|
||||||
self.trees = []
|
self.trees = []
|
||||||
|
|
||||||
x_range = [
|
x_range = [
|
||||||
self.screen.get_size()[0] * 0.1,
|
0,
|
||||||
self.screen.get_size()[0] * 0.9,
|
self.screen.get_size()[0],
|
||||||
]
|
]
|
||||||
y_range = [
|
y_range = [
|
||||||
self.screen.get_size()[1] * 0.35,
|
self.screen.get_size()[1] * 0.35,
|
||||||
self.screen.get_size()[1] * 0.5,
|
self.screen.get_size()[1] * 0.5,
|
||||||
]
|
]
|
||||||
for i in range(10):
|
for i in range(30):
|
||||||
x = random.randint(*x_range)
|
x = random.randint(*x_range)
|
||||||
y = random.randint(*y_range)
|
y = random.randint(*y_range)
|
||||||
|
|
||||||
scale = random.randint(42, 86)
|
scale = random.randint(42, 86)
|
||||||
self.trees.append(
|
self.trees.append(
|
||||||
TreeSprite(
|
TreeSprite(
|
||||||
|
game=self,
|
||||||
tree=random.choice(self.tree_imgs),
|
tree=random.choice(self.tree_imgs),
|
||||||
x=x,
|
x=x,
|
||||||
y=y,
|
y=y,
|
||||||
|
|
@ -433,10 +515,13 @@ class Creeper(Game):
|
||||||
self.controller_debug_open_debounce = 1
|
self.controller_debug_open_debounce = 1
|
||||||
self.controller_main_open_debounce = 1
|
self.controller_main_open_debounce = 1
|
||||||
|
|
||||||
|
self.debounce_walk_img = 0
|
||||||
|
|
||||||
self.inventory_menu = Menu(self, title="inventory")
|
self.inventory_menu = Menu(self, title="inventory")
|
||||||
self.debug_menu = DebugMenu(self)
|
self.debug_menu = DebugMenu(self)
|
||||||
self.debug_menu.is_open = debug
|
self.debug_menu.is_open = debug
|
||||||
self.main_menu = Menu(self, title="main menu")
|
self.main_menu = MainMenu(self, title="main menu")
|
||||||
|
self.main_menu.is_open = True
|
||||||
|
|
||||||
def get_img(self, img):
|
def get_img(self, img):
|
||||||
try:
|
try:
|
||||||
|
|
@ -461,8 +546,12 @@ class Creeper(Game):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def place_block(self):
|
def place_block(self):
|
||||||
if self.hotbar.selected.type is None:
|
# if self.hotbar.selected.type is None:
|
||||||
return False
|
# return False
|
||||||
|
self.blocks[str(self.mouse_box.get_nearest_block_pos())] = Block(
|
||||||
|
self.hotbar.selected.type, self.mouse_box.get_nearest_block_pos()
|
||||||
|
)
|
||||||
|
print(self.blocks)
|
||||||
|
|
||||||
def process_deaths(self):
|
def process_deaths(self):
|
||||||
for i, tree in enumerate(copy(self.trees)):
|
for i, tree in enumerate(copy(self.trees)):
|
||||||
|
|
@ -478,13 +567,13 @@ class Creeper(Game):
|
||||||
def normal_keys(self):
|
def normal_keys(self):
|
||||||
keys = self.keys
|
keys = self.keys
|
||||||
if keys[pygame.K_a] or keys[pygame.K_LEFT]:
|
if keys[pygame.K_a] or keys[pygame.K_LEFT]:
|
||||||
self.x -= 10
|
self.x -= 10 * self.speed * self.elapsed
|
||||||
if keys[pygame.K_d] or keys[pygame.K_RIGHT]:
|
if keys[pygame.K_d] or keys[pygame.K_RIGHT]:
|
||||||
self.x += 10
|
self.x += 10 * self.speed * self.elapsed
|
||||||
if keys[pygame.K_w] or keys[pygame.K_UP]:
|
if keys[pygame.K_w] or keys[pygame.K_UP]:
|
||||||
self.y -= 10
|
self.y -= 10 * self.speed * self.elapsed
|
||||||
if keys[pygame.K_s] or keys[pygame.K_DOWN]:
|
if keys[pygame.K_s] or keys[pygame.K_DOWN]:
|
||||||
self.y += 10
|
self.y += 10 * self.speed * self.elapsed
|
||||||
if keys[pygame.K_k]:
|
if keys[pygame.K_k]:
|
||||||
self.hotbar.next(1)
|
self.hotbar.next(1)
|
||||||
if keys[pygame.K_j]:
|
if keys[pygame.K_j]:
|
||||||
|
|
@ -509,7 +598,6 @@ class Creeper(Game):
|
||||||
|
|
||||||
if not self.joysticks:
|
if not self.joysticks:
|
||||||
if (keys[pygame.K_ESCAPE]) and self.main_open_debounce:
|
if (keys[pygame.K_ESCAPE]) and self.main_open_debounce:
|
||||||
print("opens")
|
|
||||||
self.main_menu.is_open = not self.main_menu.is_open
|
self.main_menu.is_open = not self.main_menu.is_open
|
||||||
self.main_open_debounce = 0
|
self.main_open_debounce = 0
|
||||||
elif not keys[pygame.K_ESCAPE]:
|
elif not keys[pygame.K_ESCAPE]:
|
||||||
|
|
@ -522,60 +610,84 @@ class Creeper(Game):
|
||||||
self.inventory_open_debounce = 1
|
self.inventory_open_debounce = 1
|
||||||
|
|
||||||
for joystick in self.joysticks.values():
|
for joystick in self.joysticks.values():
|
||||||
|
if joystick.get_axis(5) > 0:
|
||||||
|
if self.attack():
|
||||||
|
joystick.rumble(0.1, 0.0, 100)
|
||||||
|
|
||||||
if joystick.get_button(4) and self.hotbar_back_debounce:
|
if joystick.get_button(4) and self.controller_hotbar_back_debounce:
|
||||||
print(self.hotbar_back_debounce)
|
print(self.controller_hotbar_back_debounce)
|
||||||
self.hotbar.next(-1)
|
self.hotbar.next(-1)
|
||||||
self.hotbar_back_debounce = 0
|
self.controller_hotbar_back_debounce = 0
|
||||||
print(self.hotbar_back_debounce)
|
print(self.hotbar_back_debounce)
|
||||||
if not joystick.get_button(4):
|
if not joystick.get_button(4):
|
||||||
print("resetting")
|
self.controller_hotbar_back_debounce = 1
|
||||||
self.hotbar_back_debounce = 1
|
|
||||||
|
|
||||||
if joystick.get_button(5) and self.hotbar_forward_debounce:
|
if joystick.get_button(5) and self.controller_hotbar_forward_debounce:
|
||||||
self.hotbar.next(1)
|
self.hotbar.next(1)
|
||||||
self.hotbar_forward_debounce = 0
|
self.controller_hotbar_forward_debounce = 0
|
||||||
elif not joystick.get_button(5):
|
elif not joystick.get_button(5):
|
||||||
self.hotbar_forward_debounce = 1
|
self.controller_hotbar_forward_debounce = 1
|
||||||
|
|
||||||
if (
|
if (
|
||||||
keys[pygame.K_e] or joystick.get_button(2)
|
keys[pygame.K_e] or joystick.get_button(2)
|
||||||
) and self.inventory_open_debounce:
|
) and self.controller_inventory_open_debounce:
|
||||||
self.inventory_menu.is_open = not self.inventory_menu.is_open
|
self.inventory_menu.is_open = not self.inventory_menu.is_open
|
||||||
self.inventory_open_debounce = 0
|
self.controller_inventory_open_debounce = 0
|
||||||
elif not (keys[pygame.K_e] or joystick.get_button(2)):
|
elif not keys[pygame.K_e] and not joystick.get_button(2):
|
||||||
self.inventory_open_debounce = 1
|
self.controller_inventory_open_debounce = 1
|
||||||
|
|
||||||
if (
|
if (
|
||||||
keys[pygame.K_ESCAPE] or joystick.get_button(9)
|
keys[pygame.K_ESCAPE] or joystick.get_button(9)
|
||||||
) and self.main_open_debounce:
|
) and self.controller_main_open_debounce:
|
||||||
self.main_menu.is_open = not self.main_menu.is_open
|
self.main_menu.is_open = not self.main_menu.is_open
|
||||||
self.main_open_debounce = 0
|
self.controller_main_open_debounce = 0
|
||||||
elif not (keys[pygame.K_ESCAPE] or joystick.get_button(9)):
|
elif not (keys[pygame.K_ESCAPE] or joystick.get_button(9)):
|
||||||
self.main_open_debounce = 1
|
self.controller_main_open_debounce = 1
|
||||||
|
|
||||||
if keys[pygame.K_F3] and self.debug_open_debounce:
|
if keys[pygame.K_F3] and self.controller_debug_open_debounce:
|
||||||
self.debug_menu.is_open = not self.debug_menu.is_open
|
self.debug_menu.is_open = not self.debug_menu.is_open
|
||||||
self.debug_open_debounce = 0
|
self.controller_debug_open_debounce = 0
|
||||||
elif not keys[pygame.K_F3]:
|
elif not keys[pygame.K_F3]:
|
||||||
self.debug_open_debounce = 1
|
self.controller_debug_open_debounce = 1
|
||||||
|
|
||||||
hats = joystick.get_numhats()
|
hats = joystick.get_numhats()
|
||||||
for i in range(hats):
|
for i in range(hats):
|
||||||
hat = joystick.get_hat(i)
|
hat = joystick.get_hat(i)
|
||||||
if hat[0] == 1:
|
if hat[0] == 1:
|
||||||
self.x += 10
|
self.x += 10 * self.speed * self.elapsed
|
||||||
if hat[0] == -1:
|
if hat[0] == -1:
|
||||||
self.x -= 10
|
self.x -= 10 * self.speed * self.elapsed
|
||||||
if hat[1] == -1:
|
if hat[1] == -1:
|
||||||
self.y += 10
|
self.y += 10 * self.speed * self.elapsed
|
||||||
if hat[1] == 1:
|
if hat[1] == 1:
|
||||||
self.y -= 10
|
self.y -= 10 * self.speed * self.elapsed
|
||||||
|
|
||||||
if abs(joystick.get_axis(0)) > 0.2:
|
if abs(joystick.get_axis(0)) > 0.2:
|
||||||
self.x += joystick.get_axis(0) * 10
|
self.x += joystick.get_axis(0) * 10 * self.speed * self.elapsed
|
||||||
if abs(joystick.get_axis(1)) > 0.2:
|
if abs(joystick.get_axis(1)) > 0.2:
|
||||||
self.y += joystick.get_axis(1) * 10
|
self.y += joystick.get_axis(1) * 10 * self.speed * self.elapsed
|
||||||
|
|
||||||
|
if abs(joystick.get_axis(3)) > 0.2 and abs(joystick.get_axis(4)) > 0.2:
|
||||||
|
pygame.mouse.set_pos(
|
||||||
|
(
|
||||||
|
pygame.mouse.get_pos()[0] + joystick.get_axis(3) * 32,
|
||||||
|
pygame.mouse.get_pos()[1] + joystick.get_axis(4) * 32,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
elif abs(joystick.get_axis(3)) > 0.2:
|
||||||
|
pygame.mouse.set_pos(
|
||||||
|
(
|
||||||
|
pygame.mouse.get_pos()[0] + joystick.get_axis(3) * 32,
|
||||||
|
pygame.mouse.get_pos()[1],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
elif abs(joystick.get_axis(4)) > 0.2:
|
||||||
|
pygame.mouse.set_pos(
|
||||||
|
(
|
||||||
|
pygame.mouse.get_pos()[0],
|
||||||
|
pygame.mouse.get_pos()[1] + joystick.get_axis(4) * 32,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
def inventory_keys(self):
|
def inventory_keys(self):
|
||||||
keys = self.keys
|
keys = self.keys
|
||||||
|
|
@ -589,11 +701,11 @@ class Creeper(Game):
|
||||||
for joystick in self.joysticks.values():
|
for joystick in self.joysticks.values():
|
||||||
if (
|
if (
|
||||||
keys[pygame.K_e] or joystick.get_button(2)
|
keys[pygame.K_e] or joystick.get_button(2)
|
||||||
) and self.inventory_open_debounce:
|
) and self.controller_inventory_open_debounce:
|
||||||
self.inventory_menu.is_open = not self.inventory_menu.is_open
|
self.inventory_menu.is_open = not self.inventory_menu.is_open
|
||||||
self.inventory_open_debounce = 0
|
self.controller_inventory_open_debounce = 0
|
||||||
elif not (keys[pygame.K_e] or joystick.get_button(2)):
|
elif not keys[pygame.K_e] and not joystick.get_button(2):
|
||||||
self.inventory_open_debounce = 1
|
self.controller_inventory_open_debounce = 1
|
||||||
|
|
||||||
def main_keys(self):
|
def main_keys(self):
|
||||||
keys = self.keys
|
keys = self.keys
|
||||||
|
|
@ -609,11 +721,11 @@ class Creeper(Game):
|
||||||
for joystick in self.joysticks.values():
|
for joystick in self.joysticks.values():
|
||||||
if (
|
if (
|
||||||
keys[pygame.K_ESCAPE] or joystick.get_button(9)
|
keys[pygame.K_ESCAPE] or joystick.get_button(9)
|
||||||
) and self.main_open_debounce:
|
) and self.controller_main_open_debounce:
|
||||||
self.main_menu.is_open = not self.main_menu.is_open
|
self.main_menu.is_open = not self.main_menu.is_open
|
||||||
self.main_open_debounce = 0
|
self.controller_main_open_debounce = 0
|
||||||
elif not (keys[pygame.K_ESCAPE] or joystick.get_button(9)):
|
elif not (keys[pygame.K_ESCAPE] or joystick.get_button(9)):
|
||||||
self.main_open_debounce = 1
|
self.controller_main_open_debounce = 1
|
||||||
|
|
||||||
def make_sound(self):
|
def make_sound(self):
|
||||||
if not hasattr(self, "last_x"):
|
if not hasattr(self, "last_x"):
|
||||||
|
|
@ -631,15 +743,22 @@ class Creeper(Game):
|
||||||
) and not self.walking_sound_is_playing:
|
) and not self.walking_sound_is_playing:
|
||||||
self.walking_sound.play()
|
self.walking_sound.play()
|
||||||
self.walking_sound_is_playing = True
|
self.walking_sound_is_playing = True
|
||||||
if self.last_x != self.x or self.last_y != self.y:
|
if (
|
||||||
|
self.last_x != self.x or self.last_y != self.y
|
||||||
|
) and self.debounce_walk_img < 0:
|
||||||
self.creeper = next(self.creepers)
|
self.creeper = next(self.creepers)
|
||||||
|
self.debounce_walk_img = 0.15
|
||||||
self.last_x = self.x
|
self.last_x = self.x
|
||||||
self.last_y = self.y
|
self.last_y = self.y
|
||||||
|
|
||||||
def game(self):
|
def game(self):
|
||||||
# self.camera = (self.camera[0] + 1, self.camera[1])
|
# self.camera = (self.camera[0] + 1, self.camera[1])
|
||||||
|
|
||||||
|
self.debounce_walk_img -= self.elapsed
|
||||||
self.screen.blit(self.background, self.camera)
|
self.screen.blit(self.background, self.camera)
|
||||||
|
for block in self.blocks.values():
|
||||||
|
self.screen.blit(block.img, block.pos)
|
||||||
|
|
||||||
self.background.fill((0, 255, 247))
|
self.background.fill((0, 255, 247))
|
||||||
self.process_deaths()
|
self.process_deaths()
|
||||||
for tree in self.trees:
|
for tree in self.trees:
|
||||||
|
|
@ -659,20 +778,20 @@ class Creeper(Game):
|
||||||
light_level = pygame.time.get_ticks() % self.day_len
|
light_level = pygame.time.get_ticks() % self.day_len
|
||||||
light_level = abs(light_level * (255 * 2 / self.day_len) - 255)
|
light_level = abs(light_level * (255 * 2 / self.day_len) - 255)
|
||||||
|
|
||||||
self.darkness.fill((light_level, light_level, light_level))
|
# self.darkness.fill((light_level, light_level, light_level))
|
||||||
if self.light_power < 500:
|
# if self.light_power < 500:
|
||||||
self.light_power = min(self.light_power**1.1, 500)
|
# self.light_power = min(self.light_power**1.1, 500)
|
||||||
self.darkness.blit(
|
# self.darkness.blit(
|
||||||
pygame.transform.smoothscale(
|
# pygame.transform.smoothscale(
|
||||||
self.spot, [self.light_power, self.light_power]
|
# self.spot, [self.light_power, self.light_power]
|
||||||
),
|
# ),
|
||||||
(self.x - self.light_power / 2, self.y - self.light_power / 2),
|
# (self.x - self.light_power / 2, self.y - self.light_power / 2),
|
||||||
)
|
# )
|
||||||
self.screen.blit(
|
# self.screen.blit(
|
||||||
self.darkness,
|
# pygame.transform.scale(self.darkness, self.screen.get_size()).convert(),
|
||||||
(0, 0),
|
# (0, 0),
|
||||||
special_flags=pygame.BLEND_RGBA_MULT,
|
# special_flags=pygame.BLEND_MULT,
|
||||||
)
|
# )
|
||||||
|
|
||||||
self.hotbar.draw()
|
self.hotbar.draw()
|
||||||
self.debug_menu.draw()
|
self.debug_menu.draw()
|
||||||
|
|
@ -681,8 +800,6 @@ class Creeper(Game):
|
||||||
|
|
||||||
self.mouse_box = MouseSprite(self, self.background, hotbar=self.hotbar)
|
self.mouse_box = MouseSprite(self, self.background, hotbar=self.hotbar)
|
||||||
|
|
||||||
self.mouse_box.draw()
|
|
||||||
|
|
||||||
self.make_sound()
|
self.make_sound()
|
||||||
|
|
||||||
if self.inventory_menu.is_open:
|
if self.inventory_menu.is_open:
|
||||||
|
|
@ -691,6 +808,7 @@ class Creeper(Game):
|
||||||
self.main_keys()
|
self.main_keys()
|
||||||
else:
|
else:
|
||||||
self.normal_keys()
|
self.normal_keys()
|
||||||
|
self.mouse_box.draw()
|
||||||
|
|
||||||
|
|
||||||
def main(debug=False):
|
def main(debug=False):
|
||||||
|
|
|
||||||
13
creeper_adventure/game.py
Executable file → Normal file
|
|
@ -4,17 +4,22 @@ import pygame
|
||||||
class Game:
|
class Game:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pygame.init()
|
pygame.init()
|
||||||
|
# pygame.mouse.set_visible(False)
|
||||||
pygame.mixer.init()
|
pygame.mixer.init()
|
||||||
pygame.display.set_caption(__file__)
|
pygame.display.set_caption(__file__)
|
||||||
|
|
||||||
self.screen_size = (854, 480)
|
self.screen_size = (854, 480)
|
||||||
self.screen_size = (1280, 800)
|
self.screen_size = (1280, 800)
|
||||||
self.screen_size = (1920, 1080)
|
self.screen_size = (1920, 1080)
|
||||||
self.screen = pygame.display.set_mode(self.screen_size)
|
# pygame.display.set_mode(resolution, flags, bpp)
|
||||||
|
flags = pygame.DOUBLEBUF
|
||||||
|
self.screen = pygame.display.set_mode(self.screen_size, flags)
|
||||||
self.clock = pygame.time.Clock()
|
self.clock = pygame.time.Clock()
|
||||||
|
|
||||||
self.running = True
|
self.running = True
|
||||||
self.surfs = []
|
self.surfs = []
|
||||||
|
self.elapsed = 0
|
||||||
|
self.frames = 0
|
||||||
|
|
||||||
def should_quit(self):
|
def should_quit(self):
|
||||||
for event in self.events:
|
for event in self.events:
|
||||||
|
|
@ -25,7 +30,8 @@ class Game:
|
||||||
...
|
...
|
||||||
|
|
||||||
def reset_screen(self):
|
def reset_screen(self):
|
||||||
self.screen.fill((0, 0, 0))
|
...
|
||||||
|
# self.screen.fill((0, 0, 0))
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
while self.running:
|
while self.running:
|
||||||
|
|
@ -37,7 +43,8 @@ class Game:
|
||||||
for surf in self.surfs:
|
for surf in self.surfs:
|
||||||
pygame.blit(surf)
|
pygame.blit(surf)
|
||||||
pygame.display.update()
|
pygame.display.update()
|
||||||
self.clock.tick(30)
|
self.elapsed = self.clock.tick(60) / 100
|
||||||
|
self.frames += 1
|
||||||
pygame.quit()
|
pygame.quit()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
63
forest.py
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
import math
|
||||||
|
|
||||||
|
from noise import pnoise2
|
||||||
|
import pygame
|
||||||
|
|
||||||
|
# Initialize pygame
|
||||||
|
pygame.init()
|
||||||
|
|
||||||
|
base = 0
|
||||||
|
persistence = 0.4
|
||||||
|
lacunarity = 2.0
|
||||||
|
more_x = 0
|
||||||
|
# Set up the drawing window
|
||||||
|
screen = pygame.display.set_mode([800, 600])
|
||||||
|
|
||||||
|
|
||||||
|
def S():
|
||||||
|
i = 0
|
||||||
|
while True:
|
||||||
|
i += 0.1
|
||||||
|
yield math.sin(i)
|
||||||
|
|
||||||
|
|
||||||
|
s = S()
|
||||||
|
|
||||||
|
# Run until the user asks to quit
|
||||||
|
running = True
|
||||||
|
while running:
|
||||||
|
|
||||||
|
# Did the user click the window close button?
|
||||||
|
for event in pygame.event.get():
|
||||||
|
if event.type == pygame.QUIT:
|
||||||
|
running = False
|
||||||
|
|
||||||
|
# Fill the background with white
|
||||||
|
screen.fill((255, 255, 255))
|
||||||
|
|
||||||
|
m = next(s)
|
||||||
|
# Generate Perlin noise
|
||||||
|
for x in range(800):
|
||||||
|
for y in range(600):
|
||||||
|
noise = pnoise2(
|
||||||
|
x / 10,
|
||||||
|
y / 10,
|
||||||
|
octaves=4,
|
||||||
|
persistence=persistence + m / 10,
|
||||||
|
lacunarity=lacunarity,
|
||||||
|
repeatx=1024,
|
||||||
|
repeaty=1024,
|
||||||
|
base=base,
|
||||||
|
)
|
||||||
|
if noise > 0.2:
|
||||||
|
pygame.draw.rect(screen, (0, 255, 0), (x, y, 1, 1))
|
||||||
|
elif noise > 0:
|
||||||
|
pygame.draw.rect(screen, (0, 128, 0), (x, y, 1, 1))
|
||||||
|
else:
|
||||||
|
pygame.draw.rect(screen, (0, 64, 0), (x, y, 1, 1))
|
||||||
|
|
||||||
|
# Flip the display
|
||||||
|
pygame.display.flip()
|
||||||
|
|
||||||
|
# Done! Time to quit.
|
||||||
|
pygame.quit()
|
||||||
85
gpt-menu.py
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
import pygame
|
||||||
|
|
||||||
|
# Initialize Pygame
|
||||||
|
pygame.init()
|
||||||
|
|
||||||
|
EVENTS = []
|
||||||
|
# Set screen size
|
||||||
|
screen = pygame.display.set_mode((800, 600))
|
||||||
|
|
||||||
|
# Set title
|
||||||
|
pygame.display.set_caption("My RPG Game")
|
||||||
|
|
||||||
|
# Load font
|
||||||
|
font = pygame.font.Font(None, 30)
|
||||||
|
|
||||||
|
# Define button class
|
||||||
|
class Button:
|
||||||
|
def __init__(self, text, x, y, w, h, on_click=lambda: ...):
|
||||||
|
self.text = text
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
self.w = w
|
||||||
|
self.h = h
|
||||||
|
self.on_click = on_click
|
||||||
|
|
||||||
|
def draw(self, surface):
|
||||||
|
pygame.draw.rect(surface, (255, 255, 255), (self.x, self.y, self.w, self.h))
|
||||||
|
label = font.render(self.text, True, (0, 0, 0))
|
||||||
|
label_rect = label.get_rect()
|
||||||
|
label_rect.center = (self.x + self.w / 2, self.y + self.h / 2)
|
||||||
|
surface.blit(label, label_rect)
|
||||||
|
for event in EVENTS:
|
||||||
|
if event.type == pygame.MOUSEBUTTONDOWN:
|
||||||
|
if self.is_clicked(event.pos):
|
||||||
|
self.on_click()
|
||||||
|
# elif quit_button.is_clicked(event.pos):
|
||||||
|
# running = False
|
||||||
|
# if self.is_clicked:
|
||||||
|
# self.on_click()
|
||||||
|
|
||||||
|
def is_clicked(self, pos):
|
||||||
|
if pos[0] > self.x and pos[0] < self.x + self.w:
|
||||||
|
if pos[1] > self.y and pos[1] < self.y + self.h:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
# Create buttons
|
||||||
|
start_button = Button(
|
||||||
|
"Start Game", 300, 300, 200, 50, lambda: print("start this thing")
|
||||||
|
)
|
||||||
|
running = True
|
||||||
|
|
||||||
|
|
||||||
|
def stop():
|
||||||
|
global running
|
||||||
|
running = False
|
||||||
|
|
||||||
|
|
||||||
|
quit_button = Button("Quit Game", 300, 400, 200, 50, stop)
|
||||||
|
|
||||||
|
# Main loop
|
||||||
|
while running:
|
||||||
|
EVENTS = pygame.event.get()
|
||||||
|
for event in pygame.event.get():
|
||||||
|
if event.type == pygame.QUIT:
|
||||||
|
running = False
|
||||||
|
|
||||||
|
# Check for button clicks
|
||||||
|
|
||||||
|
# Draw background
|
||||||
|
screen.fill((0, 0, 0))
|
||||||
|
|
||||||
|
# Draw title
|
||||||
|
title = font.render("Creeper Adventure", True, (255, 255, 255))
|
||||||
|
screen.blit(title, (250, 200))
|
||||||
|
|
||||||
|
# Draw buttons
|
||||||
|
start_button.draw(screen)
|
||||||
|
quit_button.draw(screen)
|
||||||
|
|
||||||
|
pygame.display.update()
|
||||||
|
|
||||||
|
# Quit Pygame
|
||||||
|
pygame.quit()
|
||||||
42
gradients.py
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
from noise import pnoise2
|
||||||
|
import pygame
|
||||||
|
import random
|
||||||
|
|
||||||
|
# Initialize pygame
|
||||||
|
pygame.init()
|
||||||
|
|
||||||
|
# Set the size of the window
|
||||||
|
width, height = 800, 600
|
||||||
|
screen = pygame.display.set_mode((width, height))
|
||||||
|
|
||||||
|
# Create a list of 3 random blues
|
||||||
|
blues = []
|
||||||
|
for i in range(3):
|
||||||
|
blues.append(
|
||||||
|
(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create a perlin noise surface
|
||||||
|
noise_surface = pygame.Surface((width, height))
|
||||||
|
for x in range(width):
|
||||||
|
for y in range(height):
|
||||||
|
# Calculate the perlin noise value
|
||||||
|
noise_value = pnoise2(x / 100, y / 100)
|
||||||
|
# Map the noise value to a color
|
||||||
|
color_index = int(noise_value * (len(blues) - 1))
|
||||||
|
color = blues[color_index]
|
||||||
|
# Set the color of the pixel
|
||||||
|
noise_surface.set_at((x, y), color)
|
||||||
|
|
||||||
|
# Blit the noise surface to the screen
|
||||||
|
screen.blit(noise_surface, (0, 0))
|
||||||
|
|
||||||
|
# Update the display
|
||||||
|
pygame.display.flip()
|
||||||
|
|
||||||
|
# Keep the window open until it is closed
|
||||||
|
while True:
|
||||||
|
for event in pygame.event.get():
|
||||||
|
if event.type == pygame.QUIT:
|
||||||
|
pygame.quit()
|
||||||
|
exit()
|
||||||
BIN
grass.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
56
iso.py
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import pygame
|
||||||
|
from pygame.locals import DOUBLEBUF, K_ESCAPE, KEYUP, QUIT
|
||||||
|
|
||||||
|
pygame.init()
|
||||||
|
|
||||||
|
DISPLAYSURF = pygame.display.set_mode(
|
||||||
|
(640, 480), DOUBLEBUF
|
||||||
|
) # set the display mode, window title and FPS clock
|
||||||
|
pygame.display.set_caption("Map Rendering Demo")
|
||||||
|
FPSCLOCK = pygame.time.Clock()
|
||||||
|
|
||||||
|
map_data = [
|
||||||
|
[1, 1, 1, 1, 1],
|
||||||
|
[1, 0, 0, 0, 1],
|
||||||
|
[1, 0, 0, 0, 1],
|
||||||
|
[1, 0, 0, 0, 1],
|
||||||
|
[1, 0, 0, 0, 1],
|
||||||
|
[1, 1, 1, 1, 1],
|
||||||
|
] # the data for the map expressed as [row[tile]].
|
||||||
|
|
||||||
|
wall = pygame.image.load("wall.png").convert_alpha() # load images
|
||||||
|
grass = pygame.image.load("grass.png").convert_alpha()
|
||||||
|
|
||||||
|
TILEWIDTH = 64 # holds the tile width and height
|
||||||
|
TILEHEIGHT = 64
|
||||||
|
TILEHEIGHT_HALF = TILEHEIGHT / 2
|
||||||
|
TILEWIDTH_HALF = TILEWIDTH / 2
|
||||||
|
|
||||||
|
for row_nb, row in enumerate(map_data): # for every row of the map...
|
||||||
|
for col_nb, tile in enumerate(row):
|
||||||
|
if tile == 1:
|
||||||
|
tileImage = wall
|
||||||
|
else:
|
||||||
|
tileImage = grass
|
||||||
|
cart_x = row_nb * TILEWIDTH_HALF
|
||||||
|
cart_y = col_nb * TILEHEIGHT_HALF
|
||||||
|
iso_x = cart_x - cart_y
|
||||||
|
iso_y = (cart_x + cart_y) / 2
|
||||||
|
centered_x = DISPLAYSURF.get_rect().centerx + iso_x
|
||||||
|
centered_y = DISPLAYSURF.get_rect().centery / 2 + iso_y
|
||||||
|
DISPLAYSURF.blit(tileImage, (centered_x, centered_y)) # display the actual tile
|
||||||
|
|
||||||
|
while True:
|
||||||
|
for event in pygame.event.get():
|
||||||
|
if event.type == QUIT:
|
||||||
|
pygame.quit()
|
||||||
|
sys.exit()
|
||||||
|
if event.type == KEYUP:
|
||||||
|
if event.key == K_ESCAPE:
|
||||||
|
pygame.quit()
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
pygame.display.flip()
|
||||||
|
FPSCLOCK.tick(30)
|
||||||
|
|
@ -26,6 +26,7 @@ classifiers = [
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"click",
|
"click",
|
||||||
"pygame",
|
"pygame",
|
||||||
|
"noise",
|
||||||
"more_itertools",
|
"more_itertools",
|
||||||
]
|
]
|
||||||
dynamic = ["version"]
|
dynamic = ["version"]
|
||||||
|
|
|
||||||
0
requirements.txt
Executable file → Normal file
0
site/static/creeper-1.png
Executable file → Normal file
|
Before Width: | Height: | Size: 769 B After Width: | Height: | Size: 769 B |
99
spacegame.py
Normal file
|
|
@ -0,0 +1,99 @@
|
||||||
|
import pygame
|
||||||
|
|
||||||
|
# Define some colors
|
||||||
|
BLACK = (0, 0, 0)
|
||||||
|
WHITE = (255, 255, 255)
|
||||||
|
GREEN = (0, 255, 0)
|
||||||
|
RED = (255, 0, 0)
|
||||||
|
BLUE = (0, 0, 255)
|
||||||
|
|
||||||
|
# Define some constants
|
||||||
|
WIDTH = 800
|
||||||
|
HEIGHT = 600
|
||||||
|
FPS = 60
|
||||||
|
GRAVITY = 0.5
|
||||||
|
|
||||||
|
# Define some variables
|
||||||
|
x = WIDTH / 2
|
||||||
|
y = HEIGHT / 2
|
||||||
|
vx = 0
|
||||||
|
vy = 0
|
||||||
|
|
||||||
|
# Define some functions
|
||||||
|
|
||||||
|
|
||||||
|
def draw_dot(x, y):
|
||||||
|
pygame.draw.circle(window, BLACK, (int(x), int(y)), 10)
|
||||||
|
|
||||||
|
|
||||||
|
def move_dot(x, y, vx, vy):
|
||||||
|
x += vx
|
||||||
|
y += vy
|
||||||
|
return x, y
|
||||||
|
|
||||||
|
|
||||||
|
def apply_gravity(vy):
|
||||||
|
vy += GRAVITY
|
||||||
|
return vy
|
||||||
|
|
||||||
|
|
||||||
|
def jump(vy):
|
||||||
|
vy = -10
|
||||||
|
return vy
|
||||||
|
|
||||||
|
|
||||||
|
# Initialize pygame
|
||||||
|
pygame.init()
|
||||||
|
|
||||||
|
# Create a window
|
||||||
|
# Create a clock
|
||||||
|
clock = pygame.time.Clock()
|
||||||
|
|
||||||
|
# Create a window
|
||||||
|
window = pygame.display.set_mode((WIDTH, HEIGHT))
|
||||||
|
|
||||||
|
# Set window title
|
||||||
|
pygame.display.set_caption("My Game")
|
||||||
|
|
||||||
|
# Game loop
|
||||||
|
running = True
|
||||||
|
# Set the frame rate
|
||||||
|
clock.tick(FPS)
|
||||||
|
|
||||||
|
while running:
|
||||||
|
# Process events
|
||||||
|
for event in pygame.event.get():
|
||||||
|
if event.type == pygame.QUIT:
|
||||||
|
running = False
|
||||||
|
if event.type == pygame.KEYDOWN:
|
||||||
|
if event.key == pygame.K_a:
|
||||||
|
vx = -5
|
||||||
|
if event.key == pygame.K_d:
|
||||||
|
vx = 5
|
||||||
|
if event.key == pygame.K_SPACE:
|
||||||
|
vy = jump(vy)
|
||||||
|
if event.type == pygame.KEYUP:
|
||||||
|
if event.key == pygame.K_a:
|
||||||
|
vx = 0
|
||||||
|
if event.key == pygame.K_d:
|
||||||
|
vx = 0
|
||||||
|
|
||||||
|
running = False
|
||||||
|
x, y = move_dot(x, y, vx, vy)
|
||||||
|
vy = apply_gravity(vy)
|
||||||
|
|
||||||
|
# Render
|
||||||
|
# Clear the screen
|
||||||
|
|
||||||
|
# Draw the dot
|
||||||
|
draw_dot(x, y)
|
||||||
|
|
||||||
|
# Update the display
|
||||||
|
# Update
|
||||||
|
|
||||||
|
# Render
|
||||||
|
window.fill((255, 255, 255))
|
||||||
|
pygame.display.update()
|
||||||
|
|
||||||
|
# Close window on quit
|
||||||
|
pygame.quit()
|
||||||
521
tetris.py
Normal file
|
|
@ -0,0 +1,521 @@
|
||||||
|
# Tetromino (a Tetris clone)
|
||||||
|
# By Al Sweigart al@inventwithpython.com
|
||||||
|
# http://inventwithpython.com/pygame
|
||||||
|
# Released under a "Simplified BSD" license
|
||||||
|
|
||||||
|
import random
|
||||||
|
import time
|
||||||
|
import pygame
|
||||||
|
import sys
|
||||||
|
from pygame.locals import *
|
||||||
|
|
||||||
|
FPS = 25
|
||||||
|
WINDOWWIDTH = 640
|
||||||
|
WINDOWZE = 20
|
||||||
|
BOARHEIGHT = 480
|
||||||
|
BOXSIDWIDTH = 10
|
||||||
|
BOARDHEIGHT = 20
|
||||||
|
BLANK = '.'
|
||||||
|
|
||||||
|
MOVESIDEWAYSFREQ = 0.15
|
||||||
|
MOVEDOWNFREQ = 0.1
|
||||||
|
|
||||||
|
XMARGIN = int((WINDOWWIDTH - BOARDWIDTH * BOXSIZE) / 2)
|
||||||
|
TOPMARGIN = WINDOWHEIGHT - (BOARDHEIGHT * BOXSIZE) - 5
|
||||||
|
|
||||||
|
# R G B
|
||||||
|
WHITE = (255, 255, 255)
|
||||||
|
GRAY = (185, 185, 185)
|
||||||
|
BLACK = (0, 0, 0)
|
||||||
|
RED = (155, 0, 0)
|
||||||
|
LIGHTRED = (175, 20, 20)
|
||||||
|
GREEN = (0, 155, 0)
|
||||||
|
LIGHTGREEN = (20, 175, 20)
|
||||||
|
BLUE = (0, 0, 155)
|
||||||
|
LIGHTBLUE = (20, 20, 175)
|
||||||
|
YELLOW = (155, 155, 0)
|
||||||
|
LIGHTYELLOW = (175, 175, 20)
|
||||||
|
|
||||||
|
BORDERCOLOR = BLUE
|
||||||
|
BGCOLOR = BLACK
|
||||||
|
TEXTCOLOR = WHITE
|
||||||
|
TEXTSHADOWCOLOR = GRAY
|
||||||
|
COLORS = (BLUE, GREEN, RED, YELLOW)
|
||||||
|
LIGHTCOLORS = (LIGHTBLUE, LIGHTGREEN, LIGHTRED, LIGHTYELLOW)
|
||||||
|
assert len(COLORS) == len(LIGHTCOLORS) # each color must have light color
|
||||||
|
|
||||||
|
TEMPLATEWIDTH = 5
|
||||||
|
TEMPLATEHEIGHT = 5
|
||||||
|
|
||||||
|
S_SHAPE_TEMPLATE = [['.....',
|
||||||
|
'.....',
|
||||||
|
'..OO.',
|
||||||
|
'.OO..',
|
||||||
|
'.....'],
|
||||||
|
['.....',
|
||||||
|
'..O..',
|
||||||
|
'..OO.',
|
||||||
|
'...O.',
|
||||||
|
'.....']]
|
||||||
|
|
||||||
|
Z_SHAPE_TEMPLATE = [['.....',
|
||||||
|
'.....',
|
||||||
|
'.OO..',
|
||||||
|
'..OO.',
|
||||||
|
'.....'],
|
||||||
|
['.....',
|
||||||
|
'..O..',
|
||||||
|
'.OO..',
|
||||||
|
'.O...',
|
||||||
|
'.....']]
|
||||||
|
|
||||||
|
I_SHAPE_TEMPLATE = [['..O..',
|
||||||
|
'..O..',
|
||||||
|
'..O..',
|
||||||
|
'..O..',
|
||||||
|
'.....'],
|
||||||
|
['.....',
|
||||||
|
'.....',
|
||||||
|
'OOOO.',
|
||||||
|
'.....',
|
||||||
|
'.....']]
|
||||||
|
|
||||||
|
O_SHAPE_TEMPLATE = [['.....',
|
||||||
|
'.....',
|
||||||
|
'.OO..',
|
||||||
|
'.OO..',
|
||||||
|
'.....']]
|
||||||
|
|
||||||
|
J_SHAPE_TEMPLATE = [['.....',
|
||||||
|
'.O...',
|
||||||
|
'.OOO.',
|
||||||
|
'.....',
|
||||||
|
'.....'],
|
||||||
|
['.....',
|
||||||
|
'..OO.',
|
||||||
|
'..O..',
|
||||||
|
'..O..',
|
||||||
|
'.....'],
|
||||||
|
['.....',
|
||||||
|
'.....',
|
||||||
|
'.OOO.',
|
||||||
|
'...O.',
|
||||||
|
'.....'],
|
||||||
|
['.....',
|
||||||
|
'..O..',
|
||||||
|
'..O..',
|
||||||
|
'.OO..',
|
||||||
|
'.....']]
|
||||||
|
|
||||||
|
L_SHAPE_TEMPLATE = [['.....',
|
||||||
|
'...O.',
|
||||||
|
'.OOO.',
|
||||||
|
'.....',
|
||||||
|
'.....'],
|
||||||
|
['.....',
|
||||||
|
'..O..',
|
||||||
|
'..O..',
|
||||||
|
'..OO.',
|
||||||
|
'.....'],
|
||||||
|
['.....',
|
||||||
|
'.....',
|
||||||
|
'.OOO.',
|
||||||
|
'.O...',
|
||||||
|
'.....'],
|
||||||
|
['.....',
|
||||||
|
'.OO..',
|
||||||
|
'..O..',
|
||||||
|
'..O..',
|
||||||
|
'.....']]
|
||||||
|
|
||||||
|
T_SHAPE_TEMPLATE = [['.....',
|
||||||
|
'..O..',
|
||||||
|
'.OOO.',
|
||||||
|
'.....',
|
||||||
|
'.....'],
|
||||||
|
['.....',
|
||||||
|
'..O..',
|
||||||
|
'..OO.',
|
||||||
|
'..O..',
|
||||||
|
'.....'],
|
||||||
|
['.....',
|
||||||
|
'.....',
|
||||||
|
'.OOO.',
|
||||||
|
'..O..',
|
||||||
|
'.....'],
|
||||||
|
['.....',
|
||||||
|
'..O..',
|
||||||
|
'.OO..',
|
||||||
|
'..O..',
|
||||||
|
'.....']]
|
||||||
|
|
||||||
|
PIECES = {'S': S_SHAPE_TEMPLATE,
|
||||||
|
'Z': Z_SHAPE_TEMPLATE,
|
||||||
|
'J': J_SHAPE_TEMPLATE,
|
||||||
|
'L': L_SHAPE_TEMPLATE,
|
||||||
|
'I': I_SHAPE_TEMPLATE,
|
||||||
|
'O': O_SHAPE_TEMPLATE,
|
||||||
|
'T': T_SHAPE_TEMPLATE}
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
global FPSCLOCK, DISPLAYSURF, BASICFONT, BIGFONT
|
||||||
|
pygame.init()
|
||||||
|
FPSCLOCK = pygame.time.Clock()
|
||||||
|
DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
|
||||||
|
BASICFONT = pygame.font.Font('freesansbold.ttf', 18)
|
||||||
|
BIGFONT = pygame.font.Font('freesansbold.ttf', 100)
|
||||||
|
pygame.display.set_caption('Tetromino')
|
||||||
|
|
||||||
|
showTextScreen('Tetromino')
|
||||||
|
while True: # game loop
|
||||||
|
# if random.randint(0, 1) == 0:
|
||||||
|
# pygame.mixer.music.load('tetrisb.mid')
|
||||||
|
# else:
|
||||||
|
# pygame.mixer.music.load('tetrisc.mid')
|
||||||
|
#pygame.mixer.music.play(-1, 0.0)
|
||||||
|
runGame()
|
||||||
|
# pygame.mixer.music.stop()
|
||||||
|
showTextScreen('Game Over')
|
||||||
|
|
||||||
|
|
||||||
|
def runGame():
|
||||||
|
# setup variables for the start of the game
|
||||||
|
board = getBlankBoard()
|
||||||
|
lastMoveDownTime = time.time()
|
||||||
|
lastMoveSidewaysTime = time.time()
|
||||||
|
lastFallTime = time.time()
|
||||||
|
movingDown = False # note: there is no movingUp variable
|
||||||
|
movingLeft = False
|
||||||
|
movingRight = False
|
||||||
|
score = 0
|
||||||
|
level, fallFreq = calculateLevelAndFallFreq(score)
|
||||||
|
|
||||||
|
fallingPiece = getNewPiece()
|
||||||
|
nextPiece = getNewPiece()
|
||||||
|
|
||||||
|
while True: # game loop
|
||||||
|
if fallingPiece == None:
|
||||||
|
# No falling piece in play, so start a new piece at the top
|
||||||
|
fallingPiece = nextPiece
|
||||||
|
nextPiece = getNewPiece()
|
||||||
|
lastFallTime = time.time() # reset lastFallTime
|
||||||
|
|
||||||
|
if not isValidPosition(board, fallingPiece):
|
||||||
|
return # can't fit a new piece on the board, so game over
|
||||||
|
|
||||||
|
checkForQuit()
|
||||||
|
for event in pygame.event.get(): # event handling loop
|
||||||
|
if event.type == KEYUP:
|
||||||
|
if (event.key == K_p):
|
||||||
|
# Pausing the game
|
||||||
|
DISPLAYSURF.fill(BGCOLOR)
|
||||||
|
pygame.mixer.music.stop()
|
||||||
|
showTextScreen('Paused') # pause until a key press
|
||||||
|
pygame.mixer.music.play(-1, 0.0)
|
||||||
|
lastFallTime = time.time()
|
||||||
|
lastMoveDownTime = time.time()
|
||||||
|
lastMoveSidewaysTime = time.time()
|
||||||
|
elif (event.key == K_LEFT or event.key == K_a):
|
||||||
|
movingLeft = False
|
||||||
|
elif (event.key == K_RIGHT or event.key == K_d):
|
||||||
|
movingRight = False
|
||||||
|
elif (event.key == K_DOWN or event.key == K_s):
|
||||||
|
movingDown = False
|
||||||
|
|
||||||
|
elif event.type == KEYDOWN:
|
||||||
|
# moving the piece sideways
|
||||||
|
if (event.key == K_LEFT or event.key == K_a) and isValidPosition(board, fallingPiece, adjX=-1):
|
||||||
|
fallingPiece['x'] -= 1
|
||||||
|
movingLeft = True
|
||||||
|
movingRight = False
|
||||||
|
lastMoveSidewaysTime = time.time()
|
||||||
|
|
||||||
|
elif (event.key == K_RIGHT or event.key == K_d) and isValidPosition(board, fallingPiece, adjX=1):
|
||||||
|
fallingPiece['x'] += 1
|
||||||
|
movingRight = True
|
||||||
|
movingLeft = False
|
||||||
|
lastMoveSidewaysTime = time.time()
|
||||||
|
|
||||||
|
# rotating the piece (if there is room to rotate)
|
||||||
|
elif (event.key == K_UP or event.key == K_w):
|
||||||
|
fallingPiece['rotation'] = (
|
||||||
|
fallingPiece['rotation'] + 1) % len(PIECES[fallingPiece['shape']])
|
||||||
|
if not isValidPosition(board, fallingPiece):
|
||||||
|
fallingPiece['rotation'] = (
|
||||||
|
fallingPiece['rotation'] - 1) % len(PIECES[fallingPiece['shape']])
|
||||||
|
elif (event.key == K_q): # rotate the other direction
|
||||||
|
fallingPiece['rotation'] = (
|
||||||
|
fallingPiece['rotation'] - 1) % len(PIECES[fallingPiece['shape']])
|
||||||
|
if not isValidPosition(board, fallingPiece):
|
||||||
|
fallingPiece['rotation'] = (
|
||||||
|
fallingPiece['rotation'] + 1) % len(PIECES[fallingPiece['shape']])
|
||||||
|
|
||||||
|
# making the piece fall faster with the down key
|
||||||
|
elif (event.key == K_DOWN or event.key == K_s):
|
||||||
|
movingDown = True
|
||||||
|
if isValidPosition(board, fallingPiece, adjY=1):
|
||||||
|
fallingPiece['y'] += 1
|
||||||
|
lastMoveDownTime = time.time()
|
||||||
|
|
||||||
|
# move the current piece all the way down
|
||||||
|
elif event.key == K_SPACE:
|
||||||
|
movingDown = False
|
||||||
|
movingLeft = False
|
||||||
|
movingRight = False
|
||||||
|
for i in range(1, BOARDHEIGHT):
|
||||||
|
if not isValidPosition(board, fallingPiece, adjY=i):
|
||||||
|
break
|
||||||
|
fallingPiece['y'] += i - 1
|
||||||
|
|
||||||
|
# handle moving the piece because of user input
|
||||||
|
if (movingLeft or movingRight) and time.time() - lastMoveSidewaysTime > MOVESIDEWAYSFREQ:
|
||||||
|
if movingLeft and isValidPosition(board, fallingPiece, adjX=-1):
|
||||||
|
fallingPiece['x'] -= 1
|
||||||
|
elif movingRight and isValidPosition(board, fallingPiece, adjX=1):
|
||||||
|
fallingPiece['x'] += 1
|
||||||
|
lastMoveSidewaysTime = time.time()
|
||||||
|
|
||||||
|
if movingDown and time.time() - lastMoveDownTime > MOVEDOWNFREQ and isValidPosition(board, fallingPiece, adjY=1):
|
||||||
|
fallingPiece['y'] += 1
|
||||||
|
lastMoveDownTime = time.time()
|
||||||
|
|
||||||
|
# let the piece fall if it is time to fall
|
||||||
|
if time.time() - lastFallTime > fallFreq:
|
||||||
|
# see if the piece has landed
|
||||||
|
if not isValidPosition(board, fallingPiece, adjY=1):
|
||||||
|
# falling piece has landed, set it on the board
|
||||||
|
addToBoard(board, fallingPiece)
|
||||||
|
score += removeCompleteLines(board)
|
||||||
|
level, fallFreq = calculateLevelAndFallFreq(score)
|
||||||
|
fallingPiece = None
|
||||||
|
else:
|
||||||
|
# piece did not land, just move the piece down
|
||||||
|
fallingPiece['y'] += 1
|
||||||
|
lastFallTime = time.time()
|
||||||
|
|
||||||
|
# drawing everything on the screen
|
||||||
|
DISPLAYSURF.fill(BGCOLOR)
|
||||||
|
drawBoard(board)
|
||||||
|
drawStatus(score, level)
|
||||||
|
drawNextPiece(nextPiece) # Here
|
||||||
|
if fallingPiece != None:
|
||||||
|
drawPiece(fallingPiece)
|
||||||
|
|
||||||
|
pygame.display.update()
|
||||||
|
FPSCLOCK.tick(FPS)
|
||||||
|
|
||||||
|
|
||||||
|
def makeTextObjs(text, font, color):
|
||||||
|
surf = font.render(text, True, color)
|
||||||
|
return surf, surf.get_rect()
|
||||||
|
|
||||||
|
|
||||||
|
def terminate():
|
||||||
|
pygame.quit()
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
|
||||||
|
def checkForKeyPress():
|
||||||
|
# Go through event queue looking for a KEYUP event.
|
||||||
|
# Grab KEYDOWN events to remove them from the event queue.
|
||||||
|
checkForQuit()
|
||||||
|
|
||||||
|
for event in pygame.event.get([KEYDOWN, KEYUP]):
|
||||||
|
if event.type == KEYDOWN:
|
||||||
|
continue
|
||||||
|
return event.key
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def showTextScreen(text):
|
||||||
|
# This function displays large text in the
|
||||||
|
# center of the screen until a key is pressed.
|
||||||
|
# Draw the text drop shadow
|
||||||
|
titleSurf, titleRect = makeTextObjs(text, BIGFONT, TEXTSHADOWCOLOR)
|
||||||
|
titleRect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 2))
|
||||||
|
DISPLAYSURF.blit(titleSurf, titleRect)
|
||||||
|
|
||||||
|
# Draw the text
|
||||||
|
titleSurf, titleRect = makeTextObjs(text, BIGFONT, TEXTCOLOR)
|
||||||
|
titleRect.center = (int(WINDOWWIDTH / 2) - 3, int(WINDOWHEIGHT / 2) - 3)
|
||||||
|
DISPLAYSURF.blit(titleSurf, titleRect)
|
||||||
|
|
||||||
|
# Draw the additional "Press a key to play." text.
|
||||||
|
pressKeySurf, pressKeyRect = makeTextObjs(
|
||||||
|
'Press a key to play.', BASICFONT, TEXTCOLOR)
|
||||||
|
pressKeyRect.center = (int(WINDOWWIDTH / 2), int(WINDOWHEIGHT / 2) + 100)
|
||||||
|
DISPLAYSURF.blit(pressKeySurf, pressKeyRect)
|
||||||
|
|
||||||
|
while checkForKeyPress() == None:
|
||||||
|
pygame.display.update()
|
||||||
|
FPSCLOCK.tick()
|
||||||
|
|
||||||
|
|
||||||
|
def checkForQuit():
|
||||||
|
for event in pygame.event.get(QUIT): # get all the QUIT events
|
||||||
|
terminate() # terminate if any QUIT events are present
|
||||||
|
for event in pygame.event.get(KEYUP): # get all the KEYUP events
|
||||||
|
if event.key == K_ESCAPE:
|
||||||
|
terminate() # terminate if the KEYUP event was for the Esc key
|
||||||
|
pygame.event.post(event) # put the other KEYUP event objects back
|
||||||
|
|
||||||
|
|
||||||
|
def calculateLevelAndFallFreq(score):
|
||||||
|
# Based on the score, return the level the player is on and
|
||||||
|
# how many seconds pass until a falling piece falls one space.
|
||||||
|
level = int(score / 10) + 1
|
||||||
|
fallFreq = 0.27 - (level * 0.02)
|
||||||
|
return level, fallFreq
|
||||||
|
|
||||||
|
|
||||||
|
def getNewPiece():
|
||||||
|
# return a random new piece in a random rotation and color
|
||||||
|
shape = random.choice(list(PIECES.keys()))
|
||||||
|
newPiece = {'shape': shape,
|
||||||
|
'rotation': random.randint(0, len(PIECES[shape]) - 1),
|
||||||
|
'x': int(BOARDWIDTH / 2) - int(TEMPLATEWIDTH / 2),
|
||||||
|
'y': -2, # start it above the board (i.e. less than 0)
|
||||||
|
'color': random.randint(0, len(COLORS) - 1)}
|
||||||
|
return newPiece
|
||||||
|
|
||||||
|
|
||||||
|
def addToBoard(board, piece):
|
||||||
|
# fill in the board based on piece's location, shape, and rotation
|
||||||
|
for x in range(TEMPLATEWIDTH):
|
||||||
|
for y in range(TEMPLATEHEIGHT):
|
||||||
|
if PIECES[piece['shape']][piece['rotation']][y][x] != BLANK:
|
||||||
|
board[x + piece['x']][y + piece['y']] = piece['color']
|
||||||
|
|
||||||
|
|
||||||
|
def getBlankBoard():
|
||||||
|
# create and return a new blank board data structure
|
||||||
|
board = []
|
||||||
|
for i in range(BOARDWIDTH):
|
||||||
|
board.append([BLANK] * BOARDHEIGHT)
|
||||||
|
return board
|
||||||
|
|
||||||
|
|
||||||
|
def isOnBoard(x, y):
|
||||||
|
return x >= 0 and x < BOARDWIDTH and y < BOARDHEIGHT
|
||||||
|
|
||||||
|
|
||||||
|
def isValidPosition(board, piece, adjX=0, adjY=0):
|
||||||
|
# Return True if the piece is within the board and not colliding
|
||||||
|
for x in range(TEMPLATEWIDTH):
|
||||||
|
for y in range(TEMPLATEHEIGHT):
|
||||||
|
isAboveBoard = y + piece['y'] + adjY < 0
|
||||||
|
if isAboveBoard or PIECES[piece['shape']][piece['rotation']][y][x] == BLANK:
|
||||||
|
continue
|
||||||
|
if not isOnBoard(x + piece['x'] + adjX, y + piece['y'] + adjY):
|
||||||
|
return False
|
||||||
|
if board[x + piece['x'] + adjX][y + piece['y'] + adjY] != BLANK:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def isCompleteLine(board, y):
|
||||||
|
# Return True if the line filled with boxes with no gaps.
|
||||||
|
for x in range(BOARDWIDTH):
|
||||||
|
if board[x][y] == BLANK:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def removeCompleteLines(board):
|
||||||
|
# Remove any completed lines on the board, move everything above them down, and return the number of complete lines.
|
||||||
|
numLinesRemoved = 0
|
||||||
|
y = BOARDHEIGHT - 1 # start y at the bottom of the board
|
||||||
|
while y >= 0:
|
||||||
|
if isCompleteLine(board, y):
|
||||||
|
# Remove the line and pull boxes down by one line.
|
||||||
|
for pullDownY in range(y, 0, -1):
|
||||||
|
for x in range(BOARDWIDTH):
|
||||||
|
board[x][pullDownY] = board[x][pullDownY - 1]
|
||||||
|
# Set very top line to blank.
|
||||||
|
for x in range(BOARDWIDTH):
|
||||||
|
board[x][0] = BLANK
|
||||||
|
numLinesRemoved += 1
|
||||||
|
# Note on the next iteration of the loop, y is the same.
|
||||||
|
# This is so that if the line that was pulled down is also
|
||||||
|
# complete, it will be removed.
|
||||||
|
else:
|
||||||
|
y -= 1 # move on to check next row up
|
||||||
|
return numLinesRemoved
|
||||||
|
|
||||||
|
|
||||||
|
def convertToPixelCoords(boxx, boxy):
|
||||||
|
# Convert the given xy coordinates of the board to xy
|
||||||
|
# coordinates of the location on the screen.
|
||||||
|
return (XMARGIN + (boxx * BOXSIZE)), (TOPMARGIN + (boxy * BOXSIZE))
|
||||||
|
|
||||||
|
|
||||||
|
def drawBox(boxx, boxy, color, pixelx=None, pixely=None):
|
||||||
|
# draw a single box (each tetromino piece has four boxes)
|
||||||
|
# at xy coordinates on the board. Or, if pixelx & pixely
|
||||||
|
# are specified, draw to the pixel coordinates stored in
|
||||||
|
# pixelx & pixely (this is used for the "Next" piece).
|
||||||
|
if color == BLANK:
|
||||||
|
return
|
||||||
|
if pixelx == None and pixely == None:
|
||||||
|
pixelx, pixely = convertToPixelCoords(boxx, boxy)
|
||||||
|
pygame.draw.rect(DISPLAYSURF, COLORS[color],
|
||||||
|
(pixelx + 1, pixely + 1, BOXSIZE - 1, BOXSIZE - 1))
|
||||||
|
pygame.draw.rect(
|
||||||
|
DISPLAYSURF, LIGHTCOLORS[color], (pixelx + 1, pixely + 1, BOXSIZE - 4, BOXSIZE - 4))
|
||||||
|
|
||||||
|
|
||||||
|
def drawBoard(board):
|
||||||
|
# draw the border around the board
|
||||||
|
pygame.draw.rect(DISPLAYSURF, BORDERCOLOR, (XMARGIN - 3, TOPMARGIN - 7,
|
||||||
|
(BOARDWIDTH * BOXSIZE) + 8, (BOARDHEIGHT * BOXSIZE) + 8), 5)
|
||||||
|
|
||||||
|
# fill the background of the board
|
||||||
|
pygame.draw.rect(DISPLAYSURF, BGCOLOR, (XMARGIN, TOPMARGIN,
|
||||||
|
BOXSIZE * BOARDWIDTH, BOXSIZE * BOARDHEIGHT))
|
||||||
|
# draw the individual boxes on the board
|
||||||
|
for x in range(BOARDWIDTH):
|
||||||
|
for y in range(BOARDHEIGHT):
|
||||||
|
drawBox(x, y, board[x][y])
|
||||||
|
|
||||||
|
|
||||||
|
def drawStatus(score, level):
|
||||||
|
# draw the score text
|
||||||
|
scoreSurf = BASICFONT.render('Score: %s' % score, True, TEXTCOLOR)
|
||||||
|
scoreRect = scoreSurf.get_rect()
|
||||||
|
scoreRect.topleft = (WINDOWWIDTH - 150, 20)
|
||||||
|
DISPLAYSURF.blit(scoreSurf, scoreRect)
|
||||||
|
|
||||||
|
# draw the level text
|
||||||
|
levelSurf = BASICFONT.render('Level: %s' % level, True, TEXTCOLOR)
|
||||||
|
levelRect = levelSurf.get_rect()
|
||||||
|
levelRect.topleft = (WINDOWWIDTH - 150, 50)
|
||||||
|
DISPLAYSURF.blit(levelSurf, levelRect)
|
||||||
|
|
||||||
|
|
||||||
|
def drawPiece(piece, pixelx=None, pixely=None):
|
||||||
|
shapeToDraw = PIECES[piece['shape']][piece['rotation']]
|
||||||
|
if pixelx == None and pixely == None:
|
||||||
|
# if pixelx & pixely hasn't been specified, use the location stored in the piece data structure
|
||||||
|
pixelx, pixely = convertToPixelCoords(piece['x'], piece['y'])
|
||||||
|
|
||||||
|
# draw each of the boxes that make up the piece
|
||||||
|
for x in range(TEMPLATEWIDTH):
|
||||||
|
for y in range(TEMPLATEHEIGHT):
|
||||||
|
if shapeToDraw[y][x] != BLANK:
|
||||||
|
drawBox(None, None, piece['color'], pixelx
|
||||||
|
+ (x * BOXSIZE), pixely + (y * BOXSIZE))
|
||||||
|
|
||||||
|
|
||||||
|
def drawNextPiece(piece):
|
||||||
|
# draw the "next" text
|
||||||
|
nextSurf = BASICFONT.render('Next:', True, TEXTCOLOR)
|
||||||
|
nextRect = nextSurf.get_rect()
|
||||||
|
nextRect.topleft = (WINDOWWIDTH - 120, 80)
|
||||||
|
DISPLAYSURF.blit(nextSurf, nextRect)
|
||||||
|
# draw the "next" piece
|
||||||
|
drawPiece(piece, pixelx=WINDOWWIDTH - 120, pixely=100)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
41
tmp.py
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
import noise
|
||||||
|
import pygame
|
||||||
|
|
||||||
|
# Initialize pygame
|
||||||
|
pygame.init()
|
||||||
|
|
||||||
|
# Set up the drawing window
|
||||||
|
screen = pygame.display.set_mode([800, 600])
|
||||||
|
|
||||||
|
# Run until the user asks to quit
|
||||||
|
running = True
|
||||||
|
while running:
|
||||||
|
|
||||||
|
# Did the user click the window close button?
|
||||||
|
for event in pygame.event.get():
|
||||||
|
if event.type == pygame.QUIT:
|
||||||
|
running = False
|
||||||
|
|
||||||
|
# Fill the background with black
|
||||||
|
screen.fill((0, 0, 0))
|
||||||
|
|
||||||
|
# Draw stars
|
||||||
|
for i in range(2000):
|
||||||
|
x = int(noise.pnoise1(i / 10.0, octaves=4) * 800)
|
||||||
|
y = int(noise.pnoise1(i / 10.0 + 1000, octaves=4) * 600)
|
||||||
|
pygame.draw.circle(screen, (255, 255, 255), (x, y), 2)
|
||||||
|
|
||||||
|
# Draw the moon
|
||||||
|
pygame.draw.circle(screen, (180, 180, 180), (400, 5600 - 200), 5000, 0) # moon
|
||||||
|
|
||||||
|
# Draw craters on the surface of the moon (masked by the shape of the moon)
|
||||||
|
for i in range(20):
|
||||||
|
x = int(noise.pnoise1(i / 10.0, octaves=4) * 800)
|
||||||
|
y = int(noise.pnoise1(i / 10.0 + 1000, octaves=4) * 600)
|
||||||
|
pygame.draw.circle(screen, (100, 100, 100), (x, y), 20, 0)
|
||||||
|
|
||||||
|
# Flip the display
|
||||||
|
pygame.display.flip()
|
||||||
|
|
||||||
|
# Done! Time to quit.
|
||||||
|
pygame.quit()
|
||||||
BIN
wall.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |