如何旋转精灵并将子弹射向鼠标位置

如何旋转精灵并将子弹射向鼠标位置

本文介绍了如何旋转精灵并将子弹射向鼠标位置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目标是让一些子弹从玩家的当前位置射出,然后让它们沿直线移动,该直线由一个向量定义,该向量由单击按钮时鼠标位置的点定义和玩家的位置,但是当按下按钮时什么也没有发生.谁能告诉我这段代码有什么问题?谢谢

导入pygame导入数学pygame.init()赢 = pygame.display.set_mode((500,500))pygame.display.set_caption("太空射手")char = pygame.image.load("spaceship_sprite.png")x = 500/2y = 500/2宽度 = 50高度 = 50速度 = 6list_of_bullets = []def point_to_mouse(x,y,char):mouse_x, mouse_y = pygame.mouse.get_pos()vector_x, vector_y = mouse_x - x, mouse_y - y角度 = (180/math.pi) * -math.atan2(vector_y, vector_x) - 90更新图像 = pygame.transform.rotate(char,int(angle))image_location = updated_image.get_rect(center= (x,y))win.blit(updated_image,image_location)def update_game(x,y,width,height,char):win.fill((0,0,0))point_to_mouse(x,y,char)pygame.display.update()def spawn_bullet(x,y):全局 list_of_bullets初始_x = x初始_y = ymouse_x, mouse_y = pygame.mouse.get_pos()vector_x, vector_y = mouse_x - x, mouse_y - y#归一化向量距离 = math.sqrt(vector_x ** 2 + vector_y **2)normalized_vec = (vector_x/距离,vector_y/距离)list_of_bullets.append([initial_x,initial_y,normalized_vec])运行 = 真运行时:#检查事件pygame.time.delay(75)对于 pygame.event.get() 中的事件:如果 event.type == pygame.QUIT:运行 = 错误如果 event.type == pygame.MOUSEBUTTONDOWN:spawn_bullet(x,y)list_of_bullets 中的项目符号:子弹[0] = 子弹[0] * 子弹[2][0]子弹[1] = 子弹[1] * 子弹[2][1]pygame.draw.rect(win,(0,0,255),(int(bullet[0]),int(bullet[1]),20,20))如果子弹[0] >500 或子弹 [0] 500:del list_of_bullets[list_of_bullets.index(bullet)]继续键 = pygame.key.get_pressed()如果键 [pygame.K_LEFT] 和 x >0 + 宽度:x = x - 速度elif 键[pygame.K_RIGHT] 和 x 0 + 宽度:y = y - 速度elif 键[pygame.K_DOWN] 和 y 
解决方案

有 2 个问题.子弹的当前位置乘以其归一化的方向向量.这没有意义:

用于 list_of_bullets 中的项目符号:子弹[0] = 子弹[0] * 子弹[2][0]子弹[1] = 子弹[1] * 子弹[2][1]

将方向向量添加到子弹的位置:

用于 list_of_bullets 中的项目符号:子弹[0] += 子弹[2][0]子弹[1] += 子弹[2][1]

如果你想提高子弹的速度,那么你必须将向量缩放一定的speed.例如:

def spawn_bullet(x,y):全局 list_of_bullets初始_x = x初始_y = ymouse_x, mouse_y = pygame.mouse.get_pos()vector_x, vector_y = mouse_x - x, mouse_y - y距离 = math.sqrt(vector_x ** 2 + vector_y **2)速度 = 5move_vec = (速度*vector_x/距离,速度*vector_y/距离)list_of_bullets.append([initial_x, initial_y, move_vec])


第二个问题是,在绘制子弹后,显示会被清除,因此您将永远不会看到"子弹.

清除显示后在update_game中绘制子弹:

def update_game(x,y,width,height,char):win.fill((0,0,0))list_of_bullets 中的项目符号:pygame.draw.rect(win,(0,0,255),(int(bullet[0]),int(bullet[1]),20,20))point_to_mouse(x,y,char)pygame.display.update()

(删除主应用循环的绘图)


最小示例:

