Req Help with Sheep spawning

Started by phodiS, August 02, 2019, 20:44:44

Previous topic - Next topic

phodiS

Hi guys,
             I pick away at AGK from time to time and after pulling my hair out for the last few days I decided to ask for some guidance.   The below code allows me to spawn a bunch of "Sheep" on a plane, and they start moving in random directions which is great, but
later when I try to get them to individually change directions they all go the same way. There are no assets required to run this, and I would be appreciative of any
ideas on how to proceed with getting them to work properly.

// SHEEP SPAWNING

// settings
setWindowTitle( "Sheep" )
SetWindowSize( 1024, 768, 0 )
SetWindowAllowResize( 1 )         
SetVirtualResolution( 1024, 768 )

// create a red box that is the location of the spawner for the sheep
spawn = 10000
CreateObjectbox(spawn,1,1,1)
setobjectposition(spawn,random(1,20),1,random(1,50))
setobjectcolor(spawn,255,0,0,1)

// Camera position on start
cx=0: cy=20 :cz=-35
SetCameraPosition(1,cx,cy,cz)

// GROUND PLANE AND TEXTURE
createobjectplane(3000,200,200)
setobjectrotation(3000,90,0,0)
setobjectcolor(3000,120,200,120,1)

// create types
type sheeptype
x
y
z
move
anglex
angley
anglez
objectid
endtype
// create 10 sheep
dim sheep[10] as sheeptype
spr = 0
spawnrate = 5
spawnqty=0     
// tm=a timer for sheep to change direction: dir is their new direction
tm=0:dir=0

////////////////////////////////////////// MAIN LOOP  ////////////////////////////////////////
do

//move camera up with SPACE key
if GetButtonPressed(1) then cy=cy+5
SetCameraPosition(1,cx,cy,cz)

