lovexyn0827
首先排除速度。尽管Motion的取值对于大部分实体来说接近速度,但是因为每游戏刻Motion可以变化多次,所以不一定等于这一刻的位移(此处忽略浮点数误差)。例如,TNT的位移是其Motion值(tick末)除以0.98再加上0.04。另外,部分实体不受Motion影响,即使Motion不为零也不会自主移动,如画,物品展示框,末影水晶等。

晴路卡
本帖最后由 晴路卡 于 2021-2-5 10:01 编辑

墙是不能穿过的障碍,
玫瑰是红色的花,
旗帜是胜利的标志,
提问的人是你,
Motion是记录有三个双精度浮点值的列表类型的实体共通标签。

QWERTY770
本帖最后由 QWERTY_52_38 于 2021-2-5 10:09 编辑

这是net.minecraft.entity.Entity类的代码

motion其实是Vector3D


  1. private Vector3d motion = Vector3d.ZERO;

  2. public void move(MoverType typeIn, Vector3d pos) {
  3.       if (this.noClip) {
  4.          this.setBoundingBox(this.getBoundingBox().offset(pos));
  5.          this.resetPositionToBB();
  6.       } else {
  7.          if (typeIn == MoverType.PISTON) {
  8.             pos = this.handlePistonMovement(pos);
  9.             if (pos.equals(Vector3d.ZERO)) {
  10.                return;
  11.             }
  12.          }

  13.          this.world.getProfiler().startSection("move");
  14.          if (this.motionMultiplier.lengthSquared() > 1.0E-7D) {
  15.             pos = pos.mul(this.motionMultiplier);
  16.             this.motionMultiplier = Vector3d.ZERO;
  17.             this.setMotion(Vector3d.ZERO);
  18.          }

  19.          pos = this.maybeBackOffFromEdge(pos, typeIn);
  20.          Vector3d vector3d = this.getAllowedMovement(pos);
  21.          if (vector3d.lengthSquared() > 1.0E-7D) {
  22.             this.setBoundingBox(this.getBoundingBox().offset(vector3d));
  23.             this.resetPositionToBB();
  24.          }

  25.          this.world.getProfiler().endSection();
  26.          this.world.getProfiler().startSection("rest");
  27.          this.collidedHorizontally = !MathHelper.epsilonEquals(pos.x, vector3d.x) || !MathHelper.epsilonEquals(pos.z, vector3d.z);
  28.          this.collidedVertically = pos.y != vector3d.y;
  29.          this.onGround = this.collidedVertically && pos.y < 0.0D;
  30.          BlockPos blockpos = this.getOnPosition();
  31.          BlockState blockstate = this.world.getBlockState(blockpos);
  32.          this.updateFallState(vector3d.y, this.onGround, blockstate, blockpos);
  33.          Vector3d vector3d1 = this.getMotion();
  34.          if (pos.x != vector3d.x) {
  35.             this.setMotion(0.0D, vector3d1.y, vector3d1.z);
  36.          }

  37.          if (pos.z != vector3d.z) {
  38.             this.setMotion(vector3d1.x, vector3d1.y, 0.0D);
  39.          }

  40.          Block block = blockstate.getBlock();
  41.          if (pos.y != vector3d.y) {
  42.             block.onLanded(this.world, this);
  43.          }

  44.          if (this.onGround && !this.isSteppingCarefully()) {
  45.             block.onEntityWalk(this.world, blockpos, this);
  46.          }

  47.          if (this.canTriggerWalking() && !this.isPassenger()) {
  48.             double d0 = vector3d.x;
  49.             double d1 = vector3d.y;
  50.             double d2 = vector3d.z;
  51.             if (!block.isIn(BlockTags.CLIMBABLE)) {
  52.                d1 = 0.0D;
  53.             }

  54.             this.distanceWalkedModified = (float)((double)this.distanceWalkedModified + (double)MathHelper.sqrt(horizontalMag(vector3d)) * 0.6D);
  55.             this.distanceWalkedOnStepModified = (float)((double)this.distanceWalkedOnStepModified + (double)MathHelper.sqrt(d0 * d0 + d1 * d1 + d2 * d2) * 0.6D);
  56.             if (this.distanceWalkedOnStepModified > this.nextStepDistance && !blockstate.isAir(this.world, blockpos)) {
  57.                this.nextStepDistance = this.determineNextStepDistance();
  58.                if (this.isInWater()) {
  59.                   Entity entity = this.isBeingRidden() && this.getControllingPassenger() != null ? this.getControllingPassenger() : this;
  60.                   float f = entity == this ? 0.35F : 0.4F;
  61.                   Vector3d vector3d2 = entity.getMotion();
  62.                   float f1 = MathHelper.sqrt(vector3d2.x * vector3d2.x * (double)0.2F + vector3d2.y * vector3d2.y + vector3d2.z * vector3d2.z * (double)0.2F) * f;
  63.                   if (f1 > 1.0F) {
  64.                      f1 = 1.0F;
  65.                   }

  66.                   this.playSwimSound(f1);
  67.                } else {
  68.                   this.playStepSound(blockpos, blockstate);
  69.                }
  70.             } else if (this.distanceWalkedOnStepModified > this.nextFlap && this.makeFlySound() && blockstate.isAir(this.world, blockpos)) {
  71.                this.nextFlap = this.playFlySound(this.distanceWalkedOnStepModified);
  72.             }
  73.          }

  74.          try {
  75.             this.doBlockCollisions();
  76.          } catch (Throwable throwable) {
  77.             CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Checking entity block collision");
  78.             CrashReportCategory crashreportcategory = crashreport.makeCategory("Entity being checked for collision");
  79.             this.fillCrashReport(crashreportcategory);
  80.             throw new ReportedException(crashreport);
  81.          }

  82.          float f2 = this.getSpeedFactor();
  83.          this.setMotion(this.getMotion().mul((double)f2, 1.0D, (double)f2));
  84.          if (BlockPos.getAllInBox(this.getBoundingBox().shrink(0.001D)).noneMatch((p_233572_0_) -> {
  85.             BlockState state = world.getBlockState(p_233572_0_);
  86.             return state.isIn(BlockTags.FIRE) || state.isIn(Blocks.LAVA) || state.isBurning(world, p_233572_0_);
  87.          }) && this.fire <= 0) {
  88.             this.forceFireTicks(-this.getFireImmuneTicks());
  89.          }

  90.          if (this.isInWaterRainOrBubbleColumn() && this.isBurning()) {
  91.             this.playSound(SoundEvents.ENTITY_GENERIC_EXTINGUISH_FIRE, 0.7F, 1.6F + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.4F);
  92.             this.forceFireTicks(-this.getFireImmuneTicks());
  93.          }

  94.          this.world.getProfiler().endSection();
  95.       }
  96.    }
