简体   繁体   English

Pygame子弹从A点到B点的运动

[英]Pygame bullet motion from point A to point B

I am trying to make a game with a python library called ' Pygame ' (v1.9.2) and I have made a character for the player. 我正在尝试使用名为' Pygame '(v1.9.2)的python库进行游戏,并为玩家制作了一个角色。 This character is supposed to "shoot" "bullets" or "spells" to the point of mouse_pos and what I need help with is that the "bullet" has a constant speed assigned to 1 self.speed = 1 , if I try to increase the speed it will cause a flickering effect when the bullet reaches mouse_pos because self.pos will either be higher or lower than mouse_pos. 这个角色应该“射击”“子弹”或“法术”到mouse_pos点,我需要帮助的是“子弹”的恒定速度分配给1 self.speed = 1 ,如果我试图增加当子弹到达mouse_pos时,它将导致闪烁效果的速度,因为self.pos将高于或低于mouse_pos。

How can I make this bullet go quickly & smooth like a bullet and still get to the exact point where mouse_pos is set? 如何使子弹像子弹一样快速平滑地移动到仍然设置mouse_pos的确切位置?

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

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

related code is inside update() function 相关代码在update()函数内
Sprites.py (Spell/Bullet class) Sprites.py(法术/子弹类)

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()

If your bullet goes so fast that it passes through the target, you might want to test if the line between the bullets current point an its last point intersect with your target. 如果你的子弹速度太快以至于它穿过目标,你可能想要测试子弹之间的线是否指向它的最后一个点与你的目标相交。

A bit more detail is available here: https://gamedev.stackexchange.com/questions/18604/how-do-i-handle-collision-detection-so-fast-objects-are-not-allowed-to-pass-thro 这里有更多详细信息: https//gamedev.stackexchange.com/questions/18604/how-do-i-handle-collision-detection-so-fast-objects-are-not-allowed-to-pass-救援人员到场

The Pythagorean Theorem tells the distance between points in n-dimensional space. 毕达哥拉斯定理描述了n维空间中点之间的距离。 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, with different speeds at different angles. 这不是一个很好的解决方案,因为子弹将不切实际地移动,在不同角度具有不同的速度。 In fact it will move at sqrt(2) speed at a 45' angle and with a speed of 1 at 90'. 实际上,它将以45英尺的角度以sqrt(2)的速度移动,并且以90'的速度以1的速度移动。

But, I assume you don't want a trigonometry lecture. 但是,我假设你不想要三角学讲座。

EDIT: Here's the trigonometry lecture. 编辑:这是三角学讲座。 Your program will move the bullet realistically because it moves it by the full speed in both the x and y direction. 你的程序将实际移动子弹,因为它在x和y方向上以全速移动它。 What you need to do is to have the speed be slower in both directions, such that the hypotenuse of the triangle that the x-speed and y-speed (vectors) form is equal to 1. Since the speed is always 1, this triangle, just happens to be the unit circle. 你需要做的是让速度在两个方向都慢,这样x速度和y速度(矢量)形成的三角形的斜边等于1.由于速度总是1,这个三角形,恰好是单位圈。

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

If your character is at p, and the mouse is at m, then you find the angle between them labeled here as A. Then the x-speed will be the cosine of A and the y-speed will be the sine of A. 如果你的角色位于p,并且鼠标位于m,那么你会发现它们之间的角度标记为A.然后x速度将是A的余弦值,y速度将是A的正弦值。

How do you find the angle? 你怎么找到这个角度? you use the arctangent... in fact, here's the code to use. 你使用arctangent ...事实上,这是使用的代码。

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 more like that. 或类似的东西。 I may have my symbols mixed up. 我的符号可能会混淆。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM