Как мне запустить 2 функции в Pyglet?

#python #windows #pyglet

#python #Windows #pyglet

Вопрос:

Я пытаюсь создать игру «Камень, ножницы, бумага» на Python, используя Pyglet. При запуске функции ‘on_draw’ я хочу, чтобы она позволяла пользователю вводить «A» для камня, «P» для бумаги и «S» для ножниц, но я не могу найти решение. Одна из моих идей заключалась в том, что когда вы запускаете «окно», оно устанавливает фон, содержащий текст, но также не смог найти никакой информации об этом. Если у вас есть какие-либо идеи и у вас есть немного свободного времени, я был бы очень признателен за вашу помощь.

Я пытался разобраться в этом некоторое время, но я совсем новичок в Pyglet.

Вот мой код на данный момент…

 import pyglet
from pyglet.window import key
import random
import time

window = pyglet.window.Window(width = 1000, height = 700, resizable = False, caption = "Rock, Paper, Scissors!")

#images saved in root of the .py file
bg = pyglet.image.load('bg.png')
sprite_bg = pyglet.sprite.Sprite(img=bg)

# all images are defined correctly and sprites(tested it and all works)

#default choice of the computer player and user
num1 = 0
num2 = 0 #num2 is the user

@window.event
#Here is where I want it to say "Rock - A, Paper - S, Scissors - D"
def on_key_press(symbol, modifiers):
    global num2
    if symbol == key.A:
        print ("Player: Rock")
        num2 = 0
        on_draw2()
    elif symbol == key.S:
        print ("Player: Paper")
        num2 = 1
        on_draw2()
    elif symbol == key.D:
        print ("Player: Scissors")
        num2 = 2
        on_draw2()


def on_draw():

    window.clear()
    sprite_bg.draw()

    num1 = random.randint(0, 2)
    if num1 == 0:
        sprite_r_right.draw()
    elif num1 == 1:
        sprite_p_right.draw()
    elif num1 == 2:
        sprite_s_right.draw()

    if num2 == 0:
        sprite_r_left.draw()
    elif num2 == 1:
        sprite_p_left.draw()
    elif num2 == 2:
        sprite_s_left.draw()

    if num1 == num2:
        both_win.draw()

    elif num2 == 0:
        if num1 == 1:
            right_win.draw()
        else:
            left_win.draw()

    elif num2 == 1:
        if num1 == 2:
            right_win.draw()
        else:
            left_win.draw()

    elif num2 == 2:
        if num1 == 0:
            right_win.draw()
        else:
            left_win.draw()


if __name__ == '__main__':
    pyglet.app.run()
  

Я хочу, чтобы программа запускалась следующим образом:
1. Камень — A, бумага — S, Ножницы — D и ожидает ввода a, s или d
2. затем устанавливает ‘num2’ (пользователь) в 0, 1 или 2 (0 — камень, 1 — бумага, 2 —
ножницы)
3. случайное ‘num1’ (компьютерный проигрыватель) с 0, 1 или 2
4. показывает изображение камня, бумаги или ножниц с обеих сторон и сообщает, кто выиграл
5. показать результат (еще не реализован)
6. повторите (еще не реализовано)

Программа выполняется следующим образом: 1. пустой экран (ожидающий ввода a, s или d) 2. выполняет шаги 2, 3, 4, перечисленные выше

Комментарии:

1. Насколько вы знакомы с классами и наследованием?

2. Не очень знакомо, но я проведу некоторое исследование. Спасибо

3. У меня есть стандартный шаблон, который я обычно раздаю людям, который решит подобные проблемы и поможет с будущими структурами кода. Но для этого требуется, чтобы вы были знакомы с классами и наследованием. Я постараюсь заставить полученный вами код работать, чтобы вы не запутались в совершенно новом наборе кода.

Ответ №1:

В вашем коде есть пара проблем, с которыми нам нужно разобраться.
Первая из них on_draw не будет вызвана, если пользователь не нажмет кнопку, в идеале.. Эта функция вызывается с определенными интервалами / прерываниями внутри фреймворка.

Мы делаем это, выполняя:

 @window.event # <-- This is key, if you forget this - the screen won't update
def on_draw():
    window.clear()
    sprite_bg.draw()
  

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

Другая проблема заключается в том, что вы делаете num1 = random.randint(0, 2) в каждом цикле рендеринга. Без проверки, предоставил ли пользователь выбор или нет. В идеале, вы бы сделали что-то вроде:

 if num2 != 0:
    num1 = random.randint(0, 2)
  

*(Еще одно краткое замечание, эти имена переменных чертовски сбивают с толку, и кому-либо действительно трудно отследить, для чего они используются. Итак, в приведенном ниже коде я изменил их, чтобы представить что-то более логичное с точки зрения того, что они делают или для чего используются)*

Вот предлагаемый пример того, как вы могли бы настроить логику:

 import pyglet
from pyglet.window import key
import random
import time

window = pyglet.window.Window(width = 1000, height = 700, resizable = False, caption = "Rock, Paper, Scissors!")

#images saved in root of the .py file
bg = pyglet.image.load('bg.png')
sprite_bg = pyglet.sprite.Sprite(img=bg)

sprite_player = pyglet.text.Label("", x=(window.width/3), y=window.height/2)
sprite_computer = pyglet.text.Label("", x=window.width-(window.width/3), y=window.height/2)
sprite_result = pyglet.text.Label("", x=window.width/2, y=window.height/3, anchor_x="center")

@window.event
def on_key_press(symbol, modifiers):
    if symbol == key.A:
        sprite_player.text = 'Rock'

    elif symbol == key.S:
        sprite_player.text = 'Paper'

    elif symbol == key.D:
        sprite_player.text = 'Scissors'

    # Once the user presses a key, randomize the computers choice
    rng = random.randint(0, 2)
    if rng == 0:
        sprite_computer.text = 'Rock'
    elif rng == 1:
        sprite_computer.text = 'Paper'
    elif rng == 2:
        sprite_computer.text = 'Scissors'

@window.event # <-- This is key, if you forget this - the screen won't update
def on_draw():
    window.clear()
    sprite_bg.draw()

    if sprite_player.text != "" and sprite_computer.text != "":
        if sprite_player.text == sprite_computer.text:
            sprite_result.text = "Draw!"

        elif sprite_computer.text == "Rock":
            if sprite_player.text == "Paper":
                sprite_result.text = "Player wins"
            else:
                sprite_result.text = "Computer wins"

        elif sprite_computer.text == "Paper":
            if sprite_player.text == "Scissors":
                sprite_result.text = "Player wins"
            else:
                sprite_result.text = "Computer wins"

        elif sprite_computer.text == "Scissors":
            if sprite_player.text == "Rock":
                sprite_result.text = "Player wins"
            else:
                sprite_result.text = "Computer wins"
    else:
        sprite_result.text = "Press A for Rock, S for Paper and D for Scissors"

    sprite_player.draw()
    sprite_computer.draw()
    sprite_result.draw()


if __name__ == '__main__':
    pyglet.app.run()
  

Появится быстрое сообщение «справка», и как только игра начнется, будут показаны результаты и варианты выбора.

Более аккуратным способом было бы использовать объектно-ориентированное программирование для решения многих проблем рендеринга, сохранения. Из-за нехватки времени мне придется вернуться и отредактировать этот ответ с помощью этого решения, нужно пойти поработать, хех.