pygame,简单的物理引擎,如何在平面之间保持点? [英] Pygame, simple physics engine, how to hold points between planes?

查看:106
本文介绍了pygame,简单的物理引擎,如何在平面之间保持点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试写 Pygame(Python)中的教程,并且关于平面之间的保持点存在问题.

I'm trying to write this tutorial in Pygame(Python) and having problems about holding points between planes.

我的代码是: fiz2.py

向量类: vector.py

如果在Pygame屏幕上移动鼠标,飞机将旋转.并且当飞机旋转时,点正在通过飞机并向外移动.

If you move mouse on the Pygame screen, the planes will rotate. And when the planes are rotating, points are passing through planes and going outside.

我试图在每次迭代中固定点的位置,但是它们仍然通过了飞机.我不知道应该在哪里固定他们的位置.

I tried to fix points' positions on every iteration but they still passed the planes. I have no idea about where should I fix their positions.

注意:我知道我的代码有点混乱,这是我的第一个2d程序,我很难适应Pygame的坐标平面和向量.解决这个问题后,我会重写.

NOTE: I know my code is a little bit messy, this is my first 2d program and I had really hard times getting used to Pygame's coordinate plane and vectors. I will re-write when I solve this.

注2:是的,我在教程上写了关于如何在平面之间保持点的注释,我了解他固定位置的方式,但是不知道如何(在代码中的位置)实现它.

NOTE2: Yes, I wrote the comment about how to hold points between planes on the tutorial, I understand the way he fixes positions but have no idea about how(and where, in code) to implement it.

谢谢.

推荐答案

我不知道看代码.我的猜测是时变的,导致不稳定.但是我无法验证数学是否正确.虽然,我有有用的信息:

I can't tell looking at the code. My guess is a variable-timestep, causing instability. But I can't verify if the math is right. Although, I have useful information :

通过将向量用作类vs列表/元组,可以简化代码. (速度,加速度,位置)被视为一个对象,将.x和.y值分开.

You can simplify code, by using vectors as a class vs list/tuple. (velocity, acceleration, location) are treated as one object, verses separate .x and .y values.

# example:
pos[0] += vel[0]
pos[1] += vel[1]

# vs
pos += vel

有一个仅用于python的实现: euclid.py 您可以用来与向量进行比较. py.

There is a python-only implementation: euclid.py You can use to compare with your vector.py.

或在OpenGL中使用 NumPy [用于3d图形. ]是一个流行的,成熟的库.

Or use NumPy [ used for 3d graphics, in openGL. ] Is a popular, mature lib.

(您似乎想通过编写自己的物理学来学习),但请查看 PyMunk

(It looks like you want to learn by writing your own physics), but check out 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 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, 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, y, w, 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()

这篇关于pygame,简单的物理引擎,如何在平面之间保持点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