{"id":114,"date":"2026-03-24T11:22:11","date_gmt":"2026-03-24T11:22:11","guid":{"rendered":"https:\/\/optotech.no\/?page_id=114"},"modified":"2026-03-24T19:24:35","modified_gmt":"2026-03-24T19:24:35","slug":"vitrous-defender-the-oculo-guardian","status":"publish","type":"page","link":"https:\/\/optotech.no\/index.php\/vitrous-defender-the-oculo-guardian\/","title":{"rendered":"Vitrous Defender: The Oculo-Guardian"},"content":{"rendered":"\n<script><div id=\"vd11-wrapper\" style=\"max-width:900px; margin:20px auto; font-family:sans-serif; background:#0a0a0a; color:#fff; padding:25px; border-radius:16px; box-shadow:0 20px 50px rgba(0,0,0,0.9); text-align:center; border:2px solid #333; position:relative; user-select:none;\">\r\n    <h2 style=\"margin:0 0 15px 0; color:#38bdf8; letter-spacing:2px; text-transform:uppercase;\">Vitreous Defender: V11.0<\/h2>\r\n    <div style=\"display:grid; grid-template-columns:repeat(5, 1fr); gap:10px; margin-bottom:20px; background:#111; padding:15px; border-radius:12px; border:1px solid #444;\">\r\n        <div><div style=\"font-size:0.7rem; color:#888;\">VISION<\/div><div id=\"vd11-vis\" style=\"color:#4caf50; font-size:1.4rem; font-weight:800;\">100%<\/div><\/div>\r\n        <div><div style=\"font-size:0.7rem; color:#888;\">IOP<\/div><div id=\"vd11-iop\" style=\"color:#00bcd4; font-size:1.4rem; font-weight:800;\">15<\/div><\/div>\r\n        <div><div style=\"font-size:0.7rem; color:#888;\">VCDR<\/div><div id=\"vd11-cup\" style=\"color:#ff9800; font-size:1.4rem; font-weight:800;\">0.30<\/div><\/div>\r\n        <div><div style=\"font-size:0.7rem; color:#888;\">SYRINGES<\/div><div id=\"vd11-ammo\" style=\"color:#f48fb1; font-size:1.4rem; font-weight:800;\">3<\/div><\/div>\r\n        <div><div style=\"font-size:0.7rem; color:#888;\">SCORE<\/div><div id=\"vd11-score\" style=\"color:#fff; font-size:1.4rem; font-weight:800;\">0<\/div><\/div>\r\n    <\/div>\r\n    <div style=\"position:relative; border-radius:12px; overflow:hidden; border:3px solid #222;\">\r\n        <canvas id=\"vd11Canvas\" width=\"850\" height=\"550\" style=\"width:100%; height:auto; cursor:crosshair; display:block; background:#111;\"><\/canvas>\r\n        <div id=\"vd11-start-screen\" style=\"position:absolute; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.85); display:flex; flex-direction:column; justify-content:center; align-items:center; z-index:10;\">\r\n            <button id=\"vd11-start-btn\" style=\"padding:15px 40px; background:#005a66; color:white; border:2px solid #38bdf8; border-radius:8px; font-weight:800; font-size:1.2rem; cursor:pointer;\">COMMENCE SURGERY<\/button>\r\n            <p style=\"color:#aaa; font-size:0.85rem; margin-top:15px;\">[Laser] Zaps Pathogens | [Anti-VEGF] Clears Edema\/Heme | [Top Blue Bar] Lowers IOP<\/p>\r\n        <\/div>\r\n    <\/div>\r\n    <div style=\"display:grid; grid-template-columns:1fr 1fr; gap:15px; margin-top:20px;\">\r\n        <button id=\"vd11-btn-laser\" style=\"padding:15px; background:#b71c1c; color:white; border:3px solid #fff; border-radius:8px; cursor:pointer; font-weight:800;\">[1] ARGON LASER<\/button>\r\n        <button id=\"vd11-btn-syringe\" style=\"padding:15px; background:#880e4f; color:white; border:3px solid #333; border-radius:8px; cursor:pointer; font-weight:800;\">[2] ANTI-VEGF (\ud83d\udc89)<\/button>\r\n    <\/div>\r\n    <div id=\"vd11-gameover\" style=\"display:none; position:absolute; top:50%; left:50%; transform:translate(-50%, -50%); background:rgba(10,10,10,0.95); padding:30px; border:2px solid #f44336; border-radius:15px; z-index:20; width:350px;\">\r\n        <h2 style=\"color:#f44336; margin-top:0;\">VISION LOST<\/h2>\r\n        <p id=\"vd11-death-reason\" style=\"color:#ccc; font-size:0.9rem;\"><\/p>\r\n        <button id=\"vd11-retry-btn\" style=\"padding:10px 20px; background:#4caf50; color:white; border:none; border-radius:5px; cursor:pointer; font-weight:bold; width:80%;\">NEW PATIENT<\/button>\r\n    <\/div>\r\n<\/div>\r\n<script>\r\ndocument.addEventListener('DOMContentLoaded', function() {\r\n    const canvas = document.getElementById('vd11Canvas');\r\n    const ctx = canvas.getContext('2d');\r\n    const ui = { v: document.getElementById('vd11-vis'), i: document.getElementById('vd11-iop'), c: document.getElementById('vd11-cup'), a: document.getElementById('vd11-ammo'), s: document.getElementById('vd11-score'), bL: document.getElementById('vd11-btn-laser'), bS: document.getElementById('vd11-btn-syringe'), over: document.getElementById('vd11-gameover'), start: document.getElementById('vd11-start-screen') };\r\n    let st = { active: false, vis: 100, iop: 15, cup: 0.3, score: 0, ammo: 3, wpn: 'laser', frame: 0 };\r\n    let bugs = [], path = [], scars = [];\r\n    let laserFx = { active: false, x: 0, y: 0, t: 0 };\r\n    const bgCanvas = document.createElement('canvas');\r\n    bgCanvas.width = 850; bgCanvas.height = 550;\r\n    const bgCtx = bgCanvas.getContext('2d');\r\n    function preRenderFundus() {\r\n        const grad = bgCtx.createRadialGradient(425, 275, 50, 425, 275, 550);\r\n        grad.addColorStop(0, '#e64a19'); grad.addColorStop(0.6, '#bf360c'); grad.addColorStop(1, '#2e150f');\r\n        bgCtx.fillStyle = grad; bgCtx.fillRect(0, 0, 850, 550);\r\n        const discX = 250, discY = 275, macX = 550, macY = 275;\r\n        bgCtx.fillStyle = 'rgba(62, 39, 35, 0.5)'; bgCtx.beginPath(); bgCtx.arc(macX, macY, 65, 0, Math.PI*2); bgCtx.fill();\r\n        bgCtx.strokeStyle = '#7f0000'; bgCtx.lineCap = 'round'; bgCtx.lineJoin = 'round';\r\n        const drawVessel = (x, y, ang, len, w, curve, gen) => {\r\n            if(gen > 4 || w < 0.5) return;\r\n            bgCtx.lineWidth = w; bgCtx.beginPath(); bgCtx.moveTo(x, y);\r\n            let cx = x, cy = y, ca = ang;\r\n            for(let i=0; i<len; i+=5) { cx += Math.cos(ca)*5; cy += Math.sin(ca)*5; ca += curve; bgCtx.lineTo(cx, cy); }\r\n            bgCtx.stroke();\r\n            drawVessel(cx, cy, ca + 0.3 + Math.random()*0.1, len*0.7, w*0.6, curve*1.2, gen+1);\r\n            drawVessel(cx, cy, ca - 0.3 - Math.random()*0.1, len*0.7, w*0.6, curve*1.2, gen+1);\r\n        };\r\n        drawVessel(discX, 260, -0.6, 150, 6, 0.006, 0); drawVessel(discX, 290, 0.6, 150, 6, -0.006, 0);\r\n        drawVessel(discX, 260, -2.6, 100, 5, -0.002, 0); drawVessel(discX, 290, 2.6, 100, 5, 0.002, 0);\r\n        drawVessel(discX, 275, 0, 80, 2.5, 0, 0); \r\n    }\r\n    class Bug {\r\n        constructor(type) {\r\n            this.type = type; this.x = Math.random()*600 + 150; this.y = Math.random()*400 + 75;\r\n            this.hp = type === 'parasite' ? 3 : 1; this.a = Math.random()*6; this.tick = Math.random()*100;\r\n        }\r\n        update() {\r\n            this.tick++;\r\n            if(this.type === 'bacteria') { this.x += Math.sin(this.tick*0.05)*1.2; this.y += Math.cos(this.tick*0.03)*0.8; }\r\n            if(this.type === 'virus') { this.x += Math.cos(this.a)*1.2; this.y += Math.sin(this.a)*1.2; if(Math.random()<0.02) this.a = Math.random()*6; }\r\n            if(this.type === 'parasite') { if(this.tick % 80 < 12) { this.x += Math.cos(this.a)*12; this.y += Math.sin(this.a)*12; } else if (this.tick % 80 === 12) { this.a = Math.random()*6; } }\r\n            if(this.x<50) this.x=50; if(this.x>800) this.x=800; if(this.y<50) this.y=50; if(this.y>500) this.y=500;\r\n        }\r\n        draw() {\r\n            ctx.save(); ctx.translate(this.x, this.y);\r\n            if(this.type === 'bacteria') {\r\n                ctx.fillStyle = '#76ff03'; ctx.beginPath(); ctx.ellipse(0,0,16,8, Math.sin(this.tick*0.1), 0, Math.PI*2); ctx.fill();\r\n                ctx.fillStyle = '#000'; ctx.fillRect(4, -2, 3, 3);\r\n                ctx.strokeStyle = '#76ff03'; ctx.beginPath(); ctx.moveTo(-16,0); ctx.lineTo(-25, Math.sin(this.tick*0.2)*8); ctx.stroke();\r\n            } else if(this.type === 'virus') {\r\n                ctx.fillStyle = '#d500f9'; ctx.beginPath(); ctx.arc(0,0,12,0,Math.PI*2); ctx.fill();\r\n                ctx.strokeStyle = '#ff80ab'; ctx.lineWidth=2;\r\n                for(let i=0; i<6; i++) { ctx.rotate(Math.PI\/3); ctx.moveTo(12,0); ctx.lineTo(18,0); ctx.stroke(); }\r\n            } else if(this.type === 'parasite') {\r\n                ctx.strokeStyle = '#ff9100'; ctx.lineWidth = 6; ctx.lineCap='round'; ctx.beginPath(); ctx.moveTo(-25,0);\r\n                for(let i=-25; i<25; i+=5) ctx.lineTo(i, Math.sin(this.tick*0.2 + i*0.2)*8); ctx.stroke();\r\n                ctx.fillStyle = 'red'; ctx.beginPath(); ctx.arc(25, Math.sin(this.tick*0.2 + 5)*8, 4, 0, Math.PI*2); ctx.fill();\r\n            }\r\n            ctx.restore();\r\n        }\r\n    }\r\n    function startGame() {\r\n        ui.start.style.display = 'none'; ui.over.style.display = 'none';\r\n        st = { active: true, vis: 100, iop: 15, cup: 0.3, score: 0, ammo: 3, wpn: 'laser', frame: 0 };\r\n        bugs = []; path = []; scars = [];\r\n        preRenderFundus(); setWeapon('laser');\r\n        requestAnimationFrame(mainLoop);\r\n    }\r\n    function setWeapon(w) {\r\n        st.wpn = w;\r\n        ui.bL.style.borderColor = (w === 'laser') ? '#fff' : '#333';\r\n        ui.bS.style.borderColor = (w === 'avegf') ? '#fff' : '#333';\r\n        canvas.style.cursor = (w === 'laser') ? 'crosshair' : 'alias';\r\n    }\r\n    document.getElementById('vd11-start-btn').addEventListener('click', startGame);\r\n    document.getElementById('vd11-retry-btn').addEventListener('click', function() { location.reload(); });\r\n    document.getElementById('vd11-btn-laser').addEventListener('click', function() { setWeapon('laser'); });\r\n    document.getElementById('vd11-btn-syringe').addEventListener('click', function() { setWeapon('avegf'); });\r\n    canvas.addEventListener('mousedown', function(e) {\r\n        if(!st.active) return;\r\n        const r = canvas.getBoundingClientRect();\r\n        const mx = (e.clientX - r.left) * (850 \/ r.width), my = (e.clientY - r.top) * (550 \/ r.height);\r\n        if(my < 40) { st.iop = Math.max(10, st.iop - 5); st.score += 20; return; }\r\n        if(st.wpn === 'laser') {\r\n            laserFx = { active: true, x: mx, y: my, t: 8 };\r\n            let hit = false;\r\n            bugs = bugs.filter(b => {\r\n                if(Math.sqrt((b.x-mx)**2 + (b.y-my)**2) < 30) { b.hp--; hit = true; if(b.hp <= 0) { st.score += (b.type==='parasite'?500:100); st.vis = Math.min(100, st.vis + 2); return false; } } return true;\r\n            });\r\n            if(!hit) { st.score = Math.max(0, st.score - 5); st.vis -= 0.5; scars.push({x: mx, y: my}); }\r\n        } else if(st.wpn === 'avegf' && st.ammo > 0) {\r\n            let used = false;\r\n            path = path.filter(p => { if(Math.sqrt((p.x-mx)**2 + (p.y-my)**2) < 50) { used = true; st.score += 300; return false; } return true; });\r\n            if(used) { st.ammo--; st.vis = Math.min(100, st.vis + 5); ctx.fillStyle='white'; ctx.fillRect(0,0,850,550); if(st.ammo <= 0) setWeapon('laser'); }\r\n        }\r\n    });\r\n    function mainLoop() {\r\n        if(!st.active) return;\r\n        st.frame++;\r\n        ctx.drawImage(bgCanvas, 0, 0);\r\n        ctx.fillStyle = '#ffecb3'; ctx.beginPath(); ctx.ellipse(250, 275, 45, 55, 0, 0, Math.PI*2); ctx.fill();\r\n        ctx.fillStyle = '#fff9c4'; ctx.beginPath(); ctx.ellipse(250, 275, 45*st.cup, 55*st.cup, 0, 0, Math.PI*2); ctx.fill();\r\n        scars.forEach(s => { ctx.fillStyle = '#1a0000'; ctx.beginPath(); ctx.arc(s.x, s.y, 5, 0, Math.PI*2); ctx.fill(); ctx.fillStyle = '#fff'; ctx.beginPath(); ctx.arc(s.x, s.y, 1.5, 0, Math.PI*2); ctx.fill(); });\r\n        ctx.fillStyle = 'rgba(0,188,212,0.3)'; ctx.fillRect(0,0,850,40);\r\n        ctx.fillStyle = '#fff'; ctx.font = 'bold 12px sans-serif'; ctx.fillText(\"TRABECULAR OUTFLOW (CLICK TO DRAIN IOP)\", 300, 25);\r\n        let spawnRate = 0.005 + (st.frame * 0.000002);\r\n        if(Math.random() < spawnRate) bugs.push(new Bug(Math.random()>0.2?'bacteria':'virus'));\r\n        if(Math.random() < 0.0005) bugs.push(new Bug('parasite'));\r\n        bugs.forEach(b => { b.update(); b.draw(); st.vis -= (b.type==='parasite'?0.02:0.005); });\r\n        if(laserFx.t > 0) { ctx.strokeStyle='rgba(139, 195, 74, 0.8)'; ctx.lineWidth=laserFx.t*2; ctx.beginPath(); ctx.arc(laserFx.x, laserFx.y, 15, 0, Math.PI*2); ctx.stroke(); laserFx.t--; }\r\n        st.iop += 0.008;\r\n        if(st.iop > 21) st.cup = Math.min(0.98, st.cup + 0.0002);\r\n        if(st.iop > 24) st.vis -= 0.015;\r\n        if(st.iop > 18) {\r\n            const rad = Math.max(80, 700 - (st.iop-18)*25);\r\n            const v = ctx.createRadialGradient(425, 275, rad\/2, 425, 275, rad);\r\n            v.addColorStop(0, 'rgba(0,0,0,0)'); v.addColorStop(1, `rgba(0,0,0,${Math.min(0.9, (st.iop-18)*0.1)})`);\r\n            ctx.fillStyle = v; ctx.fillRect(0,0,850,550);\r\n        }\r\n        ui.v.innerText = Math.floor(st.vis) + \"%\"; ui.v.style.color = st.vis < 30 ? \"#f44336\" : \"#4caf50\";\r\n        ui.i.innerText = Math.floor(st.iop); ui.i.style.color = st.iop > 22 ? \"#f44336\" : \"#00bcd4\";\r\n        ui.c.innerText = st.cup.toFixed(2); ui.c.style.color = st.cup > 0.7 ? \"#f44336\" : \"#ff9800\";\r\n        ui.a.innerText = st.ammo; ui.s.innerText = st.score;\r\n        if(st.vis <= 0 || st.cup >= 0.98) {\r\n            st.active = false;\r\n            document.getElementById('vd11-death-reason').innerText = st.vis <= 0 ? \"Functional blindness reached.\" : \"End-stage excavation reached.\";\r\n            ui.over.style.display = 'block';\r\n        } else { requestAnimationFrame(mainLoop); }\r\n    }\r\n});\r\n<\/script>\n\n\n<script><div id=\"vd11-wrapper\" style=\"max-width:900px; margin:20px auto; font-family:sans-serif; background:#0a0a0a; color:#fff; padding:25px; border-radius:16px; box-shadow:0 20px 50px rgba(0,0,0,0.9); text-align:center; border:2px solid #333; position:relative; user-select:none;\">\r\n    <h2 style=\"margin:0 0 15px 0; color:#38bdf8; letter-spacing:2px; text-transform:uppercase;\">Vitreous Defender: V11.0<\/h2>\r\n    <div style=\"display:grid; grid-template-columns:repeat(5, 1fr); gap:10px; margin-bottom:20px; background:#111; padding:15px; border-radius:12px; border:1px solid #444;\">\r\n        <div><div style=\"font-size:0.7rem; color:#888;\">VISION<\/div><div id=\"vd11-vis\" style=\"color:#4caf50; font-size:1.4rem; font-weight:800;\">100%<\/div><\/div>\r\n        <div><div style=\"font-size:0.7rem; color:#888;\">IOP<\/div><div id=\"vd11-iop\" style=\"color:#00bcd4; font-size:1.4rem; font-weight:800;\">15<\/div><\/div>\r\n        <div><div style=\"font-size:0.7rem; color:#888;\">VCDR<\/div><div id=\"vd11-cup\" style=\"color:#ff9800; font-size:1.4rem; font-weight:800;\">0.30<\/div><\/div>\r\n        <div><div style=\"font-size:0.7rem; color:#888;\">SYRINGES<\/div><div id=\"vd11-ammo\" style=\"color:#f48fb1; font-size:1.4rem; font-weight:800;\">3<\/div><\/div>\r\n        <div><div style=\"font-size:0.7rem; color:#888;\">SCORE<\/div><div id=\"vd11-score\" style=\"color:#fff; font-size:1.4rem; font-weight:800;\">0<\/div><\/div>\r\n    <\/div>\r\n    <div style=\"position:relative; border-radius:12px; overflow:hidden; border:3px solid #222;\">\r\n        <canvas id=\"vd11Canvas\" width=\"850\" height=\"550\" style=\"width:100%; height:auto; cursor:crosshair; display:block; background:#111;\"><\/canvas>\r\n        <div id=\"vd11-start-screen\" style=\"position:absolute; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.85); display:flex; flex-direction:column; justify-content:center; align-items:center; z-index:10;\">\r\n            <button id=\"vd11-start-btn\" style=\"padding:15px 40px; background:#005a66; color:white; border:2px solid #38bdf8; border-radius:8px; font-weight:800; font-size:1.2rem; cursor:pointer;\">COMMENCE SURGERY<\/button>\r\n            <p style=\"color:#aaa; font-size:0.85rem; margin-top:15px;\">[Laser] Zaps Pathogens | [Anti-VEGF] Clears Edema\/Heme | [Top Blue Bar] Lowers IOP<\/p>\r\n        <\/div>\r\n    <\/div>\r\n    <div style=\"display:grid; grid-template-columns:1fr 1fr; gap:15px; margin-top:20px;\">\r\n        <button id=\"vd11-btn-laser\" style=\"padding:15px; background:#b71c1c; color:white; border:3px solid #fff; border-radius:8px; cursor:pointer; font-weight:800;\">[1] ARGON LASER<\/button>\r\n        <button id=\"vd11-btn-syringe\" style=\"padding:15px; background:#880e4f; color:white; border:3px solid #333; border-radius:8px; cursor:pointer; font-weight:800;\">[2] ANTI-VEGF (\ud83d\udc89)<\/button>\r\n    <\/div>\r\n    <div id=\"vd11-gameover\" style=\"display:none; position:absolute; top:50%; left:50%; transform:translate(-50%, -50%); background:rgba(10,10,10,0.95); padding:30px; border:2px solid #f44336; border-radius:15px; z-index:20; width:350px;\">\r\n        <h2 style=\"color:#f44336; margin-top:0;\">VISION LOST<\/h2>\r\n        <p id=\"vd11-death-reason\" style=\"color:#ccc; font-size:0.9rem;\"><\/p>\r\n        <button id=\"vd11-retry-btn\" style=\"padding:10px 20px; background:#4caf50; color:white; border:none; border-radius:5px; cursor:pointer; font-weight:bold; width:80%;\">NEW PATIENT<\/button>\r\n    <\/div>\r\n<\/div>\r\n<script>\r\ndocument.addEventListener('DOMContentLoaded', function() {\r\n    const canvas = document.getElementById('vd11Canvas');\r\n    const ctx = canvas.getContext('2d');\r\n    const ui = { v: document.getElementById('vd11-vis'), i: document.getElementById('vd11-iop'), c: document.getElementById('vd11-cup'), a: document.getElementById('vd11-ammo'), s: document.getElementById('vd11-score'), bL: document.getElementById('vd11-btn-laser'), bS: document.getElementById('vd11-btn-syringe'), over: document.getElementById('vd11-gameover'), start: document.getElementById('vd11-start-screen') };\r\n    let st = { active: false, vis: 100, iop: 15, cup: 0.3, score: 0, ammo: 3, wpn: 'laser', frame: 0 };\r\n    let bugs = [], path = [], scars = [];\r\n    let laserFx = { active: false, x: 0, y: 0, t: 0 };\r\n    const bgCanvas = document.createElement('canvas');\r\n    bgCanvas.width = 850; bgCanvas.height = 550;\r\n    const bgCtx = bgCanvas.getContext('2d');\r\n    function preRenderFundus() {\r\n        const grad = bgCtx.createRadialGradient(425, 275, 50, 425, 275, 550);\r\n        grad.addColorStop(0, '#e64a19'); grad.addColorStop(0.6, '#bf360c'); grad.addColorStop(1, '#2e150f');\r\n        bgCtx.fillStyle = grad; bgCtx.fillRect(0, 0, 850, 550);\r\n        const discX = 250, discY = 275, macX = 550, macY = 275;\r\n        bgCtx.fillStyle = 'rgba(62, 39, 35, 0.5)'; bgCtx.beginPath(); bgCtx.arc(macX, macY, 65, 0, Math.PI*2); bgCtx.fill();\r\n        bgCtx.strokeStyle = '#7f0000'; bgCtx.lineCap = 'round'; bgCtx.lineJoin = 'round';\r\n        const drawVessel = (x, y, ang, len, w, curve, gen) => {\r\n            if(gen > 4 || w < 0.5) return;\r\n            bgCtx.lineWidth = w; bgCtx.beginPath(); bgCtx.moveTo(x, y);\r\n            let cx = x, cy = y, ca = ang;\r\n            for(let i=0; i<len; i+=5) { cx += Math.cos(ca)*5; cy += Math.sin(ca)*5; ca += curve; bgCtx.lineTo(cx, cy); }\r\n            bgCtx.stroke();\r\n            drawVessel(cx, cy, ca + 0.3 + Math.random()*0.1, len*0.7, w*0.6, curve*1.2, gen+1);\r\n            drawVessel(cx, cy, ca - 0.3 - Math.random()*0.1, len*0.7, w*0.6, curve*1.2, gen+1);\r\n        };\r\n        drawVessel(discX, 260, -0.6, 150, 6, 0.006, 0); drawVessel(discX, 290, 0.6, 150, 6, -0.006, 0);\r\n        drawVessel(discX, 260, -2.6, 100, 5, -0.002, 0); drawVessel(discX, 290, 2.6, 100, 5, 0.002, 0);\r\n        drawVessel(discX, 275, 0, 80, 2.5, 0, 0); \r\n    }\r\n    class Bug {\r\n        constructor(type) {\r\n            this.type = type; this.x = Math.random()*600 + 150; this.y = Math.random()*400 + 75;\r\n            this.hp = type === 'parasite' ? 3 : 1; this.a = Math.random()*6; this.tick = Math.random()*100;\r\n        }\r\n        update() {\r\n            this.tick++;\r\n            if(this.type === 'bacteria') { this.x += Math.sin(this.tick*0.05)*1.2; this.y += Math.cos(this.tick*0.03)*0.8; }\r\n            if(this.type === 'virus') { this.x += Math.cos(this.a)*1.2; this.y += Math.sin(this.a)*1.2; if(Math.random()<0.02) this.a = Math.random()*6; }\r\n            if(this.type === 'parasite') { if(this.tick % 80 < 12) { this.x += Math.cos(this.a)*12; this.y += Math.sin(this.a)*12; } else if (this.tick % 80 === 12) { this.a = Math.random()*6; } }\r\n            if(this.x<50) this.x=50; if(this.x>800) this.x=800; if(this.y<50) this.y=50; if(this.y>500) this.y=500;\r\n        }\r\n        draw() {\r\n            ctx.save(); ctx.translate(this.x, this.y);\r\n            if(this.type === 'bacteria') {\r\n                ctx.fillStyle = '#76ff03'; ctx.beginPath(); ctx.ellipse(0,0,16,8, Math.sin(this.tick*0.1), 0, Math.PI*2); ctx.fill();\r\n                ctx.fillStyle = '#000'; ctx.fillRect(4, -2, 3, 3);\r\n                ctx.strokeStyle = '#76ff03'; ctx.beginPath(); ctx.moveTo(-16,0); ctx.lineTo(-25, Math.sin(this.tick*0.2)*8); ctx.stroke();\r\n            } else if(this.type === 'virus') {\r\n                ctx.fillStyle = '#d500f9'; ctx.beginPath(); ctx.arc(0,0,12,0,Math.PI*2); ctx.fill();\r\n                ctx.strokeStyle = '#ff80ab'; ctx.lineWidth=2;\r\n                for(let i=0; i<6; i++) { ctx.rotate(Math.PI\/3); ctx.moveTo(12,0); ctx.lineTo(18,0); ctx.stroke(); }\r\n            } else if(this.type === 'parasite') {\r\n                ctx.strokeStyle = '#ff9100'; ctx.lineWidth = 6; ctx.lineCap='round'; ctx.beginPath(); ctx.moveTo(-25,0);\r\n                for(let i=-25; i<25; i+=5) ctx.lineTo(i, Math.sin(this.tick*0.2 + i*0.2)*8); ctx.stroke();\r\n                ctx.fillStyle = 'red'; ctx.beginPath(); ctx.arc(25, Math.sin(this.tick*0.2 + 5)*8, 4, 0, Math.PI*2); ctx.fill();\r\n            }\r\n            ctx.restore();\r\n        }\r\n    }\r\n    function startGame() {\r\n        ui.start.style.display = 'none'; ui.over.style.display = 'none';\r\n        st = { active: true, vis: 100, iop: 15, cup: 0.3, score: 0, ammo: 3, wpn: 'laser', frame: 0 };\r\n        bugs = []; path = []; scars = [];\r\n        preRenderFundus(); setWeapon('laser');\r\n        requestAnimationFrame(mainLoop);\r\n    }\r\n    function setWeapon(w) {\r\n        st.wpn = w;\r\n        ui.bL.style.borderColor = (w === 'laser') ? '#fff' : '#333';\r\n        ui.bS.style.borderColor = (w === 'avegf') ? '#fff' : '#333';\r\n        canvas.style.cursor = (w === 'laser') ? 'crosshair' : 'alias';\r\n    }\r\n    document.getElementById('vd11-start-btn').addEventListener('click', startGame);\r\n    document.getElementById('vd11-retry-btn').addEventListener('click', function() { location.reload(); });\r\n    document.getElementById('vd11-btn-laser').addEventListener('click', function() { setWeapon('laser'); });\r\n    document.getElementById('vd11-btn-syringe').addEventListener('click', function() { setWeapon('avegf'); });\r\n    canvas.addEventListener('mousedown', function(e) {\r\n        if(!st.active) return;\r\n        const r = canvas.getBoundingClientRect();\r\n        const mx = (e.clientX - r.left) * (850 \/ r.width), my = (e.clientY - r.top) * (550 \/ r.height);\r\n        if(my < 40) { st.iop = Math.max(10, st.iop - 5); st.score += 20; return; }\r\n        if(st.wpn === 'laser') {\r\n            laserFx = { active: true, x: mx, y: my, t: 8 };\r\n            let hit = false;\r\n            bugs = bugs.filter(b => {\r\n                if(Math.sqrt((b.x-mx)**2 + (b.y-my)**2) < 30) { b.hp--; hit = true; if(b.hp <= 0) { st.score += (b.type==='parasite'?500:100); st.vis = Math.min(100, st.vis + 2); return false; } } return true;\r\n            });\r\n            if(!hit) { st.score = Math.max(0, st.score - 5); st.vis -= 0.5; scars.push({x: mx, y: my}); }\r\n        } else if(st.wpn === 'avegf' && st.ammo > 0) {\r\n            let used = false;\r\n            path = path.filter(p => { if(Math.sqrt((p.x-mx)**2 + (p.y-my)**2) < 50) { used = true; st.score += 300; return false; } return true; });\r\n            if(used) { st.ammo--; st.vis = Math.min(100, st.vis + 5); ctx.fillStyle='white'; ctx.fillRect(0,0,850,550); if(st.ammo <= 0) setWeapon('laser'); }\r\n        }\r\n    });\r\n    function mainLoop() {\r\n        if(!st.active) return;\r\n        st.frame++;\r\n        ctx.drawImage(bgCanvas, 0, 0);\r\n        ctx.fillStyle = '#ffecb3'; ctx.beginPath(); ctx.ellipse(250, 275, 45, 55, 0, 0, Math.PI*2); ctx.fill();\r\n        ctx.fillStyle = '#fff9c4'; ctx.beginPath(); ctx.ellipse(250, 275, 45*st.cup, 55*st.cup, 0, 0, Math.PI*2); ctx.fill();\r\n        scars.forEach(s => { ctx.fillStyle = '#1a0000'; ctx.beginPath(); ctx.arc(s.x, s.y, 5, 0, Math.PI*2); ctx.fill(); ctx.fillStyle = '#fff'; ctx.beginPath(); ctx.arc(s.x, s.y, 1.5, 0, Math.PI*2); ctx.fill(); });\r\n        ctx.fillStyle = 'rgba(0,188,212,0.3)'; ctx.fillRect(0,0,850,40);\r\n        ctx.fillStyle = '#fff'; ctx.font = 'bold 12px sans-serif'; ctx.fillText(\"TRABECULAR OUTFLOW (CLICK TO DRAIN IOP)\", 300, 25);\r\n        let spawnRate = 0.005 + (st.frame * 0.000002);\r\n        if(Math.random() < spawnRate) bugs.push(new Bug(Math.random()>0.2?'bacteria':'virus'));\r\n        if(Math.random() < 0.0005) bugs.push(new Bug('parasite'));\r\n        bugs.forEach(b => { b.update(); b.draw(); st.vis -= (b.type==='parasite'?0.02:0.005); });\r\n        if(laserFx.t > 0) { ctx.strokeStyle='rgba(139, 195, 74, 0.8)'; ctx.lineWidth=laserFx.t*2; ctx.beginPath(); ctx.arc(laserFx.x, laserFx.y, 15, 0, Math.PI*2); ctx.stroke(); laserFx.t--; }\r\n        st.iop += 0.008;\r\n        if(st.iop > 21) st.cup = Math.min(0.98, st.cup + 0.0002);\r\n        if(st.iop > 24) st.vis -= 0.015;\r\n        if(st.iop > 18) {\r\n            const rad = Math.max(80, 700 - (st.iop-18)*25);\r\n            const v = ctx.createRadialGradient(425, 275, rad\/2, 425, 275, rad);\r\n            v.addColorStop(0, 'rgba(0,0,0,0)'); v.addColorStop(1, `rgba(0,0,0,${Math.min(0.9, (st.iop-18)*0.1)})`);\r\n            ctx.fillStyle = v; ctx.fillRect(0,0,850,550);\r\n        }\r\n        ui.v.innerText = Math.floor(st.vis) + \"%\"; ui.v.style.color = st.vis < 30 ? \"#f44336\" : \"#4caf50\";\r\n        ui.i.innerText = Math.floor(st.iop); ui.i.style.color = st.iop > 22 ? \"#f44336\" : \"#00bcd4\";\r\n        ui.c.innerText = st.cup.toFixed(2); ui.c.style.color = st.cup > 0.7 ? \"#f44336\" : \"#ff9800\";\r\n        ui.a.innerText = st.ammo; ui.s.innerText = st.score;\r\n        if(st.vis <= 0 || st.cup >= 0.98) {\r\n            st.active = false;\r\n            document.getElementById('vd11-death-reason').innerText = st.vis <= 0 ? \"Functional blindness reached.\" : \"End-stage excavation reached.\";\r\n            ui.over.style.display = 'block';\r\n        } else { requestAnimationFrame(mainLoop); }\r\n    }\r\n});\r\n<\/script>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-114","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/optotech.no\/index.php\/wp-json\/wp\/v2\/pages\/114","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/optotech.no\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/optotech.no\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/optotech.no\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/optotech.no\/index.php\/wp-json\/wp\/v2\/comments?post=114"}],"version-history":[{"count":11,"href":"https:\/\/optotech.no\/index.php\/wp-json\/wp\/v2\/pages\/114\/revisions"}],"predecessor-version":[{"id":128,"href":"https:\/\/optotech.no\/index.php\/wp-json\/wp\/v2\/pages\/114\/revisions\/128"}],"wp:attachment":[{"href":"https:\/\/optotech.no\/index.php\/wp-json\/wp\/v2\/media?parent=114"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}