Pygame Sprite nicht steuerbar

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Antworten
Albireo
User
Beiträge: 2
Registriert: Donnerstag 13. April 2017, 22:35

Hallo liebe Python-Community,

ich habe mich neulich mit Pygame befasst und bin dabei dem Tutorial von "KidsCanCode" auf YouTube (https://www.youtube.com/playlist?list=P ... m9NhsW0Urw) gefolgt.
An der Stelle, an der man einen Sprite über die Pfeiltasten steuerbar machen möchte, ist mir aufgefallen, dass sich das Fenster, in dem sich das Spiel öffnet, immer im Hintergrund befindet. Klicke ich es an, verschwindet es wieder hinter anderen Programmfenstern und selbst auf einem leeren Desktop wird mir das Fenster als inaktiv / nicht vordergründig angezeigt.
So kann ich natürlich nicht mit dem Spiel interagieren. Ich weiß zwar nicht, ob das ein Python-spezifisches Problem ist, oder ob der Fehler an einer ganz anderen Stelle liegt, aber hier ist trotzdem der Code:

Code: Alles auswählen

# Pygame template - skeleton for a new pygame project
import pygame
import random

WIDTH = 600
HEIGHT = 480
FPS = 30

# define colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)


class Player(pygame.sprite.Sprite):
    # sprite for the Player
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((50, 50))
        self.image.fill(GREEN)
        self.rect = self.image.get_rect()
        self.rect.centerx = WIDTH / 2
        self.rect.bottom = HEIGHT - 10
        self.speedx = 0

    def update(self):
        self.speedx = 0
        keystate = pygame.key.get_pressed()
        if keystate[pygame.K_LEFT]:
            self.speedx = -5
        if keystate[pygame.K_RIGHT]:
            self.speedx = 5
        self.rect.x += self.speedx
        if self.rect.right > WIDTH:
            self.rect.right = WIDTH
        if self.rect.left < 0:
            self.rect.right = 0


# initialize pygame and create window
pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("My Game")
clock = pygame.time.Clock()

all_sprites = pygame.sprite.Group()
player = Player()
all_sprites.add(player)

# Game loop
running = True
while running:
    # keep loop runnig at the right speed
    clock.tick(FPS)
    # Process input (events)
    for event in pygame.event.get():
        # check for closing window
        if event.type == pygame.QUIT:
            running = False
    # Update
    all_sprites.update()

    # Draw / render
    screen.fill(BLACK)
    all_sprites.draw(screen)
    # *after* drawing everything, flip the display
    pygame.display.flip()

pygame.quit()

Lässt sich der Sprite bei euch bewegen? Hat jemand eine Idee, warum es bei mir nicht funktioniert?
Falls ihr Informationen zu meinem System braucht: macOS 10.12.4, Python 3.5.1, Anaconda 4.1.0

Vielen Dank
Gruß
Zuletzt geändert von Anonymous am Freitag 14. April 2017, 01:55, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@Albireo: Bei mir funktioniert es. Bis auf den kleinen Fehler das man nach links nicht über den Rand hinausgehen sollte weil das Sprite dann verschwindet und auch nicht wieder auf das Spielfeld bewegt werden kann.

Und `pygame.key.get_pressed()` würde ich eher nicht verwenden.
Albireo
User
Beiträge: 2
Registriert: Donnerstag 13. April 2017, 22:35

@BlackJack
Danke für deine Antwort. Ah ja, in der Update-Methode habe ich beim linken Bildschirmrand self.rect.right auf 0 gesetzt, da sollte self.rect.left stehen.
Was würdest du denn statt pygame.key.get_pressed() empfehlen?
Mein Problem scheint ja wohl tatsächlich nicht am Code zu liegen, aber hast du (oder jemand anders) vielleicht trotzdem eine Idee, warum es bei mir nicht funktioniert?
Lou Cyphr3
User
Beiträge: 59
Registriert: Donnerstag 6. Juli 2017, 00:04

Ich hab mir das Tutorial auch nochmal angeschaut. Man kann den Code im übrigen auch da downloaden.

nun hab ich folgendes problem

ich hab diesen code

Code: Alles auswählen

# Pygame sprite Example
import pygame
import random

WIDTH = 800
HEIGHT = 600
FPS = 30

# define colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)

class Player(pygame.sprite.Sprite):
    # sprite for the Player
    def __init__(self):
        # this line is required to properly create the sprite
        pygame.sprite.Sprite.__init__(self)
        # create a plain rectangle for the sprite image
        self.image = pygame.Surface((50, 50))
        self.image.fill(GREEN)
        # find the rectangle that encloses the image
        self.rect = self.image.get_rect()
        # center the sprite on the screen
        self.rect.center = (WIDTH / 2, HEIGHT / 2)

    def update(self):
        # any code here will happen every time the game loop updates
        self.rect.x += 5
        if self.rect.left > WIDTH:
            self.rect.right = 0

# initialize pygame and create window
pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Sprite Example")
clock = pygame.time.Clock()

all_sprites = pygame.sprite.Group()
player = Player()
all_sprites.add(player)
# Game loop
running = True
while running:
    # keep loop running at the right speed
    clock.tick(FPS)
    # Process input (events)
    for event in pygame.event.get():
        # check for closing window
        if event.type == pygame.QUIT:
            running = False

    # Update
    all_sprites.update()

    # Draw / render
    screen.fill(BLACK)
    all_sprites.draw(screen)
    # *after* drawing everything, flip the display
    pygame.display.flip()

pygame.quit()
welcher wundabar funktioniert( der grüne Kasten soll so laufen).
Nun wollte ich den grünen Kasten mit ner Grafik ersetzen, allerdings gibt es mir aus, dass es die Grafik nicht öffnen kann. Warum?

Code: Alles auswählen

# Pygame sprite Example
import pygame
import random
import os

WIDTH = 800
HEIGHT = 600
FPS = 30

# define colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)

# ordner mit grafik

grafic_folder = os.path.dirname('/home/*****/Schreibtisch/python/Grafic')
img_folder = os.path.join(grafic_folder, 'img')

class Player(pygame.sprite.Sprite):
    # sprite for the Player
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(os.path.join(img_folder, "p1_jump.png")).convert()       
        self.rect = self.image.get_rect()
        self.rect.center = (WIDTH / 2, HEIGHT / 2)

    def update(self):
        # any code here will happen every time the game loop updates
        self.rect.x += 5
        if self.rect.left > WIDTH:
            self.rect.right = 0

# initialize pygame and create window
pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("grünes ding")
clock = pygame.time.Clock()

all_sprites = pygame.sprite.Group()
player = Player()
all_sprites.add(player)
# Game loop
running = True
while running:
    # keep loop running at the right speed
    clock.tick(FPS)
    # Process input (events)
    for event in pygame.event.get():
        # check for closing window
        if event.type == pygame.QUIT:
            running = False

    # Update
    all_sprites.update()

    # Draw / render
    screen.fill(BLACK)
    all_sprites.draw(screen)
    # *after* drawing everything, flip the display
    pygame.display.flip()

pygame.quit()
Cours, camarade, le vieux monde est derrière toi!
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich bezweifele das der Orden “Schreibtisch” heißt. Sondern eher Desktop. Navigier in der Shell dahin wo das Bild liegt & lass dir den Pfad mittels pwd ausgeben.
Lou Cyphr3
User
Beiträge: 59
Registriert: Donnerstag 6. Juli 2017, 00:04

bei der deutschen Version von Mint 18.1 Cinnamon heißt es tatsächlich Schreibtisch. Das kann es nicht sein. Ich hab den Pfad auch direkt aus der Grafik entnommen.
Cours, camarade, le vieux monde est derrière toi!
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Dann zeig mal die genaue Fehlermeldung, und pruefe die Existenz des Pfades bevor du den oeffnest mit "assert os.path.exists(full_path)".
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@__deets__: `assert` ist nur dafür gedacht, Programmierfehler zu erkennen, wenn die Bedingung von externen Faktoren abhängig ist, muß man mit `if ...` prüfen.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

@Sirus3 genau, und weil das Programm eh nicht funktionsfaehig ist ohne ein Bild testet das assert die Vorbedingung eines existenten Bilds ab. Ist IMHO genau dafuer gedacht.
Lou Cyphr3
User
Beiträge: 59
Registriert: Donnerstag 6. Juli 2017, 00:04

[codebox=powershell file=Unbenannt.ps1]pygame.error: Couldn't open img/p1_jump.png
[/code]

den pfad gibt's

die grafik ist auch im selben ordner

fällt mir vllt eine komponente, weil mit wav.datein geht.es.mir ähnlich
Cours, camarade, le vieux monde est derrière toi!
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Der Pfad ist aber relativ, nicht absolut wie dein Skript suggeriert.

Du musst schon existierende Pfade angeben, und relative Pfade beziehen sich auf das current working directory des Prozesses, welches ueblicherweise nicht das Verzeichnis ist, in dem das Skript selbst liegt. Wenn man so etwas will, dann kann man zB so vorgehen:

Code: Alles auswählen

BASE = os.path.abspath(os.path.dirname(__file__)
IMAGE = os.path.join(BASE, "mein.png")
unter der Annahme, das
irgendein/pfad/skript.py
irgendein/pfad/mein.png
vorliegen.
Lou Cyphr3
User
Beiträge: 59
Registriert: Donnerstag 6. Juli 2017, 00:04

Danke hat funktioniert.
Cours, camarade, le vieux monde est derrière toi!
Antworten