2016-05-01 4 views
0

Ich habe ein Problem mit den folgenden Spiel-Maps:Connect Side-by-Side-Rects zu einem großen Rect

Picture of the Game-Map

Ich mag die ganze Fläche in einem Array (in der Nähe von gelb) speichern, so dass der Computer später weiß, ob ein Klick durch den Benutzer auf dem Wasser ist (x/y-Koordinate des Mauszeigers nicht in dem Array) oder in dem Land (x/y koordiniert den Cursor nicht in dem Array). Ich habe bereits gemacht (Grund visuelle Darstellung): Visual Reprentation of my work Wie zu sehen ist, wird die Fläche mit gleich großen Rechtecke bedeckt, die gespeichert werden wie folgt in der Reihe:

{x:upper left corner - X-postion, y: upper left corner - Ypostion, x1:width of the rect, y1: height of the rect} 
example: {x:0, y:0, x1:3, y2: 2} 

Diese obejcts alle gespeicherten in einer großen Reihe. Es dauert jedoch zu lange, um zu bestimmen, ob ein Punkt in der Anordnung (Landfläche) oder nicht in der Anordnung (Wasserfläche) ist. (Dauert 45 Millisekunden) Ich möchte nun diese kleinen einzelnen Rechtecke zusammenführen, also größere Rechtecke bilden, die schneller mit der Mausposition verglichen werden können. Wie dieses handgemachte Beispiel: Result I want to reach Wenn es möglich ist, sollten diese kleinen Rechteck-Objekte zu einem großen Rect (wie dem grünen oder braunen) hinzugefügt werden. Bis ich noch nichts finden konnte, damit ich hoffe du kannst mir helfen. Es gibt ein weiteres Problem: Das Array, in dem ich alle kleinen Recs gespeichert habe, ist sehr groß (über 100.000 Elemente). Sie alle sind wie folgt gespeichert:

[{x:0, y: 0, x1:3, y1:2},{x:0, y: 2, x1:3, y1:2},{x:0, y: 4, x1:3, y1:2}] 

Es ist kein Problem, wenn eine Lösung mehr als 10 Minuten oder so etwas dauert.

+0

Sie fragen nach einer Bitrate rot Algorithmus (Codierung). Das kann auf viele Arten gemacht werden, einschließlich des handgemachten, genau wie Sie begonnen haben und es ist immer noch legal, da Sie es nur einmal tun werden und wahrscheinlich viel kürzer dauern werden, als den besten Algorithmus zu denken und zu implementieren. – Redu

+1

Ich denke, Sie können Bildverarbeitung Basisfarbe –

+0

@Naresh Teli Ich habe Bildverarbeitung basierend auf den Farben, um die rot markierten Rechtecke zu bekommen. Oder was meinst du? –

Antwort

1

Hier ist eine Implementierung der @ m69-Idee.

Erstellen Sie ein Array, das den Status jedes Pixels island/isNotLand darstellt.

Sie können getImageData verwenden, um die RGBA-Informationen jedes Pixels abzurufen. Das gelbliche Land hat einen hohen Rotwert, während der Ozean einen niedrigen Rotwert hat. Verwenden Sie daher den Rotwert, um Land gegen Ozean zu bestimmen. Setzen Sie diese Werte isLand/isNotLand in ein Array (Land).

var land; 
var data=context.getImageData(0,0,canvas.width,canvas.height).data; 
land=new Array(data.length/4); 
for(var i=0;i<data.length;i+=4){ 
    var red=data[i]; 
    land[i/4]=(red>200)?true:false; 
} 

Dann können Sie testen, ob die Maus über Land oder Meer wie dies effizient ist:

function isLand(x,y){ 
    return(land[mouseY*canvas.width+mouseX]);  
} 

Beispielcode und eine Demo:

var canvas=document.getElementById("canvas"); 
 
var ctx=canvas.getContext("2d"); 
 
var cw=canvas.width; 
 
var ch=canvas.height; 
 
function reOffset(){ 
 
    var BB=canvas.getBoundingClientRect(); 
 
    offsetX=BB.left; 
 
    offsetY=BB.top;   
 
} 
 
var offsetX,offsetY; 
 
reOffset(); 
 
window.onscroll=function(e){ reOffset(); } 
 
window.onresize=function(e){ reOffset(); } 
 

 
var isDown=false; 
 
var startX,startY; 
 

 
var land; 
 
var img=new Image(); 
 
img.crossOrigin='anonymous'; 
 
img.onload=start; 
 
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/map2.jpg"; 
 
function start(){ 
 
    cw=canvas.width=img.width; 
 
    ch=canvas.height=img.height; 
 

 
    ctx.drawImage(img,0,0); 
 

 
    var data=ctx.getImageData(0,0,cw,ch).data; 
 
    land=new Array(data.length/4); 
 
    for(var i=0;i<data.length;i+=4){ 
 
     var red=data[i]; 
 
     land[i/4]=(red>200)?true:false; 
 
    } 
 
    
 
    $("#canvas").mousemove(function(e){handleMouseMove(e);}); 
 

 
} 
 

 
function isLand(x,y){ 
 
    return(land[mouseY*cw+mouseX]);  
 
} 
 

 
function handleMouseMove(e){ 
 
    // tell the browser we're handling this event 
 
    e.preventDefault(); 
 
    e.stopPropagation(); 
 
    // is land under mouse? 
 
    mouseX=parseInt(e.clientX-offsetX); 
 
    mouseY=parseInt(e.clientY-offsetY); 
 
    if(isLand(mouseX,mouseY)){ 
 
     ctx.fillStyle='red'; 
 
     ctx.fillRect(mouseX,mouseY,1,1); 
 
    }else{ 
 
     ctx.fillStyle='blue'; 
 
     ctx.fillRect(mouseX,mouseY,1,1); 
 
    } 
 
}
body{ background-color: ivory; } 
 
#canvas{border:1px solid red; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> 
 
<h4>Move mouse over map.<br>Land draws a red rect. Ocean draws a blue rect</h4> 
 
<canvas id="canvas" width=300 height=300></canvas>

Verwandte Themen