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 |