pygame 模拟导弹发送代码(上)

编程/开发
399
0
0
2022-10-11

此作品想法来自一位学生,一开始只是帮助他解决一个问题。

img

img

隔了一天,他已经做出下面的效果了。

img

img

代码也写了一些。

img

现在碰到问题了,想要实现鼠标点击灰色圆圈发射导弹。

img

提示他利用区域检测(之前做游戏地图按钮类似的方法 生成游戏地图文件)。

实现后,开始有了新的想法,想要模拟导弹发射出去的效果,有重力影响,可以调节角度和力度。

找了之前 GUI 做的游戏给他看,问是不是类似这种效果的。

img

确定没问题,后面难度主要在于解决角度问题。

详细过程就不写了,看代码,主要都是一些绘制的代码,射击到目标物体检测,以及自动根据目标物调整角度和力度射击等还没写。

最终效果也是慢慢加出来的。

抛物线效果

img

坐标系

img

角度控制条

img

速度控制条

img

速度,角度数值实时显示

img

前进距离高度显示

img

目标物显示以及瞄准器效果

img

源代码:

import math
import pygame
import random
# 初始化pygame
pygame.init()
# # 设置窗口的大小,单位为像素
screen_x, screen_y = 1200, 500
screen = pygame.display.set_mode((1200, 500))
# # 设置窗口标题
pygame.display.set_caption('海上战舰')
my_font = pygame.font.SysFont("arial", 20)
my_font2 = pygame.font.SysFont("arial", 14)
load = "素材/"
pic = {"ship_dark_W.png": pygame.image.load(f"{load}ship_dark_W.png"),
       "ship_light_E.png": pygame.image.load(f"{load}ship_light_E.png"),
       "ship_wreck_W.png": pygame.image.load(f"{load}ship_wreck_W.png"),
       "ship_wreck_E.png": pygame.image.load(f"{load}ship_wreck_E.png"),
       "background": pygame.image.load(f"{load}uncolored_piramids.png"),
       "ammo_rocket.png": pygame.transform.scale(pygame.image.load(f"{load}ammo_rocket.png"),(15,10)),
       "ammo_rocketModern.png": pygame.transform.scale(pygame.image.load(f"{load}ammo_rocketModern.png"),(71,27)),
       "ammo_machinegun.png": pygame.image.load(f"{load}ammo_machinegun.png")}
gray = (96, 96, 96)
fire = False
bullet_x = 180
bullet_y = 330
speed = 20
angle = 30
new_angle = angle
speed_x = speed*math.cos(math.pi*angle/180)
speed_y = -speed*math.sin(math.pi*angle/180)
gravity = 0.5
points = []

target_x = random.randint(900,1150)
target_y = 350
clock = pygame.time.Clock()
# 程序主循环
while True:
    # 获取事件 
    for event in pygame.event.get():
        # 判断事件是否为退出事件 
        if event.type == pygame.QUIT:
            # 退出pygame
            pygame.quit()
            # 退出系统
            exit()

    # 按钮侦测
    pos = pygame.mouse.get_pos()
    if 50<pos[0]<150 and 375<pos[1]<475:
        if pygame.mouse.get_pressed(3)[0]:
            fire = True

    # 调整角度 
    if pygame.mouse.get_pressed(3)[2]:
        angle = (pos[0]-200)//2 
        if angle<=0:
            angle = 0 
        elif angle>=90:
            angle=90

        speed_x = speed * math.cos(math.pi * angle / 180)
        speed_y = -speed * math.sin(math.pi * angle / 180)

    # 调整速度 
    if pygame.mouse.get_pressed(3)[1]:
        speed = (pos[0]-200)//3 
        if speed<=10:
            speed = 10 
        elif speed>=60:
            speed=60
        speed_x = speed * math.cos(math.pi * angle / 180)
        speed_y = -speed * math.sin(math.pi * angle / 180)

    # 按下按钮发射导弹 
    if fire:
        bullet_x += speed_x
        bullet_y += speed_y
        points.append((bullet_x,bullet_y))
        speed_y += gravity
        angle = math.degrees(math.atan2(-speed_y, speed_x))
        if bullet_y >=500:
            points=[]
            fire = False
            bullet_x = 180
            bullet_y = 330
            speed = 20
            angle = 30
            speed_x = speed * math.cos(math.pi * angle / 180)
            speed_y = -speed * math.sin(math.pi * angle / 180)
            gravity = 0.5

    p = pygame.transform.rotate(pic["ammo_rocketModern.png"],angle)
    pos = p.get_rect(center=(bullet_x,bullet_y))

    # 画背景
    screen.blit(pic["background"], (0, 0))
    # 画自己方船
    screen.blit(pic["ship_light_E.png"], (50, 255))
    # 创建按钮
    pygame.draw.circle(screen, gray, (100, 425), 50)
    screen.blit(pic["ammo_machinegun.png"], (85, 390))
    # 绘制坐标系 
    # speed_y绘制
    text_speed_y = my_font2.render(f"speed_y:{int(speed_y)}", True, (0, 0, 0))
    screen.blit(text_speed_y, (bullet_x-80,bullet_y-70))
    pygame.draw.line(screen,(255,0,0),(bullet_x,bullet_y),(bullet_x,bullet_y-100),3)
    # speed_x绘制
    text_speed_x = my_font2.render(f"speed_x:{int(speed_x)}", True, (0, 0, 0))
    screen.blit(text_speed_x, (bullet_x,bullet_y+30))
    pygame.draw.line(screen, (255, 0, 0), (bullet_x, bullet_y), (bullet_x+100, bullet_y),3)
    # 绘制导弹
    screen.blit(p,pos)
    # 角度滑块显示
    text1 = my_font.render(f"angle:{int(angle)}", True, (255, 0, 0))
    screen.blit(text1, (400, 85))
    pygame.draw.line(screen, (255, 0, 0), (200, 100), (20, 100), 3)
    pygame.draw.line(screen, (40, 40, 40), (200, 100), (200 +90*2, 100),3)
    pygame.draw.circle(screen,(0,255,0),(200+angle*2,100),10)
    # 速度滑块显示
    text2 = my_font.render(f"speed:{speed}", True, (255, 0, 0))
    screen.blit(text2, (400, 135))
    pygame.draw.line(screen, (40, 40, 40), (200, 150), (200 +60*3, 150),3)
    pygame.draw.circle(screen,(255,0,0),(200+speed*3,150),10)
    # 轨迹 
    if len(points)>2 and fire==True:
        # pygame.draw.polygon(screen,(255,0,0),points,2)
        pygame.draw.aalines(screen, (255, 0, 0), False,points, 2)

    # 绘制前进距离与上升高度
    distance_y = my_font.render(f"distance_y:{int(abs(bullet_y-330))}", True, (255, 0, 0))
    screen.blit(distance_y, (1000, 10))
    distance_x = my_font.render(f"distance_x:{int(abs(bullet_x-180))}", True, (255, 0, 0))
    screen.blit(distance_x, (1000, 40))
    # 绘制目标物体
    pygame.draw.circle(screen,gray,(target_x,target_y),30)
    pygame.draw.circle(screen, (255, 0, 0),(target_x,target_y),20,1)
    pygame.draw.line(screen,  (255, 0, 0), (target_x-20,target_y),(target_x+20,target_y),1)
    pygame.draw.line(screen,  (255, 0, 0), (target_x,target_y-20),(target_x,target_y+20),1)

    # 刷新屏幕
    pygame.display.update()
    clock.tick(10)

(全文完)