Πώς να δημιουργήσετε δημιουργική τέχνη σε λιγότερες από 100 γραμμές κώδικα

Η δημιουργική τέχνη, όπως οποιοδήποτε θέμα προγραμματισμού, μπορεί να είναι εκφοβιστική αν δεν το έχετε δοκιμάσει ποτέ ξανά. Πάντα με ενδιέφερε γιατί μου αρέσει να βρίσκω νέους τρόπους με τους οποίους ο προγραμματισμός μπορεί να χρησιμοποιηθεί δημιουργικά. Επιπλέον, νομίζω ότι ο καθένας μπορεί να εκτιμήσει την έννοια του έργου τέχνης που δημιουργεί κυριολεκτικά τον εαυτό του.

Τι είναι η δημιουργική τέχνη;

Η γενετική τέχνη είναι η παραγωγή ενός συστήματος που λαμβάνει τις δικές του αποφάσεις για το κομμάτι, παρά για έναν άνθρωπο. Το σύστημα θα μπορούσε να είναι τόσο απλό όσο ένα μεμονωμένο πρόγραμμα Python, αρκεί να έχει κανόνες και κάποια πτυχή της τυχαιότητας.

Με τον προγραμματισμό, είναι πολύ απλό να βρούμε κανόνες και περιορισμούς. Αυτές είναι όλες οι δηλώσεις υπό όρους. Τούτου λεχθέντος, η εύρεση τρόπων με τους οποίους αυτοί οι κανόνες δημιουργούν κάτι ενδιαφέρον μπορεί να είναι δύσκολο.

Το Παιχνίδι της Ζωής είναι ένα διάσημο σύνολο τεσσάρων απλών κανόνων που καθορίζουν τη «γέννηση» και τον «θάνατο» κάθε κελιού στο σύστημα. Κάθε ένας από τους κανόνες παίζει ρόλο στην προώθηση του συστήματος σε κάθε γενιά. Αν και οι κανόνες είναι απλοί και κατανοητοί, αρχίζουν να εμφανίζονται γρήγορα πολύπλοκα μοτίβα και τελικά σχηματίζουν συναρπαστικά αποτελέσματα.

Οι κανόνες μπορεί να είναι υπεύθυνοι για τη δημιουργία της βάσης για κάτι ενδιαφέρον, αλλά ακόμη και κάτι τόσο συναρπαστικό όσο το παιχνίδι της ζωής του Conway είναι προβλέψιμο. Δεδομένου ότι οι τέσσερις κανόνες είναι οι καθοριστικοί παράγοντες για κάθε γενιά, ο τρόπος παραγωγής απρόβλεπτων αποτελεσμάτων είναι η εισαγωγή τυχαιοποίησης στην αρχική κατάσταση των κυττάρων. Ξεκινώντας με έναν τυχαίο πίνακα θα κάνετε κάθε εκτέλεση μοναδική χωρίς να χρειάζεται να αλλάξετε τους κανόνες.

Τα καλύτερα παραδείγματα της δημιουργικής τέχνης είναι εκείνα που βρίσκουν έναν συνδυασμό προβλεψιμότητας και τυχαιότητας, προκειμένου να δημιουργήσουν κάτι ενδιαφέρον που είναι επίσης στατιστικά ανεπαίσθητο .

Γιατί να το δοκιμάσετε;

