1

This code does not allow the rectangle w/topbar to be draggable. What do I need to change? I created a scrollabel Phaser scene and can get the 'box' to draw but it is not draggable. When the user selects the topbar I want to be able to move the box in any direction within the phaser container.

This code creates the phaser scene and the scene is scrollabel x and y but the box crateed can not be selected or dragged.

let currentScene; // Global variable to store the current scene
let mainRect, topBar; // Global variables to store the main rectangle and top bar
let isDragging = false; // Variable to track if dragging is in progress

function preload() {
  console.log("Preload function called"); // Log when preload is called
  // Load assets here if needed
}

function create() {
  console.log("Create function called"); // Log when create is called
  // Assign the created scene to currentScene
  currentScene = this;

  // Log the current scene
  console.log("Current Scene:", currentScene);

  // Enable camera controls for scrolling
  this.cameras.main.setBounds(0, 0, 5000, 300); // Set the bounds of the camera
  this.cameras.main.setScroll(0, 0); // Initialize the camera position

  // Add event listener to handle two-finger scrolling within the Phaser canvas
  this.input.on('wheel', (pointer, gameObjects, deltaX, deltaY, deltaZ) => {
    if (!isDragging) {
      this.cameras.main.scrollX += deltaX;
      this.cameras.main.scrollY += deltaY;
    }
  });

  // Add touch event listeners to handle touch-based scrolling within the Phaser canvas
  this.input.on('pointerdown', (pointer) => {
    if (pointer.isDown && !isDragging) {
      this.input.dragStartX = pointer.x;
      this.input.dragStartY = pointer.y;
      this.input.cameraStartX = this.cameras.main.scrollX;
      this.input.cameraStartY = this.cameras.main.scrollY;
    }
  });

  this.input.on('pointermove', (pointer) => {
    if (pointer.isDown && !isDragging) {
      const deltaX = pointer.x - this.input.dragStartX;
      const deltaY = pointer.y - this.input.dragStartY;
      this.cameras.main.scrollX = this.input.cameraStartX - deltaX;
      this.cameras.main.scrollY = this.input.cameraStartY - deltaY;
    }
  });

  // Expose createActivityObject to the global scope for button click
  window.createActivityObject = () => createActivityObjectInternal(currentScene);
}

function update() {
  // Log the positions of the main rectangle and top bar during the update
  if (mainRect && topBar) {
    console.log(`Update - mainRect: (${mainRect.x}, ${mainRect.y}), topBar: (${topBar.x}, ${topBar.y})`);
  }
}

const config = {
  type: Phaser.AUTO,
  width: 5000, // Set the width of the visible area
  height: 300, // Set the height of the visible area
  parent: "phaser-container",
  backgroundColor: 'rgb(200, 249, 251)', // Set the background color of the Phaser scene
  scene: {
    preload: preload,
    create: create,
    update: update,
  },
  render: {
    pixelArt: true, // Enable pixel art rendering for sharper edges
    antialias: false, // Disable antialiasing for sharper edges
  },
};

document.addEventListener("DOMContentLoaded", () => {
  console.log("DOMContentLoaded event fired"); // Log when DOMContentLoaded event fires
  let game = new Phaser.Game(config);
  console.log("Game:", game); // Log the game object

  // Add event listener to the button to create the draggable object
  document.getElementById("create-activity-button").addEventListener("click", () => {
    if (currentScene) {
      createActivityObjectInternal(currentScene);
    }
  });
});