导入数学导入pygamedef blit_point_to_mouse(target_surf, char_surf, x, y):mouse_x, mouse_y = pygame.mouse.get_pos()vector_x, vector_y = mouse_x - x, mouse_y - y角度 = (180/math.pi) * -math.atan2(vector_y, vector_x) - 90旋转表面 = pygame.transform.rotate(char_surf, round(angle))旋转表面位置=旋转表面.get_rect(中心=(x,y))target_surf.blit(rotated_surface,rotated_surface_location)def spawn_bullet(list_of_bullets, x, y):mouse_x, mouse_y = pygame.mouse.get_pos()vector_x, vector_y = mouse_x - x, mouse_y - y距离 = math.hypot(vector_x, vector_y)如果距离== 0:返回速度 = 5move_vec = (速度 * vector_x/距离,速度 * vector_y/距离)list_of_bullets.append([x, y, move_vec])pygame.init()窗口 = pygame.display.set_mode((500,500))时钟 = pygame.time.Clock()火箭 = pygame.image.load('Rocket64.png')Rocket_rect = Rocket.get_rect(center = window.get_rect().center)速度 = 6list_of_bullets = []子弹 = pygame.Surface((20, 20), pygame.SRCALPHA)pygame.draw.circle(bullet, (64, 64, 64), (10, 10), 10)pygame.draw.circle(bullet, (96, 96, 96), (10, 10), 9)pygame.draw.circle(bullet, (128, 128, 128), (9, 9), 7)pygame.draw.circle(bullet, (160, 160, 160), (8, 8), 5)pygame.draw.circle(bullet, (192, 192, 192), (7, 7), 3)pygame.draw.circle(bullet, (224, 224, 224), (6, 6), 1)运行 = 真运行时:时钟滴答(60)对于 pygame.event.get() 中的事件:如果 event.type == pygame.QUIT:运行 = 错误如果 event.type == pygame.MOUSEBUTTONDOWN:spawn_bullet(list_of_bullets,*rocket_rect.center)对于 list_of_bullets 中的 bullet_pos:子弹位置[0] += 子弹位置[2][0]子弹位置[1] += 子弹位置[2][1]如果不是 (0 <= bullet_pos[0] < window.get_width() 和 0 < bullet_pos[1] < window.get_height()):del list_of_bullets[list_of_bullets.index(bullet_pos)]继续键 = pygame.key.get_pressed()Rocket_rect.x += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * 速度Rocket_rect.y += (keys[pygame.K_UP] - keys[pygame.K_DOWN]) * 速度Rocket_rect.clamp_ip(window.get_rect())window.fill(0)对于 list_of_bullets 中的 bullet_pos:window.blit(bullet, bullet.get_rect(center = (round(bullet_pos[0]),round(bullet_pos[1]))))blit_point_to_mouse(窗口,火箭,*rocket_rect.center)pygame.display.flip()pygame.quit()出口()

The objective was to make some bullets come out of the current position of the player and then have them move in a straight line, defined by a vector that is defined by the points of the mouse position at the time of clicking the button and the position of the player, but when the button is pressed nothing happens. Can anyone tell me whats wrong with this code? Thank you

import pygame
import math
pygame.init()
win = pygame.display.set_mode((500,500))
pygame.display.set_caption("Space Shooter")
char = pygame.image.load("spaceship_sprite.png")

x = 500/2
y = 500/2
width = 50
height = 50
velocity = 6
list_of_bullets = []

def point_to_mouse(x,y,char):
    mouse_x, mouse_y = pygame.mouse.get_pos()
    vector_x, vector_y = mouse_x - x, mouse_y - y
    angle = (180 / math.pi) * -math.atan2(vector_y, vector_x) - 90
    updated_image = pygame.transform.rotate(char,int(angle))
    image_location = updated_image.get_rect(center= (x,y))
    win.blit(updated_image,image_location)

def update_game(x,y,width,height,char):
    win.fill((0,0,0))
    point_to_mouse(x,y,char)
    pygame.display.update()

def spawn_bullet(x,y):
    global list_of_bullets
    initial_x = x
    initial_y = y
    mouse_x, mouse_y = pygame.mouse.get_pos()
    vector_x, vector_y = mouse_x - x, mouse_y - y
    #normalize the vector
    distance = math.sqrt(vector_x ** 2 + vector_y **2)
    normalized_vec = (vector_x/ distance, vector_y/distance)
    list_of_bullets.append([initial_x,initial_y,normalized_vec])


run = True
while run:
    #check for an event
    pygame.time.delay(75)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        if event.type == pygame.MOUSEBUTTONDOWN:
            spawn_bullet(x,y)

    for bullet in list_of_bullets:
        bullet[0] = bullet[0] * bullet[2][0]
        bullet[1] = bullet[1] * bullet[2][1]

        pygame.draw.rect(win,(0,0,255),(int(bullet[0]),int(bullet[1]),20,20))

        if bullet[0] > 500 or bullet[0] < 0 or bullet[1] < 0 or bullet[1] > 500:
            del list_of_bullets[list_of_bullets.index(bullet)]
            continue



    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT] and x > 0 + width:
        x = x - velocity
    elif keys[pygame.K_RIGHT] and x < 500 - width:
        x = x + velocity
    elif keys[pygame.K_UP] and y > 0 + width:
        y = y - velocity
    elif keys[pygame.K_DOWN] and y < 500 - width:
        y = y + velocity


    update_game(x,y,width,height,char)

