G-Rom a écrit :Petit bonus avant d'aller au dodo , reprise de mon code plus haut
avec ajout de plusieurs ennemis , et pseudo IA ( 2 statuts , poursuite & replace )
L'IA poursuit le joueur , si l'ennemi est à moins de 400 pixels , il tire 4 coups par seconde
si l'ennemi s'approche de trop près d'un autre ennemi , il ne poursuit plus le joueur , mais va à une position aléatoire sur l'écran
Super, la grande classe

Merci.
J'ai regardé ça, et je me suis aussi amusé à changer des choses (le filou que je suis

) :
Les nouveautés de ton fichier.
Ennemi :
J'ai ajouté des nouveaux paramètres :
- classe (random(3)) > la classe de l'ennemi : la classe est elle potentiellement agressive ou pas par exemple, et ça pourra servir à autre chose plus tard)
- type (random(4)): pour savoir l'ennemi tire tout de suite sur le joueur, ou s'il attend que le joueur lui tire dessus. Avec type, on définit son comportement : type = 0 (attaque), type = 1 (attend), type = 2 la fuite, type = 3 protége ses copains s'ils sont dans un rayon < 1000 pixels, etc.. Bref, y'a de quoi faire

. Ne peuvent avoir le type 0 que les ennemis de la classe > 0.
- Autre variables nouvelles : vie_max et vie_courrante, level, et speed_base
Autres nouveautés :
- variable \state=#IA_wait : il est d'abord en attente (ben oui, éh oh, il a pas non plus un radar sur sa tête pour voir le joueur)
- si le joueur passe à moins de 200 pixels, il le suit et il tire dessus, s'il a le type agressif (0) sinon, il attend que le joueur lui tire dessus et là, il se défend, le bougre (type = 1), ou bien il s'enfuit (type2).
- si le joueur est plus loin que 450 pixel, il arrête de tirer et est à nouveau en mode "attente".
Joueur :
- ajout de plusieurs variables aussi : vie_max, vie_courante, level,
- lorsque l'ennemi lui tire dessus, le jouer perd de la vie
- on se déplace au clavier et on tir en cliquant (ou restant cliqué), et en visant l'ennemi.
BUGs :
- Il y a un petit bug lors de la création de la première belette...heu bulett

