Проблемы с движением Pygame - PullRequest
1 голос
/ 28 февраля 2020

Когда я использую код перемещения в python pygame, он не загружает код при запуске.

#right to repestic creatovrs



import pygame, random, time, sys, pyscroll, pytmx
from Bruh import *
from pygame.locals import *
from pytmx.util_pygame import load_pygame

pygame.init()
width, height = 800, 600
backgroundColor = 255,  0,  0
screen = pygame.display.set_mode((width, height))

blue = (0, 0, 255)
darkblue = (20, 20, 70)
white = (255, 255, 255)
lightwhite = (170, 170, 170)
skin = (236, 188, 180)
floorcolor = (229,164,14)
sun = (250,255,63) 


#the four numbers go x axis, y axis, width, and then height
def drawLevel1(window):
  img = pygame.image.load("Overlay.png")
  window.blit(img, (0, 0))
def drawLevel2(window):
  img2 = pygame.image.load("Overlay2.png")
  window.blit(img, (0, 0))     

pygame.key.set_repeat(100,100)

Character = Bruh(35, 367)

Bruh.draw(Character, screen)

drawLevel1(screen)
'''
while True:
      for event in pygame.event.get():
          if event.type==QUIT or (event.type==KEYUP and event.key==K_ESCAPE):
            pygame.quit()
            sys.exit()
          elif event.type==KEYDOWN:

            if event.key==K_DOWN: 
                Character.moveUp()

            elif event.key==K_UP:
                Character.moveDown()

            elif event.key==K_LEFT:
                Character.moveLeft()

            elif event.key==K_RIGHT:
                Character.moveRight()

for event in pygame.event.get():
  if event.type==QUIT or (event.type==KEYUP and event.key==K_ESCAPE):
    pygame.quit()
    sys.exit()
  if event.key==K_DOWN:
    Character.moveUp()
  if event.key==K_UP:
    Character.moveDown()
  if event.key==K_LEFT:
    Character.moveLeft()
  if event.key==K_RIGHT:
    Character.moveRight
either of these won't work for some reason. it just wont load the game once these are placed in the code
'''
pygame.display.update()

while (True):
    for event in pygame.event.get() :
         if ( event.type == pygame.QUIT or (event.type==pygame.KEYDOWN and event.key==pygame.K_ESCAPE)):
              pygame.quit(); 
              sys.exit();

и код из bruh.py:

import pygame
from pygame.locals import *

class Bruh:
    def __init__(self, newX, newY):
        self.x = newX
        self.y = newY
        self.img = pygame.image.load("Bruh.png")
    def draw(self, window):
        window.blit(self.img, (self.x,self.y))
    def moveLeft(self):
        self.x = self.x - 5
    def moveRight(self):
      self.x = self.x + 5
    def moveUp(self):
        self.y = self.y + 5
    def moveDown(self):
        self.y = self.y - 5
    def getRec(self):
        myRec = self.img.get_rect()
        return (self.x, self.y, myRec[2], myRec[3])      

это все файлы .py, и они должны вызывать некоторые проблемы. Я не получаю сообщение об ошибке, оно просто не загружается, когда я нажимаю Run. Я не могу понять, почему. Если у кого-то есть помощь, было бы здорово

1 Ответ

2 голосов
/ 28 февраля 2020

Я думаю, что Pygame немного менее умна, чем вы ожидаете. В вашем while l oop вы перемещаете своего персонажа, но все, что вы делаете, когда вы «перемещаете» этого персонажа, обновляет число на этом объекте. Вы не говорите Pygame, что что-то изменилось, и вы не перерисовываете экран. Это не достаточно умно, чтобы знать, чтобы сделать это самостоятельно. Существуют фреймворки, которые будут отслеживать ваши значения и пытаться обновить отображение, чтобы синхронизироваться с ними (в основном для веб-разработки), но это не то, как работает pygame.

Вместо этого видеоигры в реальном времени обычно следуют этому шаблону :

while running:
    handle_events()  # check which keys have been pressed
    loop()           # handle, physics, AI, logic, etc
    render()         # re-draw a new version of the screen based on the new state of the world

