game.py
· 3.3 KiB · Python
Raw
import pygame
pygame.init()
class GameContext :
def __init__(
self,
dt, events, keys,
game,
):
self.dt = dt
self.events = events
self.keys = keys
self.game = game
# ctx.screen -> ctx.game.screen
class Game:
def __init__(
self,
resolution=(640, 480),
bg_color=(0, 0, 0),
fps=30,
objects=[],
):
self.resolution = resolution
self.bg_color = bg_color
self.fps = fps
self.objects = objects
def run(self):
self.screen = pygame.display.set_mode(self.resolution)
clock = pygame.time.Clock()
running = True
while running : # gist.surdeus.su/surdeus
# Здесь код на каждый кадр
dt = clock.tick(self.fps) / 1000.0
events = pygame.event.get()
for event in events :
if event.type == pygame.QUIT :
running = False
self.screen.fill(self.bg_color)
keys = pygame.key.get_pressed()
ctx = GameContext(dt, events, keys, self)
for o in self.objects :
o.update(ctx)
o.draw(ctx)
# Вывести всё нарисованное на окно
pygame.display.update()
pygame.quit()
class GameObject:
def update(self, ctx):
pass
def draw(self, ctx):
pass
# Rectangle - прямоугольник
class Rect(GameObject):
def __init__(
self,
x = 0, y = 0,
w = 100, h = 100,
fill_color=(255, 255, 255),
visible=True,
):
self.x = x
self.y = y
self.w = w
self.h = h
self.fill_color = fill_color
self.visible = visible
def draw(self, ctx):
if not self.visible :
return
pygame.draw.rect(
ctx.game.screen, self.fill_color,
(self.x, self.y,
self.w, self.h),
)
# Содержит ли точку.
def contains_point(self, px, py):
x, y, w, h = self.x, self.y, self.w, self.h
return (
py >= y and py <= (y + h) and
px >= x and px <= (x + w)
)
def points(self):
x, y, w, h = self.x, self.y, self.w, self.h
return ((x, y),
(x + w, y),
(x + w, y + h),
(x, y + h))
def intersects_with(self, other):
for point in other.points() :
if self.contains_point(point[0], point[1]) :
return True
for point in self.points() :
if other.contains_point(point[0], point[1]) :
return True
return False
class Text(GameObject):
def __init__(self, text,
x=0, y=0, fontname=None, fontsize=72,
fill_color=(255, 255, 255)):
self.x = x
self.y = y
self.text = text
if not fontname :
fontname = pygame.font.get_default_font()
print('font:', fontname)
self.font = pygame.font.SysFont(fontname, fontsize)
self.fill_color = fill_color
def draw(self, ctx):
img = self.font.render(self.text, True,
self.fill_color)
ctx.game.screen.blit(img, (self.x, self.y))
| 1 | import pygame |
| 2 | pygame.init() |
| 3 | |
| 4 | class GameContext : |
| 5 | def __init__( |
| 6 | self, |
| 7 | dt, events, keys, |
| 8 | game, |
| 9 | ): |
| 10 | self.dt = dt |
| 11 | self.events = events |
| 12 | self.keys = keys |
| 13 | self.game = game |
| 14 | # ctx.screen -> ctx.game.screen |
| 15 | |
| 16 | class Game: |
| 17 | def __init__( |
| 18 | self, |
| 19 | resolution=(640, 480), |
| 20 | bg_color=(0, 0, 0), |
| 21 | fps=30, |
| 22 | objects=[], |
| 23 | ): |
| 24 | self.resolution = resolution |
| 25 | self.bg_color = bg_color |
| 26 | self.fps = fps |
| 27 | self.objects = objects |
| 28 | def run(self): |
| 29 | self.screen = pygame.display.set_mode(self.resolution) |
| 30 | clock = pygame.time.Clock() |
| 31 | running = True |
| 32 | while running : # gist.surdeus.su/surdeus |
| 33 | # Здесь код на каждый кадр |
| 34 | |
| 35 | dt = clock.tick(self.fps) / 1000.0 |
| 36 | events = pygame.event.get() |
| 37 | for event in events : |
| 38 | if event.type == pygame.QUIT : |
| 39 | running = False |
| 40 | |
| 41 | self.screen.fill(self.bg_color) |
| 42 | |
| 43 | keys = pygame.key.get_pressed() |
| 44 | ctx = GameContext(dt, events, keys, self) |
| 45 | |
| 46 | for o in self.objects : |
| 47 | o.update(ctx) |
| 48 | o.draw(ctx) |
| 49 | |
| 50 | # Вывести всё нарисованное на окно |
| 51 | pygame.display.update() |
| 52 | pygame.quit() |
| 53 | |
| 54 | class GameObject: |
| 55 | def update(self, ctx): |
| 56 | pass |
| 57 | def draw(self, ctx): |
| 58 | pass |
| 59 | # Rectangle - прямоугольник |
| 60 | class Rect(GameObject): |
| 61 | def __init__( |
| 62 | self, |
| 63 | x = 0, y = 0, |
| 64 | w = 100, h = 100, |
| 65 | fill_color=(255, 255, 255), |
| 66 | visible=True, |
| 67 | ): |
| 68 | self.x = x |
| 69 | self.y = y |
| 70 | self.w = w |
| 71 | self.h = h |
| 72 | self.fill_color = fill_color |
| 73 | self.visible = visible |
| 74 | |
| 75 | def draw(self, ctx): |
| 76 | if not self.visible : |
| 77 | return |
| 78 | pygame.draw.rect( |
| 79 | ctx.game.screen, self.fill_color, |
| 80 | (self.x, self.y, |
| 81 | self.w, self.h), |
| 82 | ) |
| 83 | # Содержит ли точку. |
| 84 | def contains_point(self, px, py): |
| 85 | x, y, w, h = self.x, self.y, self.w, self.h |
| 86 | return ( |
| 87 | py >= y and py <= (y + h) and |
| 88 | px >= x and px <= (x + w) |
| 89 | ) |
| 90 | def points(self): |
| 91 | x, y, w, h = self.x, self.y, self.w, self.h |
| 92 | return ((x, y), |
| 93 | (x + w, y), |
| 94 | (x + w, y + h), |
| 95 | (x, y + h)) |
| 96 | def intersects_with(self, other): |
| 97 | for point in other.points() : |
| 98 | if self.contains_point(point[0], point[1]) : |
| 99 | return True |
| 100 | for point in self.points() : |
| 101 | if other.contains_point(point[0], point[1]) : |
| 102 | return True |
| 103 | return False |
| 104 | |
| 105 | class Text(GameObject): |
| 106 | def __init__(self, text, |
| 107 | x=0, y=0, fontname=None, fontsize=72, |
| 108 | fill_color=(255, 255, 255)): |
| 109 | self.x = x |
| 110 | self.y = y |
| 111 | self.text = text |
| 112 | if not fontname : |
| 113 | fontname = pygame.font.get_default_font() |
| 114 | print('font:', fontname) |
| 115 | self.font = pygame.font.SysFont(fontname, fontsize) |
| 116 | self.fill_color = fill_color |
| 117 | def draw(self, ctx): |
| 118 | img = self.font.render(self.text, True, |
| 119 | self.fill_color) |
| 120 | ctx.game.screen.blit(img, (self.x, self.y)) |
| 121 | |
| 122 | |
| 123 | |
| 124 |
pong.py
· 3.5 KiB · Python
Raw
import game
import pygame
import random
# Объект платформы
class PlayerRect(game.Rect):
# ---------------
def __init__(self, up_key, down_key, vd=(0, 1), speed=200, **kwargs):
super().__init__(**kwargs)
self.speed = speed
self.up_key = up_key
self.down_key = down_key
# --------------
self.vd = vd
def update(self, ctx): # Поведение плафтормы за кадр
dt = ctx.dt
speed = self.speed
if ctx.keys[self.up_key] :
if self.x > 0 :
self.x -= dt * speed * self.vd[0]
if self.y > 0 :
self.y -= dt * speed * self.vd[1]
if ctx.keys[self.down_key] :
if (self.x + self.w) < ctx.game.resolution[0] :
self.x += dt * speed * self.vd[0]
if (self.y + self.h) < ctx.game.resolution[1] :
self.y += dt * speed * self.vd[1]
# Сам шар летающий
class BallRect(game.Rect):
# ------- dd
def __init__(self, dx=50, dy=50, dd=40, **kwargs):
super().__init__(**kwargs)
self.dx = dx
self.dy = dy
self.dd = dd
def update(self, ctx):
res = ctx.game.resolution
dt = ctx.dt
self.x += self.dx * dt
self.y += self.dy * dt
# Отталкивание от игроков
if (self.intersects_with(player_left) or
self.intersects_with(player_right) ):
self.dx *= -1
self.dy += random.randint(0, self.dd) - self.dd/2
if (self.intersects_with(player_top) or
self.intersects_with(player_bottom)) :
self.dy *= -1
self.dx += random.randint(0, self.dd) - self.dd/2
# Касание стен (проигрыш)
if self.x <= 0 or self.y <= 0:
counter.score -= 1
self.x, self.y = res[0]/2, res[1]/2
elif self.x+self.w >= res[0] or (self.y + self.h) >= res[1]:
counter.score += 1
self.x, self.y = res[0]/2, res[1]/2
class Counter(game.Text):
def __init__(self, **kwargs):
self.score = 0
super().__init__(str(self.score), **kwargs)
def update(self, ctx):
if self.score == 0 :
self.fill_color = (255, 255, 255)
self.text = str(self.score)
elif self.score > 0 :
self.fill_color = (255, 0, 0)
self.text = str(self.score)
else:
self.fill_color = (0, 0, 255)
self.text = str(-self.score)
g = game.Game()
player_width = 30
player_left = PlayerRect(pygame.K_w, pygame.K_s,
fill_color=(255, 0, 0), w=player_width)
player_right = PlayerRect(
pygame.K_UP, pygame.K_DOWN,
fill_color=(0, 0, 255), w=player_width)
player_right.x = g.resolution[0] - player_right.w
player_top = PlayerRect(
pygame.K_a, pygame.K_d,
fill_color=player_left.fill_color, h=player_width,
vd=(1, 0))
player_bottom = PlayerRect(
pygame.K_LEFT, pygame.K_RIGHT,
fill_color=player_right.fill_color, h=player_width,
vd=(1, 0))
player_bottom.y = g.resolution[1] - player_bottom.h
player_bottom.x = g.resolution[0] - player_bottom.w
ball_size = 30
ball_speed = 150
ball = BallRect(w=ball_size, h=ball_size, dx=ball_speed, dy=ball_speed)
ball.x = g.resolution[0] / 2 - 100
ball.y = g.resolution[1] / 2 - 100
counter = Counter(x=320, y=240)
g.objects = [player_left, player_right,
player_top, player_bottom, ball,
counter]
g.run()
| 1 | import game |
| 2 | import pygame |
| 3 | import random |
| 4 | |
| 5 | # Объект платформы |
| 6 | class PlayerRect(game.Rect): |
| 7 | # --------------- |
| 8 | def __init__(self, up_key, down_key, vd=(0, 1), speed=200, **kwargs): |
| 9 | super().__init__(**kwargs) |
| 10 | self.speed = speed |
| 11 | self.up_key = up_key |
| 12 | self.down_key = down_key |
| 13 | # -------------- |
| 14 | self.vd = vd |
| 15 | def update(self, ctx): # Поведение плафтормы за кадр |
| 16 | dt = ctx.dt |
| 17 | speed = self.speed |
| 18 | if ctx.keys[self.up_key] : |
| 19 | if self.x > 0 : |
| 20 | self.x -= dt * speed * self.vd[0] |
| 21 | if self.y > 0 : |
| 22 | self.y -= dt * speed * self.vd[1] |
| 23 | if ctx.keys[self.down_key] : |
| 24 | if (self.x + self.w) < ctx.game.resolution[0] : |
| 25 | self.x += dt * speed * self.vd[0] |
| 26 | if (self.y + self.h) < ctx.game.resolution[1] : |
| 27 | self.y += dt * speed * self.vd[1] |
| 28 | |
| 29 | # Сам шар летающий |
| 30 | class BallRect(game.Rect): |
| 31 | # ------- dd |
| 32 | def __init__(self, dx=50, dy=50, dd=40, **kwargs): |
| 33 | super().__init__(**kwargs) |
| 34 | self.dx = dx |
| 35 | self.dy = dy |
| 36 | self.dd = dd |
| 37 | def update(self, ctx): |
| 38 | res = ctx.game.resolution |
| 39 | dt = ctx.dt |
| 40 | self.x += self.dx * dt |
| 41 | self.y += self.dy * dt |
| 42 | # Отталкивание от игроков |
| 43 | if (self.intersects_with(player_left) or |
| 44 | self.intersects_with(player_right) ): |
| 45 | self.dx *= -1 |
| 46 | self.dy += random.randint(0, self.dd) - self.dd/2 |
| 47 | if (self.intersects_with(player_top) or |
| 48 | self.intersects_with(player_bottom)) : |
| 49 | self.dy *= -1 |
| 50 | self.dx += random.randint(0, self.dd) - self.dd/2 |
| 51 | |
| 52 | # Касание стен (проигрыш) |
| 53 | if self.x <= 0 or self.y <= 0: |
| 54 | counter.score -= 1 |
| 55 | self.x, self.y = res[0]/2, res[1]/2 |
| 56 | elif self.x+self.w >= res[0] or (self.y + self.h) >= res[1]: |
| 57 | counter.score += 1 |
| 58 | self.x, self.y = res[0]/2, res[1]/2 |
| 59 | |
| 60 | class Counter(game.Text): |
| 61 | def __init__(self, **kwargs): |
| 62 | self.score = 0 |
| 63 | super().__init__(str(self.score), **kwargs) |
| 64 | |
| 65 | def update(self, ctx): |
| 66 | if self.score == 0 : |
| 67 | self.fill_color = (255, 255, 255) |
| 68 | self.text = str(self.score) |
| 69 | elif self.score > 0 : |
| 70 | self.fill_color = (255, 0, 0) |
| 71 | self.text = str(self.score) |
| 72 | else: |
| 73 | self.fill_color = (0, 0, 255) |
| 74 | self.text = str(-self.score) |
| 75 | |
| 76 | |
| 77 | g = game.Game() |
| 78 | player_width = 30 |
| 79 | player_left = PlayerRect(pygame.K_w, pygame.K_s, |
| 80 | fill_color=(255, 0, 0), w=player_width) |
| 81 | player_right = PlayerRect( |
| 82 | pygame.K_UP, pygame.K_DOWN, |
| 83 | fill_color=(0, 0, 255), w=player_width) |
| 84 | player_right.x = g.resolution[0] - player_right.w |
| 85 | |
| 86 | player_top = PlayerRect( |
| 87 | pygame.K_a, pygame.K_d, |
| 88 | fill_color=player_left.fill_color, h=player_width, |
| 89 | vd=(1, 0)) |
| 90 | |
| 91 | player_bottom = PlayerRect( |
| 92 | pygame.K_LEFT, pygame.K_RIGHT, |
| 93 | fill_color=player_right.fill_color, h=player_width, |
| 94 | vd=(1, 0)) |
| 95 | player_bottom.y = g.resolution[1] - player_bottom.h |
| 96 | player_bottom.x = g.resolution[0] - player_bottom.w |
| 97 | ball_size = 30 |
| 98 | ball_speed = 150 |
| 99 | ball = BallRect(w=ball_size, h=ball_size, dx=ball_speed, dy=ball_speed) |
| 100 | ball.x = g.resolution[0] / 2 - 100 |
| 101 | ball.y = g.resolution[1] / 2 - 100 |
| 102 | counter = Counter(x=320, y=240) |
| 103 | g.objects = [player_left, player_right, |
| 104 | player_top, player_bottom, ball, |
| 105 | counter] |
| 106 | g.run() |
| 107 | |
| 108 |