EaselJs performance issue for many sprite classes - javascript

I would like to ask whether does easeljs has performance issue for many sprite class objects? It seems that from my codepen demo, its terribly lagging...below's code as follows:
var $window = $(window),
wh = $window.innerHeight(),
ww = $window.innerWidth();
var stage = new createjs.Stage("sceneStage");
var w, h, drone;
var runnerSprite2, runnerContainer, drone2, droneContainer, robot;
var robot__movement_speed = 1;
var building_right, building_left;
var queue = new createjs.LoadQueue(),
$state = $('#state'),
$progress = $('#progress'),
$progressbar = $('#progressbar .bar');
queue.on('complete', onComplete);
queue.on('error', onError);
queue.on('fileload', onFileLoad);
queue.on('fileprogress', onFileProgress);
queue.on('progress', onProgress);
queue.loadManifest([
{
id: '2',
src: 'images/sprite_robot_test_plus_toss.png'
},
{
id: '3',
src: 'images/Drones-Hovering-Loop-12fps.png'
},
{
id: '4',
src: 'images/sprite_robot_plus_toss.png'
},
{
id: '5',
src: 'images/sprite_protestor.png'
}
]);
function onComplete(event) {
console.log('Complete', event);
$state.text( $state.text() + '[All loaded]' );
$progressbar.addClass('complete');
$('#mainContainer').addClass('hide');
$('#drone').removeClass('hidden');
loadScenes();
}
function onError(event) {
console.log('Error', event);
$state.text( $state.text() + '[' + event + ' errored] ');
}
function onFileLoad(event) {
console.log('File loaded', event);
$state.text( $state.text() + '[' + event.item.id + ' loaded] ');
}
function onFileProgress(event) {
console.log('File progress', event);
}
function onProgress(event) {
var progress = Math.round(event.loaded * 100);
console.log('General progress', Math.round(event.loaded) * 100, event);
$progress.text(progress + '%');
$progressbar.css({
'width': progress + '%'
});
}
function loadScenes() {
// grab canvas width and height for later calculations:
stage.canvas.width = window.innerWidth;
stage.canvas.height = window.innerHeight;
w = stage.canvas.width;
h = stage.canvas.height;
//----- Drones --------//
var data = new createjs.SpriteSheet({
"images": ["images/Drones-Hovering-Loop-12fps.png"],
"frames": {"regX": 0, "height": 262, "count": 25, "regY": 0, "width": 250},
"animations": {
"idle": [0, 24],
"stun": [0, 0]
},
framerate: 24
});
drone = new createjs.Sprite(data, "idle");
drone.setBounds(null, null, 250, 262);
drone.y = h - drone.getBounds().height;
drone.x = w - drone.getBounds().width;
building_right = drone;
var drone_left = new createjs.Sprite(data, "stun");
drone_left.setBounds(null, null, 250, 262);
drone_left.regX = 250;
drone_left.y = h - drone_left.getBounds().height;
drone_left.x = drone_left.regX;
building_left = drone_left;
droneContainer = new createjs.Container();
droneContainer.addChild(drone, drone_left);
stage.addChild(droneContainer, runnerContainer);
var robot_walk_left_arry = [],
robot_walk_right_arry = [];
for(var i = 14; i< 50; i++) {
robot_walk_left_arry.push(i);
}
for(var i = 49; i > 13; i--) {
robot_walk_right_arry.push(i);
}
console.log(robot_walk_right_arry);
var robot_data = new createjs.SpriteSheet({
"images": ["images/sprite_robot_test_plus_toss.png"],
"frames": {"regX": 0, "height": 540, "count": 83, "regY": 0, "width": 810},
"animations": {
idle: {
frames: [0,1,2,3,4,5,6,7,8,9,10,11,12,11,10,9,8,7,6,5,4,3,2,1]
},
walk_left: {
frames: robot_walk_left_arry,
speed: 1 * robot__movement_speed
},
walk_right: {
frames: robot_walk_right_arry,
speed: 1 * robot__movement_speed
},
toss_left: [50, 82, "idle", 0.8 * robot__movement_speed]
},
framerate: 24
});
robot = new createjs.Sprite(robot_data, "idle");
robot.setBounds(null, null, 810, 540);
robot.regX = 405;
robot.x = (w - robot.getBounds().width);
robot.y = h - robot.getBounds().height;
robot._body_dimen = 162;
stage.addChild(robot);
var protestor_data = new createjs.SpriteSheet({
"images": ["images/sprite_protestor.png"],
"frames": {"regX": 0, "height": 216, "count": 39, "regY": 0, "width": 384},
"animations": {
idle: {
frames: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,13,12,11,10,9,8,7,6,5,4,3,2,1]
},
recovery: [33, 38, "idle", 1],
nudge: [15,33, "recovery", 1]
},
framerate: 24
});
var protestor = new createjs.Sprite(protestor_data, "idle");
protestor.setBounds(null, null, 384, 216);
protestor.x = 200;
protestor.y = h - protestor.getBounds().height;
stage.addChild(protestor);
drone_left.on("click", function() {
tweenthis(robot, robot.x, "left");
});
drone.on("click", function() {
tweenthis(robot, robot.x, "right");
});
createjs.Ticker.framerate = 30;
createjs.Ticker.timingMode = createjs.Ticker.RAF;
createjs.Ticker.addEventListener("tick", tick);
// createjs.Ticker.on("tick", stage);
}
function handleClick(evt, data) {
console.log('test');
}
function tick(event) {
stage.update(event);
}
Generally I just create 4 sprite classes with 3 different sprite images. But didn't expect it to be running so lagging.

The protestors image seems to be 8k x 8k pixel in size (with only the top part filled apparently)... That's about 192 MB unpacked... That will bring down any engine... Make sure your animation images are more efficiently packed and of a more reasonable size...

Related

Custom range slider does not work on mobile phone

