pygame: пользовательские классы, наследуемые от pygame.Surface - PullRequest
1 голос
/ 23 октября 2010

Я играю с pygame впервые (и я вроде новичка по питону в целом), и мне интересно, может ли кто-нибудь помочь мне с этим ...

Я немного зарабатываюСтреляйте в игру и хотите создать класс для плохих парней.Я думал, что класс должен наследоваться от pygame.Surface, но это доставляет мне все виды проблем (def, может быть, я испорчу основные вещи наследования / класса).Например, почему это не работает (pygame, screen и т. Д. Все работает нормально и используется в других частях кода, я просто пытаюсь переместить функции, которые у меня уже есть, в класс):

class Zombie(pygame.Surface):
  x_pos = y_pos = 0
  def __init__(self, x, y):
    #create zombie
    self = pygame.image.load('zombie_1.png')
    self = pygame.transform.scale(self,(50, 50))

    x_pos = x
    y_pos = y

zombie = Zombie(screen.get_width()/3, screen.get_height()/3)
screen.blit(zombie, (zombie.x_pos, zombie.y_pos))

Выше приведено сообщение об ошибке: «pygame.error: display Surface quit» edit: очевидно, это результат вызова Surface после вызова pygame.display.quit ().Любой, кто имеет какой-либо опыт в Pygame, хочет попробовать свои силы в этом?

Весь код:

#Initialize
import pygame, sys
pygame.init()

#classes
class Zombie(pygame.Surface):
  x_pos = y_pos = 0
  def __init__(self, x, y):
    #create zombie
    self = pygame.image.load('zombie_1.png')
    self = pygame.transform.scale(self,(50, 50))

    x_pos = x
    y_pos = y

  def is_hit(mouse_pos):
    #grab variables
    (mouseX, mouseY) = mouse_pos
    print "\nboxW_x, y = " + str(self.x) + ", " + str(self.y) + "\nmouseX, Y = " + str(mouseX) + ", " + str(mouseY) 
    headshot_x = self.x + (.5 * zombie.get_width())
    headshot_y = self.y + (.25 * zombie.get_height())
    margin_of_error_x = (zombie.get_width()/float(1000)) * zombie.get_width()
    margin_of_error_y = (zombie.get_height()/float(1000)) * zombie.get_height()
    print "Headshot_x: " + str(headshot_x) + ", " + str(headshot_y)
    print "diff in headshot and actual shot: " + str(mouseX - headshot_x) + ", " + str(mouseY - headshot_y)
    print "margin of error x = " + str(margin_of_error_x) + " y = " + str(margin_of_error_y)
    print "zombie size: " + str(zombie.get_size())

    valid_x = valid_y = False

    if abs(mouseX-headshot_x) < margin_of_error_x:
      valid_x = True
      print "valid x"
    if abs(mouseY-headshot_y) < margin_of_error_y:
      valid_y = True
      print "valid y"

    return (valid_x and valid_y)

#list of bad guys
zombie_list = []

#functions (which should later be moved into classes)
def is_hit():
  #grab variables
  (mouseX, mouseY) = pygame.mouse.get_pos()
  print "\nboxW_x, y = " + str(boxW_x) + ", " + str(boxW_y) + "\nmouseX, Y = " + str(mouseX) + ", " + str(mouseY) 
  headshot_x = boxW_x + (.5 * boxW.get_width())
  headshot_y = boxW_y + (.25 * boxW.get_height())
  margin_of_error_x = (boxW.get_width()/float(1000)) * boxW.get_width()
  margin_of_error_y = (boxW.get_height()/float(1000)) * boxW.get_height()
  print "Headshot_x: " + str(headshot_x) + ", " + str(headshot_y)
  print "diff in headshot and actual shot: " + str(mouseX - headshot_x) + ", " + str(mouseY - headshot_y)
  print "margin of error x = " + str(margin_of_error_x) + " y = " + str(margin_of_error_y)
  print "zombie size: " + str(boxW.get_size())

  valid_x = valid_y = False

  if abs(mouseX-headshot_x) < margin_of_error_x:
    valid_x = True
    print "valid x"
  if abs(mouseY-headshot_y) < margin_of_error_y:
    valid_y = True
    print "valid y"

  return (valid_x and valid_y)

pygame.mouse.set_visible(True)
pygame.mouse.set_cursor(*pygame.cursors.diamond)

#Display
screen = pygame.display.set_mode((640, 640))
pygame.display.set_caption("Zombie Massacre")

#Entities
#background
background = pygame.Surface(screen.get_size())
background = background.convert()
background.fill((0, 0, 0))

#make a zombie
boxW = pygame.image.load('zombie_1.png')
boxW = pygame.transform.scale(boxW,(50, 50))

#set up some box variables
boxW_x = screen.get_width()/3
boxW_y = screen.get_height()/3

