phaser-arcade-physic模拟池塘放鱼自由游动及参数调节效果代码

代码语言:html

所属分类:动画

代码描述:phaser-arcade-physic模拟池塘放鱼自由游动及参数调节效果代码

代码标签: phaser-arcade-physic 模拟 池塘 自由 游动 参数 调节

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">

  <meta name="viewport" content="width=1024">
  
  
  
<style>
html, body {
  height: 100%;
}

body {
  margin: 0;
  padding: 0;
  background: #111;
  color: #eee;
  font: caption;
}

#version {
  position: absolute;
  left: 0;
  top: 0;
  padding: 0;
  background: rgba(0, 0, 0, 0.5)
}
</style>


  
</head>

<body >
  <footer><div id=version></div></footer>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/phaser-arcade-physics.min.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/colors.1.2.0.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/tweakpane.3.0.5.js"></script>
      <script  >
/* global colors, Phaser, Tweakpane */

const TIMESCALE = 1;
const ZOOM = 1;
const PHYSICS_STEPS_PER_SEC = 60;
const DEBUG = false;
const DEBUG_PHYSICS = false;

const options = {
  alignWeight: 0.8,
  cohereWeight: 0.4,
  containRadius: 512,
  containTime: 1,
  containWeight: 0.6,
  maxForce: 120,
  maxSpeed: 60,
  nearRange: 60,
  quantity: 100,
  separateRange: 15,
  separateWeight: 0.2,
  wanderRadius: 0.25,
  wanderSpeed: 360,
  wanderStrength: 0.5,
  wanderWeight: 1
};

const debugOptions = {
  acceleration: false,
  align: true,
  cohere: true,
  contain: true,
  nearRange: false,
  separate: true,
  separateRange: false,
  velocity: false,
  wander: true,
  wanderRadius: true
};

const { hexColors } = colors;

const RandomAngle = Phaser.Math.Angle.Random;
const FloatBetween = Phaser.Math.FloatBetween;
const RotateTo = Phaser.Math.RotateTo;
const DegToRad = Phaser.Math.DegToRad;
const Remove = Phaser.Utils.Array.Remove;
const Vector2 = Phaser.Math.Vector2;
const Circle = Phaser.Geom.Circle;
const Line = Phaser.Geom.Line;
const ZERO = Phaser.Math.Vector2.ZERO;

const bodyIsEnabled = function (body) {
  return body.enable === true;
};

const bodyIsFish = function (body) {
  return body.gameObject.name === "fish";
};

const getBodyCenter = function (body) {
  return body.center;
};

const getAvg = function (vectors, out) {
  out.reset();

  for (const v of vectors) {
    out.add(v);
  }

  out.scale(1 / vectors.length);

  return out;
};

const projectBody = function (body, time, pOut) {
  const { center, velocity } = body;

  return pOut.set(center.x + time * velocity.x, center.y + time * velocity.y);
};

// Vector

Phaser.Geom.Line.prototype.setFromPoints = function (a, b) {
  this.setTo(a.x, a.y, b.x, b.y);
};

Phaser.Geom.Line.prototype.setEmpty = function () {
  this.setTo(0, 0, 0, 0);
};

class Fish extends Phaser.GameObjects.Triangle {
  constructor(scene, x, y) {
    super(scene, x, y, 0, 4, 16, 0, 16, 8, hexColors.green, 0.8);

    this.name = "fish";

    // Steering forces
    this.fAlign = new Vector2();
    this.fCohere = new Vector2();
    this.fContain = new Vector2();
    this.fSeparate = new Vector2();
    this.fWander = new Vector2();

    // Positions
    this.pCohere = new Vector2();
    this.pContain = new Vector2();
    this.pWander = new Vector2();

    // Areas
    this.separateCirc = new Circle();
    this.nearCirc = new Circle();
    this.wanderCirc = new Circle();

    // Debug draw
    this.debugWanderCirc = new Circle();

    const { world } = this.scene.physics;

    this.wanderHost = scene.add.zone(0, 0, 1, 1);
    world.enableBody(this.wanderHost);
    this.wanderBody = this.wanderHost.body;

    this.once("destroy", this.onDestroy, this);
  }

  onDestroy() {
    this.wanderHost.destroy();
    this.wanderHost = null;
    this.wanderBody = null;
  }

  align(bodies, fAlign) {
    fAlign.reset();

    if (bodies.length === 0) return fAlign;

    const dBody = new Vector2();
    const vBody = new Vector2();
    const vSum = new Vector2();

    let productSum = 0;

    for (const body of bodies) {
      this.distanceTo(body.center, dBody);

      const product = dBody.dot(this.body.velocity) / dBody.length();

      if (product <= 0) continue;

      productSum += product;

      vBody.copy(body.velocity).scale(product);

      vSum.add(vBody);
    }

    if (vSum.equals(ZERO)) return fAlign;

    vSum.scale(1 / productSum);

    this.steer(vSum, fAlign);

    return fAlign;
  }