复制代码


至于TNT这东西,只不过是重写了而已

  1. public void tick() {
  2.       if (!this.hasNoGravity()) {
  3.          this.setMotion(this.getMotion().add(0.0D, -0.04D, 0.0D));
  4.       }

  5.       this.move(MoverType.SELF, this.getMotion());
  6.       this.setMotion(this.getMotion().scale(0.98D));
  7.       if (this.onGround) {
  8.          this.setMotion(this.getMotion().mul(0.7D, -0.5D, 0.7D));
  9.       }

  10.       --this.fuse;
  11.       if (this.fuse <= 0) {
  12.          this.remove();
  13.          if (!this.world.isRemote) {
  14.             this.explode();
  15.          }
  16.       } else {
  17.          this.func_233566_aG_();
  18.          if (this.world.isRemote) {
  19.             this.world.addParticle(ParticleTypes.SMOKE, this.getPosX(), this.getPosY() + 0.5D, this.getPosZ(), 0.0D, 0.0D, 0.0D);
  20.          }
  21.       }
  22.    }
复制代码


注意到this.setMotion(this.getMotion().scale(0.98D));
这就是TNT的motion要乘以0.98的原因

至于画和展示框……
它们都是HangingEntity的一种
  1. public void move(MoverType typeIn, Vector3d pos) {
  2.     if (!this.world.isRemote && !this.removed && pos.lengthSquared() > 0.0D) {
  3.         this.remove();
  4.         this.onBroken((Entity)null);
  5.     }
  6. }
复制代码

  1. public void onBroken(@Nullable Entity brokenEntity) {
  2.     this.playSound(SoundEvents.ENTITY_ITEM_FRAME_BREAK, 1.0F, 1.0F);
  3.     this.dropItemOrSelf(brokenEntity, true);
  4. }
复制代码

这种东西一移动就被破坏了

lovexyn0827
晴路卡 发表于 2021-2-5 09:58
墙是不能穿过的障碍,
玫瑰是红色的花,
旗帜是胜利的标志,

Pos也是。问的不是归类,是如何定义

lovexyn0827
QWERTY_52_38 发表于 2021-2-5 10:00
这是net.minecraft.entity.Entity类的代码

motion其实是Vector3D

这些代码近几天都看过,算是复习一遍吧。话说回来,定义是啥?总不能Vector3d(Vector with 3
doubles)吧。

QWERTY770
lovexyn0827 发表于 2021-2-5 16:45
这些代码近几天都看过,算是复习一遍吧。话说回来,定义是啥?总不能Vector3d(Vector with 3
doubles) ...

这东西本来就没有统一定义

你可以重写他

第一页 上一页 下一页 最后一页