Pygame bullet movement from point A to point B

I am trying to create a game with a library python

called " Pygame

" (v1.9.2) and I have made a character for the player. This character has to "shoot" "bullets" or "spells" at the point mouse_pos

, and I need help getting the "bullet" to have a constant velocity set to 1 self.speed = 1

, if I try to increase the velocity it will have a flickering effect when the bullet reaches mouse_pos. because self.pos will be either above or below mouse_pos.

How can I make this bullet fast and smooth like a bullet and get to the point where mouse_pos is set?

Example with self.speed = 1
https://media.giphy.com/media/AAifrctxHHQbe/giphy.gif

Example with self.speed = 2
http://4.1m.yt/d_TmNNq.gif

the related code is inside the update ()
function of Sprites.py (spell / bullet class)

class Spell(pygame.sprite.Sprite):
    def __init__(self,game,x,y,spelltype,mouse_pos):
        pygame.sprite.Sprite.__init__(self)
        self.game = game
        self.width = TILESIZE
        self.height = TILESIZE
        self.type = spelltype
        self.effects = [
                'effect_'+self.type+'_00',
                'effect_'+self.type+'_01',
                'effect_'+self.type+'_02'
        ]
        self.image = pygame.image.load(path.join(IMG_DIR,"attack/attack_"+self.type+".png")).convert_alpha()
        self.image = pygame.transform.scale(self.image,(self.width,self.height))
        self.rect = self.image.get_rect()
        self.rect.x = x+self.width
        self.rect.y = y+self.height
        self.speed = 1
        self.mouse_pos = mouse_pos
        self.idx = 0

    def update(self):
        if not self.rect.collidepoint(self.mouse_pos):
            if self.mouse_pos[0] < self.rect.x:
                self.rect.x -= self.speed
            elif self.mouse_pos[0] > self.rect.x:
                self.rect.x += self.speed

            if self.mouse_pos[1] < self.rect.y:
                self.rect.y -= self.speed
            elif self.mouse_pos[1] > self.rect.y:
                self.rect.y += self.speed
        else:
            self.image = pygame.image.load(path.join(IMG_DIR,"effects/"+self.effects[self.idx]+".png"))
            self.idx += 1
            if self.idx >= len(self.effects):
                self.kill()

      

+3


source to share


2 answers


If your bullet is traveling so fast that it goes through the target, you may need to check if the line between the current points crosses the marker and the last point intersects with your target.



More information is available here: https://gamedev.stackexchange.com/questions/18604/how-do-i-handle-collision-detection-so-fast-objects-are-not-allowed-to-pass-thro

+2


source


The Pythagorean theorem says the distance between points in n-dimensional space. For your case

distance = math.sqrt(sum[ (self.mouse_pos[0] - self.rect.x) ** 2 
                        , (self.mouse_pos[1] - self.rect.y) ** 2
                        ]))
if distance < self.speed: 
    #remove the bullet from the scene

      

This is not a great solution, because the bullet will move unrealistically, at different speeds at different angles. In fact, it will move at a speed of sqrt (2) at an angle of 45 feet and at a speed of 1 at 90 Β°.

But I suppose you don't need a trigonometry lecture.

EDIT: Here's a lecture on trigonometry. Your program will move the bullet realistically because it moves it at full speed in both the x and y directions. You need to make the speed slower in both directions, so the hypotenuse of the triangle is that the shape of the x speed and the y-speed (vectors) are 1. Since the speed is always 1, this triangle just turns out to be a unit circle.



       m
       |\
       | \
sin(A) |  \ This speed is 1
       |   \
       |   A\
       ------p
        cos(A)

      

If your character is at point p and your mouse is at point m, then you will find the angle between them, denoted here as A. Then the x-speed will be the cosine of A, and the y-speed will be the sine of a.

How do you find the angle? you're using arctangent ... actually, here's the code to use.

import math
if not self.rect.collidepoint(self.mouse_pos):
        angle = math.atan2( (self.mouse_pos[1] - self.rect.y)
                          , (self.mouse_pos[0] - self.rect.x)
        self.rect.x += self.speed * math.cos(angle)
        self.rect.y += self.speed * math.sin(angle)

      

or something similar. Perhaps my symbols are confused.

+2


source







All Articles