此作品想法来自一位学生,一开始只是帮助他解决一个问题。
隔了一天,他已经做出下面的效果了。
代码也写了一些。
现在碰到问题了,想要实现鼠标点击灰色圆圈发射导弹。
提示他利用区域检测(之前做游戏地图按钮类似的方法 生成游戏地图文件)。
实现后,开始有了新的想法,想要模拟导弹发射出去的效果,有重力影响,可以调节角度和力度。
找了之前 GUI 做的游戏给他看,问是不是类似这种效果的。
确定没问题,后面难度主要在于解决角度问题。
详细过程就不写了,看代码,主要都是一些绘制的代码,射击到目标物体检测,以及自动根据目标物调整角度和力度射击等还没写。
最终效果也是慢慢加出来的。
抛物线效果
坐标系
角度控制条
速度控制条
速度,角度数值实时显示
前进距离高度显示
目标物显示以及瞄准器效果
源代码:
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)
(全文完)