UTheoJansen.pas
上传用户:zkjn0718
上传日期:2021-01-01
资源大小:776k
文件大小:8k
源码类别:

Delphi/CppBuilder

开发平台:

Delphi

  1. unit UTheoJansen;
  2. interface
  3. {$I ......SourcePhysics2D.inc}
  4. uses
  5.    UMain, UPhysics2DTypes, UPhysics2D, SysUtils;
  6. type
  7.    TJansenWalker = class(TTester)
  8.    private
  9.       procedure CreateLeg(s: Float; const wheelAnchor: TVector2);
  10.    public
  11.       m_offset: TVector2;
  12.       m_chassis, m_wheel: Tb2Body;
  13.       m_motorJoint: Tb2RevoluteJoint;
  14.       m_motorOn: Boolean;
  15.       m_motorSpeed: Float;
  16.       constructor Create; override;
  17.       procedure Step(var settings: TSettings; timeStep: Float); override;
  18.       procedure Keyboard(key: Byte); override;
  19.    end;
  20. implementation
  21. { TJansenWalker }
  22. constructor TJansenWalker.Create;
  23. const
  24.    pivot: TVector2 = (X: 0.0; Y: 0.8);
  25. var
  26.    i: Integer;
  27.    sd: Tb2PolygonDef;
  28.    bd: Tb2BodyDef;
  29.    cd: Tb2CircleDef;
  30.    ground, body: Tb2Body;
  31.    jd: Tb2RevoluteJointDef;
  32.    wheelAnchor: TVector2;
  33. begin
  34.    inherited;
  35.    {$IFDEF OP_OVERLOAD}
  36.    m_offset.SetValue(0.0, 8.0);
  37.    {$ELSE}
  38.    SetValue(m_offset, 0.0, 8.0);
  39.    {$ENDIF}
  40.    m_motorSpeed := 2.0;
  41.    m_motorOn := True;
  42.    begin
  43.       sd := Tb2PolygonDef.Create;
  44.       sd.SetAsBox(50.0, 10.0);
  45.       bd := Tb2BodyDef.Create;
  46.       {$IFDEF OP_OVERLOAD}
  47.       bd.position.SetValue(0.0, -10.0);
  48.       {$ELSE}
  49.       SetValue(bd.position, 0.0, -10.0);
  50.       {$ENDIF}
  51.       ground := m_world.CreateBody(bd);
  52.       ground.CreateShape(sd, False);
  53.       sd.SetAsBox(0.5, 5.0, MakeVector(-50.0, 15.0), 0.0);
  54.       ground.CreateShape(sd, False);
  55.       sd.SetAsBox(0.5, 5.0, MakeVector(50.0, 15.0), 0.0);
  56.       ground.CreateShape(sd);
  57.    end;
  58.    for i := 0 to 39 do
  59.    begin
  60.       cd := Tb2CircleDef.Create;
  61.       cd.density := 1.0;
  62.       cd.radius := 0.25;
  63.       bd := Tb2BodyDef.Create;
  64.       {$IFDEF OP_OVERLOAD}
  65.       bd.position.SetValue(-40.0 + 2.0 * i, 0.5);
  66.       {$ELSE}
  67.       SetValue(bd.position, -40.0 + 2.0 * i, 0.5);
  68.       {$ENDIF}
  69.       body := m_world.CreateBody(bd);
  70.       body.CreateShape(cd);
  71.       body.SetMassFromShapes;
  72.    end;
  73.    begin
  74.       sd := Tb2PolygonDef.Create;
  75.       sd.density := 1.0;
  76.       sd.SetAsBox(2.5, 1.0);
  77.       sd.filter.groupIndex := -1;
  78.       bd := Tb2BodyDef.Create;
  79.       {$IFDEF OP_OVERLOAD}
  80.       bd.position := pivot + m_offset;
  81.       {$ELSE}
  82.       bd.position := Add(pivot, m_offset);
  83.       {$ENDIF}
  84.       m_chassis := m_world.CreateBody(bd);
  85.       m_chassis.CreateShape(sd);
  86.       m_chassis.SetMassFromShapes;
  87.    end;
  88.    begin
  89.       cd := Tb2CircleDef.Create;
  90.       cd.density := 1.0;
  91.       cd.radius := 1.6;
  92.       cd.filter.groupIndex := -1;
  93.       bd := Tb2BodyDef.Create;
  94.       {$IFDEF OP_OVERLOAD}
  95.       bd.position := pivot + m_offset;
  96.       {$ELSE}
  97.       bd.position := Add(pivot, m_offset);
  98.       {$ENDIF}
  99.       m_wheel := m_world.CreateBody(bd);
  100.       m_wheel.CreateShape(cd);
  101.       m_wheel.SetMassFromShapes;
  102.    end;
  103.    begin
  104.       jd := Tb2RevoluteJointDef.Create;
  105.       {$IFDEF OP_OVERLOAD}
  106.       jd.Initialize(m_wheel, m_chassis, pivot + m_offset);
  107.       {$ELSE}
  108.       jd.Initialize(m_wheel, m_chassis, Add(pivot, m_offset));
  109.       {$ENDIF}
  110.       jd.collideConnected := false;
  111.       jd.motorSpeed := m_motorSpeed;
  112.       jd.maxMotorTorque := 400.0;
  113.       jd.enableMotor := m_motorOn;
  114.       m_motorJoint := Tb2RevoluteJoint(m_world.CreateJoint(jd));
  115.    end;
  116.    {$IFDEF OP_OVERLOAD}
  117.    wheelAnchor := pivot + MakeVector(0.0, -0.8);
  118.    {$ELSE}
  119.    wheelAnchor := Add(pivot, MakeVector(0.0, -0.8));
  120.    {$ENDIF}
  121.    CreateLeg(-1.0, wheelAnchor);
  122.    CreateLeg(1.0, wheelAnchor);
  123.    m_wheel.SetXForm(m_wheel.GetPosition, 120.0 * Pi / 180.0);
  124.    CreateLeg(-1.0, wheelAnchor);
  125.    CreateLeg(1.0, wheelAnchor);
  126.    m_wheel.SetXForm(m_wheel.GetPosition, -120.0 * Pi / 180.0);
  127.    CreateLeg(-1.0, wheelAnchor);
  128.    CreateLeg(1.0, wheelAnchor);
  129. end;
  130. procedure TJansenWalker.CreateLeg(s: Float; const wheelAnchor: TVector2);
  131. var
  132.    p1, p2, p3, p4, p5, p6: TVector2;
  133.    sd1, sd2: Tb2PolygonDef;
  134.    bd1, bd2: Tb2BodyDef;
  135.    body1, body2: Tb2Body;
  136.    djd: Tb2DistanceJointDef;
  137.    rjd: Tb2RevoluteJointDef;
  138. begin
  139.    p1 := MakeVector(5.4 * s, -6.1);
  140.    p2 := MakeVector(7.2 * s, -1.2);
  141.    p3 := MakeVector(4.3 * s, -1.9);
  142.    p4 := MakeVector(3.1 * s, 0.8);
  143.    p5 := MakeVector(6.0 * s, 1.5);
  144.    p6 := MakeVector(2.5 * s, 3.7);
  145.    sd1 := Tb2PolygonDef.Create;
  146.    sd2 := Tb2PolygonDef.Create;
  147.    sd1.vertexCount := 3;
  148.    sd2.vertexCount := 3;
  149.    sd1.filter.groupIndex := -1;
  150.    sd2.filter.groupIndex := -1;
  151.    sd1.density := 1.0;
  152.    sd2.density := 1.0;
  153.    if s > 0.0 then
  154.    begin
  155.       sd1.vertices[0] := p1;
  156.       sd1.vertices[1] := p2;
  157.       sd1.vertices[2] := p3;
  158.       sd2.vertices[0] := b2Vec2_zero;
  159.       {$IFDEF OP_OVERLOAD}
  160.       sd2.vertices[1] := p5 - p4;
  161.       sd2.vertices[2] := p6 - p4;
  162.       {$ELSE}
  163.       sd2.vertices[1] := Subtract(p5, p4);
  164.       sd2.vertices[2] := Subtract(p6, p4);
  165.       {$ENDIF}
  166.    end
  167.    else
  168.    begin
  169.       sd1.vertices[0] := p1;
  170.       sd1.vertices[1] := p3;
  171.       sd1.vertices[2] := p2;
  172.       sd2.vertices[0] := b2Vec2_zero;
  173.       {$IFDEF OP_OVERLOAD}
  174.       sd2.vertices[1] := p6 - p4;
  175.       sd2.vertices[2] := p5 - p4;
  176.       {$ELSE}
  177.       sd2.vertices[1] := Subtract(p6, p4);
  178.       sd2.vertices[2] := Subtract(p5, p4);
  179.       {$ENDIF}
  180.    end;
  181.    bd1 := Tb2BodyDef.Create;
  182.    bd2 := Tb2BodyDef.Create;
  183.    bd1.position := m_offset;
  184.    {$IFDEF OP_OVERLOAD}
  185.    bd2.position := p4 + m_offset;
  186.    {$ELSE}
  187.    bd2.position := Add(p4, m_offset);
  188.    {$ENDIF}
  189.    bd1.angularDamping := 10.0;
  190.    bd2.angularDamping := 10.0;
  191.    body1 := m_world.CreateBody(bd1);
  192.    body2 := m_world.CreateBody(bd2);
  193.    body1.CreateShape(sd1);
  194.    body2.CreateShape(sd2);
  195.    body1.SetMassFromShapes;
  196.    body2.SetMassFromShapes;
  197.    djd := Tb2DistanceJointDef.Create;
  198.    {$IFDEF OP_OVERLOAD}
  199.    djd.Initialize(body1, body2, p2 + m_offset, p5 + m_offset);
  200.    {$ELSE}
  201.    djd.Initialize(body1, body2, Add(p2, m_offset), Add(p5, m_offset));
  202.    {$ENDIF}
  203.    m_world.CreateJoint(djd, False);
  204.    {$IFDEF OP_OVERLOAD}
  205.    djd.Initialize(body1, body2, p3 + m_offset, p4 + m_offset);
  206.    {$ELSE}
  207.    djd.Initialize(body1, body2, Add(p3, m_offset), Add(p4, m_offset));
  208.    {$ENDIF}
  209.    m_world.CreateJoint(djd, False);
  210.    {$IFDEF OP_OVERLOAD}
  211.    djd.Initialize(body1, m_wheel, p3 + m_offset, wheelAnchor + m_offset);
  212.    {$ELSE}
  213.    djd.Initialize(body1, m_wheel, Add(p3, m_offset), Add(wheelAnchor, m_offset));
  214.    {$ENDIF}
  215.    m_world.CreateJoint(djd, False);
  216.    {$IFDEF OP_OVERLOAD}
  217.    djd.Initialize(body2, m_wheel, p6 + m_offset, wheelAnchor + m_offset);
  218.    {$ELSE}
  219.    djd.Initialize(body2, m_wheel, Add(p6, m_offset), Add(wheelAnchor, m_offset));
  220.    {$ENDIF}
  221.    m_world.CreateJoint(djd);
  222.    rjd := Tb2RevoluteJointDef.Create;
  223.    {$IFDEF OP_OVERLOAD}
  224.    rjd.Initialize(body2, m_chassis, p4 + m_offset);
  225.    {$ELSE}
  226.    rjd.Initialize(body2, m_chassis, Add(p4, m_offset));
  227.    {$ENDIF}
  228.    m_world.CreateJoint(rjd);
  229. end;
  230. procedure TJansenWalker.Step(var settings: TSettings; timeStep: Float);
  231. begin
  232.    inherited;
  233.  DrawText('Keys: left = A, brake = S, right = D, toggle motor = M');
  234. end;
  235. procedure TJansenWalker.Keyboard(key: Byte);
  236. begin
  237.    case key of
  238.       65{A}:
  239.          begin
  240.       m_chassis.WakeUp;
  241.       m_motorJoint.m_motorSpeed := -m_motorSpeed;
  242.          end;
  243.       83{S}:
  244.          begin
  245.       m_chassis.WakeUp;
  246.       m_motorJoint.m_motorSpeed := 0.0;
  247.          end;
  248.       68{D}:
  249.          begin
  250.       m_chassis.WakeUp;
  251.       m_motorJoint.m_motorSpeed := m_motorSpeed;
  252.          end;
  253.       77{M}:
  254.          begin
  255.       m_chassis.WakeUp;
  256.       m_motorJoint.MotorEnabled := not m_motorJoint.MotorEnabled;
  257.          end;
  258.    end;
  259. end;
  260. initialization
  261.    RegisterTestEntry('Theo Jansen''s Walker', TJansenWalker);
  262. end.