I have a webpage with a custom price slider. For desktop it works just fine and when I check it in google developer tools for mobile, it works too, but when I open the webpage with my phone, slider stops working properly, it does not change the plan column. How can I debug something like that?
http://sagemailer-17.eugeneskom.com/
that's the code being used for the slider
window.onload = () => {
const init = function() {
const breakpoints = [{
value: 0,
step: 12.5,
stepsSoFar: 0
},
{
value: 200,
step: 50,
stepsSoFar: 16
},
{
value: 1000,
step: 50,
stepsSoFar: 32
},
{
value: 2000,
step: 500,
stepsSoFar: 52
},
{
value: 10000,
step: 1000,
stepsSoFar: 68
},
{
value: 30000,
step: 5000,
stepsSoFar: 88
},
{
value: 100000,
step: 10000,
stepsSoFar: 102
},
{
value: 300000,
step: 50000,
stepsSoFar: 122
},
{
value: 1000000,
stepsSoFar: 136,
step: 1
}
];
const pricing = [
[200, 4, 0.2],
[500, 10, 0.01],
[1000, 15, 0.01],
[2000, 20, 0.005],
[7000, 50, 0.005],
[10000, 65, 0.0025],
[16000, 80, 0.0022],
[25000, 100, 0.006],
[30000, 130, 0.002],
[65000, 200, 0.002],
[100000, 270, 0.0015],
[200000, 420, 0.0015],
[300000, 570, 0.0006],
[600000, 750, 0.0006],
[700000, 810, 0.0006],
[800000, 870, 0.0006],
[900000, 930, 0.0006],
[1000000, 990, 0.001]
];
const planBgs = document.querySelectorAll(".StepRangeSlider__trackHeadItem");
const media = window.matchMedia("(max-width: 1024px)");
const minValue = 200;
const maxStep = breakpoints[breakpoints.length - 1].stepsSoFar;
const slider = document.getElementById("stepRangeSliderWrap");
const handle = document.getElementById("rangeSliderHandle");
const tooltip = document.getElementById("rangeSliderTooltip");
const plans = document.querySelectorAll(".plan-content .right .content");
let plansBreakPoints;
let valueBlock;
let emailsBlock;
let isHorizontal;
let value = 200;
let step = 18;
let pressed = false;
const checkRangeSliderVersion = () => {
if (media.matches) {
valueBlock = document.querySelectorAll(".display-price-mob");
emailsBlock = document.querySelectorAll(".emails-count");
isHorizontal = false;
} else {
valueBlock = document.querySelectorAll(".display-price");
emailsBlock = document.querySelectorAll(".emails-count");
isHorizontal = true;
}
plansBreakPoints = [
planBgs[1].getBoundingClientRect()[isHorizontal ? "left" : "top"],
planBgs[2].getBoundingClientRect()[isHorizontal ? "left" : "top"]
];
};
checkRangeSliderVersion();
media.addListener(checkRangeSliderVersion);
const getPriceForEmailsCount = emails => {
for (let i = pricing.length - 1; i >= 0; i--) {
if (emails === pricing[i][0]) {
return pricing[i][1];
}
if (emails > pricing[i][0]) {
return (emails - pricing[i][0]) * pricing[i + 1][2] + pricing[i][1];
}
}
return null;
};
const getValueForStep = step => {
const nearest = breakpoints.reduce((prev, curr) =>
curr.stepsSoFar < step && curr.stepsSoFar > prev.stepsSoFar ?
curr :
prev
);
const additionalValue = (step - nearest.stepsSoFar) * nearest.step;
return nearest.value + additionalValue;
};
const handleChange = () => {
const offset = (step / maxStep) * 100;
handle.style[isHorizontal ? "left" : "top"] = offset + "%";
tooltip.textContent = Math.floor(value);
valueBlock.forEach(e => {
e.textContent = getPriceForEmailsCount(value) + "$";
});
emailsBlock.forEach(e => {
e.textContent = Math.floor(value);
});
};
const handleMove = e => {
const client = isHorizontal ? e.clientX : e.clientY;
const sliderRect = slider.getBoundingClientRect();
let startPosition = isHorizontal ? sliderRect.left : sliderRect.top;
let endPosition = isHorizontal ? sliderRect.right : sliderRect.bottom;
if (client <= plansBreakPoints[0]) {
plans.forEach(e => {
e.style.display = "none";
});
plans[0].style.display = "block";
} else if (
client >= plansBreakPoints[0] &&
client <= plansBreakPoints[1]
) {
plans.forEach(e => {
e.style.display = "none";
});
plans[1].style.display = "block";
} else if (client >= plansBreakPoints[1]) {
plans.forEach(e => {
e.style.display = "none";
});
plans[2].style.display = "block";
}
if (!client) return;
let position;
if (client < startPosition) {
position = 0;
} else if (client > endPosition) {
position = endPosition - startPosition;
} else {
position = client - startPosition;
}
const currentStep = Math.round(
(position / (isHorizontal ? sliderRect.width : sliderRect.height)) *
maxStep
);
const currentStepValue = getValueForStep(currentStep);
if (
currentStepValue >= minValue &&
(currentStepValue !== value || currentStep !== step)
) {
value = currentStepValue;
step = currentStep;
handleChange();
}
};
const handleTouchMove = e => {
if (pressed) {
handleMouseMove(e.touches[0]);
}
};
const handleMouseUp = e => {
if (pressed) {
pressed = false;
}
};
const handleMouseMove = e => {
if (pressed) {
handleMove(e);
}
};
window.addEventListener("touchmove", handleTouchMove);
window.addEventListener("touchend", handleMouseUp);
window.addEventListener("mousemove", handleMouseMove);
window.addEventListener("mouseup", handleMouseUp);
slider.addEventListener("mousedown", function(e) {
e.preventDefault();
pressed = true;
handleMove(e);
});
slider.addEventListener("touchmove", e => {
e.preventDefault();
pressed = true;
handleMove(e.touches[0]);
});
handle.addEventListener("mousedown", function(e) {
e.preventDefault();
pressed = true;
handleMove(e);
});
handle.addEventListener("ontouchstart", function(e) {
e.preventDefault();
pressed = true;
handleMove(e.touches[0]);
});
};
init();
};

Three JS: OrbitControls the pixel of picture jumps when dragging

