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");
}
}
Well first of all there are two point I would like to make:
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
andtopBar
global will create an issue. For the demo I moved the definition to the functioncreateActivityObjectInternal
scope, but if you want to use them outside this function, you would have to find a better solution.