Problem bei K_RIGHT/LEFT

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Antworten
Miro Santino
User
Beiträge: 4
Registriert: Dienstag 16. Juni 2020, 20:27

Hallo ich bin Miro und ich bin 10 Jahre alt

Ich programmiere gerade an einem Tetris und habe ein Problem.Habe schon umgefär analysiert wo das Problem ist und brauch Hilfe es genau zu finden um es zu Lösen.

Hier ist der code:

Code: Alles auswählen

import pygame as pg 
from dataclasses import dataclass 

BREITE, SPALTEN, ZEILEN = 400, 10, 20
ABSTAND = BREITE // SPALTEN
HÖHE = ABSTAND * ZEILEN
grid = [0] * SPALTEN * ZEILEN
speed = 500

pg.init()

display_width = 800
display_height = 600

gameDisplay = pg.display.set_mode((display_width,display_height))
pg.display.set_caption('A bit Racey')

black = (0,0,0)
white = (255,255,255)

clock = pg.time.Clock()
crashed = False

bilder = []
for n in range(8):
  bilder.append(pg.transform.scale(pg.image.load(f'Tetrominos\\Cube_{n}.jpg'),(ABSTAND,ABSTAND)))

tetrominoes = [[0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0],       
               [0,0,0,0,3,3,3,3,0,0,0,0,0,0,0,0],
               [0,0,0,0,5,5,5,0,0,0,5,0,0,0,0,0],
               [0,0,7,0,7,7,7,0,0,0,0,0,0,0,0,0],
               [0,2,2,0,2,2,0,0,0,0,0,0,0,0,0,0],
               [4,4,0,0,0,4,4,0,0,0,0,0,0,0,0,0],
               [0,0,0,0,6,6,6,0,0,6,0,0,0,0,0,0]]
               
@dataclass
class Tetrominoe():
  tet : list
  zeile : int = 0
  spalte : int = 3
  
  def show(self):
    for n, farbe in enumerate(self.tet):
      if farbe > 0:
        y = (self.zeile + n // 4) * ABSTAND 
        x = (self.spalte + n % 4) * ABSTAND
        screen.blit(bilder[farbe], (x,y))

  def update(self, zoff, soff):
    self.zeile += zoff
    self.spalte += soff


def car(x,y):
    gameDisplay.blit(carImg, (x,y))

x =  (display_width * 0.45)
y = (display_height * 0.8)
x_change = 0
car_speed = 0

while not crashed:
    for event in pg.event.get():
        if event.type == pg.QUIT:
            crashed = True

        ############################
        if event.type == pg.KEYDOWN:
            if event.key == pg.K_LEFT:
                x_change = -5
            elif event.key == pg.K_RIGHT:
                x_change = 5
        if event.type == pg.KEYUP:
            if event.key == pg.K_LEFT or event.key == pg.K_RIGHT:
                x_change = 0
        ######################
    ##
    x += x_change
   ##         
    gameDisplay.fill(white)
    car(x,y)
        
    pg.display.update()
    clock.tick(60)

pygame.quit()
quit()
Benutzeravatar
__blackjack__
User
Beiträge: 13082
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Miro Santino: Und was ist jetzt das Problem bei dem Du nicht weiterkommst? Das sind ja mehrere, welches ist Dir denn jetzt aufgefallen und wie? Was machst Du genau, was passiert draufhin, und wie weicht das von dem ab was Du erwartest? Gibt es eine Ausnahme? Falls ja welche? Bitte komplett 1:1 den gesamten Traceback zeigen.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
__blackjack__
User
Beiträge: 13082
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Miro Santino: Allgemeine Anmerkungen zum Quelltext:

Eingerückt wird in Python mit vier Leerzeichen pro Ebene.

Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst. Besonders unübersichtlich ist es wenn man Code vom Hauptprogramm auf Modulebene mit Funktionsdefinitionen mischt.

Die Klasse `Tetrominoe` wird nirgends verwendet. Damit fällt auch die Abhängigkeit vom `dataclasses`-Modul. (Wenn ich da schon etwas externes einbinde, würde ich eher `attr` nehmen, das zwingt einen nicht zu Typannotationen die man, wenn man sie verwendet, auch mit einem zusätzlichen Werkzeug prüfen muss, damit da am Ende nix falsches steht.)

`black`, `car_speed`, `grid`, `speed`, und `tetrominoes` werden definiert, aber nirgends verwendet.

`display_width`, `display_height`, und `white` sollten wohl eher Konstanten sein.

Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase).

Pfadtrenner sollten nicht hart im Quelltext stehen. Selbst wenn ich ein ``Tetrominos/``-Verzeichnis hätte und da die entsprechenden Bilddateien drin liegen würden — \ ist auf meinem Rechner der falsche Pfadtrenner. Für so etwas gibt es das `pathlib`-Modul.