I recently started to deal with 3d, I want to move around the scene, but when dragging, I see how the pixels in the pictures start jumping before the camera stops moving. This is clearly the wrong job
Why is this happening? And how to avoid it?
My code: https://codepen.io/davedev13/pen/zYEyxRX
const data = {
"objects": [
{
"img": "https://picsum.photos/400/500",
"title": "Creative",
"description": "lorem ipsum",
"url": "/1",
"position": {
"left": "-500",
"top": "500"
}
},
{
"img": "https://picsum.photos/400/500",
"title": "Angles",
"description": "lorem ipsum",
"url": "/2",
"position": {
"left": "500",
"top": "-500"
}
},
{
"img": "https://picsum.photos/400/500",
"title": "Awwards",
"description": "lorem ipsum",
"url": "/3",
"position": {
"left": "500",
"top": "0"
}
},
{
"img": "https://picsum.photos/400/500",
"title": "Conexe",
"description": "lorem ipsum",
"url": "/4",
"position": {
"left": "0",
"top": "500"
}
},
{
"img": "https://picsum.photos/400/500",
"title": "Luxury",
"description": "lorem ipsum",
"url": "/5",
"position": {
"left": "-500",
"top": "0"
}
},
{
"img": "https://picsum.photos/400/500",
"title": "Develop",
"description": "lorem ipsum",
"url": "/6",
"position": {
"left": "0",
"top": "-500"
}
},
{
"img": "https://picsum.photos/400/500",
"title": "Desing",
"description": "lorem ipsum",
"url": "/7",
"position": {
"left": "500",
"top": "500"
}
},
{
"img": "https://picsum.photos/400/500",
"title": "Sociality",
"description": "lorem ipsum",
"url": "/8",
"position": {
"left": "-500",
"top": "-500"
}
}
]
}
class Drag {
drag = {
width: 2560,
height: 1440,
};
mouseOut = false;
constructor(container) {
this.container = container;
let w = container.clientWidth;
let h = container.clientHeight;
let viewSize = h;
let aspectRatio = w / h;
this.viewport = {
viewSize: viewSize,
aspectRatio: aspectRatio,
left: (-aspectRatio * viewSize) / 2,
right: (aspectRatio * viewSize) / 2,
top: viewSize / 2,
bottom: -viewSize / 2,
near: -10,
far: 100
}
this.initScene();
}
initScene() {
this.camera = new THREE.OrthographicCamera(
this.viewport.left, this.viewport.right,
this.viewport.top, this.viewport.bottom,
this.viewport.near, this.viewport.far
);
this.scene = new THREE.Scene();
this.renderer = new THREE.WebGLRenderer({
// alpha: true // чтобы сцена была прозрачной
});
this.renderer.domElement.id = 'canvasGrid';
this.renderer.setPixelRatio(window.devicePixelRatio);
this.renderer.setSize(window.innerWidth, window.innerHeight);
this.renderer.setClearColor(0xdcdcdc, 1);
this.container.appendChild(this.renderer.domElement);
// драг контейнер для сцены
const geometry = new THREE.PlaneGeometry(this.drag.width, this.drag.height);
const material = new THREE.MeshBasicMaterial({
color: 0xdcdcdc,
});
this.drag.plane = new THREE.Mesh(geometry, material);
// драг бокс по которому гранимац которого будет двигаться сцена при драге
this.dragBox = new THREE.Box3().setFromObject(this.drag.plane);
this.scene.add(this.drag.plane);
this.sceneObjects();
this.setControls();
this.animate();
window.addEventListener('mouseout', () => this.mouseOut = true, false);
window.addEventListener('mouseover', () => {
this.mouseOut = false;
this.animate();
}, false);
}
sceneObjects() {
// instantiate a loader
const loader = new THREE.TextureLoader();
data.objects.map((item) => {
const group = new THREE.Group();
group.name = item.title;
// load a resource
loader.load(
// resource URL
item.img,
// onLoad callback
function (texture) {
const width = texture.image.naturalWidth * 0.5;
const height = texture.image.naturalHeight * 0.5;
// in this example we create the material when the texture is loaded
const geometry = new THREE.BoxGeometry(width, height, 0);
const material = new THREE.MeshBasicMaterial({map: texture});
const mesh = new THREE.Mesh(geometry, material);
group.add(mesh);
group.position.set(item.position.left, item.position.top, 0);
},
// onProgress callback currently not supported
undefined,
// onError callback
function (err) {
console.error('An error happened.', err);
}
);
this.scene.add(group);
});
const geometry1 = new THREE.BoxGeometry(550, 300, 0);
const texture = new THREE.TextureLoader().load("https://miro.medium.com/max/1400/1*Ynit7J26tXLwyq-sB3AUug.png");
console.log(texture)
const material1 = new THREE.MeshBasicMaterial({map: texture, opacity: 0.3});
const mesh = new THREE.Mesh(geometry1, material1);
this.scene.add(mesh);
}
render() {
// if (this.mouseDownPressed) {
let x1 = this.camera.position.x + (this.camera.left / this.camera.zoom);
let x1a = Math.max(x1, this.dragBox.min.x);
let pos_x = x1a - (this.camera.left / this.camera.zoom);
let x2 = pos_x + (this.camera.right / this.camera.zoom);
let x2a = Math.min(x2, this.dragBox.max.x);
pos_x = x2a - (this.camera.right / this.camera.zoom);
let y1 = this.camera.position.y + (this.camera.bottom / this.camera.zoom);
let y1a = Math.max(y1, this.dragBox.min.y);
let pos_y = y1a - (this.camera.bottom / this.camera.zoom);
let y2 = pos_y + (this.camera.top / this.camera.zoom);
let y2a = Math.min(y2, this.dragBox.max.y);
pos_y = y2a - (this.camera.top / this.camera.zoom);
this.camera.position.set(pos_x, pos_y, this.camera.position.z);
this.camera.lookAt(pos_x, pos_y, this.controls.target.z); // todo: what is it?
this.controls.target.set(pos_x, pos_y, 0);
this.controls.update();
// }
this.renderer.render(this.scene, this.camera);
}
setControls() {
// Need to be similar to what is in OrbitControls3Dpane.js constructor
this.controls = new THREE.OrbitControls(this.camera, this.renderer.domElement);
this.controls.mouseButtons = {
LEFT: THREE.MOUSE.PAN,
MIDDLE: THREE.MOUSE.DOLLY,
RIGHT: THREE.MOUSE.PAN
}
//////////////////////////////////////
// Set rotate related parameters
//////////////////////////////////////
// No rotation.
this.controls.enableRotate = false;
this.controls.minPolarAngle = Math.PI / 2;
this.controls.maxPolarAngle = Math.PI / 2;
// No orbit horizontally.
this.controls.minAzimuthAngle = 0; // radians
this.controls.maxAzimuthAngle = 0; // radians
//////////////////////////////////////
// Set zoom related parameters
//////////////////////////////////////
this.controls.enableZoom = true;
this.controls.zoomSpeed = 0.9;
this.controls.minDistance = this.camera.near;
this.controls.maxDistance = this.camera.far;
this.controls.minZoom = window.innerWidth > window.innerHeight ?
window.innerWidth / this.drag.width : window.innerHeight / this.drag.height;
this.controls.maxZoom = 1 + this.controls.minZoom;
//////////////////////////////////////
// Set pan related parameters
//////////////////////////////////////
this.controls.enablePan = true;
this.controls.panSpeed = 0.6;
this.controls.screenSpacePanning = true;
this.controls.enableDamping = true;
// this.renderer.domElement.addEventListener('mousedown', () => {
// this.mouseDownPressed = true;
// }, false);
// this.renderer.domElement.addEventListener('mouseup', () => {
// setTimeout(() => {
// this.mouseDownPressed = false;
// }, 700);
// }, false);
}
animate() {
this.render();
if (!this.mouseOut) {
requestAnimationFrame(this.animate.bind(this));
}
}
}
function init() {
new Drag(document.querySelector('.canvas'));
}
init();
.canvas {
width: 100vw;
height: 100vh;
}
<!-- partial:index.partial.html -->
<div class="canvas"></div>
<!-- partial -->
<script src='https://threejs.org/build/three.js'></script>
<script src='https://threejs.org/examples/js/controls/OrbitControls.js'></script><script src="./script.js"></script>
I created a scene using "OrthographicCamera" and move this camera along with OrbitControls, perhaps this is not the best option in my case, if so - tell me how to do it correctly?
antialias: true resolved at WebGLRenderer
with all the same settings, the scene immediately became smoother and the pictures do not bug
that is, he lowered the performance and taxied out...