Δεν δημιουργούνται όλα τα δευτερεύοντα έργα ισότιμα ​​και η δημιουργική τέχνη μπορεί να μην είναι κάτι που έχετε την τάση να αφιερώσετε χρόνο. Εάν αποφασίσετε να εργαστείτε σε ένα έργο, ωστόσο, μπορείτε να περιμένετε αυτά τα οφέλη:

  • Εμπειρία - Η γενετική τέχνη είναι μια ακόμη ευκαιρία να ακονίσετε κάποιες νέες και παλιές δεξιότητες. Μπορεί να χρησιμεύσει ως πύλη για την εξάσκηση εννοιών όπως αλγόριθμοι, δομές δεδομένων και ακόμη και νέες γλώσσες.
  • Απτά αποτελέσματα - Στον κόσμο του προγραμματισμού σπάνια βλέπουμε κάτι που βγαίνει από τις προσπάθειές μας, ή τουλάχιστον δεν το κάνω. Αυτή τη στιγμή έχω μερικές αφίσες στο σαλόνι μου όπου εμφανίζονται εκτυπώσεις της δημιουργικής μου τέχνης και μου αρέσει ότι ο προγραμματισμός είναι υπεύθυνος για αυτό.
  • Ελκυστικά έργα - Όλοι είχαμε την εμπειρία να εξηγήσουμε ένα προσωπικό έργο σε κάποιον, πιθανώς ακόμη και κατά τη διάρκεια μιας συνέντευξης, χωρίς έναν εύκολο τρόπο να μεταδώσουμε την προσπάθεια και τα αποτελέσματα του έργου. Η γενετική τέχνη μιλά από μόνη της και οι περισσότεροι θα εντυπωσιαστούν από τις δημιουργίες σας, ακόμα κι αν δεν μπορούν να κατανοήσουν πλήρως τις μεθόδους.

Από πού πρέπει να ξεκινήσετε;

Το να ξεκινήσετε με τη δημιουργική τέχνη είναι η ίδια διαδικασία με οποιοδήποτε έργο, το πιο κρίσιμο βήμα είναι να βρείτε μια ιδέα ή να βρείτε μια ιδέα για να χτίσετε. Μόλις έχετε κατά νου έναν στόχο, τότε μπορείτε να αρχίσετε να εργάζεστε με την τεχνολογία που απαιτείται για να τον επιτύχετε.

Τα περισσότερα από τα δημιουργικά μου έργα τέχνης έχουν πραγματοποιηθεί στο Python. Είναι μια αρκετά εύκολη γλώσσα για να το συνηθίσετε και διαθέτει μερικά απίστευτα πακέτα διαθέσιμα για να βοηθήσετε στη διαχείριση εικόνων, όπως το Pillow.

Ευτυχώς για εσάς, δεν χρειάζεται να ψάξετε πολύ μακριά για ένα σημείο εκκίνησης, επειδή έχω δώσει έναν παρακάτω κώδικα για να παίξετε.

Γεννήτρια Sprite

Αυτό το έργο ξεκίνησε όταν είδα μια ανάρτηση να δείχνει μια γεννήτρια sprite γραμμένη σε Javascript Το πρόγραμμα δημιούργησε γραφικά sprite 5x5 pixel με μερικές τυχαίες επιλογές χρώματος και η παραγωγή του έμοιαζε με πολύχρωμους εισβολείς χώρου.

Ήξερα ότι ήθελα να ασκήσω χειραγώγηση εικόνων στο Python, οπότε σκέφτηκα ότι θα μπορούσα απλώς να επαναδημιουργήσω αυτήν την ιδέα μόνη μου. Επιπλέον, σκέφτηκα ότι θα μπορούσα να επεκταθώ σε αυτό, δεδομένου ότι το αρχικό έργο ήταν τόσο περιορισμένο στο μέγεθος των sprites. Ήθελα να μπορώ να καθορίσω όχι μόνο το μέγεθος, αλλά και τον αριθμό τους, ακόμη και το μέγεθος της εικόνας.

Ακολουθεί μια ματιά σε δύο διαφορετικές εξόδους από τη λύση που κατέληξα με:

Αυτές οι δύο εικόνες δεν μοιάζουν καθόλου μεταξύ τους, αλλά είναι και τα δύο αποτελέσματα του ίδιου συστήματος. Για να μην αναφέρουμε, λόγω της πολυπλοκότητας της εικόνας και της τυχαιότητας της παραγωγής sprite, υπάρχει μια εξαιρετικά υψηλή πιθανότητα ότι ακόμη και με τα ίδια επιχειρήματα, αυτές οι εικόνες θα είναι για πάντα μοναδικές. Το αγαπώ.

