ThePythonGameBook

learn Python. Create Games

User Tools

Site Tools


en:pygame:step021

Step 021 - Rotating toward a target

video

Video link: http://www.youtube.com/watch?v=nfaOmkhK-V0 Bug: tank angle and turret angle is swapped in the video. The source code below is correct.

description

targetingdemo In the code example below, you can move both tanks (as in step020) or you can “teleport” the yellow tank toward the mouse pointer by clicking the left mouse button. The blue tank will rotate it's turrent toward the position of the yellow tank. The problem is to decide in wich direction the turret should move.

source code discussion

In the code example below this is solved by the Tank class method aim_at_player. Note that the angle diff can result in values > than 360, so the result is divided by 360 and its modulo1), is saved. You will also note that very few lines are altered since step020, mostly the tank class got a new method:

    def aim_at_player(self, targetnumber=0):
        #print "my  pos: x:%.1f y:%.1f " % ( self.pos[0], self.pos[1])
        #print "his pos: x:%.1f y:%.1f " % ( Tank.book[0].pos[0], Tank.book[0].pos[1])  
        deltax = Tank.book[targetnumber].pos[0] - self.pos[0]
        deltay = Tank.book[targetnumber].pos[1] - self.pos[1]
        angle =   math.atan2(-deltax, -deltay)/math.pi*180.0    
 
        diff = (angle - self.turretAngle - 90) %360 #reset at 360
        if diff == 0:
            self.turndirection = 0
        elif diff > 180:
            self.turndirection = 1
        else:
            self.turndirection = -1
        return diff

And also the mainloop's event handler is expanded. He now checks the MOUSEBUTTON event to teleport player1 tank around:

            # teleport player1 tank if left mousebutton is pressed
            elif event.type == pygame.MOUSEBUTTONDOWN:
                if pygame.mouse.get_pressed()[0]:
                    #left mousebutton was pressed
                    player1.pos[0]=pygame.mouse.get_pos()[0]
                    player1.pos[1]=pygame.mouse.get_pos()[1]

<note>yipyipUser yipyip has donated a very interesting solution to this problem, using Complex numbers. See his source code here: yipyip's solution </note>

ideas

<note tip>Do you remember the keyboard-rollover problem from step020 ? Now you could use less keyboard commands by letting both players turrets automatically rotate toward each other</note> <note tip>Can you code an Artificial_intelligence for the bow machine gun ? Let it firing as soon as it's Deflection angle is low enough:

if -5 < tankDiffAngle < 5:
  Tracer(self)

</note>

additional resources

no additional resources needed

source code on github

To run this example you need:

file in folder download
021_targeting.py pygame Download the whole Archive with all files from Github:
https://github.com/horstjens/ThePythonGameBook/archives/master

View/Edit/Download the file directly in Github: https://github.com/horstjens/ThePythonGameBook/blob/master/pygame/021_targeting.py

click reload in your browser if you see no code here:

comment this page

~~DISQUS~~

1)
the part remaining after a division by 360. See the modulo operator %
/var/www/horst/thepythongamebook.com/data/pages/en/pygame/step021.txt · Last modified: 2014/01/09 11:07 (external edit)