Last active 1748091728

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,
119 self.fill_color)
120 ctx.game.screen.blit(img, (self.x, self.y))
121
122
123
124
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 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# Сам шар летающий
30class 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
60class 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
77g = game.Game()
78player_width = 30
79player_left = PlayerRect(pygame.K_w, pygame.K_s,
80 fill_color=(255, 0, 0), w=player_width)
81player_right = PlayerRect(
82 pygame.K_UP, pygame.K_DOWN,
83 fill_color=(0, 0, 255), w=player_width)
84player_right.x = g.resolution[0] - player_right.w
85
86player_top = PlayerRect(
87 pygame.K_a, pygame.K_d,
88 fill_color=player_left.fill_color, h=player_width,
89 vd=(1, 0))
90
91player_bottom = PlayerRect(
92 pygame.K_LEFT, pygame.K_RIGHT,
93 fill_color=player_right.fill_color, h=player_width,
94 vd=(1, 0))
95player_bottom.y = g.resolution[1] - player_bottom.h
96player_bottom.x = g.resolution[0] - player_bottom.w
97ball_size = 30
98ball_speed = 150
99ball = BallRect(w=ball_size, h=ball_size, dx=ball_speed, dy=ball_speed)
100ball.x = g.resolution[0] / 2 - 100
101ball.y = g.resolution[1] / 2 - 100
102counter = Counter(x=320, y=240)
103g.objects = [player_left, player_right,
104 player_top, player_bottom, ball,
105 counter]
106g.run()
107
108