Pop up rain down missiles

pop missiles :cat:

missile.blend (687.5 KB)

import bge


def main():

    cont = bge.logic.getCurrentController()
    own = cont.owner
    if not own.parent and not cont.sensors['Ray'].positive:
        
        if 'target' not in own:
            own['target'] = own.scene.objects['a_target']
        target = own['target']    
            
        #own.applyForce((0,0,9.8*own.mass),0)
        local = own.worldTransform.inverted() @ target.worldPosition
        #print(local)
        own.worldAngularVelocity*=.9
        
        if local.x>0:
            #target is in front
            if local.y>.25:
                own.applyTorque((0,0,6),1)
                own.localLinearVelocity.x*=.975
                if local.y>.5:
                    own.applyTorque((0,0,6),1) 
                 
            elif local.y<-.25:
                own.applyTorque((0,0,-6),1)
                own.localLinearVelocity.x*=.975
                if local.y>.5:
                    own.applyTorque((0,0,-6),1)
                    
                  
            else:
                own.localAngularVelocity.z*=.975    
                       
            if local.z>.25:
                own.applyTorque((0,-6,0),1)
                own.localLinearVelocity.x*=.975
                if local.z>.5:
                    own.applyTorque((0,-6,0),1)
                  
            elif local.z<-.25:
                own.applyTorque((0,6,0),1)
                own.localLinearVelocity.x*=.975
                if local.z<-.5:
                    own.applyTorque((0,6,0),1)
                
                  
            else:
                own.localAngularVelocity.y*=.95
            
            
            if abs(local.y)-local.x<0 and abs(local.z)-local.x<0:
                #missile aimed at target
                own.localAngularVelocity.y*=.95
                own.localAngularVelocity.z*=.95                   
                own.applyForce((125,0,0),1)
                own.alignAxisToVect(own.getVectTo(target)[1],0,.25)
                own.applyForce((0,0,9.8),0)           
                own.localLinearVelocity.z*=.95
                own.localLinearVelocity.y*=.95
            
            
        else:
            
            if local.y>.1:
                own.applyTorque((0,0,6),1)
                if local.y>.5:
                    own.applyTorque((0,0,6),1)
            elif local.y<.1:
                own.applyTorque((0,0,-6),1)
                if local.y<-.5:
                    own.applyTorque((0,0,-6),1)
            if local.z>.1:
                own.applyTorque((0,-6,0),1)
                if local.z>.5:
                    own.applyTorque((0,-6,0),1)
                
            elif local.z<.1:
                own.applyTorque((0,6,0),1)
                if local.z<-.5:
                    own.applyTorque((0,6,0),1)
                
                
    elif cont.sensors['Ray'].positive and not own.parent:
        print('fire')
        own.setParent(cont.sensors['Ray'].hitObject,0,1)
        own.worldPosition = cont.sensors['Ray'].hitPosition
                

main()

1 Like

missile2.blend (727.0 KB)

2 Likes

Hey,

So, this is probably a lot to ask. But, it has been quite a while since I have really been into coding, and it was all much simpler than games. And I am just starting to play around with BGE.

Since this is such a small and specific example…

Is there any chance you would be willing to heavily comment those scripts above, maybe also with references to the objects in the scene? Or perhaps even a tutorial?

Obviously it’s not your job to do that, lol, but… this strikes me as a very short-and-sweet BGE example that I could learn a lot from if there was some more commenting on there…

I think that would be really really cool, and I would like to try to rebuild this on my own once I understand a little more about what is actually being done. Especially because a missile track program/game was always the first one I wanted to make!

Thanks!

import bge
from mathutils import Vector

