【问题标题】:Pong with Background Image乒乓球与背景图像
【发布时间】:2019-11-07 15:11:00
【问题描述】:

我正在尝试将背景图像添加到 Pong 游戏中。我已经尝试了很多东西,但它不起作用。 我是 Python 新手,所以可能是我做错了什么我不知道。

### Bibliothek spiel.py

import pygame, sys, time

class Einstellungen():
    fps = 40 # Frames pro Sekunde

    # Dimensionen
    fensterBreite = 640
    fensterHoehe = 480
    linienDicke = 10
    abstand = 2*linienDicke
    schlaegerBreite = 10
    schlaegerHoehe = 50
    schriftGroesse = 16
    ballRadius = 5 # nur fuer runden Ball notwendig

    def __init__(self):
        # Notwendige Initialisierung fuer pygame
        pygame.init()
        pygame.display.set_caption('Pong')
        pygame.mouse.set_visible(0)  # setze Mauszeiger unsichtbar

    def fenster_mitte(self):
        return self.fensterHoehe // 2

    def schlaeger_mitte(self):
        return self.fenster_mitte() - self.schlaegerHoehe // 2

    def linker_rand(self):
        return self.abstand

    def rechter_rand(self):
        return self.fensterBreite - self.schlaegerBreite - self.abstand

    def schrift(self):
        return pygame.font.SysFont('arial', self.schriftGroesse, bold=True)

'''Idealer Weise waere dies kein globales Objekt'''
config = Einstellungen()


class Form(pygame.sprite.Sprite):
    def __init__(self, x, y, breite, hoehe, geschwindigkeit, farbe=pygame.Color('white')):
        self.x = x
        self.y = y
        self.breite = breite
        self.hoehe = hoehe
        self.geschwindigkeit = geschwindigkeit
        self.farbe = farbe


class Rectangle(Form):
    def __init__(self, x, y, breite, hoehe, geschwindigkeit, farbe=pygame.Color('white')):
        super().__init__(x, y, breite, hoehe, geschwindigkeit, farbe)
        self.rect = pygame.Rect(self.x, self.y, self.breite, self.hoehe)

    def draw(self, fensterFlaeche):
        pygame.draw.rect(fensterFlaeche, self.farbe, self.rect)


class Circle(Form):
    def __init__(self, x, y, breite, hoehe, geschwindigkeit, farbe=pygame.Color('white')):
        super().__init__(x, y, breite, hoehe, geschwindigkeit, farbe)
        self.rect = pygame.Rect(self.x, self.y, self.breite, self.hoehe)
        self.radius = config.ballRadius

    def draw(self, fensterFlaeche):
        pygame.draw.circle(fensterFlaeche, self.farbe,
                           (self.rect.x, self.rect.y), self.radius)


