Hallo zusammen,
seit einiger Zeit arbeite ich an einer Art Spiele-Engine. Diese basiert auf Pygame und macht das Programmieren von Spielen für mich wegen einiger netter Funktionen einfacher.
Die wichtigste Funktion ist vielleicht, dass die Darstellung von Gegenständen übernommen wird.
Meine Frage ist jetzt, ob sich noch jemand anderes für die Benutzung interessieren könnte.
Oder gibt es überhaupt jemanden, der im Bereich Spiele-Programmierung mit Python tätig ist?
Danke im voraus,
Teilu
meine Spiele-Engine: Interesse?
Ich würde mich schon dafür interessieren, aber ich habe gerade erst mit Python angefangen habe in Pygame bisher nicht mehr als das folgende geschrieben.
Das ist ein Programm, mit dem ich für zukünftige Spiele testen wollte, wie man NPC bewegen kann.
Code: Alles auswählen
# -*- coding: cp1252 -*-
import pygame
import easygui
def Entfernung(a, b):
Abstand = ((a[0]-b[0])**2+(a[1]-b[1])**2)**0.5
Abstand = str(int(Abstand))
return Abstand
class Ball:
def __init__(self,pos):
self.pos = pos
self.int_pos = pos
def bewegen(self,target,distance):
Ueberschritten = False
vektor = [target[0] - self.pos[0] , target[1] - self.pos[1]]
vektor_distance = (vektor[0]**2+vektor[1]**2)**0.5
if not vektor_distance == 0:
vektor[0] = vektor[0] / vektor_distance
vektor[1] = vektor[1] / vektor_distance
if distance > vektor_distance:
Ueberschritten = True
self.pos[0] = self.pos[0] + vektor[0] * distance
self.pos[1] = self.pos[1] + vektor[1] * distance
self.int_pos = [int(self.pos[0]) , int(self.pos[1])]
if Ueberschritten:
self.int_pos = target
pygame.init()
screen = pygame.display.set_mode([640,480])
clock = pygame.time.Clock()
this_ball = Ball([320,240])
step_distance = float(easygui.enterbox("Geschwindigkeit in 100Pixel/Sekunde"))
message1_str = "Klick mit der Maus irgendwo hin!"
message2_str = "Du kannst die Maus auch gedrückt halten!"
message3_str = "WARNUNG: FPS EINBRUCH!"
messagex_str = "x: 320"
messagey_str = "y: 240"
messageabstand_str = "Abstand: ?"
ballx_str = "x: 320"
bally_str = "y: 240"
gedrueckt = False
running = True
while running:
clock.tick(60)
try:
messagefps_str = str(int(clock.get_fps())) + " FPS"
messagex_str = str("x: " + str(finish[0]))
messagey_str = str("y: " + str(finish[1]))
except:
pass
try:
Abstand = int(((finish[0]-this_ball.int_pos[0])**2+(finish[1]-this_ball.int_pos[1])**2)**0.5)
messageabstand_str = "Abstand: " + str(Abstand)
except:
pass
ballx_str = "x: " + str(this_ball.int_pos[0])
bally_str = "y: " + str(this_ball.int_pos[1])
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.MOUSEBUTTONDOWN:
gedrueckt = True
finish = event.pos
if event.type == pygame.MOUSEBUTTONUP:
gedrueckt = False
if event.type == pygame.MOUSEMOTION:
if gedrueckt:
finish = event.pos
try:
this_ball.bewegen(finish,step_distance)
except:
pass
message1_font = pygame.font.Font(None, 18)
message1_surf = message1_font.render(message1_str, 1, (255, 255, 255))
message2_font = pygame.font.Font(None, 18)
message2_surf = message2_font.render(message2_str, 1, (255, 255, 255))
messagefps_font = pygame.font.Font(None, 18)
messagefps_surf = messagefps_font.render(messagefps_str, 1, (255, 0, 0))
messagex_font = pygame.font.Font(None, 18)
messagex_surf = messagex_font.render(messagex_str, 1, (255, 255, 255))
messagey_font = pygame.font.Font(None, 18)
messagey_surf = messagey_font.render(messagey_str, 1, (255, 255, 255))
messageabstand_font = pygame.font.Font(None, 18)
messageabstand_surf = messageabstand_font.render(messageabstand_str, 1, (255, 255, 255))
ballx_font = pygame.font.Font(None, 18)
ballx_surf = ballx_font.render(ballx_str, 1, (255, 255, 255))
bally_font = pygame.font.Font(None, 18)
bally_surf = bally_font.render(bally_str, 1, (255, 255 ,255))
screen.fill([0,0,0])
pygame.draw.circle(screen,[128,255,128],this_ball.int_pos, 25, 0)
screen.blit(message1_surf, [10, 10])
screen.blit(message2_surf, [10, 30])
screen.blit(messagefps_surf, [560, 10])
screen.blit(messagex_surf, [500, 30])
screen.blit(messagey_surf, [500, 50])
screen.blit(messageabstand_surf, [10, 90])
screen.blit(ballx_surf, [400, 30])
screen.blit(bally_surf, [400 ,50])
if clock.get_fps < 100:
message3_font = pygame.font.Font(None, 26)
message3_surf = message3_font.render(message3_str, 1, (255,0,0))
screen.blit(message3_surf, [10,90])
pygame.display.flip()
Zuletzt geändert von Anonymous am Samstag 5. Oktober 2013, 10:49, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
Grund: Quelltext in Python-Code-Tags gesetzt.
Bisher gibt es noch keine Dokumentation und die Benutzung von den eingebauten Funktionalitäten wird bis jetzt nur durch wenige Beispiele erklärt.
Naja, das grafik-system funktioniert bei mir jedenfalls so, dass Gegenstände angelegt werden können.
Die wichtigsten Attribute sind Position, Abmessung, Ausrichtung, Farbe und Textur.
Mögliche Figuren sind bisher Kreis, Rechteck und Linie.
Mit dem Aufruf von einer Funktion wird die gesamte Szene gezeichnet.
Daneben gibt es noch Funktionen für kollision, sound, Benutzereingaben und Speicher-Zugriff nach bestimmten "Datenstrukturen".
Unklar ist für mich, ob sich das Schreiben einer Dokumentation, da diese doch sehr lang wird, lohnt.
MFG,
Teilu
@Tobs: Dein Code würde auf jeden Fall deutlich kürzer werden!
Naja, das grafik-system funktioniert bei mir jedenfalls so, dass Gegenstände angelegt werden können.
Die wichtigsten Attribute sind Position, Abmessung, Ausrichtung, Farbe und Textur.
Mögliche Figuren sind bisher Kreis, Rechteck und Linie.
Mit dem Aufruf von einer Funktion wird die gesamte Szene gezeichnet.
Daneben gibt es noch Funktionen für kollision, sound, Benutzereingaben und Speicher-Zugriff nach bestimmten "Datenstrukturen".
Unklar ist für mich, ob sich das Schreiben einer Dokumentation, da diese doch sehr lang wird, lohnt.
MFG,
Teilu
@Tobs: Dein Code würde auf jeden Fall deutlich kürzer werden!
-
BlackJack
@Tobs: Ein paar Anmerkungen zum Quelltext:
Die `Entfernung()`-Funktion wird nirgends verwendet. Der Name hat auch zwei Probleme: 1. er fängt mit einem Grossbuchstaben an, was per Konvention nur Klassennamen sollten (oder Konstanten die komplett in Grossbuchstaben benannt werden), und 2. beschreibt er keine Tätigkeit. Letzteres ist üblich um Funktionen leichter von Werten unterscheiden zu können. Denn `entfernung` könnte ja auch eine Zahl sein die eine Entfernung angibt. Für die Funktion drei Zeilen zu verwenden in denen der gleiche Name an zwei sehr unterschiedliche Datentypen gebunden wird, ist auch keine so gute Idee. Vom Typ her ist eine Entfernung oder ein Abstand ja auch keine Zeichenkette. Diese Umwandlung gehört deshalb auch nicht in so eine Funktion.
`Ball.int_pos()` als unabhängiges Attribut zu führen ist fehleranfällig. So muss man überall wo man das `pos`-Attribut verändert immer darauf achten, dass auch `int_pos` entsprechend gesetzt wird. Dafür würde sich ein `property()`, also ein berechnetes Attribut anbieten. Dazu muss `Ball` von `object` erben, was man generell machen sollte (in Python 2.x, und in Python 3.x schadet es zumindest nicht).
Etwas später werden die Werte dann auch sehr komisch ungleich behandelt. Wenn das Ziel überschritten wurde, wird nur `int_pos` auf das Ziel gesetzt, `pos` dagegen normal berechnet, also über das Ziel hinaus. Dazu wird auch noch ein Flag `Ueberschritten` über die gesamte Funktion verteilt. Wenn man die Bedingungen und Aktionen sinvoll umstellt, braucht man weder das `Ueberschritten`-Flag, noch den Test ob die Länge des Vektors grösser als Null ist bevor man teilt. Damit kann die Methode ein cirka ein Drittel kürzer und damit auch leichter verständlich werden. `vektor_distance` sollte man dann noch in `vector_length` umbenennen, damit es die richtige Bezeichnung für den Wert ist und nicht Deutsch und Englisch in einem Bezeichner vermischt werden.
Der Hauptprogramm-Quelltext sollte nicht auf Modulebene stehen, sondern in einer Funktion. Beziehungsweise in mehr, denn das ist eine ganz schöne Menge an Code der unterschiedliche Sachen tut und Wiederholungen enthält, die man sinnvoll auf Funktionen verteilen kann.
Ausserdem enthät das Hauptprogramm eine Menge „magischer” Zahlen die man entweder als Konstanten definieren, oder aus diesen Konstanten berechnen kann. Noch schlimmer ist, dass ein paar Zeichenketten diese magischen Zahlen auch noch mal die gleichen magischen Zahlen enthalten. Überleg mal wo Du überall Änderungen von Hand vornehmen musst, wenn Du die Anzeigegrösse ändern willst. Im Idealfall gibt es dafür *eine* Konstante im Programm die man ändern muss, und das war es dann.
Der `this_`-Präfix bei `this_ball` macht keinen Sinn. Und `step_distance` als Name für die Antwort auf die Frage nach der Geschwindigkeit hiesse besser `speed`. In der Frage steckt auch wieder eine magische Zahl, die man als Konstante festlegen sollte, damit man sie einfach ändern kann. Dann hätte man auch nicht das Problem dass der ganze Code von 100 FPS ausgeht *ausser* die Stelle an der mit der `clock` dann tatsächlich auf 60 FPS hingearbeitet wird. Das ist Dir wahrscheinlich nicht aufgefallen weil die FPS-Einbruchswarnung entweder *nie* oder *immer* ausgegeben wird, weil Du dort nicht den FPS-Wert mit einer Zahl vergleichst, sondern die *Methode*. Du hättest sie an der Stelle auch *aufrufen* müssen.
Warum hast Du Zeichenketten am Anfang an an so nichtssagende, durchnummerierte Namen wie `message1_str` gebunden die dann später benutzt werden und man an der Stelle dann nicht mehr sieht was da eigentlich ausgegeben wird. Also nicht mal mehr die Bedeutung am Namen, denn so etwas wie `message2_str` sagt nicht wirklich etwas aus, zumindest nicht dass was der Leser an der Stelle gerne wissen möchte.
Auch die anderen `message*`-Variablen werden relativ weit von der Verwendung entfernt definiert. Und unnötig vor der Schleife wegen diesem gruseligen Ausnahmedurcheinander was Du Dir mit `finish` eingehandelt hast. Wenn der Name vor der ersten Verwendung nicht definiert ist, dann „behandelt” man das nicht mit ``except``, schon gar nicht ohne eine konkrete Ausnahme dort anzugeben, sondern in dem man doch bitte vorher einfach mal `finish` definiert. Damit spart man sich dann eine ganze Menge von dem Code der nur existiert um diesen einen Spezialfall abzufangen.
Die ganzen ``if``-Bedingungen in der Ereignisverarbeitung schliessen sich gegenseitig aus. Hier sollte man also mit ``elif``\s arbeiten.
Wenn man bei den `blit()`-Aufrufen für die Texte mal die Zeilen die dafür benötigt werden direkt darüber gruppiert und das nicht alles über die gesamte Schleife verteilt, dann sieht man deutlich das immer die gleichen drei bis vier Schritte nur mit anderen Werten durchgeführt werden. Das lässt sich also prima in eine Funktion auslagern. Damit lassen sich einige Zeilen einsparen.
Statt mit `int()`, `str()`, und ``+`` zu hantieren um Werte und Zeichenketten zusammenzusetzen wie in BASIC, bietet Python Zeichenkettenformatierung mittels der `format()`-Methode auf Zeichenketten und Platzhaltern und Formatierungsangaben in der Zeichenkette.
Mal angefangen die Punkte umzusetzen:
Die `Entfernung()`-Funktion wird nirgends verwendet. Der Name hat auch zwei Probleme: 1. er fängt mit einem Grossbuchstaben an, was per Konvention nur Klassennamen sollten (oder Konstanten die komplett in Grossbuchstaben benannt werden), und 2. beschreibt er keine Tätigkeit. Letzteres ist üblich um Funktionen leichter von Werten unterscheiden zu können. Denn `entfernung` könnte ja auch eine Zahl sein die eine Entfernung angibt. Für die Funktion drei Zeilen zu verwenden in denen der gleiche Name an zwei sehr unterschiedliche Datentypen gebunden wird, ist auch keine so gute Idee. Vom Typ her ist eine Entfernung oder ein Abstand ja auch keine Zeichenkette. Diese Umwandlung gehört deshalb auch nicht in so eine Funktion.
`Ball.int_pos()` als unabhängiges Attribut zu führen ist fehleranfällig. So muss man überall wo man das `pos`-Attribut verändert immer darauf achten, dass auch `int_pos` entsprechend gesetzt wird. Dafür würde sich ein `property()`, also ein berechnetes Attribut anbieten. Dazu muss `Ball` von `object` erben, was man generell machen sollte (in Python 2.x, und in Python 3.x schadet es zumindest nicht).
Etwas später werden die Werte dann auch sehr komisch ungleich behandelt. Wenn das Ziel überschritten wurde, wird nur `int_pos` auf das Ziel gesetzt, `pos` dagegen normal berechnet, also über das Ziel hinaus. Dazu wird auch noch ein Flag `Ueberschritten` über die gesamte Funktion verteilt. Wenn man die Bedingungen und Aktionen sinvoll umstellt, braucht man weder das `Ueberschritten`-Flag, noch den Test ob die Länge des Vektors grösser als Null ist bevor man teilt. Damit kann die Methode ein cirka ein Drittel kürzer und damit auch leichter verständlich werden. `vektor_distance` sollte man dann noch in `vector_length` umbenennen, damit es die richtige Bezeichnung für den Wert ist und nicht Deutsch und Englisch in einem Bezeichner vermischt werden.
Der Hauptprogramm-Quelltext sollte nicht auf Modulebene stehen, sondern in einer Funktion. Beziehungsweise in mehr, denn das ist eine ganz schöne Menge an Code der unterschiedliche Sachen tut und Wiederholungen enthält, die man sinnvoll auf Funktionen verteilen kann.
Ausserdem enthät das Hauptprogramm eine Menge „magischer” Zahlen die man entweder als Konstanten definieren, oder aus diesen Konstanten berechnen kann. Noch schlimmer ist, dass ein paar Zeichenketten diese magischen Zahlen auch noch mal die gleichen magischen Zahlen enthalten. Überleg mal wo Du überall Änderungen von Hand vornehmen musst, wenn Du die Anzeigegrösse ändern willst. Im Idealfall gibt es dafür *eine* Konstante im Programm die man ändern muss, und das war es dann.
Der `this_`-Präfix bei `this_ball` macht keinen Sinn. Und `step_distance` als Name für die Antwort auf die Frage nach der Geschwindigkeit hiesse besser `speed`. In der Frage steckt auch wieder eine magische Zahl, die man als Konstante festlegen sollte, damit man sie einfach ändern kann. Dann hätte man auch nicht das Problem dass der ganze Code von 100 FPS ausgeht *ausser* die Stelle an der mit der `clock` dann tatsächlich auf 60 FPS hingearbeitet wird. Das ist Dir wahrscheinlich nicht aufgefallen weil die FPS-Einbruchswarnung entweder *nie* oder *immer* ausgegeben wird, weil Du dort nicht den FPS-Wert mit einer Zahl vergleichst, sondern die *Methode*. Du hättest sie an der Stelle auch *aufrufen* müssen.
Warum hast Du Zeichenketten am Anfang an an so nichtssagende, durchnummerierte Namen wie `message1_str` gebunden die dann später benutzt werden und man an der Stelle dann nicht mehr sieht was da eigentlich ausgegeben wird. Also nicht mal mehr die Bedeutung am Namen, denn so etwas wie `message2_str` sagt nicht wirklich etwas aus, zumindest nicht dass was der Leser an der Stelle gerne wissen möchte.
Auch die anderen `message*`-Variablen werden relativ weit von der Verwendung entfernt definiert. Und unnötig vor der Schleife wegen diesem gruseligen Ausnahmedurcheinander was Du Dir mit `finish` eingehandelt hast. Wenn der Name vor der ersten Verwendung nicht definiert ist, dann „behandelt” man das nicht mit ``except``, schon gar nicht ohne eine konkrete Ausnahme dort anzugeben, sondern in dem man doch bitte vorher einfach mal `finish` definiert. Damit spart man sich dann eine ganze Menge von dem Code der nur existiert um diesen einen Spezialfall abzufangen.
Die ganzen ``if``-Bedingungen in der Ereignisverarbeitung schliessen sich gegenseitig aus. Hier sollte man also mit ``elif``\s arbeiten.
Wenn man bei den `blit()`-Aufrufen für die Texte mal die Zeilen die dafür benötigt werden direkt darüber gruppiert und das nicht alles über die gesamte Schleife verteilt, dann sieht man deutlich das immer die gleichen drei bis vier Schritte nur mit anderen Werten durchgeführt werden. Das lässt sich also prima in eine Funktion auslagern. Damit lassen sich einige Zeilen einsparen.
Statt mit `int()`, `str()`, und ``+`` zu hantieren um Werte und Zeichenketten zusammenzusetzen wie in BASIC, bietet Python Zeichenkettenformatierung mittels der `format()`-Methode auf Zeichenketten und Platzhaltern und Formatierungsangaben in der Zeichenkette.
Mal angefangen die Punkte umzusetzen:
Code: Alles auswählen
#!/usr/bin/env python
# coding: utf8
import easygui
import pygame
DISPLAY_WIDTH, DISPLAY_HEIGHT = DISPLAY_SIZE = (640, 480)
PIXEL_PER_SECOND = 100
DEFAULT_FONT_SIZE = 18
BLACK, WHITE, RED = (0, 0, 0), (255, 255, 255), (255, 0, 0)
BALL_COLOR = (128, 255, 128)
BALL_RADIUS = DISPLAY_HEIGHT // 20
def blit_text(
surface, text, position, color=WHITE, font_size=DEFAULT_FONT_SIZE
):
surface.blit(
pygame.font.Font(None, font_size).render(text, 1, color), position
)
class Ball(object):
def __init__(self, pos):
self.pos = pos
@property
def int_pos(self):
return (int(self.pos[0]), int(self.pos[1]))
def move(self, target, distance):
vector = (target[0] - self.pos[0] , target[1] - self.pos[1])
vector_length = (vector[0]**2 + vector[1]**2)**0.5
if distance >= vector_length:
self.pos = target
else:
self.pos = (
self.pos[0] + vector[0] / vector_length * distance,
self.pos[1] + vector[1] / vector_length * distance
)
def main():
speed = float(
easygui.enterbox(
'Geschwindigkeit in {} Pixel/Sekunde'.format(PIXEL_PER_SECOND)
)
)
pygame.init()
screen = pygame.display.set_mode(DISPLAY_SIZE)
clock = pygame.time.Clock()
ball = Ball(screen.get_rect().center)
target = ball.int_pos
any_mouse_button_down = False
running = True
while running:
clock.tick(PIXEL_PER_SECOND)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
any_mouse_button_down = True
target = event.pos
elif event.type == pygame.MOUSEBUTTONUP:
any_mouse_button_down = False
elif event.type == pygame.MOUSEMOTION:
if any_mouse_button_down:
target = event.pos
ball.move(target, speed)
screen.fill(BLACK)
pygame.draw.circle(screen, BALL_COLOR, ball.int_pos, BALL_RADIUS)
blit_text(screen, 'Klick mit der Maus irgendwo hin!', (10, 10))
blit_text(screen, u'Du kannst die Maus auch gedrückt halten!', (10, 30))
blit_text(screen, '{0:.0f} FPS'.format(clock.get_fps()), (560, 10), RED)
blit_text(screen, 'x: {0}'.format(target[0]), (500, 30))
blit_text(screen, 'y: {0}'.format(target[1]), (500, 50))
distance = int(
(
(target[0] - ball.int_pos[0])**2
+ (target[1] - ball.int_pos[1])**2
)**0.5
)
blit_text(screen, 'Abstand: {0}'.format(distance), (10, 90))
blit_text(screen, 'x: {0}'.format(ball.int_pos[0]), (400, 30))
blit_text(screen, 'y: {0}'.format(ball.int_pos[1]), (400, 50))
if clock.get_fps() < PIXEL_PER_SECOND * 0.95:
blit_text(screen, 'WARNUNG: FPS EINBRUCH!', (10, 110), RED, 28)
pygame.display.flip()
if __name__ == '__main__':
main()Naja,
wie ich sehe insgesamt sehr wenige Rückmeldungen.
Falls doch noch jemand interesse zeigen sollte findet man mein projekt unter:
http://sourceforge.net/projects/pygengine/
oder bei der Eingabe von pyGEngine in die Suchleiste der Suchmaschiene.
Wie gesagt, es gibt keine Dokumentation.
Gruß,
Teilu
wie ich sehe insgesamt sehr wenige Rückmeldungen.
Falls doch noch jemand interesse zeigen sollte findet man mein projekt unter:
http://sourceforge.net/projects/pygengine/
oder bei der Eingabe von pyGEngine in die Suchleiste der Suchmaschiene.
Wie gesagt, es gibt keine Dokumentation.
Gruß,
Teilu
-
BlackJack
@Teilu: Nach einem Blick in den Quelltext habe ich definitiv kein Interesse.
Mal ein Beispiel:
Und das sieht alles so aus. Die Klassen haben Funktionsnamen, Attribute sind alles `__slots__`, `self` heisst `obj`, Schleifen über Sequenzen mit ``for i in range(0, len(sequenze)):``, Einrücktiefe von 3 pro Ebene.
Also wenn man nicht in Python programmieren möchte, dann soll man es doch einfach lassen wenn einen niemand dazu zwingt…
Mal ein Beispiel:
Code: Alles auswählen
class new_controller():
__slots__ = ("stick","button_ID","axis_ID","name","ID","axis","pressed","button","deadzone","sign")
def __init__(obj,ID):
obj.stick = None; obj.name = "(kein Name)"; obj.ID = ID
obj.axis_ID = []; obj.button_ID = []
obj.axis = []; obj.sign = []; obj.button = []
obj.deadzone = 0
try:
obj.stick = joystick.Joystick(ID)
obj.stick.init()
obj.name = obj.stick.get_name().replace(" ","")
obj.axis = [0]*obj.stick.get_numaxes()
obj.button = [False]*obj.stick.get_numbuttons()
except py_error: pass
obj.pressed = False#pressed for user
obj.load()
def get_state(obj):
if obj.stick and obj.stick.get_init():
#get all axis states with deadzone and sign
for i in range(len(obj.axis)):
obj.axis[obj.axis_ID[i]] = round(obj.stick.get_axis(i)*100)*obj.sign[i]
#set axis to 0 if its value is in deadzone
if abs(obj.axis[obj.axis_ID[i]]) <= obj.deadzone:
obj.axis[obj.axis_ID[i]] = 0
#get all buttons states
for i in range(len(obj.button)):
obj.button[obj.button_ID[i]] = obj.stick.get_button(i)
#load IDs of axis, button and sign of axis
def load(obj):
#load data from file named like joystick
data = memory.open_file(path+"\\Data"+obj.name+".txt","r")
if data:
res = True
values = memory.load_values(data)
memory.close_file(data)
else:
#standart joystick if file does not exist
res = False
values = [i for i in range(len(obj.button))] + [i for i in range(len(obj.axis))] + [0]
#set ID,sign for axis
for i in range(0,len(obj.axis)):
obj.axis_ID.append(int(abs(values[i])))
obj.sign.append(pos_neg(values[i]))
length = len(obj.axis)
#set IDs for buttons
for i in range(len(obj.button)):
obj.button_ID.append(int(values[i+length]))
length += len(obj.button)
obj.deadzone = values[length]
return resFür den erfahrenen Python-Entwickler sieht das in der Tat nicht schön aus.BlackJack hat geschrieben:Also wenn man nicht in Python programmieren möchte, dann soll man es doch einfach lassen wenn einen niemand dazu zwingt…
Ich möchte hier dringend auf den Style Guide for Python Code verweisen.
Ich habe es mir angewöhnt, parallel zum Coden die Doku mitzuschreiben. Die Vorteile überwiegen klar den Umstand, dass Programmieren mehr Spaß macht als Dokumentationen zu formulieren:Teilu hat geschrieben:Unklar ist für mich, ob sich das Schreiben einer Dokumentation, da diese doch sehr lang wird, lohnt.
- Umständlicher Code und dadurch oftmals umständliche Bedienung werden schneller erkannt
- Eine durchgängig gleich strukturierte API bzw. UI sind beim Schreiben der Doku leichter zu definieren
- Ideen neuer Features bzw. Verbesserung bestehender entwickeln sich oft während der Notwendigkeit, die Verwendung des eigenen Programmes zu erklären
- Nach Zeiten, in denen man sich gedanklich in ein bestimmtes Problem hineingeschraubt hat, tut es gut, über die Doku wieder einen Blick auf das "große Gesamte" zu werfen
- Last but not least: Fängt man zu spät zu dokumentieren an, macht man es mangels Motivation doch meistens eh nicht mehr...
Und ein schlecht dokumentiertes Programm oder Framework wird später kaum jemand verwenden.
mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit
)