//get random sheep direction
direction# = random(0,360)
          if spawnqty<10   //spawn sheep
            SetObjectRotation(spawn,0,direction#,0)
            if spr = 10 then spr = 0
            spr = spr + 1
            createObjectBox(spr,1,1,1)
            SetObjectPosition(spr,0,0,0)
            setObjectPosition(spr,GetObjectX(spawn),GetObjectY(spawn),GetObjectZ(spawn))
            SetObjectRotation(spr,GetObjectAngleX(spawn),GetObjectAngleY(spawn),GetObjectAngleZ(spawn)) //aim direction of spawner
            sheep[spr].move = 1
            sheep[spr].x = GetObjectX(spawn)
            sheep[spr].y = GetObjectY(spawn)
            sheep[spr].z = GetObjectZ(spawn)
            sheep[spr].anglex = GetObjectAngleX(spr)
            sheep[spr].angley = GetObjectAngleY(spr)
            sheep[spr].anglez = GetObjectAngleZ(spr)
            makenow = 0
            spawntimer=0
            spawnqty=spawnqty+1
        else
            makenow = makenow + 1
        endif
     
// "Change direction timer"
////////////////////////////////////////////////
tm=tm+1                                               //   Here im trying to change the direction of the sheep
if tm=80                                              //   And it works.... except it puts all the sheep together
   dir#=random(0,360) : tm=0                         //   and wont treat them as individuals, as such they all move together
   endif                                             // in the same direction
///////////////////////////////////////////////   
   
   
// Move the sheep     
    for b=0 to 10
        if sheep.move=1
         MoveObjectLocalZ(b,-0.08) //sheep speed
     
       //    SetObjectRotation((b),0,dir#,0)            //  Here is where I am using the above "change direction timer"
                                                        //  to make them change.... this is where I am stuck!>..
            if (GetObjectX(b)-sheep.x) > 100  then sheep.move=0
            if (GetObjectX(b)-sheep.x) < -100 then sheep.move=0
            if (GetObjectZ(b)-sheep.z) > 100  then sheep.move=0
            if (GetObjectZ(b)-sheep.z) < -100 then sheep.move=0
       
        // DeleteObject(b)
        endif
    next b
    Print( ScreenFPS() )
Sync()

loop[code][/b]

phodiS

#1
Ok, well I kinda solved it... will have to be tweaked, but this is what I did...
... I know it's wrong, but I think if I adjust the random values in sync with the direction they came from it should be ok.
I would love to know how to add pausing between changing directions tho... I'm thinking a state machine for this would be the way to go
as I would like them to eat grass and drink water to replenish depleting health.
Getting there.


// SHEEP SPAWNING

// settings
setWindowTitle( "Sheep" )
SetWindowSize( 1024, 768, 0 )
SetWindowAllowResize( 1 )         
SetVirtualResolution( 1024, 768 )

// create a red box that is the location of the spawner for the sheep
spawn = 10000
CreateObjectbox(spawn,1,1,1)
setobjectposition(spawn,random(1,20),1,random(1,50))
setobjectcolor(spawn,255,0,0,1)

// Camera position on start
cx=0: cy=20 :cz=-35
SetCameraPosition(1,cx,cy,cz)

// GROUND PLANE AND TEXTURE
createobjectplane(3000,200,200)
setobjectrotation(3000,90,0,0)
setobjectcolor(3000,120,200,120,1)

// create types
type sheeptype
x
y
z
move
anglex
angley
anglez
objectid
endtype
// create 10 sheep
dim sheep[10] as sheeptype
spr = 0
spawnrate = 5
spawnqty=0     
// tm=a timer for sheep to change direction: dir is their new direction
tm=0:dir=0


////////////////////////////////////////// MAIN LOOP  ////////////////////////////////////////
do


//move camera up with SPACE key
if GetButtonPressed(1) then cy=cy+5
SetCameraPosition(1,cx,cy,cz)

//get random sheep direction
direction# = random(0,360)
          if spawnqty<10   //spawn sheep
            SetObjectRotation(spawn,0,direction#,0)
            if spr = 10 then spr = 0
            spr = spr + 1
            createObjectBox(spr,1,1,1)
            SetObjectPosition(spr,0,0,0)
            setObjectPosition(spr,GetObjectX(spawn),GetObjectY(spawn),GetObjectZ(spawn))
            SetObjectRotation(spr,GetObjectAngleX(spawn),GetObjectAngleY(spawn),GetObjectAngleZ(spawn)) //aim direction of spawner
            sheep[spr].move = 1
            sheep[spr].x = GetObjectX(spawn)
            sheep[spr].y = GetObjectY(spawn)
            sheep[spr].z = GetObjectZ(spawn)
            sheep[spr].anglex = GetObjectAngleX(spr)
            sheep[spr].angley = GetObjectAngleY(spr)
            sheep[spr].anglez = GetObjectAngleZ(spr)
            makenow = 0
            spawntimer=0
            spawnqty=spawnqty+1
        else
            makenow = makenow + 1
        endif
     
// "Change direction timer"
////////////////////////////////////////////////
tm=tm+1                                               //   Here im trying to change the direction of the sheep
if tm=80                                              //   And it works.... except it puts all the sheep together
angley=random(0,360) : tm=0                         //   and wont treat them as individuals, as such they all move together
endif                                             // in the same direction :(
///////////////////////////////////////////////


// Move the sheep  
    for b=0 to 10
        if sheep[b].move=1
MoveObjectLocalZ(b,-0.08) //sheep speed
     
    //     SetObjectRotation((b),0,angley,0)            //  Here is where I am using the above "change direction timer"
                                                        //  to make them change.... this is where I am stuck!>..
            if (GetObjectX(b)-sheep[b].x) > 20  then SetObjectRotation((b),0,random(-30,30),0)
            if (GetObjectX(b)-sheep[b].x) < -20 then SetObjectRotation((b),0,270+random(-30,30),0)
            if (GetObjectZ(b)-sheep[b].z) > 20  then SetObjectRotation((b),0,360+random(-30,30),0)
            if (GetObjectZ(b)-sheep[b].z) < -20 then SetObjectRotation((b),0,90+random(-30,30),0)
         
        // DeleteObject(b)
        endif
    next b
    Print( ScreenFPS() )
Sync()

loop

Xerra

AGK isn't an OOP language, is it?

If it was me using GameMaker II then I'd be using an index to create those sheep so I had a reference to change fields within it later on. As in something like:

x = instance_create(type of object, layer)

then you would use something like:

x.direction = 1 or -1 to set the way it was moving.

Suspect I'm on the wrong track with this but maybe something there makes sense because you're definitely not keeping track of the sheep you create - even in a data structure - so there's no way to control them individually that I can see.
M2 Pro Mac mini - 16GB 512 SSD
ACER Nitro 5 15.6" Gaming Laptop - Intel® Core™ i7, RTX 3050, 1 TB SSD
Vic 20 - 3.5k 1mhz 6502

Latest game - https://xerra.itch.io/Gridrunner
Blog: http://xerra.co.uk
Itch.IO: https://xerra.itch.io/

Xerra

Ah you posted while I was typing my reply. You're using a type for the sheep so you already have a grip on what I'm blabbering on about it seems :)
M2 Pro Mac mini - 16GB 512 SSD
ACER Nitro 5 15.6" Gaming Laptop - Intel® Core™ i7, RTX 3050, 1 TB SSD
Vic 20 - 3.5k 1mhz 6502

Latest game - https://xerra.itch.io/Gridrunner
Blog: http://xerra.co.uk
Itch.IO: https://xerra.itch.io/

phodiS

Hi there,
            OMG, :) if I was using Gamemaker I would have created half the game by now!!.. but I want to do it in 3d, and Gamemaker is hopeless there.

