Seite 1 von 1

Erster Versuch mit Pygame

Verfasst: Donnerstag 30. April 2009, 23:36
von Shikari
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()

Verfasst: Freitag 1. Mai 2009, 19:57
von Shikari
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

Verfasst: Freitag 1. Mai 2009, 20:11
von DasIch
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.

Verfasst: Freitag 1. Mai 2009, 21:55
von derdon
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.

Verfasst: Montag 18. Mai 2009, 13:40
von mayx
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.

Verfasst: Montag 18. Mai 2009, 14:06
von Shikari
Danke für die Tipps, werde, wenn ich mal wieder etwas Zeit finde, mein Programm überarbeiten.