Программирование аркадных игр и обучение информатике

Программирование аркадных игр
и обучение информатике

Chapter 11: Растровая графика и звук

Для того, чтобы продвинуться дальше, чем рисование простых форм с помощью окружностей и прямоугольников, нашей программе требуется возможность работы с растровой графикой. Растровой графикой могут считаться фотографии или картинки, созданные и сохранённые в программе для рисования.

Одна лишь графика не сможет сделать игру атмосферной. Играм нужен звук! Здесь мы добавим звук в вашу игру.

11.1 Хранение программы в папке

Программы, рассмотренные до этого момента, представляли из себя лишь один .py файл. Добавляя картинки и звуки, появляется больше файлов, являющимися частями игры. Легко перемешать эти файлы с другими программами. Для предотвращения беспорядка будет правильным разместить более сложные программы в отдельные папки. Перед началом любого подобного проекта, щёлкните на кнопке “new folder” и используйте только что созданную папку как место размещения всех новых файлов.

fig.create_a_folder
Figure 11.1: Создание новой папки

11.2 Установка фонового изображения

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

fig.background_image
Figure 11.2: Фоновый Рисунок

Любая картинка, используемая в игре должна быть такого размера, каким ей нужно быть показанной на экране. Не пытайтесь загрузить картинку 5000х5000 пикселей из камеры с большим разрешением в окне 800х600. Используйте программу для редактирования графики (подойдёт даже MS Paint) и измените размер картинки перед её использованием.

Загрузка картинки - простой процесс, требующий только одну строку кода. В этой строке кода много чего происходит, так что её объяснение будет разбито на три части. Следующая строка загрузит файл saturn_family1.jpg. Этот файл должен быть расположен там же, где и ваша новая python программа, иначе компьютер не сможет его найти.

pygame.image.load("saturn_family1.jpg")

Загрузка картинки не означает её отображение. Для того, чтобы можно было использовать эту картинку позднее, нам нужно задать значение переменной равное тому, что вернёт команда load(). В этом случае, будет создана новая переменная background_image. Этот вариант показан ниже:

background_image = pygame.image.load("saturn_family1.jpg")

Наконец, изображение нужно конвертировать в формат, с которым Pygame сможет легко работать. Для этого, мы добавляем .convert() в конце команды для вызова соответствующей функции. Все картинки должны быть загружены используя этот шаблон, меняя лишь имя переменной и имя файла.

background_image=pygame.image.load("saturn_family1.jpg").convert()

Загрузка изображения должна быть произведена до основного игрового цикла. Хотя вполне возможно загрузить картинку во время главного игрового цикла, это заставит программу загружать картинку с диска примерно 20 раз в секунду. Это абсолютно не нужно. Картинку нужно загрузить лишь раз, в начале работы программы.

Для отображения картинки, программа использует команду blit(). Это “переносит” биты на экран. Мы однажды уже использовали эту команду для вывода текста на игровой экран.

После вызова команды blit, ей передаётся переменная, содержащая картинку, а также значения или переменная, содержащая начальную верхнюю левую кординату картинки. Эта команда должна быть вызвана внутри цикла, чтобы картинка перерисовывалась в каждом кадре:

screen.blit(background_image, [0,0])

Этот код переносит картинку, сохранённую в background_image на экран в координатах (0,0).

11.3 Передвижение картинки

Этот раздел описывает движение красного креста по экрану. Картинка может быть взята здесь:

fig.player_image
Figure 11.3: Player image

Для подготовки картинки, способной передвигаться по экрану с помощью мыши, потребуется та же самая команда, что и раньше:

player_image = pygame.image.load("player.png").convert()

Внутри главного цикла программы, достаются координаты мыши, а затем передаются в другую функцию blit как координаты для рисования картинки:

# Достать текущую позицию мыши.
# Это вернёт позицию как список из двух номеров.
player_position = pygame.mouse.get_pos()
x=player_position[0]
y=player_position[1]

# Скопировать картинку на экран:
screen.blit(player_image, [x,y])

Появляется проблема. Картинка, красный крест с белым фоном, рисутеся следующим образом:

fig.nontrans_background

Нам же нужен только красный крест. Хотя картинки являются прямоугольниками, нам иногда нужна абсолютно другая форма. Чтобы обойти это ограничение, нужно сказать программе, чтобы она считала один цвет “прозрачным”, таким образом не отображая его. Это можно сделать сразу же после загрузки. Следующий пример делает белый цвет (предполагая, что white уже задана как переменная) прозрачным:

