Рубрики
Без рубрики

Начало работы с Pygame, создавая игру змеи

Вступление и настройка Да, я знаю, еще одна игра змеи … Но я хотел познакомить вас с … Tagged с Python, Gamedev, Tulciory, Programming.

Да, я знаю, еще одна игра змеи … Но я хотел познакомить вас с пигама , забавный маленький модуль, способный сделать простые и веселые 2D -игры в Python, так что я здесь …

Чтобы начать, вы должны установить Python и PIP на вашу систему, Вы можете получить больше информации в Здесь Чтобы убедиться, что Python установлен, на терминале, бежать

# check if python is installed
python --version

#check if pip is installed
pip --version

Если вы получите что -то взамен, это означает, что вы успешны 🎉🎉 🎉 … Теперь пришло время установить pygame, просто запустите

pip install pygame

Если вы столкнулись с какими -либо проблемами, вы можете проверить это страница

В качестве альтернативы, если вы не хотите проходить всю эту настройку, вы можете использовать Repl.it, у него есть онлайн -компилятор Pygame, который вы можете использовать Проверьте это здесь

Мы, наконец, можем начать писать какой -то код, вы можете использовать любую вашу любимую IDE … VSCODE, Sublime, Atom, Pycharm, Crackets и т. Д. Это не имеет значения ╮ (╯3╰) ╭ …

Просто сделайте новый файл Python в любом каталоге и назовите его все, что вы хотите 👍 … Первая работа будет заключаться в том, чтобы импортировать Pygame и инициализацию нашего игрового окна

import sys,random
import pygame 

# initialize pygame 
pygame.init()

# constants that store our screen width and height ,
# they are in pixels
WIN_X = 800
WIN_Y = 600

# setting up our game window in pygame with 
# our screen width and height constants as tuple
WIN = pygame.display.set_mode((WIN_X,WIN_Y))

# setting the caption of our game
# or more precisely the label that
# you will see on the game window

pygame.display.set_caption('snake game')

Давайте обсудим код выше,

  • Мы импортируем Pygame и некоторые другие локальные модули, а затем используем метод init в Pygame, чтобы начать нашу игру или запустить Pygame
  • Мы делаем две переменные или константы, Win_x и Win_y, чтобы сохранить наши размеры экрана или ширину экрана и высоту экрана, (📝 Причина, по которой мы нуждаемся в том, что Pygame создает игровое окно, и нам нужно объявить ширину и высоту, вы можете выбрать любую ширину и высоту, я выбираю 800×600)

  • Далее мы настроили наше игровое окно или говорим Pygame инициализировать нашу игру с pygame.display.set_mode () Метод прохождения в наших размерах экрана в кортеже

  • В конце концов, я только что настроил подпись или этикетку для окна игры, используя pygame.display.set_caption () Метод прохождения в строке подписи, вы можете передать любую строку, которую вы хотите здесь 👍 …

Теперь, если вы запустите этот код, вы увидите экран игры на короткое время, а затем он выходит из программы … Можете ли вы догадаться, почему это происходит, потому что мы не определили ни одного игрового цикла … Игровая петля – это просто бесконечный цикл, который продолжается навсегда, пока пользователь выходит или не закроет его … Поскольку мы не определили ни одного игрового петля, окно было видно на мгновение, но затем программа закончилась, и поэтому игра игры также исчез …

Давайте продолжим и внедрим нашу игру

#importing modules
import sys,random
import pygame 

pygame.init()

WIN_X = 800
WIN_Y = 600

WIN = pygame.display.set_mode((WIN_X,WIN_Y))

pygame.display.set_caption('snake game')

#initializing pygame.time.Clock() which controls
#The FPS or frame per second or more explicitly
#For how many times per second our game loop 
#below should run
CLOCK = pygame.time.Clock()

