Turret Targeting
Blitz3D Forums/Blitz3D Programming/Turret Targeting
| ||
How do you make one Entity target another Entity, like on Sheep Defence? Edit Or could someone at least tell me how to find the closest entity to another entity. |
| ||
pointentity or aligntovector on the z axis. to find the closest entity i would check to see if the enemy is in range with entitydistance and then if it is in range check its distance aganst the othe entitysin range. |
| ||
Well I'm using types and it doesn't work out the same way. I'm checking one entities distance, and then another one's distance(whether it even exists or not which I probably shouldn't do), and whichever one is closer is the target. I could do it like this, checking all the entities that I know exist... Graphics3D 800,600,0,2 SetBuffer BackBuffer() cam = CreateCamera() PositionEntity cam,0,2,-10 light = CreateLight() a2.Unit = Unit(CreateCube(),2,0,0,"a") b2.Unit = Unit(CreateSphere(32),-2,-1,0,"b") c2.Unit = Unit(CreateSphere(32),7,-1,0,"c") While Not KeyDown(1) If KeyDown(200) a2\y = a2\y + .1 If KeyDown(208) a2\y = a2\y - .1 If KeyDown(205) a2\x = a2\x + .1 If KeyDown(203) a2\x = a2\x - .1 UpdateUnit If EntityDistance(a2\mdl,b2\mdl) < EntityDistance(a2\mdl,c2\mdl) a2\target = EntityName(b2\mdl) ElseIf EntityDistance(a2\mdl,c2\mdl) < EntityDistance(a2\mdl,b2\mdl) a2\target = EntityName(c2\mdl) Else a2\target = 0 EndIf UpdateWorld RenderWorld Text 0,0,"Target = " + a2\target Text 0,20,EntityDistance(a2\mdl,b2\mdl) Text 0,40,EntityDistance(a2\mdl,c2\mdl) Flip Wend End Type Unit Field mdl Field x#,y#,z# Field target$ Field name$ End Type Function Unit.Unit(mdl,x#,y#,z#,name$) a.Unit = New Unit a\mdl = mdl a\x = x a\y = y a\z = z a\name = name NameEntity a\mdl,a\name PositionEntity a\mdl,a\x,a\y,a\z Return a End Function Function UpdateUnit() For a.Unit = Each Unit PositionEntity a\mdl,a\x,a\y,a\z Next End Function But I want it updating for ALL of that Type... Graphics3D 800,600,0,2 SetBuffer BackBuffer() cam = CreateCamera() PositionEntity cam,0,2,-10 light = CreateLight() a2.Unit = Unit(CreateCube(),2,0,0,"a") b2.Unit = Unit(CreateSphere(32),-2,-1,0,"b") c2.Unit = Unit(CreateSphere(32),7,-1,0,"c") While Not KeyDown(1) If KeyDown(200) a2\y = a2\y + .1 If KeyDown(208) a2\y = a2\y - .1 If KeyDown(205) a2\x = a2\x + .1 If KeyDown(203) a2\x = a2\x - .1 UpdateUnit UpdateWorld RenderWorld Text 0,0,"Target = " + a2\target Text 0,20,EntityDistance(a2\mdl,b2\mdl) Text 0,40,EntityDistance(a2\mdl,c2\mdl) Flip Wend End Type Unit Field mdl Field x#,y#,z# Field target$ Field name$ End Type Function Unit.Unit(mdl,x#,y#,z#,name$) a.Unit = New Unit a\mdl = mdl a\x = x a\y = y a\z = z a\name = name NameEntity a\mdl,a\name PositionEntity a\mdl,a\x,a\y,a\z Return a End Function Function UpdateUnit() For a.Unit = Each Unit For b.Unit = Each Unit For c.Unit = Each Unit If EntityDistance(a\mdl,b\mdl) < EntityDistance(a\mdl,c\mdl) a\target = EntityName(b\mdl) ElseIf EntityDistance(a\mdl,c\mdl) < EntityDistance(a\mdl,b\mdl) a\target = EntityName(c\mdl) Else a\target = 0 EndIf Next Next PositionEntity a\mdl,a\x,a\y,a\z Next End Function |
| ||
Why not just have two nested for loops? Have a local variable, smallestDistance. For a.Unit = each Unit For b.Unit = each Unit If EntityDistance(a\mdl, b\mdl) < smallestDistance smallestDistance = EntityDistance(a\mdl, b\mdl) a\target = EntityName(b\mdl) Endif Next Next It's hard to write code, because I usually do things differently, but I've used this general implementation many times to great success. |
| ||
Because what if two entities are under the smallestDistance, it would target both of them... somehow... it just wouldn't turn out right. Edit Oh wait a minute here... you put smallestDistance = EntityDistance... I'll go ahead and try that one out |
| ||
HA HA Thank you! Man y'all are really helpful... this is what I came up with..Graphics3D 800,600,0,2 SetBuffer BackBuffer() cam = CreateCamera() PositionEntity cam,0,2,-10 light = CreateLight() a2.Unit = Unit(CreateCube(),2,0,0,"A2") b2.Unit = Unit(CreateSphere(32),-2,-1,0,"B2") c2.Unit = Unit(CreateSphere(32),7,-1,0,"C2") While Not KeyDown(1) If KeyDown(200) a2\y = a2\y + .1 If KeyDown(208) a2\y = a2\y - .1 If KeyDown(205) a2\x = a2\x + .1 If KeyDown(203) a2\x = a2\x - .1 If KeyDown(17) c2\y = c2\y + .1 If KeyDown(31) c2\y = c2\y - .1 If KeyDown(32) c2\x = c2\x + .1 If KeyDown(30) c2\x = c2\x - .1 UpdateUnit() UpdateWorld RenderWorld Text 0,0,"Target = " + a2\target Text 0,20,"B2 Distance= " + EntityDistance(a2\mdl,b2\mdl) Text 0,40,"C2 Distance= " + EntityDistance(a2\mdl,c2\mdl) Text 0,80,"A2 Smallest Distance = " + a2\sD Text 0,100,"B2 Smallest Distance = " + c2\sD Text 0,120,"C2 Smallest Distance = " + b2\sD Flip Wend End Type Unit Field mdl Field x#,y#,z# Field target$ Field name$ Field sD# End Type Function Unit.Unit(mdl,x#,y#,z#,name$) a.Unit = New Unit a\mdl = mdl a\x = x a\y = y a\z = z a\sD#=5 a\name = name NameEntity a\mdl,a\name PositionEntity a\mdl,a\x,a\y,a\z Return a End Function Function UpdateUnit() For ua.Unit = Each Unit For ub.Unit = Each Unit If EntityDistance(ua\mdl,ub\mdl) < ua\sD If EntityDistance(ua\mdl,ub\mdl) > 0 ua\sD = EntityDistance(ua\mdl,ub\mdl) ua\target = EntityName(ub\mdl) Else ua\sD=5 ua\target = 0 EndIf EndIf Next PositionEntity ua\mdl,ua\x,ua\y,ua\z Next End Function I didn't know before that I had to check if the distance was above 0 Should I put it in the code archives? |
| ||
You don't have to check if distance > 0, just make sure ua<>ub so that a unit doesn't try and target itself. Normally you would have a TEAM field so the check would be ua\Team <> ub\Team so that you don't target your own units. You should hold a unit maximum range so that it doesn't target units which it has no chance of hitting. The code below is slightly more efficient as you only call entitydistance once. I'd also recommend not changing the target every frame, only when the target is dead or out of range or your ai decides to do a runner etc.. Function UpdateUnit() For ua.Unit = Each Unit ua\sD = ua\MaxRange ua\Target = 0 For ub.Unit = Each Unit If ua <> ub Distance# = EntityDistance(ua\mdl,ub\mdl) If Distance < ua\sD ua\sD = Distance ua\target = EntityName(ub\mdl) EndIf EndIf Next PositionEntity ua\mdl,ua\x,ua\y,ua\z Next End Function |
| ||
Thats funny! The biggest problem is predicting where the target will be when the bullet gets there. Bullets have finite speed and direction as do targets. So how far ahead do you have to "lead" the target? I know because I wrote sheep defence. Bring on the solutions! |
| ||
Ello there mister srcoder.. Couldnt you somehow add the objects current velocity to determie which way to shoot the bulet? It pretty much what you already do in FPS games, and if I'm not mistaken, the best way to figure out how to do code certain things (like ai) is to figure out how a human would do it. |
| ||
I would: 1. calculate the time the bullet would take to get to the enemy. 2. calculate the speed the enemy is travelling at 3. figure out how much ground the enemy could make up, based on the time the bullet would take to hit it 4. extend the target in front of the enemy (using some sort of TFormPoint), using the distance worked out in step 3. That should work. At least it does in my head :o) |
| ||
Ah yes...... However 1. Once you predict how long it will take for the bullet to get to the target 2. You can work how where the target will be after that length of time 3. But the target could be moving towards or away from the turret 4. therefore the bullet will take slightly more/or less time to get to the predicted position of the player.... Work that puppy out!!! Kep it up and I will give you the Sheep Defence Source Code! (;o# |
| ||
Yes, that's where a vector comes into it. It points the direction in which the entity is travelling. So, work out the angle the entity is travelling. Once you have the distance, project it along that angle, from the entity position, along the angle :o) |
| ||
Think of a fast moving obect. Now you calculate the time the bullet will take to get to the target and use a vector to calculate the target's position after that length of time (and therefore predict where to aim). Problem..... Well the distance the bullet will have to travel to get the targets predicted position is now different.... therefore it will take more/less time to get there..... therefore you need to predict a new vector for the target's position after the new length of time..... oh nuts........ Keep trying......You're nearly there...... |
| ||
I got bored waiting!!! Here is my code for the machine gun turrets. I have not included the vector library but it's simple enought to find those. I might be persuaded to make the test code available to download if you want to use it. Have fun!! |