Перечень используемых переменных



В данной программе используется большое количество переменных, среди которых часто встречаться однотипные, поэтому удобства они будут только те переменные, которые часто используются и играют значимую роль в программе.

· Переменные для инициализации геометрических параметров разных объектов

o PLATWIDTH – ширина платформы

o PLATHEIGHT – высота платформы

o RADIUS – радиус шарика

o BLOCKWIDTH - ширина блока

o BLOCKHEIGHT – высота блока

· Переменные для инициализации сопутствующих параметров разных объектов

o ball_loc_x – координата х для шарика

o ball_loc_у – координата у для шарика

o directionX – знак направления шарика по горизонтали

o directionY – знак направления шарика по вертикали

o direction – общее направление шарика (напрямую зависит от directionX и directionY)

o BALL_SPEED_X, BALL_SPEED_Y – скорости шарика по горизонтали и вертикали соответственно

o PLAT_SPEED – скорость платформы по горизонтали

· Переменные требуемые для механики игры

o score – количество очков, набранных игроком 

o life_num - число жизней игрока, которые расходуются при «потере шара»

3 Результат выполнения работы

Результатом выполнения работы является программа, выводящая окно (графический пользовательский интерфейс) (см. Рисунок 4 и Рисунок 5), на котором, с частотой 60 кадров в секунду, прорисовываются разные геометрические объекты поверх основного фона. Также данная программа способна принимать информацию от пользователя при помощи клавиатуры, то есть при помощи только одного нажатия/отжатия пользователь способен влиять на работу программы, а не как при помощи команды input () и т.п, где от пользователя требовалось вписать в определённое место определенную информацию и после этого нажать Enter.

 

 

1.

2.

3.

Вывод

Подводя итоги, при написании программы, которая позиционировалась как компьютерная игра с графическим пользовательским интерфейсом, были затронуты следующие темы, характерные при программировании компьютерных игр: геймплей, «игровой цикл», коллизии и прорисовка графических объектов. В свою очередь, освоение этих тем даёт программисту практику, которая в будущем даст фундамент для освоения более сложных тем в программировании.

 

Список литературы

1) Свейгарт Эл. Учим Python, делая крутые игры / Свейгарт Эл. – Москва: Бомбора, 2018. – 416 с.

 

 

Приложение 1

Код программы

 

import pygame, sys, random, time, math

from pygame.locals import *

 

# Установка pygame

pygame.init()

mainClock = pygame.time.Clock()

 

# Настройка окна и установка основных координат для позиционирования объектов

WINDOWWIDTH = 1200

WINDOWHEIGHT = 600

 

middle_x = WINDOWWIDTH // 2

middle_y = WINDOWHEIGHT // 2

 

windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), pygame.FULLSCREEN)

 

# Настройка цветов.

BLACK = (0, 0, 0)

GREEN = (0, 181, 54)

WHITE = (255, 255, 255)

GREY = (34, 58, 94)

YELLOW = (199, 190, 14)

RED = (240, 14, 14)

ORANGE = (240, 135, 14)

BLUE = (0, 0, 255)

 

# Создание переменных для платформы и её перемещения

 

PLATWIDTH = 230

PLATHEIGHT = 20

 

