让对象在Pygame中不断朝一个方向移动
我在用Pygame做一个俯视角射击游戏,试着实现子弹朝某个点移动的功能。在网上找到了一段关于角度移动的代码,拿来用在子弹上。不过我遇到了一个问题,就是怎么让子弹一直朝计算出来的方向移动。我数学不太好(还在学习中),但我大致明白这里的逻辑:
speed = speed
distance = [t0 - psx, t1 - psy]
norm = math.sqrt(distance[0] ** 2 + distance[1] ** 2)
direction = [distance[0] / norm, distance[1 ] / norm]
bullet_vector = [direction[0] * speed, direction[1] * speed]
这个是基于斜率公式的,也就是deltaY/deltaX,对吧?有没有人知道怎么实现这个?
这里是完整的源代码,供参考:
import pygame
from pygame.locals import *
import math
#init stuff
pygame.init()
screen=pygame.display.set_mode((640,480))
clock=pygame.time.Clock()
run=True
orbs=[]
px=1
py=1
clock=pygame.time.Clock()
#movement from one point to another
def Move(t0,t1,psx,psy,speed):
global mx
global my
speed = speed
distance = [t0 - psx, t1 - psy]
norm = math.sqrt(distance[0] ** 2 + distance[1] ** 2)
direction = [distance[0] / norm, distance[1 ] / norm]
bullet_vector = [direction[0] * speed, direction[1] * speed]
return bullet_vector
#bullet class
class Orb(object):
def __init__(self,posorg,posdest):
self.posx=posorg[0]
self.posy=posorg[1]
self.targ=posdest
self.posorg=posorg
def update(self):
bullet_vector=Move(self.targ[0],self.targ[1],self.posx,self.posy,20)
self.posx += bullet_vector[0]
self.posy += bullet_vector[1]
pygame.draw.circle(screen, ((0,0,255)), (int(self.posx),int(self.posy)), 5)
#main loop
while run:
screen.fill((220,220,220))
for o in orbs:
o.update()
(mx,my)=(pygame.mouse.get_pos()[0],pygame.mouse.get_pos()[1])
for e in pygame.event.get():
#quit on close button
if e.type == QUIT:
run=False
if e.type==MOUSEBUTTONDOWN:
if e.button==1:
orbs.append(Orb((px,py),(mx,my)))
#player movement
key=pygame.key.get_pressed()
if key[K_a]:
px-=2
if key[K_d]:
px+=2
if key[K_w]:
py-=2
if key[K_s]:
py+=2
clock.tick(60)
pygame.draw.circle(screen, ((2,150,2)), (int(px),int(py)), 30)
pygame.display.update()
1 个回答
4
你的更新每次都在改变子弹的运动方向,其实你想要的是在发射的时候只计算一次这个方向,然后根据这个初始方向来更新位置。所以把orb改成类似下面的样子:
class Orb(object):
def __init__(self,posorg,posdest):
self.posx=posorg[0]
self.posy=posorg[1]
self.targ=posdest
self.posorg=posorg
self.bullet_vector=Move(self.targ[0],self.targ[1],self.posx,self.posy,20)
def update(self):
self.posx += self.bullet_vector[0]
self.posy += self.bullet_vector[1]
pygame.draw.circle(screen, ((0,0,255)), (int(self.posx),int(self.posy)), 5)
这样的话,运动方向就只会在创建的时候计算一次。
不过你还应该加一个检查,看看子弹是否还在屏幕上。如果不在了,就把它删除,这样在游戏中有很多子弹的时候可以节省资源。
祝你好运!