def main():
    force_1 = 32
    cont = bge.logic.getCurrentController()
    own = cont.owner
    
    #we have not hit anything
    if not own.parent and not cont.sensors['Ray'].positive:
        # get target
        # later on we can use lock on/ radar etc
        # for now we are using a generic target on the scene
      
        if 'target' not in own:
            own['target'] = own.scene.objects['a_target']
            
        target = own['target']    
        
        
        
        #this is used to lead the thing off based on it's speed
        if 'last' not in own:
            diff = Vector([0,0,0])
        else:
            diff = target.worldPosition - own['last']
            
        own['last']=target.worldPosition.copy()
        
        #uncomment for a little debug info
        #print(diff.magnitude)          
        
        #localize target position to missile space and add lead off a little
        local = own.worldTransform.inverted() @ (target.worldPosition+(diff*(diff.magnitude+1)*8))
        
        #dampen motion a bit
        own.worldAngularVelocity*=.9
        own.worldLinearVelocity*=.9
         
        if local.x>0:
            #target is in front
            
            #turn left is missile is to your left
            if local.y>.25:
                own.applyTorque((0,0,force_1),1)
                own.localLinearVelocity.x*=.965
                #turn more left if the missile is further left 
                if local.y>.5:
                    own.applyTorque((0,0,force_1),1) 
                    
            #turn right if target is to right
            elif local.y<-.25:
                own.applyTorque((0,0,-force_1),1)
                own.localLinearVelocity.x*=.965
                #turn more right if the missile is further right 
                if local.y>.5:
                    own.applyTorque((0,0,-force_1),1)
                    
            #slow down rotation on left/right axis we good               
            else:
                own.localAngularVelocity.z*=.975    
                       
            
            
            #same proccess for up/down
            
            if local.z>.25:
                own.applyTorque((0,-force_1,0),1)
                own.localLinearVelocity.x*=.965
                if local.z>.5:
                    own.applyTorque((0,-force_1,0),1)
                  
            elif local.z<-.25:
                own.applyTorque((0,force_1,0),1)
                own.localLinearVelocity.x*=.965
                if local.z<-.5:
                    own.applyTorque((0,force_1,0),1)
                
                  
            else:
                own.localAngularVelocity.y*=.95
            
            
            #target ahead captain this math is like a vision cone
            if abs(local.y)-local.x<0 and abs(local.z)-local.x<0:
                #missile aimed at target
                own.localAngularVelocity.y*=.925
                own.localAngularVelocity.z*=.925
                
                #all power to thrusters                  
                own.applyForce((1000,0,0),1)
                    
                own.alignAxisToVect(own.getVectTo(target)[1],0,.35)
                own.applyForce((0,0,9.8),0)
                
                #dampen sideways motions           
                own.localLinearVelocity.z*=.925
                own.localLinearVelocity.y*=.925
                
                #FX
                added = own.scene.addObject('Icosphere',own,12)
                added.worldPosition = own.worldPosition + (own.worldOrientation.col[0]*-1.25)
                #added.localLinearVelocity=own.localLinearVelocity+(own.worldOrientation.col[0]*-7)
                #added['owner']=own
            
        else:
            
            
            #the target is behind you spin in place
            #left/right
            if local.y>.1:
                own.applyTorque((0,0,force_1),1)
                if local.y>.5:
                    own.applyTorque((0,0,force_1),1)
            elif local.y<.1:
                own.applyTorque((0,0,-force_1),1)
                if local.y<-.5:
                    own.applyTorque((0,0,-force_1),1)
            
            
            #up/down
            if local.z>.1:
                own.applyTorque((0,-force_1,0),1)
                if local.z>.5:
                    own.applyTorque((0,-force_1,0),1)
                
            elif local.z<.1:
                own.applyTorque((0,force_1,0),1)
                if local.z<-.5:
                    own.applyTorque((0,force_1,0),1)
                
    #we hit something              
    elif (cont.sensors['Ray'].positive and not own.parent) or (cont.sensors['Collision'].positive and not own.parent):
        print('fire')
        
        if cont.sensors['Ray'].positive:
            #we hit with ray
            own.setParent(cont.sensors['Ray'].hitObject,0,1)
            own.worldPosition = cont.sensors['Ray'].hitPosition
        else:
            #we hit with collision
            own.setParent(cont.sensors['Collision'].hitObject,0,1)
            #own.worldPosition = cont.sensors['Ray'].hitPosition
                        

main()

@arcarsenal

Dude. You’re awesome. I’m going to see if I can recreate this in the next couple days. If I have some more specific questions, hopefully you won’t mind if I ask?

Thank you. Seriously, this was really cool of you to do.

1 Like