  flee(pTarget, fFlee) {
    this.distanceFrom(pTarget, fFlee);

    // Desired velocity.
    fFlee.setLength(options.maxSpeed);

    return this.steer(fFlee, fFlee);
  }

  cohere(bodies, fCohere) {
    fCohere.reset();

    if (bodies.length === 0) return fCohere;

    getAvg(bodies.map(getBodyCenter), this.pCohere);

    return this.seek(this.pCohere, fCohere);
  }

  distanceFrom(pTarget, dFrom) {
    return dFrom.copy(this.body.center).subtract(pTarget);
  }

  distanceTo(pTarget, dTo) {
    return dTo.copy(pTarget).subtract(this.body.center);
  }

  draw(graphic) {
    const {
      acceleration,
      align,
      cohere,
      contain,
      nearRange,
      separate,
      separateRange,
      velocity,
      wander,
      wanderRadius
    } = debugOptions;

    if (align) {
      this.drawSteer(graphic, this.fAlign, hexColors.yellow);
    }

    if (cohere) {
      this.drawSteer(graphic, this.fCohere, hexColors.yellow);
      this.drawPoint(graphic, this.pCohere, hexColors.yellow);
    }

    if (contain) {
      this.drawSteer(graphic, this.fContain, hexColors.red);
      this.drawPoint(graphic, this.pContain, hexColors.red);
    }

    if (separate) {
      this.drawSteer(graphic, this.fSeparate, hexColors.yellow);
    }

    if (nearRange) {
      this.drawCircle(graphic, this.nearCirc, hexColors.gray);
    }

    if (separateRange) {
      this.drawCircle(graphic, this.separateCirc, hexColors.gray);
    }

    if (wander) {
      this.drawSteer(graphic, this.fWander, hexColors.fuchsia);
      this.drawCircle(graphic, this.debugWanderCirc, hexColors.fuchsia);
    }

    if (velocity) {
      this.drawSteer(graphic, this.body.velocity, hexColors.lime);
    }

    if (acceleration) {
      this.drawSteer(graphic, this.body.acceleration, hexColors.red);
    }
  }

  drawCircle(graphic, circle, color) {
    graphic.lineStyle(1, color).strokeCircleShape(circle);
  }

  drawLine(graphic, line, color) {
    graphic.lineStyle(1, color).strokeLineShape(line);
  }

  drawPoint(graphic, point, color) {
    graphic.fillStyle(color).fillPointShape(point, 3);
  }

  drawRect(graphic, rect, color) {
    graphic.lineStyle(1, color).strokeRectShape(rect);
  }

  drawSteer(graphic, fSteer, color) {
    const { x, y } = this.body.center;

    graphic.lineStyle(1, color).lineBetween(x, y, x + fSteer.x, y + fSteer.y);
  }

  drawVector(graphic, vector, x, y, color) {
    graphic.lineStyle(1, color).lineBetween(x, y, x + vector.x, y + vector.y);
  }

  overlap(rect, includeDynamic, includeStatic) {
    const bodies = this.scene.physics.overlapRect(
      rect.x,
      rect.y,
      rect.width,
      rect.height,
      includeDynamic,
      includeStatic
    );

    Remove(bodies, this.body);

    return bodies;
  }

  overlapCirc(circ, includeDynamic, includeStatic) {
    const bodies = this.scene.physics.overlapCirc(
      circ.x,
      circ.y,
      circ.radius,
      includeDynamic,
      includeStatic
    );

    Remove(bodies, this.body);

    return bodies;
  }

  overlapPoint(point, includeDynamic, includeStatic) {
    const bodies = this.scene.physics.overlapRect(
      point.x,
      point.y,
      1,
      1,
      includeDynamic,
      includeStatic
    );

    Remove(bodies, this.body);

    return bodies;
  }

  seek(pTarget, fSeek) {
    // Distance to target.
    this.distanceTo(pTarget, fSeek);

    // Desired velocity.
    fSeek.scale(PHYSICS_STEPS_PER_SEC);

    // Steering force.
    return this.steer(fSeek, fSeek);
  }

  separate(bodies, fSeparate) {
    fSeparate.reset();

    if (bodies.length === 0) return fSeparate;

    // Distance to each body. Recycled.
    cons.........完整代码请登录后点击上方下载按钮下载查看

网友评论0