Erster Versuch mit Pygame

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Antworten
Shikari
User
Beiträge: 9
Registriert: Donnerstag 30. April 2009, 23:21

Hi Leute,

ich habe neu mit Pygame angefangen und jetzt mal den ersten Versuch eines Programms gestartet. Nicht viel, ein Pong-ähnliches Spiel.

Ich würde einfach gerne wissen, wo man etwas besser oder anders machen kann. Außerdem treten häufig Geschwindigkeitsschwankungen im Bereich zwischen 100 und 240 fps auf, wäre gut wenn ich das beheben könnte.

Hier mal mein Quelltext:

Code: Alles auswählen

import pygame

#Linkes Paddel
class Paddle1:
    def __init__(self,surface):
        self.surface = surface
        self.hoehe = 70
        self.breite = 10
        self.x = 50
        self.y = surface.get_height()/2 - self.hoehe/2
        self.color = 255,255,254

    #stelle Paddel dar
    def draw(self):
        pygame.draw.rect(self.surface,self.color,(self.x,self.y,self.breite,self.hoehe))

    #Tastaturbedienung Spieler 1
    def move(self,event):
        if event.key == pygame.K_UP and self.y > 0:
            self.y -= 2
        elif event.key == pygame.K_DOWN and self.y < self.surface.get_height()-self.hoehe:
            self.y += 2


#Ball
class Ball:
    def __init__(self,surface):
        self.surface = surface
        self.x = surface.get_width()/2
        self.y = surface.get_height()/2
        self.xdir = 1
        self.ydir = 1
        self.color = 255,255,255

    #stelle Ball dar
    def draw(self):
        pygame.draw.rect(self.surface,self.color,(self.x,self.y,10,10))

    #Ballbewegung
    def move(self):
        self.x += self.xdir
        self.y += self.ydir


class main():
    pygame.init()
    screen = pygame.display.set_mode((500,400))
    pygame.display.set_caption('PONG')
    clock = pygame.time.Clock()
    pygame.key.set_repeat(1,1)
    pygame.mouse.set_visible(False)
    running = True
        
    #Leben
    lives = 5

    #erstelle Spielfiguren
    ball = Ball(screen)
    paddle1 = Paddle1(screen)

    def DrawString(surface, string, x, y, fontColor, fontSize):
        font = pygame.font.SysFont('Arial', fontSize)
        text = font.render(string, 1, fontColor)
        textpos = text.get_rect()
        textpos.x = x
        textpos.y = y
        surface.blit(text, textpos)
    
    while running:
        string = 'Lives: '+str(lives)
            
        #Richtungswechsel des Balls
        r,g,b,a = ball.surface.get_at((ball.x,ball.y))
        
        if ball.y <= 0 or ball.y >= screen.get_height()-11:
            ball.ydir *= -1
        elif (r,g,b) == (255,255,254) or ball.x >= screen.get_width()-11:
            ball.xdir *= -1

        #Ball im Aus
        elif ball.x <= 0:
            lives -= 1
            ball.x = screen.get_width()/2
            ball.y = screen.get_height()/2
            ball.xdir = 1

    
        screen.fill((0,0,0))

        #zeige verbleibende Leben
        DrawString(screen,string,screen.get_width()/2-50,5,(255,255,255),20)
        
        ball.move()
        ball.draw()
        paddle1.draw()


        #Events
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == pygame.KEYDOWN: 
                paddle1.move(event)

        #Game Over
        if lives == 0:
            print 'GAME OVER\n'
            neu = raw_input('Again? (y/n) ')
            if neu == 'n':
                running = False
            else:
                lives = 5
                paddle1.y = screen.get_height()/2 - paddle1.hoehe/2
                ball.x = screen.get_width()/2
                ball.y = screen.get_height()/2
                ball.xdir = 1
                ball.ydir = 1


        pygame.display.flip()
        clock.tick(240)


if __name__=='__main__':
    main()
Shikari
User
Beiträge: 9
Registriert: Donnerstag 30. April 2009, 23:21

so, das mit den Geschwindigkeitsschwankungen hab ich in den Griff bekommen indem ich das clock.tick() auf 120 gesenkt und die Bewegung des Balls auf 2 erhöht habe.

Ich hoffe, dass ich noch ein paar Tips zu meinem Programm bekomme.

mfg Shikari
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Der Code ist leicht verständlich und ziemlich gut geworden :)

Allerdings solltest du aus der main() Klasse eine Funktion machen und Paddle1 hätte ich eher gleich LeftPaddle oder UserPaddle genannt.

In diesem Fall fällt es jetzt nicht auf aber im Allgemeinen sollte man eher New-Style Klassen verwenden die mit Python 3 die "normalen" Klassen ersetzt haben. Außerdem wäre es sinnvoll sich an den Styleguide zu halten.
Zuletzt geändert von DasIch am Freitag 1. Mai 2009, 22:55, insgesamt 1-mal geändert.
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Aus Zeile 4, 14, 18, 36 und 40 würde ich Docstrings machen. Die Kommentare in Zeile 26 und 55 sind überflüssig. Das sind aber eher Kleinigkeiten, ansonsten schließe ich mich DasIch an.
mayx
User
Beiträge: 71
Registriert: Sonntag 3. Mai 2009, 02:51

Ich würde die Tastenlogik aus der Paddle Klasse entfernen und die Klasse nur Paddle nennen.
Beim TastenEvent lieber die Funktion Move mit den gewünschten X,Y-Werten aufrufen.

Code: Alles auswählen

class Paddle:
    def __init__(self,surface):
        self.surface = surface
        self.hoehe = 70
        self.breite = 10
        self.x = 50
        self.y = surface.get_height()/2 - self.hoehe/2
        self.color = 255,255,254

    #stelle Paddel dar
    def draw(self):
        pygame.draw.rect(self.surface,self.color,(self.x,self.y,self.breite,self.hoehe))

    #Paddle bewegen
    def move(self,x,y): 
        self.x += x
        if self.y > 0 and self.y < self.surface.get_height()-self.hoehe:
            self.y += y
            
        if self.y == 0:
            if y > 0:
                self.y += y   
        if self.y == self.surface.get_height()-self.hoehe:
            if y < 0:
                self.y += y

Code: Alles auswählen

#Events
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == pygame.KEYDOWN:  
                if event.key == pygame.K_UP:
                    paddle1.move(0,-1)
                    paddle2.move(0,-1)
                elif event.key == pygame.K_DOWN:
                    paddle1.move(0,1)
                    paddle2.move(0,1)
                if event.key == pygame.K_a:
                    paddle2.move(-1,0)
                elif event.key == pygame.K_s:
                    paddle2.move(1,0)
                
du siehst das man so auch mehrere paddles wunderbar steuern kann.
Zuletzt geändert von mayx am Montag 18. Mai 2009, 14:17, insgesamt 2-mal geändert.
Shikari
User
Beiträge: 9
Registriert: Donnerstag 30. April 2009, 23:21

Danke für die Tipps, werde, wenn ich mal wieder etwas Zeit finde, mein Programm überarbeiten.
Antworten