haldur Posted February 4, 2016 Share Posted February 4, 2016 Hello ! At first : I'm not good in english writing and speeking, sorry for the quality of the language ... I'm new in javascript, and I wanted to write a little game. After days of searching and reading, I choose pixi.js. I write an object named Hexagone, witch contains a PIXI.Graphics named hex that I want to be interactive. in this object I create an hitArea into hex and I had a hex.click function (line 81) I want that when I click on one figures that the console print the x and y coordonate of the hexagone, but it always print 0, 0, can you explain me why ? Here is the code, thanks for your attention function jeu(){ console.log(PIXI); var renderer = PIXI.autoDetectRenderer(600, 600,{antialias: true, transparent: false, resolution: 1}); document.getElementById("pixi").appendChild(renderer.view); var stage = new PIXI.Container(0xFFFFFF); //var background= new PIXI.Sprite.fromImage('prairie-verte-1_2997580.jpg'); var param = { l : 60, calcule : function(){ this.h= this.l*0.45; this.x1 = this.l/4; this.y1 = 0; this.x2 = this.l*3/4; this.y2 = this.y1; this.x3 = this.l; this.y3 = this.h; this.x4 = this.x2; this.y4 = this.h*2; this.x5 = this.x1; this.y5 = this.h*2; this.x6 = 0; this.y6 = this.h; }, }; param.calcule() function Hexagone(x,y) { this.x=x; this.y=y; if(this.x%2 == 0){ this.xBase = this.x*3*param.l/4; this.yBase = this.y*2*param.h } else{ this.xBase = this.x*3*param.l/4; this.yBase = (this.y+1/2)*2*param.h } } Hexagone.prototype.dessiner = function(){ this.hex = new PIXI.Graphics(); this.hex.beginFill(0x00FF00); this.hex.lineStyle(1, 0x000000); this.hex.moveTo(this.xBase + param.x1, this.yBase + param.y1); this.hex.lineTo(this.xBase + param.x2, this.yBase + param.y2); this.hex.lineTo(this.xBase + param.l/2, this.yBase + param.h); this.hex.endFill(); this.hex.beginFill(0x00FF00); this.hex.moveTo(this.xBase + param.x2, this.yBase + param.y2); this.hex.lineTo(this.xBase + param.x3, this.yBase + param.y3); this.hex.lineTo(this.xBase + param.l/2, this.yBase + param.h); this.hex.endFill(); this.hex.beginFill(0x00FF00); this.hex.moveTo(this.xBase + param.x3, this.yBase + param.y3); this.hex.lineTo(this.xBase + param.x4, this.yBase + param.y4); this.hex.lineTo(this.xBase + param.l/2, this.yBase + param.h); this.hex.endFill(); this.hex.beginFill(0x00FF00); this.hex.moveTo(this.xBase + param.x4, this.yBase + param.y4); this.hex.lineTo(this.xBase + param.x5, this.yBase + param.y5); this.hex.lineTo(this.xBase + param.l/2, this.yBase + param.h); this.hex.endFill(); this.hex.beginFill(0x00FF00); this.hex.moveTo(this.xBase + param.x5, this.yBase + param.y5); this.hex.lineTo(this.xBase + param.x6, this.yBase + param.y6); this.hex.lineTo(this.xBase + param.l/2, this.yBase + param.h); this.hex.endFill(); this.hex.beginFill(0x00FF00); this.hex.moveTo(this.xBase + param.x6, this.yBase + param.y6); this.hex.lineTo(this.xBase + param.x1, this.yBase + param.y1); this.hex.lineTo(this.xBase + param.l/2, this.yBase + param.h); this.hex.endFill(); this.hex.hitArea = new PIXI.Polygon([ new PIXI.Point(this.xBase + param.x1,this.yBase + param.y1), new PIXI.Point(this.xBase + param.x2,this.yBase + param.y2), new PIXI.Point(this.xBase + param.x3,this.yBase + param.y3), new PIXI.Point(this.xBase + param.x4,this.yBase + param.y4), new PIXI.Point(this.xBase + param.x5,this.yBase + param.y5) ]); this.hex.interactive = true; this.hex.click =function(data){console.log("click x :"+this.x+" y : "+this.y)}; stage.addChild(this.hex); } listeHexa=[]; for(var y=0;y<10;y++){ for(var x=0;x<10;x++){ hexa = new Hexagone(x,y) hexa.dessiner() listeHexa.push(hexa); } } renderer.render(stage); update(); function update(){ requestAnimationFrame(update); renderer.render(stage); }; } Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted February 4, 2016 Share Posted February 4, 2016 Can you look at whats in the "data" variable? Quote Link to comment Share on other sites More sharing options...
haldur Posted February 4, 2016 Author Share Posted February 4, 2016 Hello Ivan For the moment I've seen just 'object' Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted February 4, 2016 Share Posted February 4, 2016 console.log("event data", data); Quote Link to comment Share on other sites More sharing options...
haldur Posted February 4, 2016 Author Share Posted February 4, 2016 Ok when i typed data.data.getLocalPosition(stage) I have the location of the mouse Quote Link to comment Share on other sites More sharing options...
haldur Posted February 4, 2016 Author Share Posted February 4, 2016 and whith your command : event data Object { stopped: false, target: Object, type: "click", data: Object, stopPropagation: InteractionManager/this.eventData.stopPropagation() } Quote Link to comment Share on other sites More sharing options...
haldur Posted February 4, 2016 Author Share Posted February 4, 2016 to be more precise i changed the function : this.hex.click =function(event){ console.log("click x :"+this.x+" y : "+this.y) console.log("event",event) console.log("event.data",event.data) console.log("event.data.global",event.data.global) }; and the result is click x :0 y : 0 hexaboom.js:82:4 14:05:48,307 event Object { stopped: false, target: Object, type: "click", data: Object, stopPropagation: InteractionManager/this.eventData.stopPropagation() } hexaboom.js:83:4 14:05:48,310 event.data Object { global: Object, target: null, originalEvent: mouseup } hexaboom.js:84:4 14:05:48,313 event.data.global Object { x: 346, y: 361.1333312988281 } But what I want is not just the coordonates in pixels but the column and the row of the Hexagone clicked Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted February 4, 2016 Share Posted February 4, 2016 // either this var self = this; this.hex.on('click', function(event) { console.log(self.x, self.y); }); // or bind function click(event) { console.log(this.x, this.y); } this.hex.on('click', click.bind(this); // ES6 way this.hex.on(() => { console.log(this.x, this.y); }); The problem is to pass "this" into the function. Its common javascript problem Its the same problem as here: haldur 1 Quote Link to comment Share on other sites More sharing options...
haldur Posted February 4, 2016 Author Share Posted February 4, 2016 Thank you Ivan I've choosen the bind way and it's OK ! Your right it's a problem for newbies in JS (I'm a java programer). And understanding how to handle with function is not easy ! The ECMASCRIPT 6 Way look like scala function, but I didn't manage to implement it. For peoble who wans to know the solution I post my code here function jeu(){ console.log(PIXI); var renderer = PIXI.autoDetectRenderer(600, 600,{antialias: true, transparent: false, resolution: 1}); document.getElementById("pixi").appendChild(renderer.view); var stage = new PIXI.Container(0xFFFFFF); //var background= new PIXI.Sprite.fromImage('prairie-verte-1_2997580.jpg'); var param = { l : 60, calcule : function(){ this.h= this.l*0.45; this.x1 = this.l/4; this.y1 = 0; this.x2 = this.l*3/4; this.y2 = this.y1; this.x3 = this.l; this.y3 = this.h; this.x4 = this.x2; this.y4 = this.h*2; this.x5 = this.x1; this.y5 = this.h*2; this.x6 = 0; this.y6 = this.h; }, }; param.calcule() function Hexagone(x,y) { this.x=x; this.y=y; if(this.x%2 == 0){ this.xBase = this.x*3*param.l/4; this.yBase = this.y*2*param.h } else{ this.xBase = this.x*3*param.l/4; this.yBase = (this.y+1/2)*2*param.h } } Hexagone.prototype.dessiner = function(){ this.hex = new PIXI.Graphics(); this.hex.beginFill(0x00FF00); this.hex.lineStyle(1, 0x000000); this.hex.moveTo(this.xBase + param.x1, this.yBase + param.y1); this.hex.lineTo(this.xBase + param.x2, this.yBase + param.y2); this.hex.lineTo(this.xBase + param.l/2, this.yBase + param.h); this.hex.endFill(); this.hex.beginFill(0x00FF00); this.hex.moveTo(this.xBase + param.x2, this.yBase + param.y2); this.hex.lineTo(this.xBase + param.x3, this.yBase + param.y3); this.hex.lineTo(this.xBase + param.l/2, this.yBase + param.h); this.hex.endFill(); this.hex.beginFill(0x00FF00); this.hex.moveTo(this.xBase + param.x3, this.yBase + param.y3); this.hex.lineTo(this.xBase + param.x4, this.yBase + param.y4); this.hex.lineTo(this.xBase + param.l/2, this.yBase + param.h); this.hex.endFill(); this.hex.beginFill(0x00FF00); this.hex.moveTo(this.xBase + param.x4, this.yBase + param.y4); this.hex.lineTo(this.xBase + param.x5, this.yBase + param.y5); this.hex.lineTo(this.xBase + param.l/2, this.yBase + param.h); this.hex.endFill(); this.hex.beginFill(0x00FF00); this.hex.moveTo(this.xBase + param.x5, this.yBase + param.y5); this.hex.lineTo(this.xBase + param.x6, this.yBase + param.y6); this.hex.lineTo(this.xBase + param.l/2, this.yBase + param.h); this.hex.endFill(); this.hex.beginFill(0x00FF00); this.hex.moveTo(this.xBase + param.x6, this.yBase + param.y6); this.hex.lineTo(this.xBase + param.x1, this.yBase + param.y1); this.hex.lineTo(this.xBase + param.l/2, this.yBase + param.h); this.hex.endFill(); this.hex.hitArea = new PIXI.Polygon([ new PIXI.Point(this.xBase + param.x1,this.yBase + param.y1), new PIXI.Point(this.xBase + param.x2,this.yBase + param.y2), new PIXI.Point(this.xBase + param.x3,this.yBase + param.y3), new PIXI.Point(this.xBase + param.x4,this.yBase + param.y4), new PIXI.Point(this.xBase + param.x5,this.yBase + param.y5) ]); this.hex.interactive = true; this.hex.on('click',this.click.bind(this)); stage.addChild(this.hex); } Hexagone.prototype.click = function(event){ console.log("click x :"+this.x+" y : "+this.y) console.log("event",event) console.log("event.data",event.data) console.log("event.data.global",event.data.global) } listeHexa=[]; for(var y=0;y<10;y++){ for(var x=0;x<10;x++){ hexa = new Hexagone(x,y) hexa.dessiner() listeHexa.push(hexa); } } renderer.render(stage); update(); function update(){ requestAnimationFrame(update); renderer.render(stage); }; } Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted February 4, 2016 Share Posted February 4, 2016 WOW! I just wrote a tutorial for you. I didnt test it Ok, there is other stuff I see: 1) if you declare a local variable, that'll remove all "this": var hex = this.hex = new PIXI.Graphics; hex.beginFill(...); 2) That will remove xbase and ybase from your code. hex.position.x = baseX; hex.position.y = baseY; hex.moveTo(param.x1, param.y1); 3) Performance of that stuff will be AWFUL. Its better to generate a texture of hexagon, and create multiple sprites based on it. You can look at https://github.com/pixijs/pixi.js/blob/master/src/core/graphics/Graphics.js#L695 if you want to understand it. //setup a shape for interaction. I assume that (0,0) is your center. var shape = new PIXI.Polygon([param.x1, param.y1, param.x2, param.y2, ... ]); // generate texture for hex var graphics = new PIXI.Graphics(); //set lineWidth and stuff //... //now add the shape //may be this thing will be needed: //shape.closed = true; graphics.drawShape(shape); var hexTex = graphics.generateTexture(); //somewhere in hex this.hex = new Sprite(hexTex); //we need the shape for interaction this.hex.hitArea = shape; //here i really hope that (0,0) was the center of your shape this.hex.anchor.x = 0.5; this.hex.anchor.y = 0.5; //but if it wasnt, its not the problem. Graphics calculates the shift anyway :) //var shapeBounds = graphics.getLocalBounds(); //this.hex.anchor.x = -bounds.x / bounds.width; //this.hex.anchor.y = -bounds.y / bounds.height; Now we have only one texture, and PIXI will draw a bunch of sprite hexes for the same price as it draws one. On mouse click PIXI will check every for hex shape for intersection. We have only one shape, but each sprite has different position, so of course it can be optimized. But mouse clicks are so rare, why bother? If you have multiple types of hex, you can use multiple texture, though that will be a problem in v3 (v4 will have multitexturing), you can switch to using multiple textures per one basetexture, also called "an atlas": http://renderhjs.net/shoebox/ can produce it. haldur 1 Quote Link to comment Share on other sites More sharing options...
haldur Posted February 5, 2016 Author Share Posted February 5, 2016 Hello Thanks for your advices, it's very kind of you. Now I'll working on animation ! See you soon ! Quote Link to comment Share on other sites More sharing options...
haldur Posted February 5, 2016 Author Share Posted February 5, 2016 It was a good id to have juste one shape that could be use everyware. But I change my code and I work now with a real sprite from a png file. And I don't manage to make work interactivity with the same shape on all object, I have to create a new one each time. like that : var renderer = PIXI.autoDetectRenderer(600, 600,{antialias: true, transparent: false, resolution: 1}); document.getElementById("pixi").appendChild(renderer.view); var stage = new PIXI.Container(0xFFFFFF,true); var textureAssiette= new PIXI.Texture.fromImage('assiette60.png'); ... ... function Hexagone(x,y) { this.x=x; this.y=y; var hex = new PIXI.Sprite(textureAssiette); hex.anchor.x = 0; hex.anchor.y = 0; hex.position.x=this.xBase; hex.position.y=this.yBase; hex.interactive=true; hex.hitArea = new PIXI.Polygon([ param.x1,param.y1, param.x2,param.y2, param.x3,param.y3, param.x4,param.y4, param.x5,param.y5 ]); hex.on('click',this.click.bind(this)); if(this.x%2 == 0){ hex.position.x = x*3*param.l/4; hex.position.y = y*2*param.h } else{ hex.position.x = x*3*param.l/4; hex.position.y = (y+1/2)*2*param.h } stage.addChild(hex); this.hex=hex; } and this doesn't work with no error var renderer = PIXI.autoDetectRenderer(600, 600,{antialias: true, transparent: false, resolution: 1}); document.getElementById("pixi").appendChild(renderer.view); var stage = new PIXI.Container(0xFFFFFF,true); var textureAssiette= new PIXI.Texture.fromImage('assiette60.png'); ... ... var zoneCliquable = new PIXI.Polygon([ param.x1,param.y1, param.x2,param.y2, param.x3,param.y3, param.x4,param.y4, param.x5,param.y5 ]); param.calcule(); function Hexagone(x,y) { this.x=x; this.y=y; var hex = new PIXI.Sprite(textureAssiette); hex.anchor.x = 0; hex.anchor.y = 0; hex.position.x=this.xBase; hex.position.y=this.yBase; hex.interactive=true; hex.hitArea = zoneCliquable; hex.on('click',this.click.bind(this)); if(this.x%2 == 0){ hex.position.x = x*3*param.l/4; hex.position.y = y*2*param.h } else{ hex.position.x = x*3*param.l/4; hex.position.y = (y+1/2)*2*param.h } stage.addChild(hex); this.hex=hex; } Quote Link to comment Share on other sites More sharing options...
haldur Posted February 5, 2016 Author Share Posted February 5, 2016 Ok all is workign well now !!! function jeu(){ var renderer = PIXI.autoDetectRenderer(600, 600,{antialias: true, transparent: false, resolution: 1}); document.getElementById("pixi").appendChild(renderer.view); var stage = new PIXI.Container(0xFFFFFF,true); var textureAssiette= new PIXI.Texture.fromImage('assiette60.png'); var param = { l : 60, calcule : function(){ this.h= this.l*0.45; this.x1 = this.l/4; this.y1 = 0; this.x2 = this.l*3/4; this.y2 = this.y1; this.x3 = this.l; this.y3 = this.h; this.x4 = this.x2; this.y4 = this.h*2; this.x5 = this.x1; this.y5 = this.h*2; this.x6 = 0; this.y6 = this.h; }, }; textureAssiette.hitArea = new PIXI.Polygon([ param.x1,param.y1, param.x2,param.y2, param.x3,param.y3, param.x4,param.y4, param.x5,param.y5 ]); param.calcule(); function Hexagone(x,y) { this.x=x; this.y=y; var hex = new PIXI.Sprite(textureAssiette); hex.anchor.x = 0; hex.anchor.y = 0; hex.position.x=this.xBase; hex.position.y=this.yBase; hex.interactive=true; hex.on('click',this.click.bind(this)); if(this.x%2 == 0){ hex.position.x = x*3*param.l/4; hex.position.y = y*2*param.h } else{ hex.position.x = x*3*param.l/4; hex.position.y = (y+1/2)*2*param.h } stage.addChild(hex); this.hex=hex; } Hexagone.prototype.click = function(event){ console.log("click x :"+this.x+" y : "+this.y) console.log("event",event) console.log("event.data",event.data) console.log("event.data.global",event.data.global) } Hexagone.prototype.deplacer = function(){ this.hex.position.x+=3; } listeHexa=[]; for(var y=0;y<10;y++){ for(var x=0;x<10;x++){ hexa = new Hexagone(x,y) listeHexa.push(hexa); } } update(); function update(){ requestAnimationFrame(update); renderer.render(stage); }; Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted February 5, 2016 Share Posted February 5, 2016 You forgot to use hitArea. Your hexes are rectangular from interaction manager perspective haldur 1 Quote Link to comment Share on other sites More sharing options...
haldur Posted February 5, 2016 Author Share Posted February 5, 2016 So I have to make a new Polygon each time... Thanks ! Quote Link to comment Share on other sites More sharing options...
haldur Posted February 5, 2016 Author Share Posted February 5, 2016 Ok it works, and I don't have to make a new Polygon each time. All is perfect now ! Quote Link to comment Share on other sites More sharing options...
haldur Posted February 5, 2016 Author Share Posted February 5, 2016 I understand why the area didn't worked the last time : the function param.calcule() where called after the polygone definition ... Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.