Requirements : Windows 7 / XP ( 86 ), PureBasic 5.30
Dungeon raider (game demo)
Re: Dungeon raider (game demo)
dige
			
			
									
									'Happiness for everybody, free, and no one will go away unsatisfied!'
SMsF town: http://www.youtube.com/watch?v=g6RRKYf_Pd0
SMf locations module (Ogre). Game video: http://www.youtube.com/watch?v=ZlhBgPJhAxI
						SMsF town: http://www.youtube.com/watch?v=g6RRKYf_Pd0
SMf locations module (Ogre). Game video: http://www.youtube.com/watch?v=ZlhBgPJhAxI
Re: Dungeon raider (game demo)
@dige
I was able to run it on Windows 8.1 x64 without problems. Maybe it's a graphic card issue.
			
			
									
									I was able to run it on Windows 8.1 x64 without problems. Maybe it's a graphic card issue.
If any of you native English speakers have any suggestions for the above text, please let me know (via PM). Thanks!
						Re: Dungeon raider (game demo)
Did you install DirectX9 ?
			
			
									
									
						Re: Dungeon raider (game demo)
I already had this kind of crash. The code can be compiled with OpenGL. Probably a problem with shadows.
			
			
									
									➽ Windows 11 64-bit - PB 6.21 x64 - AMD Ryzen 7 - NVIDIA GeForce GTX 1650 Ti
Sorry for my bad english and the Dunning–Kruger effect
Re: Dungeon raider (game demo)
Yes, some people complained that on 8 does not work .
The code is compiled on DirectX . Shadows are modulative.
			
			
									
									The code is compiled on DirectX . Shadows are modulative.
'Happiness for everybody, free, and no one will go away unsatisfied!'
SMsF town: http://www.youtube.com/watch?v=g6RRKYf_Pd0
SMf locations module (Ogre). Game video: http://www.youtube.com/watch?v=ZlhBgPJhAxI
						SMsF town: http://www.youtube.com/watch?v=g6RRKYf_Pd0
SMf locations module (Ogre). Game video: http://www.youtube.com/watch?v=ZlhBgPJhAxI
- Fangbeast
 - PureBasic Protozoa

 - Posts: 4792
 - Joined: Fri Apr 25, 2003 3:08 pm
 - Location: Not Sydney!!! (Bad water, no goats)
 
Re: Dungeon raider (game demo)
I ran it here under 8.1 x64. Must have been the compiled version though as I am still on pb 5.22x86
			
			
									
									Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
						Re: Dungeon raider (game demo)
Guys, if anyone had a working code for search path, as A* Pathfinding, but for 3D space.
I want, no I need to add a moving enemies with AI .
			
			
									
									I want, no I need to add a moving enemies with AI .
'Happiness for everybody, free, and no one will go away unsatisfied!'
SMsF town: http://www.youtube.com/watch?v=g6RRKYf_Pd0
SMf locations module (Ogre). Game video: http://www.youtube.com/watch?v=ZlhBgPJhAxI
						SMsF town: http://www.youtube.com/watch?v=g6RRKYf_Pd0
SMf locations module (Ogre). Game video: http://www.youtube.com/watch?v=ZlhBgPJhAxI
Re: Dungeon raider (game demo)
There are already a couple of examples floating around in the forum.AndyLy wrote:Guys, if anyone had a working code for search path, as A* Pathfinding, but for 3D space.
I want, no I need to add a moving enemies with AI .
It should be easy to add an extra dimension to one of those examples.
Current configurations: 
Ubuntu 20.04/64 bit - Window 10 64 bit
Intel 6800K, GeForce Gtx 1060, 32 gb ram.
Amd Ryzen 9 5950X, GeForce 3070, 128 gb ram.
						Ubuntu 20.04/64 bit - Window 10 64 bit
Intel 6800K, GeForce Gtx 1060, 32 gb ram.
Amd Ryzen 9 5950X, GeForce 3070, 128 gb ram.
Re: Dungeon raider (game demo)
DK_PETER
Do you mean that there is no working code ?
I don't know mathematics, and for me the problem is to add to the equation another dimension.
			
			
									
									Do you mean that there is no working code ?
I don't know mathematics, and for me the problem is to add to the equation another dimension.
'Happiness for everybody, free, and no one will go away unsatisfied!'
SMsF town: http://www.youtube.com/watch?v=g6RRKYf_Pd0
SMf locations module (Ogre). Game video: http://www.youtube.com/watch?v=ZlhBgPJhAxI
						SMsF town: http://www.youtube.com/watch?v=g6RRKYf_Pd0
