Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Maltrix

Frischling

  • »Maltrix« ist der Autor dieses Themas

Beiträge: 31

Wohnort: Hamburg

  • Private Nachricht senden

1

21.02.2018, 18:58

pygame FULLSCREEN Probleme

Hallo,

Ich bringe mir zur Zeit Python 3 in Verbindung mit PyGame bei. Als Umgebung benutze ich Visual Studio 2017.

Ich bringe mir das Meiste über Turtorials bei und mache auch gute Fortschritte.
Da ich heute keine Lust auf Turtorials hatte und ich in einem abgeschlossenen Turtorial bereits mit meinen eigenen Sprites gearbeitet habe, habe ich mir Codebeispiele für einen Vollbildmodus
herausgesucht und ein bisschen rumprobiert.

Der Code bzw. der Befehl war schön simpel und lautete einfach nur screen = pygame.display.set_mode((breite, höhe),pygame.FULLSCREEN)

Als ich das Programm startete funktionierte es auch eigentlich einwandfrei.

Was mir dabei nur auffiel war, dass erstens das Bild nicht wirklich Vollbild war und ich an den rändern nach wie vor schwarze Balken hatte,
obwohl meine Variablen für breite und höhe im Verhältnis 16:9 sind und dass mein Sprite irgendwie ein bisschen schwammig aussah.

Die Größe des Sptites ist mit 16x32 Pixeln zwar relativ klein aber ich habe gelesen, dass das keine unübliche Größe für solche Spiele ist und irgendwie muss es ja gehen,
da eine Großzahl von Indi-games ähnliche Größen benutzen. Da ich auch schon 3D Projekte gesehen habe, die mit Pygame geschrieben wurden denke ich auch nicht, dass es an Pygame liegt.

Außerdem fiel mir auf, dass das Bild minimal ruckelt. clock.tick() ist bei mir auf 30 FPS eingestellt aber auch mit 60 sieht es ein bisschen unflüssig aus
Bisher besteht mein Programm gerade mal aus einer einzigen Klasse und einer Programmschleife, die nur aus einer Hand voll Zeilen besteht.
Der Sprite bewegt sich lediglich in einem sich ständig wiederholenden Zick Zack muster über den Bildschirm und da eine große reihe von Spielen, die eine um einiges höhere Performance benötigen flüssig auf meinem Laptop laufen wundert mich das eben.

Hat wer eine Idee, was ich besser machen könnte? Braucht ihr mehr Details zu meinem Programm?
Ich würde mich über hilfreiche Ratschläge freuen.

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

2

21.02.2018, 19:28

Zeig mal deinen Code.

Maltrix

Frischling

  • »Maltrix« ist der Autor dieses Themas

Beiträge: 31

Wohnort: Hamburg

  • Private Nachricht senden

3

21.02.2018, 19:36

Klar, hier bitte.
Das ist das gesamte Programm. Sorry für die vielen Kommentare im Code aber ich brauche die um besser lernen zu können.



Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import pygame # importiere PyGame
import random # importiere Zufallsgenerator
import os # importiere Datenverwaltung


#Globale Variablen festlegen
höhe = 255
breite = 400
x = breite / 2  #Startkoordinaten X-Achse
y = höhe / 2 #Startkoordinaten Y-Achse
FPS = 60 #Framerate variable
running = True #abschaltvariable

blau = (0,0,255) # Farbe Blau
schwarz = (0,0,0) #Farbe Schwarz

# set up assets
game_folder = os.path.dirname(__file__) # verpacke den Programmordner Pfad in Variable game_folder
img_folder = os.path.join(game_folder, "img") # verpacke den Bilderordner Pfad in Variable img_folder (achte darauf, dass der Ordner existiert)

class Avatar(pygame.sprite.Sprite): # Erschaffe Spriteklasse namens Avatar
    def __init__(self): # fülle die Klasse Avatar mit folgenden Daten
        pygame.sprite.Sprite.__init__(self) # initialisierung des Sprites (super wichtig!)
        self.image = pygame.image.load(os.path.join(img_folder, "Rahl_rechts.png")).convert() # lade Spriteimage aus Bilderordner
        self.image.set_colorkey(schwarz) # weise colorkey eine Farbe zu (diese Farbe wird daraufhin transparent wiedergegeben)
        self.rect = self.image.get_rect() # Erschaffe Quadrat um den Avatar so groß wie Avatar
        self.rect.center = (x, y) # setze die Startkoordinaten
        self.y_speed = 2 # 

    def update(self): 
        self.rect.x += 2 # Bewegungsgeschwindigkeit auf der X-Achse
        self.rect.y += self.y_speed # Bewegungsgeschwindigkeit auf der Y-Achse
        if self.rect.bottom > höhe - 20:
            self.y_speed = - 2
        if self.rect.top < 20:
            self.y_speed = 2
        if self.rect.left > breite:
            self.rect.right = 0

