Code : Tout sélectionner
; Dobro Version 8.8
Declare.f RotationX(x.f, angle.f, dist.f)
Declare.f RotationY(y.f, angle.f, dist.f)
Declare.f ReturnDegAngle(x1.f, y1.f, x2.f, y2.f) ; DEGREE
Structure fourmi
x.f
y.f
memoire_nid_x.f
memoire_nid_y.f
memoire_bouffe_x.f
memoire_bouffe_y.f
mode.s ; determinera si la fourmi est en mode recherche,rapatriement de bouffe, ou pondeuse de pheromone
tictac.b ; ceci va dire a la fourmis dans quel sens elle doit aller
angle.f
memoire_coul.l
memoire_phero.l
EndStructure
Structure pheromone
x.l
y.l
memoire_bouffe_x.f ; chaque pheromones contien la coordoné de la bouffe
memoire_bouffe_y.f ; comme ça si une fourmis tombe dessus, elle saura ou ce trouve la bouffe
coul.l
id.l
EndStructure
Structure nid
x.f
y.f
EndStructure
Structure bouffe
x.f
y.f
quantite.l ; servira a diminuer la taille de la bouffe au fur et a mesure
id.l
EndStructure
Enumeration 1 Step 1000
#sprite_fond
#fourmi ; image de la fourmi
#bouffe ; image de la bouffe
#nid ; image du nid
#pheromone ; image des phero
#retour
EndEnumeration
; Test
Global EcranX = GetSystemMetrics_(#SM_CXSCREEN)
Global EcranY = GetSystemMetrics_(#SM_CYSCREEN)
; ************* variables initialisations **************************
;- tableau de bord reglages
Global nbr_fourmi = 10
Global nbr_bouffe = 5
Global nbr_pheromone = nbr_bouffe
Global nbr_nid = 0
Global Dim bouffe.bouffe(nbr_bouffe)
Global Dim nId.nid(nbr_nid)
Global Dim pheromone.pheromone(nbr_bouffe) ; le nombre de piste de pheromone doit etre egale au nombre de bouffe
Global Dim fourmi.fourmi(nbr_fourmi)
Global aaa
; *********************************
; ***********************************************************
InitSprite() : InitKeyboard()
OpenScreen (EcranX, EcranY, 32, "Fourmis")
; *********** ce sprite sert a effacer le fond ! ****************************
CreateSprite(#sprite_fond, EcranX, EcranY)
StartDrawing(SpriteOutput(#sprite_fond))
Box(0, 0, EcranX, EcranY, RGB(0, 0, 0))
StopDrawing()
; ***************************************************************************
; *********** cree le sprite nid *****************
nid(0)\x = EcranX / 2 ; coordoné du nid
nid(0)\y = EcranY / 2
CreateSprite(#nid, 32, 32) ;
; dessine le sprite
StartDrawing(SpriteOutput(#nid))
Circle(16, 16, 16, RGB($0, $80, $FF))
StopDrawing()
; ***********************************************
; *********** cree le sprite fourmi*****************
; prepare les fourmis en leur chargeant en "rom" les coordonée de leur nid
; et en leur indiquant leur mode a la naissance !! "recherche"
For i = 0 To nbr_fourmi
fourmi(i)\x = nid(0)\x : fourmi(i)\y = nid(0)\y
fourmi(i)\memoire_nid_x = nid(0)\x ; on donne a la fourmi la memoire de la coordonné de son nid
fourmi(i)\memoire_nid_y = nid(0)\y ; de cette façon elle saura ou se trouve celui-ci
fourmi(i)\mode = "recherche"
fourmi(i)\angle = Random(360)
Next i
CreateSprite(#fourmi, 16, 16) ; c'est la meme image qui est employé
; dessine le sprite
StartDrawing(SpriteOutput(#fourmi))
Circle(8, 8, 8, RGB($D6, $74, $3F))
StopDrawing()
; ***********************************************
; *********** cree le sprite pheromonone de retour *****************
CreateSprite(#retour, 4, 4) ; c'est la meme image qui est employé
; dessine le sprite
StartDrawing(SpriteOutput(#retour))
Circle(2, 2, 2, RGB($FF, 0, 0))
StopDrawing()
; ***********************************************
; *********** cree le sprite pheromone *****************
For i = 0 To nbr_pheromone
CreateSprite(#pheromone + i, 4, 4 ) ;
deb :
; dessine le sprite
coul = Random(155) + 100
coul1 = Random(155) + 100
coul2 = Random(155) + 100
; empeche la creation de 2 fois la meme couleur
For oo = 0 To i
cooul = pheromone(oo)\coul
If RGB(coul, coul2, coul3) = cooul
Goto deb
EndIf
Next oo
StartDrawing(SpriteOutput(#pheromone + i))
Circle(2, 2, 2, RGB(coul, coul1, coul2))
StopDrawing()
pheromone(i)\coul = RGB(coul, coul1, coul2)
pheromone(i)\id = #pheromone + i
Next i
; ***********************************************
; *********** cree le sprite bouffe *****************
For i = 0 To nbr_bouffe
; ****** initialisation bouffe **********
bouffe(i)\x = Random(EcranX - 50) + 25
bouffe(i)\y = Random(EcranY - 50) + 25
bouffe(i)\quantite = 32
bouffe(i)\id = i
; *****²²****************************
CreateSprite(#bouffe + i, bouffe(i)\quantite, bouffe(i)\quantite) ;
; dessine le sprite
StartDrawing(SpriteOutput(#bouffe + i))
Circle(bouffe(i)\quantite / 2, bouffe(i)\quantite / 2, bouffe(i)\quantite / 2, RGB($FF, $FF, $0))
StopDrawing()
Next i
; ***********************************************
Repeat
DisplaySprite(#sprite_fond, 0, 0) ; lui il passe son temps a effacer l'ecran , et a retenir les traces de pheromones
For i = 0 To nbr_fourmi
For rr = 0 To nbr_bouffe
; ; ************* collision fourmi =>bouffe et rapatriement ***************************************
If SpritePixelCollision(#fourmi, fourmi(i)\x, fourmi(i)\y, #bouffe + rr, bouffe(rr)\x, bouffe(rr)\y)
If fourmi(i)\mode = "rap"
fourmi(i)\tictac = 1 ; retourne vers le nid
bouffe(rr)\quantite = bouffe(rr)\quantite - 1
; *************** reduit la bouffe ***************
StartDrawing(SpriteOutput(#bouffe + rr))
Box(0, 0, bouffe(rr)\quantite + 1, bouffe(rr)\quantite + 1, RGB(0, 0, 0))
Circle(bouffe(rr)\quantite / 2, bouffe(rr)\quantite / 2, bouffe(rr)\quantite / 2, RGB($FF, $FF, $0))
StopDrawing()
EndIf
EndIf
; ***********************************************************************
; *************** collision fourmi => bouffe et mode recherche *********************************
If SpritePixelCollision(#fourmi, fourmi(i)\x, fourmi(i)\y, #bouffe + rr, bouffe(rr)\x, bouffe(rr)\y) And bouffe(rr)\quantite > 5
If fourmi(i)\mode = "recherche"
fourmi(i)\memoire_bouffe_x = bouffe(rr)\x ; la fourmis recupere les cordonné de la bouffe
fourmi(i)\memoire_bouffe_y = bouffe(rr)\y ; la fourmis recupere les cordonné de la bouffe
fourmi(i)\mode = "pondre" ; et passe en mode pondre des pheromones
fourmi(i)\memoire_phero = pheromone(rr)\id ; autant de phero que de bouffe
EndIf
EndIf
; ************************************************************************
; ************* collision fourmi => nid et mode pondre ***************************************
If SpritePixelCollision(#fourmi, fourmi(i)\x, fourmi(i)\y, #nid, nid(0)\x, nid(0)\y)
If fourmi(i)\mode = "pondre"
fourmi(i)\mode = "rap"
EndIf
EndIf
; ***********************************************************************
; ************* collision fourmi => nid et rapatriement***************************************
If SpritePixelCollision(#fourmi, fourmi(i)\x, fourmi(i)\y, #nid, nid(0)\x, nid(0)\y)
For bbb = 0 To nbr_bouffe
If fourmi(i)\mode = "rap"
fourmi(i)\tictac = 0 ; retourne vers la bouffe
; ************************************************
If bouffe(bbb)\quantite < 5
; passe en mode recherche si plus de bouffe
bouffe(bbb)\quantite = 0 ;
uuu = i
If fourmi(uuu)\mode = "rap"
If fourmi(uuu)\memoire_bouffe_x = bouffe(bbb)\x
If fourmi(uuu)\memoire_bouffe_y = bouffe(bbb)\y
fourmi(uuu)\tictac = 1
fourmi(uuu)\mode = "recherche"
fourmi(uuu)\memoire_bouffe_x = 0 ; efface la memoire de la fourmis
fourmi(uuu)\memoire_bouffe_y = 0
EndIf
EndIf
EndIf
EndIf
EndIf
Next bbb
EndIf
; ************* collision fourmi => pheromone et que bouffe valable***************************************
;- collision fourmi =>phero
;
If fourmi(i)\mode = "recherche"
StartDrawing(ScreenOutput())
For xxxx = 0 To nbr_pheromone
; on regarde si collision entre fourmis et couleur de phero existante
If Point(fourmi(i)\x + 2, fourmi(i)\y + 2) = pheromone(xxxx)\coul ; si oui
If bouffe(xxxx)\quantite > 5
fourmi(i)\memoire_bouffe_x = pheromone(xxxx)\memoire_bouffe_x ;
fourmi(i)\memoire_bouffe_y = pheromone(xxxx)\memoire_bouffe_y
fourmi(i)\memoire_coul = pheromone(xxxx)\coul ; met en memoire la couleur
fourmi(i)\memoire_phero = pheromone(xxxx)\id
fourmi(i)\mode = "rap"
fourmi(i)\tictac = 0 ; va ver la bouffe
EndIf
EndIf
Next xxxx
StopDrawing()
EndIf
; ***********************************************************************
Select fourmi(i)\mode
;- mode recherche
;{ mode recherche
Case"recherche"
StartDrawing(SpriteOutput(#fourmi))
Circle(8, 8, 8, RGB($0, $FF, $0))
StopDrawing()
temp = Random(50)
If temp = 25
fourmi(i)\angle + Random(91) - 45 ; choix de la direction
EndIf
;- mode rapatriement
Case "rap"
If bouffe(rr)\quantite >= 5 ; on va effectuer des allez retour nid<=>bouffe
If fourmi(i)\tictac = 0 ; va ver la bouffe
StartDrawing(SpriteOutput(#fourmi))
Circle(8, 8, 8, RGB($0, 0, $FF))
StopDrawing()
fourmi(i)\angle.f = ReturnDegAngle(fourmi(i)\x, fourmi(i)\y, fourmi(i)\memoire_bouffe_x, fourmi(i)\memoire_bouffe_y) ; DEGREE
; va vers la bouffe (trace du retour )x,y
;- trace retour
StartDrawing(SpriteOutput(fourmi(i)\memoire_phero))
Circle(2, 2, 2, fourmi(i)\memoire_coul )
StopDrawing()
UseBuffer(#sprite_fond)
DisplayTransparentSprite(fourmi(i)\memoire_phero, fourmi(i)\x + 2, fourmi(i)\y + 2)
UseBuffer(#PB_Default)
EndIf
EndIf
If fourmi(i)\tictac = 1 ; va ver le nid
fourmi(i)\angle.f = ReturnDegAngle(fourmi(i)\x, fourmi(i)\y, fourmi(i)\memoire_nid_x, fourmi(i)\memoire_nid_y) ; DEGREE
StartDrawing(SpriteOutput(#fourmi))
Circle(8, 8, 8, RGB($0, 0, $FF))
Circle(8, 8, 4, RGB($FF, $FF, $0))
StopDrawing()
EndIf
;- mode pondre
Case "pondre"
; va vers le nid x,y
fourmi(i)\angle.f = ReturnDegAngle(fourmi(i)\x, fourmi(i)\y, fourmi(i)\memoire_nid_x, fourmi(i)\memoire_nid_y) ; DEGREE
pheromone(rr)\x = fourmi(i)\x + 2 ; la pheromone recupere la coordoné de la fourmis
pheromone(rr)\y = fourmi(i)\y + 2
pheromone(rr)\memoire_bouffe_x = fourmi(i)\memoire_bouffe_x ; et recupere la coordoné de la bouffe
pheromone(rr)\memoire_bouffe_y = fourmi(i)\memoire_bouffe_y ; et recupere la coordoné de la bouffe
UseBuffer(#sprite_fond)
DisplayTransparentSprite( fourmi(i)\memoire_phero, pheromone(rr)\x, pheromone(rr)\y)
UseBuffer(#PB_Default)
EndSelect
; *************************************************************************************
;}
; une fois que le sens est aquis: déplacement
fourmi(i)\x = RotationX( fourmi(i)\x, fourmi(i)\angle.f, 0.5)
fourmi(i)\y = RotationY( fourmi(i)\y, fourmi(i)\angle.f, 0.5)
If fourmi(i)\x < 10
fourmi(i)\x = 10
If fourmi(i)\angle > 180
fourmi(i)\angle = 270
Else
fourmi(i)\angle = 90
EndIf
EndIf
If fourmi(i)\x > EcranX - 20
fourmi(i)\x = EcranX - 20
If fourmi(i)\angle > 0
fourmi(i)\angle = 90
Else
fourmi(i)\angle = 270
EndIf
EndIf
If fourmi(i)\y < 10
fourmi(i)\y = 10
If fourmi(i)\angle > 90
fourmi(i)\angle = 180
Else
fourmi(i)\angle = 0
EndIf
EndIf
If fourmi(i)\y > EcranY - 20 ; 768
fourmi(i)\y = EcranY - 20
If fourmi(i)\angle > 270
fourmi(i)\angle = 0
Else
fourmi(i)\angle = 180
EndIf
EndIf
;- affichage
DisplayTransparentSprite(#fourmi, fourmi(i)\x, fourmi(i)\y) ; toujour la meme image qui est affiché
DisplayTransparentSprite(#nid, nid(0)\x, nid(0)\y ) ; affiche le nid (1 pour commencer)
DisplayTransparentSprite(#bouffe + rr, bouffe(rr)\x, bouffe(rr)\y) ; affiche la bouffe (1 pour commencer)
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Escape)
End
EndIf
Next rr
dede = Random(10)
If dede = 8
; ************ les pheromones qui s'efface progressivement sur tout le terrain
UseBuffer(#sprite_fond)
xplo = Random(EcranX - 2) + 1
yplo = Random(EcranY - 2) + 1
xplo2 = Random(EcranX - 2) + 1
yplo2 = Random(EcranY - 2) + 1
StartDrawing(SpriteOutput(#sprite_fond))
LineXY(xplot, yplo, xplo2, yplo2, RGB(0, 0, 0))
StopDrawing()
UseBuffer(#PB_Default)
; ************************************************************
EndIf
Next i
FlipBuffers()
ForEver
; ²
Procedure.f RotationX(x.f, angle.f, dist.f)
ProcedureReturn x + Cos(angle * #PI / 180) * dist
EndProcedure
Procedure.f RotationY(y.f, angle.f, dist.f)
ProcedureReturn y + Sin(angle * #PI / 180) * dist
EndProcedure
Procedure.f ReturnDegAngle(x1.f, y1.f, x2.f, y2.f) ; DEGREE
; cpl-Bator
A.f = x1 - x2
b.f = y1 - y2
c.f = -Sqr(A * A + b * b)
angle.f = ACos(A / c) * 180 / #PI
If y1 < y2 : angle = 360 - angle : EndIf
ProcedureReturn Abs(angle - 360)
EndProcedure