Problem mit Pygame Programm

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Antworten
PyBeginner
User
Beiträge: 19
Registriert: Sonntag 7. Juli 2013, 12:45

Samstag 16. November 2013, 11:15

Hallo Leute,
ich wollte mit Pygame nun ein Android Spiel machen und wollte deshalb ein Programm schreiben in dem man über 2 Buttons den Spieler lenken kann (Mouse Events werden mit dem Androi Subset ja zu Touch Events).
Nur leider bekomme ich immer Fehler Meldungen...
Hier der Code:

Code: Alles auswählen

import pygame, sys
from pygame.locals import*
pygame.init()
FPS = 30
clock = pygame.time.Clock()


size = (480, 320)
screen = pygame.display.set_mode(size)
RED = (255, 155, 0)
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
p_rect = pygame.Rect(0, 0, 64, 64)
px = 0
py = 0
right_rect = pygame.Rect(100, 100, 50, 50)
left_rect = pygame.Rect(100, 120, 50, 50)


direction = "no"

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
if event.type == MOUSEBUTTONDOWN:
    mouse_pos = pygame.mouse.get_pos()
    if right_rect.collidepoint(mouse_pos):
        direction = "right"
px += 1
if event.type == MOUSEBUTTONDOWN:
    mouse_pos = pygame.mouse.get_pos()
    if left_rect.collidepoint(mouse_pos):
        direction = "left"
px += -1
   


screen.fill(BLACK)
pygame.draw.rect(screen, RED, p_rect)

pygame.draw.rect(screen, GREEN, right_rect)
pygame.draw.rect(screen, BLUE, left_rect)



if direction == "left":
    p_rect.centerx -= 1
elif direction == "right":
    p_rect.centerx -= 1
elif direction == "no":
    p_rect.centerx == 0
    

pygame.display.update()
Einige Teil des Codes sind von: http://www.youtube.com/user/surfkidsdad ... sp-in-feed
bzw. von seinen Videos.

Nun mein Problem:
Wenn ich das ganze Debugge passiert nichts.
Es öffnet sich die IDLE und das wars.
Wenn ich als event:
if event.type == MOUSEBUTTONUP:
direction = "no"
eingebe, dann kommt ein Fehler zu MOUSEBUTTONUP.

Bitte helft mir und sagt mir was ich falsch mache. :?:
PS: Ich hab PyGame und Python noch nicht so lange und bin noch ziemlicher Anfänger

Danke
Zuletzt geändert von Anonymous am Samstag 16. November 2013, 12:35, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
Sirius3
User
Beiträge: 7909
Registriert: Sonntag 21. Oktober 2012, 17:20

Samstag 16. November 2013, 11:36

Hallo PyBeginner,
nutze bitte die Code-Umgebung des Forums um Programmcode zu posten. Da in Python die Einrückungen essentiell sind, kann man an Deinem Programm hier nichts mehr lesen. Außerdem solltest Du nicht nur sagen, dass es einen Fehler gibt, sondern auch welchen und wo. Das hilft schon sehr viel weiter.
BlackJack

Samstag 16. November 2013, 13:13

@PyBeginner: Wie Sirius3 schon schrieb: Bei Python ist die Einrückung wichtig, weil die bestimmt was zu einem Block und damit zum Beispiel zu einem Schleifenkörper gehört. Also was *in* der Schleife immer wieder ausgeführt wird und was *nach* der Schleife, wenn der Schleifenkörper verlassen wird, ausgeführt wird. Und nun mach Dir mal klar was *in* der ``while``-Schleife ausgeführt wird. Und was *nicht*.

Ansonten fällt noch auf, das `px` und `py` gar nicht verwendet werden, jedenfalls nicht in einer Weise die irgendeinen Effekt hätte.

