2016-07-25 1 views
4

를 사용하여 다른 위에 한 몸을 유지하는 방법 :상단에 상자, 내가 원을 가지고 Pymunk

Circle with box on top

원은 간단한 모터입니다. 상자가 원 위에 직접 머물고 싶습니다. 나는 다른 제약 조건을 시도했지만, 시도의 대부분이 상자를 옆으로 쳐서 떨어 뜨립니다.

가장 성공적인 시도는 상자의 body.moment를 pymunk.inf로 설정하고 상자를 원에 고정하는 것입니다. 그게 다가 오지만 상자가 여전히 원의 중심을 넘어서고 싶을 때 좌우로 움직입니다. 수동으로 설정할 수는 있지만 일종의 제약으로 그렇게 할 수 있어야합니다.

아이디어가 있으십니까? 다음은 Pymunk 및 Arcade 라이브러리를 사용하는 일부 샘플 코드입니다.

import arcade 
import pymunk 
import math 

SCREEN_WIDTH = 1200 
SCREEN_HEIGHT = 800 
BOX_SIZE = 45 

class MyApplication(arcade.Window): 
    """ Main application class. """ 

    def __init__(self, width, height): 
     super().__init__(width, height) 
     arcade.set_background_color(arcade.color.DARK_SLATE_GRAY) 

     # -- Pymunk space 
     self.space = pymunk.Space() 
     self.space.gravity = (0.0, -900.0) 

     # Create the floor 
     body = pymunk.Body(body_type=pymunk.Body.STATIC) 
     self.floor = pymunk.Segment(body, [0, 10], [SCREEN_WIDTH, 10], 0.0) 
     self.floor.friction = 10 
     self.space.add(self.floor) 

     # Create the circle 
     player_x = 300 
     player_y = 300 
     mass = 2 
     radius = 25 
     inertia = pymunk.moment_for_circle(mass, 0, radius, (0, 0)) 
     circle_body = pymunk.Body(mass, inertia) 
     circle_body.position = pymunk.Vec2d(player_x, player_y) 
     self.circle_shape = pymunk.Circle(circle_body, radius, pymunk.Vec2d(0, 0)) 
     self.circle_shape.friction = 1 

     self.space.add(circle_body, self.circle_shape) 

     # Create the box 
     size = BOX_SIZE 
     mass = 5 
     moment = pymunk.moment_for_box(mass, (size, size)) 
     moment = pymunk.inf 
     body = pymunk.Body(mass, moment) 
     body.position = pymunk.Vec2d(player_x, player_y + 49) 
     self.box_shape = pymunk.Poly.create_box(body, (size, size)) 
     self.box_shape.friction = 0.3 
     self.space.add(body, self.box_shape) 

     # Create a joint between them 
     constraint = pymunk.constraint.PinJoint(self.box_shape.body, self.circle_shape.body) 
     self.space.add(constraint) 

     # Make the circle rotate 
     constraint = pymunk.constraint.SimpleMotor(self.circle_shape.body, self.box_shape.body, -3) 
     self.space.add(constraint) 

    def on_draw(self): 
     """ 
     Render the screen. 
     """ 
     arcade.start_render() 

     # Draw circle 
     arcade.draw_circle_outline(self.circle_shape.body.position[0], 
            self.circle_shape.body.position[1], 
            self.circle_shape.radius, 
            arcade.color.WHITE, 
            2) 

     # Draw box 
     arcade.draw_rectangle_outline(self.box_shape.body.position[0], 
             self.box_shape.body.position[1], 
             BOX_SIZE, 
             BOX_SIZE, 
             arcade.color.WHITE, 2, 
             tilt_angle=math.degrees(self.box_shape.body.angle)) 

     # Draw floor 
     pv1 = self.floor.body.position + self.floor.a.rotated(self.floor.body.angle) 
     pv2 = self.floor.body.position + self.floor.b.rotated(self.floor.body.angle) 
     arcade.draw_line(pv1.x, pv1.y, pv2.x, pv2.y, arcade.color.WHITE, 2) 

    def animate(self, delta_time): 

     # Update physics 
     self.space.step(1/80.0) 

window = MyApplication(SCREEN_WIDTH, SCREEN_HEIGHT) 

arcade.run() 
+0

문제의 코드를 게시 할 수 있습니까? 샘플 코드로 업데이트 된 [mcve] –

+0

확인에 도움이되는 것이 훨씬 쉽습니다. –

답변

2

하나의 핀 접합부 대신 2 개의 핀 접합부를 사용할 수 있으며 상자에 앵커 지점이 펼쳐져 있습니다. 정렬의 충분한 그것의 좋은 그렇지 않은 경우

# Create a joint between them 
constraint = pymunk.constraint.PinJoint(self.box_shape.body, self.circle_shape.body, (-20,0)) 
self.space.add(constraint) 

constraint = pymunk.constraint.PinJoint(self.box_shape.body, self.circle_shape.body, (20,0)) 
self.space.add(constraint) 

현실 :)에서 또한 안정적으로 만들 것이다 당신은 어떻게 제약에 낮은 error_bias 값으로 실험을 시도 할 수 있지만, 그것은 도움이 얼마나 임 확실하지. 만약 당신이 완벽하게 픽셀이 필요 없다면 관절은 그것을 할 수 있다고 생각하지 않는다. 그들은 항상 작은 오류가있을 수있다. 따라서 위와 같은 스프라이트를 같은 x 값으로 그리면 위조했다고 생각합니다.

+0

이 작품! 감사. –

관련 문제