class Willkommen():
    # Willkommensbildschirm beim Programmstart
    def __init__(self, fensterFlaeche):
        popupFenster = pygame.Rect((config.linker_rand()+80, config.linker_rand()+60),
                (config.fensterBreite*2//3, config.fensterHoehe*1//3))
        fensterFlaeche.fill(pygame.Color('white'), popupFenster)
        textZeile1='Willkommen zu Pong'
        textZeile2='Spielstart mit beliebiger Taste'
        textWidth1 , textHeight1 = config.schrift().size(textZeile1)
        textWidth2 , textHeight2 = config.schrift().size(textZeile2)
        zeile1 = config.schrift().render(textZeile1, False, pygame.Color('black'))
        xZeile1 = (config.fensterBreite-textWidth1)//2
        yZeile1 = (config.fensterHoehe*2//3-textHeight1)//2
        zeile2 = config.schrift().render(textZeile2, False, pygame.Color('black'))
        xZeile2 = (config.fensterBreite-textWidth2)//2
        yZeile2 = (config.fensterHoehe-config.abstand-textHeight2)//2
        fensterFlaeche.blit(zeile1, (xZeile1, yZeile1))
        fensterFlaeche.blit(zeile2, (xZeile2, yZeile2))            


class Spiel():
    # Initialisierung (OOP Konstruktor)
    def __init__(self, spielfeld, spieler, computer, ball, punkteAnzeige):
        self.punkte = 0
        self._fpsTimer = pygame.time.Clock()

        self._spielfeld = spielfeld
        self._fensterFlaeche = pygame.display.set_mode(
            (config.fensterBreite, config.fensterHoehe))
        self._spieler = spieler
        self._computer = computer
        self._ball = ball
        self._allSchlaeger = [self._spieler, self._computer] # Liste
        self._punkteAnzeige = punkteAnzeige

    def run(self):
        '''
        Spielschleife - Game Loop Pattern, siehe auch:
        http://gameprogrammingpatterns.com/game-loop.html
        '''
        running = False
        # Willkommensbildschirm anzeigen, weiter mit Taste
        while running == False:
            Willkommen(self._fensterFlaeche)
            pygame.display.update()
            # Ueberpruefe ob Taste gedrueckt wurde
            for event in pygame.event.get():
                if event.type == pygame.KEYDOWN:
                    running = True
        # Spielschleife
        while running:
            self._ereignisse_behandeln()
            self._update()
            self._zeichnen()
            pygame.display.update()
            self._fpsTimer.tick(config.fps)

    def _ereignisse_behandeln(self):
        # Ereignis abfragen
        for ereignis in pygame.event.get():
            self._behandle(ereignis)

    def _behandle(self, event):
        # Ueberpruefe ob Schliessen-Symbol im Fenster gedrueckt wurde
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
            return
        # Ueberpruefe ob Maus bewegt wurde
        elif event.type == pygame.MOUSEMOTION:
            self._spieler.move(event.pos)
            return
        return event

    def _update(self):
        self._bewegen()
        self._aufprall_berechnen()

    def _bewegen(self):
        self._ball.move()
        self._computer.move(self._ball)

    def _aufprall_berechnen(self):
        if self._ball.hit_schlaeger(self._computer):
            self._ball.bounce('x')

        elif self._ball.hit_schlaeger(self._spieler):
            self._ball.bounce('x')
            self.punkte += 1

        elif self._ball.trefferComputer():
            self.punkte += 5

        elif self._ball.trefferSpieler():
            self.punkte = 0

    def _zeichnen(self):
        self._spielfeld.draw(self._fensterFlaeche)
        self._ball.draw(self._fensterFlaeche)
        for schlaeger in self._allSchlaeger:
            schlaeger.draw(self._fensterFlaeche)
        self._punkteAnzeige.draw(self.punkte, self._fensterFlaeche)


class Spielfeld():
    # Initialisierung (OOP Konstruktor)
    def __init__(self, farbe=pygame.Color('black')):
        self.farbe = farbe

    def draw(self, fensterFlaeche):
        fensterFlaeche.fill(self.farbe)
        self._umrandung(fensterFlaeche)
        self._mittellinie(fensterFlaeche)

    def _umrandung(self, fensterFlaeche):
        pygame.draw.rect(fensterFlaeche, pygame.Color('white'),
                ((0, 0), (config.fensterBreite, config.fensterHoehe)),
                config.linienDicke*2)

    def _mittellinie(self, fensterFlaeche):
        pygame.draw.line(fensterFlaeche, pygame.Color('white'),
                 (config.fensterBreite//2, 0),
                 (config.fensterBreite//2, config.fensterHoehe),
                  config.linienDicke//4)


class Ball(Rectangle): # Alternativer Parameter: Circle
    # Pfeiltasten
    LEFT = -1
    RIGHT = 1
    UP = -1
    DOWN = 1

    # Initialisierung (OOP Konstruktor)
    def __init__(self, x, y, breite, hoehe, geschwindigkeit, farbe=pygame.Color('white')):
        super().__init__(x, y, breite, hoehe, geschwindigkeit, farbe)
        self.richtungX = self.LEFT
        self.richtungY = self.UP

    # Funktion zum Bewegen des Balls, neue Position setzen
    def move(self):
        self.rect.x += (self.richtungX * self.geschwindigkeit)
        self.rect.y += (self.richtungY * self.geschwindigkeit)

        # Pruefe Kollision mit Wand
        if self.hit_ceiling() or self.hit_floor():
            self.bounce('y')
        if self.hit_wall():
            self.bounce('x')

    # Richtungsaenderung fuer Ball
    def bounce(self, axis):
        if axis == 'x':
            self.richtungX *= -1
        elif axis == 'y':
            self.richtungY *= -1

    # Treffen von Ball auf Schlaeger
    def hit_schlaeger(self, schlaeger):
        return pygame.sprite.collide_rect(self, schlaeger)

    # Treffen von Ball auf Wand links oder rechts
    def hit_wall(self):
        return (
            (self.richtungX == -1
                and self.rect.left <= self.breite) or
            (self.richtungX ==  1
                and self.rect.right >= config.fensterBreite - self.breite)
        )

    # Treffen von Ball auf Decke
    def hit_ceiling(self):
        return self.richtungY == -1 and self.rect.top <= self.breite

    # Treffen von Ball auf Boden
    def hit_floor(self):
        return (self.richtungY == 1
                and self.rect.bottom >= config.fensterHoehe - self.breite)

    def trefferSpieler(self):
        return self.rect.left <= self.breite

    def trefferComputer(self):
        return self.rect.right >= config.fensterBreite - self.breite


class Schlaeger(Rectangle):
    # Funktion zum Zeichnen des Schlaegers
    def draw(self, fensterFlaeche):
        # Stoppt Schlaeger am unteren Spielfeldrand
        if self.rect.bottom > config.fensterHoehe - config.linienDicke:
            self.rect.bottom = config.fensterHoehe - config.linienDicke
        # Stoppt Schlaeger am oberen Spielfeldrand
        elif self.rect.top < config.linienDicke:
            self.rect.top = config.linienDicke+1 # randkorrektur

        super().draw(fensterFlaeche)

    # Funktion zum Bewegen des Schlaegers mit Maus
    def move(self, pos):
        self.rect.y = pos[1]


class AutoSchlaeger(Schlaeger):
    # Initialisierung (OOP Konstruktor)
    def __init__(self, x, y, breite, hoehe, geschwindigkeit, ball, farbe=pygame.Color('white')):
        super().__init__(x, y, breite, hoehe, geschwindigkeit, farbe)
        self._ball = ball

    # Automatische Bewegung, richtet sich nach dem Ball
    def move(self, pos):
        # Wenn Ball sich vom Schlaeger wegbewegt, zentriere ihn
        if self._ball.richtungX == -1:
            self._zentrieren()
        # Wenn Ball sich auf Schlaeger zubewegt, beoachte seine Bewegung
        elif self._ball.richtungX == 1:
            self._beobachten()

    def _beobachten(self):
        if self.rect.centery < self._ball.rect.centery:
            self.rect.y += self.geschwindigkeit
        else:
            self.rect.y -= self.geschwindigkeit

    def _zentrieren(self):
        if self.rect.centery < config.fenster_mitte():
            self.rect.y += self.geschwindigkeit
        elif self.rect.centery > config.fenster_mitte():
            self.rect.y -= self.geschwindigkeit


class PunkteAnzeige():
    # Initialisierung (OOP Konstruktor)
    def __init__(self, punkte, x, y, schrift, farbe=pygame.Color('white')):
        self.punkte = punkte
        self.x = x
        self.y = y
        self.schrift = schrift
        self.farbe = farbe

    # Schreibe aktuellen Punktestand an den Bildschirm
    def draw(self, punkte, fensterFlaeche):
        self.punkte = punkte
        result_surf = self.schrift.render('Punkte: %s' %(self.punkte), True, self.farbe)
        rect = result_surf.get_rect()
        rect.topleft = (self.x, self.y)
        fensterFlaeche.blit(result_surf, rect)

我尝试在 Spielfeld 中添加一些 Surface 并加载 blit,这实际上是英文的 Playground。我也用 Sprite 尝试过,加载图像没有任何效果。我在互联网上搜索了几个小时,我尝试了所有方法,但我不知道我是否太愚蠢了。

【问题讨论】:

  • 我建议您编辑您的问题并仅显示处理您想要实现的目标的代码。你在那里展示了很多代码,这需要相当长的时间才能完成。此外,请展示您已经尝试过的内容以及失败的原因。
  • 你应该使用 blit 图像而不是 fensterFlaeche.fill(self.farbe)

标签: python image background pygame pong


【解决方案1】:

好吧,我尝试的最后一件事是将斯皮尔菲尔德课程改为:

class Spielfeld:
    # Initialisierung (OOP Konstruktor)
    WIDTH = 1920
    HEIGHT = 1080

    t_WIDTH = 0
    t_HEIGHT = 0

    screen = pygame.display.set_mode((WIDTH, HEIGHT))
    screen.fill((255,255,255))

    texture = pygame.image.load("pong.png")

    t_WIDTH = texture.get_size()[0]
    t_HEIGHT = texture.get_size()[1]

    for i in range(1, WIDTH, t_WIDTH):
        for k in range(1, HEIGHT, t_HEIGHT):
            screen.blit(texture, (i,k))
            pygame.display.flip()

    def draw(self, fensterFlaeche):
        fensterFlaeche.fill(self.farbe)

所以我在很短的时间内得到了图片,直到菜单开始。如果我按下任何按钮然后开始我得到一个错误: 回溯(最近一次通话最后): 第 71 行 主要的() 第 67 行 斯皮尔(.....).run 第 141 行 self._zeichen() 第 185 行 self._spielfeld.draw(self._fensterfFlaeche) 第 214 行平局 fensterFlaeche.fill(self.farbe)

我知道 farbe 没有属性,这是最后一个错误,但如果我删除 def draw 或将 fensterFlaeche.fill 更改为 screen.blit,程序将根本无法启动。

【讨论】:

  • 好吧,我的错误是 screen 应该被称为 fensterFlaeche 它现在可以为您的 cmets 工作了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多