#our infinite game loop
while 1:
   #checking for events in pygame.event.get() which
   #returns the event that occurs like 
   #any key presses or user clicking the
   #exit , maximize , minimize button
   for event in pygame.event.get():
        #here we are checking if user has clicked the exit button
        #by checking if the event.type is pygame.QUIT 
        #which is predefined in pygame as the exit button
        if event.type == pygame.QUIT:
            #if user clicked the exit button , quit the game
            #and exit out of the program
            pygame.quit()
            sys.exit()

        #using CLOCK variable mentioned above and using
        #tick method on it passing in the fps
        #this means that this loop will run 
        #25 times per second, 
        #feel free to change the value
        CLOCK.tick(25)

Теперь, если вы запустите программу, окно останется до тех пор, пока вы не нажмете кнопку выхода, поздравляете, если вы сможете следить за этим 👍 …

📝 В вышесказанном я только что написал простой бесконечный, в то время как петля, Затем я написал еще один для цикла, который проверяет такие события, как клик мыши, Hover и другие, (метод pygame.event.get () Возвращает события, которые происходят в настоящее время, там я проверяю, если .type равен событиям Pygame. Выйти или, другими словами, пользователь нажал кнопку «Крест», если это правда, бросьте программу, иначе продолжайте запускать …)

Вы также могли бы увидеть переменную часа, которую я объявил, она просто инициализирует pygame.time. Часы () И используя его, в цикле Whice я использовал Clock.tick (25) , что просто говорит Pygame запустить цикл while 25 раз в секунду, вы можете изменить число ╮ (╯3╰) ╭ …

Теперь пришло время спланировать нашу основную игровую логику,

Итак, у нас будут эти 3 функции, Главный , main_menu В Game_over , они представляют разные сцены нашей игры, пока мы сосредоточимся только на основной функции или основной игровой логике …

Итак, прежде всего, как мы будем делать и перемещать нашу змею 🤔, это первая и самая очевидная вещь, которую нужно делать …

  • Что ж, наша змея будет квадратной 🟨, я имею в виду коллекцию квадратов, и всякий раз, когда он может съесть еду, Количество квадратов в теле змей увеличится

Теперь, как мы будем хранить эти квадраты, и как мы будем отслеживать положение квадрата …

  • Чтобы сохранить квадраты тела змеи, структура данных, которая входит в мой разум,-это список, поэтому мы можем создать список тела змеи, и для каждого элемента этого списка мы будем оценить квадратный форма…
  • Теперь сами квадраты станут списком, потому что в пигаме нарисовать прямоугольник или квадрат, нам понадобится его координата x, y координата И это ширина И это высота …
  • Теперь, что касается позиции змеи, мы могли бы ввести еще один список, в котором будут содержать координату x и y, скажем, это [100,50], а затем мы увеличим или уменьшаем ее по скорости змеи в игре …
  • Нам также понадобится переменная направления, чтобы отслеживать, если змея движется вверх, вниз, влево или вправо …
  • Отнесее отметить, что список Snake POS будет перемещен к списку тела змеи после каждого раунда петли, и мы будем выставлять первый элемент в списке тела змеи после каждого раунда в цикле, причина, по которой мы это делаем Будет ясно, как только мы начнем его реализовать, Snake POS также поможет нам отслеживать, куда идет змея, поэтому, если змея попадет в границы, или съесть фрукты, мы можем это знать, а также изменить направление змеи..

  • Теперь, когда пользователь щелкнет W, змея поднимется, чтобы змея уходит влево, D для справа и для S для Down, вы можете изменить эти элементы управления или представить новые элементы управления, если хотите …

  • Для фруктов мы создадим один квадрат, который будет выглядеть как фрукты, вы также можете использовать изображения, если хотите … Мы случайным образом появимся на экране, используя случайный модуль, используя случайный модуль …

📝 Для змеи я мог бы создать класс змей, и для фруктов я мог бы создать класс фруктов, а также я мог бы создать класс игровых объектов, от которого все игровые объекты будут наследовать, но для простоты я не собираюсь этого делать Вместо этого я просто храню их в соответствующих переменных …

Мы можем начать реализовывать логику, обсуждаемую выше, во -первых, давайте начнем создавать нашу основную функцию, я собираюсь изменить туда игровой цикл там

