pygame学习记录-做一个可以由鼠标瞄准的炮台【1】
让炮台瞄准你的鼠标的位置
目标:让炮台可以瞄准你的鼠标。
思路:如果想让炮台瞄准你的鼠标,图像肯定需要旋转,旋转就需要找到一个旋转点,这样可以不用去管炮台的旋转过程,但也可以了解;一帧流程图如下:
思路详解
先来看一下pygame中旋转后的变化:
x,y代表当前图片的pos,width,height代表着当前图片的宽和高。
旋转前:
旋转后:
我们可以发现旋转后的图片变大了,原来pygame在对图片进行选转后会出现以下的变化:
白色为旋转前的,黄色为旋转后能看到的图片,而红色边框才为旋转后图片的实际占面积的地方,所以出现了旋转后宽和高的变化。所以如果保持N点不动,然后我们去求E的角度,这是非常难求的。所以我决定保持B点不动,然后我就可以已知角E,然后求N点的位置。旋转的变化就会如下图:
A为鼠标所在位置,B为CF的中点(炮口/旋转点),已知线段CF,CD的长度,B点的坐标,便能很容易求出图片的打印点N的坐标。懒得写计算过程了,直接上完整代码:
在这里插入代码片
typing import List
import pygame
from pygame.locals import *
from sys import exit
import math
pygame.init()
screen_size = [640, 480]
screen = pygame.display.set_mode(screen_size)
background_image = pygame.image.load(r'E:\AProject\python\game\xiaoxin.jpg')
bullet_image = pygame.image.load(r'E:\AProject\python\game\bullet1.png')
move_image = pygame.image.load(r'E:\AProject\python\game\mouse.png')
my_font = pygame.font.SysFont('calibri', 32)
background_image_width = background_image.get_width()
background_image_height = background_image.get_height()
bullet_image_width = bullet_image.get_width()
bullet_image_height = bullet_image.get_height()
move_image_width = move_image.get_width()
move_image_height = move_image.get_height()
move_image_pos = [320, 240]
speed = 300
angle = 0
def pow_2(a):
"""
功能:算出a的平方
参数:a为数字
:return: a 的平方
"""
ret = math.pow(a, 2)
return ret
def get_pos(rotate_pos, width, height):
"""
描述:将image以rotate_pos(这里是指上边中点的位置)为旋转点,将image的方向始终对着鼠标的位置,
width, height为原图像的宽与高
:return:image的打印pos
"""
pos = [0, 0]
mouse_pos_x, mouse_pos_y = pygame.mouse.get_pos()
angle = math.atan2(mouse_pos_y - rotate_pos[1], mouse_pos_x - rotate_pos[0]) # angle 为弧度值
a_angle = math.degrees(angle) # d_angle 为角度
d_angle = a_angle if a_angle >= 0 else (a_angle + 360)
if 0 <= d_angle < 90:
a_angle = math.radians(d_angle)
d_angle = a_angle
pos[0] = rotate_pos[0] - height * math.cos(d_angle) - (width * math.sin(d_angle))/2
pos[1] = rotate_pos[1] - height * math.sin(d_angle) - (width * math.cos(d_angle))/2
if 90 <= d_angle < 180:
d_angle = math.radians(180 - d_angle)
pos[0] = rotate_pos[0] - (width * math.sin(d_angle))/2
pos[1] = rotate_pos[1] - (width * math.cos(d_angle))/2 - height * math.sin(d_angle)
if 180 <= d_angle < 270:
d_angle = math.radians(270 - d_angle)
pos[0] = rotate_pos[0] - (width * math.cos(d_angle))/2
pos[1] = rotate_pos[1] - (width * math.sin(d_angle))/2
if 270 <= d_angle < 360:
d_angle = math.radians(360 - d_angle)
pos[0] = rotate_pos[0] - (width * math.sin(d_angle))/2 - height * math.cos(d_angle)
pos[1] = rotate_pos[1] - (width * math.cos(d_angle))/2
return pos
def run():
direction_x = 0 # x方向的值
direction_y = 0 # y方向的值
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
pressed_keys = pygame.key.get_pressed()
mouse_pos = pygame.mouse.get_pos()
if pressed_keys[K_w]:
direction_y = -1
if pressed_keys[K_s]:
direction_y = 1
if pressed_keys[·K_a]:
direction_x = -1
if pressed_keys[K_d]:
direction_x = 1
sec = pygame.time.Clock().tick()/1000
dis = sec * speed
angle = math.atan2(mouse_pos[1] - move_image_pos[1], mouse_pos[0] - move_image_pos[0])
angle = math.degrees(angle)
dis_x = math.fabs(dis * math.cos(math.radians(angle)))
dis_y = math.fabs(dis * math.sin(math.radians(angle)))
point_new = my_font.render("*", True, (255, 0, 0))
# move_image_pos[0] += dis_x
# move_image_pos[1] += dis_y
move_image_pos_new = get_pos(move_image_pos, 106, 142)
text_pos = my_font.render("pos:{0},{1}, {2}".format(int(move_image_pos_new[0]), int(move_image_pos_new[1]), angle), True, (255, 0, 0))
move_image_new = pygame.transform.rotate(move_image, -angle - 90)
screen.blit(background_image, (0, 0))
screen.blit(move_image_new, move_image_pos_new)
screen.blit(point_new, (320, 240))
screen.blit(text_pos, (0, 100))
pygame.display.update()
while True:
run()
别说了,写博客好累。