PDFjs view pdf to canvas

I am developing a pdf viewer, with the ability to apply additional elements by the user.
Pdf has drag and drop capability, zoom in and out.
I ran into the following problems that baffle me:
Correctly position the new elements so that the image is set at coordinates x: 0, y: 0. (image 1) When displacing pdf, I can not track what distance to displace the coordinates of the new element. (image 2)
To keep the image quality when zooming in, I set the camera Zoom (init scale) to 3. I can't find a solution how to display it in a smaller size when opening the page, so as not to lose quality when zooming in. (image 3)
import React, { useEffect, useState, useRef } from 'react';
import * as PDFJS from 'pdfjs-dist'
import pdfjsWorker from "pdfjs-dist/build/pdf.worker.entry";
import {makeStyles} from "#material-ui/core/styles";
export const PdfCanvas = ({pageNum, editCanvas, colorCircle}) => {
const canvasRef = useRef();
const [image, setImage] = useState();
const fileUri = "https://s3-us-east-2.amazonaws.com/c9e8e9c8-7ec0-412f-81cc-60fc07201419/Bar%20Yohai_Coordination%20plane%2000.pdf";
const mainCanvas = canvasRef.current
const mainCtx = mainCanvas?.getContext('2d');
let cameraOffset = { x: window.innerWidth/2, y: window.innerHeight/2 }
let cameraZoom = 3
let MAX_ZOOM = 108
let MIN_ZOOM = 0.01
let SCROLL_SENSITIVITY = 0.0005
const [positionArr, setPositionArr] = useState([
{id: '1', x: 400, y: 40, radius: 10, color: 'rgb(255,0,0)'},
{id: '2', x: 800, y: 40, radius: 10, color: 'rgb(134,211,17)'},
{id: '3', x: 100, y: 40, radius: 10, color: 'rgb(32,52,157)'},
{id: '4', x: 720, y: 40, radius: 10, color: 'rgb(10,9,9)'},
{id: '5', x: 640, y: 40, radius: 10, color: 'rgb(227,170,24)'},
]);
function isIntersect(point: { x: any; y: any; }, circle: { id?: string; x: any; y: any; radius: any; color?: string; }) {
return Math.sqrt((point.x-circle.x) ** 2 + (point.y - circle.y) ** 2) < circle.radius;
}
const renderPage = (pageNum) => {
const canvas = document.createElement('canvas'), ctx = canvas.getContext('2d');
const container = document.getElementById("container")
if (fileUri) {
const loadingTask = PDFJS.getDocument(fileUri);
loadingTask.promise.then(loadedPdf => {
loadedPdf && loadedPdf.getPage(pageNum).then(function(page) {
const viewport = page.getViewport({scale: cameraZoom});
canvas.width = viewport.width;
canvas.height = viewport.height ;
canvas.style.width = "100%";
canvas.style.height = "100%";
container.style.width = Math.floor(viewport.width/cameraZoom) + 'pt';
container.style.height = Math.floor(viewport.height/cameraZoom) + 'pt';
const renderContext = {
canvasContext: ctx,
viewport: viewport
};
page.render(renderContext).promise.then(() => {
var pdfImage = new Image();
pdfImage.src = canvas.toDataURL("image/png", 1)
setImage(pdfImage)
})
});
}, function (reason) {
console.error(reason);
});
}
};
function draw()
{
if (mainCanvas) {
mainCanvas.width = visualViewport.width
mainCanvas.height = visualViewport.height
}
// Translate to the canvas centre before zooming - so you'll always zoom on what you're looking directly at
if (mainCtx) {
mainCtx.scale(cameraZoom, cameraZoom)
mainCtx.translate( -window.innerWidth / .8 + cameraOffset.x, -window.innerHeight / .8 + cameraOffset.y )
mainCtx.clearRect(0,0, window.innerWidth, window.innerHeight)
mainCtx.fillStyle = "#991111"
if (image) {
mainCtx.drawImage(image, 1, 1);
(positionArr || []).map(circle => {
mainCtx?.beginPath();
mainCtx?.arc(circle.x, circle.y, circle.radius / cameraZoom, 0, 2 * Math.PI, false);
if (mainCtx) {
mainCtx.fillStyle = circle.color
}
mainCtx?.fill();
});
}
}
requestAnimationFrame( draw )
}
// Gets the relevant location from a mouse or single touch event
function getEventLocation(e)
{
if (e.touches && e.touches.length === 1)
{
return { x:e.touches[0].clientX, y: e.touches[0].clientY }
}
else if (e.clientX && e.clientY)
{
return { x: e.clientX, y: e.clientY }
}
}
let isDragging = false
let dragStart = { x: 0, y: 0 }
function onPointerDown(e)
{
isDragging = true
dragStart.x = getEventLocation(e).x/cameraZoom - cameraOffset.x
dragStart.y = getEventLocation(e).y/cameraZoom - cameraOffset.y
}
function onPointerUp(e)
{
isDragging = false
initialPinchDistance = null
lastZoom = cameraZoom
}
function onPointerMove(e)
{
if (isDragging)
{
cameraOffset.x = getEventLocation(e).x/cameraZoom - dragStart.x
cameraOffset.y = getEventLocation(e).y/cameraZoom - dragStart.y
}
}
function handleTouch(e, singleTouchHandler)
{
if ( e.touches.length === 1 )
{
singleTouchHandler(e)
}
else if (e.type === "touchmove" && e.touches.length === 2)
{
isDragging = false
handlePinch(e)
}
}
let initialPinchDistance = null
let lastZoom = cameraZoom
function handlePinch(e)
{
e.preventDefault()
let touch1 = { x: e.touches[0].clientX, y: e.touches[0].clientY }
let touch2 = { x: e.touches[1].clientX, y: e.touches[1].clientY }
// This is distance squared, but no need for an expensive sqrt as it's only used in ratio
let currentDistance = (touch1.x - touch2.x)**2 + (touch1.y - touch2.y)**2
if (initialPinchDistance == null)
{
initialPinchDistance = currentDistance
}
else
{
adjustZoom( null, currentDistance/initialPinchDistance )
}
}
function adjustZoom(zoomAmount, zoomFactor, e)
{
if (!isDragging)
{
if (zoomAmount)
{
cameraZoom += zoomAmount*zoomFactor
}
else if (zoomFactor)
{
cameraZoom = zoomFactor*lastZoom
}
cameraZoom = Math.min( cameraZoom, MAX_ZOOM )
cameraZoom = Math.max( cameraZoom, MIN_ZOOM )
}
}
const handleAddIcon = (event: React.MouseEvent<HTMLCanvasElement, MouseEvent>) => {
if (editCanvas){
const x = event.nativeEvent.offsetX / cameraZoom
const y = event.nativeEvent.offsetY / cameraZoom
console.log(x, y)
const circle = {
id: Math.random().toFixed(2), x, y, radius: 10, color: colorCircle
}
mainCtx?.beginPath();
mainCtx?.arc(circle.x, circle.y, circle.radius, 0, 2 * Math.PI, false);
if (mainCtx) {
mainCtx.fillStyle = circle.color
}
mainCtx?.fill();
const newArr = positionArr;
newArr.push(circle)
setPositionArr(newArr)
} else {
const point = {
x : event.nativeEvent.offsetX / cameraZoom,
y : event.nativeEvent.offsetY / cameraZoom
};
console.log(cameraOffset, "cameraOffset")
console.log(point, "point")
positionArr.forEach(circle => {
if (isIntersect(point, circle)) {
alert('click on circle: ' + circle.id);
}
});
}
};
// Ready, set, go
useEffect(() => {
renderPage(pageNum)
}, [])
draw()
return (
<div id="container">
<canvas
onWheel={(e) => adjustZoom(cameraZoom, e.deltaY*SCROLL_SENSITIVITY, e)}
onMouseMove={onPointerMove}
onMouseUp={onPointerUp}
onTouchStart={(e) => handleTouch(e, onPointerDown)}
onTouchMove={(e) => handleTouch(e, onPointerMove)}
onTouchEnd={(e) => handleTouch(e, onPointerUp)}
onMouseDown={(e) => {onPointerDown(e)}}
onClick={(e) => handleAddIcon(e)}
ref={canvasRef} />
</div>
)
}
image 1
image 2
image 3
I would be very glad if someone can tell me the ways to solve these problems.

