A simple missile auto-tracking and real-time image rotation algorithm, Python-pygame code implementation

Source: Internet
Author: User
Tags pow

Automatic tracking algorithm, in our design of 2D shooting games often used, this sounds very tall things, in fact, is not a military science patent, in mathematics to solve the words need to resolve the differential equation,

It's hard to work out a mathematical basis. But we have a computer is not the same, relying on the computer very fast computing speed, we use the idea of differentiation, coupled with a simple triangular knowledge, we can achieve it.

Well, don't say much, let's look at its algorithm principle, look at the graph:

        

Since we're going to demonstrate with Pygame, his coordinate system is the y-axis downward, so here we also use the Y-downward coordinate system.

The general idea of the algorithm is that the time t is divided into small enough fragments (such as 1/1000, the time slice smaller and more accurate), each fragment is constructed as the upper triangle, calculating the direction of the next time slice of the missile (ie, ∠a) and walk (i.e. vt=| ac|), when the target again in the second time slice moved position, then the calculation of the C point has become the initial point of the second time slice, then on the second time slice on the C point and the new target point to construct a triangle to calculate the new VT, and then into the third time slice, so repeated.

Assuming the coordinates of the initial state of the missile and the target are (x1,y1), (x, y), constructs the right triangle Abe, which is used to seek the sine and cosine of the ∠a, because the VT is set by itself, we need to calculate how much a to C point x and Y coordinates are moved, the moving value is the length of the ad and the CD , these two respectively with VT multiply Cosa and Sina can.

Calculated Sina and Cosa, sinusoidal contrast oblique, Yu Ying ratio oblique, the hypotenuse can be calculated using the two-point distance formula, namely:

      

So

      

The length of the AC is the speed of the missile multiplied by the time | AC|=VT, and then you can calculate the length of the ad and CD, so this one time slice past, the missile should appear in the new position C point, his coordinates is the old point a x increase ad and y minus the CD.

So, the new C-point coordinates are:

      

Just keep repeating this operation over and over, okay, for a better image, put the first time slice and the second time slice together to see:

        

The first is the time slice structure of the triangle is Abe, after a time slice, the target from point B to D Point, the missile at this point in C, so the construction of a new triangular cdf, repeating just the calculation process can be, the figure of the angle ∠b is the missile need to rotate the angle, In reality only need to revise the direction of the missile each time slice, how to let the missile change direction, this is not the problem we need to study

Well, with the recent creation of a mini-game in Python's Pygame library, we'll use pygame to demonstrate this effect, such as:

          

The very simple code is as follows:

1 ImportPygame,sys2  fromMathImport*3 Pygame.init ()4Screen=pygame.display.set_mode (800,700), 0,32)5Missile=pygame.image.load ('Element/red_pointer.png'). Convert_alpha ()6x1,y1=100,600#the initial launch position of the missile7velocity=800#Missile Speed8time=1/1000#the length of each time slice9clock=Pygame.time.Clock ()Tenold_angle=0 One  whileTrue: A      forEventinchpygame.event.get (): -         ifevent.type==Pygame. QUIT: - sys.exit () theClock.tick (300) -X,y=pygame.mouse.get_pos ()#get mouse position, mouse is the target to hit -Distance=sqrt (Pow (x1-x,2) +pow (y1-y,2))#Two-point distance formula -Section=velocity*time#the distance to move each time slice +Sina= (y1-y)/Distance -Cosa= (X-X1)/Distance +Angle=atan2 (Y-Y1,X-X1)#the Radian value of the two-point segment AX1,y1= (x1+section*cosa,y1-section*Sina) atD_angle = degrees (angle)#Radian to Angle -Screen.blit (missile, (X1-missile.get_width (), Y1-missile.get_height ()/2)) -Dis_angle=d_angle-old_angle#Dis_angle is the angle that needs to be changed to the next position. -Old_angle=d_angle#Update Initial angle -Pygame.display.update ()

If the missile is only considered a particle, then the above algorithm is sufficient, I did not do the rotation of the missile, because a particle does not have to split the tail does not need to rotate, of course, this premise is that you load the missile picture is very small when the rotation does not seem to be a problem. But it's not easy to spin in Pygame (or maybe I'm ignorant), okay? Let's replace the picture with a rectangle, and then add the rotation function to see how it works.