Die Mausposition ist Bestandteil von Mausereignissen, also als Attribut auf dem `event`-Objekt verfügbar. Darum würde ich die von dort nehmen und nicht per Funktionsaufruf ermitteln. Das macht hier wohl noch keinen Unterschied, aber irgendwann kann es wichtig sein die Position an der Stelle wo der Mausknopf gedrückt wurde zu verwenden, statt der Position die kurz nach dem drücken des Mausknopfs ermittelt wird und schon ein paar Pixel entfernt sein kann.

Bei der Auswertung der `direction` im 'no'-Fall macht der Ausdruck in Zeile 54 keinen Sinn. Dort wird das `centerx`-Attribut mit 0 verglichen. Da kommt dann `True` oder `False` bei heraus, aber mit dem Wert wird dann nichts gemacht. Die Zeile hat also überhaupt keinen Effekt und kann auch einfach weggelassen werden, und damit das gesamte ``elif`` für diesen Fall.

Man könnte sich auch die Indirektion über Zeichenketten sparen und Konstanten für `MOVE_LEFT`, `NO_MOVEMENT`, und `MOVE_RIGHT` als -1, 0, und 1 definieren und dann direkt `direction` addieren ohne dass man da so eine Unterscheidung der drei Fälle braucht.

Wenn das soweit läuft, solltest Du als nächsten Schritt Funktionen definieren lernen und keinen Code mehr auf Modulebene schreiben der nicht Klassen, Funktionen, oder Konstanten definiert.
BlackJack

Samstag 16. November 2013, 13:45

@PyBeginner: `clock` und `FPS` werden auch nicht verwendet. Sollten sie aber vielleicht, damit die CPU nicht unnötig auf Vollast läuft und die Bewegungsgeschwindigkeit nicht abhängig von der Hardwareleistung ist.

Abkürzungen in Namen sollte man vermeiden. Namen sollten dem Leser die Bedeutung des Wertes der dahinter steckt verraten ohne das der Leser rästeln muss was die Abkürzung vielleicht bedeuten mag. Ich rate jetzt mal das das 'p' in `p_rect` für `player` steht. Dann sollte man das auch schreiben.

Den Test ob der Mausknopf gedrückt ist muss man nur einmal machen. Falls er gedrückt ist kann man in dem ``if``-Zweig dann die beiden Rechtecke nacheinander testen.
PyBeginner
User
Beiträge: 19
Registriert: Sonntag 7. Juli 2013, 12:45

Samstag 16. November 2013, 13:58

Erstmal danke für die schnellen Antworten.
Ich werde das, was ihr gesagt habt gleich ausprobieren.
Das mit der Code umgebung wollte ich eigentlich machen, hab aber nicht gewusst wie.
Sirius3 hat geschrieben:Hallo PyBeginner,
nutze bitte die Code-Umgebung des Forums um Programmcode zu posten. Da in Python die Einrückungen essentiell sind, kann man an Deinem Programm hier nichts mehr lesen. Außerdem solltest Du nicht nur sagen, dass es einen Fehler gibt, sondern auch welchen und wo. Das hilft schon sehr viel weiter.
Das mit dem Fehler ist das Problem:
Bei mir wird keiner angezeigt, das PyGame Fenster öffnet sich aber nicht. Einmal hat es sich geöffnet, aber ohne den Player und die Buttons. Der Bildschirm war nur schwarz...

Noch mal danke und ich meld mich wieder wenn ich eure Vorschläge ausprobiert habe.
MfG PyBeginner
BlackJack

Samstag 16. November 2013, 14:11

@PyBeginner: Am besten startest Du das Programm aus der Konsole und nicht aus IDLE. Dann kannst Du sicher sein, dass alle Ausgaben auf der Standardausgabe erscheinen und das sich IDLE und Pygame nicht gegenseitig mit der Abfrage der GUI in die Quere kommen.

`clock` und `FPS` werden auch nicht verwendet. Sollten sie aber vielleicht, damit die CPU nicht unnötig auf Vollast läuft und die Bewegungsgeschwindigkeit nicht abhängig von der Hardwareleistung ist.

