2015-06-12 3 views
1

У меня есть 2 функции, первая функция рисует пустую сетку с выровненной сеткой (28x16), а вторая функция рисует квадратный квадрат, который заполняет выбранное место сетки цветом, каждый из которых равен 25X25 , вторая функция позволяет мне нарисовать прямоугольник в любом месте холста, используя расположение сетки. поэтому, чтобы нарисовать ящик, я создал другую функцию, которая вызывает места сетки и рисует ее там, например, чтобы нарисовать поле в месте сетки, где x = 5 и y = 4, эта строка должна быть введена drawWalls(5,4); эта строка может быть использована снова и снова рисовать разные коробки, поэтому я могу рисовать ящики, и функция работает отлично, теперь я хочу создать более 1 квадратного окна одновременно (например, строку ящиков), проблема в том, что я никогда не создавал такой цикл или цикл, который имеет более 1 переменной, пожалуйста, помогите, также я немного запутался с массивами, я хочу знать, хранятся ли эти поля в массиве и как я могу их снова вызвать, скажем, например Я нажимаю на коробку, и она удаляется, это не важно, но если у вас есть идеи по первой проблеме, пожалуйста, помогите, спасибо за ваше время.рисунок 2d объектов с использованием координат в сетке JavaScript

ничьих сетки

function drawGrid() { 
    ctxBg.beginPath(); 
    for (var i = 0; i <= canvasWidth-25; i+= 25) { 
     ctxBg.moveTo(-25 + i,55); 
     ctxBg.lineTo(-25 + i, canvasHeight - 55); 
    } 
    for (var i = 25; i <= canvasHeight -75; i+= 25) { 
     ctxBg.moveTo(55,25 + i); 
     ctxBg.lineTo(canvasWidth-55, 25 + i); 
    } 
    ctxBg.stroke(); 
} 

function ClearBg() { 
    ctxBg.clearRect(0,0,canvasWidth,canvasHeight); 
}  

Draw стены

function Wall(row, col) { 
    this.row = row; 
    this.col = col; 
    this.color = "#000"; 

    this.width = 25 
    this.height = 25 
    this.leftX = this.row; 
    this.rightX = this.row + this.width; 
    this.topY = this.col; 
    this.bottomY = this.col + this.height; 
} 
function drawWalls(x,y) { 
    walls.push(new Wall(x, y)); 

    for (var b = 0; b < walls.length; b++) { 
    ctxWall.fillStyle = walls[b].color; 
    ctxWall.fillRect(walls[b].row * gridSize, walls[b].col * gridSize, walls[b].width, walls[b].height); 
    } 
} 

function createWalls() { 
    drawWalls(9,9); 
    drawWalls(8,8); 
    drawWalls(7,7); 
} 

Я пытаюсь сделать функцию createWalls в цикле, чтобы привлечь их все вместе, к сожалению, я до сих пор не создал мыши событие, но я скоро буду

+0

Покажите свой фактический код. – alex

+0

Вы должны показать какой-то существующий код. Что касается нажатия на ящик, холст не поддерживает события ни на чем, что вы рисуете, единственный способ добиться этого - сохранить границы объекта, который можно щелкнуть, захватить клики на холсте и пройти все границы до тех пор, пока вы не найдете его внутри. SVG может сохранять каждую фигуру в виде объекта и реагировать на события. –

+0

Я посмотрю на SVG, спасибо – Dalomo

ответ

3

Поместите определения ваших стен в объекты javascript и сохраните эти настенные объекты в массиве. Затем используйте массив, чтобы нарисовать ваши стены по мере необходимости.

Каждая стена-объект содержит информацию, необходимую для нарисовать одну стену:

var walls=[ 
    {direction:'horizontal',startX:4,endX:6,Y:3,fill:'skyblue'}, 
    {direction:'vertical',startY:2,endY:6,X:1,fill:'lightgreen'} 
]; 

Затем вы можете перебрать массив и сделать каждую стену, основанную на каждой стене-объекта:

var cellSize=25; 

function drawAllWalls(walls){ 
    for(var i=0;i<walls.length;i++){ 
     var w=walls[i]; 
     ctxWall.fillStyle=w.fill; 
     if(w.direction=='horizontal'){ 
      for(var x=w.startX;x<=w.endX;x++){ 
       ctxWall.fillRect(x*cellSize,w.Y*cellSize,cellSize,cellSize) 
      } 
     }else{ 
      for(var y=w.startY;y<=w.endY;y++){ 
       ctxWall.fillRect(w.X*cellSize,y*cellSize,cellSize,cellSize) 
      } 
     } 
    } 
} 

Если вы позже захотите удалить конкретную стену, вы можете:

  • Удалить эту стену из массива стен.
  • Очистить холст,
  • Перерисовать все оставшиеся стены в массиве (удаленная стена не будет перерисована).