import sys, random
import pygame

pygame.init()

WIN_X = 800
WIN_Y = 600
WIN = pygame.display.set_mode((WIN_X,WIN_Y))
pygame.display.set_caption('snake game')

#main function
def main():
    CLOCK = pygame.time.Clock()
    #variable to store snake position , default when starting is [200,70],
    #Feel free to change
    snake_pos=[200,70]

    #snake body is going to be a 2d list or matrix storing snakes full body
    #here by default, the snake is going to be 3 squares long
    #individual square in this list contains the x and y coordinate
    #of the square itself
    snake_body=[[200,70] , [200-10 , 70] , [200-(2*10),70]]

    #direction of the snake , default is 'right'
    direction = 'right'
    #score of the snake
    score=0

    CLOCK = pygame.time.Clock()
    #game loop
    while 1:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
        #filling the window with black color , the (0,0,0)
        #here represents black in rgb , 
        #we are filling the screen for background
        #withouth this your game will act glitchy
        #feel free to change the color
        WIN.fill((0,0,0))

        #for loop that goes through the snake_body
        for square in snake_body:
            #rendering the square of the snake using
            #pygame.draw.rect
            #here the first argument is the surface where
            #YOU wanna draw, in our case, it's the 
            #WIN surface defined above
            #The second argument is the color of the rectangle
            # I chose yellow, feel free to change,
            # color must be RGB
            #third argument is the pos or where to place the rect
            #It takes a tuple with an x coordinate as the first argument
            #AND y coordinate as 2nd argumenT
            #width as 3rd argument and height as 
            #4th argument
            pygame.draw.rect(WIN ,(255, 255, 0), (square[0],square[1],10,10))


        #updating the display with pygame.display.update()
        #withouth this , you wouldn't see anything on the screen
        #You should write all your rendering logic or code
        #that renders things to screen before this line
        pygame.display.update()
        CLOCK.tick(25)

#caliing the main function
main()

Здесь я только что перевел свой код на основную функцию, сделал переменную Snake_body и Snake_pos, в петле игры я отобрал змею, прочитайте комментарии, если вы не можете понять, код должен быть самоэкспланирующим (━☞◔ ‿ ゝ ◔) ━☞,

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

Поэтому, когда мы говорим 20 на x, 10 на Y в Pygame, это означает, что выпейте 20 вправо с самого верхнего левого угла и 10 вниз сверху. Если вы запустите код, вы должны увидеть что -то подобное

Что ж, мы можем видеть змею, так что это отличная новость, но змея не движется, это просто статичная змея на экране, ну, это скучно 🥱, Давайте заставим его двигаться 🙌. В конце основной функции, прежде чем мы запустим pygame.display.update () Добавить следующий код

 #remember the direction variable declared at the start
        #of main function , we are checking if direction is
        #up,down,right or left
        if direction == 'right':
            #if direction is right , add 10 to x coordinate
            #of snake_pos , adding to x coordinate makes things
            #move right
            snake_pos[0] += 10
        elif direction == 'left':
            #if direction is left, deduct 10 from x coordinate
            #of snake_pos , deducting from x coordinate 
            #makes things move left
            snake_pos[0] -= 10
        elif direction == 'up':
            #if direction is up, add 10 to y coordinate
            #of snake_pos , adding to y coordinate 
            #makes things move up
            snake_pos[1] -= 10
        elif direction == 'down':
            #if direction is down, deduct 10 from y coordinate
            #of snake_pos , deducting from y coordinate 
            #makes things move down
            snake_pos[1] += 10

Если вы запускаете код сейчас, абсолютно ничего не произойдет, змея не движется (º﹃º), почему это так? Потому что мы рендерировали квадраты в smake_body , мы не визуаливы snake_pos , и здесь мы корректируем smake_pos

Так что же делать сейчас, чтобы заставить змею двигаться, мы можем вставить наше snake_pos К началу списка давайте посмотрим, что произойдет, ниже кода, где мы проверяем указания и перед pygame.display.update () Добавить это