Подробнее см. в этом руководстве .

В вашем случае это может выглядеть так:

pygame.key.set_repeat(100, 100)
character = Bruh(35, 367)

while True:
    for event in pygame.event.get():
        if event.type == QUIT or (event.type == KEYUP and event.key == K_ESCAPE):
            pygame.quit()
            sys.exit()
        elif event.type == KEYDOWN:
            if event.key == K_DOWN:
                character.moveUp()
            elif event.key == K_UP:
                character.moveDown()
            elif event.key == K_LEFT:
                character.moveLeft()
            elif event.key == K_RIGHT:
                character.moveRight()

    screen.fill((0, 0, 0))
    drawLevel1(screen)
    character.draw(screen)

    pygame.display.update()

На самом деле, хотя, это не отличный способ делать вещи. Строка pygame.key.set_repeat(100, 100) означает, что вы будете получать событие KEYDOWN только каждые 100 мс (10 раз / сек c). Но while l oop будет работать намного больше, чем это. Это означает, что движение вашего персонажа будет происходить только со скоростью 10FPS, но вы будете сжигать ресурсы, чтобы запустить игру намного быстрее.

Вместо этого я бы сделал что-то вроде этого:

# make a clock to help us run at a consistent framerate
clock = pygame.time.Clock()

# a dictionary to help us keep track of which keys are currently held down
keys_down = {
    K_DOWN: False,
    K_UP: False,
    K_LEFT: False,
    K_RIGHT: False,
}

while True:
    for event in pygame.event.get():
        if event.type == QUIT or (event.type == KEYUP and event.key == K_ESCAPE):
            pygame.quit()
            sys.exit()
        elif event.type == KEYDOWN:
            # when the user presses a key, we keep track of the fact
            # that that key is down until they release it
            if event.key in keys_down:
                keys_down[event.key] = True
        elif event.type == KEYUP:
            # when the user releases a key, it's not down anymore
            if event.key in keys_down:
                keys_down[event.key] = False

    # This code will run *every loop*, regardless of
    # whether the user has pressed or released a key recently
    if keys_down[K_DOWN]:
        character.moveDown()
    if keys_down[K_UP]:
        character.moveUp()
    if keys_down[K_LEFT]:
        character.moveLeft()
    if keys_down[K_RIGHT]:
        character.moveRight()

    # Then, clear the screen and re-draw everything in the scene
    screen.fill((0, 0, 0))
    # drawLevel1(screen)
    character.draw(screen)
    pygame.display.update()

    # clock.tick gets the number of `ticks` (milliseconds) since the
    # last time it was called. If you specify a number like tick(30),
    # then it will also wait an amount of time equal to 30 minus that
    # number. Effectively it will limit you to 30fps.
    clock.tick(30)

На самом деле, даже это не идеально. На самом деле, вы должны бежать как можно быстрее и обновлять игровую логику c, чтобы учесть частоту кадров (т.е. двигаться дальше каждый кадр, если у вас меньше кадров в секунду), чтобы ваш персонаж всегда двигался с постоянной скоростью, даже если вы получаете окунуться в частоту кадров. Более того, пусть ваша логика c и рендеринг работают асинхронно. Однако мы разберемся с некоторыми сложными вещами.


Редактировать:

Как указал @Kingsley, в Pygame встроена эта функциональность. Приведенный выше пример можно упростить следующим образом:

import pygame
from pygame.locals import *

clock = pygame.time.Clock()

while True:
    for event in pygame.event.get():
        if event.type == QUIT or (event.type == KEYUP and event.key == K_ESCAPE):
            pygame.quit()
            sys.exit()

    # This line handles all the KEYUP and KEYDOWN events
    # instead of doing it manually
    keys_down =  pygame.key.get_pressed()

    if keys_down[K_DOWN]:
        character.moveDown()
    if keys_down[K_UP]:
        character.moveUp()
    if keys_down[K_LEFT]:
        character.moveLeft()
    if keys_down[K_RIGHT]:
        character.moveRight()

    screen.fill((0, 0, 0))
    drawLevel1(screen)
    character.draw(screen)
    pygame.display.update()

    clock.tick(30)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...