missiled = Pygame.transform.rotate (missile,-(D_angle)) Screen.blit (missiled, (X1-missile.get_width (), Y1-missile.get_height ()/2))

Because the coordinate point of the picture is the point of its upper-left corner, so if we want the coordinates of the image to be fixed at the Arrowhead Point, then the actual print position of the picture is reduced by the length of the image, and y is reduced by half the width.

But the actual performance is not good:

The direction is the same, but the arrow point of the picture doesn't follow the mouse all the time. After my research (just because this problem has not been resolved has not been released),

I found out that this is the mechanism of the rotation of the diagram, we look at the rotation of the picture becomes what:

After the rotation of the picture into the blue range, depending on the angle of rotation, the size of the picture is different, we look at the situation of rotation 90

We found that the rotated picture not only became larger, but also changed the position of the missile head. How is that supposed to solve the problem? The idea is that after each rotation of the picture, find the head position of the rotation chart (green arrow points in the picture), and then the green map to move the print position, the next, X, Y, respectively, moving two head distance, you can let the rotating missile head to the actual we participate in the operation of the missile head position, should be this:

In this way, the points of the two missile heads are identical. Next we analyze the algorithm of the missile head after the rotation. Depending on the angle of rotation, the rotation angle differs in different quadrant parameters, so we are divided into these four cases

Quadrant

3,4 quadrant, which rotates only plus or minus 0-180, so the 3,4 quadrant is the negative angle

We'll move him when we show the picture.

Screen.blit (missiled, (x1-width+ (x1-c[0]), y1-height/2+ (y1-c[1)))

Here (X1-WIDTH,Y1-HEIGHT/2) is actually in the (X1,Y1)

So finally we add the relevant algorithm code, the effect is more perfect

Complete, and finally attach the entire algorithm code

1 ImportPygame,sys2  fromMathImport*3 Pygame.init ()4Font1=pygame.font.sysfont ('MICROSOFTYAHEIMICROSOFTYAHEIUI', 23)5Textc=font1.render ('*', True, (250, 0,0))6Screen=pygame.display.set_mode (800,700), 0,32)7Missile=pygame.image.load ('Element/rect1.png'). Convert_alpha ()8height=missile.get_height ()9Width=missile.get_width ()Ten pygame.mouse.set_visible (0) Onex1,y1=100,600#the initial launch position of the missile Avelocity=800#Missile Speed -time=1/1000#the length of each time slice -clock=Pygame.time.Clock () theA=() -b=() -C=() -  whileTrue: +      forEventinchpygame.event.get (): -         ifevent.type==Pygame. QUIT: + sys.exit () AClock.tick (300) atX,y=pygame.mouse.get_pos ()#get mouse position, mouse is the target to hit -Distance=sqrt (Pow (x1-x,2) +pow (y1-y,2))#Two-point distance formula -Section=velocity*time#the distance to move each time slice -Sina= (y1-y)/Distance -Cosa= (X-X1)/Distance -Angle=atan2 (Y-Y1,X-X1)#the Radian value of the segment between two points inFangle=degrees (angle)#Radian to Angle -X1,y1= (x1+section*cosa,y1-section*Sina) toMissiled=pygame.transform.rotate (missile,-(fangle)) +     if0<=-fangle<=90: -A= (WIDTH*COSA+X1-WIDTH,Y1-HEIGHT/2) theB= (a[0]+height*sina,a[1]+height*cosa) *  $     if90<-fangle<=180:Panax NotoginsengA = (X1-width, y1-height/2+height* (-cosa)) -B = (X1-width+height*sina, Y1-HEIGHT/2) the  +     if-90<=-fangle<0: AA = (X1-width+missiled.get_width (), Y1-height/2+missiled.get_height ()-height*cosa) theB = (A[0]+height*sina, y1-height/2+missiled.get_height ()) +  -     if-180<-fangle<-90: $A = (X1-width-height*sina, y1-height/2+missiled.get_height ()) $B = (x1-width,a[1]+height*cosa) -          -C = ((A[0] + b[0])/2, (A[1] + b[1])/2) the  - Screen.fill ((0,0,0))WuyiScreen.blit (missiled, (x1-width+ (x1-c[0)), y1-height/2+ (y1-c[1]))) theScreen.blit (TEXTC, (x, y))#Mouse with a red * instead -Pygame.display.update ()

A simple missile auto-tracking and real-time image rotation algorithm, Python-pygame code implementation

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.