Το περιβάλλον

Εάν θέλετε να αρχίσετε να παίζετε με τη γεννήτρια sprite, υπάρχει μια μικρή θεμελιώδη εργασία που πρέπει να γίνει πρώτα.

Η δημιουργία ενός κατάλληλου περιβάλλοντος με το Python μπορεί να είναι δύσκολη. Εάν δεν έχετε συνεργαστεί με το Python στο παρελθόν, πιθανότατα θα χρειαστεί να κατεβάσετε το Python 2.7.10. Αρχικά είχα πρόβλημα να ρυθμίσω το περιβάλλον, οπότε αν αρχίσετε να αντιμετωπίζετε προβλήματα, μπορείτε να κάνετε ό, τι έκανα και να κοιτάξετε σε εικονικά περιβάλλοντα. Τελευταίο αλλά όχι λιγότερο σημαντικό, βεβαιωθείτε ότι έχετε εγκαταστήσει επίσης το Μαξιλάρι.

Μόλις ρυθμίσετε το περιβάλλον, μπορείτε να αντιγράψετε τον κωδικό μου σε ένα αρχείο με επέκταση .py και να εκτελέσετε με την ακόλουθη εντολή:

python spritething.py [SPRITE_DIMENSIONS] [NUMBER] [IMAGE_SIZE]

Για παράδειγμα, η εντολή για τη δημιουργία του πρώτου πίνακα sprites από πάνω θα ήταν:

python spritething.py 7 30 1900

Ο κώδικας

import PIL, random, sysfrom PIL import Image, ImageDraw
origDimension = 1500
r = lambda: random.randint(50,215)rc = lambda: (r(), r(), r())
listSym = []
def create_square(border, draw, randColor, element, size): if (element == int(size/2)): draw.rectangle(border, randColor) elif (len(listSym) == element+1): draw.rectangle(border,listSym.pop()) else: listSym.append(randColor) draw.rectangle(border, randColor)
def create_invader(border, draw, size): x0, y0, x1, y1 = border squareSize = (x1-x0)/size randColors = [rc(), rc(), rc(), (0,0,0), (0,0,0), (0,0,0)] i = 1
 for y in range(0, size): i *= -1 element = 0 for x in range(0, size): topLeftX = x*squareSize + x0 topLeftY = y*squareSize + y0 botRightX = topLeftX + squareSize botRightY = topLeftY + squareSize
 create_square((topLeftX, topLeftY, botRightX, botRightY), draw, random.choice(randColors), element, size) if (element == int(size/2) or element == 0): i *= -1; element += i
def main(size, invaders, imgSize): origDimension = imgSize origImage = Image.new('RGB', (origDimension, origDimension)) draw = ImageDraw.Draw(origImage)
 invaderSize = origDimension/invaders padding = invaderSize/size
 for x in range(0, invaders): for y in range(0, invaders): topLeftX = x*invaderSize + padding/2 topLeftY = y*invaderSize + padding/2 botRightX = topLeftX + invaderSize - padding botRightY = topLeftY + invaderSize - padding
 create_invader((topLeftX, topLeftY, botRightX, botRightY), draw, size)
 origImage.save("Examples/Example-"+str(size)+"x"+str(size)+"-"+str(invaders)+"-"+str(imgSize)+".jpg")
if __name__ == "__main__": main(int(sys.argv[1]), int(sys.argv[2]), int(sys.argv[3]))

Αυτή η λύση απέχει πολύ από το τέλειο, αλλά δείχνει ότι η δημιουργία δημιουργικής τέχνης δεν απαιτεί τόνο κώδικα. Θα προσπαθήσω να εξηγήσω τα βασικά κομμάτια.