// Internal function to create a draggable rectangle with a top bar
function createActivityObjectInternal(scene) {
  console.log("Creating activity object"); // Log the function call
  console.log("The scene is: ", scene); // Log the scene object

  if (!scene) {
    console.error("Scene is not defined");
    return;
  }

  const scale = 0.15; // Scale factor to reduce size to 15%
  const rectWidth = 400 * scale * 1.5; // Increase width by 50%
  const rectHeight = 100 * scale; // Keep height the same
  const topBarHeight = 12 * scale;
  const rectX = 100;
  const rectY = 100;

  // Create the main rectangle
  mainRect = scene.add.rectangle(rectX, rectY + topBarHeight, rectWidth, rectHeight - topBarHeight, 0xffffff).setOrigin(0);
  mainRect.setStrokeStyle(2 * scale, 0x000000);
  mainRect.setDepth(1); // Ensure the main rectangle is on top
  console.log("Main rectangle created:", mainRect); // Log the main rectangle creation

  // Create the top bar
  topBar = scene.add.rectangle(rectX, rectY, rectWidth, topBarHeight, 0xffa500).setOrigin(0);
  topBar.setStrokeStyle(2 * scale, 0xffa500);
  topBar.setDepth(2); // Ensure the top bar is on top
  console.log("Top bar created:", topBar); // Log the top bar creation

  // Ensure the topBar is created before making it draggable
  if (topBar) {
    console.log("Top bar is not null or undefined"); // Log the top bar check

    // Check if input plugin is available
    if (scene.input) {
      console.log("Input plugin is available"); // Log input plugin availability

      // Add the top bar to the input system
      topBar.setInteractive();
      scene.input.setDraggable(topBar);
      console.log("Top bar added to input system and set as draggable"); // Log input system addition and draggable setting

      // Handle dragging
      scene.input.on("dragstart", (pointer, gameObject) => {
        console.log("Drag start:", gameObject); // Log drag start
        isDragging = true; // Disable scrolling
      });

      scene.input.on("drag", (pointer, gameObject, dragX, dragY) => {
        if (gameObject === topBar) {
          mainRect.x = dragX;
          mainRect.y = dragY + topBarHeight;
          topBar.x = dragX;
          topBar.y = dragY;
          console.log("Dragging:", { dragX, dragY }); // Log dragging coordinates
        }
      });

      scene.input.on("dragend", (pointer, gameObject) => {
        console.log("Drag end:", gameObject); // Log drag end
        isDragging = false; // Re-enable scrolling
      });
    } else {
      console.error("Input plugin is not available");
    }
  } else {
    console.error("Failed to create topBar");
  }
}

1 Answer 1

0

Well first of all there are two point I would like to make:

  • Great question and good documentation
  • BUT you should only post relevant code to make the question easier/fast to read and solve the issue (AND while making a MRE you might even find the bug yourself).

This out of the way, while shortening your code (see demo below), I go a functioning build.

I think the Problem is scene.input.setDraggable(topBar);, I removed this line an activated the dragging functionality through the .setInteractive({ draggable: true }) method on the topBar.
With this the dragging should work.

Short Demo:
(ShowCasing this)

let currentScene;
let isDragging = false;

function create() {
  console.log("Create function called"); // Log when create is called
  // Assign the created scene to currentScene
  currentScene = this;

  console.log("Current Scene:", currentScene);

  this.cameras.main.setBounds(0, 0, 5000, 300);
  this.cameras.main.setScroll(0, 0);

  window.createActivityObject = () => createActivityObjectInternal(currentScene);
}

const config = {
  width: 500,
  height: 180,
  parent: "phaser-container",
  scene: { create },
};

new Phaser.Game(config);

document.getElementById("create-activity-button").addEventListener("click", () => {
  if (currentScene) {
    createActivityObjectInternal(currentScene);
  }
});


function createActivityObjectInternal(scene) {

  if (!scene) {
    console.error("Scene is not defined");
    return;
  }

  const rectWidth = 100;
  const rectHeight = 50;
  const topBarHeight = 20;
  const pos = {x: 100, y:100};

  let mainRect = scene.add.rectangle(pos.x, pos.y + topBarHeight, rectWidth, rectHeight - topBarHeight, 0xffffff).setOrigin(0).setStrokeStyle(2, 0x000000);
  let topBar = scene.add.rectangle(pos.x, pos.y, rectWidth, topBarHeight, 0xffa500).setOrigin(0).setStrokeStyle(1 , 0xffa500).setInteractive({ draggable: true });
  

  scene.input.on("drag", (pointer, gameObject, dragX, dragY) => {
    if (gameObject === topBar) {
      topBar.x = dragX;
      topBar.y = dragY; 
      mainRect.x = dragX;
      mainRect.y = dragY + topBarHeight;
    }
  });

}

console.clear();
document.body.style = 'margin:0;';
<script src="//cdn.jsdelivr.net/npm/phaser/dist/phaser.min.js"></script>

<button id="create-activity-button">ADD STUFF</button>
<br />

btw.: if you are creating multipe "Items" with the Button, defining mainRect and topBar global will create an issue. For the demo I moved the definition to the function createActivityObjectInternal scope, but if you want to use them outside this function, you would have to find a better solution.

Sign up to request clarification or add additional context in comments.

3 Comments

This worked. I will be more prudent on thr code i include in the future. Thank you very much for yur help
@psimonson Sure no Problem, if you could accept my answer with the checkmark by the voting arrows of my answer, to indicate your answer was solved, that would be great. Thanks in advance
Done! Thanks again.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.