Alexander Farber Posted July 8, 2016 Share Posted July 8, 2016 Hello again, I have followed the great advices given me here in the forum and have extended PIXI.Container to create draggable letter tiles for my word game. Here is my current implementation however I have now a problem with dragging (so I have opened a new topic) - "use strict"; function SmallTile() { PIXI.Container.call(this); this.interactive = true; this.buttonMode = true; this.dragging = false; this .on('mousedown', onDragStart) .on('touchstart', onDragStart) .on('mouseup', onDragEnd) .on('mouseupoutside', onDragEnd) .on('touchend', onDragEnd) .on('touchendoutside', onDragEnd) .on('mousemove', onDragMove) .on('touchmove', onDragMove); this.bgGraphics = new PIXI.Graphics(); this.bgGraphics.lineStyle(4, 0xFF00FF, 1); this.bgGraphics.beginFill(0xFFCC00, 1); this.bgGraphics.drawRoundedRect(0, 0, SmallTile.WIDTH, SmallTile.WIDTH, 15); this.bgGraphics.endFill(); this.addChild(this.bgGraphics); this.letterSprite = new PIXI.Sprite(); this.indexSprite = new PIXI.Sprite(); this.addChild(this.letterSprite); this.addChild(this.indexSprite); } SmallTile.prototype = Object.create(PIXI.Container.prototype); SmallTile.prototype.constructor = SmallTile; SmallTile.WIDTH = 60; SmallTile.sDarkLetters = {}; SmallTile.sWhiteLetters = {}; SmallTile.sDarkIndices = {}; SmallTile.sWhiteIndices = {}; SmallTile.SHADOW = [ new PIXI.filters.DropShadowFilter() ]; SmallTile.SHADOW[0].alpha = .2; SmallTile.init = function(darkLettersTexture, whiteLettersTexture, darkIndicesTexture, whiteIndicesTexture) { for (var i = 0; i < LETTERS.length; i++) { var letter = LETTERS[i]; var rect = new PIXI.Rectangle(i * SmallTile.WIDTH, 0, SmallTile.WIDTH, SmallTile.WIDTH); SmallTile.sDarkLetters[letter] = new PIXI.Texture(darkLettersTexture, rect); SmallTile.sWhiteLetters[letter] = new PIXI.Texture(whiteLettersTexture, rect); } for (var i = 0; i <= 15; i++) { var letter = LETTERS[i]; var rect = new PIXI.Rectangle(i * SmallTile.WIDTH, 0, SmallTile.WIDTH, SmallTile.WIDTH); SmallTile.sDarkIndices[i] = new PIXI.Texture(darkIndicesTexture, rect); SmallTile.sWhiteIndices[i] = new PIXI.Texture(whiteIndicesTexture, rect); } } SmallTile.prototype.setLetter = function(letter) { this.letterSprite.texture = SmallTile.sDarkLetters[letter]; this.indexSprite.texture = SmallTile.sDarkIndices[7]; } function onDragStart(event) { // QUESTION 1: How to save local mouse coords here? // QUESTION 2: How to put this SmallTile on top? this.data = event.data; this.dragging = true; this.filters = SmallTile.SHADOW; } function onDragEnd() { this.dragging = false; this.filters = null; this.data = null; } function onDragMove() { if (this.dragging) { var newPosition = this.data.getLocalPosition(this.parent); this.position.x = newPosition.x; this.position.y = newPosition.y; } } My problem is that when I start dragging a SmallTile, then it jumps to the origin (shown by the red arrow in the attached screenshot). I am sure this is a well-known beginner's problem and on another platforms (Android, Flash) I solved it by saving the local coordinates of mouse pointer in onDragStart and then subtracting them from mouse coordinates in onDragMove. But as JavaScript and pixi.js newbie I don't understand yet, how to fix this problem in the above code. I am confused by the "data" argument passed to the onDragStart function (for example in the pixi.js dragging example). Is this a MouseEvent instance and how to get the local mouse coordinates from it? When I look at the PIXI.interaction.InteractionManager doc, I am confused too - am I looking at the right doc and why doesn't it describe its "onMouseDown" member (like which arguments does it have)? Finally, here is my main invoking code and I would also be very glad to receive hints for another "well-known" problem: which code to add in SmallTile onDragStart function so that its "depth" is changed and it is put above all other children of its parent container? "use strict"; var LETTERS = [ '*', 'A', 'B', 'C', 'D', 'E', 'F' ]; jQuery(document).ready(function($) { var renderer = new PIXI.WebGLRenderer(600, 600); var boardDiv = document.getElementById('board'); boardDiv.appendChild(renderer.view); var stage = new PIXI.Container(); var loader = new PIXI.loaders.Loader('/drawable-mdpi/'); loader.add('board1' ,'game_board_1.png') .add('dark_small_letters', 'dark-letters-1980x60.png') .add('dark_large_letters', 'dark-letters-3564x108.png') .add('dark_small_indices', 'dark-indices-960x60.png') .add('dark_large_indices', 'dark-indices-1728x108.png') .add('white_small_indices', 'white-indices-960x60.png') .add('white_small_letters', 'white-letters-1980x60.png') .load(init); function init() { var board1 = new PIXI.Sprite(loader.resources.board1.texture); stage.addChild(board1); SmallTile.init( loader.resources.dark_small_letters.texture.baseTexture, loader.resources.white_small_letters.texture.baseTexture, loader.resources.dark_small_indices.texture.baseTexture, loader.resources.white_small_indices.texture.baseTexture ); for (var i = 0; i < 5; i++) { var tile = new SmallTile(); tile.setLetter(LETTERS[i]); tile.x = i * 60; tile.y = i * 60; stage.addChild(tile); } animate(); } function animate() { requestAnimationFrame(animate); renderer.render(stage); } }); Greetings Alex Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted July 8, 2016 Share Posted July 8, 2016 That's a snippet from one of my games: I dont remember why dragMove is using the same data that onDragStart got, but i think thats because we need to know which finger or mouse are doing the drag function onDragStart(event) { this.data = event.data; this.start_data = {x: event.data.originalEvent.screenX, y: event.data.originalEvent.screenY}; this.dragPos = this.data.getLocalPosition(this.parent); this.oldPosition = new PIXI.Point(); this.oldPosition.copy(this.position); this.dragging = true; } function onDragEnd(event) { var ev_data = event.data.originalEvent; //if real dragend and not a click if (this.start_data) { if (Math.abs(this.start_data.x - ev_data.screenX) > 2 || Math.abs(this.start_data.y - ev_data.screenY) > 2) event.stopPropagation(); } this.dragging = false; // set the interaction data to null this.data = null; } function onDragMove() { if (this.dragging) { var newDragPos = this.data.getLocalPosition(this.parent); var pv = this.position, pv2 = this.oldPosition; // I actually dont remember + or - , I did it with pivot but in your case its a position pv.x = pv2.x + (newDragPos.x - this.dragPos.x); pv.y = pv2.y + (newDragPos.y - this.dragPos.y); } } 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.