Jeu de type infiltration

Programmation avancée de jeux en PureBasic
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Jeu de type infiltration

Message par Dr. Dri »

Les derniers jeux postés sur le forum n'ont pas trop plu apparament (pas tous hein =) et ça m'a motivé pour commencer un ptit truc en 2D ^^

Je m'inspire pas mal de metal gear solid et de mes anciens codes DB sur les champs de vision et j'en suis encore au tout début... (élaboration du moteur)

Pour les graphismes je chercherai un moyen sans tout repomper mais en attendant merci RPG Maker...
Y me manque un ou deux trucs avant d'avoir une démo potable :oops: mais j'ai déjà codé les routines de champ de vision

Dri
Avatar de l’utilisateur
venom
Messages : 3128
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Message par venom »

Je m'inspire pas mal de metal gear solid
:wink: tres bonne inspiration j'adore metal gear je sait sa ne va pas t'avancer mais bon :wink: bonne continuation


@++
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

Tiens , je suis aussi en train d'en coder un en 3D.
Enfin je fais un truc tout simple , je lance un rayon en direction du joueur.
Si le rayon touche un mur , la recherche s'arrête et je considère que le joueur est caché derrière le mur , si le rayon atteint sa destination (le joueur) alors le joueur est visible .

Bon je fais simple dans un premier temps , avec un seul rayon , peut-être qu'il faudrait en lancer plusieurs selon l'angle de vision ? mais ça risque de devenir assez lent.

Comment tu fais toi ? C'est aussi des lancer de rayons ? ou une autre méthode ?
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

Mon systeme ne prend en compte que deux dimensions mais on peut tres bien lui appliquer un rendu 3D ^^
Voila de quel code j'ai démarré, c'est un de mes codes DarkBasic que j'ai codé pour faire du raycasting ^_^

Code : Tout sélectionner

InitSprite()
InitKeyboard()