player_image.set_colorkey(white)

Это сработает с большим количеством файлов с расширениями .gif и .png. Это не будет так хорошо работать с большинством .jpg файлов. Формат jpeg отлично подходит для хранения фотографий, но он незаметно меняет картинку для уменьшения её размера. Это значит, что не весь цвет фона будет одинаковым. Нижеприведённая картинка с красным крестом была сохранена как jpeg. Белый цвет вокруг креста - не совсем (255,255,255), а просто очень близок к белому.

fig.jpeg_artifacts
Figure 11.4: JPEG компрессия

11.4 Звуки

Этот раздел использует звук щелчка, который быть может скачан с помощью нажатия правой кнопки мыши здесь и выбора “save link as” (или “save target as”, в зависимости от того, как это пишется в вашем браузере)

Так же как и картинки, звуки должны быть загружены перед использованием. Это должно быть проделано только один раз, до главного цикла программы. Следующая команда загружает звуковой файл и создаёт переменную click_sound для того, чтобы ссылаться на него:

click_sound = pygame.mixer.Sound("click.wav")

Этот звук можно проиграть, когда пользователь нажимает на кнопку мыши, с помощью следующего кода:

for event in pygame.event.get():
	if event.type == pygame.QUIT:
		done=True
	if event.type == pygame.MOUSEBUTTONDOWN:
		click_sound.play()

Pygame не сможет проигрывать все .wav файлы, которые можно найти в интернете. Если бесплатная программа VLC Media Player не сможет проиграть звук, то не сможет это сделать и Pygame.

11.5 Полный код

"""
 Sample Python/Pygame Programs
 Simpson College Computer Science
 http://programarcadegames.com/
 http://simpson.edu/computer-science/

 Explanation video: http://youtu.be/4YqIKncMJNs
 Explanation video: http://youtu.be/ONAK8VZIcI4
 Explanation video: http://youtu.be/_6c4o41BIms
"""

import pygame

# Define some colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)

# Call this function so the Pygame library can initialize itself
pygame.init()

# Create an 800x600 sized screen
screen = pygame.display.set_mode([800, 600])

# This sets the name of the window
pygame.display.set_caption('CMSC 150 is cool')

clock = pygame.time.Clock()

# Before the loop, load the sounds:
click_sound = pygame.mixer.Sound("laser5.ogg")

# Set positions of graphics
background_position = [0, 0]

# Load and set up graphics.
background_image = pygame.image.load("saturn_family1.jpg").convert()
player_image = pygame.image.load("playerShip1_orange.png").convert()
player_image.set_colorkey(BLACK)

done = False

while not done:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
        elif event.type == pygame.MOUSEBUTTONDOWN:
            click_sound.play()

    # Copy image to screen:
    screen.blit(background_image, background_position)

    # Get the current mouse position. This returns the position
    # as a list of two numbers.
    player_position = pygame.mouse.get_pos()
    x = player_position[0]
    y = player_position[1]

    # Copy image to screen:
    screen.blit(player_image, [x, y])

    pygame.display.flip()

    clock.tick(60)

pygame.quit()

11.6 Проверка пройденного

Что выводит следующие Python программы?

  1. def f():
        return 10
    
    x=f()
    print (x)
    
  2. def f(x):
        x=x+10
        return x
    
    x=10
    f(x)
    print (x)
    
  3. def f(x):
        x=x+10
        return x
    
    def g(x):
        return x*2
    
    print ( f( g(10) ) )
    
  4. def f(x):
        x=x+10
        return x
    
    def g(x):
        return x*2
    
    print ( g( f(10) ) )
    
  5. def f(x,y):
        return x/y
    
    x=20
    y=5
    print ( f(y,x) )
    
  6. def f(x):
        return x*2
    
    def g(x):
        return x-2
    
    def h(x):
        return x+10
    
    print ( f(5) + g(f(5)) + h(g(10)) )
    print ( h(g(f(10))) )
    
  7. x=len( [2,3,[5,6],[7,9]]
    print (x)
    
  8. Напишите функцию, выводящую на экран “Hello”.
  9. Вызовите функцию из предыдущей задачи.
  10. Напишите функцию, берущую строку и считающую в ней количество пробелов.
  11. Напишите функцию, берущую массив и выводящую каждый отдельный элемент по очереди.
  12. Напишите функцию, берущую массив и возвращающую сумму его элементов.

You are not logged in. Log in here and track your progress.