pymunk + tkinter: Как заставить шар перемещаться влево или вправо с помощью pymunk?

Я создал небольшую примерную программу, в которой я использую pymunk для физики, а tkinter - для графического интерфейса (потому что я перестал пытаться установить pygame на мой Mac...)

У меня это работает, когда один мяч создается, падает и отскакивает от пола. Если я наклоню пол, он начнет правильно подпрыгивать влево или вправо.

Чего я не могу понять, так это как сначала приложить силу к мячу, чтобы его начальная скорость была направлена ​​вправо.

Я включил мой код ниже. Возможно, это что-то действительно простое, но я не физик и ничего не знаю о моментах и ​​т. Д. И т. Д.

Благодарю.

Vic

"""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()

1 ответ

Решение

Ты можешь использовать body.apply_impulse_at_local_point (или же *at_world_point) на тело, которое вы хотите нажать. API описывается здесь: http://www.pymunk.org/en/latest/pymunk.html

Итак, в вашем коде вы могли бы сделать body.apply_impulse_at_local_point((10000,0)) сразу после того, как вы установите положение тела в x,400, Обратите внимание, что вам нужно изменить силу импульса, чтобы получить желаемый эффект. Обычно я создаю вектор длиной один в направлении, которое я хочу, чтобы он выдвинул, а затем умножаю его на то, сколько импульса я хочу. как это: body.apply_impulse_at_local_point(10000 * Vec2d(1,0)), Тогда вместо этого можно легко прицелиться, например, немного вверх.

В этом примере показан стреляющий мяч с применением импульса: https://github.com/viblo/pymunk/blob/master/examples/box2d_vertical_stack.py

Другие вопросы по тегам