Petit programme de raycasting ( - de 3ko) [Python] - Python - Programmation
Marsh Posté le 03-03-2005 à 21:34:04
printf a écrit : Le John Carmack suisse |
Je précise encore une fois que je n'ai strictement rien inventé. J'ai repris ce programme de Login, qui l'a surement repris de John Carmack.
Marsh Posté le 04-03-2005 à 00:12:09
New version !!!
Pour ceux qui veulent avoir un truc plus "style", téléchargez cette image:
http://img71.exs.cx/img71/421/degrade8ag.gif
Ca met un dégradé en fond d'image. Il faut le sauver sur le disque, le placer dans le même dossier que le script et le renommer en "degrade.gif".
Ensuite, il faut modifier le code. Il faut ajouter ces deux lignes entre les lignes 110 et 111:
photo = PhotoImage(file="degrade.gif",width=360, height=200)
item = can1.create_image(0, 0, anchor=NW, image=photo)
Et voici le résultat:
Marsh Posté le 04-03-2005 à 02:30:44
Est-ce que tu pourrais expliquer/commenter ce que fait exactement le code ( quelle est la logique pour rendre une telle image ) stp ?
Marsh Posté le 04-03-2005 à 02:39:04
0x90 a écrit : Est-ce que tu pourrais expliquer/commenter ce que fait exactement le code ( quelle est la logique pour rendre une telle image ) stp ? |
Ouaip, je le ferais demain, promis.
Marsh Posté le 04-03-2005 à 20:05:03
Voila, j'ai ajouté quelques commentaires dans le code. Je vais essayer d'en rajouter un peu plus ce soir.
Si vous avez des questions, n'hésitez pas.
Marsh Posté le 04-03-2005 à 20:29:12
Nan .. pas de questions ..
Par contre, je dis !
J'espère que tu vas continuer à nous abbreuver de ce genre de petits programmes très sympathiques !
Marsh Posté le 04-03-2005 à 20:32:45
Mr Mala a écrit : Nan .. pas de questions .. |
Merci. Mais c'était facile, vu que j'avais tout sous la main. Par contre, j'ai un autre projet en tête, mais bien, bien plus lourd et plus sérieux que celui-ci.
(mais qui n'a rien à voir avec ce genre de programme)
Citation : J'espère que tu vas continuer à nous abbreuver de ce genre de petits programmes très sympathiques ! |
Si je trouve des idées, pourquoi pas.
A part ça, je suis un peu déçu du faible nombre de posts dans cette rubrique Python.
Y'aurait pourtant de quoi faire nettement plus.
Marsh Posté le 04-03-2005 à 20:44:06
Ben faut peut-être lancer la machine ?
D'autant plus qu'en voyant ça, tout doucement envie de m'y mettre moi !
Marsh Posté le 04-03-2005 à 20:56:38
Mr Mala a écrit : Ben faut peut-être lancer la machine ? |
Ouaip.
Citation : D'autant plus qu'en voyant ça, tout doucement envie de m'y mettre moi ! |
C'est clair, c'est graphique, ludique, ça donne envie.
Tu programmes dans quel(s) langage(s) actuellement ?
Marsh Posté le 04-03-2005 à 22:28:26
Rasthor a écrit : Tu programmes dans quel(s) langage(s) actuellement ? |
Ben .. mmmmmmmmh .. je sais pas comment je dois te dire ça .. mmmmmmh ... ActionScript
( entre autre .. mais principalement .. cf ma signature - Chemistry - pour avoir une idée plus précise )
Marsh Posté le 04-03-2005 à 23:21:42
Mr Mala a écrit : Ben .. mmmmmmmmh .. je sais pas comment je dois te dire ça .. mmmmmmh ... ActionScript |
C'est toi qui l'a fait ? Sympa.
Mais Python, c'est mieux.
Marsh Posté le 09-03-2005 à 20:39:34
C'est vraiment cool ça. Quand est ce qu'on a la version avec textures et avec forme plus arbitraires comme dans Doom 1 ?
Marsh Posté le 10-03-2005 à 00:33:45
Kristoph a écrit : C'est vraiment cool ça. Quand est ce qu'on a la version avec textures et avec forme plus arbitraires comme dans Doom 1 ? |
Je peux vite essayer de coder ça.
Marsh Posté le 13-04-2006 à 15:41:17
ReplyMarsh Posté le 19-04-2006 à 01:18:18
juste une petite suggestion... ca a l'air de rien, parce que la c'est du precalcul, mais quand même, pour la route
Code :
|
le truc, c'est que cos(a) est compris entre -1 et 1 modulo Pi donc, il te suffi de calculer la moitiée... ce qui deviendrait
Code :
|
on peut même aller jusqu'a ne calculer qu'un quart de cercle...
Marsh Posté le 22-05-2006 à 22:03:54
Il est où le problème ?
Bon, sinon, il y a quelque temps, j'ai repris le script python et l'article Rebol que j'avais aussi, j'ai adapté ça en java, ça marche. et y'a 2 semaines, j'ai essayé le "Write Once, Run Every Where" de java, en faisiant une version J2ME
et ça marche
Ca sert bien evidement a rien
(désoler pour le screen un peu grand...)
Marsh Posté le 03-03-2005 à 13:49:25
(j'ai changé le titre, ça fait moins pompeux )
Je me suis mis sérieusement au Python et je viens d'achever mon premier code original hier soir, donc c'est un peu la fête.
Enfin original est un bien grand mot, puisque je n'ai fait que retranscrire mot pour mot, variables pour variables, un programme Rebol, qui était donné en exemple dans un numéro de Login (Numéro 14 de Septembre 2002, pages 76-77).
Le principe du programme est bêtement un moteur de Raycasting, comme celui de Wolfenstein premier du nom.
Un screenshot () :
Il faut aussi télécharger cette image:
http://img71.exs.cx/img71/421/degrade8ag.gif
Ca met un dégradé en fond d'image. Il faut le sauver sur le disque, le placer dans le même dossier que le script et le renommer en "degrade.gif".
Enfin bref, voici le code:
Faut encore que je fasse un degradé en fond d'écran (quelqu'un saurait-il faire ceci ?), que je fusionne les commande avance et recule et que je le commente un peu plus.
Sinon des avis sur le code en lui-même ? Des idées d'amélioration, d'optimisation ?
PS: le code pour le copier coller directement:
#########################
# #
# Moteur de Raycasting #
# #
#########################
# Import de Tkinter et des fonctions trigo utilisees
from Tkinter import *
from math import cos, radians
# Definition des variables
px = 9 * 1024
py = 11 * 1024
stride = 5 # pas de deplacement
heading = 0 # angle de vue
turn = 10 # nombre de degres par rotation
# Definition du labyrinthe.
# 0 = sol ou l'on peut se deplacer
# Plus grand que 0 = mur, et le chiffre defini la couleur
laby = [[ 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7],
[ 7, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 8],
[ 8, 0, 0, 0, 12, 0, 0, 0, 14, 0, 9, 7],
[ 7, 0, 0, 0, 12, 0, 4, 0, 13, 0, 0, 8],
[ 8, 0, 4, 11, 11, 0, 3, 0, 0, 0, 0, 7],
[ 7, 0, 3, 0, 12, 3, 4, 3, 4, 3, 0, 8],
[ 8, 0, 4, 0, 0, 0, 3, 0, 3, 0, 0, 7],
[ 7, 0, 3, 0, 0, 0, 4, 0, 4, 0, 9, 8],
[ 8, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 7],
[ 7, 0, 5, 6, 5, 6, 0, 0, 0, 0, 0, 8],
[ 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7],
[ 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7]]
# Palette de couleur. La valeur du mur defini la valeur de la couleur.
palette = ["#000080","#008000","#008080",
"#000080","#800080","#808000","#C0C0C0",
"#808080","#0000FF","#00FF00","#FFFF00",
"#0000FF","#FF00FF","#00FFFF","#FFFFFF"]
# Table des cosinus precalcules. On gagne un peu en vitesse.
ctable = []
for a in range(0,(359+180)):
ctable.append(int((cos(radians(a))*1024)/10))
# Fonction pour trouver le cosinu de l'angle v.
def getangle(v):
return ctable[v+1]
#####################################
#
# Moteur principal du raycasting
#
def retrace():
# On efface le labyrinthe
can1.delete('rectangle')
# On initialise les valeurs
xy1x = 0
xy1y = 0
xy2x = 0
xy2y = 0
angle = heading-44 % 360
if angle < 0:
angle = angle+360
# On parcout les 90 degres de l'angle de vue.
# On lance un rayon xx/yy et des qu'il touche un mur,
# on affiche un rectangle
for a in range(angle,angle+89):
xx = px
yy = py
stepx = getangle(a+90)
stepy = getangle(a)
l = 0
while 1:
xx = xx-stepx
yy = yy-stepy
l = l+1
colonne = int(xx/1024)
ligne = int(yy/1024)
# Instruction de controle:
# la boucle s'arrete si le rayon touche un mur (<> 0).
if laby[ligne][colonne] <> 0:
break
# On calcule la hauteur du rectangle
h = int(900/l)
xy1y = 100-h
xy2y = 100+h
# Le rectangle fait 3 pixels de largeur
xy2x = xy1x + 3
# On determine la couleur du rectangle
color = palette[laby[ligne][colonne]]
# On affiche le rectangle et on recommence
can1.create_rectangle(xy1x, xy1y, xy2x, xy2y, fill=color,outline=color,tag='rectangle')
xy1x = xy2x+1
##################################
#
# Gestionnaire d'evenements :
#
# On determine les 4 fonctions possibles: avancer, reculer, tourner la tête
# à droite et tourner la tête à gauche.
def depl_avance(event):
global px, py
# On avance selon le pas "stride" determie au debut.
# On calcul le cosinus de l'angle en question.
newpx = px - getangle(heading+90)*stride
newpy = py - getangle(heading)*stride
c = int(newpx/1024)
l = int(newpy/1024)
# On controle si l'on peut se deplacer.
if laby[l][c] == 0:
px = newpx
py = newpy
retrace()
def depl_recule(event):
global px, py
newpx = px - getangle(heading+90)*stride*-1
newpy = py - getangle(heading)*stride*-1
c = int(newpx/1024)
l = int(newpy/1024)
if laby[l][c] == 0:
px = newpx
py = newpy
retrace()
def turn_left(event):
global heading
heading = (heading + (360 -turn)) % 360
retrace()
def turn_right(event):
global heading
heading = (heading + turn) % 360
retrace()
# Creation du canvas:
fen1 = Tk()
can1 = Canvas(fen1,bg="dark grey", height=200, width=360)
# On charge le degrade de fond. C'est une image gif.
# A ameliorer: degrade directement en python.
if open("degrade.gif" ):
photo = PhotoImage(file="degrade.gif",width=360, height=200)
item = can1.create_image(0, 0, anchor=NW, image=photo)
can1.pack()
# On trace une premiere fois le labyrinthe
retrace()
# Liaison des evenements
fen1.bind("<Up>",depl_avance)
fen1.bind("<Down>",depl_recule)
fen1.bind("<Left>",turn_left)
fen1.bind("<Right>",turn_right)
# demarrage du receptionnaire d'evenements (boucle principale) :
fen1.mainloop()
Message édité par Rasthor le 04-03-2005 à 23:57:50