Last active 1748084376

game.py Raw
1import pygame
2pygame.init()
3
4class 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
16class 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
54class GameObject:
55 def update(self, ctx):
56 pass
57 def draw(self, ctx):
58 pass
59# Rectangle - прямоугольник
60class 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
105class 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, self.fill_color)
119 ctx.game.screen.blit(img, (self.x, self.y))
120
121
122
123
pong.py Raw
1import game
2import pygame
3import random
4
5# Объект платформы
6class 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 # ---------------- Весь блок движения
19 if ctx.keys[self.up_key] :
20 if self.x > 0 :
21 self.x -= dt * speed * self.vd[0]
22 if self.y > 0 :
23 self.y -= dt * speed * self.vd[1]
24 if ctx.keys[self.down_key] :
25 if (self.x + self.w) < ctx.game.resolution[0] :
26 self.x += dt * speed * self.vd[0]
27 if (self.y + self.h) < ctx.game.resolution[1] :
28 self.y += dt * speed * self.vd[1]
29
30# Сам шар летающий
31class BallRect(game.Rect):
32 # ------- dd
33 def __init__(self, dx=50, dy=50, dd=40, **kwargs):
34 super().__init__(**kwargs)
35 self.dx = dx
36 self.dy = dy
37 self.dd = dd
38 def update(self, ctx):
39 res = ctx.game.resolution
40 dt = ctx.dt
41 self.x += self.dx * dt
42 self.y += self.dy * dt
43
44 # Отталкивание от игроков
45 if (self.intersects_with(player_left) or
46 self.intersects_with(player_right) ):
47 self.dx *= -1
48 self.dy += random.randint(0, self.dd) - self.dd/2
49 if (self.intersects_with(player_top) or
50 self.intersects_with(player_bottom)) :
51 self.dy *= -1
52 self.dx += random.randint(0, self.dd) - self.dd/2
53
54 # Касание стен (проигрыш)
55 if (self.x <= 0 or self.x+self.w >= res[0] or
56 self.y <= 0 or (self.y + self.h) >= res[1]):
57 self.x, self.y = res[0]/2, res[1]/2
58g = game.Game()
59player_width = 30
60player_left = PlayerRect(pygame.K_w, pygame.K_s,
61 fill_color=(255, 0, 0), w=player_width)
62player_right = PlayerRect(
63 pygame.K_UP, pygame.K_DOWN,
64 fill_color=(0, 0, 255), w=player_width)
65player_right.x = g.resolution[0] - player_right.w
66
67player_top = PlayerRect(
68 pygame.K_a, pygame.K_d,
69 fill_color=player_left.fill_color, h=player_width,
70 vd=(1, 0))
71
72player_bottom = PlayerRect(
73 pygame.K_LEFT, pygame.K_RIGHT,
74 fill_color=player_right.fill_color, h=player_width,
75 vd=(1, 0))
76player_bottom.y = g.resolution[1] - player_bottom.h
77player_bottom.x = g.resolution[0] - player_bottom.w
78ball_size = 30
79ball_speed = 150
80ball = BallRect(w=ball_size, h=ball_size, dx=ball_speed, dy=ball_speed)
81ball.x = g.resolution[0] / 2 - 100
82ball.y = g.resolution[1] / 2 - 100
83g.objects = [player_left, player_right,
84 player_top, player_bottom, ball,
85 game.Text("Hello, Pong!", x=300, y=300)]
86g.run()
87
88