Abkürzungen in Namen sollte man vermeiden. Namen sollten dem Leser die Bedeutung des Wertes der dahinter steckt verraten ohne das der Leser rästeln muss was die Abkürzung vielleicht bedeuten mag. Ich rate jetzt mal das das 'p' in `p_rect` für `player` steht. Dann sollte man das auch schreiben.

Den Test ob der Mausknopf gedrückt ist muss man nur einmal machen. Falls er gedrückt ist kann man in dem ``if``-Zweig dann die beiden Rechtecke nacheinander testen.

Code: Alles auswählen

import sys
import pygame
from pygame.locals import *

BLACK = (0, 0, 0)
BLUE = (0, 0, 255)
GREEN = (0, 255, 0)
RED = (255, 155, 0)

FPS = 30

MOVE_LEFT, NO_MOVEMENT, MOVE_RIGHT = -1, 0, 1


def main():
    pygame.init()
    clock = pygame.time.Clock()
     
    screen = pygame.display.set_mode((480, 320))
    player_rect = pygame.Rect(0, 0, 64, 64)
    right_rect = pygame.Rect(100, 100, 50, 50)
    left_rect = pygame.Rect(100, 120, 50, 50)
    direction = NO_MOVEMENT
     
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == MOUSEBUTTONDOWN:
                if right_rect.collidepoint(event.pos):
                    direction = MOVE_RIGHT
                if left_rect.collidepoint(event.pos):
                    direction = MOVE_LEFT
     
        screen.fill(BLACK)
        pygame.draw.rect(screen, RED, player_rect)
        pygame.draw.rect(screen, GREEN, right_rect)
        pygame.draw.rect(screen, BLUE, left_rect)
        pygame.display.update()
        
        player_rect.centerx += direction

        clock.tick(FPS)


if __name__ == '__main__':
    main()
PyBeginner
User
Beiträge: 19
Registriert: Sonntag 7. Juli 2013, 12:45

Samstag 16. November 2013, 15:08

Super, danke!!
Das ist genau das was ich brauche.
Nur eine Sache noch: Ich wollte mit dem direction = "no" dafür sorgen, dass wenn kein Button angeklickt wird, dass der Player stehen bleibt.
Ist das noch irgendwie möglich?
Nochmals vielen Dank! :D
BlackJack

Samstag 16. November 2013, 19:00

@PyBeginner: Ja das ist möglich. Da musst Du jetzt mal überlegen an welcher Stelle und bei welchem Ereignis Du `direction` entsprechend binden musst.
PyBeginner
User
Beiträge: 19
Registriert: Sonntag 7. Juli 2013, 12:45

Samstag 16. November 2013, 19:49

Habs geschafft!!!
Danke!
Hab einfach:

Code: Alles auswählen


            elif event.type == MOUSEBUTTONUP:
                    direction = NO_MOVEMENT
hinzugefügt :D

Ich hab zuvor nur nicht gewusst, dass die Einrückungen wichtig sind. :mrgreen: :K
Bin halt noch ein Anfänger...

EDIT: Weiß zufällig jemand wie man eine .py Datei zu einer .apk macht? Ich meine mit dem Android Subset für Pygame. Das Subset braucht man ja dazu, aber zu einer .apk Datei muss man es trotzdem "machen".
Danke
PyBeginner
User
Beiträge: 19
Registriert: Sonntag 7. Juli 2013, 12:45

Sonntag 17. November 2013, 16:08

Noch eine Frage:
Wie kann ich in mein Spiel einbauen, dass ein Schuss vom Player aus auf Knopfdruck auf der x Position des Players erscheint und sich dann bis zum Bildschirmrand bewegt.

Achja: Man muss eine Klasse erstellen, dass damit man mehrere Schüsse hintereinander abfeuern kann, oder?
Gibts dazu irgendwelche Tutorials oder so? Also wie man Klassen erstellt.

Danke
MfG PyBeginner :D
Antworten