この質問はpymunkに関するものですが、Chimpunkのユーザがたくさんいることを知っています。あなたの答えがC/Chipmunkコードを含んでいれば大丈夫です。私はCコードの記述方法はわかりませんが、他の誰かを読むと、何が起きているのか把握することができます。衝突中のある物体から別の物体へのエネルギーの移動
セットアップ
私は(カールやシャッフルボードを考える)トップダウンスライドオブジェクトのゲームをシミュレートしています。 私は(質問の最後に)コードの関連部分の最小限の例を作ったが、それの心は次のとおりです。
- 2つの同一の物理オブジェクトが作成される(カーリングの用語を以下、私はそれらを呼び出します'stones')
- 位置は同じx値ですが、y値が異なります(1つは直線上にあります)。
私は何を望んでいる
とき達成するために、下の石がまっすぐに他の石で「打ち上げ」される(他の方法が試みられたものの、今のところ)apply_impulse使用
私は石が衝突すると、下の石が停止しない代わりに
を得ている、と上部の石upscreenを押して開始します。 下の方が上よりも質量が大きいようですが、同じ関数で作成されているので同じでなければなりません。
私はそれが助け場合は、このことを示しているimgurする.GIFをアップロードしました: http://imgur.com/a/FF6Xq
をそれが実際にスクリプトを実行しているときよりも低いフレームレートだが、それはまだ何が起こっているのかを示します。私は、関連するかもしれないすべてのボディと形状の特性を特定しようとする、pygameのドキュメントを通じて読む
を試してみた何
は、私は様々な組み合わせで、次のすべてを調整しようとしました:
- body.mass shape.friction
- 形状。弾性
- 「接地摩擦」(トップダウンシナリオで接地摩擦をシミュレートピボット制約のmax_force)
- 下石を起動している時に「電源」(apply_impulseに渡される引数のうちの1つ) どの/これらの全てが目立たや石の行動の変化を期待しますが、どれも、彼らが衝突したとき、他のを押して一石の根本的な問題を変更しない微調整の代わりにapply_impulse
のapply_forceを使用して
私はpymunk.CollisionHandler()の使用について読んでいますが、まだ使用しようとしていません。ドキュメントから、これは主に、衝突に何かの基本的な物理を変更するのではなく、衝突に追加の効果を加えることを主な目的としているということがわかります。しかし、私は誤解している可能性があり、いかなる示唆にも開放しています。
私はpymunkデモのいくつかを見てきました。特に注目すべきは、newtons_cradle.pyというデモが、私が望む動作を示すことです。それは5つの球が連続して停止しているそれらのガジェットの1つのシミュレーションです。ユーザーが最後のボールを1つ後ろに引くと、残りの行に当たってエネルギーが反対側のボールに移動します。 newtons_crade.pyは私のコードから2つの大きな違いがあります。それは
- を、重力のみをするために使用されますボールを他のものに向けて推進する(制約によって制約される)。
残念ながら、私のトップダウン設定で重力を使用することはできません。 問題は私がapply_impulse/apply_forceを使用している可能性がありますが、これらの使用方法を変更する方法はありません(私はすでにさまざまな組み合わせの力と質量を試していますが、制約の設定も調整しています) 。
正しい方向で私を指差しても、それ以外の何かを読んでいるかもしれないというアドバイスや、改めて試してみようと思うことがあります。私はpymunk/chipmunkでこれを試す最初の人になることはできませんが、私は例を見つけることができませんでした。少なくともpymunk側ではない。もし私が勉強することができるC/Chipmunkの良い例があれば、それも役に立つだろう。
ありがとうございます。
最小限のコード例
それは質問を理解するためのコードを勉強する必要はありませんが、私はそれが便利です念のためにそれをここに掲載しました。コードの中心を示すために削除されましたが、完全なスクリプトであり、実行することができます。 Python 3にあります。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import pygame
from pygame.locals import *
import pymunk
import pymunk.pygame_util
def add_and_tether_stone(space,sx,sy):
"""Creates a stone and its corresponding shape, and tethers it with constraints that simulate ground friction and govern spin."""
#body
mass = stone_mass
radius = stone_radius
moment = pymunk.moment_for_circle(mass, 0, radius)
body = pymunk.Body(mass, moment)
body.position = sx,sy
#shape
shape = pymunk.Circle(body, radius)
shape.friction = stone_friction
shape.elisticity = stone_elisticity
space.add(body, shape)
#constraints
fpiv = pymunk.constraint.PivotJoint(space.static_body,body,(0.0,0.0),(0.0,0.0))
fpiv.max_force = ground_friction
fpiv.max_bias = 0.0
fmot = pymunk.constraint.SimpleMotor(space.static_body,body,0)
fmot.max_force = 5000000 #arbitry 'very high' value clamps down on the high rotation imparted by apply_impulse or apply_force
space.add(fpiv)
space.add(fmot)
return body,shape,fpiv,fmot
def launch_stone(body,power):
"""Launches a stone in the manner of a player taking a shot."""
body.apply_impulse_at_world_point((0,power),(0,0)) #force(x,y),offset(x,y)
def main():
global ground_friction,stone_mass,stone_radius,stone_friction,stone_elisticity
running = True
#PyGame setup
pygame.init()
screen = pygame.display.set_mode((500,500))
clock = pygame.time.Clock()
sheet = pygame.Surface((500,500))
sheetcolor = (0,0,0)
sheet.fill(sheetcolor)
sheet = sheet.convert()
sheetblit = (0,0)
screen.blit(sheet,sheetblit)
#PyMunk setup
space = pymunk.Space() #space.damping defaults to 1.0, and space.gravity defaults to (0.0, 0.0).
draw_options = pymunk.pygame_util.DrawOptions(sheet) #used only for the pygame_util debug draw mode
#Constants to Tweak
stone_mass = 1.4
stone_radius = 20
power = 340 #in a full implementation, this would vary with player input
ground_friction = 4.5
stone_friction = 2.0
stone_elisticity = 1.0
#Setup for the minimal example: add two stones and launch one at the other.
stone_a = add_and_tether_stone(space,40,260)
stone_b = add_and_tether_stone(space,40,21)
launch_stone(stone_b[0],power)
while running:
for event in pygame.event.get(): #listen for controls (all the controls except 'esc' have been removed for the minimal example)
if event.type == KEYDOWN and event.key == K_ESCAPE:
running = False
#Draw, update physics, and advance
sheet.fill(sheetcolor)
space.debug_draw(draw_options) #from pymunk.pygame-util (handy!)
screen.blit(sheet,sheetblit)
space.step(1/50.0)
pygame.display.flip()
clock.tick(50)
if __name__ == '__main__':
sys.exit(main())
ありがとうございました。
ありがとうございました!あなたのコードと私を比較することで、私は問題を見つけることができました。 shape.elasticityを1.0(デフォルトの0から)に設定することは、決定的な違いを生み出しました。そして、私にとって恥ずかしいことに、「弾力性」という言葉のタイプミスは、私が弾力性を設定していると思っていましたが、実際に変更されたことはありません。私のコードをS.Oに投稿することで、どのようなタイプミスを見つけることができますか?さて、ご協力いただきありがとうございます。ご迷惑をおかけして申し訳ございません。 –