Adrien, un ami entrepreneur, m'a montré récemment un petit projet qu'il a fait sur sa machine. Il a créé un fond d'écran animé Space Invaders (probablement à un moment d'ennui entre midi et deux ). Ce projet est visible à l'adresse suivante : http://www.space-bitton.com/
Les petits space invaders bougent sur la page web aléatoirement, avec une position des yeux et une couleur aléatoires. Adrien a fait ça avec les outils qu'il avait sous la main (HTML, CSS, un serveur PHP). Regardez le code de la page pour voir comment il a fait.
On s'est dit qu'il y avait beaucoup de façons différentes de faire ce space invaders et on vous propose justement un petit défi sous forme d'atelier sur ce forum. Les règles sont simples :
Ce défi durera 3 semaines, du 23 avril 2013 au 14 mai 2013 inclus. Durant ce temps, tout le monde est invité à présenter sa création dans ce topic et à aider les autres
A la fin, Adrien et moi ferons un petit compte-rendu des projets qui ont été créés à l'initiative de cet atelier. Nous en sélectionnerons en particulier 3 selon les critères suivants :
Code le plus concis (le moins d'octets possible)
Code le plus inutilement compliqué
Code le plus étonnant
L'atelier est ouvert à tout le monde, débutants comme plus expérimentés. N'oubliez pas que le but est simplement de s'amuser, il n'y a pas d'enjeu particulier.
Bon courage à tous !
Gagnants
Le jury (à savoir Adrien et moi ) a délibéré ! Nous avons été très agréablement surpris de l'intérêt porté à cet atelier, il y a eu plus de participations que nous ne pouvions rêver ! Du coup, les délibérations ont été longues mais il faut dire que vous avez fait preuve d'une créativité extraordinaire ! Nous tenons donc vraiment à féliciter tout le monde.
Sans plus attendre, notre verdict !
Catégorie "Code le plus étonnant"
Un grand bravo à Eskimon qui nous a tous vraiment surpris en choisissant la voie... électronique pour réaliser le space invaders ! Son projet Arduino est sans conteste le plus inattendu et le plus étonnant !
C'est une catégorie qui ne manquait pas de prétendants ! Nous avons eu du mal à choisir, mais nous nous inclinons devant la solution exotique en silverlight bien cossue de nico.pyright !
Beaucoup de prétendants ici. Il était très difficile de compter les caractères pour donner un gagnant "juste" (ça dépend pas mal du langage), donc nous en avons sélectionné un très bon réalisé par geex :
Tout d'abord merci pour ce défi qui, j'en suis sûr, sera suivi par pas mal de monde, mais avant de commencer à coder, j'ai une petite question: Dans le cas où l'un des participants utiliserait un lib externe (par exemple, dans mon cas, KineticJS), son poids compterait-elle dans le nombre d'octet pour le challenge du code le plus concis?
Je trouve que c'est une très bonne idée de lancer ce genre de concours, comme ça tout le monde pourra participer et exploiter ces compétences et les renforcer.
Donc voila je décide de participé et de réaliser un font animé avec toutes mes outils que je connais afin de produire le meilleur font dans le délai le plus rapide
Enfin je tiens a remercié toute l'équipe du SDZ et surtout Mateo21 et je vous dis soyez nombreux a participer et que le meilleur gagne
Pas nécessairement. Si tu le fais en Python pour générer des GIFs animés sans utiliser la lib standard (j'en ai entendu me dire qu'ils pensaient faire ça !), bah la validité w3c est hors sujet.
Au niveau de la technique, je dessine l'Invader sur base d'un tableau à deux dimensions. Je le redessine toutes les 3 secondes, et je le change de place. A mon avis, on peut difficilement faire plus simple.
La couleur est choisie aléatoirement, de même que la position.
C'est possible de l'utiliser comme Bookmarklet, pour pouvoir l'utiliser sur n'importe quelle page, suffit de glisser le lien se trouvant sur cette page
J'avais un peu de temps à tuer (ou plutôt la flemme de bosser), donc en attendant la version GIF animé de mon collegue, voici une autre version en Python utilisant uniquement la lib standard.
Au niveau technique
J'ai rusé, chaque pixel est en fait une fenetre (tkinter) sans bordure qui va se déplacer aléatoirement. Donc si vous le lancé chez vous, ça va créer un certain nombre de fenetre qui vont se déplacer et changer de couleurs. J'utilise un tableau 2D, tout comme Thunderseb mais legerement plus "souple" (au vu de son code que j'ai lu rapidement). En particulier, à chaque mise à jour, les yeux se "déplacent" (eventuellement, ils peuvent rester fixe) dans l'une des cases libres autour. Il peut y en avoir autant qu'on veut.
Le code brut ci-dessous reproduit la page donné en exemple. En decommentant les lignes 21 à 30 vous rajoutez en plus un deuxième space-invader qui va se déplacer plus souvent (1sec pour la MAJ), d'une forme différente avec des yeux plus gros.
Le code
Bon par contre le code est crade et vite fait, je pense que je le modifierai plus tard, c'est qu'une première ebauche. Mais si vous vous voulez vous en servir comme base, allez y
NB : Sur certaines distrib il peut être necessaire de remplacer la première ligne par #!/usr/bin/env python3
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import tkinter as tk
import random
from threading import Timer
class App(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.withdraw()
patt = (
(0,0,1,0,1,0,0),
(0,1,1,1,1,1,0),
(0,1,0,1,0,1,0),
(0,1,8,1,8,1,0),
(1,1,1,1,1,1,1),
(1,0,1,0,1,0,1))
self.si = SpaceInvader(self, patt, 50, 5, 3)
#patt2 = (
# (0,0,1,0,0,0,0,0,1,0,0),
# (0,0,0,1,0,0,0,1,0,0,0),
# (0,0,1,1,1,1,1,1,1,0,0),
# (0,1,1,8,0,1,0,8,1,1,0),
# (1,1,1,0,0,1,0,0,1,1,1),
# (1,0,1,1,1,1,1,1,1,0,1),
# (1,0,1,0,0,0,0,0,1,0,1),
# (0,0,0,1,1,0,1,1,0,0,0))
#self.si2 = SpaceInvader(self, patt2, 25, 2, 1)
class SpaceInvader:
def __init__(self, root, patern, size, margin, intMAJ):
self.intMAJ = intMAJ
self.margin = margin
self.fw = []
for l in range(len(patern)):
NL=[]
for c in range(len(patern[0])):
fp = None
if patern[l][c] is not 0:
fp = FloatingPixel(c,l,size,margin,root)
fp.dep = patern[l][c] is 8
NL.append(fp)
self.fw.append(NL)
self.DepPosX = root.winfo_screenwidth()-(len(patern)*size+(len(patern)+1)*margin)
self.DepPosY = root.winfo_screenheight()-(len(patern[0])*size+(len(patern[0])+1)*margin)
self.updateApp()
def updateApp(self):
depX = random.randint(0,self.DepPosX)
depY = random.randint(0,self.DepPosY)
col='#{:02x}{:02x}{:02x}'.format(*[random.randrange(0, 255) for i in range(3)])
ldep = []
for l in range(len(self.fw)):
for c in range(len(self.fw[0])):
if self.fw[l][c] is not None:
if not self.fw[l][c].dep:
self.fw[l][c].Updateconf(depX,depY,col )
else:
ldep.append((l,c,self.fw[l][c]))
for ol,oc,fwt in ldep:
lposPoss = []
for ii in range(max(0,ol-1),min(len(self.fw),ol+2)):
for jj in range(max(0,oc-1),min(len(self.fw[0]),oc+2)):
if self.fw[ii][jj] is None or self.fw[ii][jj] is fwt:
lposPoss.append((ii,jj))
nl,nc = lposPoss[random.randint(0,len(lposPoss)-1)]
self.fw[ol][oc],self.fw[nl][nc]=self.fw[nl][nc],self.fw[ol][oc]
fwt.yy = nl
fwt.xx = nc
fwt.Updateconf(depX,depY,'#000000')
self.ttimer = Timer(self.intMAJ, self.updateApp)
self.ttimer.start()
class FloatingPixel(tk.Toplevel):
def __init__(self,xx,yy,ss,margin, *args, **kwargs):
tk.Toplevel.__init__(self, *args, **kwargs)
self.overrideredirect(True)
self.xx=xx
self.yy=yy
self.ss=ss
self.margin=margin
self.dep = False
self.Updateconf(0,0,'#FFFFFF')
def Updateconf(self,depX,depY,col):
self.depX=depX
self.depY=depY
self.col = col
self.geometry("%dx%d%+d%+d" % (self.ss, self.ss, self.xx*(self.ss+self.margin) + self.depX, self.yy*(self.ss+self.margin)+self.depY))
self.configure(background=self.col)
app=App()
app.mainloop()
Bonus : A noter que si vous trouvez mes tableaux 2D pas tres lisibles, vous pouvez utiliser cette classe pour générer les paterne. Perso je trouve ça plus joli ainsi (je vous ai reproduit les 2 exemple de l'autre code)
class sic(object):
def __init__(self,base=None):
self.base= ([] if base is None else base)
def __getattr__(self, key):
self.base.append(tuple([ (0 if c is '_' else ( 1 if c is 'X' else 8 )) for c in key ]))
return sic(self.base)
def __call__(self):
return self.base
patt =sic().__X_X__.\
_XXXXX_.\
_XoXoX_.\
_X_X_X_.\
XXXXXXX.\
X_X_X_X()
patt2=sic().__X_____X__.\
___X___X___.\
__XXXXXXX__.\
_XXo_X_oXX_.\
XXX__X__XXX.\
X_XXXXXXX_X.\
X_X_____X_X.\
___XX_XX___()
Bonus 2 Une autre version en jouant avec Unicode cette fois, toujours pour générer les patterns.
def sic2(ss):
return tuple([tuple([ (0 if c == '░' else ( 1 if c == '█' else 8 )) for c in l ]) for l in ss.split('\n') if len(l) > 0])
patt=sic2("""
░░█░█░░
░█████░
░█◉█◉█░
░█░█░█░
███████
█░█░█░█
""")
patt2=sic2("""
░░█░░░░░█░░
░░░█░░░█░░░
░░███████░░
░██◉░█░◉██░
███░░█░░███
█░███████░█
█░█░░░░░█░█
░░░██░██░░░
""")
PS: A noter que meme si tkinter fait bien partit de la lib standard, tk n'est pas forcément installé. j'ai du l'installer chez moi (pour arch un pacman -S tk suffit)
- Edité par Dr. kristofjé 23 avril 2013 à 20:56:06
C'est dommage que la page soit obligée de se recharger, ce qui fait que ce n'est pas vraiment un "background". Tu devrais modifier pur ajouter un peu d'AJAX, qui réactualiserait l'invader sans recharger complètement la page.
Le javascript seul fait 489 caractères... 688 avec le html...
Edit : je n'arrive pas trop à me servir des bbcodes de la nouvelle version du SdZ, alors voici le lien direct du script : http://rannios.free.fr/spaceInvader.js
Une autre version en C, également avec la SDL. Je n’ai qu’un nombre ridicule de couleur, mais c’est juste des triplets rgb à ajouter et j’ai un peu la flemme.
Une version en console ça pourrait être sympa aussi.
Ah oui, le code (sensiblement identique à celui de Blodangan).
Je vois que personne n'a posté de code dégueulasse jusqu'à présent ; je m'empresse donc de relever le niveau. Voici un petit programme conforme à la norme (pas strictly-conforming, certes). Bon, c'est du code pour UNIX. Sous MS Windows, il faut faire un coup de compilation conditionnelle, mais ça enlevait un peu d'élégance, je trouvais. Voilà la bête :
À exécuter dans un émulateur de terminal en 25*80, sinon c'est pas drôle. Et puis, uhm, c'est assez rudimentaire.
Bonne soirée !
PS : C'est pas non plus super obfusqué, mais ça tient sur 361 c (sans les #include). Si j'ai le temps, je ferai peut-être une participation un peu plus « sérieuse ».
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
If you'd like to join us, read "How do we work at OpenClassrooms"! :)
Avatar by MaxRoyo. Venez parler du sdz
If you'd like to join us, read "How do we work at OpenClassrooms"! :)
N'utilisez JAMAIS alert() pour debugger. Utilisez console.log()
If you'd like to join us, read "How do we work at OpenClassrooms"! :)
If you'd like to join us, read "How do we work at OpenClassrooms"! :)
Ma vraie biographie - Ex-Manager de la Validation sur le Site du Zéro - sdlm.be - Horus.aero
Ma vraie biographie - Ex-Manager de la Validation sur le Site du Zéro - sdlm.be - Horus.aero
Ma vraie biographie - Ex-Manager de la Validation sur le Site du Zéro - sdlm.be - Horus.aero
N'utilisez JAMAIS alert() pour debugger. Utilisez console.log()
If you'd like to join us, read "How do we work at OpenClassrooms"! :)