交通轨迹动画效果
代码语言:html
所属分类:动画
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title> traffic</title> </head> <body translate="no"> <script> "use strict"; /* no street : they run everywhere */ window.addEventListener("load", function () { let canv, ctx; let sqSide; let nbx, nby; // nb of squares horiz. / vert. let terrain; // bi-dimensionnal array for car paths let cars; let blocked, veryVeryBlocked; // thresholds for blocking detection let carsMaxLength; // maximum length for cars let nbCars; // number of cars let initTime; let msByStep; // interval between 2 moves /******************************************************** parameters - play with them ********************************************************/ const bgColor = '#004'; // background color nbCars = 20; // number of cars /* an 'element' is a little square - a car id made of a few elements */ carsMaxLength = 15; // cars max length (in elements, not pixels) nbx = 50; // width (in elements) msByStep = 100; // ms between 2 moves blocked = 2 * carsMaxLength; // threshold for blocking detection veryVeryBlocked = 3 * carsMaxLength; // threshold for blocking detection //******************************************************** // shortcuts for Math const mrandom = Math.random; const mfloor = Math.floor; const mceil = Math.ceil; const mround = Math.round; const mabs = Math.abs; const mmin = Math.min; const mmax = Math.max; const mPI = Math.PI; const mPIS2 = Math.PI / 2; const m2PI = Math.PI * 2; const msin = Math.sin; const mcos = Math.cos; const matan2 = Math.atan2; const mhypot = Math.hypot; const msqrt = Math.sqrt; //------------------------------------------------------------------------ // classe Car function Car(index) { /* color points = [[x,y],[x,y]..] dir 0 1 2 3 = up right down left index identifier ntci nb of turns without moving nbSteps nb of steps to go ahead in a direction */ let kx, ky, lum; // lum = (index == 0) ? 70 : 30; lum = 60; this.color = `hsl(${alea(360)}, 100%, ${lum}%)`; this.size = intAlea(2, carsMaxLength + 1); // length in elements this.points = []; // to store "pieces" of a car this.dir = intAlea(4); // 0 1 2 3 = up right down left this.index = index; // identifier for car this.ntci = 0; // nb of turns without moving do { kx = intAlea(nbx); // choose a free cell ky = intAlea(nby); } while (terrain[ky][kx] != -1); terrain[ky][kx] = index; for (let kp = 0; kp < this.size; ++kp) { this.points[kp] = [kx, ky]; } // for kp this.initNbSteps(); } // function Car // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Car.prototype.initNbSteps = function () { /* the direction beeing given by this.dir, computes the number of steps the car will go ahead. Normally, some random position between present position and the edge of the terrain in the given direction */ let e1, e2; let [x, y] = this.points[0]; switch (this.dir) { case 0:e1 = 0;e2 = y;break; case 1:e1 = x + 1;e2 = nbx;break; case 2:e1 = y + 1;e2 = nby;break; case 3:e1 = 0;e2 = x;break;} if (e2 <= e1) ++e2; this.nbSteps = intAlea(e2 - e1); }; // Car.prototype.initNbSteps // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Car.prototype.move = function () { /* moves the car, if possible straightforward for nbSteps, avoiding collisions and using unblocking strategies */ let x, y, kfront; this.ntci++; // count blockigg time a priori if (this.ntci > 2000) {// things are going very wrong console.dir(this); throw "blocked ! "; } /* is it time to change of direction ? */ if (this.nbSteps < 0) { this.turn(); return; } /* try to go ahead */ [x, y] = this.futurePosition(this.dir); if (Car.ifOutOfTerrain(x, y)) { this.turn(); return; } // if hit edge kfront = terrain[y][x]; if (kfront == -1) {// free place, we can go this.moveOneStep(); return; } // detect if front shock if (cars[kfront].points[0][0] == x && cars[kfront].points[0][1] == y && cars[kfront].dir == (this.dir + 2) % 4) { this.doUTurn(); return; } // if front shock if (this.ntci > blocked) {// if waiting for too long this.turn(); // try to turn if (this.ntci > veryVeryBlocked) {// if waiting for really too long this.doUTurn(); // try U turn } return; } }; // Car.prototype.move // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Car.ifOutOfTerrain = function (x, y) { /* tests if a cell is outside the terrain */ return x < 0 || x >= nbx || y < 0 || y >= nby; }; // Car.ifOutOfTerrain // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Car.prototype.futurePosition = function (dir) { /* evaluates futer place if we go towards the 'dir' direction */ let x, y; x = this.points[0][0] + [0, 1, 0, -1][dir]; y = this.points[0][1] + [-1, 0, 1, 0][dir]; return [x, y]; }; // Car.prototype.futurePosition // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Car.prototype.turn = function () { /* change l'orientation de 90 degrés */ let x, y; this.dir = (this.dir + 1 + 2 * intAlea(2)) % 4; // + ou - 1 randomly this.initNbSteps(); // nb of steps [x, y] = this.futurePosition(this.dir); if (Car.ifOutOfTerrain(x, y) || terrain[y][x] != -1) { this.dir = (this.dir + 2) % 4; // try the other side this.initNbSteps(); // nb de pas [x, y] = this.futurePosition(this.dir); if (Car.ifOutOfTerrain(x, y) || terrain[y][x] != -1) { return; // still blocked… } // if blocked } // if cannot on one side this.moveOneStep(); // Now we can go }; // Car.prototype.turn // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Car.prototype.doUTurn = function () { /* reverts head and tail and moves one step */ let x, y, xpre, ypre; let k1 = 0; // the first let k2 = this.points.length - 1; // the last /* the present head becomes tail : redraw it as a simple element */ [x, y] = this.points[0]; drawElement(x, y, this.color); for (; k1 < k2; ++k1, --k2) {// revert elements of car [this.points[k1], this.points[k2]] = [this.points[k2], this.points[k1]]; } // evaluate new direction from first new two elements [x, y] = this.points[0]; [xpre, ypre] = this.points[1]; if (y < ypre) this.dir = 0; // up else if (x > xpre) this.dir = 1; // right else if (y > y.........完整代码请登录后点击上方下载按钮下载查看
网友评论0