news 2026/4/23 23:26:28

生成子弹的弹道——射线路径的生成

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
生成子弹的弹道——射线路径的生成

继续练手我的塔防小游戏,开发过程中用到了子弹弹道计算(一条简单的射线啦,没有考虑真实的抛物线巴拉巴拉的),结合游戏路径生成算法,就自己手搓了一个,还不错挺好用,废话不多说直接上原码诸君自便:

#!D:/Python/Python310 python
"""通过给定的屏幕rect大小和给定的两个点point_xy,point_xiyi计算弹道,生成穿越\
屏幕的路径坐标列表,当作为主程序运行时,测试鼠标点击下的任意两点的弹道生成"""
from math import *
import pygame,sys

def amo_way(wnd_rect,point_xy,point_xiyi):
sub_list=[] #两点之间的坐标子列表
x=point_xy[0]
y=point_xy[1]
xi=point_xiyi[0]
yi=point_xiyi[1]
#依据dy,dx预测屏幕边缘的终点坐标作为新的xi,yi(y=mx+d)
dx=xi-x
dy=yi-y
if dx!=0: #dx为零会出现除零错误要避免
m=dy/dx
d=y-m*x

if xi>x: #当进行X正迭代时
for xi in range(xi,wnd_rect.width):
yi=m*xi+d
#当xi迭代到终点时yi未必会到达边界(即符合下一句条件if yi<=1 or yi>=wnd_rect.height)所以要在此提前取整,迭代完毕后即可得到yi整数结果
yi=round(yi)
if yi<=1 or yi>=wnd_rect.height:
break
elif xi<x: #当进行X负迭代时
for xi in range(xi,0,-1):
yi=m*xi+d
#当xi迭代到终点时yi未必会到达边界(即符合下一句条件if yi<=1 or yi>=wnd_rect.height)所以要在此提前取整,迭代完毕后即可得到yi整数结果
yi=round(yi)
if yi<=1 or yi>=wnd_rect.height:
break
elif xi==x:#当是一条90度的垂直线时
if yi>y:yi=wnd_rect.height
else: yi=0

#通过新的xi,yi 计算弹道
#print(xi,yi) #test usesing
dx=abs(xi-x)
dy=abs(yi-y)
s1=1 if xi>x else -1 #依据起点与终点坐标值大小进行x方向的步进值设置
s2=1 if yi>y else -1 #依据起点与终点坐标值大小进行y方向的步进值设置
interchange=0
if(dy>dx): #当线条的斜率大于1时(对Y方向做步进)交换dx与dy 则X=my+d
dx=dx^dy #不用中间变量交换两个值(C++实验有序二叉树),
#A=a,B=b,通过a^b给A 再通过A^b得到a=>B,再通过A^a得到a=>A
dy=dx^dy
dx=dx^dy
interchange=1 #表示斜率大于1,此时做Y方向的递增推导即对Y迭代Y+=1
else:interchange=0
p=2*dy-dx #初始化决策参数P0项
for i in range(1,dx+1):
sub_list.append((x,y))
if(p>=0):#表示DOWN>UP Y/X取真坐标值的向上取整坐标的点
if interchange==0:#当进行X方向递推时
y+=s2 #当斜率小于1时做X方向的递推求对应的Y值P>0时Y=Y+1
else: x+=s1 #当斜率大于1时做Y方向的递推求对应的X值P>0时X=X+1

p-=2*dx #决策参数的递推公式公式当P(i)>=0时由公式:P(i+1)=Pi+2dy-2dx[Y(i+1)-Yi]
#可知此处(Y(i+1)-Y(i))==1即P(i+1)=Pi+2dy-2dx(此处是后半部分表达式)

if interchange==0: #当interchange==0时表示进行X递增
x+=s1 #
else: y+=s2 #当interchange==1时表示进行Y的递增
p+=2*dy #当P(i)<0时Y(i+1)-Y(i)==0此处有P(i+1)=Pi+2dy(此处是部分表达式前半部分,当P>0时与上式拼接)
#print(sub_list) #test usering
return sub_list

def mak_amo_way(wnd_rect,point_xy,point_xiyi):
"""该函数通过给定起点坐标和终点坐标,在指定的矩形中生成一个射线"""
way_list=[] #两点之间的坐标子列表
pos_list=amo_way(wnd_rect,point_xy,point_xiyi)#pos_list为一个暂存变量
way_list=pos_list[0::10]+[pos_list[-1]] #必须包含第一个点加最后一个点

return way_list



def hy_main():
#设置地图的大小及图片文件名称
size_str=input("Input the window size format x,y:")
size_list=size_str.split(',')
wnd_width=int(size_list[0])
wnd_heigh=int(size_list[1])

