public/lib/world.js

分割 2 / 2 · 元ファイル 266〜358行付近

原文の連続部分です。長い圧縮行は行の途中で分割する場合があります。全分割を順に連結するとファイル全文になります。

      c.x-=C.CROW_SPD*dt;
      c.y=c.y0+Math.sin(c.ph*0.3)*0.10;
      if(c.cd>0) c.cd-=dt;
      p=this.front();
      if(full && c.cd<=0 && p && p.alive && Math.abs(c.x-this.xOf(p.id))<0.35){
        c.dive=C.CROW_DIVE_CD; c.bit=0;
      }
      if(c.x<-0.8) this.cs.splice(i,1);
    }
  }

  /* 終わり。生きている人が1人もいなくなったら世界は終わる */
  if(full && !this.over && this.ps.length>0){
    var any=false;
    for(i=0;i<this.ps.length;i++) if(this.ps[i].alive) any=true;
    if(!any){ this.over=true; this.ev.push({e:'over'}); }
  }
};

/* ---------- サーバー→端末に送る中身 ----------
   数だけの短い形にする。1秒に12回送る物なので、名前の長い鍵を使わない */
World.prototype.snap=function(){
  var z=[],c=[],p=[],i;
  for(i=0;i<this.zs.length;i++){
    var a=this.zs[i];
    z.push([a.id, +a.x.toFixed(3), +a.spd.toFixed(3), a.dead?1:0, a.gr?1:0,
            a.look.h, a.look.hc, a.look.sk, a.look.w, +a.tilt.toFixed(2)]);
  }
  for(i=0;i<this.cs.length;i++){
    var b=this.cs[i];
    c.push([b.id, +b.x.toFixed(3), +b.y.toFixed(3), b.dead?1:0, b.dive>0?1:0]);
  }
  for(i=0;i<this.ps.length;i++){
    var q=this.ps[i];
    p.push([q.id, Math.round(q.hp), q.alive?1:0, q.base, +Math.max(0,q.bT-this.t).toFixed(1),
            q.av.h,q.av.hc,q.av.sk,q.av.w, q.look.c,q.look.ht,q.look.st]);
  }
  var e=this.ev; this.ev=[];
  return { y:'s', t:+this.t.toFixed(2), q:++this.seq, k:this.kills, o:this.over?1:0,
           m:this.mult(), z:z, c:c, p:p, e:e };
};
/* 端末側: 届いた中身を今の世界へ合わせる。
   ゾンビの横位置は**飛ばさずに寄せる**(カクカクさせない。K1「ガクガクしない」)。
   離れすぎている時だけ飛ばす(入ってきた直後・裏に回って戻った時) */
World.prototype.apply=function(s,meId){
  var i,j,seen={},z;
  this.t=s.t; this.kills=s.k; this.over=!!s.o; this.seq=s.q;
  for(i=0;i<s.z.length;i++){
    var a=s.z[i]; seen[a[0]]=1;
    z=this.zById(a[0]);
    if(!z){
      z={ id:a[0], x:a[1], spd:a[2], kb:0, stag:0, gr:null, dead:0, dt:0,
          look:{h:a[5],hc:a[6],sk:a[7],w:a[8]}, ph:(a[0]*0.7)%6.28, tilt:a[9] };
      this.zs.push(z);
    }
    z.spd=a[2];
    if(Math.abs(z.x-a[1])>0.75) z.x=a[1]; else z.x+=(a[1]-z.x)*0.34;
    if(a[3]&&!z.dead){ z.dead=1; z.dt=0; }
    z.gr=a[4]?'x':null;
  }
  for(i=this.zs.length-1;i>=0;i--) if(!seen[this.zs[i].id] && !this.zs[i].dead) this.zs.splice(i,1);

  seen={};
  for(i=0;i<s.c.length;i++){
    var b=s.c[i]; seen[b[0]]=1;
    var c=this.cById(b[0]);
    if(!c){ c={ id:b[0], x:b[1], y:b[2], y0:b[2], dead:0, dt:0, dive:0, cd:0, ph:(b[0]*1.3)%6.28 }; this.cs.push(c); }
    if(Math.abs(c.x-b[1])>0.75) c.x=b[1]; else c.x+=(b[1]-c.x)*0.34;
    c.y+=(b[2]-c.y)*0.34;
    c.dive=b[4]?1:0;
    if(b[3]&&!c.dead){ c.dead=1; c.dt=0; }
  }
  for(i=this.cs.length-1;i>=0;i--) if(!seen[this.cs[i].id] && !this.cs[i].dead) this.cs.splice(i,1);

  /* 人は並び順がそのまま前衛/後衛。届いた順に作り直す */
  var np=[];
  for(i=0;i<s.p.length;i++){
    var q=s.p[i], old=this.find(q[0]);
    var pl=old||{ id:q[0], av:{h:0,hc:0,sk:0,w:0}, look:{c:0,ht:0,st:0} };
    pl.hp=q[1]; pl.alive=!!q[2]; pl.base=q[3]; pl.bT=this.t+q[4];
    pl.av={h:q[5],hc:q[6],sk:q[7],w:q[8]};
    pl.look={c:q[9],ht:q[10],st:q[11]};
    np.push(pl);
  }
  this.ps=np;
  return s.e||[];
};
/* 端末側の毎コマ: 動きだけ進める(湧かない・HPを削らない・倒さない) */

var M={ World:World, C:C };
if(typeof module!=='undefined'&&module.exports) module.exports=M;
root.ZWORLD=M;
})(typeof globalThis!=='undefined'?globalThis:this);