Collider in Phaser 3 randomly doesn't work

I just began coding in Phaser 3 after developing some games with p5.js and wanted to make a 2d endless runner game. So here's the code for my game:
var game;
var gameOptions = {
monkeyGravity: 1200,
monkeyPower: 1000
}
window.onload = function() {
let gameConfig = {
type: Phaser.AUTO,
backgroundColor:0x87ceeb,
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_BOTH,
parent: 'thegame',
width: 1920,
height: 1080
},
physics: {
default: 'arcade',
arcade: {debug: true}
},
scene: [
startGame,
playGame
]
}
game = new Phaser.Game(gameConfig);
window.focus();
}
class startGame extends Phaser.Scene{
constructor(){
super('StartGame');
}
preload(){
this.load.image('menu-bg', '/jeffrey2nd/menu-bg.png');
this.load.image('play-button', '/jeffrey2nd/play-button.png');
}
create() {
this.menuBg = this.add.sprite(game.config.width / 2, 0, 'menu-bg').setScale(2);
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2;
const screenCenterY = this.cameras.main.worldView.y + this.cameras.main.height / 2;
const startButton = this.add.sprite(screenCenterX, screenCenterY, 'play-button');
startButton.setInteractive();
startButton.on('pointerdown', () => this.scene.start('PlayGame'));
}
}
class playGame extends Phaser.Scene{
constructor(){
super('PlayGame');
}
preload(){
this.load.image('background', '/jeffrey2nd/background.png');
this.load.image('backgroundL1', '/jeffrey2nd/backgroundL1.png');
this.load.image('backgroundL2', '/jeffrey2nd/backgroundL2.png');
this.load.image('backgroundL3', '/jeffrey2nd/backgroundL3.png');
this.load.image('backgroundL4', '/jeffrey2nd/backgroundL4.png');
this.load.image('ground', '/jeffrey2nd/ground.png');
//ANIMATIONS
this.load.image('run0', '/jeffrey2nd/animations/monkey/Running_000.png');
this.load.image('run1', '/jeffrey2nd/animations/monkey/Running_001.png');
this.load.image('run2', '/jeffrey2nd/animations/monkey/Running_002.png');
this.load.image('run3', '/jeffrey2nd/animations/monkey/Running_003.png');
this.load.image('run4', '/jeffrey2nd/animations/monkey/Running_004.png');
this.load.image('run5', '/jeffrey2nd/animations/monkey/Running_005.png');
this.load.image('run6', '/jeffrey2nd/animations/monkey/Running_006.png');
this.load.image('run7', '/jeffrey2nd/animations/monkey/Running_007.png');
this.load.image('run8', '/jeffrey2nd/animations/monkey/Running_008.png');
this.load.image('run9', '/jeffrey2nd/animations/monkey/Running_009.png');
this.load.image('run10', '/jeffrey2nd/animations/monkey/Running_010.png');
this.load.image('run11', '/jeffrey2nd/animations/monkey/Running_011.png');
this.load.image('run12', '/jeffrey2nd/animations/monkey/Running_012.png');
this.load.image('run13', '/jeffrey2nd/animations/monkey/Running_013.png');
this.load.image('jump0', '/jeffrey2nd/animations/monkey/Jumping_000.png');
this.load.image('jump1', '/jeffrey2nd/animations/monkey/Jumping_001.png');
this.load.image('jump2', '/jeffrey2nd/animations/monkey/Jumping_002.png');
this.load.image('jump3', '/jeffrey2nd/animations/monkey/Jumping_003.png');
this.load.image('jump4', '/jeffrey2nd/animations/monkey/Jumping_004.png');
}
create(){
//BACKGROUND AND LAYERS
this.bgLs = this.add.group();
this.background = this.bgLs.create(0, game.config.height / 2, 'background');
this.backgroundL1 = this.bgLs.create(0, game.config.height / 2, 'backgroundL1');
this.backgroundL12 = this.bgLs.create(game.config.width, game.config.height / 2, 'backgroundL1');
this.backgroundL2 = this.bgLs.create(0, game.config.height / 2, 'backgroundL2');
this.backgroundL22 = this.bgLs.create(game.config.width, game.config.height / 2, 'backgroundL2');
this.backgroundL3 = this.bgLs.create(0, game.config.height / 2, 'backgroundL3');
this.backgroundL32 = this.bgLs.create(game.config.width, game.config.height / 2, 'backgroundL3');
this.backgroundL4 = this.bgLs.create(0, game.config.height / 2, 'backgroundL4');
this.backgroundL42 = this.bgLs.create(game.config.width, game.config.height / 2, 'backgroundL4');
for (let b of this.bgLs.children.entries) {
b.setOrigin(0, 0.5);
}
//GROUND PLATFORMS
this.groundGroup = this.physics.add.group();
this.ground1 = this.groundGroup.create(0, game.config.height - 50, 'ground');
this.ground2 = this.groundGroup.create(game.config.width, game.config.height - 50, 'ground');
this.ground3 = this.groundGroup.create(game.config.width + game.config.width / 2, game.config.height - 275, 'ground');
this.ground4 = this.groundGroup.create(game.config.width + game.config.width / 1.5, game.config.height - 500, 'ground');
this.ground4.setScale(0.5, 1);
for (let g of this.groundGroup.children.entries) {
g.setOrigin(0, 0.5);
g.setImmovable(true);
g.setScale(1,0.3);
g.body.checkCollision.down = false;
}
//MONKEY
this.monkey = this.physics.add.sprite(game.config.width / 10 * 2, 500, 'run0');
this.monkey.setScale(0.3);
this.anims.create({
key: "player-run",
frames: [
{ key: 'run0' },
{ key: 'run1' },
{ key: 'run2' },
{ key: 'run3' },
{ key: 'run4' },
{ key: 'run5' },
{ key: 'run6' },
{ key: 'run7' },
{ key: 'run8' },
{ key: 'run9' },
{ key: 'run10' },
{ key: 'run11' },
{ key: 'run12' },
{ key: 'run13' }
],
frameRate: 20,
repeat: -1
})
this.anims.create({
key: "player-jump",
frames: [
{ key: 'jump0' },
{ key: 'jump1' },
{ key: 'jump2' },
{ key: 'jump3' },
{ key: 'jump4' }
],
frameRate: 20,
repeat: -1
})
this.monkey.body.setSize(this.monkey.width/2, this.monkey.height/2);
this.input.on('pointerdown', this.jump, this);
this.input.on('pointerup', this.fall, this);
}
update(){
this.backgroundL1.x -= 0.2;
this.backgroundL12.x -= 0.2;
this.backgroundL2.x -= 0.4;
this.backgroundL22.x -= 0.4;
this.backgroundL3.x -= 0.6;
this.backgroundL32.x -= 0.6;
this.backgroundL4.x -= 0.8;
this.backgroundL42.x -= 0.8;
for (let b of this.bgLs.children.entries) {
if (b.x <= -game.config.width) b.setX(game.config.width);
}
var speed = 5;
for (let g of this.groundGroup.children.entries) {
g.setX(g.x-speed);
//if (g.x <= -game.config.width) g.setX(game.config.width);
}
if (this.ground1.x <= -game.config.width) this.ground1.setX(game.config.width);
if (this.ground2.x <= -game.config.width) this.ground2.setX(game.config.width);
if (this.ground3.x <= -game.config.width) {
this.rnd1 = (Phaser.Math.Between(0, 500))/100;
this.ground3.setX(game.config.width + game.config.width / this.rnd1);
}
if (this.ground4.x <= -game.config.width) {
this.rnd2 = (Phaser.Math.Between(0, 500))/100;
this.ground4.setX(game.config.width + game.config.width / this.rnd2);
}
this.physics.world.collide(this.groundGroup, this.monkey, ()=> {console.log('touche' + game.loop.time )}, null, this);
this.monkey.body.gravity.y = gameOptions.monkeyGravity;
if(this.monkey.body.touching.down) this.monkey.anims.play("player-run", true);
else this.monkey.anims.play("player-jump", true);
}
jump(){
if(this.monkey.body.touching.down) {
this.monkey.body.setVelocity(0, -gameOptions.monkeyPower);
this.monkey.anims.stop();
this.monkey.anims.play("player-jump");
}
}
fall(){
if (this.monkey.body.velocity.y < 0) this.monkey.body.setVelocity(0, -100);
}
}
Game start scene has the Start Button, the game begins, the monkey runs on the platforms and you can jump on the upper platforms.
All seems to work fine, but sometimes randomly the monkey falls down off the screen.
You can see a playable version of the bug at https://420videogames.com/jeffrey2nd
Here I added a console log in the 'monkey vs ground goup collide' callback function, logging the game.loop.time to try to understand. My idea was that maybe some frames were missed during Update and the objects did not collide perfectly, but when the monkey falls off, the callback function runs 2 times and then the monkey keeps falling and the game breaks up.
Another strange thing about this issue is that on my mobile phone REDMI8 the game works with no problems, as for the iPhone8 of my GF. On Firefox mobile of another friend, by the way, the game has the same PC issue.
Thank you in advance for your attention, hope someone can help me fix this problem,
Ab
The issue was resolved moving the colliders from Update function to Create function.