Zum erstellen der `bilder`-Liste würde sich eine „list comprehension“ anbieten.

Code: Alles auswählen

    bilder = [
        pg.transform.scale(
            pg.image.load(
                str(Path("Tetrominos", f"Cube_{n}.jpg")), (ABSTAND, ABSTAND),
            )
        )
        for n in range(8)
    ]
Aber auch `bilder` wird nirgends verwendet.

Den Test auf die beiden möglichen Tasten im KEY_UP-Fall kann man durch ``in`` etwas vereinfachen.

Bei den Tests des Ereignistyps macht ``if`` nur beim ersten Zweig Sinn, denn der Wert kann nur *einen* Wert annehmen. Die Bedingungen schliessen sich gegenseitig aus, also ``elif``.

Die `car()`-Funktion hat einen schlechten Namen. Funktions und Methodennamen beschreiben üblicherweise Tätigkeiten. `car` ist keine Tätigkeit. Da würde man eher ein Objekt erwarten das ein Auto repräsentiert.

Funktionen und Methoden sollten alles was sie ausser Konstanten benötigen als Argument(e) übergeben bekommen. `car()` fehlt also `gameDisplay` und `carImg` als Argumente. Wobei `carImg` undefiniert ist. Was soll das denn sein?

Nach der Schleife wird versucht `pygame.quit()` aufzurufen aber `pygame` ist nicht definiert. Das sollte wohl `pg.quit()` heissen.

Die `quit()`-Funktion gibt es eigentlich gar nicht und es ist auch völlig unnötig da noch irgendetwas zu machen. Das Programm endet da ganz normal.

Zwischenstand (ungetestet):

Code: Alles auswählen

#!/usr/bin/env python3
from pathlib import Path

import pygame as pg

BREITE, SPALTEN, ZEILEN = 400, 10, 20
ABSTAND = BREITE // SPALTEN
HÖHE = ABSTAND * ZEILEN
DISPLAY_WIDTH = 800
DISPLAY_HEIGHT = 600
WHITE = (255, 255, 255)


def main():
    pg.init()
    game_display = pg.display.set_mode((DISPLAY_WIDTH, DISPLAY_HEIGHT))
    pg.display.set_caption("A bit Racey")

    x = DISPLAY_WIDTH * 0.45
    y = DISPLAY_HEIGHT * 0.8
    x_change = 0
    clock = pg.time.Clock()
    crashed = False
    while not crashed:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                crashed = True

            elif event.type == pg.KEYDOWN:
                if event.key == pg.K_LEFT:
                    x_change = -5
                elif event.key == pg.K_RIGHT:
                    x_change = 5
            
            elif event.type == pg.KEYUP:
                if event.key in [pg.K_LEFT, pg.K_RIGHT]:
                    x_change = 0

        x += x_change
        game_display.fill(WHITE)
        #
        # FIXME `car_image` ist undefiniert!
        #
        game_display.blit(car_image, (x, y))
        pg.display.update()
        clock.tick(60)

    pg.quit()


if __name__ == "__main__":
    main()
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Miro Santino
User
Beiträge: 4
Registriert: Dienstag 16. Juni 2020, 20:27

Vielen vielen Dank für die Hilfe. Ich werde die Sachen ausprobieren.

Und 3 Sachen

1.Es tut mir wirklich wirklich leid ich habe den Unvollständigen eingetragen. Hier findest du den richtigen Code :

Code: Alles auswählen

import pygame as pg 
from dataclasses import dataclass 

BREITE, SPALTEN, ZEILEN = 400, 10, 20
ABSTAND = BREITE // SPALTEN
HÖHE = ABSTAND * ZEILEN
grid = [0] * SPALTEN * ZEILEN
speed = 500

pg.init()

display_width = 800
display_height = 600

gameDisplay = pg.display.set_mode((display_width,display_height))
pg.display.set_caption('A bit Racey')

black = (0,0,0)
white = (255,255,255)

clock = pg.time.Clock()
crashed = False

bilder = []
for n in range(8):
  bilder.append(pg.transform.scale(pg.image.load(f'Tetrominos\\Cube_{n}.jpg'),(ABSTAND,ABSTAND)))

tetrominoes = [[0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0],       
               [0,0,0,0,3,3,3,3,0,0,0,0,0,0,0,0],
               [0,0,0,0,5,5,5,0,0,0,5,0,0,0,0,0],
               [0,0,7,0,7,7,7,0,0,0,0,0,0,0,0,0],
               [0,2,2,0,2,2,0,0,0,0,0,0,0,0,0,0],
               [4,4,0,0,0,4,4,0,0,0,0,0,0,0,0,0],
               [0,0,0,0,6,6,6,0,0,6,0,0,0,0,0,0]]
               
