Initial
This commit is contained in:
commit
36a53f343e
6 changed files with 300431 additions and 0 deletions
40
Visualisation/css/main.css
Normal file
40
Visualisation/css/main.css
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
:root {
|
||||
--bg-color: #303030;
|
||||
--text-color: #EEEEEE;
|
||||
}
|
||||
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
background-color: var(--bg-color);
|
||||
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6, p {
|
||||
font-family: "Roboto", sans-serif;
|
||||
font-weight: 100;
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 5em;
|
||||
text-align: center;
|
||||
margin-top: 0;
|
||||
padding-top: 1em;
|
||||
}
|
||||
|
||||
.flexContainer {
|
||||
display: flex;
|
||||
align-content: center;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@media (max-width: 800px) {
|
||||
|
||||
}
|
||||
66
Visualisation/css/visualiser.css
Normal file
66
Visualisation/css/visualiser.css
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
:root {
|
||||
--bg-color: #303030; /*Ez a pulse háttérszíne, a canvasét jsben kell megváltoztatni */
|
||||
--pulse-color: #AAAAAA;
|
||||
}
|
||||
|
||||
.simulationContainer {
|
||||
transform: matrix(0.87,-0.50,0.93,0.62,0,0);
|
||||
-ms-transform: matrix(0.87,-0.50,0.93,0.62,0,0);
|
||||
-webkit-transform: matrix(0.87,-0.50,0.93,0.62,0,0);
|
||||
|
||||
margin: 2em calc((50% - 350px) / 2);
|
||||
}
|
||||
|
||||
.simulationContainer > .passedCarCount {
|
||||
font-size: 2.5em;
|
||||
|
||||
width: 90%;
|
||||
margin-top: 0.33em;
|
||||
text-align: right;
|
||||
|
||||
text-shadow: -10px 10px 5px rgba(0, 0, 0, 0.35);
|
||||
}
|
||||
|
||||
.simulationContainer > canvas {
|
||||
background: linear-gradient(270deg, var(--bg-color) 0%, var(--bg-color) 40%, var(--pulse-color) 50%, var(--bg-color) 60%, var(--bg-color) 100%);
|
||||
background-size: 600% 600%;
|
||||
-webkit-animation: pulsing 10s ease infinite;
|
||||
-moz-animation: pulsing 10s ease infinite;
|
||||
animation: pulsing 10s ease infinite;
|
||||
|
||||
box-shadow: -15px 10px 5px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
@-webkit-keyframes pulsing {
|
||||
0% {
|
||||
background-position: 0% 51%;
|
||||
}
|
||||
50% {
|
||||
background-position: 100% 50%;
|
||||
}
|
||||
100% {
|
||||
background-position: 0% 51%;
|
||||
}
|
||||
}
|
||||
@-moz-keyframes pulsing {
|
||||
0% {
|
||||
background-position: 0% 51%;
|
||||
}
|
||||
50% {
|
||||
background-position: 100% 50%;
|
||||
}
|
||||
100% {
|
||||
background-position: 0% 51%;
|
||||
}
|
||||
}
|
||||
@keyframes pulsing {
|
||||
0% {
|
||||
background-position: 0% 51%;
|
||||
}
|
||||
50% {
|
||||
background-position: 100% 50%;
|
||||
}
|
||||
100% {
|
||||
background-position: 0% 51%;
|
||||
}
|
||||
}
|
||||
BIN
Visualisation/favicon.png
Normal file
BIN
Visualisation/favicon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
23
Visualisation/index.html
Normal file
23
Visualisation/index.html
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Simulation</title>
|
||||
<link rel="stylesheet" type="text/css" href="css/visualiser.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/main.css">
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto:100&subset=latin-ext" rel="stylesheet">
|
||||
|
||||
<link rel="icon" type="image/png" href="favicon.png">
|
||||
<meta name="theme-color" content="#303030">
|
||||
</head>
|
||||
<body>
|
||||
<div class="flexContainer">
|
||||
<div class="simulationContainer">
|
||||
<canvas id="canvas_0"></canvas>
|
||||
<h3 class="passedCarCount" id="canvas_0_text">0000</h3>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<script type="text/javascript" src="js/visualiser.js"></script>
|
||||
<script type="text/javascript" src="js/main.js"></script>
|
||||
</html>
|
||||
5
Visualisation/js/main.js
Normal file
5
Visualisation/js/main.js
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
//Visualiser.constructor(int width, int height, string canvasID, string textID, string serverAddress, bool shouldPulse, bool shouldDrawGrid);
|
||||
|
||||
const visualiser_0 = new Visualiser(300, 300, "canvas_0", "canvas_0_text", "http://localhost:8080/", true, false);
|
||||
visualiser_0.start();
|
||||
521
Visualisation/js/visualiser.js
Normal file
521
Visualisation/js/visualiser.js
Normal file
|
|
@ -0,0 +1,521 @@
|
|||
/*
|
||||
2D vizualizáció a szimuláció állapotáról
|
||||
|
||||
Az utakon lévő autók számából találja ki, hogy milyen szélesek legyenek az utak a grafikán.
|
||||
(Ezeket a határértékeket az intToVisual methodban lehet állítani.)
|
||||
|
||||
A normálisan müködő dolgok kék színűek, a nem jó dolgok piros színűek.
|
||||
|
||||
Ha egy úton túl sok autó van, azaz dugó alakult ki, akkor az út kék helyett piros színű lesz.
|
||||
|
||||
A pulzáló körök a jelzőlámpákat jelképezik, ha valid állapotban van egy lámpa (egyik irányba piros, másikba zöld, vagy mindegyik sárga),
|
||||
akkor kék színű, ha invalid (minden más, pl összes piros, összes zöld), akkor piros színű lesz.
|
||||
|
||||
Minél pirosabb a megjelenítés annál rosszabb a helyzet.
|
||||
|
||||
A RestAPI-t használja, azon belül is a GET /all-t.
|
||||
Szépen animált, nem túl erőforrásigényes. Ha mégis az lenne, akkor a shouldPulse = false értékkel célszerű inicializálni, ez nagy mértékben felgyorsítja.
|
||||
A hibákat tűri, ha elveszti a kapcsolatot, amint lehet helyreállítja.
|
||||
A resize-t szépen kezeli, animált átmenettel mérteződik újra.
|
||||
|
||||
Használható metódusok:
|
||||
//Célszerű width = height-tal dolgozni, különben széthúzza, és az nem szép.
|
||||
constructor(int width, int height, string canvasID, string textID, string serverAddress, bool shouldPulse, bool shouldDrawGrid);
|
||||
|
||||
//Egyszer kell meghívni az indításhoz, 2 setInterval van benne. Stop nincs.
|
||||
void start();
|
||||
|
||||
//A canvas méretét kizárólag ezen keresztül változtassuk.
|
||||
void resize(int width, int height);
|
||||
|
||||
|
||||
Részletek:
|
||||
Kifejezetten izgalmas része nincsen, az olvashatóságra törekedtem írás közben. Szóval előbbiek következménye, hogy szükség esetén
|
||||
könnyű továbbfejleszteni.
|
||||
A beállításokat a konstruktor kódjában lehet változtatni.
|
||||
|
||||
*/
|
||||
|
||||
class Visualiser {
|
||||
constructor(width, height, canvasName, canvasTextName, serverAddress, shouldPulse, shouldDrawGrid) {
|
||||
|
||||
/* Külső referenciák */
|
||||
this.canvas = document.getElementById(canvasName);
|
||||
this.text = document.getElementById(canvasTextName);
|
||||
this.serverAddress = serverAddress;
|
||||
this.ctx = this.canvas.getContext("2d");
|
||||
/**/
|
||||
|
||||
|
||||
/* Beállítások, amiket könnyen lehet változtatni */
|
||||
this.goodColor = "#4242FF";
|
||||
this.badColor = "#9E1414";
|
||||
this.bgColor = "rgb(55, 55, 55)";
|
||||
this.strokeColor = "#EEEEEE";
|
||||
|
||||
//Egy négyzetrács hányad részét foglalja el egy adott szélességű útelem?
|
||||
this.smallWidthQ = 0.25;
|
||||
this.mediumWidthQ = 0.75;
|
||||
this.largeWidthQ = 1.33; //lógjon túl rajta
|
||||
|
||||
//A lámpa pulzálásának méretei, szintén a cellák oldalhosszúságához mérve.
|
||||
this.trafficlightRadiusMinQ = 0.75;
|
||||
this.trafficlightRadiusMaxQ = 0.85;
|
||||
this.trafficlightSpeedQ = 0.025;
|
||||
//A lámpa körvonalának (és a gridnek) a vastagsága.
|
||||
this.lineWidthQ = 0.073;
|
||||
|
||||
//s-ben, célszerű kissebnek lennie, mint this.ajaxUpdateInterval
|
||||
this.roadGrowSpeed = 0.7;
|
||||
/**/
|
||||
|
||||
|
||||
/* Beállítások, amiket nem nagyon kell változtatni */
|
||||
//Az utak topológiája ettől függ, velük együtt lehet csak megváltoztatni.
|
||||
this.horizontalLineCount = 11;
|
||||
this.verticalLineCount = 11;
|
||||
|
||||
this.FPS = 30;
|
||||
|
||||
//s-ben, az egész projektben 1s-es intervallumok vannak updatekre, szóval ez ahhoz illeszkedik.
|
||||
this.ajaxUpdateInterval = 1;
|
||||
|
||||
this.shouldPulse = shouldPulse;
|
||||
this.shouldDrawGrid = shouldDrawGrid;
|
||||
/**/
|
||||
|
||||
|
||||
/* Belső */
|
||||
this.resize(width, height);
|
||||
|
||||
this.trafficlightRadiusCurrent = this.trafficlightRadiusMin;
|
||||
|
||||
if(!shouldPulse) this.canvas.style["animation"] = "none";
|
||||
|
||||
//Az útelemek animációjához kell, kezdő és végállapotokat tárol.
|
||||
//startWidth: az útelem először rajzolt oldala, endWith: az utoljára rajzolt
|
||||
this.roadElemWidths = [];
|
||||
for(let x = 0; x < this.verticalLineCount; x++) {
|
||||
|
||||
this.roadElemWidths[x] = [];
|
||||
for(let y = 0; y < this.horizontalLineCount; y++) {
|
||||
|
||||
this.roadElemWidths[x][y] = [];
|
||||
for(let layer = 0; layer < 2; layer++)
|
||||
this.roadElemWidths[x][y][layer] = {
|
||||
//Lehetne külön class ehhez, de nem szépítene annyit, hogy megérje
|
||||
startWidth: {
|
||||
start: 0,
|
||||
end: 0
|
||||
},
|
||||
endWith: {
|
||||
start: 0,
|
||||
end: 0
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
this.deltaTimeSinceAjax = 0;
|
||||
/**/
|
||||
|
||||
}
|
||||
|
||||
//Az úton lévő autók számából kitalálja, hogy milyen széles legyen az út a grafikán
|
||||
//A visual egy nem túl intuitív nevű struct, ami tartalmazza, hogy egy út milyen fajta elemekből áll, visual(szélesElemekSzáma, közepes, vékony);
|
||||
intToVisual(int) {
|
||||
if(int >= 5) this.ctx.fillStyle = this.badColor;
|
||||
if(int <= 0)
|
||||
return new visual(0, 0, 3);
|
||||
if(int <= 1)
|
||||
return new visual(0, 1, 2);
|
||||
if(int <= 2)
|
||||
return new visual(0, 2, 1);
|
||||
if(int <= 3)
|
||||
return new visual(0, 3, 0);
|
||||
if(int <= 5)
|
||||
return new visual(1, 2, 0);
|
||||
if(int <= 7)
|
||||
return new visual(2, 1, 0);
|
||||
else
|
||||
return new visual(3, 0, 0);
|
||||
}
|
||||
|
||||
resize(width, height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
this.canvas.width = this.width
|
||||
this.canvas.height = this.height
|
||||
|
||||
this.deltaX = this.width / this.verticalLineCount;
|
||||
this.deltaY = this.height / this.horizontalLineCount;
|
||||
|
||||
this.smallWidth = 0.5 * this.deltaX * this.smallWidthQ;
|
||||
this.mediumWidth = 0.5 * this.deltaX * this.mediumWidthQ;
|
||||
this.largeWidth = 0.5 * this.deltaX * this.largeWidthQ;
|
||||
|
||||
this.trafficlightRadiusMin = this.deltaX * this.trafficlightRadiusMinQ;
|
||||
this.trafficlightRadiusMax = this.deltaX * this.trafficlightRadiusMaxQ;
|
||||
this.trafficlightSpeed = this.deltaX * this.trafficlightSpeedQ;
|
||||
|
||||
this.ctx.lineWidth = this.deltaX * this.lineWidthQ;
|
||||
this.ctx.strokeStyle = this.strokeColor;
|
||||
}
|
||||
|
||||
start() {
|
||||
this.getRoadStates();
|
||||
|
||||
let that = this;
|
||||
|
||||
setInterval(function() {
|
||||
that.getRoadStates();
|
||||
}, this.ajaxUpdateInterval * 1000);
|
||||
|
||||
setInterval(function() {
|
||||
that.drawTraffic(false);
|
||||
}, 1000 / this.FPS);
|
||||
}
|
||||
|
||||
//Index vektor által jelölt cella bal felső sarkának koordinátáit adja vissza.
|
||||
getOriginOfVec(indexVec) {
|
||||
return new Vec2 (
|
||||
this.deltaX * indexVec.x,
|
||||
this.deltaY * indexVec.y
|
||||
);
|
||||
}
|
||||
|
||||
drawGrid() {
|
||||
this.ctx.beginPath();
|
||||
|
||||
for(let i = 1; i < this.horizontalLineCount; i++) {
|
||||
this.ctx.moveTo(0, i * this.deltaY);
|
||||
this.ctx.lineTo(this.width, i * this.deltaY);
|
||||
}
|
||||
|
||||
for(let i = 1; i < this.verticalLineCount; i++) {
|
||||
this.ctx.moveTo(i * this.deltaX, 0);
|
||||
this.ctx.lineTo(i * this.deltaX, this.height);
|
||||
}
|
||||
|
||||
this.ctx.stroke();
|
||||
}
|
||||
|
||||
//Egy cellát tölt fel
|
||||
drawRoadElem(newStartWidth, newEndWith, isHorizontal, indexVec, isKey, isJamAtStart) {
|
||||
//A kereszteződések közti utak duplán vannak rajzolva (egyszer egyik irány, aztán a másik), ezért külön rétegen tárolom az állapotukat
|
||||
const layerIndex = isJamAtStart ? 0 : 1;
|
||||
|
||||
|
||||
//Nincs külön tárolva, mert egységes mindegyik útra nézve
|
||||
const currentStartWidth = this.deltaTimeSinceAjax < this.roadGrowSpeed ?
|
||||
this.roadElemWidths[indexVec.x][indexVec.y][layerIndex].startWidth.start +
|
||||
(this.roadElemWidths[indexVec.x][indexVec.y][layerIndex].startWidth.end -
|
||||
this.roadElemWidths[indexVec.x][indexVec.y][layerIndex].startWidth.start)
|
||||
/ this.roadGrowSpeed * this.deltaTimeSinceAjax :
|
||||
this.roadElemWidths[indexVec.x][indexVec.y][layerIndex].startWidth.end;
|
||||
|
||||
const currentEndWith = this.deltaTimeSinceAjax < this.roadGrowSpeed ?
|
||||
this.roadElemWidths[indexVec.x][indexVec.y][layerIndex].endWith.start +
|
||||
(this.roadElemWidths[indexVec.x][indexVec.y][layerIndex].endWith.end -
|
||||
this.roadElemWidths[indexVec.x][indexVec.y][layerIndex].endWith.start)
|
||||
/ this.roadGrowSpeed * this.deltaTimeSinceAjax :
|
||||
this.roadElemWidths[indexVec.x][indexVec.y][layerIndex].endWith.end;
|
||||
|
||||
//isKey"frame", csak ha igaz, akkor veszi figyelembe a start/endWidth-et, onnan folytatja, ahol most tart
|
||||
if(isKey) {
|
||||
this.roadElemWidths[indexVec.x][indexVec.y][layerIndex] = {
|
||||
startWidth: {
|
||||
start: currentStartWidth,
|
||||
end: newStartWidth
|
||||
},
|
||||
endWith: {
|
||||
start: currentEndWith,
|
||||
end: newEndWith
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let origin = this.getOriginOfVec(indexVec);
|
||||
|
||||
//szebb anti-aliasing, picit nagyobbra rajzolja, mint kéne, így nem lesznek indokolatlan vonalak
|
||||
let d = 0.5;
|
||||
|
||||
this.ctx.beginPath();
|
||||
if(isHorizontal) {
|
||||
this.ctx.moveTo(origin.x - d, origin.y + this.deltaY / 2 - currentStartWidth);
|
||||
this.ctx.lineTo(origin.x + this.deltaX + d, origin.y + this.deltaY / 2 - currentEndWith);
|
||||
this.ctx.lineTo(origin.x + this.deltaX + d, origin.y + this.deltaY / 2 + currentEndWith);
|
||||
this.ctx.lineTo(origin.x - d, origin.y + this.deltaY / 2 + currentStartWidth);
|
||||
}
|
||||
else {
|
||||
this.ctx.moveTo(origin.x + this.deltaX / 2 + currentStartWidth, origin.y - d);
|
||||
this.ctx.lineTo(origin.x + this.deltaX / 2 + currentEndWith, origin.y + this.deltaY + d);
|
||||
this.ctx.lineTo(origin.x + this.deltaX / 2 - currentEndWith, origin.y + this.deltaY + d);
|
||||
this.ctx.lineTo(origin.x + this.deltaX / 2 - currentStartWidth, origin.y - d);
|
||||
}
|
||||
|
||||
this.ctx.fill();
|
||||
}
|
||||
|
||||
//Egy egész utat lerajzol
|
||||
drawRoad(road, visual, isKey) {
|
||||
const startVec = road.startVec;
|
||||
const isHorizontal = road.isHorizontal;
|
||||
const isJamAtStart = road.isJamAtStart;
|
||||
|
||||
const smallLength = visual.small;
|
||||
const mediumLength = visual.medium;
|
||||
const largeLength = visual.large;
|
||||
|
||||
const length = largeLength + mediumLength + smallLength;
|
||||
|
||||
if(isJamAtStart) {
|
||||
for(let i = 0; i < length; i++) {
|
||||
|
||||
if(i < largeLength)
|
||||
this.drawRoadElem(this.largeWidth, this.largeWidth, isHorizontal, startVec, isKey, isJamAtStart);
|
||||
else if(i == largeLength && i > 0)
|
||||
this.drawRoadElem(this.largeWidth, this.mediumWidth, isHorizontal, startVec, isKey, isJamAtStart);
|
||||
else if(i < largeLength + mediumLength)
|
||||
this.drawRoadElem(this.mediumWidth, this.mediumWidth, isHorizontal, startVec, isKey, isJamAtStart);
|
||||
else if(i == largeLength + mediumLength && i > 0)
|
||||
this.drawRoadElem(this.mediumWidth, this.smallWidth, isHorizontal, startVec, isKey, isJamAtStart);
|
||||
else
|
||||
this.drawRoadElem(this.smallWidth, this.smallWidth, isHorizontal, startVec, isKey, isJamAtStart);
|
||||
|
||||
if(isHorizontal) startVec.x++;
|
||||
else startVec.y++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(isHorizontal) startVec.x += length - 1;
|
||||
else startVec.y += length - 1;
|
||||
|
||||
for(let i = 0; i < length; i++) {
|
||||
|
||||
if(i < largeLength)
|
||||
this.drawRoadElem(this.largeWidth, this.largeWidth, isHorizontal, startVec, isKey, isJamAtStart);
|
||||
else if(i == largeLength && i > 0)
|
||||
this.drawRoadElem(this.mediumWidth, this.largeWidth, isHorizontal, startVec, isKey, isJamAtStart);
|
||||
else if(i < largeLength + mediumLength)
|
||||
this.drawRoadElem(this.mediumWidth, this.mediumWidth, isHorizontal, startVec, isKey, isJamAtStart);
|
||||
else if(i == largeLength + mediumLength && i > 0)
|
||||
this.drawRoadElem(this.smallWidth, this.mediumWidth, isHorizontal, startVec, isKey, isJamAtStart);
|
||||
else
|
||||
this.drawRoadElem(this.smallWidth, this.smallWidth, isHorizontal, startVec, isKey, isJamAtStart);
|
||||
|
||||
if(isHorizontal) startVec.x--;
|
||||
else startVec.y--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
drawTrafficlight(indexVec, isValid) {
|
||||
const origin = this.getOriginOfVec(indexVec);
|
||||
origin.x += this.deltaX / 2;
|
||||
origin.y += this.deltaY / 2;
|
||||
|
||||
this.ctx.fillStyle = isValid ? this.goodColor : this.badColor;
|
||||
this.trafficlightRadiusCurrent += this.trafficlightSpeed / this.FPS;
|
||||
|
||||
if(this.trafficlightRadiusCurrent > this.trafficlightRadiusMax) {
|
||||
this.trafficlightRadiusCurrent = this.trafficlightRadiusMax;
|
||||
this.trafficlightSpeed *= -1;
|
||||
}
|
||||
|
||||
else if(this.trafficlightRadiusCurrent < this.trafficlightRadiusMin) {
|
||||
this.trafficlightRadiusCurrent = this.trafficlightRadiusMin;
|
||||
this.trafficlightSpeed *= -1;
|
||||
}
|
||||
|
||||
|
||||
this.ctx.beginPath();
|
||||
this.ctx.arc(origin.x, origin.y, this.trafficlightRadiusCurrent, 0, Math.PI * 2);
|
||||
this.ctx.fill();
|
||||
this.ctx.stroke();
|
||||
}
|
||||
|
||||
drawTraffic(isKey) {
|
||||
this.deltaTimeSinceAjax += 1 / this.FPS;
|
||||
|
||||
this.ctx.fillStyle = this.bgColor;
|
||||
this.ctx.fillRect(0, 0, this.width, this.height);
|
||||
|
||||
this.ctx.fillStyle = this.goodColor;
|
||||
|
||||
|
||||
if(this.shouldDrawGrid)
|
||||
this.drawGrid();
|
||||
|
||||
|
||||
|
||||
if(this.roads) {
|
||||
|
||||
/* Út topológia:
|
||||
* (megjelenítésben ez balra van "forgatva" 45°-kal)
|
||||
*
|
||||
* 1 5
|
||||
* V V
|
||||
* 0 > < 2 4 > < 6
|
||||
* ^ ^
|
||||
* 3 7
|
||||
*
|
||||
* 13 9
|
||||
* V V
|
||||
* 12 > < 14 8 > < 10
|
||||
* ^ ^
|
||||
* 15 11
|
||||
*/
|
||||
|
||||
//Az indexek nem az id-k
|
||||
const roads = [
|
||||
new road(new Vec2(0, 3), true, false, "NW", "W"),
|
||||
new road(new Vec2(3, 0), false, false, "NW", "N"),
|
||||
|
||||
new road(new Vec2(4, 3), true, true, "NW", "E", true),
|
||||
new road(new Vec2(4, 3), true, false, "NE", "W"),
|
||||
|
||||
new road(new Vec2(7, 0), false, false, "NE", "N"),
|
||||
new road(new Vec2(8, 3), true, true, "NE", "E"),
|
||||
|
||||
new road(new Vec2(7, 4), false, true, "NE", "S", true),
|
||||
new road(new Vec2(7, 4), false, false, "SE", "N"),
|
||||
|
||||
new road(new Vec2(8, 7), true, true, "SE", "E"),
|
||||
new road(new Vec2(7, 8), false, true, "SE", "S"),
|
||||
new road(new Vec2(0, 7), true, false, "SW", "W"),
|
||||
|
||||
new road(new Vec2(3, 4), false, true, "NW", "S", true),
|
||||
new road(new Vec2(3, 4), false, false, "SW", "N"),
|
||||
|
||||
new road(new Vec2(4, 7), true, false, "SE", "W", true),
|
||||
new road(new Vec2(4, 7), true, true, "SW", "E"),
|
||||
|
||||
new road(new Vec2(3, 8), false, true, "SW", "S"),
|
||||
];
|
||||
|
||||
|
||||
//Mivel a kereszteződések közt 2 utat rajzol egymásra, fontos, hogy azok azonos színűek legyenek
|
||||
let shouldNotResetColor = false;
|
||||
for(let i = 0; i < roads.length; i++) {
|
||||
if(!shouldNotResetColor)
|
||||
this.ctx.fillStyle = this.goodColor;
|
||||
this.drawRoad(roads[i], this.intToVisual(this.roads[roads[i].secondaryDirection][roads[i].primaryDirection]), isKey);
|
||||
shouldNotResetColor = roads[i].shouldNotResetColor;
|
||||
}
|
||||
|
||||
//Lámpák rajzolása
|
||||
const tlVecs = [new Vec2(3, 3), new Vec2(7, 3), new Vec2(7, 7), new Vec2(3, 7)];
|
||||
const directions = ["NW", "NE", "SE", "SW"];
|
||||
|
||||
for(let i = 0; i < 4; i++) {
|
||||
//Ezeket tartom valid jelzőlámpa helyzeteknek
|
||||
this.drawTrafficlight(
|
||||
tlVecs[i],
|
||||
(
|
||||
this.trafficLights[directions[i]]["W"] == "red" &&
|
||||
this.trafficLights[directions[i]]["E"] == "red" &&
|
||||
this.trafficLights[directions[i]]["N"] == "green" &&
|
||||
this.trafficLights[directions[i]]["S"] == "green"
|
||||
) ||
|
||||
(
|
||||
this.trafficLights[directions[i]]["W"] == "green" &&
|
||||
this.trafficLights[directions[i]]["E"] == "green" &&
|
||||
this.trafficLights[directions[i]]["N"] == "red" &&
|
||||
this.trafficLights[directions[i]]["S"] == "red"
|
||||
) ||
|
||||
(
|
||||
this.trafficLights[directions[i]]["W"] == "yellow" &&
|
||||
this.trafficLights[directions[i]]["E"] == "yellow" &&
|
||||
this.trafficLights[directions[i]]["N"] == "yellow" &&
|
||||
this.trafficLights[directions[i]]["S"] == "yellow"
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//Minimálisan CPU igényes, inkább GPU-val kéne ilyeneket csinálni, de ez még belefér-
|
||||
if(this.shouldPulse) {
|
||||
let pixels = this.ctx.getImageData(0, 0, this.width, this.height);
|
||||
|
||||
for(let y = 0; y < this.height; y++) {
|
||||
for(let x = 0; x < this.width; x++) {
|
||||
if(
|
||||
!( pixels.data[(this.width * y + x) * 4 + 0] == 55 &&
|
||||
pixels.data[(this.width * y + x) * 4 + 1] == 55 &&
|
||||
pixels.data[(this.width * y + x) * 4 + 2] == 55 )
|
||||
) {
|
||||
pixels.data[(this.width * y + x) * 4 + 3] = 200;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.ctx.putImageData(pixels, 0, 0);
|
||||
|
||||
}
|
||||
|
||||
//Itt nullázom le a számlálót, az animáció és amiatt van erre szükség, hogy a jelenlegi szélességét nem tárolom az utaknak, ezért amikor update érkezik,
|
||||
//tudnia kell, hogy jelenleg hol tart, azt eltárolja kezdetinek, és csak utána lehet lenullázni.
|
||||
if(isKey)
|
||||
this.deltaTimeSinceAjax = 0;
|
||||
}
|
||||
|
||||
//a restApi /all-ját használja
|
||||
//Átírja a szöveget is, ezt értelemszerűen lehet továbbbővíteni, más infókkal
|
||||
getRoadStates() {
|
||||
let xhttp = new XMLHttpRequest();
|
||||
let that = this;
|
||||
xhttp.onreadystatechange = function() {
|
||||
//4-szer hívódik meg egy kérés alatt
|
||||
if(this.readyState == 4) {
|
||||
if(this.status == 200) {
|
||||
const parsed = JSON.parse(this.responseText);
|
||||
|
||||
that.text.innerHTML = parsed.passedCarCount;
|
||||
that.roads = parsed.roads;
|
||||
that.trafficLights = parsed.trafficLights;
|
||||
|
||||
that.drawTraffic(true);
|
||||
}
|
||||
//Megfelelő mértékű hibakezelés
|
||||
else if(this.status)
|
||||
that.text.innerHTML = "Error: " + this.status;
|
||||
else
|
||||
that.text.innerHTML = "Timeout";
|
||||
}
|
||||
|
||||
};
|
||||
xhttp.open("GET", this.serverAddress + "all", true);
|
||||
xhttp.send();
|
||||
}
|
||||
}; //Nem kell pontosvessző, de azért így jobban néz ki.
|
||||
|
||||
//Így gyorsabb létrehozni új vektorokat.
|
||||
class Vec2 {
|
||||
constructor(x, y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
};
|
||||
|
||||
//A visual egy nem túl intuitív nevű struct, ami tartalmazza, hogy egy út milyen fajta elemekből áll.
|
||||
class visual {
|
||||
constructor(large, medium, small) {
|
||||
this.large = large;
|
||||
this.medium = medium;
|
||||
this.small = small;
|
||||
}
|
||||
};
|
||||
|
||||
//Struct az utak tárolására, hossz nincs benne, az egységesen három, ez az intToVisualban van "megadva".
|
||||
//Csak az utak tárolásában van igazi szerepe, később nem lesz nagyon kihasználva
|
||||
class road {
|
||||
constructor(startVec, isHorizontal, isJamAtStart, secondaryDirection, primaryDirection, shouldNotResetColor) {
|
||||
this.startVec = startVec;
|
||||
this.isHorizontal = isHorizontal;
|
||||
this.isJamAtStart = isJamAtStart;
|
||||
this.secondaryDirection = secondaryDirection;
|
||||
this.primaryDirection = primaryDirection;
|
||||
this.shouldNotResetColor = shouldNotResetColor;
|
||||
}
|
||||
};
|
||||
Loading…
Reference in a new issue