Help with enemy-tank firing behavior

– This turned out to be a long post – :rolleyes:

I had my user_tank set to user_tank.class = “Player”
My enemy-tanks, IGmines and a few other objects also had a defined .class

I added the .objType to the following objects - just to see if they would actually register in the terminal when hit:

[lua]
user_tank.objType = “PlayerTank”
user_turret.objType = “PlayerTank”
enemyB02.objType = “EnemyTank”
ET02radar.objType = “Radar”
[/lua]
And here is all of the code that deals with the ray

[lua]
    E1Dray = physics.rayCast( enemyB02.x - 50, enemyB02.y, user_tank.x, user_tank.y, “sorted” )
        
    local hitFirst = E1Dray[1]
    local hitX, hitY = hitFirst.position.x, hitFirst.position.y
        
    DRline = display.newLine( enemyB02.x - 50, enemyB02.y, user_tank.x, user_tank.y )
    DRline.width = 10
    DRline:setColor( 255,50,40,100 )
    DRline.blendMode = “add”
    level1group:insert( DRline )

    if E1Dray then
        – There’s at least one hit.
        print( "Hit count: " … tostring( #E1Dray ) )

        – Output all the results.
         for i,v in ipairs(E1Dray)  do
            print( "Hit: ", i, object_name, " Position: ", v.position.x, v.position.y, " Surface normal: ", v.normal.x, v.normal.y )
    end
        print( "The first object hit is: ",
        E1Dray[1].object, " at position: ", E1Dray[1].position.x, E1Dray[1].position.y, " where the surface normal is: ", E1Dray[1].normal.x, E1Dray[1].normal.y )

        else
        – There’s no hit.
    end
    if ( E1Dray[1].objType and E1Dray[1].objType == “PlayerTank” ) then
[/lua]

Using all that code, this is what the terminal window prints - based on the conditions in this photo

2013-06-21 12:33:52.560 Corona Simulator[23416:f03] Hit count: 2
2013-06-21 12:33:52.560 Corona Simulator[23416:f03] Hit:     1    nil     Position:     365.51693725586    387.89959716797     Surface normal:     0.56341761350632    0.82617217302322
2013-06-21 12:33:52.560 Corona Simulator[23416:f03] Hit:     2    nil     Position:     355.6755065918    393.59799194336     Surface normal:     0.89465683698654    -0.44675385951996
2013-06-21 12:33:52.561 Corona Simulator[23416:f03] The first object hit is:     table: 0x10e4fbad0     at position:     365.51693725586    387.89959716797     where the surface normal is:     0.56341761350632    0.82617217302322

The ray seems to only register a hit for the user_tank and user_turret (both with the same objType) which to me would make perfect sense, but it still won’t fire even though it’s hitting the PlayerTank. :wacko:

P.S. When I removed the - 50 from the ray and line (to make it originate from within the enemy-tank) the terminal still printed the exact same thing.

On line 16, where is “object_name” coming from?

Ummm… I’m not sure. I just copied all that print code from the RayCast docs
I assumed that it would get the name of the object that collides with the ray and then print that object’s name…

Thanks Larry. :smiley:

Hey Brent,

I managed to get the firing on a timer, but I’ve run into a few kinks and I was hoping you’d be willing to help me out.

  1. The timer for the enemy-firing works fine, but it’s getting it to stop that is the problem.
    When I try to stop the timer, it doesn’t work.
    timer.cancel( timerId ) What is the timerId?
    I just use timer.performWithDelay()

Btw - I am trying to stop it on the ended phase of the collision between the player and radar.

— text Removed —

Hi Saer,

I can answer the timer question now, but please move the second question to another forum thread… this thread is getting very, very long, as you may have noticed. :slight_smile:

For the timer, the “timerID” is just a variable that you assigned the timer to when you started it. For example, near the top of your code, you may pre-declare a variable:

[lua]

local firingTimer

[/lua]

Then, somewhere below, you say:

[lua]

firingTimer = timer.performWithDelay( 1000, fireBullet )

[/lua]

And to pause/resume or cancel the timer:

[lua]

timer.pause( firingTimer )

timer.resume( firingTimer )

timer.cancel( firingTimer )

[/lua]

Brent

hehe okay, will do. :slight_smile:

Thanks, that fixed it. I was declaring it wrong.

Well, as for the enemy-firing, I think I’ve got it working 'bout as good as I can get it.
Many, many thanks for all your help Brent!

Ten levels basically finished; only forty more to go! :smiley:
 

– bump –
:ph34r:

Hi Saer,

I looked at the API documentation and I agree, that little part is a bit confusing. I’m going to update that code bit this week.

Anyway, to get the name of the object, you’ll have to access its “object” property and then get the name based on that, from however you specified the property on your object(s).

So, on line 16, if you attached your own “name” parameter to the necessary objects, it would be:

[lua]

print( "Hit: ", i, v.object.name, " Position: ", v.position.x, v.position.y, " Surface normal: ", v.normal.x, v.normal.y )

[/lua]

So, using:

[lua]v.object.name[/lua]

You should be able to determine which type of object (name) the raycast hit is representing.

Brent

Thanks for replying.

I use object.class for my objects.
I changed object_name to v.object.class and it now prints the name of whatever object the ray collides with. :smiley:

Sadly, using the code you suggested for my ray’s conditional statement, it still won’t fire even when the object.class is PlayerTank…?

-You’ll notice, in the code below, right after the ray’s if statement I have

print( “PlayerTank in range! Fire!” )

When I run the simulator, and the only object.class that hits the radar is PlayerTank, the enemy won’t fire…?
I don’t get any errors and it doesn’t print the statement I just mentioned.
Obviously it’s colliding with and registering the PlayerTank, but it won’t go beyond that if statement :huh:
[lua]
function fire( tower, user_tank )
    
    E1Dray = physics.rayCast( enemyB02.x, enemyB02.y, user_tank.x, user_tank.y, “closest” )
        
    local hitFirst = E1Dray[1]
    local hitX, hitY = hitFirst.position.x, hitFirst.position.y
        
    DRline = display.newLine( enemyB02.x, enemyB02.y, user_tank.x, user_tank.y )
    DRline.width = 10
    DRline:setColor( 255,50,40,100 )
    DRline.blendMode = “add”
    level1group:insert( DRline )

    if E1Dray then
        – There’s at least one hit.
        print( "Hit count: " … tostring( #E1Dray ) )

        – Output all the results.
         for i,v in ipairs(E1Dray)  do
            print( "Hit: ", i, v.object.class, " Position: ", v.position.x, v.position.y, " Surface normal: ", v.normal.x, v.normal.y )
    end
        print( "The first object hit is: ",
        E1Dray[1].object, " at position: ", E1Dray[1].position.x, E1Dray[1].position.y, " where the surface normal is: ", E1Dray[1].normal.x, E1Dray[1].normal.y )

        else
        – There’s no hit.
    end
    if ( E1Dray[1].class and E1Dray[1].class == “PlayerTank” ) then
    
    
        print(“PlayerTank in range! Fire!”)
        – solution: “firing solution” - the collision point between the tower’s bullet and the target
        – success: true if the tower can successfully fire on the target, false if the target will escape
        local solution, success = intercept( tower, user_tank, bulletSpeed )
                    –   
                local math_deg = math.deg  – localize ‘math.deg’ for better performance
                local math_atan2 = math.atan2  – localize ‘math.atan2’ for better performance
 
                – Calculates the angle between specified points A & B
                local function angleBetween( enemyB02X, enemyB02Y, user_tankX, user_tankY )
                local angle = ( math_deg( math_atan2( user_tankY-enemyB02Y, user_tankX-enemyB02X ) )+180) --; return angle
                    if ( angle < 0 ) then angle = angle + 360 end ; return angle % 360
                end

                local ang = angleBetween( enemyB02.x, enemyB02.y, user_tank.x, user_tank.y )
                enemyT02.rotation = ang
            –
        
        – only fire if the firing solution is successful
        if (success) then
                – calculate vx and vy
                local angle = angleOf( tower, solution )
                local pt = rotateTo( {x=bulletSpeed, y=0}, angle)
                local pt2 = mathapi.rotateAboutPoint( {x=enemyT02.x,y=enemyT02.y -65}, enemyT02, enemyT02.rotation - 90 )
                
                – create bullet
                Enemybullet = loader:createSpriteFromSHDocument(“Weapon5ex”, “GameFX”, “LevelAssets.pshs”);
                Enemybullet.x, Enemybullet.y, Enemybullet.solution = pt2.x, pt2.y, solution
                --bullet.x = pt2.x; bullet.y = pt2.y;
                physics.addBody(Enemybullet,{friction = 0, bounce = 1.0, density = 1.5, radius=10, isSensor = true})
                Enemybullet:scale(.65,.65)
                Enemybullet.class = “bullet”
                Enemybullet.isBulet = true
                Enemybullet.rotation = enemyT02.rotation + 90
                
                – fire bullet
                --bullet:applyForce( pt2.x - enemyT02.x, pt2.y - enemyT02.y, enemyT02.x, enemyT02.y )
                Enemybullet:setLinearVelocity(pt.x, pt.y)       
        end
    end
end
[/lua]

P.S. When I comment-out the if statement and the closing end, it fires whenever the user collides with the radar; so I know the code/logic for the actual firing works fine.

Again, you’ve stated the conditional check incorrectly. :slight_smile:  It should be:

[lua]

“E1Dray[1].object.class”

[/lua]

Because “object” is the internal table ID of the display object, and “class” is the property you’ve given it, as in “PlayerTank”.

lol Wow… can’t believe I didn’t notice that! :rolleyes:

Thank you so much for all your help, Brent. I greatly appreciate it!

Here is a video of how it works:
video

–I’ll have to tweak it a little to take care of a few weird results that occur when the enemy-tank is moving, but that should be easy–
:smiley:

Looking very good :slight_smile: Good luck

Larry

Thanks Larry. :smiley:

Hey Brent,

I managed to get the firing on a timer, but I’ve run into a few kinks and I was hoping you’d be willing to help me out.

  1. The timer for the enemy-firing works fine, but it’s getting it to stop that is the problem.
    When I try to stop the timer, it doesn’t work.
    timer.cancel( timerId ) What is the timerId?
    I just use timer.performWithDelay()

Btw - I am trying to stop it on the ended phase of the collision between the player and radar.

— text Removed —

Hi Saer,

I can answer the timer question now, but please move the second question to another forum thread… this thread is getting very, very long, as you may have noticed. :slight_smile:

For the timer, the “timerID” is just a variable that you assigned the timer to when you started it. For example, near the top of your code, you may pre-declare a variable:

[lua]

local firingTimer

[/lua]

Then, somewhere below, you say:

[lua]

firingTimer = timer.performWithDelay( 1000, fireBullet )

[/lua]

And to pause/resume or cancel the timer:

[lua]

timer.pause( firingTimer )

timer.resume( firingTimer )

timer.cancel( firingTimer )

[/lua]

Brent

hehe okay, will do. :slight_smile:

Thanks, that fixed it. I was declaring it wrong.

Well, as for the enemy-firing, I think I’ve got it working 'bout as good as I can get it.
Many, many thanks for all your help Brent!

Ten levels basically finished; only forty more to go! :smiley:
 

– removed –

– removed –