So my inspiration is coming from this video..   https://www.youtube.com/watch?v=r_It_X7v-1E

I really want to make this (well a version of it at least).... in AGK!
Simulating an ecosystem.. with a hands off ~no Player~ approach... ~should be something I can do here on a 3d terrain would be great!!!... anyways I'll keep at it  :)
If anyone else has any Ideas/hints, please chime in.

phodiS

Bahh.. can anyone tell me why this code wont cover the plane I created in the above code?. The plane is 200x200 I even set the position of the plane to 0,0,0
but the trees only spawn in 1/4 of the land.
//trees
t=0:
repeat
t=t+1
x=random(0,200):z=random(0,200)  // I also tried -200,200 in both the x and z axis with seemingly the same results.
tree=createobjectbox(1,5,1)
top=createobjectsphere(random(2,4),random(2,16),random(5,8))
setobjectposition(tree,x,0,z)
setobjectposition(top,x,2,z)
until t=100

blinkok

If the plane is 200x200 and at 0,0
Then it's surface will go from -100 to 100 along the x/z axis
So i think changing
x=random(0,200):z=random(0,200)
to
x=random(0,200) - 100:z=random(0,200) -100
Should fix it.
One other thing to note is there is no check to see if you are using the same position twice

Qube

Quote from: phodiS on August 02, 2019, 23:24:14
Bahh.. can anyone tell me why this code wont cover the plane I created in the above code?. The plane is 200x200 I even set the position of the plane to 0,0,0
but the trees only spawn in 1/4 of the land.
At a guess I'd say that even though your land is 200 x 200 your starting x / z position should be 100 + random( -100, 100 ) as 0, 0 may be the centre of your plane? - Could be wrong but without testing that's just my guess.

Also in regards to your sheep type / dim. I would skip dim altogether and have it more dynamic, like :


Type tSheep
   x As Integer
   z As Integer
   ... all the rest of your parameters
EndType

Global sheep As tSheep
Global sheeps As tSheep[]

For newSheep = 1 to 1000
   sheep.x = random( -100, 100 )
   sheep.z = random(- 100, 100 )
   
   sheeps.insert( sheep )
Next

For sheepCount = sheeps.length To 0 Step -1
   // do funky stuff
   // If you want to remove a sheep then sheeps.remove( sheepCount )
Next


That way you won't have to worry about exceeding your dim length at any point.
Mac Studio M1 Max ( 10 core CPU - 24 core GPU ), 32GB LPDDR5, 512GB SSD,
Beelink SER7 Mini Gaming PC, Ryzen 7 7840HS 8-Core 16-Thread 5.1GHz Processor, 32G DDR5 RAM 1T PCIe 4.0 SSD
MSI MEG 342C 34" QD-OLED Monitor

Until the next time.

phodiS