#appending snake_pos to snake_body
#make sure to convert snake_pos
#explicitly to list or else 
#it won't work
snake_body.append(list(snake_pos))

Теперь, если вы запустите программу, вы увидите что -то подобное,

Змея продолжает расти бесконечно, но мы хотим, чтобы наша змея вырастила только после того, как он ест фрукты, мы должны это исправить …

Но почему это ведет себя таким образом 🤔, ну, мы добавляем snake_pos к smake_body , но не удаляя старые квадраты из Snake_body, так что он растет бесконечно, одна вещь, которую мы можем сделать, это удалить самый старый квадрат, удалив первый элемент из списка,

Под кодом, где мы добавляем snake_pos к smake_body , добавить следующее

#remove the first element from snake_body
snake_body.pop(0)

Теперь вы должны увидеть что -то подобное

Так что наша змея движется наконец, но она только движется правильно, ну, это не то, что мы хотим, давайте добавим некоторые элементы управления

        #The for loop where we check for events
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            #here , we are storing pygame.key_pressed() in 
            #keys variable , pygame.key_pressed() returns what key
            #The user has pressed and we can check that below 
            keys= pygame.key.get_pressed()

            #Now in keys , we check if pygame.K_w is true
            #what does that mean
            #well pygame.K_w represents w in pygame
            #and pygame.K_UP represents the up arrow key
            #if keys[pygame.K_w] or keys[pygame.K_UP] 
            #returns true or in other words if the
            #user has clicked the w key or up arrow
            #we change direction to up
            #we then also check clicks on s,a,d,down
            #arrow key,left arrow key and change
            #the direction accordingly
            if (keys[pygame.K_w] or keys[pygame.K_UP]):
                direction = 'up'
            if (keys[pygame.K_s] or keys[pygame.K_DOWN]):
                direction = 'down'
            if (keys[pygame.K_d] or keys[pygame.K_RIGHT]):
                direction = 'right'
            if (keys[pygame.K_a] or keys[pygame.K_LEFT]):
                direction = 'left'

Если вы запускаете код сейчас, вы должны увидеть что -то подобное

Итак, мы заставили нашу змею двигаться, теперь одна вещь, которую я хотел бы сразу же починить, это то, что змея движется мгновенно 💨 …

Что я имею в виду под этим, ну, если змея поднимается, то когда мы нажимаем кнопку стрелки или S, змея проходит через свое тело очень странным образом, что не должно случиться, то же самое происходит, когда змея в слева и змее уходит направо или змея вниз, и змея поднимается, позвольте мне показать вам, что я имею в виду 🙃

Увидил это правильно, к счастью, у него легко исправить 🎊, когда мы меняем направление змеи, мы можем проверить, находится ли змея в противоположном направлении

Предположим, что направление змеи истекло, пользователь хочет сейчас спуститься, но змея поднимается, и мы не хотим немало мгновенного движения, поэтому мы не пойдем вниз

Место, где мы меняем направление в цикле, изменить проверку на это

            #preventing instanteous movement
            #here we are checking if user and wants to
            #to go up , but snake's direction is not
            #'down' which is opposite of up , change
            #the direction
            if (keys[pygame.K_w] or keys[pygame.K_UP]) and direction != 'down':
                direction = 'up'
            if (keys[pygame.K_s] or keys[pygame.K_DOWN]) and direction != 'up':
                direction = 'down'
            if (keys[pygame.K_d] or keys[pygame.K_RIGHT]) and direction != 'left':
                direction = 'right'
            if (keys[pygame.K_a] or keys[pygame.K_LEFT]) and direction != 'right':
                direction = 'left'

При этом ошибка исправляется 👍.

Но теперь змея может пройти через границы нашего экрана и продолжать бесконечно …

Что ж, мы можем выйти из нашего приложения, если змея попадет в границы окна, позже мы представим сцену Game_Over и Main_Menu …

