问题描述
|
我正在尝试用Pygame(Python)编写本教程,并且遇到关于在平面之间保持点的问题。
我的代码是:fiz2.py
向量类别:vector.py
如果在Pygame屏幕上移动鼠标,飞机将旋转。当飞机旋转时,点将通过飞机并向外移动。
我试图在每次迭代中固定点的位置,但是它们仍然通过了飞机。我不知道该在哪里固定他们的位置。
注意:我知道我的代码有点混乱,这是我的第一个2d程序,我真的很难适应Pygame的坐标平面和向量。解决此问题后,我将重新编写。
注意2:是的,我在教程中写了关于如何在平面之间保持点的注释,我了解他固定位置的方式,但是不知道如何(在代码中)实现它。
谢谢。
解决方法
我看不出来看代码。我的猜测是时变的,导致不稳定。但是我无法验证数学是否正确。虽然,我有有用的信息:
向量
通过将向量用作类与列表/元组,可以简化代码。 (速度,加速度,位置)视为一个对象,请分别使用.x和.y值。
# example:
pos[0] += vel[0]
pos[1] += vel[1]
# vs
pos += vel
有一个仅python的实现:euclid.py您可以用来与vector.py进行比较。
或在openGL中使用NumPy [用于3d图形。 ]是一个流行的,成熟的库。
物理
(看来您想通过编写自己的物理学来学习),但请查看PyMunk
颜色
您可以使用:pygame.Color
import pygame
from pygame import Color
color = Color(\'white\')
color2 = Color(\'lightgray\')
color3 = Color(0,128,128)
碰撞
查看pygame.sprite。* collide和pygame.Rect。* collide
pygame游戏循环与numpy vector \'s
我写的样板
\"\"\" Pygame boilerplate. <ninmonkey>2011/04
pygame main Game() loop,and numpy for vector math.
note:
this might not be the most effecient way to use numpy as vectors,but it\'s an intro.
And this does not force fixed-timesteps. If you want a stable simulation,you need to use a fixed timestep.
see: http://gafferongames.com/game-physics/fix-your-timestep/
Keys:
ESC : exit
Space : game_init()
\"\"\"
import pygame
from pygame.locals import *
from pygame import Color,Rect
import numpy as np
def get_screen_size():
\"\"\"return screen (width,height) tuple\"\"\"
screen = pygame.display.get_surface()
return screen.get_size()
class Actor():
\"\"\"basic actor,moves randomly.
members:
loc = position vector
velocity = velocity vector
width,height
\"\"\"
def __init__(self,loc=None,velocity=None):
\"\"\"optional initial loc and velocity vectors\"\"\"
self.width = 50
self.height = 50
# if loc or velocity are not set: use random
if loc is None: self.rand_loc()
else: self.loc = loc
if velocity is None: self.rand_velocity()
else: self.velocity = velocity
def update(self):
\"\"\"update movement\"\"\"
self.loc += self.velocity
def rand_velocity(self):
\"\"\"set a random vector,based on random direction. Using unit circle:
x = cos(deg) * speed
\"\"\"
rad = np.radians( np.random.randint(0,360) )
speed = np.random.randint(1,15)
x = np.cos(rad)
y = np.sin(rad)
velocity = np.array( [x,y])
velocity *= speed
self.velocity = velocity
def rand_loc(self):
\"\"\"random location onscreen\"\"\"
width,height = get_screen_size()
x = np.random.randint(0,width)
y = np.random.randint(0,height)
self.loc = np.array([x,y])
def is_onscreen(self):
\"\"\"test is screen.colliderect(actor) true?\"\"\"
x,y = self.loc
w,h = get_screen_size()
screen = Rect(0,w,h)
actor = Rect(x,y,self.width,self.height)
if screen.colliderect(actor): return True
else: return False
class GameMain():
\"\"\"game Main entry point. handles intialization of game and graphics.\"\"\"
done = False
debug = False
color_gray = Color(\'lightgray\')
def __init__(self,width=800,height=600,color_bg=None):
\"\"\"Initialize PyGame\"\"\"
pygame.init()
self.width,self.height = width,height
self.screen = pygame.display.set_mode(( self.width,self.height ))
pygame.display.set_caption( \"boilerplate : pygame\" )
self.clock = pygame.time.Clock()
self.limit_fps = True
self.limit_fps_max = 60
if color_bg is None: color_bg = Color(50,50,50)
self.color_bg = color_bg
self.game_init()
def game_init(self):
\"\"\"new game/round\"\"\"
self.actors = [Actor() for x in range(10)]
def loop(self):
\"\"\"Game() main loop\"\"\"
while not self.done:
self.handle_events()
self.update()
self.draw()
if self.limit_fps: self.clock.tick( self.limit_fps_max )
else: self.clock.tick()
def update(self):
\"\"\"update actors,handle physics\"\"\"
for a in self.actors:
a.update()
if not a.is_onscreen():
a.rand_loc()
def handle_events(self):
\"\"\"handle regular events. \"\"\"
events = pygame.event.get()
# kmods = pygame.key.get_mods() # key modifiers
for event in events:
if event.type == pygame.QUIT: sys.exit()
elif event.type == KEYDOWN:
if (event.key == K_ESCAPE): self.done = True
elif (event.key == K_SPACE): self.game_init()
def draw(self):
\"\"\"render screen\"\"\"
# clear screen
self.screen.fill( self.color_bg )
# Actor: draw
for a in self.actors:
x,y = a.loc
w,h = a.width,a.height
r = Rect(x,h)
self.screen.fill(self.color_gray,r)
# will call update on whole screen Or flip buffer.
pygame.display.flip()
if __name__ == \'__main__\':
g = GameMain()
g.loop()