Η κύρια λειτουργία ξεκινά δημιουργώντας την αρχική εικόνα και καθορίζοντας το μέγεθος των ξωτικών. Οι δύο για βρόχους είναι υπεύθυνοι για τον καθορισμό ενός περιγράμματος για κάθε sprite, διαιρώντας βασικά τις διαστάσεις της εικόνας με τον αριθμό των απαιτούμενων sprite. Αυτές οι τιμές χρησιμοποιούνται για τον προσδιορισμό των συντεταγμένων για κάθε μία.

Ας αγνοήσουμε την επένδυση και ρίξτε μια ματιά στην παρακάτω εικόνα. Φανταστείτε ότι καθένα από τα τέσσερα τετράγωνα αντιπροσωπεύει ένα sprite με μέγεθος 1. Το περίγραμμα που περνά στην επόμενη συνάρτηση αναφέρεται στις συντεταγμένες πάνω αριστερά και κάτω δεξιά. Έτσι η πλειάδα για το πάνω αριστερό sprite θα ήταν (0,0,1,1) ενώ η πλειάδα για το πάνω δεξί θα ήταν (1,0,2,1). Αυτά θα χρησιμοποιηθούν ως διαστάσεις και συντεταγμένες βάσης για τα τετράγωνα κάθε sprite.

Η συνάρτηση create_invader καθορίζει το περίγραμμα για κάθε τετράγωνο εντός του sprite. Η ίδια διαδικασία για τον προσδιορισμό του περιγράμματος εφαρμόζεται εδώ και παρουσιάζεται παρακάτω, μόνο αντί για την πλήρη εικόνα που χρησιμοποιούμε ένα προκαθορισμένο περίγραμμα για να εργαστούμε μέσα. Αυτές οι τελικές συντεταγμένες για κάθε τετράγωνο θα χρησιμοποιηθούν στην επόμενη συνάρτηση για να σχεδιάσουν πραγματικά το sprite.

To determine the color, a simple array of three random RGB tuples and three blacks are used to simulate a 50% chance of being drawn. The lambda functions near the top of the code are responsible for generating the RGB values.

The real trick of this function is creating symmetry. Each square is paired with an element value. In the image below you can see the element values increment as they reach the center and then decrement. Squares with matching element values are drawn with the same color.

As create_square receives its parameters from create_invader, it uses a queue and the element values from before to ensure symmetry. The first occurrence of the values have their colors pushed onto the queue and the mirrored squares pop the colors off.

Συνειδητοποιώ πόσο δύσκολο είναι να διαβάσω και να καταλάβω τη λύση κάποιου άλλου για ένα πρόβλημα και η τραχύτητα του κώδικα σίγουρα δεν βοηθά στην πολυπλοκότητά του, αλλά ελπίζουμε ότι έχετε μια πολύ καλή ιδέα για το πώς λειτουργεί. Τελικά θα ήταν απίστευτο εάν μπορείτε να απορρίψετε εντελώς τον κωδικό μου και να βρείτε μια εντελώς διαφορετική λύση.

συμπέρασμα

Η δημιουργική τέχνη χρειάζεται χρόνο για να εκτιμήσει πλήρως, αλλά αξίζει τον κόπο. Μου αρέσει να συνδυάζω τον προγραμματισμό με ένα πιο παραδοσιακό οπτικό, και έχω μάθει σίγουρα πολλά σε κάθε έργο μου.

Συνολικά, μπορεί να υπάρχουν πιο χρήσιμα έργα για επιδίωξη και η δημιουργική τέχνη μπορεί να μην είναι κάτι με το οποίο χρειάζεστε εμπειρία, αλλά είναι πολύ διασκεδαστικό και ποτέ δεν ξέρετε πώς μπορεί να σας χωρίσει από το πλήθος.

Ευχαριστούμε που το διαβάσατε!