@dataclass
class Tetrominoe():
  tet : list
  zeile : int = 0
  spalte : int = 3
  
  def show(self):
    for n, farbe in enumerate(self.tet):
      if farbe > 0:
        y = (self.zeile + n // 4) * ABSTAND 
        x = (self.spalte + n % 4) * ABSTAND
        screen.blit(bilder[farbe], (x,y))

  def update(self, zoff, soff):
    self.zeile += zoff
    self.spalte += soff


def car(x,y):
    gameDisplay.blit(carImg, (x,y))

x =  (display_width * 0.45)
y = (display_height * 0.8)
x_change = 0
car_speed = 0

while not crashed:
    for event in pg.event.get():
        if event.type == pg.QUIT:
            crashed = True
            
figur = Tetrominoe(tetrominoes[3])

weitermachen = True
clock = pg.time.Clock()
while weitermachen:
  clock.tick(80)
  for event in pg.event.get():
    if event.type == pg.QUIT:
      weitermachen = False
    if event.type == TETROMINODOWN:
      figur.update(1,0)
      if event.type == SPEEDUP:
        speed = int(speed * 0.8)
        pg.time.set_timer(TETROMINODOWN, speed)
      if event.type == pg.KEYDOWN:
            if event.key == pg.K_LEFT:
                x_change = -5
            elif event.key == pg.K_RIGHT:
                x_change = 5
      if event.type == pg.KEYUP:
      if event.key == pg.K_LEFT or event.key == pg.K_RIGHT:
                x_change = 0
    screen.fill((0,0,0))
    figur.show()
    
  for n, farbe in enumerate(grid):
    if farbe > 0:
      x = n % SPALTEN * ABSTAND
      y = n // SPALTEN * ABSTAND
      screen.blit(bilder[farbe],(x,y))
    
  pg.display.flip()

        ############################
        if event.type == pg.KEYDOWN:
            if event.key == pg.K_LEFT:
                x_change = -5
            elif event.key == pg.K_RIGHT:
                x_change = 5
        if event.type == pg.KEYUP:
            if event.key == pg.K_LEFT or event.key == pg.K_RIGHT:
                x_change = 0
        ######################
    ##
    x += x_change
   ##         
    gameDisplay.fill(white)
    car(x,y)
        
    pg.display.update()
    clock.tick(60)

pygame.quit()
quit()
2. Den Code Habe ich von einem Tutorial das ich gerade mache. Die Variablen sind für Später im Tutorial.

3. Es ging um die Funktion KEYDOWN die nicht funktioniert hat.Wen ich Pygame aufgemacht habe ist das Tetris erschienen das ich schon Programmiert hatte aber als ich die Pfeiltasten Betätigt habe ist einfach nichts Passiert. Hier ist das Stück Code :

Code: Alles auswählen

if event.type == pg.KEYDOWN:
            if event.key == pg.K_LEFT
Benutzeravatar
__blackjack__
User
Beiträge: 13082
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Miro Santino: Der Code jetzt kommt nicht mal am Compiler vorbei weil da Teile syntaktisch falsch eingerückt sind. Mir scheint auch dass das nicht *ein* Programm ist, denn `crashed` und `car` klingt mehr nach einem Autorennspiel denn nach Tetris. Diese Teile machen bei Tetris keinen Sinn.

Die Datenstruktur für die Tetrominos sind unnötig einfach was den Code der darauf zugreift unnötig kompliziert macht. Statt pro Tetromino eine eindimensionale Liste zu haben und die per Rechenoperationen jedes mal als zweidimensionale Struktur zu ”sehen” wäre es viel einfacher und verständlicher jedes Tetromino durch eine zweidimensionale Struktur zu repräsentiern. Da die einfarbig sind, würde ich die Farbe auch separat speichern und in der 2D-Struktur nur ob da ein Kästchen ist oder nicht.

Das mit der Struktur gilt auch für `grid`. Das ist eine 2D-Struktur und ich sehe keinen sinnvollen Grund das in einer eindimensionalen Liste zu speichern.

Insgesamt ist das alles viel zu unübersichtlich und chaotisch.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Miro Santino
User
Beiträge: 4
Registriert: Dienstag 16. Juni 2020, 20:27

Hallo tut mir leid das es länger gedauert hat es ist jetzt ja wieder Schule

danke nochmal für die Tipps sie haben geholfen und es hat funktioniert,
ich habe die Tabs richtig gemacht und ein paar fehlende Stücke Text hinzugefügt.

den original Text lerne ich wie schon gesagt, aus einem Tutorial und der Ersteller verwendet noch 2 Leerzeichen als Tabs und etwas veraltete Arten. Link: https://www.youtube.com/watch?v=_0RWx78VwOk&t=1301s

und ich habe ein neues Problem:Man kann jetzt die Figur bewegen und der Spielrand ist festgelegt, jetzt
habe ich eine Funktion gemacht mit der das unten liegende Tetrominoe aus Spielraster soll, stattdessen
erscheinen oben jetzt komische, verbundene und Falsche Tetrominoes, wenn das Tetrominoe unten ist.
Und ich habe diese mal schon ausprobiert und es liegt nicht an den Tabs, aber in der Schleife Weitermachen: wiederholt sich ein bestimmter teil und ich weiß nicht wie ich das beende kann.
Code:

Code: Alles auswählen

 
import pygame as pg 
from dataclasses import dataclass


BREITE, SPALTEN, ZEILEN = 400, 10, 20
ABSTAND = BREITE // SPALTEN
HÖHE = ABSTAND * ZEILEN
grid = [0] * SPALTEN * ZEILEN 
speed = 500

bilder = []
for n in range(8):
    bilder.append(pg.transform.scale(pg.image.load(f'Tetrominos\\Cube_{n}.jpg'),(ABSTAND,ABSTAND)))

pg.init()
screen = pg.display.set_mode([BREITE, HÖHE])
TETROMINODOWN = pg.USEREVENT+1
SPEEDUP = pg.USEREVENT+2
pg.time.set_timer(TETROMINODOWN, speed)
pg.time.set_timer(SPEEDUP, 30_000)
pg.key.set_repeat(1,100)

tetrominoes = [[0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0],       
               [0,0,0,0,3,3,3,3,0,0,0,0,0,0,0,0],
               [0,0,0,0,5,5,5,0,0,0,5,0,0,0,0,0],
               [0,0,7,0,7,7,7,0,0,0,0,0,0,0,0,0],
               [0,2,2,0,2,2,0,0,0,0,0,0,0,0,0,0],
               [4,4,0,0,0,4,4,0,0,0,0,0,0,0,0,0],
               [0,0,0,0,6,6,6,0,0,6,0,0,0,0,0,0]]

@dataclass
class Tetrominoe():
    tet : list
    zeile : int = 0
    spalte : int = 3 
    
    def show(self):
        for n, farbe in enumerate(self.tet):
            if farbe > 0:
                y = (self.zeile + n // 4) * ABSTAND 
                x = (self.spalte + n % 4) * ABSTAND
                screen.blit(bilder[farbe], (x,y))

    def gültig(self, z, s):
        for n, farbe in enumerate(self.tet):
            if farbe > 0:
                z1 = z + n // 4
                s1 = s + n % 4
                if z1 >= ZEILEN or s1 < 0 or s1 >= SPALTEN or grid[z1 * SPALTEN + s1] > 0:
                    return False
        return True

    def update(self, zoff, soff):
        if self.gültig(self.zeile+zoff, self.spalte+soff):
            self.zeile += zoff
            self.spalte += soff
            return True
        return False

    def rotate(self):
        saveTet = self.tet.copy()
        for n, farbe in enumerate(saveTet):
            z = n // 4
            s = n % 4
            self.tet[(2-s)*4+z] = farbe

def ObjektAufsRaster():
    for n, farbe in enumerate(figur.tet):
        if farbe > 0:
            z = figur.zeile + n // 4
            s = figur.spalte + n % 4
            grid[z+SPALTEN+s] = farbe

figur = Tetrominoe(tetrominoes[3])

weitermachen = True
clock = pg.time.Clock()
while weitermachen:
    clock.tick(80)
    for event in pg.event.get():
        if event.type == pg.QUIT:
            weitermachen = False
        if event.type == TETROMINODOWN:
            if not figur.update(1,0):
                ObjektAufsRaster()
                figur = Tetrominoe(tetrominoes[3])
        if event.type == SPEEDUP:
            speed = int(speed * 0.8)
            pg.time.set_timer(TETROMINODOWN, speed)
        if event.type == pg.KEYDOWN:
            if event.key == pg.K_LEFT:
                figur.update(0,-1)
            if event.key == pg.K_RIGHT:
                figur.update(0,1)
            if event.key == pg.K_DOWN:
                figur.update(1,0)
            if event.key == pg.K_LCTRL:
                figur.rotate()
    screen.fill((0,0,0))
    figur.show()

    for n, farbe in enumerate(grid):
            if farbe > 0:
                x = n % SPALTEN * ABSTAND
                y = n // SPALTEN * ABSTAND
                screen.blit(bilder[farbe],(x,y))
        
    pg.display.flip()

pg.quit()
Miro Santino
User
Beiträge: 4
Registriert: Dienstag 16. Juni 2020, 20:27

bump und Gruß vom Papa :D
Antworten