1
私は何時間も自分のコードを見てきましたが、それでも何が間違っているのか正確には分かりません。グリッド内の六角形を選択できません
私は非常に単純なバージョンの六角形グリッドシステムを作成しました。どこでグリッド内の任意の六角形を選択したいのですか?すべての六角形が正しく表示されています。グリッドをクリックすると不正な六角形が選択されます。マウスの位置が正しくないかのように振る舞い、または おそらく、位置データ(?)が不正確な六角形である可能性があります。 しかし、どのように正しく配置されていますか?
////////// [ Hexagon ] ////////////////////
function Hexagon(options){
\t if(options !== "undefined"){
\t \t this.attributes = {
\t \t \t type : options.type || 0, //// 0 is cell , 1 player /// Default : 0 ////
\t \t \t id: options.id,
\t \t \t color : this.getColor(),
\t \t \t coords: [], //// [ r, q ] /// row/col ///
\t \t \t points: [],
\t \t \t pos: options.pos,
\t \t \t size: options.size
\t \t };
\t \t
\t \t this.states = {
\t \t \t selected: false
\t \t };
\t \t
\t \t //// make short-cuts to frequently used attributes ////
\t \t this.pos = this.attributes.pos;
\t \t this.coords = this.attributes.coords;
\t \t this.size = this.attributes.size;
\t \t this.points = this.attributes.points;
\t \t
\t \t ///// caclulate top_left, bottom and center points ////
\t \t this.TopLeftPoint = [ this.pos[0], this.pos[1] ];
\t \t this.BottomRightPoint = [ this.pos[0] + this.size.w, this.pos[1] + this.size.h ];
\t \t this.MidPoint = [ this.pos[0] + (this.size.w/2), this.pos[1] + (this.size.h/2) ];
\t \t
\t \t ///////// generate points ///////
\t \t this.generate();
\t }
}
Hexagon.prototype = {
\t constructor : Hexagon,
\t changeState: function(st_name, st_value){
\t \t if(this.checkState(st_name)) {
\t \t \t this.states[st_name] = st_value;
\t \t }
\t },
\t checkState: function(st_name){
\t \t if(typeof this.states[st_name] !== "undefined") {
\t \t \t return this.states[st_name];
\t \t }
\t \t return false;
\t },
\t isInHexBounds : function(p){ /*Point*/
\t \t if(this.TopLeftPoint[0] < p[0] && this.TopLeftPoint[1] < p[1] && p[0] < this.BottomRightPoint[0] && p[1] < this.BottomRightPoint[0]){
\t \t \t return true;
\t \t }
\t \t return false;
\t },
\t contains: function(p) {
\t \t var isIn = false;
\t \t if(this.isInHexBounds(p)){
\t \t \t var i, j = 0;
\t \t \t for (i = 0, j = this.points.length - 1; i < this.points.length; j = i++){
\t \t \t \t var iP = this.points[i];
\t \t \t \t var jP = this.points[j];
\t \t \t \t if (
\t \t \t \t \t (((iP[1] <= p[1]) && (p[1] < jP[1])) || ((jP[1] <= p[1]) && (p[1] < iP[1]))) && (p[0] < (jP[0] - iP[0]) * (p[1] - iP[1])/(jP[1] - iP[1]) + iP[0])
\t \t \t \t){
\t \t \t \t \t isIn = !isIn;
\t \t \t \t }
\t \t \t }
\t \t }
\t \t return isIn;
\t },
\t getColor: function(){
\t \t switch(this.type){
\t \t \t case 0:
\t \t \t \t return "blue";
\t \t \t case 1:
\t \t \t \t return "red";
\t \t \t default:
\t \t \t \t return "yellow";
\t \t }
\t },
\t trigger: function(e_name){
\t \t this.events[ e_name ].call(this);
\t },
\t events: {
\t \t "select" : function(){
\t \t \t if(! this.checkState("selected")){
\t \t \t \t this.changeState("selected", true);
\t \t \t \t //console.log(this.coords)
\t \t \t \t this.type = 1;
\t \t \t }
\t \t }
\t },
\t setType: function(type){
\t \t this.attributes.type = type;
\t },
\t generate: function(){///// generate hexagon points //////
\t \t var x1 = (this.size.w - this.size.s)/2;
\t \t var y1 = (this.size.h/2);
\t \t this.points.push(
\t \t \t [ x1 + this.pos[0], this.pos[1] ],
\t \t \t [ x1 + this.size.s + this.pos[0], this.pos[1] ],
\t \t \t [ this.size.w + this.pos[0], y1 + this.pos[1] ],
\t \t \t [ x1 + this.size.s + this.pos[0], this.size.h + this.pos[1] ],
\t \t \t [ x1 + this.pos[0], this.size.h + this.pos[1] ],
\t \t \t [ this.pos[0], y1 + this.pos[1] ]
\t \t);
\t },
\t draw : function(ctx){
\t \t if(this.type > 0){
\t \t \t ctx.globalAlpha = 0.5;
\t \t \t ctx.fillStyle = this.color;
\t \t \t ctx.fill();
\t \t \t ctx.globalAlpha = 1.0;
\t \t }else{
\t \t \t ctx.strokeStyle = "grey";
\t \t }
\t \t
\t \t //ctx.rect(this.BottomRightPoint[0],this.BottomRightPoint[1],4,4);
\t \t //ctx.stroke();
\t \t
\t \t ctx.lineWidth = 1;
\t \t ctx.beginPath();
\t \t ctx.moveTo(this.points[0][0], this.points[0][1]);
\t \t for(var c=1; c < this.points.length; c++){
\t \t \t ctx.lineTo(this.points[c][0], this.points[c][1]);
\t \t }
\t \t ctx.closePath();
\t \t ctx.stroke();
\t \t
\t \t this.draw_coords(ctx);
\t },
\t draw_coords: function(ctx){
\t \t ctx.font="10px Georgia";
\t \t ctx.textAlign = "center";
\t \t ctx.textBaseline = 'middle';
\t \t ctx.fillStyle = "blue";
\t \t ctx.fillText(this.coords[0]+" , "+this.coords[1], this.MidPoint[0], this.MidPoint[1]);
\t }
}
///////// [ Grid ] /////////////////////
function Grid(options){
\t if(typeof options !== "undefined"){
\t \t this.size = {
\t \t \t width: options.size[0],
\t \t \t height: options.size[1]
\t \t };
\t \t
\t \t //this.mouse_pos = [];
\t \t
\t \t this.pos = options.pos; //// position within the canvas /// [ x , y ] ////
\t \t this.ctx = options.ctx;
\t \t this.ctx_pos = options.ctx_pos; //// position of canvas element /// [ left, top] ///
\t \t this.hex_size = this.calculate_hex_size(options.hex_def);
\t \t this.hexagons = []; //// [ row, col ] ///// just a temporary array ////
\t \t this.grid2D = []; ///// includes all hexagons to be drawn ///
\t }
\t this.generate();
\t this.animate();
\t this.enable_mouse_events();
}
Grid.prototype = {
\t constructor : Grid,
\t
\t generate : function(){
\t \t var hex_pos_x = 0.0, hex_pos_y = 0.0, row = 0, col = 0, offset = 0.0, h = null, h_id = 0;
\t \t while((hex_pos_y + this.hex_size.h) <= this.size.height){
\t \t \t col = 0; //// reset col
\t \t \t offset = 0.0; //// reset offset
\t \t \t
\t \t \t if((row % 2) == 1){
\t \t \t \t offset = ((this.hex_size.w - this.hex_size.s) /2) + this.hex_size.s ;
\t \t \t \t col = 1;
\t \t \t }
\t \t \t
\t \t \t hex_pos_x = offset;
\t \t \t
\t \t \t while((hex_pos_x + this.hex_size.w) <= this.size.width){
\t \t \t \t h = new Hexagon({ pos : [ hex_pos_x, hex_pos_y ], size: this.hex_size , id: row+""+col, type: 0 });
\t \t \t \t h.coords[0] = col; //// set coord X ///
\t \t \t \t
\t \t \t \t this.grid2D.push(h);
\t \t \t \t if(! this.hexagons[col]){
\t \t \t \t \t this.hexagons[col] = [];
\t \t \t \t }
\t \t \t \t this.hexagons[col].push(h);
\t \t
\t \t \t \t col += 2;
\t \t \t \t hex_pos_x += (this.hex_size.w + this.hex_size.s);
\t \t \t }
\t \t \t
\t \t \t row++;
\t \t \t
\t \t \t hex_pos_y += (this.hex_size.h/2);
\t \t }
\t \t
\t \t ////finally go through our list of hexagons by their x co-ordinate to assign the y co-ordinate
\t \t var coordX = 0, coordY = 0, h_l = this.hexagons.length, hex_arr = [];
\t \t for( ; coordX < h_l; coordX++){
\t \t \t hex_arr = this.hexagons[ coordX ];
\t \t \t coordY = Math.floor((coordX/2) + (coordX % 2));
\t \t \t for(var h = 0, size = hex_arr.length; h < size; h++){
\t \t \t \t hex_arr[h].coords[1] = coordY++;
\t \t \t }
\t \t }
\t },
\t
\t getHexAt: function(p){ //// point [ x, y ]
\t \t for (var h = 0, h_l = this.grid2D.length; h < h_l; h++){
\t \t \t if (this.grid2D[h].contains(p)){
\t \t \t \t return this.grid2D[h];
\t \t \t }
\t \t }
\t \t return null;
\t },
\t
\t animate: function(){
\t \t var self = this;
\t \t window.requestAnimationFrame(function(){
\t \t \t self.animate();
\t \t });
\t \t self.draw();
\t },
\t draw : function(){
\t \t this.ctx.clearRect(0, 0, this.size.width, this.size.height);
\t \t for(var h = 0, h_l = this.grid2D.length; h < h_l; h++){
\t \t \t this.grid2D[h].draw(this.ctx);
\t \t }
\t },
\t calculate_hex_size : function(hex_def){
\t \t return {
\t \t \t w: hex_def.radius * 2,
\t \t \t m: hex_def.margin,
\t \t \t h: (Math.sqrt(3)/2) * (hex_def.radius * 2),
\t \t \t r: hex_def.radius,
\t \t \t s: hex_def.radius
\t \t }
\t },
\t
\t enable_mouse_events: function(){
\t \t var self = this;
\t \t var mouse_pos = [];
\t \t var cur_hex = null;
\t \t window.addEventListener('mousemove', function(e){
\t \t \t mouse_pos = [ (e.clientX - self.ctx_pos[0]), (e.clientY - self.ctx_pos[1])];
\t \t \t //self.mouse_pos = mouse_pos;
\t \t });
\t \t
\t \t window.addEventListener('mousedown', function(e){
\t \t \t if(mouse_pos.length > 0){
\t \t \t \t cur_hex = self.getHexAt(mouse_pos);
\t \t \t \t if(cur_hex != null){
\t \t \t \t \t cur_hex.trigger("select");
\t \t \t \t }
\t \t \t }
\t \t });
\t }
}
\t var c_el = document.getElementById("myCanvas");
\t var ctx = c_el.getContext("2d");
\t var nGrid = new Grid({
\t \t /// size : [ c_el.width, c_el.height ], /// [rows/cols ] //// 20 px x 10 px///
\t \t size : [ 70 , 70 ],
\t \t pos: [ 20, 20 ], /// [X, Y] ////
\t \t hex_def: {
\t \t \t radius: 20,
\t \t \t margin: 0
\t \t },
\t \t ctx : ctx,
\t \t ctx_pos: [ c_el.getBoundingClientRect().left, c_el.getBoundingClientRect().top ]
\t });
<body stye="width: 100%; height: 100%" >
\t <canvas id="myCanvas" width="750px" height="405px" style="margin:0; padding:0; border:1px solid #d3d3d3;"></canvas>
</body>