second
This commit is contained in:
parent
5f7fcb96ed
commit
01204dfa2f
34 changed files with 1498 additions and 0 deletions
21
worker.js
Normal file
21
worker.js
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import {World,DT} from './engine.js?v=41';
|
||||
import {roleCode} from './ecology/feeding.js';
|
||||
const seedBuffer=new Uint32Array(1);crypto.getRandomValues(seedBuffer);const world=new World(seedBuffer[0]);let speed=1,statMode=false,last=performance.now(),debt=0,lastSend=0,lastMeasure=last,steps=0,actual=0,selected=null,limited=false,lastFieldEpoch=-1,lastSummary=0,forceSnapshot=true,lastHistoryTime=-1,lastEvent=null,awaitingAck=false,waterDirty=true,rocksDirty=true,moistureDirty=true;
|
||||
|
||||
onmessage=({data:d})=>{
|
||||
if(d.type==='ack'){awaitingAck=false;return}
|
||||
if(d.type==='speed'){speed=d.speed;statMode=d.stat;debt=0;last=performance.now();forceSnapshot=true}
|
||||
if(d.type==='water'){const ok=world.setWater(d.water);if(ok){world.log('水域を編集');waterDirty=true;moistureDirty=true}postMessage({type:'notice',text:ok?'水域を更新しました':'生物の退避先がないため、水域の変更を取り消しました'});forceSnapshot=true;send()}
|
||||
if(d.type==='rocks'){const ok=world.setRocks(d.rocks);if(ok){world.log('岩を編集');rocksDirty=true}postMessage({type:'notice',text:ok?'岩を更新しました':'安全な退避先がないため、岩の変更を取り消しました'});forceSnapshot=true;send()}
|
||||
if(d.type==='load-profile'){try{world.setAquaticProfile(d.profile);moistureDirty=true;forceSnapshot=true;send()}catch(error){postMessage({type:'notice',text:error.message})}}
|
||||
if(d.type==='select'){selected=d.id;forceSnapshot=true;send()}
|
||||
};
|
||||
|
||||
|
||||
function send(){
|
||||
if(awaitingAck)return;const now=performance.now(),summary=forceSnapshot||now-lastSummary>850,field=!statMode&&(forceSnapshot||Math.floor(world.tick/20)!==lastFieldEpoch),a=world.animals.find(a=>a.id===selected&&!a.dead);const packet={type:'state',actual,limited,statMode};const alive=statMode?[]:world.animals.filter(a=>!a.dead),data=new Float32Array(alive.length*7),ids=new Uint32Array(alive.length),sids=new Uint32Array(alive.length);
|
||||
for(let i=0;i<alive.length;i++){const a=alive[i],j=i*7;ids[i]=a.id;sids[i]=a.sid;data[j]=a.x;data[j+1]=a.y;data[j+2]=world.radius(a);data[j+3]=a.vx;data[j+4]=a.vy;data[j+5]=roleCode(world.species[a.sid]?.trophicRole);data[j+6]=a.g.waterAffinity}packet.animalData=data;packet.animalIds=ids;packet.animalSids=sids;
|
||||
if(summary){packet.stats=world.stats();const newest=world.history.at(-1)?.time;if(forceSnapshot||newest!==lastHistoryTime){packet.history=world.history;lastHistoryTime=newest}if(forceSnapshot||world.events[0]!==lastEvent){packet.events=world.events;lastEvent=world.events[0]}packet.selected=a?{id:a.id,sid:a.sid,g:a.g,age:a.age,energy:a.energy,stamina:a.stamina,maxStamina:world.staminaCapacity(a),concealment:world.concealmentAt(a.x,a.y),action:a.action,parents:a.parents,generation:a.generation,mass:world.biomass(a),maxEnergy:world.maxEnergy(a)}:null;lastSummary=now}
|
||||
if(field){packet.carcasses=world.carcasses;if(waterDirty){packet.water=world.water;waterDirty=false}if(rocksDirty){packet.rocks=world.rocks;rocksDirty=false}packet.trees=world.trees.map(({x,y,r,trunk,leaves,maxLeaves,variant})=>({x,y,r,trunk,leaves,maxLeaves,variant}));packet.fallen=world.fallen;packet.plants=world.plants;if(moistureDirty){packet.moisture=world.moisture;moistureDirty=false}lastFieldEpoch=Math.floor(world.tick/20)}if(statMode)packet.carcasses=[];awaitingAck=true;postMessage(packet,[data.buffer,ids.buffer,sids.buffer]);forceSnapshot=false;lastSend=now;
|
||||
}
|
||||
function loop(){const now=performance.now(),elapsed=Math.min(.2,(now-last)/1000);last=now;if(speed){debt=Math.min(debt+elapsed*speed,DT*300);const start=performance.now();while(debt>=DT&&performance.now()-start<22){world.step();debt-=DT;steps++;if(world.animals.length>18000){speed=0;limited=true;world.log('計算保護:18,000個体を超えたため一時停止');break}}}if(now-lastMeasure>1000){actual=steps*DT/((now-lastMeasure)/1000);steps=0;lastMeasure=now}if(now-lastSend>(statMode?900:120))send();setTimeout(loop,4)}send();loop();
|
||||
Loading…
Add table
Add a link
Reference in a new issue