Игра на JS эффект ночи
Всем привет. Решил я вообщем сделать свою небольшую игрушку, ничего особенного простенькая бродилка по карте из двухмерного массива с индексами координат спрайтов для отрисовки текстур ландшафта.
И вот стало мне интересно, как можно реализовать в игре эффект смены времени суток? Что бы вся карта очень сильно затемнялась, но в некоторых точках которые я определю на оси X и Y (например у фонаря или в точке нахождения персонажа), был небольшой радиус подсвечивающий ближайшую местность. Хочу добиться вот такого эффекта как на этих скриншотах! https://www.google.ru/imgres?imgurl=...&iact=c&ictx=1 https://www.google.ru/imgres?imgurl=...&iact=c&ictx=1 https://www.google.ru/imgres?imgurl=...&iact=c&ictx=1 Буду благодарен за помощь! |
я так полагаю делаете используя обычные html элементы?
|
Вложений: 1
Цитата:
В принципе я немного продвинулся по этому направлению, написал для персонажа функцию нахождения дистанции объекта относительно персонажа и установил переменную с радиусом света, если дистанция больше, тогда поверх фона отрисовываю новый слой rgba(0,0,0,0.8) если же радиус меньше то добавляю легкое затемнение, вроде работает var map = location.getMap("bg"); for (var i = 0 ; i < map.length; i++) { for (var j = 0; j < map[i].length; j++) { var x = (j * cellSize) + offset_map.x, y = (i * cellSize) + offset_map.y; if(character.getDistanseTo({x: x + (cellSize / 2), y: y + (cellSize / 2)}) >= character.getRadiusLight()) { ctx.fillStyle = "rgba(0,0,0,0.8)"; ctx.fillRect(x, y, cellSize, cellSize); } else { ctx.fillStyle = "rgba(0,0,0,0.3)"; ctx.fillRect(x, y, cellSize, cellSize); } } } Но есть некоторые недочеты и тут так как вся система карты у меня построена на сетке 32х32 так и отрисовка немного "квадратная" получается... Вот думаю как исправить. Если кто подскажет красивую формулу вычета разницы между этими отступами и закрашивания соседних квадратов ровно по линии радиуса персонажа, буду безмерно благодарен! |
canvas круг света
Arhitector,
мысли вслух ... <!DOCTYPE HTML> <html> <head> <title>Untitled</title> </head> <body> <canvas id="canvas" width="600" height="400" style="border:1px solid #d3d3d3;"></canvas> <script> var img = new Image; img.src = "https://mdn.mozillademos.org/files/5397/rhino.jpg"; img.onload = function() { draw(this); }; function draw(img) { var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); ctx.fillStyle = "black"; ctx.fillRect(0, 0, 600, 400); function move(event) { ctx.drawImage(img, 0, 0, 600, 400); var x = event.layerX; var y = event.layerY; var grd = ctx.createRadialGradient(x, y, 5, x, y, 100); grd.addColorStop(0, "transparent"); grd.addColorStop(1, "black"); ctx.fillStyle = grd; ctx.fillRect(0, 0, 600, 400); } canvas.addEventListener("mousemove", move); }; </script> </body> </html> |
Вложений: 2
Цитата:
Тут возникает немного другая проблема, когда вешаю данный код на функцию при наведением мыши которая запускается при попадании курсора на холст, всё работает замечательно. А вот когда пытаюсь привязать данное действие к координатам персонажа в функции которая запускается сразу и начинает зацикленно отрисовывать мою карту, вот тут сразу же игру ломает вот такая ошибка Uncaught TypeError: Failed to execute 'createRadialGradient' on 'CanvasRenderingContext2D': The provided double value is non-finite. at Object.drawMapBackground (draw.js:212) at render (game.js:178) at Image.water_bg.onload (game.js:211) function render () { // отрисовка ландшафта, объектов персонажа и тд тд тд draw.drawMapBackground(); // <<<<----- сюда requestAnimationFrame(render); // зацикливание отрисовки } var draw = { // код код код // drawMapBackground: function () { var real_pos = character.getRealCoordinates(); var grd = ctx.createRadialGradient(real_pos.x, real_pos.y, 10, real_pos.x, real_pos.y, r); grd.addColorStop(0, "transparent"); grd.addColorStop(1, "rgba(0,0,0,0.85)"); ctx.fillStyle = grd; ctx.fillRect(0, 0, example.width, example.height); } } С чем это может быть связано? Сам я что то не смог разобраться, гугловский перевод аля "Предоставляемое двойное значение не ограничено" как то совсем не помог увы :( |
Arhitector,
по обрывкам кода сложно что-то сказать, и выше была только идея, реализовать её можно по разному. |
Проверьте real_pos.x, real_pos.y и r.
Они должны быть числами(но не NaN или Infinite) и не строками. Возможно перед вызовом createRadialGradient можно проверить? if(!Number.isFinite(real_pos.x)) console.log("invalid real_pos.x"); if(!Number.isFinite(real_pos.y)) console.log("invalid real_pos.y"); if(!Number.isFinite(r)) console.log("invalid r"); |
Цитата:
И правда, совсем уже видимо замотался с этим делом, голова у меня не варит, переменные то проверить забыл, всё сразу встало на места. Я уже даже такую штуку написать успел... брр var r = character.getRadiusLight(), pos = character.getCoordinates(), normalDrawBG = function(object) { var r = object.r, x = object.x, y = object.y, bend = Math.round(object.r / Math.PI); ctx.fillStyle = "rgba(0,0,0,0.85)"; ctx.moveTo(x - r, y); ctx.bezierCurveTo(x - r, (y - r) - bend, x + r, (y - r) - bend, x + r, y); ctx.bezierCurveTo(x + r, y + r + bend, x - r, y + r + bend, x - r, y); }; ctx.beginPath(); normalDrawBG({x: pos.x, y: pos.y, r: r}); ctx.moveTo(0, 0); ctx.lineTo(0, canvas.height); ctx.lineTo(canvas.width, canvas.height); ctx.lineTo(canvas.width, 0); ctx.closePath(); ctx.fill(); |
Цитата:
|
Еще сразу тогда спрошу тут же, что бы темы не плодить. Можно ли добавить одновременно 2-3 и более таких эффектов на карту?
|
Часовой пояс GMT +3, время: 02:25. |