#testing zombie class
zombie = Zombie(screen.get_width()/3, screen.get_height()/3)

#Action

#Assign
clock = pygame.time.Clock()
keepGoing = True

#Loop
count = 0;
rotation_vect = 1.01
while keepGoing:

  #setup rotation_vect for this pass
  if (count % 3) == 0:
    rotation_vect = 0 - rotation_vect

  #Time
  clock.tick(30)

  #Events
  for event in pygame.event.get():
    if event.type == pygame.QUIT:
      keepGoing = False
    elif event.type is pygame.MOUSEBUTTONDOWN:
      #loop through zombie list, using each one's "is_hit()" function
      keepGoing = not(is_hit())

#Refresh screen
  screen.blit(background, (0,0))
  boxW = pygame.transform.rotozoom(pygame.image.load('zombie_1.png'), rotation_vect, 1.01)
  boxW = pygame.transform.scale(boxW,(count+50, count+100))
#for zombie in zombies
  screen.blit(boxW,(boxW_x+(boxW_x * .1), boxW_y+(boxW_y * .1)))
# error is result of following line
  screen.blit(zombie, (zombie.x_pos, zombie.y_pos))
  pygame.display.flip()

#increment count
  count += 1

Ответы [ 2 ]

3 голосов
/ 26 ноября 2010

Я вижу, что этот вопрос был задан месяц назад, но, возможно, еще не слишком поздно ...

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

Я не понял, о чем идет игра (за исключением выстрела в голову: D), но вот пример того, как отображать зомби и определять, когдав них стреляют:

import pygame

TITLE = "Zombie Massacre"
SCREEN_WIDTH = 640
SCREEN_HEIGHT = 480

class ZombieSprite(pygame.sprite.Sprite):
    def __init__(self, image):
        pygame.sprite.Sprite.__init__(self)
        self.image = image
        self.rect = pygame.Rect((0, 0), image.get_size())
        self.defineHeadPos()

    def defineHeadPos(self):
        # To call each time the size of the rect changes.
        head_x_center = self.rect.width / 2
        head_y_center = self.rect.height / 4
        head_width = self.rect.height / 4
        head_height = self.rect.height / 4
        head_x_min = head_x_center - head_width / 2
        head_y_min = head_y_center - head_height / 2
        self.head_rect = pygame.Rect((head_x_min, head_y_min), 
                                     (head_width, head_height))

    def update(self):
        # Here we could move the zombie.
        pass

    def shoot(self, pos):
        x, y = pos
        x -= self.rect.left
        y -= self.rect.top
        if self.head_rect.collidepoint(x, y):
            print "Head shot !"
        else:
            print "Shot."


def ActionShoot(zombies, pos):
    print "Shot at %s." % (pos,)
    sprites = zombies.get_sprites_at(pos)
    if not sprites:
        print "Missed."
        return
    sprite = sprites[-1]
    sprite.shoot(pos)


def DrawScene(screen, background, zombies):
    screen.blit(background, (0, 0))
    zombies.draw(screen)

pygame.init()

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption(TITLE)

background = pygame.Surface(screen.get_size())
background = background.convert()
background.fill((32, 32, 32))

image_zombie = pygame.image.load('zombie.png')
image_zombie.convert()

zombies = pygame.sprite.LayeredUpdates()

zombie = ZombieSprite(image_zombie)
zombie.rect.move_ip(0, 0)
zombies.add(zombie)

zombie = ZombieSprite(image_zombie)
zombie.rect.move_ip(400, 100)
zombies.add(zombie)

zombie = ZombieSprite(image_zombie)
zombie.rect.move_ip(300, 250)
zombies.add(zombie)

clock = pygame.time.Clock()
running = True
while running:
    clock.tick(30)
    zombies.update()
    DrawScene(screen, background, zombies)
    pygame.display.flip()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.MOUSEBUTTONDOWN:
            ActionShoot(zombies, pygame.mouse.get_pos())

print "Quitting..."
pygame.quit()

Это не полная игра, но я оставляю это на ваше усмотрение.Ключевым моментом здесь является использование спрайтов и групп для отображения группы зомби в разных местах.Вы можете поместить «интеллект» зомби в метод их обновления (переместите их, увеличьте, если они приблизятся к экрану).Примечание: я использовал только один объект изображения для всех зомби.Если вы начинаете масштабирование, вы хотите, чтобы у каждого зомби был свой собственный объект изображения, что означает загрузку zombie.png для каждого из них.В противном случае, когда вы увеличиваете масштаб, они все увеличивают.

3 голосов
/ 23 октября 2010

Вы не вызвали наследуемый конструктор:

class Zombie(pygame.Surface):
    def __init__(self, x, y):
        pygame.Surface.__init__(self, size=(w,h))

И вы присваиваете self.Это не сработает.

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