des ennemis. Je verrai pour le corriger.
Corrigé : un autre bug, mais je ne sais pas le résoudre celui-là : lorsqu'un ennemi disparait, les bullets continuent à comparer leur position avec les ennemy, mais il arrive que cela plante, car elles ne trouvent pas l'ennemy qui vient de disparaitre. Savez-vous comment résoudre ça ?
Todos-liste
Je pense aussi ajouter ça par la suite :
- un déplacement aléatoire en attendant que le joueur passe devant lui.
- faire que si la vie est à zéro, il se passe quelque chose :p.
- par la suite, lorsque l'ennemi meurt, mettre sur le sol des objets de drop (potions de vie par exemple)
- ajouter aussi des tips d'armes qui font plus de dégats
- on pourrait ajouter plein d'autres trucs encore
le code un peu modifié :
Code : Tout sélectionner
;{ ************************ Option compilation ***********************
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
KeyboardMode(#PB_Keyboard_International)
If Subsystem("opengl")=0
CloseScreen()
MessageRequester("Erreur","must use opengl subsystem")
End
EndIf
CompilerEndIf
;}
;{ ************************ enumeration et variables ***********************
Enumeration
#FOLLOW_PLAYER
#REPLACE
#IA_wait
EndEnumeration
#NB_ENNEMY = 5
#window = 0
#ScreenW = 1024
#ScreenH = 768
ShowCursor_(1)
Global inscreen = 1
;}
;{ ************************ Structures ***********************
Structure vector2f
x.f
y.f
EndStructure
Structure objet
position.vector2f
Direction.vector2f
Length.f ; la distance entre 2 positions
timeToCalcTraj.i
temps_sort.i ; le temps qu'il met entre 2 tirs
speed.f ; la vitesse actuelle (à l'arret speed = 0, si il court speed= speed_base
speed_base.f ; la vitesse maximum
vie_max.i ; vie maximum qu'on peut avoir
vie_courante.i ; vie actuelle que l'on a
level.i ; le niveau du personnage
classe.i ; la classe
type.i ; 0 = agressif, 1 = attend qu'on l'attaque, 2 = peureux (s'enfuit si on l'attaque), 3 = défend ses copains si on les attaque..
timeToShoot.i
xp.i ; les points d'xp qu'on récolte
EndStructure
Structure bullet Extends objet
cible.vector2f
degat.i
timer.i
lanceur.i ; 0 = joueur, 1 = ennemi > ça évite qu'un tire ennemi ne blesse les autres ennemis, si besoin
distance.f
EndStructure
Structure ennemy Extends objet
IA_State.i
ReplacePos.vector2f
EndStructure
;********* ennemy et bullett***********
Global NewList ennemy.ennemy()
Global NewList bullet.bullet()
For i = 1 To #NB_ENNEMY+Random(5)
AddElement(ennemy())
With ennemy()
\position\x = Random( #ScreenW )
\position\y = Random( #ScreenH )
\IA_State = #IA_wait
\speed_base = 1+Random(2)
\level = 1+Random(4)
\vie_max = 20 + \level*10
\vie_courante = \vie_max
\classe = Random(3)
If \classe >0
\type = 1+Random(3)
ElseIf \classe =0
\type = Random(4)
EndIf
\temps_sort = 550 + 10*Random(10) - 5*\classe
EndWith
Next
;**************** joueur ************
Global Player.objet
Player\position\x = 150
Player\position\y = 150
Player\speed_base = 2+Random(2)
Player\level = 1
Player\vie_max = 50 + Player\level*10
Player\vie_courante = Player\vie_max
Player\temps_sort = 400 - 10*level
Player\xp = 0
;}
;{ ************************ Declaration ***********************
Declare gestion_souris()
Declare deplace_joueur()
Declare Tire_Player()
Declare Affichage()
;}
;{ ************************ initialisation ***********************
InitSprite() : InitMouse() : InitKeyboard()
;}
;{ ************************ openWindow ***********************
;OpenScreen(DesktopWidth(0), DesktopHeight(0), DesktopDepth(0),"")
OpenWindow(#window, 0, 0,#ScreenW, #ScreenH, "Collision" , #PB_Window_SystemMenu|#PB_Window_BorderLess |#PB_Window_ScreenCentered )
OpenWindowedScreen( WindowID (#window),0,0, #ScreenW,#ScreenH, 1, 0,0)
;}
;{ ************************ boucle ***********************
Repeat
Event= WindowEvent ()
ExamineMouse() : ExamineKeyboard()
gestion_souris()
;{ ***************************** ENNEMY ****************************************
If ListSize(ennemy()) <> 0
For i =0 To ListSize(ennemy())-1
If SelectElement(ennemy(), i)
;ForEach ennemy()
With ennemy()
; ---------------------------------------------------------------------
; Calcul de la direction
; ---------------------------------------------------------------------
If \timeToCalcTraj < ElapsedMilliseconds()
\timeToCalcTraj = ElapsedMilliseconds() + 75
If \IA_State = #FOLLOW_PLAYER
\Direction\x = Player\position\x - \position\x
\Direction\y = Player\position\y - \position\y
EndIf
If \IA_State = #REPLACE
\Direction\x = \ReplacePos\x - \position\x
\Direction\y = \ReplacePos\y - \position\y
EndIf
\Length = Sqr( \Direction\x*\Direction\x + \Direction\y*\Direction\y ) ; la distance entre 2 positions
If \Length>0
\Direction\x / \Length
\Direction\y / \Length
EndIf
;{ Collision avec autres ennemis
; ---------------------------------------------------------------------
; Vérification de collision avec d'autre ennemis
; ---------------------------------------------------------------------
*Element.ennemy = @ennemy()
FirstElement(@ennemy())
ForEach ennemy()
If @ennemy() <> *Element ; N'est pas lui même...
If *Element\IA_State = #FOLLOW_PLAYER
A.f = (*Element\position\x - ennemy()\position\x)*(*Element\position\x - ennemy()\position\x)
B.f = (*Element\position\y - ennemy()\position\y)*(*Element\position\y - ennemy()\position\y)
Dist.f = Sqr( A + B )
If Dist < 50 ; Approche de < 50 pixels un autre gus , on le replace sur l'écran
*Element\IA_State = #REPLACE
*Element\ReplacePos\x = *Element\position\x - Random(10) + Random(10)
*Element\ReplacePos\y = *Element\position\y - Random(10) + Random(10)
*Element\speed = *Element\speed_base
EndIf
EndIf
EndIf
Next
ChangeCurrentElement(ennemy(),*Element)
;}
;{ on test si le gus arrive à son point de raliment avant de repoursuivre le joueur
If \IA_State = #REPLACE
A.f = (\position\x - \ReplacePos\x)*(\position\x - \ReplacePos\x)
B.f = (\position\y - \ReplacePos\y)*(\position\y - \ReplacePos\y)
Dist.f = Sqr( A + B )
If Dist < 20
\IA_State = #IA_wait
\speed = \speed_base
EndIf
EndIf
If \IA_State = #IA_wait Or \IA_State = #FOLLOW_PLAYER
A.f = (\position\x - Player\position\x)*(\position\x - Player\position\x)
B.f = (\position\y - Player\position\y)*(\position\y - Player\position\y)
Dist.f = Sqr( A + B )
If Dist < 200 And (\type = 0 Or \vie_courante < \vie_max)
\IA_State = #FOLLOW_PLAYER
\speed = \speed_base
ElseIf Dist >450
\IA_State = #IA_wait
\speed=0
EndIf
EndIf
;}
; ---------------------------------------------------------------------
; Mise a jour de la vie et de la liste des ennemis
; ---------------------------------------------------------------------
If \vie_courante <1
DeleteElement(ennemy())
Continue
ResetList(ennemy())
EndIf
; ---------------------------------------------------------------------
; Mise a jour de la position
; ---------------------------------------------------------------------
\position\x + (\Direction\x * \speed)
\position\y + (\Direction\y * \speed)
; ---------------------------------------------------------------------
; Gestion du tir des ennemis
; ---------------------------------------------------------------------
If \Length < 400 And \timeToShoot < ElapsedMilliseconds() And \IA_State = #FOLLOW_PLAYER And \type = 0
\timeToShoot = ElapsedMilliseconds() + \temps_sort
AddElement(bullet())
bullet()\position\x = \position\x
bullet()\position\y = \position\y
bullet()\Direction\x = \Direction\x
bullet()\Direction\y = \Direction\y
bullet()\speed = 10
bullet()\degat = \level
bullet()\lanceur = 1
EndIf
EndIf
EndWith
EndIf
Next
EndIf
;}
;{ ***************************** BULETT ****************************************
ForEach bullet()
With bullet()
; ---------------------------------------------------------------------
; Mise a jour de la position
; ---------------------------------------------------------------------
\position\x + (\Direction\x * \speed)
\position\y + (\Direction\y * \speed)
; ---------------------------------------------------------------------
; Sortie de l'écran
; ---------------------------------------------------------------------
If \position\x < 0
DeleteElement(bullet())
Continue
EndIf
If \position\x > #ScreenW+8
DeleteElement(bullet())
Continue
EndIf
If \position\y < 0
DeleteElement(bullet())
Continue
EndIf
If \position\y > #ScreenH+8
DeleteElement(bullet())
Continue
EndIf
; ---------------------------------------------------------------------
; collision avec joueur ou ennemi
; ---------------------------------------------------------------------
If \lanceur = 1
If \position\x > PLayer\position\x-8 And \position\y > PLayer\position\y-8 And \position\x < PLayer\position\x + 8 And \position\y < PLayer\position\y + 8
PLayer\vie_courante - \degat
DeleteElement(bullet())
Continue
EndIf
EndIf
If \lanceur=0
If ListSize(ennemy()) <> 0 And ListSize(bullet()) <> 0
For i =0 To ListSize(ennemy())-1
If SelectElement(ennemy(), i)
If \position\x > ennemy()\position\x -8 And \position\y > ennemy()\position\y-8 And \position\x < ennemy()\position\x + 8 And \position\y < ennemy()\position\y + 8
ennemy()\vie_courante - \degat
Player\xp + 1 + 1*ennemy()\level
DeleteElement(bullet(),1)
EndIf
EndIf
ChangeCurrentElement(ennemy(),i)
Next
EndIf
EndIf
EndWith
Next
;}
;{ ***************************** PLAYER ****************************************
deplace_joueur()
Tire_Player()
;}
;{ ***************************** Affichage *************************************
Affichage()
;}
FlipBuffers()
ClearScreen(RGB(64,128,255))
ElapsedMilliseconds()
Until Event= #PB_Event_CloseWindow Or KeyboardPushed ( #PB_Key_Escape )
; CloseScreen()
;
; End
;}
;{---------------------------- procedures Generales ----------------------------
Procedure gestion_souris()
mx = WindowMouseX(#window):my = WindowMouseY(#window)
If inscreen = 1
If mx> #ScreenW-2 Or my> #ScreenH-2 Or mx<1 Or my<1
inscreen = 0
ReleaseMouse(1)
EndIf
ElseIf mx <#ScreenW-1 And my < #ScreenH-1 And mx > 0 And my > 0
ReleaseMouse(0)
MouseLocate(mx,my)
inscreen = 1
EndIf
EndProcedure
;}
;{---------------------------- procedure joueur ----------------------------
Procedure deplace_joueur()
If KeyboardPushed(#PB_Key_Left)
Player\position\x - Player\speed_base
EndIf
If KeyboardPushed(#PB_Key_Right)
Player\position\x + Player\speed_base
EndIf
If KeyboardPushed(#PB_Key_Up)
Player\position\y - Player\speed_base
EndIf
If KeyboardPushed(#PB_Key_Down)
Player\position\y + Player\speed_base
EndIf
EndProcedure
Procedure Tire_Player()
If MouseButton(#PB_MouseButton_Left)
If Player\timeToShoot < ElapsedMilliseconds()
Player\timeToShoot = ElapsedMilliseconds() + Player\temps_sort
AddElement(bullet())
bullet()\lanceur = 0
bullet()\position\x = Player\position\x
bullet()\position\y = Player\position\y
bullet()\Direction\x = MouseX() - bullet()\position\x
bullet()\Direction\y = MouseY() - bullet()\position\y
bullet()\distance = Sqr( bullet()\direction\x * bullet()\direction\x + bullet()\direction\y * bullet()\direction\y )
bullet()\direction\x = bullet()\direction\x / bullet()\distance
bullet()\direction\y = bullet()\direction\y / bullet()\distance
bullet()\speed = 3
bullet()\degat = 2+2*Player\level
EndIf
EndIf
EndProcedure
;}
;{---------------------------- procedure Affichage ----------------------------
Procedure Affichage()
StartDrawing(WindowOutput(#window))
DrawingMode(#PB_2DDrawing_Transparent)
;---------------- personnage et bullet ------------------
Circle(Player\position\x , Player\position\y,8,RGB(255,128,64))
DrawText(Player\position\x , Player\position\y,Str(Player\vie_courante)+"/"+Str(Player\vie_max))
ForEach ennemy()
Circle(ennemy()\position\x , ennemy()\position\y,8,$FF)
DrawText(ennemy()\position\x , ennemy()\position\y,Str(ennemy()\vie_courante)+"/"+Str(ennemy()\vie_max))
Next
ForEach bullet()
Circle(bullet()\position\x , bullet()\position\y,4,$00FFFF)
Next
;------------------- interface ------------------------
Box(10, 10, 180, 30 ,RGB(125,125,125))
DrawText(20,18,"Niveau : " +Str(PLayer\level+Round(Player\xp/100,0))+" ("+Str(Player\xp)+"/"+Str(Player\level*100)+")")
StopDrawing()
EndProcedure
;}
;}
Hope que la 4.6 kill aussi
elle sort quand ?
