Демо JavaScript:
<canvas id="canvas" width="500" height="500" style="border: 1px solid black" onclick="storeGuess(event)"></canvas> <script> let ctx = document.getElementById('canvas').getContext('2d'); // отрисовка фона ctx.beginPath (); ctx.fillStyle = "blue"; ctx.fillRect (0, 0, 500, 300); ctx.fillStyle = "green"; ctx.fillRect (0, 300, 500, 500); ctx.stroke (); let score = 0; // переменная, хранящая кол-во попаданий в быка // функция проверки попадения точки с координатами (х, у) в многоугольник, координаты которого находятся в массивах рХ[], рУ[] function PIP (x, y) { let parity = 0; // флаг четности for (let i = 1; i < pX.length; i ++) { // цикл, перебирающий все ребра многоугольника if (pY[i] - pY[i - 1] == 0) continue; // проверка горизонтальности ребра if (Math.max (pX[i], pX[i - 1]) > x) { // проверка расположения ребра многоугольника (правее ли оно точки (х, у)) if (Math.max (pY[i], pY[i - 1]) != y) { // проверка непопадания сканируещего луча на нижний конец ребра многоугольника if (y - Math.max (pY[i], pY[i - 1]) < 0 && y - Math.min (pY[i], pY[i - 1]) >= 0) // проверка пересечения лучом ребра многоугольника parity = 1 - parity; } } } return parity; } // функция обработки нажатия на холст function storeGuess(event) { let coordX = event.offsetX, coordY = event.offsetY; if (PIP(coordX, coordY)) score ++; // добавление очков, если нажатие попадает внутрь многоугольника console.log ("coord x: " + coordX + " coord y: " + coordY, PIP(coordX, coordY)); } let x, y; x = -220; y = 220; // задание точек, относительно которых будем отрисовывать двигающиеся элементы let imgData = ctx.getImageData (0, 0, 500, 500); let pX = [], pY = []; // массивы, хранящие координаты вершин многоугольника // функция отрисовки function draw () { ctx.putImageData (imgData, 0, 0); ctx.beginPath(); // отрисовка баллов (количества попаданий в быка) ctx.font = "20px Georgia"; ctx.fillText ("Score: ", 390, 25); ctx.fillText (score, 460, 25); ctx.fillStyle = "brown"; ctx.strokeStyle = "black"; // tulovische ctx.fillRect (x, y, 150, 100); ctx.strokeRect (x, y, 150, 100); // golova ctx.fillRect (x + 125, y - 35, 80, 80); ctx.strokeRect (x + 125, y - 35, 80, 80); // glaza ctx.fillStyle = "white"; ctx.arc (x + 125 , y - 10, 10, 0, 2 * Math.PI); ctx.moveTo (x + 125 + 10 + 10 + 60 + 10, y - 10); ctx.arc (x + 125 + 10 + 10 + 60, y - 10, 10, 0, 2 * Math.PI); ctx.fill(); ctx.stroke(); ctx.beginPath(); ctx.fillStyle = "black"; ctx.moveTo (x + 125 , y - 10); ctx.arc (x + 125 + 2, y - 10, 4, 0, 2 * Math.PI); ctx.moveTo (x + 125 + 10 + 10 + 60, y - 10); ctx.arc (x + 125 + 10 + 10 + 60 - 2, y - 10, 4, 0, 2 * Math.PI); ctx.fill(); ctx.stroke(); ctx.beginPath(); // roga ctx.fillStyle = "grey"; ctx.moveTo (x + 140, y - 35 + 5); ctx.lineTo (x + 125, y - 40); ctx.lineTo (x + 127, y - 55); ctx.lineTo (x + 132, y - 42); ctx.lineTo (x + 150, y - 30); ctx.lineTo (x + 140, y - 30); ctx.fill(); let sdvig = 2 * (x + 165); // определение оси симметрии многоугольника головы ctx.moveTo (sdvig - (x + 140), y - 35 + 5); ctx.lineTo (sdvig - (x + 125), y - 40); ctx.lineTo (sdvig - (x + 127), y - 55); ctx.lineTo (sdvig - (x + 132), y - 42); ctx.lineTo (sdvig - (x + 150), y - 30); ctx.lineTo (sdvig - (x + 140), y - 30); ctx.fill(); ctx.stroke(); // rot ctx.beginPath(); ctx.fillStyle = "white"; ctx.moveTo (x + 150, y + 15); ctx.lineTo (sdvig - (x + 150), y + 15); ctx.lineTo (sdvig - (x + 150) + 10, y + 7); ctx.lineTo (sdvig - (x + 150) + 3, y + 25); ctx.lineTo (x + 147, y + 25); ctx.lineTo (x + 140, y + 7); ctx.lineTo (x + 150, y + 15); // zubi //gorizont srez ctx.moveTo (x + 145, y + 20); ctx.lineTo (sdvig - (x + 150) + 5, y + 20); // vertikalniy srez ctx. moveTo (x + 165, y + 15); ctx.lineTo (x + 165, y + 25); ctx.moveTo (x + 155, y + 15); ctx.lineTo (x + 155, y + 25); ctx.moveTo (x + 175, y + 15); ctx.lineTo (x + 175, y + 25); ctx.fill(); ctx.stroke(); ctx.beginPath(); // hvost ctx.fillStyle = "brown"; ctx.moveTo (x, y); ctx.lineTo (x - 50, y + 80); ctx.lineTo (x - 48, y + 83); ctx.lineTo (x - 46, y + 80); ctx.lineTo (x, y + 5); ctx.fill(); // nogi ctx.fillRect (x + 10, y + 100, 5, 75); ctx.fillRect (x + 40, y + 100, 5, 75); ctx.fillRect (x + 100, y + 100, 5, 75); ctx.fillRect (x + 125, y + 100, 5, 75); ctx.fillStyle = "black"; ctx.fillRect (x + 10, y + 170, 5, 5); ctx.fillRect (x + 40, y + 170, 5, 5); ctx.fillRect (x + 100, y + 170, 5, 5); ctx.fillRect (x + 125, y + 170, 5, 5); // забивка массивов координат вершин многоугольника pX[0] = x; pY[0] = y; pX[1] = x + 125; pY[1] = y; pX[2] = x + 125; pY[2] = y - 35; pX[3] = x + 205; pY[3] = y - 35; pX[4] = x + 205; pY[4] = y + 45; pX[5] = x + 150; pY[5] = y + 45; pX[6] = x + 150; pY[6] = y + 100; pX[7] = x + 130; pY[7] = y + 100; pX[8] = x + 130; pY[8] = y + 175; pX[9] = x + 125; pY[9] = y + 175; pX[10] = x + 125; pY[10] = y + 100; pX[11] = x + 105; pY[11] = y + 100; pX[12] = x + 105; pY[12] = y + 175; pX[13] = x + 100; pY[13] = y + 175; pX[14] = x + 100; pY[14] = y + 100; pX[15] = x + 45; pY[15] = y + 100; pX[16] = x + 45; pY[16] = y + 175; pX[17] = x + 40; pY[17] = y + 175; pX[18] = x + 40; pY[18] = y + 100; pX[19] = x + 15; pY[19] = y + 100; pX[20] = x + 15; pY[20] = y + 175; pX[21] = x + 10; pY[21] = y + 175; pX[22] = x + 10; pY[22] = y + 100; pX[23] = x; pY[23] = y + 100; pX[24] = x; pY[24] = y + 5; pX[25] = x - 46; pY[25] = y + 80; pX[26] = x - 48; pY[26] = y + 83; pX[27] = x - 50; pY[27] = y + 80; pX[28] = x; pY[28] = y; ctx.stroke(); // смена направления движения if (x == -220) key = 1; if (x == -80) key = -1; x += key * 5; } setInterval (draw, 100); // создаем анимацию
Прикрепленный файл | Размер |
---|---|
Kozenko_bull.zip | 2.18 кб |