SMf locations module (Ogre). Game video: http://www.youtube.com/watch?v=ZlhBgPJhAxI
Re: Dungeon raider (game demo)
No..there is nothing specific in 3D, when it comes to pathfinding and AI.AndyLy wrote:DK_PETER
Do you mean that there is no working code ?
I don't know mathematics, and for me the problem is to add to the equation another dimension.
But as I said: It should be easy to add the extra dimension (perspective).
I believe, that user 'Fig' made a nice path finding example, and Heathen did one too.
But pathfinding is only a minor hurdle. The real deal is AI.
Here's Heathen's pathfinding (2D). It works for PB 5.30 too.
Pathfind.pb
Code: Select all
Code:
;Written by Heathen
Structure pathfinding_structure ;Main Options
  Width.l          ; Width of the grid (cells, not pixels)
  Height.l         ; Height of the grid (cells, not pixels)
  tilesize.w       ;Size of the cells (tiles) in pixels. For now, this applies to everything.
  allowdiag.c      ;Can move diagonally?
  blockdiag.c      ;Can move diagonally between blocked squares?
  blocked.l        ;pointer to a 2d array (width-1,height-1). 1 = blocked, 0 = free
  Priority.l       ;pointer to a 2d array (width-1,height-1). 0-100. 0 = normal/low priority, 100 = high priority
  cast_ray.c       ;try to cast a ray before pathfinding? Please use with caution as this needs more work
  dynamic.l        ;pointer to a 1d array of structure pointers (which contain x and y coordinates). This is for dynamic pathfinding and is optional.
  dynamic_size.w   ;size of the array structure. (Can use sizeof(structure))
  xoff.w           ;offset in the structure of the x coordinate (in pixels). (Can use offsetof(structure/x))
  yoff.w           ;offset in the structure of the y coordinate (in pixels). (Can use offsetof(structure/y)))
  xto_off.w        ;offset to the next x coordinate (in cells). -The square the object will move to next-. (not necessary but can lead to less problems and will usuall be faster/more precise.)
  yto_off.w        ;offset to the next y coordinate (in cells). -The square the object will move to next-. (not necessary but can lead to less problems and will usually be faster/more precise.)
  dynamic_count.w  ;number of items in the array. (Doesn't have to be the size of the whole array, just the size you are using)
  ignore.l         ;Dynamic array index to ignore.  Can use 'ignore_ovverride' arguments in the procedures to override this with a new index.
  cost.w           ;cost to move horizontally and vertically (optional default 10)
  diagcost.w       ;cost to move diagonally (option default 14)
  alt_copymemory.c
EndStructure
;{ Internal
Structure openlist
  x.l
  y.l
  f.l
EndStructure
strucsize_.c  = SizeOf(openlist)
Procedure CopyMemoryAMD(*src, *dst, Size)
  CopyMemory(*src,*dst, Size)
EndProcedure
Macro check(xx,yy,gg=cost)
  If xx > -1 And yy > -1 And xx < Width And yy < Height And open(xx,yy) > -1
    g = gg+g(x,y)
    p = array_2d(Priority,Width,xx,yy)
    If p > 0
      g/(100/p)
    EndIf
    If (open(xx,yy) = 0 Or g < g(xx,yy))
      xd = xend-xx
      yd = yend-yy
      If xd < 0 : xd = -xd : EndIf
      If yd < 0 : yd = -yd : EndIf
      g(xx,yy) = g
      parentx(xx,yy) = x
      parenty(xx,yy) = y
      If open(xx,yy) > 0
        openlist(open(xx,yy))\f = xd+yd + g(xx,yy)
        pos = open(xx,yy)
      Else
        oc + 1
        If oc/50 >= oa
          oa+1
          ReDim openlist.openlist(oa*50)
        EndIf
        openlist(oc)\x = xx
        openlist(oc)\y = yy
        openlist(oc)\f = xd+yd + g(xx,yy)
        open(xx,yy) = oc
        pos = oc
      EndIf
      a = pos >> 1
      While pos > 1 And openlist(pos)\f < openlist(a)\f
        open(openlist(pos)\x,openlist(pos)\y) = a
        open(openlist(a)\x,openlist(a)\y) = pos
        If Not alt_copymemory
          CopyMemory(@openlist(pos),*temp,strucsize_)
          CopyMemory(@openlist(a),@openlist(pos),strucsize_)
          CopyMemory(*temp,@openlist(a),strucsize_)
        Else
          CopyMemoryAMD(@openlist(pos),*temp,strucsize_)
          CopyMemoryAMD(@openlist(a),@openlist(pos),strucsize_)
          CopyMemoryAMD(*temp,@openlist(a),strucsize_)
        EndIf
        pos = a
        a = pos >> 1
      Wend
    EndIf
  EndIf
EndMacro
Procedure.c array_2d(pointer,Width,field1,field2,pointer2=0)
  If pointer > 0
    Protected c = PeekC(pointer+field1*Width+field2)
    If c = 0 And pointer2 > 0
      c = PeekC(pointer2+field1*Width+field2)
    EndIf
    ProcedureReturn c
  EndIf
  ProcedureReturn 0
EndProcedure
Procedure ray(x,y,xto,yto,blocked,Width,diag,dyn=0)
  Protected xd,yd,a.w,b.w,d
  *mem = AllocateMemory(8)
  b = 0
  Repeat
    If array_2d(blocked,Width,x,y,dyn) = 1
      FreeMemory(*mem)
      ProcedureReturn 0
    Else
      PokeL(*mem+b*8,x)
      PokeL(*mem+b*8+4,y)
      b + 1
      xd = xto-x
      yd = yto-y
      If xd < 0 : xd = -xd : EndIf
      If yd < 0 : yd = -yd : EndIf
      d = xd+yd
      *mem = ReAllocateMemory(*mem,(b+1)*8)
    EndIf
    a = 0
    If xto > x : x + 1 : a = 1
    ElseIf xto < x : x - 1 : a = 1
    EndIf
    If a = 0 Or diag = 1
      If yto > y : y + 1
      ElseIf yto < y : y - 1
      EndIf
    EndIf
    If x = xto And y = yto
      ReAllocateMemory(*mem,b*8)
      ProcedureReturn *mem
    EndIf
  ForEver
EndProcedure
Macro get_ops()
  Width.l = *pathfinding_structure\Width
  Height.l = *pathfinding_structure\Height
  allowdiag.c = *pathfinding_structure\allowdiag
  blockdiag.c = *pathfinding_structure\blockdiag
  blocked.l = *pathfinding_structure\blocked
  Priority.l = *pathfinding_structure\Priority
  cast_ray.l = *pathfinding_structure\cast_ray
  dynamic.l  = *pathfinding_structure\dynamic
  dynamic_size.w = *pathfinding_structure\dynamic_size
  xoff.w = *pathfinding_structure\xoff
  yoff.w = *pathfinding_structure\yoff
  xto_off.w = *pathfinding_structure\xto_off
  yto_off.w = *pathfinding_structure\yto_off
  dynamic_count.w = *pathfinding_structure\dynamic_count
  ignore.l = *pathfinding_structure\ignore
  tilesize.w = *pathfinding_structure\tilesize
  cost.w = *pathfinding_structure\cost
  diagcost.w = *pathfinding_structure\diagcost
  alt_copymemory.c = *pathfinding_structure\alt_copymemory
  If cost = 0
    cost = 10
  EndIf
  If diagcost = 0
    diagcost = 14
  EndIf
  If ignore_override > 0
    ignore = ignore_override
  EndIf
EndMacro
;}
Procedure.l get_path(xstart,ystart,xend,yend,*pathfinding_structure.pathfinding_structure,ignore_override.l=0)
  get_ops()
  If (xstart = xend And yend = ystart) Or Width < 1 Or Height < 1
    ProcedureReturn 0
  EndIf
  Protected x,y,g,xx,yy,xd,yd,oc,pos,a,oa.w=1,b1.c,b2.c,b3.c,b4.c,d.c=0
  If dynamic > 0 And dynamic_size > 0 And dynamic_count > 0
    Dim dynamic.c(Width-1,Height-1)
    Protected dyn = @dynamic()
    For x = 0 To dynamic_count-1
      If x <> ignore
        xx = PeekL(dynamic+x*dynamic_size+xoff)/tilesize
        yy = PeekL(dynamic+x*dynamic_size+yoff)/tilesize
        dynamic(xx,yy) = 1
        If xto_off > 0 And yto_off > 0 And dynamic(xx,yy) = 0
          xx = PeekL(dynamic+x*dynamic_size+xto_off)
          yy = PeekL(dynamic+x*dynamic_size+yto_off)
          dynamic(xx,yy) = 1
        EndIf
      EndIf
    Next x
  EndIf
  If cast_ray = 1
    Protected r
    r = ray(xend,yend,xstart,ystart,blocked,Width,allowdiag,dyn)
    If r > 0
      Debug "ray"
      ProcedureReturn r
    EndIf
  EndIf
  Shared strucsize_
  Protected Dim openlist.openlist(50)
  Protected Dim g.l(Width-1,Height-1)
  Protected Dim open.l(Width-1,Height-1)
  Protected Dim parentx.l(Width-1,Height-1)
  Protected Dim parenty.l(Width-1,Height-1)
  Protected *temp = AllocateMemory(strucsize_)
  x = xstart : y = ystart : open(x,y) = -1
  Repeat
    If x-1 >=0 : b1 = array_2d(blocked,Width,x-1,y,dyn) : Else :  b1=0 : EndIf
    If x+1 < Width : b2 = array_2d(blocked,Width,x+1,y,dyn) : Else : b2=0 : EndIf
    If y-1 >= 0 : b3 = array_2d(blocked,Width,x,y-1,dyn) : Else :  b3=0 : EndIf
    If y+1 < Height : b4 = array_2d(blocked,Width,x,y+1,dyn) : Else :  b4=0 : EndIf
    If allowdiag
      If array_2d(blocked,Width,x+1,y-1,dyn)=0 And (blockdiag = 0 Or (blockdiag=1 And (b2 = 0 Or b3=0)))
        check(x+1,y-1,diagcost)
      EndIf
      If array_2d(blocked,Width,x-1,y+1,dyn)=0 And (blockdiag = 0 Or (blockdiag=1 And (b1= 0 Or b4=0)))
        check(x-1,y+1,diagcost)
      EndIf
      If array_2d(blocked,Width,x-1,y-1,dyn)=0 And (blockdiag = 0 Or (blockdiag=1 And (b1 = 0 Or  b3=0)))
        check(x-1,y-1,diagcost)
      EndIf
      If array_2d(blocked,Width,x+1,y+1,dyn)=0 And (blockdiag = 0 Or (blockdiag=1 And (b2 = 0 Or b4=0)))
        check(x+1,y+1,diagcost)
      EndIf
    EndIf
    If b1 = 0 : check(x-1,y) : EndIf
    If b2 = 0 : check(x+1,y) : EndIf
    If b3 = 0 : check(x,y-1) : EndIf
    If b4 = 0 : check(x,y+1) : EndIf
    If oc = 0
      FreeMemory(*temp)
      ProcedureReturn 0
    EndIf
    x = openlist(1)\x
    y = openlist(1)\y
    open(x,y) = -1
    open(openlist(oc)\x,openlist(oc)\y) = 1
    If Not alt_copymemory
      CopyMemory(@openlist(oc),@openlist(1),strucsize_)
    Else
      CopyMemoryAMD(@openlist(oc),@openlist(1),strucsize_)
    EndIf
    oc-1
    If oc > 1
      pos = 1
      Repeat
        a = pos << 1
        c = 0
        If a <= oc And openlist(pos)\f >= openlist(a)\f
          c = 1
        EndIf
        If a+1 <= oc And openlist(pos)\f >= openlist(a+1)\f And (c = 0 Or (c = 1 And openlist(a+1)\f < openlist(a)\f))
          a + 1
          c = 1
        EndIf
        If c = 1
          open(openlist(pos)\x,openlist(pos)\y) = a
          open(openlist(a)\x,openlist(a)\y) = pos
          If Not alt_copymemory
            CopyMemory(@openlist(pos),*temp,strucsize_)
            CopyMemory(@openlist(a),@openlist(pos),strucsize_)
            CopyMemory(*temp,@openlist(a),strucsize_)
          Else
            CopyMemoryAMD(@openlist(pos),*temp,strucsize_)
            CopyMemoryAMD(@openlist(a),@openlist(pos),strucsize_)
            CopyMemoryAMD(*temp,@openlist(a),strucsize_)
          EndIf
          pos=a
        Else
          Break 1
        EndIf
      ForEver
    EndIf
  Until x = xend And y = yend
  pos = 0
  *mem = AllocateMemory(320)
  oa = 0
  Repeat
    PokeL(*mem+pos,x)
    PokeL(*mem+pos+4,y)
    xx = parentx(x,y)
    yy = parenty(x,y)
    x = xx
    y = yy
    pos + 8
    If (x <> xstart Or y <> ystart) And pos/320 > oa
      oa + 1
      *mem = ReAllocateMemory(*mem,(oa+1)*320)
    EndIf
  Until x = xstart And y = ystart
  ReAllocateMemory(*mem,pos)
  FreeMemory(*temp)
  ProcedureReturn *mem
EndProcedure
Procedure path_get_size(*path)
  If *path > 0
    ProcedureReturn MemorySize(*path)/8
  Else
    ProcedureReturn -1
  EndIf
EndProcedure
Procedure path_get_x(*path,ind)
  If *path > 0
    Protected s = MemorySize(*path)
    ind + 1
    If ((s-(ind*8))+4<=s Or ind = 0) And s > 0
      ProcedureReturn PeekW(*path+(s-(ind*8)))
    EndIf
  EndIf
  ProcedureReturn -1
EndProcedure
Procedure path_get_y(*path,ind)
  If *path > 0
    Protected s = MemorySize(*path)
    ind + 1
    If ((s-(ind*8))+8<=s Or ind = 0) And s > 0
      ProcedureReturn PeekW((*path+(s-(ind*8)))+4)
    EndIf
  EndIf
  ProcedureReturn -1
EndProcedure
;{ The following procedures are optional 'utility' procedures.
Procedure is_node_at(*path,x,y)
  If *path > 0
    s = path_get_size(*path)
    If s > 0
      For I = 0 To s-1
        If path_get_x(*path,I) = x And path_get_y(*path,I) = y
          ProcedureReturn 1
        EndIf
      Next I
    EndIf
  EndIf
  ProcedureReturn 0
EndProcedure
Procedure validate_path(*path,*pathfinding_structure.pathfinding_structure,ignore_override=0)
  If *path > 0
    get_ops()
    s = path_get_size(*path)
    If s > 0
      Protected dyn
      If dynamic > 0 And dynamic_size > 0 And dynamic_count > 0
        Dim dynamic.c(Width-1,Height-1)
        dyn = @dynamic()
        For x = 0 To dynamic_count-1
          If x <> ignore
            xx = PeekL(dynamic+x*dynamic_size+xoff)/tilesize
            yy = PeekL(dynamic+x*dynamic_size+yoff)/tilesize
            dynamic(xx,yy) = 1
            If xto_off > 0 And yto_off > 0 And dynamic(xx,yy) = 0
              xx = PeekL(dynamic+x*dynamic_size+xto_off)
              yy = PeekL(dynamic+x*dynamic_size+yto_off)
              dynamic(xx,yy) = 1
            EndIf
          EndIf
        Next x
      EndIf
      For I = 0 To s-1
        If array_2d(blocked,Width,path_get_x(*path,I),path_get_y(*path,I),dyn)
          ProcedureReturn 0
        EndIf
      Next I
      ProcedureReturn 1
    EndIf
  EndIf
  ProcedureReturn 0
EndProcedure
Procedure.w nearest_node(*path,x,y,distalgo=1)
  min = 2147483647
  sz = path_get_size(*path)
  If sz > 0
    For I = 0 To sz-1
      If distalgo = 1
        s = Sqr(Pow(path_get_x(*path,I)-x,2)+Pow(path_get_y(*path,I)-y,2))
      Else
        xd = path_get_x(*path,I)-x
        yd = path_get_y(*path,I)-y
        If xd < 0
          xd * -1
        EndIf
        If yd < 0
          yd * -1
        EndIf
        s = xd+yd
      EndIf
      If s < min
        min = s
        n = I
      EndIf
    Next I
    ProcedureReturn n
  Else
    ProcedureReturn -1
  EndIf
EndProcedure
Procedure.c save_path(*path,filename.s)
  If *path > 0
    s = MemorySize(*path)
    If s >= 8
      f=CreateFile(#PB_Any,filename)
      WriteData(f,*path,s)
      CloseFile(f)
      ProcedureReturn 1
    EndIf
  EndIf
  ProcedureReturn 0
EndProcedure
Procedure load_path(filename.s)
  sz = FileSize(filename)
  If sz >= 8
    *mem = AllocateMemory(sz)
    f=ReadFile(#PB_Any,filename)
    ReadData(f,*mem,sz)
    CloseFile(f)
    ProcedureReturn *mem
  EndIf
  ProcedureReturn 0
EndProcedure
Code: Select all
#tileSize = 40
XIncludeFile "pathfind.pb"
InitSprite()
InitMouse()
InitKeyboard()
#width = 120
#height = 120
#view_width = 120
#view_height = 120
Global Dim blocked.c(#width-1,#height-1)
Global Dim priority.c(#width-1,#height-1)
Structure monster
  x.l
  y.l
  X2.l
  Y2.l
  xto.l
  yto.l
  speed.c
  Path.l
  num.l
  pathsize.l
EndStructure
Structure player
  x.l
  y.l
  xto.l
  yto.l
  Path.l
EndStructure
Global Dim monster.monster(10)
monster(0)\x = 0
monster(0)\y = 1*#tileSize
monster(0)\speed = Random(5)+1
monster(1)\x = 0
monster(1)\y = 2*#tileSize
monster(1)\speed = Random(5)+1
monster(2)\x = 0
monster(2)\y = 3*#tileSize
monster(2)\speed = Random(5)+1
monster(3)\x = 0
monster(3)\y = 4*#tileSize
monster(3)\speed = Random(5)+1
blocked(1,1) = 1
blocked(1,2) = 1
blocked(1,3) = 1
blocked(1,4) = 1
blocked(1,5) = 1
blocked(1,6) = 1
blocked(8,10) = 1
blocked(12,10) = 1
blocked(12,9) = 1
blocked(11,9) = 1
blocked(10,8) = 1
blocked(10,12) = 1
monsters = 4
Global player.player
player\x = 10*#tileSize
player\y = 10*#tileSize
goto_counter = -1
pathfinding_structure.pathfinding_structure
pathfinding_structure\Width = #width
pathfinding_structure\Height = #height
pathfinding_structure\dynamic = @monster()
pathfinding_structure\dynamic_size = SizeOf(monster)
pathfinding_structure\dynamic_count = monsters
pathfinding_structure\xoff = OffsetOf(monster\x)
pathfinding_structure\yoff = OffsetOf(monster\y)
pathfinding_structure\xto_off = OffsetOf(monster\xto)
pathfinding_structure\yto_off = OffsetOf(monster\yto)
pathfinding_structure\tilesize = #tileSize
pathfinding_structure\blocked = @blocked()
pathfinding_structure\cast_ray = 1
pathfinding_structure\alt_copymemory = 0
Procedure elapsed()
  Static maxfreq.q
  Protected T.q
  If maxfreq=0
    QueryPerformanceFrequency_(@maxfreq)
    maxfreq=maxfreq/1000000
  EndIf
  QueryPerformanceCounter_(@T.q)
  ProcedureReturn T/maxfreq
EndProcedure
Procedure monster_at(x,y,num_monsters,ignore)
  For I = 0 To num_monsters-1
    If I <> ignore
      If monster(I)\x /#tileSize = x And monster(I)\y/#tileSize  = y
        ProcedureReturn I
      EndIf
    EndIf
  Next I
  ProcedureReturn -1
EndProcedure
Procedure goto_player(num_monsters,*pathfinding_structure.pathfinding_structure)
  Shared goto_counter
  Shared average_time_path
  goto_counter + 1
  If goto_counter > num_monsters - 1
    goto_counter = 0
  EndIf
  I = goto_counter
  If monster(I)\Path = 0
    xd = monster(I)\xto-player\x/#tileSize
    yd = monster(I)\yto-player\y/#tileSize
    If xd < 0 : xd * -1 : EndIf
    If yd < 0 : yd * -1 : EndIf
    If xd + yd > 1
      monster(I)\xto = monster(I)\x/#tileSize
      monster(I)\yto = monster(I)\y/#tileSize
      T = elapsed()
      monster(I)\Path = get_path(monster(I)\x/#tileSize,monster(I)\y/#tileSize,player\x/#tileSize,player\y/#tileSize,*pathfinding_structure,I)
      T = elapsed()-T
      If average_time_path > 0
        average_time_path = (T+average_time_path)/2
      Else
        average_time_path = T
      EndIf
      If monster(I)\Path > 0
        monster(I)\pathsize = path_get_size(monster(I)\Path)
        monster(I)\num = 0
        Debug "Got path"
      EndIf
    EndIf
  EndIf
EndProcedure
Procedure walk(num_monsters,*pathfinding_structure.pathfinding_structure)
  Shared average_time_validation
  Shared failed_validations
  For I = 0 To num_monsters-1
    If monster(I)\Path > 0
      m = monster_at(monster(I)\xto,monster(I)\yto,num_monsters,I)
      If m = -1
        m = monster_at(monster(I)\x / *pathfinding_structure\tilesize,monster(I)\y  /*pathfinding_structure\tilesize,num_monsters,I)
      EndIf
      If (monster(I)\x = monster(I)\xto*#tileSize And monster(I)\y = monster(I)\yto *#tileSize) Or m > -1
        If monster(I)\num < monster(I)\pathsize-1 Or m > -1
          If m = -1
            monster(I)\xto = path_get_x(monster(I)\Path,monster(I)\num)
            monster(I)\yto = path_get_y(monster(I)\Path,monster(I)\num)
            monster(I)\num + 1
            T = elapsed()
            v = validate_path(monster(I)\Path,*pathfinding_structure,I)
            T = elapsed()-T
            If average_time_validation > 0
              average_time_validation = (T+average_time_validation)/2
            Else
              average_time_validation = T
            EndIf
          EndIf
          If v = 0 Or m > 0
            failed_validations + 1
            xd = monster(I)\x/#tileSize-player\x/#tileSize
            yd = monster(I)\y/#tileSize-player\y/#tileSize
            If xd < 0 : xd * -1 : EndIf
            If yd < 0 : yd * -1 : EndIf
            If xd + yd > 1
              FreeMemory(monster(I)\Path)
              T = elapsed()
              monster(I)\Path = get_path(monster(I)\x/#tileSize,monster(I)\y/#tileSize,player\x/#tileSize,player\y/#tileSize,*pathfinding_structure,I)
              T = elapsed()-T
              If average_time_path > 0
                average_time_path = (T+average_time_path)/2
              Else
                average_time_path = T
              EndIf
              If monster(I)\Path > 0
                monster(I)\pathsize = path_get_size(monster(I)\Path)
                monster(I)\num = 0
                monster(I)\xto = path_get_x(monster(I)\Path,0)
                monster(I)\yto = path_get_y(monster(I)\Path,0)
              EndIf
            EndIf
          EndIf
        EndIf
      Else
        If monster(I)\x < monster(I)\xto*#tileSize And blocked((monster(I)\x+monster(I)\speed)/#tileSize,monster(I)\y/#tileSize) = 0
          monster(I)\x + monster(I)\speed
          If monster(I)\x > monster(I)\xto*#tileSize
            monster(I)\x = monster(I)\xto*#tileSize
          EndIf
          Continue
        ElseIf monster(I)\x > monster(I)\xto*#tileSize And blocked((monster(I)\x-monster(I)\speed)/#tileSize,monster(I)\y/#tileSize)=0
          monster(I)\x - monster(I)\speed
          If monster(I)\x < monster(I)\xto*#tileSize
            monster(I)\x = monster(I)\xto*#tileSize
          EndIf
          Continue
        EndIf
       
       
       
        If monster(I)\y < monster(I)\yto*#tileSize And blocked(monster(I)\x/#tileSize,(monster(I)\y+monster(I)\speed)/#tileSize)=0
          monster(I)\y + monster(I)\speed
          If monster(I)\y > monster(I)\yto*#tileSize
            monster(I)\y = monster(I)\yto*#tileSize
          EndIf
          Continue
        ElseIf monster(I)\y > monster(I)\yto*#tileSize And blocked(monster(I)\x/#tileSize,(monster(I)\y-monster(I)\speed)/#tileSize)=0
          monster(I)\y - monster(I)\speed
          If monster(I)\y < monster(I)\yto*#tileSize
            monster(I)\y = monster(I)\yto*#tileSize
          EndIf
          Continue
        EndIf
       
      EndIf
    EndIf
  Next I
EndProcedure
Procedure draw(num_monsters)
  Shared average_time_path
  Shared average_time_validation
  Shared failed_validations
  Shared FrameRate
  
  ClearScreen(#Black)
  StartDrawing(ScreenOutput())
 
  For I = 0 To num_monsters-1
    Box(monster(I)\x,monster(I)\y,#tileSize,#tileSize,#Green)
    DrawingMode(#PB_2DDrawing_Outlined)
    Box(monster(I)\x,monster(I)\y,#tileSize,#tileSize,#White)
    DrawingMode(#PB_2DDrawing_Default)
    If monster(I)\Path > 0
      xx = monster(I)\x
      yy = monster(I)\y
      For z = monster(I)\num To monster(I)\pathsize-1
        x = path_get_x(monster(I)\Path,z)*#tileSize
        y = path_get_y(monster(I)\Path,z)*#tileSize
        LineXY(xx+#tileSize/2,yy+#tileSize/2,x+#tileSize/2,y+#tileSize/2,#White)
        xx = x
        yy = y
      Next z
    EndIf
  Next I
 
  Box(player\x,player\y,#tileSize,#tileSize,#Blue)
  DrawingMode(#PB_2DDrawing_Outlined)
  Box(player\x,player\y,#tileSize,#tileSize,#White)
  DrawingMode(#PB_2DDrawing_Default)
  For x = 0 To #view_width-1
    For y = 0 To #view_height-1
      If blocked(x,y) = 1
        Box(x*#tileSize,y*#tileSize,#tileSize,#tileSize,#Red)
        DrawingMode(#PB_2DDrawing_Outlined)
        Box(x*#tileSize,y*#tileSize,#tileSize,#tileSize,#White)
        DrawingMode(#PB_2DDrawing_Default)
      EndIf
    Next y
  Next x
  DrawingMode(#PB_2DDrawing_Transparent)
  DrawText(45,5," AVG path generation time: "+StrF(average_time_path/1000,3)+"ms",#White,#Black)
  DrawText(45,5+TextHeight("P")," AVG path validation time: "+StrF(average_time_validation/1000,3)+"ms",#White,#Black)
  DrawText(45,5+TextHeight("P")*2," Failed validations: "+Str(failed_validations),#White,#Black)
  DrawText(45,5+TextHeight("P")*3," FPS: "+Str(FrameRate)+"/40",#White,#Black)
  StopDrawing()
  FlipBuffers()
 
EndProcedure
OpenWindow(0,#PB_Ignore,#PB_Ignore,#view_width*#tileSize,#view_height*#tileSize,"Example",#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
OpenWindowedScreen(WindowID(0),0,0,WindowWidth(0),WindowHeight(0),0,0,0)
SetFrameRate(40)
Repeat
  walk(monsters,pathfinding_structure)
  draw(monsters)
  If ElapsedMilliseconds() < FT
    fps + 1
  Else
    FrameRate = fps
    fps = 0
    FT = ElapsedMilliseconds() + 1000
  EndIf
  If sk = 4
    sk = 0
    goto_player(monsters,pathfinding_structure)
  EndIf
  sk + 1
  Event = WaitWindowEvent(1)
Until Event = #PB_Event_CloseWindow 
http://www.policyalmanac.org/games/aStarTutorial.htm
http://www.codeproject.com/Articles/148 ... e-in-Games
http://www.gameai.com/papers.php
http://www.gamasutra.com/view/feature/1 ... hp?print=1
Current configurations: 
Ubuntu 20.04/64 bit - Window 10 64 bit
Intel 6800K, GeForce Gtx 1060, 32 gb ram.
Amd Ryzen 9 5950X, GeForce 3070, 128 gb ram.
						Ubuntu 20.04/64 bit - Window 10 64 bit
Intel 6800K, GeForce Gtx 1060, 32 gb ram.
Amd Ryzen 9 5950X, GeForce 3070, 128 gb ram.
Re: Dungeon raider (game demo)
Thank you DK_PETER, but I have a code for 2D .
Okay, maybe later I something will come up with.
			
			
									
									Okay, maybe later I something will come up with.
'Happiness for everybody, free, and no one will go away unsatisfied!'
SMsF town: http://www.youtube.com/watch?v=g6RRKYf_Pd0
SMf locations module (Ogre). Game video: http://www.youtube.com/watch?v=ZlhBgPJhAxI
						SMsF town: http://www.youtube.com/watch?v=g6RRKYf_Pd0
SMf locations module (Ogre). Game video: http://www.youtube.com/watch?v=ZlhBgPJhAxI
Re: Dungeon raider (game demo)
i find this useful, even it is 2D, and works with PB 5.30
https://sites.google.com/site/cerisecod ... inding-c01
its french forum here:
http://www.purebasic.fr/french/viewtopi ... 0&start=30
right click anywhere to position the red circle , and the program will draw yellow smaller circles in the path between blue and red circles, you can move the red circles by arrows, and we can position the blue circle by left click
i don't want to study the program nowadays, but i think the path info is in path list
when he draw the path he execute this
ForEach Path()
Circle((path()\x + 0.5) * casesize\cx, (path()\y + 0.5) * casesize\cy, casesize\cx / 5, #Yellow)
Next
without the file CarteMap.byte it will draw a default map, i don't know how CarteMap.byte is made, it can be found in PathFinding_exemple.zip here https://sites.google.com/site/cerisecod ... athfinding go down down the page
now we need only the path list, and to reflect the the 2D map to a 3D map, a good project, i hope i will do but not now.
			
			
									
									
						https://sites.google.com/site/cerisecod ... inding-c01
its french forum here:
http://www.purebasic.fr/french/viewtopi ... 0&start=30
right click anywhere to position the red circle , and the program will draw yellow smaller circles in the path between blue and red circles, you can move the red circles by arrows, and we can position the blue circle by left click
i don't want to study the program nowadays, but i think the path info is in path list
when he draw the path he execute this
ForEach Path()
Circle((path()\x + 0.5) * casesize\cx, (path()\y + 0.5) * casesize\cy, casesize\cx / 5, #Yellow)
Next
without the file CarteMap.byte it will draw a default map, i don't know how CarteMap.byte is made, it can be found in PathFinding_exemple.zip here https://sites.google.com/site/cerisecod ... athfinding go down down the page
now we need only the path list, and to reflect the the 2D map to a 3D map, a good project, i hope i will do but not now.
Re: Dungeon raider (game demo)
Isn't your level map 2D, when viewed from above/top? For different floors, you could find 2 paths:AndyLy wrote:Thank you DK_PETER, but I have a code for 2D .
First search path to next elevator, go with elevator to a new floor, second path from elevator to
target within this floor. The 3rd dimension is only player/bot level above ground, not required for the path finding..?
Re: Dungeon raider (game demo)
First things first: for example we have a room height of 3 units.
The room has columns and balconies. Hero on the first level, and the enemy on level 3. I therefore have three 2D map (level 1, 2, etc.)
If the hero and the enemy is on the same level - that is clear. But I need to determine the path between the levels. I do not understand how can I locate the point where I need to go from one level to another?
			
			
									
									The room has columns and balconies. Hero on the first level, and the enemy on level 3. I therefore have three 2D map (level 1, 2, etc.)
If the hero and the enemy is on the same level - that is clear. But I need to determine the path between the levels. I do not understand how can I locate the point where I need to go from one level to another?
'Happiness for everybody, free, and no one will go away unsatisfied!'
SMsF town: http://www.youtube.com/watch?v=g6RRKYf_Pd0
SMf locations module (Ogre). Game video: http://www.youtube.com/watch?v=ZlhBgPJhAxI
						SMsF town: http://www.youtube.com/watch?v=g6RRKYf_Pd0
SMf locations module (Ogre). Game video: http://www.youtube.com/watch?v=ZlhBgPJhAxI
Re: Dungeon raider (game demo)
On the level of the bot, you need to find the next elevator, stairs, or ramp, if the player is not on the same level.AndyLy wrote:But I need to determine the path between the levels. I do not understand how can I locate the point where I need to go from one level to another?
Next, the bot goes to the level where the player is (using elevator, stairs, or ramp). On the same level, it is no problem, you said.

