Python每日一练:通过Pygame制作小球追踪鼠标
思路
一、通过Pygame模块绘制小球、获取鼠标焦点,设置起点为小球坐标,终点为鼠标焦点位置。
二、通过math不断分解速度V,得到横向瞬时速度Vx,纵向瞬时速度Vy。
1、全局速度:V = 800;
2、小球坐标为:(c_x, c_y);
3、鼠标焦点坐标为:(pos_x, pos_y);
由三角函数可知:Vx = V*Sinθ;
Vy = V*Cosθ;
由欧氏距离公式可知:d = sqrt((x2-x1)^2+(y2-y1)^2)可得:
小球到焦点的距离(也就是斜边)为:d = sqrt((pos_x-c_x)^2+( pos_y-c_y)^2)
所以可求出:V*Sinθ = V*(pos_x-c_x)/d→Vx
V*Cosθ = V*(pos_y-c_y)/d→Vy
最后只需要在x轴与y轴分别加上此数值,便可让小球按预定的轨迹动起来。
代码
一、模块
使用的模块有:
Pygame:用于实现动画效果
Math:用于计算上文中的计算公式
random:用于小球随机位置生成
sys:用于退出程序
import pygame import math import sys import random
二、初始化pygame
pygame.init()
三、设置窗口大小为800*800
screen = pygame.display.set_mode((800, 800))
四、设置帧率为60
clock = pygame.time.Clock()
clock.tick(60)
五、背景设置为黑色
screen.fill((0, 0, 0)) screen.fill(color='black')
六、构造小球类(用于生成多个小球)
1、小球具有的属性包括:速度speed、半径r、起点x坐标pos_x、起点y坐标pos_y
class A: def __init__(self, speed, r, pos_x, pos_y): self.speed = speed self.r = r self.pos_x = pos_x self.pos_y = pos_y
七、构造方法:绘制小球
1、需要的参数有:screen绘制的窗口,color小球的颜色
def circle(self, screen, color): pygame.draw.circle(screen, color, [self.pos_x, self.pos_y], self.r)
八、构造方法:向目标移动
1、根据上文给出的思路计算横向速度与纵向速度,分别加到小球的x坐标与y坐标上
2、需要的的参数:target_x目标x轴坐标,target_y目标y轴坐标
def track(self, target_x, target_y): m_ab = math.sqrt(math.pow(target_x - self.pos_x, 2)+math.pow(target_y - self.pos_y, 2)) sina = (target_x - self.pos_x)/m_ab cosa = (target_y - self.pos_y)/m_ab self.pos_x += self.speed/60 * sina self.pos_y += self.speed/60 * cosa
九、构造方法:绘制指向线段,使活动更明显
1、需要的参数:screen绘制的窗口,target_x目标x轴坐标,target_y目标y轴坐标
def line(self, screen, target_x, target_y): pygame.draw.line(screen, (255, 255, 255), (self.pos_x, self.pos_y), (target_x, target_y), 1)
十、构造主函数main()
1、其中for循环的作用是生成6个速度随机、半径随机、初始位置随机的小球,并将其通过面向对象的方式装在列表ab中
2、其次for迭代器是为了检测程序是否退出,用来关闭窗口
3、主迭代器是遍历ab列表中的小球实例,通过构造的各类方法从而实现目标
def main(): pygame.init() screen = pygame.display.set_mode((800, 800)) clock = pygame.time.Clock() ab = [] for i in range(6): x = random.randint(100, 700) y = random.randint(100, 700) n_r = random.randint(3, 17) n_speed = random.randint(60, 300) ab.append(A(n_speed, n_r, x, y)) while 1: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() clock.tick(60) target_x, target_y = pygame.mouse.get_pos() screen.fill((0, 0, 0)) for a in ab: a.track(target_x, target_y) a.circle(screen, (255, 255, 255)) a.line(screen, target_x, target_y) pygame.display.flip()
十一、运行程序
1、如何简单理解:if __name__ == '__main__',我看到过的最简单的一个说法是,只有当你在当前py程序中运行时,他才会发生作用,当你从其他程序引入时则不会产生效果。
if __name__ == '__main__': main()
全部代码
import pygame import math import sys import random class A: def __init__(self, speed, r, pos_x, pos_y): self.speed = speed self.r = r self.pos_x = pos_x self.pos_y = pos_y def circle(self, screen, color): pygame.draw.circle(screen, color, [self.pos_x, self.pos_y], self.r) def track(self, target_x, target_y): m_ab = math.sqrt(math.pow(target_x - self.pos_x, 2)+math.pow(target_y - self.pos_y, 2)) sina = (target_x - self.pos_x)/m_ab cosa = (target_y - self.pos_y)/m_ab self.pos_x += self.speed/60 * sina self.pos_y += self.speed/60 * cosa def line(self, screen, target_x, target_y): pygame.draw.line(screen, (255, 255, 255), (self.pos_x, self.pos_y), (target_x, target_y), 1) def main(): pygame.init() screen = pygame.display.set_mode((800, 800)) clock = pygame.time.Clock() ab = [] for i in range(6): x = random.randint(100, 700) y = random.randint(100, 700) n_r = random.randint(3, 17) n_speed = random.randint(60, 300) ab.append(A(n_speed, n_r, x, y)) while 1: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() clock.tick(60) target_x, target_y = pygame.mouse.get_pos() screen.fill((0, 0, 0)) for a in ab: a.track(target_x, target_y) a.circle(screen, (255, 255, 255)) a.line(screen, target_x, target_y) pygame.display.flip() if __name__ == '__main__': main()
最后
一个小白的理解与描述,致力于让另一个小白也看得懂,就酱。
程序虽然不是完美与标准的,但能跑得起来<手动狗头>
本文来自博客园,作者:梦月剑心,转载请注明原文链接:https://www.cnblogs.com/ldooo/p/15857854.html