OpenWindow(0, 0, 0, 800, 600, #PB_Window_SystemMenu|#PB_Window_TitleBar|#PB_Window_ScreenCentered, "DarkBasic rules ??")
OpenWindowedScreen(WindowID(), 0, 0, 800, 600, 0, 0, 0)

Declare fov(camera_x, camera_z, camera_a, camera_fov)
Global screen_w, screen_h, wall_w, wall_h, wall_d, maze_w, maze_d, column_a.f

screen_w = 320
screen_h = 240

wall_w =  64/2
wall_h = 256
wall_d =  64/2

maze_w = 7
maze_d = 5
Dim maze(maze_w-1, maze_d-1)

camera_x = 78
camera_y = wall_h/2
camera_z = 171/2
camera_a = 25
camera_fov = 60 ;field of view/champ de vision
camera_speed = 5

Dim grid_x(screen_w - 1)
Dim grid_z(screen_w - 1)
Dim distance.f(screen_w - 1)
column_a.f = (camera_fov + 0.0) / screen_w
distance.f = screen_w / (2 * Tan(0.01745329*camera_fov/2))

Restore maze
For z=1 To maze_d
  For x=1 To maze_w
    Read maze(x-1, z-1)
  Next x
Next z

;screen = 0
;buffer = 1
;create bitmap buffer, screen_w, screen_h*2

;**********************************************************************************************

Repeat
  ClearScreen(0, 0, 0)
  ExamineKeyboard()

  old_x = camera_x
  old_z = camera_z
  
  h_dir = 0
  If KeyboardPushed(#PB_Key_Right) : h_dir + 1 : EndIf
  If KeyboardPushed(#PB_Key_Left ) : h_dir - 1 : EndIf
  v_dir = 0
  If KeyboardPushed(#PB_Key_Up   ) : v_dir + 1 : EndIf
  If KeyboardPushed(#PB_Key_Down ) : v_dir - 1 : EndIf
  
  h_dir * camera_speed
  v_dir * camera_speed

  camera_x + v_dir * Cos(0.01745329*camera_a)
  camera_z + v_dir * Sin(0.01745329*camera_a)
  camera_a + h_dir
  
  mx = camera_x/wall_w
  mz = camera_z/wall_d
  
  If mx<0 Or mx>=maze_w Or mz<0 Or mz>=maze_d
    camera_x = old_x
    camera_z = old_z
  EndIf
  
  mx = camera_x/wall_w
  mz = camera_z/wall_d

  If maze(mx, mz)=1
    camera_x = old_x
    camera_z = old_z
  EndIf
  
  If StartDrawing( ScreenOutput() )
    fov(camera_x, camera_z, camera_a, camera_fov)
  
    FrontColor(0, 0, 255)
    Locate(240,  0) : DrawText("x : " + Str(camera_x) + " px")
    Locate(240, 16) : DrawText("z : " + Str(camera_z) + " pz")
    Locate(240, 32) : DrawText("angle : " + Str(camera_a) + "°")
    
    StopDrawing()
  EndIf
  
  FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)

;**********************************************************************************************

Procedure.f min(a.f, b.f)
  If b < a : a = b : EndIf
  ProcedureReturn a
EndProcedure

Procedure.f max(a.f, b.f)
  If b > a : a = b : EndIf
  ProcedureReturn a
EndProcedure

Procedure.f WrapValue(Angle.f)
  Angle - Int(Angle / 360) * 360
  If Angle < 0
    Angle + 360
  EndIf
  ProcedureReturn Angle
EndProcedure

Procedure draw_maze(mw, md, ww, wd)
  
  Box(0, 0, mw*ww, md*wd, $FFFFFF)
  
  For z=0 To md-1
    For x=0 To mw-1

      Box(x*ww+1, z*wd+1, ww-2, wd-2, maze(x, z)*$00FFFF)

    Next x
  Next z

EndProcedure

Procedure fov(camera_x, camera_z, camera_a, camera_fov)
  draw_maze(maze_w, maze_d, wall_w, wall_d)
  
  alpha.f = wrapvalue(camera_a - camera_fov / 2)

  For x=0 To screen_w-1

    ;initialisation
    tan_alpha.f = 0
    v_distance.f = 0
    h_distance.f = 0

    ;Recherche verticale
    If Sin(0.01745329*alpha) <> 0
      If alpha<180
        If alpha <>  90 : tan_alpha = Tan(0.01745329*alpha) : EndIf
        v_dz = wall_d
        v_grid_z = camera_z / wall_d * wall_d + wall_d + 1
      Else
        If alpha <> 270 : tan_alpha = Tan(0.01745329*alpha) : EndIf
        v_dz = 0-wall_d
        v_grid_z = camera_z / wall_d * wall_d - 1
      EndIf
      If tan_alpha = 0
        v_dx = 0
        v_grid_x = camera_x
      Else
        v_dx = v_dz / tan_alpha
        v_grid_x = camera_x + (v_grid_z - camera_z) / tan_alpha
      EndIf
      gx = v_grid_x / wall_w
      gz = v_grid_z / wall_d
      If gx>=0 And gx<maze_w And gz>=0 And gz<maze_d
        If maze(gx, gz) = 0
          Repeat
            v_grid_x + v_dx
            v_grid_z + v_dz
            gx = v_grid_x / wall_w
            gz = v_grid_z / wall_d
            If gx<0 Or gx>=maze_w Or gz<0 Or gz>=maze_d : Break : EndIf
            If maze(gx, gz) : v_distance = Sqr((camera_x - v_grid_x)*(camera_x - v_grid_x) + (camera_z - v_grid_z)*(camera_z - v_grid_z)) : EndIf
          Until v_distance <> 0
        Else
          v_distance = Sqr((camera_x - v_grid_x)*(camera_x - v_grid_x) + (camera_z - v_grid_z)*(camera_z - v_grid_z))
        EndIf
      EndIf
    EndIf

    ;Recherche horizontale
    If tan_alpha <> 0 Or Sin(0.01745329*alpha) = 0
      If alpha>=90 And alpha<270
        h_dx = 0-wall_w
        h_grid_x = camera_x / wall_w * wall_w - 1
      Else
        h_dx = wall_w
        h_grid_x = camera_x / wall_w * wall_w + wall_w + 1
      EndIf
      h_dz = h_dx * tan_alpha
      h_grid_z = camera_z + (h_grid_x - camera_x) * tan_alpha
      gx = h_grid_x / wall_w
      gz = h_grid_z / wall_d
      If gx>=0 And gx<maze_w And gz>=0 And gz<maze_d
        If maze(gx, gz) = 0
          Repeat
            h_grid_x + h_dx
            h_grid_z + h_dz
            gx = h_grid_x / wall_w
            gz = h_grid_z / wall_d
            If gx<0 Or gx>=maze_w Or gz<0 Or gz>=maze_d : Break : EndIf
            If maze(gx, gz) : h_distance = Sqr((camera_x - h_grid_x)*(camera_x - h_grid_x) + (camera_z - h_grid_z)*(camera_z - h_grid_z)) : EndIf
          Until h_distance <> 0
        Else
          h_distance = Sqr((camera_x - h_grid_x)*(camera_x - h_grid_x) + (camera_z - h_grid_z)*(camera_z - h_grid_z))
        EndIf
      EndIf
    EndIf

    alpha = wrapvalue(alpha + column_a)

    If v_distance <> 0 And h_distance <> 0
      distance(x) = min(v_distance, h_distance)
    Else
      distance(x) = max(v_distance, h_distance)
    EndIf
    If distance(x) = v_distance
      grid_x(x) = v_grid_x
      grid_z(x) = v_grid_z
    Else
      grid_x(x) = h_grid_x
      grid_z(x) = h_grid_z
    EndIf

;**********************************log**********************************
If x > 0
  LineXY(camera_x, camera_z, grid_x(x), grid_z(x), $0000FF)
EndIf
;**********************************log**********************************
  
  Next x
EndProcedure

DataSection
  maze:
  Data.l 1,1,1,1,1,1,1
  Data.l 1,0,0,0,0,0,1
  Data.l 1,0,0,0,1,0,1
  Data.l 1,0,0,0,0,0,1
  Data.l 1,1,1,0,1,1,1
EndDataSection
Je reprend ce principe en y ajoutant la possibilité d'une portée limitée (comme dans metal gear solid =)
La différence c'est qu'au lieu de me servir des rayons, je me sers du contour du champ de vision, ca me permet de savoir tres facilement si aux coordonées X, Z on se trouve dans le champ de vision sous windows

Code : Tout sélectionner

CreatePolygonRgn_()
PtInRegion_()
une petite démo technique ici :
vu.exe
Image


Dri ^^
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

sympa la démo :)

Je vais rester sur mon lancer de rayon , j'en mettrai peut-être 3 , 1 à chaque extrémité du champ de vision , et 1 au centre .
Par contre maintenant il faut que je gère un octree pour sélectionner les triangles , sinon ça risque de ralentir grave si je m'amuse à tester tous les triangles d'une scène :)

Et toi ? tu envisages un quadtree pour ta scène 2D ? :)
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

octree, quadtree, ca donne quoi dans la langue de molière ?
J'ai cru comprendre que tu me parles d'arbres mais ca m'avance à rien :lol:

Dri
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

pour moi aussi c'est du chinois :)

Mais je sais qu'il serait temps que je mette à bosser le sujet .C'est utile pour beaucoup de choses.C'est toujours bon d'apprendre à le maitriser , je vais commencer par un quadtree pour mon éditeur de map.

ici un exemple concret :

http://www-igm.univ-mlv.fr/~biri/Enseig ... TR/TD1.htm
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

J'ai pas tout compris mais je garde ce lien au cas où ^^
Ma scène 2D gagnerait quoi à utiliser un quadtree ?? Parce qu'en fait j'ai pas compris le but même des quadtree :-?

[edit]
comme je passe par les fonction de l'api windows, et que je récupère le handle de ma "region", il est probable que windows fasse ca tout seul comme un grand... Enfin là les 4 coins de chaque case + le centre de la case sont testés pour savoir s'ils appartiennent au champ de vision découpé en 60 segments et c'est tout de même très rapide... Là c'est une démo sans graphisme, j'en ai une autre avec des sprite3D et une tilemap et ca ne rame pas non plus sur mon vieux PC. En plus le programme est fenêtré donc en plein écran ca devrait encore gagner en performances...

Dri
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

moi je vois bien à quoi ça peut me servir , mais je n'en ai jamais fait :)
Dès que j'ai codé un truc concret , je file le source.

Image

tu vois bien sur cette image que ça permet de sélectionner les segments à tester , dans ton cas c'est peut-être inutile parce que tu n'as pas beaucoup d'éléments à tester, mais dans un monde 3D composé de milliers de triangles , ça devient vite intéressant de sélectionner ceux qui sont susceptibles de croiser le chemin du rayon , et seulement ceux là.
Donc dans un premier temps , tu ne testes pas les triangles , mais les cases , et si ton rayon se trouve dans un noeud de ton arbre tu testes les triangles rattachés à ce noeud , et ainsi de suite.
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

Je vois, je n'ai pas besoin de faire tout ca moi...
Je me contente de la position x z pour savoir si c'est visible ou pas ^^

Dri
lionel_om
Messages : 1500
Inscription : jeu. 25/mars/2004 11:23
Localisation : Sophia Antipolis (Nice)
Contact :

Message par lionel_om »

Super Dri !!! ^^
Par contre t'as modifié les ptt bugs que j'avais trouvé ? (je t'avais renvoyé d'autres images par mails...)
Webmestre de Basic-univers
Participez à son extension: ajouter vos programmes et partagez vos codes !
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

Nan ils n'ont pas été modifiés :-?
Mais du coup tu m'as fait penser à une solution pour régler ca

Dri ^^
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

C'est super Dr Dri, je t'encourage... :twisted:
Image
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

oui c'est super bien fait :)

Dri tu m'as donné une idée pour tester un point dans un triangle, je vais essayer ton truc

Code : Tout sélectionner

CreatePolygonRgn_()
PtInRegion_()
il faudra que je fasse une projection pour travailler en 2D , mais c'est peut-être plus rapide que ma méthode ? je ferai des tests cette semaine.
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

@comtois
en théorie pas besoin de projection 2D... sauf si ton champ de vision est 3D... De mon côté je travaille sur x, z dans un monde x, y, z (c'est pas encore fait mais par exemple le personnage peut ramper sous certains décors et c'est là qu'intervient le "y" =)

sinon merci pour les encouragements ^^ J'essaye de faire une démo avec le personnage qu'on contrôle mais bon j'ai quelques problemes du côté des graphismes... Comme personnage capable de se tourner dans 8 directions je n'ai trouvé que mario (super mario rpg)

Faudra imaginer que c'est solid snake XD

Dri ;)
Répondre