pygame.quit()
解决方案

There are 2 issues. The current position of the bullets is multiplied by its the normalized direction vector. That doesn't make sense:

Add the direction vector to the position of the bullet:

for bullet in list_of_bullets:
    bullet[0] += bullet[2][0]
    bullet[1] += bullet[2][1]

If you want to increase the speed of the bullets, then you've to scale the vector by a certain speed. e.g.:

def spawn_bullet(x,y):
    global list_of_bullets
    initial_x = x
    initial_y = y
    mouse_x, mouse_y = pygame.mouse.get_pos()
    vector_x, vector_y = mouse_x - x, mouse_y - y

    distance = math.sqrt(vector_x ** 2 + vector_y **2)
    speed = 5
    move_vec = (speed*vector_x/distance, speed*vector_y/distance)

    list_of_bullets.append([initial_x, initial_y, move_vec])


The 2nd issue is, that the display is cleared, after the bullets are draw, so you'll never "see" the bullets.

Draw the bullets in update_game after the display is cleared:

def update_game(x,y,width,height,char):
    win.fill((0,0,0))
    for bullet in list_of_bullets:
        pygame.draw.rect(win,(0,0,255),(int(bullet[0]),int(bullet[1]),20,20))
    point_to_mouse(x,y,char)
    pygame.display.update()

(Delete the drawing for the main application loop)


Minimal example:

import math
import pygame

def blit_point_to_mouse(target_surf, char_surf, x, y):
    mouse_x, mouse_y = pygame.mouse.get_pos()
    vector_x, vector_y = mouse_x - x, mouse_y - y
    angle = (180 / math.pi) * -math.atan2(vector_y, vector_x) - 90
    rotated_surface = pygame.transform.rotate(char_surf, round(angle))
    rotated_surface_location = rotated_surface.get_rect(center = (x, y))
    target_surf.blit(rotated_surface, rotated_surface_location)

def spawn_bullet(list_of_bullets, x, y):
    mouse_x, mouse_y = pygame.mouse.get_pos()
    vector_x, vector_y = mouse_x - x, mouse_y - y
    distance = math.hypot(vector_x, vector_y)
    if distance == 0:
        return
    speed = 5
    move_vec = (speed * vector_x / distance, speed * vector_y / distance)
    list_of_bullets.append([x, y, move_vec])

pygame.init()
window = pygame.display.set_mode((500,500))
clock = pygame.time.Clock()

rocket = pygame.image.load('Rocket64.png')
rocket_rect = rocket.get_rect(center = window.get_rect().center)
velocity = 6
list_of_bullets = []
bullet = pygame.Surface((20, 20), pygame.SRCALPHA)
pygame.draw.circle(bullet, (64, 64, 64), (10, 10), 10)
pygame.draw.circle(bullet, (96, 96, 96), (10, 10), 9)
pygame.draw.circle(bullet, (128, 128, 128), (9, 9), 7)
pygame.draw.circle(bullet, (160, 160, 160), (8, 8), 5)
pygame.draw.circle(bullet, (192, 192, 192), (7, 7), 3)
pygame.draw.circle(bullet, (224, 224, 224), (6, 6), 1)

run = True
while run:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        if event.type == pygame.MOUSEBUTTONDOWN:
            spawn_bullet(list_of_bullets, *rocket_rect.center)

    for bullet_pos in list_of_bullets:
        bullet_pos[0] += bullet_pos[2][0]
        bullet_pos[1] += bullet_pos[2][1]
        if not (0 <= bullet_pos[0] < window.get_width() and 0 < bullet_pos[1] < window.get_height()):
            del list_of_bullets[list_of_bullets.index(bullet_pos)]
            continue

    keys = pygame.key.get_pressed()
    rocket_rect.x += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * velocity
    rocket_rect.y += (keys[pygame.K_UP] - keys[pygame.K_DOWN]) * velocity
    rocket_rect.clamp_ip(window.get_rect())

    window.fill(0)
    for bullet_pos in list_of_bullets:
        window.blit(bullet, bullet.get_rect(center = (round(bullet_pos[0]),round(bullet_pos[1]))))
    blit_point_to_mouse(window, rocket, *rocket_rect.center)
    pygame.display.flip()

pygame.quit()
exit()

这篇关于如何旋转精灵并将子弹射向鼠标位置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-01 15:18