在 Pygame 中沿角度方向移动 Sprite [英] Moving a Sprite in the direction of an angle in Pygame
问题描述
我试图在 pygame 中的某个角度方向上移动精灵,使用 left &向右箭头键可以改变精灵的方向,但是当我按下向上键时,精灵只是向右移动.我有 2 个变量来计算速度和速度并将它们加在一起(vel_x & vel_y),然后我将它添加到精灵的位置(方向),但是当它向前移动时它不遵循精灵的方向(如果 keybd_tupl[K_UP]).
导入pygame随机导入导入数学从 pygame.locals 导入 *window_wid = 800window_hgt = 600帧速率 = 50delta_time = 1/frame_rate状态_就绪 = 2def game_loop_inputs():# 在事件队列中查找退出事件quit_ocrd = 假对于 pygame.event.get() 中的事件:如果 evnt.type == 退出:quit_ocrd = 真返回quit_ocrddef game_loop_update(circle_hitbox):# 首先假设没有发生冲突circle_hitbox["col"] = False# 返回旋转线和圆形hitbox的新状态返回 circle_hitboxdef game_loop_render(circle_hitbox, window_sfc):# 清除窗口表面(用黑色填充)window_sfc.fill( (0,0,0) )# 绘制圆形碰撞盒,如果发生碰撞则为红色,否则为白色如果 circle_hitbox["col"]:#pygame.draw.circle(window_sfc, (255, 0, 0), circle_hitbox["pos"], circle_hitbox["rad"])旋转损坏 = pygame.transform.rotate(circle_hitbox["damage"], circle_hitbox["angle"])window_sfc.blit(rotated_damage, circle_hitbox["pos"])别的:#pygame.draw.circle(window_sfc, (255, 255, 255), circle_hitbox["pos"], circle_hitbox["rad"])旋转图像 = pygame.transform.rotate(circle_hitbox["sprite"], circle_hitbox["angle"])window_sfc.blit(rotated_image, circle_hitbox["pos"])# 更新显示pygame.display.update()定义主():# 初始化pygamepygame.init()# 创建窗口并设置窗口标题window_sfc = pygame.display.set_mode( (window_wid, window_hgt) )pygame.display.set_caption('MDA 练习的玩具"')# 创建一个时钟时钟 = pygame.time.Clock()# 这是初始游戏状态游戏状态 = STATE_READY################################################################################################ 这些是提供的核心机制所需的初始游戏对象(以某种形式)################################################################################################ 这个游戏对象是一个圆形circle_hitbox = {}circle_hitbox["pos"] = (window_wid//2, window_hgt//2)circle_hitbox["rad"] = 30circle_hitbox["col"] = Falsecircle_hitbox["sprite"] = pygame.image.load("cars_racer_{}.png".format(random.randint(1, 3)))circle_hitbox["damage"] = pygame.image.load("cars_racer_red.png")circle_hitbox["crash"] = pygame.image.load("explosion.png")circle_hitbox["损坏"] = Falsecircle_hitbox["angle"] = 0速度 = 10.0vel_x = 速度 * math.cos(circle_hitbox["angle"] * (math.pi/180))vel_y = 速度 * math.sin(circle_hitbox["angle"] * (math.pi/180))# 游戏循环是一个使用布尔标志控制的后置条件循环关闭标志 = 假虽然不是 closed_flag:################################################################################################ 这是游戏循环的输入"阶段,玩家输入被检索和存储###############################################################################################closed_flag = game_loop_inputs()keybd_tupl = pygame.key.get_pressed()如果 keybd_tupl[K_UP]:circle_hitbox["pos"] = (circle_hitbox["pos"][0] + vel_x, circle_hitbox["pos"][1] + vel_y)打印(vel_y)如果 keybd_tupl[K_LEFT]:circle_hitbox["angle"] = (circle_hitbox["angle"] + 10.0)如果 keybd_tupl[K_RIGHT]:circle_hitbox["angle"] = (circle_hitbox["angle"] - 10.0)################################################################################################ 这是游戏循环的更新"阶段,处理游戏世界的变化###############################################################################################circle_hitbox = game_loop_update(circle_hitbox)################################################################################################ 这是游戏循环的渲染"阶段,其中显示了游戏世界的表示###############################################################################################游戏循环渲染(circle_hitbox,window_sfc)# 强制最小帧率时钟滴答(frame_rate)如果 __name__ == "__main__":主要的()
它只是不工作&我不知道为什么.
你必须在while循环中计算vel_x
和vel_y
.
虽然不是 closed_flag:closed_flag = game_loop_inputs()keybd_tupl = pygame.key.get_pressed()如果 keybd_tupl[K_UP]:circle_hitbox["pos"] = (circle_hitbox["pos"][0] + vel_x, circle_hitbox["pos"][1] + vel_y)打印(vel_y)如果 keybd_tupl[K_LEFT]:circle_hitbox["angle"] -= 1.0如果 keybd_tupl[K_RIGHT]:circle_hitbox["angle"] += 1.0# `math.radians` 可以用来代替 `* (math.pi/180)`vel_x = 速度 * math.cos(math.radians(circle_hitbox["angle"]))vel_y = 速度 * math.sin(math.radians(circle_hitbox["angle"]))
另外,将负角传递给game_loop_render
函数中的pygame.transform.rotate
:
rotated_damage = pygame.transform.rotate(circle_hitbox["damage"], -circle_hitbox["angle"])
旋转看起来可能仍然不正确(我使用了一些替换图像,但它们旋转不正确).如果您想知道如何在 pygame 中围绕其中心旋转 pygame 精灵和图像,请查看 这个答案.>
Im trying to move a sprite in the direction of an angle in pygame, using the left & right arrow keys to change the direction of the sprite but when I press the up key, the sprite just moves right. I have 2 variables that take speed and a velocity calculation and adds them together (vel_x & vel_y), I then add this to the position (orientation) of the sprite but it isnt following the sprite orientation when it moves forward (if keybd_tupl[K_UP]).
import pygame
import random
import math
from pygame.locals import *
window_wid = 800
window_hgt = 600
frame_rate = 50
delta_time = 1 / frame_rate
STATE_READY = 2
def game_loop_inputs():
# look in the event queue for the quit event
quit_ocrd = False
for evnt in pygame.event.get():
if evnt.type == QUIT:
quit_ocrd = True
return quit_ocrd
def game_loop_update(circle_hitbox):
# start by assuming that no collisions have occurred
circle_hitbox["col"] = False
# return the new state of the rotating line and the circle hitbox
return circle_hitbox
def game_loop_render(circle_hitbox, window_sfc):
# clear the window surface (by filling it with black)
window_sfc.fill( (0,0,0) )
# draw the circle hitbox, in red if there has been a collision or in white otherwise
if circle_hitbox["col"]:
#pygame.draw.circle(window_sfc, (255, 0, 0), circle_hitbox["pos"], circle_hitbox["rad"])
rotated_damage = pygame.transform.rotate(circle_hitbox["damage"], circle_hitbox["angle"])
window_sfc.blit(rotated_damage, circle_hitbox["pos"])
else:
#pygame.draw.circle(window_sfc, (255, 255, 255), circle_hitbox["pos"], circle_hitbox["rad"])
rotated_image = pygame.transform.rotate(circle_hitbox["sprite"], circle_hitbox["angle"])
window_sfc.blit(rotated_image, circle_hitbox["pos"])
# update the display
pygame.display.update()
def main():
# initialize pygame
pygame.init()
# create the window and set the caption of the window
window_sfc = pygame.display.set_mode( (window_wid, window_hgt) )
pygame.display.set_caption('"Toy" for the MDA Exercise')
# create a clock
clock = pygame.time.Clock()
# this is the initial game state
game_state = STATE_READY
#####################################################################################################
# these are the initial game objects that are required (in some form) for the core mechanic provided
#####################################################################################################
# this game object is a circulr
circle_hitbox = {}
circle_hitbox["pos"] = (window_wid // 2, window_hgt // 2)
circle_hitbox["rad"] = 30
circle_hitbox["col"] = False
circle_hitbox["sprite"] = pygame.image.load("cars_racer_{}.png".format(random.randint(1, 3)))
circle_hitbox["damage"] = pygame.image.load("cars_racer_red.png")
circle_hitbox["crash"] = pygame.image.load("explosion.png")
circle_hitbox["damaged"] = False
circle_hitbox["angle"] = 0
speed = 10.0
vel_x = speed * math.cos(circle_hitbox["angle"] * (math.pi / 180))
vel_y = speed * math.sin(circle_hitbox["angle"] * (math.pi / 180))
# the game loop is a postcondition loop controlled using a Boolean flag
closed_flag = False
while not closed_flag:
#####################################################################################################
# this is the "inputs" phase of the game loop, where player input is retrieved and stored
#####################################################################################################
closed_flag = game_loop_inputs()
keybd_tupl = pygame.key.get_pressed()
if keybd_tupl[K_UP]:
circle_hitbox["pos"] = (circle_hitbox["pos"][0] + vel_x, circle_hitbox["pos"][1] + vel_y)
print(vel_y)
if keybd_tupl[K_LEFT]:
circle_hitbox["angle"] = (circle_hitbox["angle"] + 10.0)
if keybd_tupl[K_RIGHT]:
circle_hitbox["angle"] = (circle_hitbox["angle"] - 10.0)
#####################################################################################################
# this is the "update" phase of the game loop, where the changes to the game world are handled
#####################################################################################################
circle_hitbox = game_loop_update(circle_hitbox)
#####################################################################################################
# this is the "render" phase of the game loop, where a representation of the game world is displayed
#####################################################################################################
game_loop_render(circle_hitbox, window_sfc)
# enforce the minimum frame rate
clock.tick(frame_rate)
if __name__ == "__main__":
main()
It just isnt working & I dont know why.
You have to calculate the vel_x
and vel_y
in the while loop.
while not closed_flag:
closed_flag = game_loop_inputs()
keybd_tupl = pygame.key.get_pressed()
if keybd_tupl[K_UP]:
circle_hitbox["pos"] = (circle_hitbox["pos"][0] + vel_x, circle_hitbox["pos"][1] + vel_y)
print(vel_y)
if keybd_tupl[K_LEFT]:
circle_hitbox["angle"] -= 1.0
if keybd_tupl[K_RIGHT]:
circle_hitbox["angle"] += 1.0
# `math.radians` can be used instead of `* (math.pi / 180)`
vel_x = speed * math.cos(math.radians(circle_hitbox["angle"]))
vel_y = speed * math.sin(math.radians(circle_hitbox["angle"]))
Also, pass the negative angle to pygame.transform.rotate
in the game_loop_render
function:
rotated_damage = pygame.transform.rotate(circle_hitbox["damage"], -circle_hitbox["angle"])
The rotation probably still doesn't look right (I'm using some replacement images and they don't rotate correctly). Take a look at this answer if you want to know how to rotate pygame sprites and images around their center in pygame.
这篇关于在 Pygame 中沿角度方向移动 Sprite的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!