Last active 1748091728

surdeus's Avatar surdeus revised this gist 1748091728. Go to revision

2 files changed, 230 insertions

game.py(file created)

@@ -0,0 +1,123 @@
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 +

pong.py(file created)

@@ -0,0 +1,107 @@
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 +
Newer Older