Thanks guys :) I now have the trees on the map! (it's a big deal for me as I could not work that out).
I will try your suggestion Qube, but I am only going to be dealing with a hundred or so sheep for now, and am not
proficient enough yet to implement your suggestion.
Anyways.. here's literally one whole days effort.


// SHEEP SPAWNING

// settings
setWindowTitle( "Sheep" )
roomwidth=1024
roomheight=768
SetWindowSize( roomwidth, roomheight, 0 )
SetWindowAllowResize( 1 )         
SetVirtualResolution( roomwidth, roomheight )

//LIGHTING
light=1
CreatePointLight(light,100.0,1000.0,100.0,1500.0,205,205,255)
SetPointLightPosition(light,450,200,45)
SetPointLightRadius(light,200)

// create a red box spawner for the sheep
spawn = 10000
CreateObjectbox(spawn,1,1,1)
setobjectposition(spawn,random(1,20),1,random(1,50))
setobjectcolor(spawn,255,0,0,1)

// Camera position on start
cx=0: cy=20 :cz=-35
SetCameraPosition(1,cx,cy,cz)

//skybox
SetSkyBoxSkyColor(77,121,255)
SetSkyBoxHorizonColor(120,128,128)
setSkyBoxHorizonSize(1,0)
SetSkyBoxVisible(1)
SetShadowMappingMode(1)

// GROUND PLANE AND TEXTURE
createobjectplane(3000,200,200)
setobjectrotation(3000,90,0,0)
setobjectcolor(3000,120,200,120,1)
setobjectposition(3000,0,0,0)

// create types
type sheeptype
x
y
z
move
anglex
angley
anglez
objectid
endtype
// create 10 sheep
dim sheep[10] as sheeptype
spr = 0
spawnrate = 5
spawnqty=0     
// tm=a timer for sheep to change direction: dir is their new direction
tm=0:dir=0
//trees
t=0:
repeat
t=t+1
x=random(0,200) - 100:z=random(0,200) -100
tree=createobjectbox(1,8,1)
top=createobjectcone(10,4,6)
setobjectposition(tree,x,0,z)
setobjectposition(top,x,8,z)
SetObjectCastShadow(tree,1)
SetObjectCastShadow(top,1)
until t=100

////////////////////////////////////////// MAIN LOOP  ////////////////////////////////////////
do

//move camera up with SPACE key
if GetButtonPressed(1) then cy=cy+5
SetCameraPosition(1,cx,cy,cz)

//get random sheep direction
direction# = random(0,360)
          if spawnqty<10   //spawn sheep
            SetObjectRotation(spawn,0,direction#,0)
            if spr = 10 then spr = 0
            spr = spr + 1
            createObjectBox(spr,1,1,1)
            SetObjectPosition(spr,0,0,0)
            setObjectPosition(spr,GetObjectX(spawn),GetObjectY(spawn),GetObjectZ(spawn))
            SetObjectRotation(spr,GetObjectAngleX(spawn),GetObjectAngleY(spawn),GetObjectAngleZ(spawn)) //aim direction of spawner
            sheep[spr].move = 1
            sheep[spr].x = GetObjectX(spawn)
            sheep[spr].y = GetObjectY(spawn)
            sheep[spr].z = GetObjectZ(spawn)
            sheep[spr].anglex = GetObjectAngleX(spr)
            sheep[spr].angley = GetObjectAngleY(spr)
            sheep[spr].anglez = GetObjectAngleZ(spr)
            makenow = 0
            spawntimer=0
            spawnqty=spawnqty+1
        else
            makenow = makenow + 1
        endif
     
// "Change direction timer"
tm=tm+1                                               
if tm=80                                             
angley=random(0,360) : tm=0                         
endif                                             

// Move the sheep  
    for b=0 to 10
        if sheep[b].move=1
MoveObjectLocalZ(b,-0.08) //sheep speed
            if (GetObjectX(b)-sheep[b].x) > 20  then SetObjectRotation((b),0,random(-30,30),0)
            if (GetObjectX(b)-sheep[b].x) < -20 then SetObjectRotation((b),0,270+random(-30,30),0)
            if (GetObjectZ(b)-sheep[b].z) > 20  then SetObjectRotation((b),0,360+random(-30,30),0)
            if (GetObjectZ(b)-sheep[b].z) < -20 then SetObjectRotation((b),0,90+random(-30,30),0)
                 
        // DeleteObject(b)
        endif
    next b
    Print( ScreenFPS() )
Sync()

loop