#定义路径列表
way_point_list=[]
trajectory_list=[]#弹道坐标列表
choose=False #第一次点击鼠标左键时变为True,当为False 时移动鼠标不画线
pygame.init()
#游戏刷新率时间参数的建立
game_clock=pygame.time.Clock()
mainwnd=pygame.display.set_mode((wnd_width,wnd_heigh))
pygame.display.set_caption("amo_way_module")
#主窗口对象填充为白色
mainwnd.fill("black")
wnd_rect=pygame.Rect(0,0,wnd_width,wnd_heigh)


while True:
#游戏刷新率的设置
game_clock.tick(60)

# 循环获取事件,监听事件
for event in pygame.event.get():
# 判断用户是否点了关闭按钮
if event.type == pygame.QUIT:
#卸载所有模块
pygame.quit()
#终止程序
sys.exit()
elif event.type==pygame.MOUSEBUTTONDOWN:
if pygame.mouse.get_pressed()==(1,0,0):#左键按下时开始确定记录第一个点
if choose==False:
pos_xy=pygame.mouse.get_pos()
way_point_list+=(pos_xy),
choose=True#为True则证明至少有一个点被存储
else:#choose==True已经选择了两个点,开始调用amo_way
way_point_list+=(pos_xy),
#trajectory_list弹道列表
trajectory_list=amo_way(wnd_rect,way_point_list[0],way_point_list[1])
#print(way_point_list)#test code
way_point_list.clear()
choose=False

elif pygame.mouse.get_pressed()==(0,0,1): #右键按下时,取消上一个点
try:
way_point_list.pop()
except IndexError:
if len(way_point_list)<1:
choose=False
elif event.type==pygame.MOUSEMOTION and choose: #鼠标移动
pos_xy=pygame.mouse.get_pos()

for cur_xy in iter(trajectory_list):
mainwnd.set_at(cur_xy,"white")


pygame.display.flip() #显示
if __name__=="__main__":hy_main()

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 15:28:30

5分钟掌握G-Helper:华硕笔记本性能调校终极指南

5分钟掌握G-Helper&#xff1a;华硕笔记本性能调校终极指南 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops. Control tool for ROG Zephyrus G14, G15, G16, M16, Flow X13, Flow X16, TUF, Strix, Scar and other models 项目地址: htt…

作者头像 李华
网站建设 2026/4/19 17:38:30

AI读脸术效果惊艳!看它如何准确识别明星年龄

AI读脸术效果惊艳&#xff01;看它如何准确识别明星年龄 1. 技术背景与核心价值 在人工智能快速发展的今天&#xff0c;人脸属性分析正成为计算机视觉领域的重要应用方向。从安防监控到智能营销&#xff0c;从社交娱乐到个性化推荐&#xff0c;对人脸性别、年龄等属性的自动识…

作者头像 李华
网站建设 2026/4/23 13:22:41

G-Helper性能调优实战:华硕笔记本硬件控制的终极解决方案

G-Helper性能调优实战&#xff1a;华硕笔记本硬件控制的终极解决方案 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops. Control tool for ROG Zephyrus G14, G15, G16, M16, Flow X13, Flow X16, TUF, Strix, Scar and other models 项目…

作者头像 李华
网站建设 2026/4/20 17:29:06

Holistic Tracking影视制作应用:低成本动捕系统搭建

Holistic Tracking影视制作应用&#xff1a;低成本动捕系统搭建 1. 引言&#xff1a;AI 全身全息感知的现实落地 在影视、动画与虚拟内容创作领域&#xff0c;动作捕捉技术长期被视为高成本、高门槛的专业工具。传统光学动捕系统依赖昂贵的专用设备和复杂的标定流程&#xff…

作者头像 李华
网站建设 2026/4/21 20:15:22

华硕笔记本性能调优神器:GHelper让你的设备更懂你

华硕笔记本性能调优神器&#xff1a;GHelper让你的设备更懂你 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops. Control tool for ROG Zephyrus G14, G15, G16, M16, Flow X13, Flow X16, TUF, Strix, Scar and other models 项目地址: h…

作者头像 李华
网站建设 2026/4/23 18:35:27

GHelper终极指南:免费解锁华硕笔记本隐藏性能的完整教程

GHelper终极指南&#xff1a;免费解锁华硕笔记本隐藏性能的完整教程 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops. Control tool for ROG Zephyrus G14, G15, G16, M16, Flow X13, Flow X16, TUF, Strix, Scar and other models 项目地…

作者头像 李华