LocatXP = middle_x - (PLATWIDTH // 2)

LocatYP = WINDOWHEIGHT - PLATHEIGHT

 

moveLeftP = False

moveRightP = False

stopLeftP = False

stopRightP = False

 

platform = pygame.Rect(LocatXP, LocatYP, PLATWIDTH, PLATHEIGHT)

 

# Создание переменных перемещения.

moveLeft = False

moveRight = False

moveUp = False

moveDown = False

PLAT_SPEED = 12

 

# Создание псевдоблоков (rectangle) для шара, для его дальнейшей коллизии с остальными ообъектами

 

# координаты псевдокруга

ball_loc_x = 200

ball_loc_y = 50

 

ball = (ball_loc_x, ball_loc_y)

directionX = 1

directionY = 1

direction = 5

 

BALL_SPEED_X = PLAT_SPEED * 1 // 2 + 3

BALL_SPEED_Y = BALL_SPEED_X * 1 // 2 + 3

 

RADIUS = 15

num_ball_bloks = 30 # детализация псевдокруга

 

def cos_loc(angle):

rad_angle = math.radians(angle + 180)

x = int(math.cos(rad_angle + math.pi) * RADIUS)

return x

 

def sin_loc(angle):

rad_angle = math.radians(angle + 180)

y = int(math.sin(rad_angle + math.pi) * RADIUS)

return y

 

# Функция отображения текста

 

def drawText(text, font, surface, x, y):

textobj = font.render(text, 1, WHITE)

textrect = textobj.get_rect()

textrect.topleft = (x, y)

surface.blit(textobj, textrect)

 

# Настройка шрифта для выше описанной функции

font = pygame.font.SysFont(None, 35)

 

ball_blocks = []

color_list = [BLACK, GREEN, WHITE, GREY, YELLOW, RED, ORANGE, BLUE]

 

for i in range(num_ball_bloks + 1):

angle_block = 180 // num_ball_bloks

 

ball_block_x = ball_loc_x - sin_loc(angle_block * i)

ball_block_y = ball_loc_y - cos_loc(angle_block * i)

 

ball_blocks.append(

   {'rect': pygame.Rect(ball_block_x, ball_block_y, (sin_loc(angle_block * i)) * 2,

                        (cos_loc(angle_block * i)) * 2), 'color': WHITE})

 

ball_loc_x = ball_blocks[0]['rect'].centerx

ball_loc_y = ball_blocks[0]['rect'].centery

 

# Создание структуры данных для блоков

 

BLOCKWIDTH = 80

BLOCKHEIGHT = 50

BLOCKINTERVAL = 1

NUMBLOCKS = 10

ROWBLOCKS = 2

 

firstX = middle_x - (

   (BLOCKINTERVAL // 2) + ((NUMBLOCKS // 2 - 1) * BLOCKINTERVAL) + ((NUMBLOCKS // 2) * BLOCKWIDTH))

 

brick = []

 

for i in range(0, NUMBLOCKS):

presetLocat = firstX + ((BLOCKWIDTH + BLOCKINTERVAL) * i)

 

brick.append(

   {'rect': pygame.Rect(presetLocat, BLOCKINTERVAL + RADIUS + BLOCKHEIGHT * 0 + 60, BLOCKWIDTH, BLOCKHEIGHT),

    'color': RED,

    'strength': 3})

brick.append(

   {'rect': pygame.Rect(presetLocat + (BLOCKWIDTH // 2), BLOCKINTERVAL + RADIUS + BLOCKHEIGHT * 1 + 1 * 60 + 1,

                        BLOCKWIDTH,

                        BLOCKHEIGHT),

    'color': YELLOW, 'strength': 2})

brick.append(

   {'rect': pygame.Rect(presetLocat, BLOCKINTERVAL + RADIUS + BLOCKHEIGHT * 2 + 1 * 60 + 2, BLOCKWIDTH,

                        BLOCKHEIGHT),

    'color': GREEN,

    'strength': 1})

 

for i in range(0, 5):

brick.append(

   {'rect': pygame.Rect(60, 220 + (BLOCKHEIGHT + 1) * i, BLOCKWIDTH, BLOCKHEIGHT),

    'color': RED,

    'strength': 3})

 

for i in range(0, 5):

brick.append(

   {'rect': pygame.Rect(WINDOWWIDTH - 60 - BLOCKWIDTH, 220 + (BLOCKHEIGHT + 1) * i, BLOCKWIDTH, BLOCKHEIGHT),

    'color': RED,

    'strength': 3})

 

for i in range(0, 9):

presetLocat = firstX + ((BLOCKWIDTH + BLOCKINTERVAL) * i)

 

brick.append(

   {'rect': pygame.Rect(presetLocat + (BLOCKWIDTH // 2), BLOCKINTERVAL + RADIUS + BLOCKHEIGHT * 3 + 2 * 60 + 1,

                        BLOCKWIDTH,

                        BLOCKHEIGHT),

    'color': RED, 'strength': 3})

 

# Создание буфферных переменных

 

bufferP = PLAT_SPEED

bufferBX = BALL_SPEED_X

bufferBY = BALL_SPEED_Y

 

# Создание переменных для подсчитывания суммы очков и других игровых переменных

score = 0

life_num = 5

 

# Запуск игрового цикла.

while True:

# Проверка событий.

for event in pygame.event.get():

   if event.type == QUIT:

       pygame.quit()

       sys.exit()

 

   if event.type == KEYDOWN:

       # Изменение переменных клавиатуры.

 

       if event.key == K_p:

           PLAT_SPEED = 0

           BALL_SPEED_X = 0

           BALL_SPEED_Y = 0

 

       if event.key == K_o:

           PLAT_SPEED = bufferP

           BALL_SPEED_X = bufferBX

           BALL_SPEED_Y = bufferBY

 

       if event.key == K_q:

           ball_loc_x = 500

           ball_loc_y = 50

 

       if event.key == K_LEFT or event.key == K_a:

           moveRight = False

           moveLeft = True

 

       if event.key == K_RIGHT or event.key == K_d:

           moveLeft = False

           moveRight = True

 

       if direction == 5 and event.key == K_1:

           directionX = -1 * abs(directionX)

           BALL_SPEED_X = -bufferBX

           BALL_SPEED_Y = bufferBY

 

           direction = 4

 

       if direction == 5 and event.key == K_3:

           directionX = abs(directionX)

           BALL_SPEED_X = bufferBX

           BALL_SPEED_Y = bufferBY

 

           direction = 1

 

   if event.type == KEYUP:

 

       if event.key == K_ESCAPE:

           pygame.quit()

           sys.exit()

       # Изменение переменных клавиатуры

       if event.key == K_LEFT or event.key == K_a:

           moveLeft = False

       if event.key == K_RIGHT or event.key == K_d:

           moveRight = False

 

# Перемещение платформы

 

if moveLeft and platform.left > 0:

 

   # Проверка на заталкивание псевдошара в левую стенку

 

   if (platform.left - (2 * RADIUS + PLAT_SPEED) <= 0) and (platform.top <= ball_blocks[0]['rect'].centery) and (

           0 <= ball_blocks[0]['rect'].centerx <= platform.left):

 

       platform.left = platform.left

   else:

       platform.left -= PLAT_SPEED

 

if moveRight and platform.right < WINDOWWIDTH:

 

   # Проверка на заталкивание псевдошара в правую стенку

   if (platform.right + (2 * RADIUS + PLAT_SPEED) >= WINDOWWIDTH) and (

           platform.top <= ball_blocks[0]['rect'].centery) and (

           platform.right <= ball_blocks[0]['rect'].centerx <= WINDOWWIDTH):

 

       platform.right = platform.right

   else:

       platform.right += PLAT_SPEED

 

# Перемещение псевдошара

 

if life_num > 0:

 

   if direction == 1: # Шар летит вправо и вверх----------------------------------------

 

       ball_loc_x = ball_loc_x + BALL_SPEED_X * directionX

       ball_loc_y = ball_loc_y - BALL_SPEED_Y * directionY

 

   if direction == 2: # Шар летит вправо и вниз

 

       ball_loc_x = ball_loc_x + BALL_SPEED_X * directionX

       ball_loc_y = ball_loc_y + BALL_SPEED_Y * directionY

 

   if direction == 3: # Шар летит влево и вниз

 

       ball_loc_x = ball_loc_x - BALL_SPEED_X * directionX

       ball_loc_y = ball_loc_y + BALL_SPEED_Y * directionY

 

   if direction == 4: # Шар летит влево и вверх

 

       ball_loc_x = ball_loc_x - BALL_SPEED_X * directionX

       ball_loc_y = ball_loc_y - BALL_SPEED_Y * directionY

 

   if direction == 5: # Шар летит на платформе

 

       ball_loc_x = platform.centerx

       ball_loc_y = platform.top - RADIUS

       BALL_SPEED_X = 0

       BALL_SPEED_Y = 0

 

for i in ball_blocks:

   i['rect'].centerx = ball_loc_x

   i['rect'].centery = ball_loc_y

 

for i in ball_blocks:

 

   if i['rect'].centery - RADIUS <= 0: # верхняя стенка

       directionY = -directionY

       break

 

   if i['rect'].centerx - RADIUS <= 0 + 1: # левая стенка

       directionX = -directionX

       break

 

   if i['rect'].centerx + RADIUS >= WINDOWWIDTH - 1: # правая стенка

       directionX = -directionX

       break

       # Оканачание игры, если шар "провалися" в нижнюю стенку

 

   if i['rect'].bottom >= WINDOWHEIGHT + 2 * RADIUS:

 

       life_num = life_num - 1

 

       if life_num < 1:

 

           direction = 5

           life_num = 0

           break

 

       else:

           direction = 5

           break

 

for i in ball_blocks[:]:

   if platform.colliderect(i['rect']) and life_num > 0:

 

       # Проверка на соприкосновение псевдошара с правой частью платформы

 

       if ball_blocks[0]['rect'].centery + RADIUS >= platform.top:

           if platform.left <= ball_blocks[0]['rect'].centerx <= platform.right:

               if directionY == -1:

                   directionY = -directionY

                   score = score + 1

                   break

 

       # Проверка на соприкосновение псевдошара с правой частью платформы

 

       if platform.right >= ball_blocks[0]['rect'].centerx - RADIUS >= platform.centerx:

           if platform.top <= ball_blocks[0]['rect'].centery <= platform.bottom:

               if directionX == -1:

                   directionX = -directionX

                   score = score + 1

                   break

 

       # Проверка на соприкосновение псевдошара с левой частью платформы

 

       if platform.left <= ball_blocks[0]['rect'].centerx + RADIUS <= platform.centerx:

           if platform.top <= ball_blocks[0]['rect'].centery <= platform.bottom:

               if directionX == 1:

                   directionX = -directionX

                   score = score + 1

                   break

 

# Создание на поверхности фона.

windowSurface.fill(GREY)

 

# Отображение игрока на поверхности.

pygame.draw.rect(windowSurface, WHITE, platform)

drawText("Очки игрока: " + str(score), font, windowSurface, 20, 20)

drawText("Жизни игрока: " + str(life_num), font, windowSurface, 20, 45)

 

# Отображение всех псевдоблоков для псевдошара, для его дальнейшей коллизии с остальными ообъектами

 

for i in ball_blocks[:]:

   pygame.draw.rect(windowSurface, i['color'], i['rect'])

 

# Отображение группы блоков на поверхности

 

for b in brick:

   pygame.draw.rect(windowSurface, b['color'], b['rect'])

 

if direction == 5:

   if life_num == 0:

 

       phrase1 = "Вы проиграли!!!"

       fontWIN = pygame.font.SysFont(None, 100)

       textobj = fontWIN.render(phrase1, 3, WHITE)

       textrect = textobj.get_rect()

       textrect.centerx = WINDOWWIDTH // 2

       textrect.centery = WINDOWHEIGHT // 2

       windowSurface.blit(textobj, textrect)

 

         PLAT_SPEED = 0

       BALL_SPEED_X = 0

       BALL_SPEED_Y = 0

 

   else:

 

       phrase = "1 - шар полетит влево, 3 - шар полетит вправо"

       drawText(phrase, font, windowSurface, WINDOWWIDTH - 570, 20)

 

# Проверка на столкновение псевдошара с блоками

 

# Функция для проверки на столкновение сверху и снизу блока

def BlockClashUpDown(directionY, score, b):

 

   if b['strength'] > 3:

       b['strength'] = b['strength'] - 1

       directionY = -directionY

       return directionY, score

 

   if b['strength'] == 3:

       b['strength'] = 2

       b['color'] = YELLOW

       directionY = -directionY

       score = score + 3

       return directionY, score

 

   if b['strength'] == 2:

       b['strength'] = 1

       b['color'] = GREEN

       directionY = -directionY

       score = score + 2

       return directionY, score

 

   if b['strength'] == 1:

       directionY = -directionY

       brick.remove(b)

       score = score + 1

       return directionY, score

 

# Функция для проверки на столкновение слева и справа блока

def BlockClashLeftRight(directionX, score, b):

 

   if b['strength'] > 3:

       b['strength'] = b['strength'] - 1

       directionX = -directionX

       return directionX, score

 

   if b['strength'] == 3:

       b['strength'] = 2

       b['color'] = YELLOW

       directionX = -directionX

       score = score + 3

       return directionX, score

 

   if b['strength'] == 2:

       b['strength'] = 1

       b['color'] = GREEN

       directionX = -directionX

       score = score + 2

       return directionX, score

 

   if b['strength'] == 1:

       directionX = -directionX

       brick.remove(b)

       score = score + 1

       return directionX, score

 

if len(brick) == 0:

 

   PLAT_SPEED = 0

   BALL_SPEED_X = 0

   BALL_SPEED_Y = 0

 

   # Настройка текста сообщения победы по центру

 

   phrase1 = "Вы выиграли!!!"

   fontWIN = pygame.font.SysFont(None, 100)

   textobj = fontWIN.render(phrase1, 3, WHITE)

   textrect = textobj.get_rect()

   textrect.centerx = WINDOWWIDTH // 2

   textrect.centery = WINDOWHEIGHT // 2

   windowSurface.blit(textobj, textrect)

 

else:

   for b in brick[:]:

       for i in ball_blocks[:]:

           if i['rect'].colliderect(b['rect']): # Проверка на факт столкновения

 

               # Если псевдошар коснулся верхней стороны блока

               if (b['rect'].left <= ball_blocks[0]['rect'].centerx <= b['rect'].right) and (

                       b['rect'].top <= ball_blocks[0]['rect'].centery <= b['rect'].centery - 1):

                   BlockdataY = BlockClashUpDown(directionY, score, b)

                   directionY = BlockdataY[0]

                   score = BlockdataY[1]

                   break

 

               # Если псевдошар коснулся нижней стороны блока

               if (b['rect'].left <= ball_blocks[0]['rect'].centerx <= b['rect'].right) and (

                       b['rect'].bottom <= ball_blocks[0]['rect'].centery >= b['rect'].bottom - 1) and (

                       directionY == 1):

                   BlockdataY = BlockClashUpDown(directionY, score, b)

                   directionY = BlockdataY[0]

                   score = BlockdataY[1]

                   break

 

               # Если псевдошар коснулся правой стороны блока

               if (b['rect'].right >= ball_blocks[0]['rect'].centerx - RADIUS >= b['rect'].centerx) and (

                       b['rect'].top <= ball_blocks[0]['rect'].centery <= b['rect'].bottom) and (

                       directionX == -1):

                   BlockdataX = BlockClashLeftRight(directionX, score, b)

                   directionX = BlockdataX[0]

                   score = BlockdataX[1]

                   break

 

               # Если псевдошар коснулся левой стороны блока

               if (b['rect'].left <= ball_blocks[0]['rect'].centerx + RADIUS <= b['rect'].centerx) and (

                       b['rect'].top <= ball_blocks[0]['rect'].centery <= b['rect'].bottom) and (

                       directionX == 1):

                   BlockdataX = BlockClashLeftRight(directionX, score, b)

                   directionX = BlockdataX[0]

                   score = BlockdataX[1]

                   break

 

               # Если псевдошар коснулся угла блока

               else:

 

                   b['strength'] = b['strength'] - 1

 

                   if b['strength'] == 2:

                       b['color'] = YELLOW

                       directionX = -directionX

                       directionY = -directionY

                       break

 

                   elif b['strength'] == 1:

                       b['color'] = GREEN

                       directionX = -directionX

                       directionY = -directionY

                       break

 

                   elif b['strength'] == 0:

                       brick.remove(b)

                       directionX = -directionX

                       directionY = -directionY

                       break

 

# Вывод окна на экран.

pygame.display.update()

mainClock.tick(60)

 

 

   

 


Дата добавления: 2020-11-15; просмотров: 99; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!