В конце игровой петли, добавьте это

        #checking if x coordinate of snaake is smaller than 0,
        #if that's true , than snake has crossed left side
        #of screen , we also check if snakes x coordinate is 
        #greater than our screen , if that happens , snake
        #has crossed right side of the screen ,
        if snake_pos[0] <=0 or snake_pos[0] >= WIN_X:
            sys.exit()

        #checking if y coordinate of snake is smaller than 0,
        #if that's true than the snake has crossed the upper side
        #of the screen, we also check if snakes y coordinate is 
        #greater than our screens y coordinate,
        #if that happens, snake
        #has crossed the lower side of the screen,
        if snake_pos[1] <=0 or snake_pos[1] >= WIN_Y:
            sys.exit()

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

        if snake_pos[0]+10 <=0 or snake_pos[0] >= WIN_X:
            sys.exit()
        if snake_pos[1]+10 <=0 or snake_pos[1] >= WIN_Y:
            sys.exit()

намного лучше …

Теперь добавим несколько винограда 🤤

  • Для винограда мы можем сделать две переменные Fruit_pos и Fruit_spawn
  • Fruit_pos Будет POS о виноградном или фруктах, он будет расположен случайным образом на экране …
  • Далее у нас есть Fruit_spawn который проверяет, если должны быть получены новые фрукты , по умолчанию это будет правда …

В начале основной функции, перед игрой, добавьте это

    fruit_pos = [0,0]
    fruit_spawn = True

Затем в петле игры, перед pygame.display.update (), добавьте эту строку

#generating a random position for the grape
#for the x coordinate its going to be from
#range 40 to screen_width-40 
#i am not starting from 0 as the grape  can
#be very close to the boundaries then
#same logic for y coordinate
fruit_pos = [random.randrange(40,WIN_X-40),random.randrange(40,WIN_Y-40)]

#Drawing the fruit to the screen using 
#pygame.draw.rect()
pygame.draw.rect(WIN ,(138,43,226),(fruit_pos[0],fruit_pos[1],10,10))

Здесь мы генерируем случайную позицию для винограда и рисуем прямое 10×10. Если вы запускаете код сейчас, он должен выглядеть примерно так

Что ж, это как бы продолжает генерировать виноград и вообще не останавливаться, причина, по которой это происходит, в том, что в каждом раунде в цикле мы меняем Fruit_pos и рендеринг (º﹃º), …

Чтобы исправить это, мы можем использовать наш Fruit_spawn переменная, которая была установлена на истинность изначально

Место, где мы написали нашу логику нереста винограда, вырезали это и используем это

        #if fruit spawn is true , change fruit_pos
        #and make fruit_spawn false
        if fruit_spawn:
            fruit_pos = [random.randrange(40,WIN_X-40),random.randrange(40,WIN_Y-40)]
            fruit_spawn = False
        pygame.draw.rect(WIN ,(138,43,226),(fruit_pos[0],fruit_pos[1],10,10))

Теперь, если вы заметите только один фрукт, вы увидите, что у нас есть только один фрукт, мы просто меняем его положение

Но змея все еще не может съесть фрукты, давайте добавим это

В петле игры, до pygame.display.update () , Добавь это

        if pygame.Rect(snake_pos[0],snake_pos[1],10,10).colliderect(pygame.Rect(fruit_pos[0],fruit_pos[1],10,10)):
            fruit_spawn=True
            score += 5

Позвольте мне прямо описать, что я сделал, а не комментировал 🙃 …

Ну, я проверяю, если snake_pos Сталкивается с Fruit_pos

