Pygame Surface durch Strings erstellen?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
liil92
User
Beiträge: 8
Registriert: Mittwoch 30. Dezember 2020, 14:05

Hallo, ich bin derzeit auf am programmieren eines kleinen roboters. Dieser soll wie der cozmo nur augen zur anschaulichung haben.

Bis jetzt hab ich die Augen mittels einzelner Bilder und Frames dargestellt, dies wird aber bei rund 10 verschiedenen Formen etc nicht mehr lohnenswert. ( Da zu viele Bilder beigefügt werden müssen um Animationen flüssig darzustllen)
Deswegen habe ich mir überlegt, statt die Bilder einzeln anzeigen zu lassen, mir strings zu erstellen, welche als surface dargestellt werden.
Somit könnte ich die Strings in dem Programm verändern und abrufen, aussehen würden diese dann etwa so hatte ich mir überlegt, wobei wie beim cozmo nur die Augen eine Farbe hätten, also die '0' :

Code: Alles auswählen

 
"                     ",
"   OOOOOO            ",
"   OOOOOO   OOOOOO   ",
"   OOOOOO   OOOOOO   ",
"   OOOOOO   OOOOOO   ",
"                     ",
"                     ",

 
Leider finde ich im Internet nichts unter dieser Suche 'Strings als Surface ausgeben - pygame'
Nun ist die Frage, ob dies überhaupt geht? Kann man Strings als Surface darstellen lassen? und wenn ja, wie? Welche Funktion etc?

Mfg
liil92
Benutzeravatar
__blackjack__
User
Beiträge: 14053
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@liil92: Ich verstehe nicht so ganz welches Problem dieser Umweg über Zeichenketten lösen soll. Das geht natürlich. Du müsstest dafür halt Code schreiben der die Zeichen irgendwie in Grafik umsetzt. Zum Beispiel für jedes "O" an der entsprechenden Stelle ein Quadrat oder einen Kreis zeichnet.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
liil92
User
Beiträge: 8
Registriert: Mittwoch 30. Dezember 2020, 14:05

__blackjack__ hat geschrieben: Mittwoch 30. Dezember 2020, 15:49 @liil92: Ich verstehe nicht so ganz welches Problem dieser Umweg über Zeichenketten lösen soll. Das geht natürlich. Du müsstest dafür halt Code schreiben der die Zeichen irgendwie in Grafik umsetzt. Zum Beispiel für jedes "O" an der entsprechenden Stelle ein Quadrat oder einen Kreis zeichnet.
Hey Blackjack,

damit umgehe ich das Problem andauernd Bilder beizufügen. Außerdem spare ich Speicherplatz ein. Bisher habe ich beispielsweise: Augen bewegen sich von der mitte nach rechts. Dafür brauche ich schon 8 Bilder um dies darzustellen. Abfragen tu ich diese nacheinander in einem Array. Auch das beifügen der Bilder dauert Zeit (Import(), etc).
Mit dem string array würde ich bezwecken wollen, dass man erstens Animationen schneller beifügen kann, da man lediglich ein neues string array erstellt. zweitens würde ich dadurch auch Speicherplatz sparen. :)

So zusagen würde ich gerne über die Pixel arbeiten und beispielsweiße bei jedem O das Pixel Blau Färben.
Genau da stellt sich mir die Frage, ob es hierfür eine Funktion gibt welche mein String Array einließt und daraus ein Surface erstellt, oder ich aber wie du schon geschrieben hast, selbst Code schreiben muss.

Ps: Ich bin relativ neu bei Python vorallem bei pygame..
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Es gibt dafür keine Funktion. Du kannst sie dir aber schreiben. In dem du durch deinen String wanderst & an den entsprechenden Stellen die Pixel setzt.
Benutzeravatar
ThomasL
User
Beiträge: 1379
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Hi, kannst du so umsetzen:

Code: Alles auswählen

import numpy as np
import pygame

eyes = ["                     ",
        "   OOOOOO            ",
        "   OOOOOO   OOOOOO   ",
        "   OOOOOO   OOOOOO   ",
        "   OOOOOO   OOOOOO   ",
        "                     ",
        "                     "]

eyes_converted = np.array([[int(char.translate({ord('O'):'255', ord(' '):'0'})) for char in line] for line in eyes])

print(eyes_converted)

surf = pygame.surfarray.make_surface(eyes_converted)
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Benutzeravatar
ThomasL
User
Beiträge: 1379
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

@Admin Warum kann ich meinen Beitrag nicht mehr ändern?
(OK, gerade gesehen, dass das wohl nur innerhalb eines Zeitfensters nach einstellen geht. Ist auch gut so. )

@OP pygame.surfarray.make_surface() nimmt auch ein 2D Array mit (R,G,B) Werten. So kannst du über das Dictionary die komplette RGB Palette verwenden.

Code: Alles auswählen

import numpy as np
import pygame

eyes = ["                     ",
        "   OOOOOO            ",
        "   OOOOOO   OOOOOO   ",
        "   OOOOOO   OOOOOO   ",
        "   OOOOOO   OOOOOO   ",
        "                     ",
        "                     "]

CONVERT = {'O': (0, 0, 0), ' ': (255, 255, 255)}
eyes_converted = np.array([[CONVERT[char] for char in line] for line in eyes])
surf = pygame.surfarray.make_surface(eyes_converted)
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Benutzeravatar
__blackjack__
User
Beiträge: 14053
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Wobei ich da immer noch nicht den Vorteil gegenüber einem Bild sehe. 🤔
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
liil92
User
Beiträge: 8
Registriert: Mittwoch 30. Dezember 2020, 14:05

Guten Abend,

erstmal danke für die vielen antworten:)

Ich habe mich nach den Feiertagen, heute selbst nochmal daran versucht..
Ich denke ich bin auf dem richtigen Weg, jedoch stimmt irgendwas nicht wirklich.

Ich versuche über die Funktion 'set_at()' die Pixel an den bestimmten Stellen zu färben.
Anschließend will ich das Ergebnis vergrößern.

Herauskommt jedoch lediglich ein einfarbiges viereck.

Hier mein Code, ich bitte um Entschuldigung wenn dieser etwas wirr ist.

Code: Alles auswählen

import pygame
import sys
import time
import numpy
import cv2

meinArray=[
"   OOOOOO   OOOOOO  ",
"   OOOOOO   OOOOOO   ",
"   OOOOOO   OOOOOO   ",
"   OOOOOO   OOOOOO   ",
]

#Parameter
white = (255,255,255)
height, width = 400, 300
size = height, width
a = b = 0


# Initialisierung pygame
pygame.init()
clock= pygame.time.Clock()

#initialisierung der Bildschirme
screen = pygame.display.set_mode([800,600])
leeres_Bild = pygame.Surface((len(meinArray[0]), len(meinArray)))
#pygame.Surface.fill(leeres_Bild, white)

#Ausgaben test
print('Hello World')
#print(rect)
print(len(meinArray[0]), len(meinArray))
print(pygame.Surface.get_size(screen))

#Separierung und Untersuchung der Zeilen und Spalten, mit anschließender Aktion
x = y = 0
for row in meinArray:
    for col in row:
        if col == "O":
            leeres_Bild.set_at((x, y), pygame.Color(255,0,0))
            x += 1
        y += 1
        x = 0
leeres_Bild = pygame.transform.scale(leeres_Bild, (40*len(meinArray[0]), 40*len(meinArray)))
rect = leeres_Bild.get_rect()



while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT: sys.exit()

        screen.fill((30,30,30))
        screen.blit(leeres_Bild, rect)
        pygame.display.update()
        clock.tick(60)
MFG
Antworten