#Modulinitialisierung und Bildschirmgröße
pygame.init() #initialisiere pygame
pygame.mixer.init() #initialisiere Soundmodul
screen = pygame.display.set_mode((breite, höhe),pygame.FULLSCREEN) #Screen größe
pygame.display.set_caption("Prototyp") # Fenster benennen
clock = pygame.time.Clock() # Frameratemodul

all_sprites = pygame.sprite.Group() # Erstelle Spritegruppe namens all_sprites

avatar = Avatar() # Erschaffe variable welche die Klasse Avatar beinhaltet

all_sprites.add(avatar) # speicher avatar in all_sprites Gruppe

#Programmschleife
while running:
    clock.tick(FPS) #Framerate festlegen
    for event in pygame.event.get(): # Überwachung ob das Programm beendet wurde
        if event.type == pygame.QUIT:
            running = False
    pressedKeys = pygame.key.get_pressed()
    if pressedKeys[pygame.K_ESCAPE]:
        running = False
    all_sprites.update() # Frage alle aktuellen Spritzustände ab

# Den Bildschirm vor jedem Update mit hintergrundfarbe füllen
    screen.fill(blau)

    all_sprites.draw(screen) # Übertrage akuelle sprites auf screen
#Screen wird nur mit neuen Daten beschrieben, unverändertes bleibt unverändert (dubblebuffering)
#Dubblebuffering MUSS immer am Ende stehen!
    pygame.display.flip() 

#Das Programm wird beendet
pygame.quit()

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Maltrix« (21.02.2018, 19:42)


David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

4

21.02.2018, 20:57

Unter der Annahme, dass V-Sync benutzt wird: Dein Problem ist vermutlich der clock.tick-Aufruf. Ich könnte mir vorstellen, dass dieser Aufruf, wenn die Zeitmessung nicht ganz exakt ist, manchmal dazu führt, dass dein Aufruf von pygame.display.flip ein bisschen zu spät für das aktuelle Frame kommt und dann bis zum nächsten Bildaufbau gewartet werden muss (wodurch ein Ruckeln entsteht). Mit V-Sync brauchst du clock.tick nicht, denn dann findet die Pause, die deine Framerate begrenzt, automatisch in pygame.display.flip statt.

5

21.02.2018, 21:08

In Zeile 43 Setzt du den Display Mode auf 400x255. Das ist keine übliche Bildschirmauflösung für eine Vollbildanwendung. Du solltest prüfen ob die Auflösung unterstützt wird. Behandeln der Display Modes Der Link erklärt das ganz gut.

Maltrix

Frischling

  • »Maltrix« ist der Autor dieses Themas

Beiträge: 31

Wohnort: Hamburg

  • Private Nachricht senden

6

22.02.2018, 10:12

Ok folgendes habe ich erstmal gemacht:

Erstmal habe ich diesen Code ausprobiert

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
>>> #give me the best depth with a 640 x 480 windowed display
>>> pygame.display.set_mode((640, 480))

>>> #give me the biggest 16-bit display available
>>> modes = pygame.display.list_modes(16)
>>> if not modes:
...     print '16-bit not supported'
... else:
...     print 'Found Resolution:', modes[0]
...     pygame.display.set_mode(modes[0], pygame.FULLSCREEN, 16)

>>> #need an 8-bit surface, nothing else will do
>>> if pygame.display.mode_ok((800, 600), 0, 8) != 8:
...     print 'Can only work with an 8-bit display, sorry'
... else:
...     pygame.display.set_mode((800, 600), 0, 8)


Um herauszufinden, ob mein Laptop 16 bit unterstützt. Dem ist nicht so (was blöd ist, wenn man ein 16-bit spiel programmieren will)

ich habe ungeachtet der bit zahl daraufhin versucht einen größeren Sprite zu laden (32x64 anstatt 16x32) und die qualität wurde besser.
Ich habe auch versucht, den clock.tick zu löschen, kann aber jetzt nicht wirklich überprüfen, ob das spiel flüssiger läuft, weil die Bewegungsgeschwindigkeiten jetzt unfassbar schnell wiedergegeben werden. selbst wenn ich alles auf 1 bzw. -1 setze. Ich habe dann versucht mit kommazahlen zu arbeiten, die aber in keiner Bewegung sondern Stillstand resultiert haben.

