pygame 飞机大战子弹的编写(五)让奔跑不那么累,子弹的AI实现

目标:用pygame自带的pygame.math.Vector2 悠闲的向着夕阳奔跑

Vector2 里提供了二维坐标的常用功能,列如计算距离,角度,长度等,尝试下用这个函数来算距离和偏角。

import pygame
import math
from pygame import Vector2

vect = pygame.math.Vector2
pos0 =vect (0,0)
pos1 = vect(1,1)
pos2 = vect (2,2)
dist12  = pos2 - pos1
dist01 = pos1 -pos0
angle01 = pos0.angle_to(dist01)
angle12 = pos1.angle_to(dist12)
print(angle01,angle12)

测试如上代码,原意是输出pos1的角度,pos2-pos1这条线的角度,以为结果会是 45,45,但结果是 45.0 ,0.00。

理解了一下,pos2的角度是45,pos1的角度是45,两者的差值当然是0度了。

改行代码就实现了想要的效果,输出两点间的角度。

#angle12 = pos1.angle_to(dist12)
angle12 = pos0.angle_to(dist12)
print(angle01,angle12)

因为角度都是相对于原点的,也就是(0,0),一个差值包含了坐标和角度的信息,其实就是个向量,所以从原点到该点的角度就是在笛卡尔坐标里的真实角度。由于函数自带了异常处理方法,所以不用进行上篇中分母为零的判断。也不用进行象限的判定,不用进行数学直角坐标和笛卡尔坐标的转换。

再测试一组数据来验证。对应四个象限。

import pygame
import math
from pygame import Vector2

vect = pygame.math.Vector2
pos0 = vect (0,0)
pos1 = vect(1,1.732)
pos2 = vect (-1,1.732)
pos3 = vect (-1, - 1.732)
pos4 = vect (1,-1.732)

angle01 = pos0.angle_to(pos1)
angle02 = pos0.angle_to(pos2)
angle03 = pos0.angle_to(pos3)
angle04 = pos0.angle_to(pos4)
print(pos1,pos2,pos3,pos4)
print(angle01,angle02,angle03,angle04)

输出结果:[1, 1.732] [-1, 1.732] [-1, -1.732] [1, -1.732]
59.99927221917263 120.00072778082739 -120.00072778082739 -59.99927221917263

符合预期效果。

回到游戏中来。子弹从中间发射,向着四个目标奔跑。修改main.py就行了。

完整代码如下:main.py

import pygame
from bullet import *
from sys import exit
import random
from pygame import Vector2
vect = pygame.math.Vector2
pygame.init()
#定义屏幕类
class MainScene(object):
    #初始化
    def __init__(self):
        self.size = (480,860)
        self.scene = pygame.display.set_mode(self.size)
        pygame.display.set_caption("自学飞机大战--V0.98")
        self.image = pygame.image.load('images/bg.png')
       
        self.bullet_sprite = pygame.sprite.Group()
        #子弹1方向向下
        bullet1 = Bullet()
        bullet1.set_pos(50,0)
        bullet1.set_speed(5,90)
        #子弹2 方向向上
        bullet2 = Bullet()
        bullet2.set_pos(400,680)
        bullet2.set_speed(4,270)
        #子弹3,随机,夕阳方向(0,0)(480,0)(0,860)(480,860)
        pos0 = vect (0,0)
        pos1 = vect(0,0)
        pos2 = vect (480,0)
        pos3 = vect (0, 860)
        pos4 = vect (480,860)

        pos_bullet = vect(random.randint(0,580), 300)
        angle1 = pos0.angle_to(pos1 - pos_bullet)
        angle2 = pos0.angle_to(pos2 - pos_bullet)
        angle3 = pos0.angle_to(pos3 - pos_bullet)
        angle4 = pos0.angle_to(pos4 - pos_bullet)

        bullet31 = Bullet()
        bullet31.set_pos(pos_bullet.x,pos_bullet.y)
        bullet31.set_speed(10,angle1)

        bullet32 = Bullet()
        bullet32.set_pos(pos_bullet.x,pos_bullet.y)
        bullet32.set_speed(100,angle2)

        bullet33 = Bullet()
        bullet33.set_pos(pos_bullet.x,pos_bullet.y)
        bullet33.set_speed(100,angle3)
        
        bullet34 = Bullet()
        bullet34.set_pos(pos_bullet.x,pos_bullet.y)
        bullet34.set_speed(100,angle4)

        self.bullet_sprite.add(bullet1)
        self.bullet_sprite.add(bullet2)
        # self.bullet_sprite.add(bullet3)

        self.bullet_sprite.add(bullet31)
        self.bullet_sprite.add(bullet32)
        self.bullet_sprite.add(bullet33)
        self.bullet_sprite.add(bullet34)

    #绘制各个元素
    def drawElements(self):
        self.scene.blit(self.image,(0,0))
        self.bullet_sprite.draw(self.scene)
    #处理键盘相应
    def handleEvent(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()

    #运行主程序
    def runScene(self):
        while True:
            self.drawElements()
            self.handleEvent()
            self.bullet_sprite.update()
            pygame.display.update()
            pygame.time.delay(100)



if __name__ == '__main__':
    mainScene = MainScene()
    mainScene.runScene()

程序中未考虑子弹本身的尺寸,未考虑float和int之间换算存在的偏差,所以看起来目标不是很准。设置了两个速度,速度快的,准确性高,设置了延迟,方便观察。

bullet.py

import pygame
import math
import random 

class Bullet(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load('images/enemybullet5.png')
        self.rect = self.image.get_rect()
        # self.speed = 2
        self.x_speed = 0.00
        self.y_speed = 2.00
        self.angle = 0

    def update(self):
        self.rect.x += self.x_speed
        self.rect.y += self.y_speed

    def set_pos(self,x, y):
        self.rect.x = x
        self.rect.y = y 

    def set_speed(self,speed, angle = 0):
        # self.speed = speed
        self.angle = math.pi * angle/180
        self.x_speed = speed * math.cos(self.angle)
        self.y_speed = speed * math.sin(self.angle)

 

你可能感兴趣的:(python,pygame)