Теперь, как я сделал, это выглядит странно 🥴, так что позвольте мне объяснить, что 👍

  • В Pygame у нас есть такая вещь, называемая Прямо , Больше информации здесь
  • ПРЕРТЫ Сделайте обнаружение столкновения легко, вы также можете использовать Прямо На изображениях любой прямоугольный объект работает, он также может быть круглым ..
  • Теперь, чтобы сделать Прямо , мы должны использовать Пигама. Rect () метод

  • Мы должны пройти в координате X в качестве первого аргумента, y координируется как 2 -й аргумент, а также ширина и высота как 3 -й и 4 -й аргумент соответственно

  • В нашем случае мы сначала передаем координату змей x, координата Y, ширина и высота

  • Теперь ПРЕРТЫ Иметь много методов, один – это Colliderect () , Этот метод занимает еще один Пигама. Rect () как аргумент и проверяет, если они двое сталкиваются друг с другом

  • В нашем случае мы проходим Fruit_pos преобразование как Прямо к коллайдер метод

  • Если это вернулось истинно, Fruit_spawn будет правдой, поэтому будут получены новые фрукты, и оценка будет увеличена … С этим, вы должны увидеть что -то подобное

Но наша змея не растет, почему это так, как мы можем заставить его расти?

Ну, помните, что мы всегда удаляли первый элемент из smake_body После того, как мы добавим snake_pos к smake_body

Что если мы удалим первый элемент в списке только тогда, когда змея не может съесть виноград, если змея сталкивается с Прямо , мы не удаляем первый элемент из smake_body 😮

Место, где мы удаляем первый элемент из smake_body , отрежьте эту часть, затем получили часть, где мы проверяем столкновение между фруктами и змеей, измените ее на это

        if pygame.Rect(snake_pos[0],snake_pos[1],10,10).colliderect(pygame.Rect(fruit_pos[0],fruit_pos[1],10,10)):
            fruit_spawn=True
            score += 5
        else:
            snake_body.pop(0)

И теперь змея начнет расти, Но почему это работает 🤔, Когда мы впервые начинаем нашу игру, smake_body должен быть таким

snake_body=[[200,70] , [190 , 70] , [180,70]]

В игре мы добавляем snake_pos к этому и удалить первый элемент Тогда это должно быть что -то вроде этого

snake_body=[[190, 70], [180, 70], [210, 70]]

Здесь змея длиной 3 квадрата, Что произойдет, если мы не удалим первый элемент в следующий раз

snake_body=[[190, 70], [180, 70], [210, 70], [220, 70]]

Змея длиной 4 квадрата

Теперь мы сталкиваемся с другой проблемой, когда змея сталкивается с его собственным телом, мы должны остановить игру, если это произойдет

В петле игры добавьте эту линию

        for square in snake_body[1:]:
            if pygame.Rect(square[0],square[1],10,10).colliderect(pygame.Rect(snake_pos[0],snake_pos[1],10,10)):
                sys.exit()

Что я здесь делал?

  • Сначала я пробегаю через smake_body и проверить, если snake_pos сталкивается с другими квадратами.

Теперь, почему я исключил последний элемент в smake_body используя snake_body [:-1]

Это немного сбивает с толку, но думайте о последнем элементе как о главе змеи, здесь мы проверяем, если голова или snake_pos Сталкивается с другими частями тела, но если мы включим последний элемент в список, мы будем проверять, сталкивается ли головка с головой, когда туда достигнет цикла, вызовет последний элемент в smake_body будет smake_pos И мы бы проверили, если snake_pos Сталкивается с snake_pos Или, если голова сталкивается с головой, что всегда верно.

С этим наша игра почти готова

Теперь мы должны отобразить наш счет в Pygame, чтобы показать текст, во -первых, мы должны загрузить шрифт в начале файла, после импорта Pygame и перед основной функцией, добавьте это

font = pygame.font.SysFont('comicsans',40)

Здесь мы загружаем системный шрифт, используя pygame.font. Sysfont (), который принимает шрифт как первый аргумент и размер как 2 -й я выбрал Comicsans, вы можете выбрать другие системы системных шрифтов, такие как Timesnewroman

Далее мы также должны использовать этот шрифт сейчас … В игре, перед Pygame.display.update () Добавить эти две строки

        #setting the font up
        score_font = font.render(f'{score}' , True , (255,255,255))
        #declaring position of the font to be in center
        #in x coordinate and 30 in y
        font_pos = score_font.get_rect(center=(WIN_X//2-40 , 30))
        WIN.blit(score_font , font_pos)

Так что я здесь сделал?

  • Сначала я сделал SCOST_FONT переменная, и вы можете назвать это все, что хотите, кстати, и установить ее равным Font.Render

  • Теперь шрифт – это переменная, которую мы объявили выше, поэтому измените его на то, что вы его назвали …

  • Теперь, в этом шрифте, у нас есть метод рендеринга, это требует строки, которую мы хотим показать как 1 -й аргумент, в нашем случае его оценка, но оценка – это число, и 1 -й аргумент должен быть строкой И поэтому я изменил его на строку, используя F -строки в Python. Следующий аргумент может быть установлен как TRUE или FALSE, ваше желание, 3 -й аргумент – это цвет в RGB, я выбрал белый.

  • Теперь только это не покажет текст на экране, мы должны Блита Это. Вот почему я использовал Win.blit () Что требует того, чтобы блажать или отображать как 1 -й аргумент, который в нашем случае был шрифтом, и кортеж или список, который берет координаты X и Y, я уже объявил font_pos Выше которого находится центральная позиция в верхней части экрана. Если вы хотите знать, как центрировать текст в Pygame, есть много способов … Вы можете проверить этот Stackoverflow Тема Больше подробностей.

Давайте запустим игру сейчас ………………

Это полностью функционирующая игра змеи, которая у нас здесь есть 🎉🎊🕺 …

И прежде чем я закончу этот пост, давайте внедрим главное меню и игру над сценой … Начнем с главного меню

В нашем игровом коде перед основной функцией поместите этот код

#The main menu
def main_menu():
    #creating seperate game loop for the main_menu
    while 1:
        #listening for events
        for event in pygame.event.get():
            #you know what this does
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

            #IF THE user clicks anywhere in the screen
            #call the main function , start the game
            if event.type == pygame.MOUSEBUTTONDOWN:
                main()
        #nothing new here
        WIN.fill((0,0,0))

        #showing the message 
        #'Press anywhere to start'
        # at the center of the screen
        main_menu_message = font.render('Press anywhere to start the game' , True , (255,255,255))
        font_pos = main_menu_message.get_rect(center=(WIN_X//2, WIN_Y//2))
        WIN.blit(main_menu_message , font_pos)
        pygame.display.update()

Хорошо, давайте пройдем это быстро. В этой функции мы написали еще один игровую петлю и еще одну проверку на pygame.event.get ()

Если пользователь нажимает в любом месте, будет вызвана основная функция, что означает, что игра начнется, мы также отображаем сообщение ‘Нажмите где угодно, чтобы начать’ в центре экрана

Теперь в конце нашего кода, где мы называем Main (), вместо

main_menu()

Мы почти закончили, остается вещь, это Game_over сцена Давайте быстро пройдемся через это

#game over scene, this takes the score to display as 
#the argument
def game_over(score):
        #I won't explain these again
        while 1:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
            WIN.fill((0,0,0))

            #showing 'You lost' in red color
            game_over_message = font.render('You Lost' , True , (255,0,0))
            #showing 'You score was SCORE'
            game_over_score = font.render(f'Your Score was {score}' , True , (255,255,255))

            font_pos_message = game_over_message.get_rect(center=(WIN_X//2, WIN_Y//2))
            font_pos_score = game_over_score.get_rect(center=(WIN_X//2, WIN_Y//2+40))
            WIN.blit(game_over_message , font_pos_message)
            WIN.blit(game_over_score , font_pos_score)
            pygame.display.update()

            #here what we are doing is we
            #use time.sleep() to stop our 
            #program for 3 seconds ,
            #don't forget to import time module at
            #the top ...
            #after 3 seconds, we call our main_menu()
            time.sleep(3)
            main_menu()

Что за game_over () Показывает, что вы потеряли, и ваш счет. Паузу программы на 3 секунды, а затем просто звонит главное меню()

Теперь в основной функции, когда мы умираем, мы звоняем sys.exit () , вместо этого, звоните game_over () Переходя в счете

Ваша основная функция должна быть близка к этому

def main():
    CLOCK = pygame.time.Clock()
    snake_pos=[200,70]
    snake_body=[[200,70] , [200-10 , 70] , [200-(2*10),70]]
    fruit_pos = [0,0]
    fruit_spawn = True
    direction = 'right'
    score=0
    CLOCK = pygame.time.Clock()
    while 1:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

            keys= pygame.key.get_pressed()
            if (keys[pygame.K_w] or keys[pygame.K_UP]) and direction != 'down':
                direction = 'up'
            if (keys[pygame.K_s] or keys[pygame.K_DOWN]) and direction != 'up':
                direction = 'down'
            if (keys[pygame.K_d] or keys[pygame.K_RIGHT]) and direction != 'left':
                direction = 'right'
            if (keys[pygame.K_a] or keys[pygame.K_LEFT]) and direction != 'right':
                direction = 'left'

        WIN.fill((0,0,0))
        for square in snake_body:
            pygame.draw.rect(WIN ,(255, 255, 0), (square[0],square[1],10,10))
        if direction == 'right':
            snake_pos[0] += 10
        elif direction == 'left':
            snake_pos[0] -= 10
        elif direction == 'up':
            snake_pos[1] -= 10
        elif direction == 'down':
            snake_pos[1] += 10

        snake_body.append(list(snake_pos))

        if fruit_spawn:
            fruit_pos = [random.randrange(40,WIN_X-40),random.randrange(40,WIN_Y-40)]
            fruit_spawn = False

        pygame.draw.rect(WIN ,(138,43,226),(fruit_pos[0],fruit_pos[1],10,10))

        score_font = font.render(f'{score}' , True , (255,255,255))
        font_pos = score_font.get_rect(center=(WIN_X//2-40 , 30))
        WIN.blit(score_font , font_pos)

        if pygame.Rect(snake_pos[0],snake_pos[1],10,10).colliderect(pygame.Rect(fruit_pos[0],fruit_pos[1],10,10)):
            fruit_spawn=True
            score += 5
        else:
            snake_body.pop(0)

        for square in snake_body[:-1]:
            if pygame.Rect(square[0],square[1],10,10).colliderect(pygame.Rect(snake_pos[0],snake_pos[1],10,10)):
                game_over(score)

        if snake_pos[0]+10 <=0 or snake_pos[0] >= WIN_X:
            game_over(score)
        if snake_pos[1]+10 <=0 or snake_pos[1] >= WIN_Y:
            game_over(score)
        pygame.display.update()

        CLOCK.tick(25)

При этом у нас должна быть полная игра змеи …

Полный код можно найти на моем GitHub здесь

Итак, здесь у вас есть … Змеиная игра с Pygame, не стесняйтесь играть с кодом и добавлять такие функции, как, возможно, система с высокой оценкой, некоторые небольшие анимации, добавляйте уровни сложности и т. Д… Кроме того, было бы лучше, если бы вы создали что -то сами. Есть много ресурсов, которые помогут вам работать с Во -первых, это веб -сайт Pygame: https://www.pygame.org/news 2 -й будет изобретен с Python: https://inventwithpython.com/ Проверьте эту статью: https://inventwithpython.com/blog/2012/02/20/i-need-practice-programming-49-ideas-for-game-clones-to-code/

Вы также можете проверить игры, которые я сделал с Pygame, они могут быть не самыми крутыми, но вы получите какую -то идею

Фруктовый ниндзя клон: Фруктовые хмурые Ссылка: https://github.com/grapejuice1/fruit-frowns Прорыв Ссылка: https://github.com/grapejuice1/grape bricks Космические захватчики Ссылка: https://github.com/grapeJUICE1/space-invaders

Если вы нашли это полезным или полезным, пожалуйста, 💓, 🦄 и 🔖.

Оригинал: “https://dev.to/grapejuice/getting-started-with-pygame-making-a-snake-game-2i1g”