Если позже вы захотите удалить только один ящик от стены, вы можете:

  • Удалить эту стену из стен массива.
  • Добавить обратно часть (части) стены, которые все еще существуют в массив стены,
  • Очистить холст,
  • перерисовать все стены в массиве (удаленный ящик не будет перерисовывается).

Вот пример кода и демо:

enter image description here

var canvas=document.getElementById("canvas"); 
 
var ctxBg=canvas.getContext("2d"); 
 
var ctxWall=canvas.getContext("2d"); 
 
var canvasWidth=canvas.width; 
 
var canvasHeight=canvas.height; 
 

 
var colCount=8; 
 
var rowCount=8; 
 
var cellSize=25; 
 

 
var walls=[ 
 
    {direction:'horizontal',startX:4,endX:6,Y:3,fill:'skyblue'}, 
 
    {direction:'vertical',startY:2,endY:6,X:1,fill:'lightgreen'} 
 
]; 
 

 
drawGrid(); 
 
drawAllWalls(walls); 
 

 
function drawAllWalls(walls){ 
 
    for(var i=0;i<walls.length;i++){ 
 
    var w=walls[i]; 
 
    ctxWall.fillStyle=w.fill; 
 
    if(w.direction=='horizontal'){ 
 
     for(var x=w.startX;x<=w.endX;x++){ 
 
     ctxWall.fillRect(x*cellSize,w.Y*cellSize,cellSize,cellSize) 
 
     } 
 
    }else{ 
 
     for(var y=w.startY;y<=w.endY;y++){ 
 
     ctxWall.fillRect(w.X*cellSize,y*cellSize,cellSize,cellSize) 
 
     } 
 
    } 
 
    } 
 
} 
 

 
function drawGrid(){ 
 
    ctxBg.beginPath(); 
 
    for(var x=0;x<colCount+1;x++){ 
 
    ctxBg.moveTo(x*cellSize,0); 
 
    ctxBg.lineTo(x*cellSize,rowCount*cellSize); 
 
    } 
 
    for(var y=0;y<rowCount+1;y++){ 
 
    ctxBg.moveTo(0,y*cellSize,0); 
 
    ctxBg.lineTo(colCount*cellSize,y*cellSize); 
 
    } 
 
    ctxBg.stroke(); 
 
}
body{ background-color: ivory; } 
 
#canvas{border:1px solid red; margin:0 auto; }
<canvas id="canvas" width=300 height=300></canvas>

+1

спасибо, это действительно помогает alot :) – Dalomo

4

Это была забавная вещь, чтобы сделать: http://jsfiddle.net/techsin/rcjouqkf/

Для того, чтобы получить какую-либо «коробку/клетка» координирует все, что вам нужно сделать, это:

  1. прибудет й положение щелчка делит его по размеру коробки, так что вы знаете
  2. который боксировать вы в туре это до следующего целого числа, которое
  3. представляют собой коробку, в которой вы находитесь. затем раз это номер с ящиком размер. это дает вам правый край окна повторите для y, чтобы получить нижний край.

    Чтобы получить сверху и слева, просто вычтите размер от краев.

    var can = getById('can'), 
        boxes = 20, 
        size = 20, 
        ctx = can.getContext('2d'), 
        clearBtn = getById('clearBtn'); 
    
    drawGrid(); 
    
    function drawGrid() { 
        var len = can.height = can.width = boxes * size; 
        for (var i = 0; i < boxes; i++) { 
         ctx.beginPath(); 
         ctx.moveTo(size + size * i - .5, 0); 
         ctx.lineTo(size + size * i - .5, len); 
         ctx.moveTo(0, size + size * i - .5); 
         ctx.lineTo(len, size + size * i - .5); 
         ctx.stroke(); 
        } 
    } 
    
    
    can.addEventListener('mousemove', function (evt) { 
        var mousePos = getMousePos(can, evt); 
        var sx = (Math.ceil(mousePos.x/size)-1)*size, 
         sy = (Math.ceil(mousePos.y/size)-1)*size; 
        console.log(sx,sy,sx+size,sy+size); 
        ctx.fillRect(sx,sy,size,size); 
    }, false); 
    
    clearBtn.addEventListener('click', function (evt) { 
        ctx.clearRect(0,0,can.width,can.height); 
        drawGrid(); 
    }); 
    
    
    function getMousePos(canvas, evt) { 
        var rect = can.getBoundingClientRect(); 
        return { 
         x: evt.clientX - rect.left, 
         y: evt.clientY - rect.top 
        }; 
    } 
    
    function getById(x) { 
        return document.getElementById(x); 
    } 
    
+1

Upvote для краткости кода. :-) Вы можете выделить sx, sy & fillRect в отдельную функцию, чтобы вопроситель также мог программно рисовать стену. – markE

+0

Ха-ха, это потрясающе, спасибо – Dalomo

Смежные вопросы