Zuerst habe ich einfach nur die Bewegungsgeschwindigkeiten direkt als kommazahl geschrieben also z.B:

self.y_speed = 0.5

was in einem früheren Programm (das zugegebenermaßen anders aufgebaut war) funktioniert hatte.

self.y_speed = float(0.5)

Hat auch nicht funktioniert und wenn ich die Zahl vorher in einer Variablen speicher also z.B in Zeile 16.

Speed = float(0.5)

und dann später

self.y_speed = Speed

funktioniert es auch nicht.

Eine weitere Frage, die ich mir jetzt stelle ist, wie der Laptop die Geschwindigkeit ohne clock.tick berechnet.
Immerhin soll das Spiel ja auf anderen Rechnern genau so schnell laufen, weswegen der clock.tick überhaupt erst eingebaut wurde.

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

7

22.02.2018, 10:41

Ich hatte angenommen, dass V-Sync aktiv ist. Das ist scheinbar nicht der Fall, darum läuft jetzt alles super schnell.

Maltrix

Frischling

  • »Maltrix« ist der Autor dieses Themas

Beiträge: 31

Wohnort: Hamburg

  • Private Nachricht senden

8

22.02.2018, 11:01

hmm achso.

Ich hatte jetzt in der Systemsteuerung meiner Grafikkarte V-Sync aktiviert und dann nochmal geguckt aber die Geschwindigkeit ist immer noch genau so schnell.
Vorher stand die Einstellung auf "Einstellung für 3D Anwendungen verwenden" aber da war das Problem ja das selbe. Aber wie berechnet er die Geschwindigkeit denn jetzt ohne clock.tick?
Denn auch, wenn der Sprite jetzt super schnell ist, scheint er flüssiger zu laufen. Also wenn das am Ende keine Probleme auf anderen Geräten verursacht und ich die Geschwindigkeit irgendwie in Kommazahlen angeben kann würde ich in die Richtung weiter suchen.

Kannst du mir irgendetwas zu meinem float() problem sagen?

Oh und bevor ich das vergesse, und es wichtig sein könnte. Immer wenn ich in den Vollbildmodus gehe ploppt dieses kleine Windowsfenster auf, dass mir sagt, dass ich das Bild nicht in den optimalen 1920 X 1080 wiedergebe und sobald ich versuche das wegzuklicken schließt sich meine Surface und nur die Konsole bleibt geöffnet.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Maltrix« (22.02.2018, 11:08)


Maltrix

Frischling

  • »Maltrix« ist der Autor dieses Themas

Beiträge: 31

Wohnort: Hamburg

  • Private Nachricht senden

9

23.02.2018, 10:19

Hey, kleines Update:

Ich habe jetzt mit Spritegrößen herumexperimentiert und meine 16x32 Sprites auf 64x128 skaliert. Der Sprite wird jetzt scharf und detailreich wiedergegeben, was mich zu dem Schluss führt,
dass meine gewünschte Größe wohl etwas zu viel für den FULLSCREEN mode war. Das Hat für mich jetzt Vor- und auch Nachteile, aber egal. Ich habe auch endlich ein Screenformat gefunden, was mir einen echtes Vollbild erzeugt also diese Probleme scheinen (vorerst) der Vergangenheit anzugehören.

Jetzt bleibt aber noch das Ruckelproblem. Wenn ich in der Systemsteuerung meiner Grafikkarte V-Sync ein-, aus-, oder auf die 3D Anwendung schalte verändert sich nichts.
Wenn ich ohne clock.tick arbeite sind die Bewegungen zu schnell, wenn ich mit clock.tick arbeite habe ich Ruckler und ich kann die Geschwindigkeiten nicht kleiner als 1 setzen.

Kann mir da jemand helfen? Es muss doch möglich sein mit Kommazahlen zu arbeiten und wie gesagt, einfach float() funktioniert nicht.

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

10

23.02.2018, 10:31

tick sollte eigentlich keine Probleme machen. Das sieht man in allen möglichen PyGame Beispielen. Ansonsten kannst du mit deltaTiming arbeiten um die Bewegungsgeschwindigkeit konstant zu halten, egal bei welcher Framerate.
In wie fern kannst du die Geschwindigkeit nicht kleiner als 1 setzen?
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Werbeanzeige