2017-11-15 1 views
1

필자는 pymunk를 사용하여 물리학을 수행하고 GUI 작업을 수행하는 tkinter를 만들었습니다. (왜냐하면 필자의 파이크 게임을 내 맥에 설치하려하기 때문에 ...)pymunk + tkinter : 공이 pymunk로 왼쪽이나 오른쪽으로 이동하는 방법?

나는 가지고있다. 하나의 공이 생성되고 떨어지며 바닥에서 튀어 오르는 작업. 바닥을 기울이면 왼쪽이나 오른쪽으로 튀는 것을 올바르게 시작합니다.

처음에는 볼에 힘을 가하는 방법을 알아낼 수 없으므로 초기 속도가 오른쪽으로 향하게됩니다.

아래 코드를 포함합니다. 아마 뭔가 간단 할 지 모르겠지만 저는 물리학자가 아니며 순간 등등에 대해서는 전혀 모릅니다.

고마워요.

"""Simple example that bounces one ball against a floor. 
The BallPhysics class defines the "model". The Ball class is the "view". 

@author: Victor Norman 
""" 

from tkinter import * 
import pymunk 
import pymunk.util 
from pymunk import Vec2d 
import math, sys, random 


class Ball: 

    RADIUS = 10 

    def __init__(self, window): 
     self._window = window 
     self._window.title("Bouncing Ball with pymunk physics") 

     self._model = BallPhysics() 

     self._width = 400 

     self._canvas = Canvas(self._window, bg='black', 
           width=self._width, height=self._width) 
     self._canvas.pack() 

     self._render() 

    def _render(self): 

     self._model.next_step() 
     x, y = self._model.get_xy_for_ball() 

     # subtract y values from self._width because y increases from 0 downward. 
     self._canvas.create_oval(x - self.RADIUS, self._width - (y - self.RADIUS), 
           x + self.RADIUS, self._width - (y + self.RADIUS), 
           fill = 'white') 
     self._canvas.after(20, self._render) 


class BallPhysics: 
    def __init__(self): 

     self._space = pymunk.Space() 
     self._space.gravity = (0.0, -900.0) 

     self._balls = [] 

     mass = 10 
     inertia = pymunk.moment_for_circle(mass, 0, Ball.RADIUS, (0, 0)) 
     body = pymunk.Body(mass, inertia) 
     x = random.randint(50, 350) 
     body.position = x, 400 
     shape = pymunk.Circle(body, Ball.RADIUS, Vec2d(0,0)) 
     shape.elasticity = 0.9 
     self._space.add(body, shape) 
     self._balls.append(shape) 

     # floor 
     floor = pymunk.Segment(self._space.static_body, (0.0, 10.0), (400.0, 10.0), 1.0) 
     floor.friction = 1.0 
     floor.elasticity = 0.9 
     self._space.add(floor) 


    def next_step(self): 
     # Remove balls that are below the bottom. 
     balls_to_remove = [] 
     for ball in self._balls: 
      if ball.body.position.y < 0: 
       balls_to_remove.append(ball) 
     for ball in balls_to_remove: 
      self._space.remove(ball, ball.body) 
      self._balls.remove(ball) 

     if len(self._balls) >= 1: 
      v = self._balls[0].body.position 
      print("point = %.2f, %.2f" % (v.x, v.y)) 

     self._space.step(1/50) 

    def get_xy_for_ball(self): 
     ball_num = 0 
     return (self._balls[ball_num].body.position.x, 
       self._balls[ball_num].body.position.y) 


main = Tk() 
app = Ball(main) 
main.mainloop() 
+0

:

이 예는 충동을 적용하여 촬영 공을 포함한다. 첫 번째 단계는 tkinter 코드를 제거하고 새로운 좌표를 정확하게 계산하고 화면에 출력하는 루프를 만드는 것입니다. 일단 캔버스에 객체를 그리는 것은 쉽습니다. (그리고 각 틱에 새 객체를 그리지 말아야합니다. 기존 객체를 새 좌표로 옮겨야합니다.) –

+0

어떻게 대답 할 지 모르겠습니다. 내 사본이 작동합니다. 메시지에 붙여 넣은 내용이 올바른지 확인하기 위해 새 파일에 복사하여 붙여 넣습니다. python3이 아닌 python2를 사용하고 있습니다. 콘솔에 출력은 다음과 같이 시작 다윈 (64 비트)에 대한 로드 다람쥐 [/usr/local/lib/python3.5/site-packages/pymunk/libchipmunk.dylib] 점 = 127.00, 400.00 포인트 = 127.00, 400.00 점 = 127.00, 399.64 점 = 127.00, 398.92 점 = 127.00, 397.84 점 = 127.00, 396.40 점 = 127.00, 394.60 점 = 127.00, 392.44 – VictorNorman

답변

1

당신은 당신이 밀어하려는 몸에 body.apply_impulse_at_local_point (또는 *at_world_point)를 사용할 수 있습니다. API는 여기에 설명되어 있습니다. http://www.pymunk.org/en/latest/pymunk.html#pymunk.Body.apply_impulse_at_local_point

코드에서 본체 위치를 x,400으로 설정 한 직후에 body.apply_impulse_at_local_point((10000,0))을 수행 할 수 있습니다. 원하는 효과를 얻으려면 충동의 강도를 수정해야합니다. 보통 나는 길이 방향으로 하나의 벡터를 만들어서 밀기를 원하는 방향으로 만든 다음, 얼마나 많은 충동으로 그 벡터를 곱합니다. 이렇게 : body.apply_impulse_at_local_point(10000 * Vec2d(1,0)). 그런 다음 예를 들어 약간 위쪽으로 향하기가 쉽습니다. 난 당신의 코드를 실행하면 X/Y는 절대 변경 좌표, https://github.com/viblo/pymunk/blob/master/examples/box2d_vertical_stack.py

관련 문제