Phaser - How to make images fit on all devices

So I have a source code that I'm learning from but I'm having trouble making images such as the background and sprites fitting on various devices.
Here is what I have so far:
var game = new Phaser.Game(800, 600, Phaser.AUTO, '');
game.state.add('play', {
preload: function() {
this.game.load.image('forest-back', 'assets/parallax_forest_pack/layers/parallax-forest-back-trees.png');
this.game.load.image('forest-lights', 'assets/parallax_forest_pack/layers/parallax-forest-lights.png');
this.game.load.image('forest-middle', 'assets/parallax_forest_pack/layers/parallax-forest-middle-trees.png');
this.game.load.image('forest-front', 'assets/parallax_forest_pack/layers/parallax-forest-front-trees.png');
this.game.load.image('aerocephal', 'assets/allacrost_enemy_sprites/aerocephal.png');
this.game.load.image('arcana_drake', 'assets/allacrost_enemy_sprites/arcana_drake.png');
this.game.load.image('aurum-drakueli', 'assets/allacrost_enemy_sprites/aurum-drakueli.png');
this.game.load.image('bat', 'assets/allacrost_enemy_sprites/bat.png');
this.game.load.image('daemarbora', 'assets/allacrost_enemy_sprites/daemarbora.png');
this.game.load.image('deceleon', 'assets/allacrost_enemy_sprites/deceleon.png');
this.game.load.image('demonic_essence', 'assets/allacrost_enemy_sprites/demonic_essence.png');
this.game.load.image('dune_crawler', 'assets/allacrost_enemy_sprites/dune_crawler.png');
this.game.load.image('green_slime', 'assets/allacrost_enemy_sprites/green_slime.png');
this.game.load.image('nagaruda', 'assets/allacrost_enemy_sprites/nagaruda.png');
this.game.load.image('rat', 'assets/allacrost_enemy_sprites/rat.png');
this.game.load.image('scorpion', 'assets/allacrost_enemy_sprites/scorpion.png');
this.game.load.image('skeleton', 'assets/allacrost_enemy_sprites/skeleton.png');
this.game.load.image('snake', 'assets/allacrost_enemy_sprites/snake.png');
this.game.load.image('spider', 'assets/allacrost_enemy_sprites/spider.png');
this.game.load.image('stygian_lizard', 'assets/allacrost_enemy_sprites/stygian_lizard.png');
this.game.load.image('gold_coin', 'assets/496_RPG_icons/I_GoldCoin.png');
this.game.load.image('dagger', 'assets/496_RPG_icons/W_Dagger002.png');
this.game.load.image('swordIcon1', 'assets/496_RPG_icons/S_Sword15.png');
// build panel for upgrades
var bmd = this.game.add.bitmapData(250, 500);
bmd.ctx.fillStyle = '#9a783d';
bmd.ctx.strokeStyle = '#35371c';
bmd.ctx.lineWidth = 12;
bmd.ctx.fillRect(0, 0, 250, 500);
bmd.ctx.strokeRect(0, 0, 250, 500);
this.game.cache.addBitmapData('upgradePanel', bmd);
var buttonImage = this.game.add.bitmapData(476, 48);
buttonImage.ctx.fillStyle = '#e6dec7';
buttonImage.ctx.strokeStyle = '#35371c';
buttonImage.ctx.lineWidth = 4;
buttonImage.ctx.fillRect(0, 0, 225, 48);
buttonImage.ctx.strokeRect(0, 0, 225, 48);
this.game.cache.addBitmapData('button', buttonImage);
// the main player
this.player = {
clickDmg: 1,
gold: 50,
dps: 0
};
// world progression
this.level = 1;
// how many monsters have we killed during this level
this.levelKills = 0;
// how many monsters are required to advance a level
this.levelKillsRequired = 10;
},
create: function() {
var state = this;
this.background = this.game.add.group();
// setup each of our background layers to take the full screen
['forest-back', 'forest-lights', 'forest-middle', 'forest-front']
.forEach(function(image) {
var bg = state.game.add.tileSprite(0, 0, state.game.world.width,
state.game.world.height, image, '', state.background);
bg.tileScale.setTo(4,4);
});
this.upgradePanel = this.game.add.image(10, 70, this.game.cache.getBitmapData('upgradePanel'));
var upgradeButtons = this.upgradePanel.addChild(this.game.add.group());
upgradeButtons.position.setTo(8, 8);
var upgradeButtonsData = [
{icon: 'dagger', name: 'Attack', level: 0, cost: 5, purchaseHandler: function(button, player) {
player.clickDmg += 1;
}},
{icon: 'swordIcon1', name: 'Auto-Attack', level: 0, cost: 25, purchaseHandler: function(button, player) {
player.dps += 5;
}}
];
var button;
upgradeButtonsData.forEach(function(buttonData, index) {
button = state.game.add.button(0, (50 * index), state.game.cache.getBitmapData('button'));
button.icon = button.addChild(state.game.add.image(6, 6, buttonData.icon));
button.text = button.addChild(state.game.add.text(42, 6, buttonData.name + ': ' + buttonData.level, {font: '16px Arial Black'}));
button.details = buttonData;
button.costText = button.addChild(state.game.add.text(42, 24, 'Cost: ' + buttonData.cost, {font: '16px Arial Black'}));
button.events.onInputDown.add(state.onUpgradeButtonClick, state);
upgradeButtons.addChild(button);
});
var monsterData = [
{name: 'Aerocephal', image: 'aerocephal', maxHealth: 10},
{name: 'Arcana Drake', image: 'arcana_drake', maxHealth: 20},
{name: 'Aurum Drakueli', image: 'aurum-drakueli', maxHealth: 30},
{name: 'Bat', image: 'bat', maxHealth: 5},
{name: 'Daemarbora', image: 'daemarbora', maxHealth: 10},
{name: 'Deceleon', image: 'deceleon', maxHealth: 10},
{name: 'Demonic Essence', image: 'demonic_essence', maxHealth: 15},
{name: 'Dune Crawler', image: 'dune_crawler', maxHealth: 8},
{name: 'Green Slime', image: 'green_slime', maxHealth: 3},
{name: 'Nagaruda', image: 'nagaruda', maxHealth: 13},
{name: 'Rat', image: 'rat', maxHealth: 2},
{name: 'Scorpion', image: 'scorpion', maxHealth: 2},
{name: 'Skeleton', image: 'skeleton', maxHealth: 6},
{name: 'Snake', image: 'snake', maxHealth: 4},
{name: 'Spider', image: 'spider', maxHealth: 4},
{name: 'Stygian Lizard', image: 'stygian_lizard', maxHealth: 20}
];
this.monsters = this.game.add.group();
var monster;
monsterData.forEach(function(data) {
// create a sprite for them off screen
monster = state.monsters.create(1000, state.game.world.centerY, data.image);
// use the built in health component
monster.health = monster.maxHealth = data.maxHealth;
// center anchor
monster.anchor.setTo(0.5, 1);
// reference to the database
monster.details = data;
//enable input so we can click it!
monster.inputEnabled = true;
monster.events.onInputDown.add(state.onClickMonster, state);
// hook into health and lifecycle events
monster.events.onKilled.add(state.onKilledMonster, state);
monster.events.onRevived.add(state.onRevivedMonster, state);
});
// display the monster front and center
this.currentMonster = this.monsters.getRandom();
this.currentMonster.position.set(this.game.world.centerX + 100, this.game.world.centerY + 50);
this.monsterInfoUI = this.game.add.group();
this.monsterInfoUI.position.setTo(this.currentMonster.x - 220, this.currentMonster.y + 120);
this.monsterNameText = this.monsterInfoUI.addChild(this.game.add.text(0, 0, this.currentMonster.details.name, {
font: '48px Arial Black',
fill: '#fff',
strokeThickness: 4
}));
this.monsterHealthText = this.monsterInfoUI.addChild(this.game.add.text(0, 80, this.currentMonster.health + ' HP', {
font: '32px Arial Black',
fill: '#ff0000',
strokeThickness: 4
}));
this.dmgTextPool = this.add.group();
var dmgText;
for (var d=0; d<50; d++) {
dmgText = this.add.text(0, 0, '1', {
font: '64px Arial Black',
fill: '#fff',
strokeThickness: 4
});
// start out not existing, so we don't draw it yet
dmgText.exists = false;
dmgText.tween = game.add.tween(dmgText)
.to({
alpha: 0,
y: 100,
x: this.game.rnd.integerInRange(100, 700)
}, 1000, Phaser.Easing.Cubic.Out);
dmgText.tween.onComplete.add(function(text, tween) {
text.kill();
});
this.dmgTextPool.add(dmgText);
}
// create a pool of gold coins
this.coins = this.add.group();
this.coins.createMultiple(50, 'gold_coin', '', false);
this.coins.setAll('inputEnabled', true);
this.coins.setAll('goldValue', 1);
this.coins.callAll('events.onInputDown.add', 'events.onInputDown', this.onClickCoin, this);
this.playerGoldText = this.add.text(30, 30, 'Gold: ' + this.player.gold, {
font: '24px Arial Black',
fill: '#fff',
strokeThickness: 4
});
// 100ms 10x a second
this.dpsTimer = this.game.time.events.loop(100, this.onDPS, this);
// setup the world progression display
this.levelUI = this.game.add.group();
this.levelUI.position.setTo(this.game.world.centerX, 30);
this.levelText = this.levelUI.addChild(this.game.add.text(0, 0, 'Level: ' + this.level, {
font: '24px Arial Black',
fill: '#fff',
strokeThickness: 4
}));
this.levelKillsText = this.levelUI.addChild(this.game.add.text(0, 30, 'Kills: ' + this.levelKills + '/' + this.levelKillsRequired, {
font: '24px Arial Black',
fill: '#fff',
strokeThickness: 4
}));
},
onDPS: function() {
if (this.player.dps > 0) {
if (this.currentMonster && this.currentMonster.alive) {
var dmg = this.player.dps / 10;
this.currentMonster.damage(dmg);
// update the health text
this.monsterHealthText.text = this.currentMonster.alive ? Math.round(this.currentMonster.health) + ' HP' : 'DEAD';
}
}
},
onUpgradeButtonClick: function(button, pointer) {
// make this a function so that it updates after we buy
function getAdjustedCost() {
return Math.ceil(button.details.cost + (button.details.level * 1.46));
}
if (this.player.gold - getAdjustedCost() >= 0) {
this.player.gold -= getAdjustedCost();
this.playerGoldText.text = 'Gold: ' + this.player.gold;
button.details.level++;
button.text.text = button.details.name + ': ' + button.details.level;
button.costText.text = 'Cost: ' + getAdjustedCost();
button.details.purchaseHandler.call(this, button, this.player);
}
},
onClickCoin: function(coin) {
if (!coin.alive) {
return;
}
// give the player gold
this.player.gold += coin.goldValue;
// update UI
this.playerGoldText.text = 'Gold: ' + this.player.gold;
// remove the coin
coin.kill();
},
onKilledMonster: function(monster) {
// move the monster off screen again
monster.position.set(1000, this.game.world.centerY);
var coin;
// spawn a coin on the ground
coin = this.coins.getFirstExists(false);
coin.reset(this.game.world.centerX + this.game.rnd.integerInRange(-100, 100), this.game.world.centerY);
coin.goldValue = Math.round(this.level * 1.33);
this.game.time.events.add(Phaser.Timer.SECOND * 3, this.onClickCoin, this, coin);
this.levelKills++;
if (this.levelKills >= this.levelKillsRequired) {
this.level++;
this.levelKills = 0;
}
this.levelText.text = 'Level: ' + this.level;
this.levelKillsText.text = 'Kills: ' + this.levelKills + '/' + this.levelKillsRequired;
// pick a new monster
this.currentMonster = this.monsters.getRandom();
// upgrade the monster based on level
this.currentMonster.maxHealth = Math.ceil(this.currentMonster.details.maxHealth + ((this.level - 1) * 10.6));
// make sure they are fully healed
this.currentMonster.revive(this.currentMonster.maxHealth);
},
onRevivedMonster: function(monster) {
monster.position.set(this.game.world.centerX + 100, this.game.world.centerY + 50);
// update the text display
this.monsterNameText.text = monster.details.name;
this.monsterHealthText.text = monster.health + 'HP';
},
onClickMonster: function(monster, pointer) {
// apply click damage to monster
this.currentMonster.damage(this.player.clickDmg);
// grab a damage text from the pool to display what happened
var dmgText = this.dmgTextPool.getFirstExists(false);
if (dmgText) {
dmgText.text = this.player.clickDmg;
dmgText.reset(pointer.positionDown.x, pointer.positionDown.y);
dmgText.alpha = 1;
dmgText.tween.start();
}
// update the health text
this.monsterHealthText.text = this.currentMonster.alive ? this.currentMonster.health + ' HP' : 'DEAD';
}
});
game.state.start('play');
In your init or preload function, you should choose your scale mode. Please check the documentation to understand the different options:
//Options here are: NO_SCALE, EXACT_FIT, SHOW_ALL, RESIZE and USER_SCALE
this.scale.scaleMode = Phaser.ScaleManager.EXACT_FIT;
Please also check if you want to set pageAlignHorizontally and pageAlignVertically to true:
this.scale.pageAlignHorizontally = true;
this.scale.pageAlignVertically = true;
In some cases, you will want to call the refresh method:
this.scale.refresh();

Categories