How can I avoid overlapping when creating sprites? JS - PHASER3 - javascript

I'm new in this and I'm making a small game in JS, the problem that I have now is when I create enemies it sometimes overlaps, creating this:
The way that use to create them is simple,
resetShip(enemy_spaceship) {
enemy_spaceship.y = 0;
enemy_spaceship.x = Phaser.Math.Between(10,globalThis.config.width);
}
In X each sprite will have a random number from 10 to the width of the screen (canvas), the problem is that if a sprite has 440 in X and another one has 450 in X, those 10px aren't enough to separate them, some people told me to create a grid, but like I said I'm new and searching about grid can't find any example that I can use to this, thanks if you can help me :)

One option is for each enemy ship to be allocated a specific region in which it may start. If you have 2 ships, that means the first ship can be anywhere in the first half of the X axis, and the second ship can be anywhere in the second half of the X axis.
To do this, you should update your resetShip function to also take in a minX and maxX, and use that when defining it's location:
resetShip (enemy_spaceship, minX, maxX) {
enemy_spaceship.y = 0;
enemy_spaceship.x = Phaser.Math.Between(minX, maxX);
}
Then, you need to find a way to rest the group of ships, providing valid regions for each ship. Something like this:
resetEnemies(ships) {
//Each ship may be in a region that is 1/Nth of the width
let regionWidth = globalThis.config.width / ships.length
//We need to know the shipWidth so we don't let ships get too
//close to the left edge.
let shipWidth = 64
ships.forEach((ship, i) => {
//Assuming you just want padding on the left so it is no closer than 10px,
//this will define the minX for the Nth ship
const minX = Math.min(10, i*regionWidth)
//The maxX should not let a ship overlap the next region. So, we subtract the shipWidth
//to ensure that, at worst, it is right next to the next ship
const maxX = (i+1)*regionWidth-shipWidth
//Use the updated restShip to put it in a valid location for it's region
resetShip(ship, minX, maxX)
})
}

Related

fabric.js - Rotate "Child" Object based on Parent w/o Grouping

Using fabric.js (1.7.11) , I am trying to have one object follow the rotation of another without grouping them, and while maintaining the relative position of the child object to the parent. So I believe I need to (1) set the rotation center of the "child" object to that of the "parent", then (2) as the parent object is rotating, apply that rotation delta to the child ( which may already start in a rotated state ). The end result is such that the child appears "stuck" to the parent ( like a sticky-note on a game-board, and you then rotate the game-board )
Here is the pseudo-code
canvas.on('object:rotating', canvasEvent_ObjectRotating);
function canvasEvent_ObjectRotating(e)
{
// set r2'2 center of rotation = r1's center of rotation
// r2.angle += ( delta of rotation of r1 angle )
}
Here is a fiddle:
https://jsfiddle.net/emaybert/bkb5awj6/
Any help with 1 or 2 would be appreciated. Either how to get the angle delta in the object:rotating callback, and/or how to pivot a object around an arbitrary point. I've seen the reference to fabric.util.rotatePoint and an example of how to rotate a Line using it, but not an object, and couldn't make that mental transformation.
Is this something that you're trying to do?
https://jsfiddle.net/logie17/ofr8e6qd/1/
function canvasEvent_ObjectRotating(e)
{
origX = r2.getCenterPoint().x;
origY = r2.getCenterPoint().y;
let topLeftPoint = new fabric.Point(origX, origY);
if (!previousAngle) {
previousAngle = r1.getAngle();
}
let angle = fabric.util.degreesToRadians(r1.getAngle() - previousAngle);
previousAngle = r1.getAngle();
let center = r1.getCenterPoint();
let origin = new fabric.Point(r1.left, r1.top);
let newCoords = fabric.util.rotatePoint(topLeftPoint,origin,angle);
r2.set({ left: newCoords.x, top: newCoords.y }).setCoords();
}

Tooltips for data in javascript using p5.js

I am trying to make tooltips for a data visualization I made using p5.js but I am completely lost. Nothing I tried works. This is my code as is.
var table;
var i;
var j;
var cellValue;
var label;
var test;
function preload() {
matrix = loadTable("dataLayer2matrix.csv","csv")
labels = loadTable("dataLayer2labels.csv","csv")
test = matrix
}
function setup() {
createCanvas(1500,1500)
noStroke()
fill(0,0,255,10)
angleMode(DEGREES)
background(255,255,255)
matrixStartX = 200
matrixStartY = 250
var matrixRows = matrix.getRows()
var matrixSize = matrixRows.length
// Experiment with grid
fill(75, 75, 75, 50)
for (r = 0; r <= matrixSize; r++) {
rect(matrixStartX , matrixStartY + r * 20 - 1 , 20 * matrixSize, 1)
rect(matrixStartX + r * 20 - 1 , matrixStartY, 1, 20 * matrixSize)
}
// Draw matrix
for (var mr = 0; mr < matrixSize; mr++) {
for (var mc = 0; mc < matrixSize; mc++) {
cellValue = matrixRows[mr].getNum(mc)
fill(49,130,189,cellValue*10)
rect(mc * 20 + matrixStartX, mr * 20 + matrixStartY, 19 ,19)
}
}
// Labels - horizontal
fill(75, 75, 75, 255)
labelsRow = labels.getRows()
for (mc = 0; mc < matrixSize; mc++) {
label = labelsRow[0].getString(mc)
text(label, 10, mc*20+matrixStartY + 15)
}
// Labels - vertical
push()
translate(matrixStartX + 15, matrixStartY - 15)
rotate(-90)
for (mc = 0; mc < matrixSize; mc++) {
label = labelsRow[0].getString(mc)
text(label, 0, mc*20)
}
pop()
//Tooltip when clicked
}
/* if(mouseIsPressed){
fill(50);
text(cellValue, 10,10,70,80);
}*/
}
}
It makes this image:
I want it so that when I go over a square I get the data in it. I really can't seem to do it. Thanks.
I think the advice telling you to use bootstrap is missing the fact that you're using p5.js. Bootstrap is more for dealing with html components, not internal Processing sketches.
Instead, you probably want to do this with p5.js code. The best thing you can do is break your problem down into smaller steps:
Step 1: Can you draw a single rectangle?
Instead of trying to add this new functionality to your existing sketch, it might be easier if you start with a simpler example sketch with just a single rectangle.
Step 2: Can you detect when the mouse is inside that rectangle?
If you know where you're drawing the rectangle, you know its coordinates. You also know the coordinates of the mouse from the mouseX and mouseY variables. So to detect whether the mouse is inside the rectangle, you simply have to use if statements that compare the coordinates of the mouse to the coordinates of the rectangle. There are a ton of resources on google for this, and it might help if you draw some examples out on a piece of paper.
Also, don't worry about the tooltip just yet. Just do something simple like change the color of the rectangle when the mouse is inside it.
Step 3: Can you display the information box?
Again, do this in its own sketch first. Maybe create a function that takes a position and the information you want to display as parameters and displays it in a rectangle. Don't worry about making it a tooltip yet. Just get it displaying. Use hard-coded values for the information.
Step 4: Can you combine your small example sketches?
You have code that triggers when the mouse is inside a rectangle. You have code that draws the tooltip. Can you make it so the tooltip is drawn when the mouse is inside the rectangle?
Step 5: Only when all of the above works, then you should start thinking about adding it to your full sketch.
Instead of using an example rectangle, you'll have to use the rectangles you're drawing on the screen. Instead of calling the tooltip function with hard-coded values, use the values you get from the squares.
Take on those pieces one at a time, and make small steps toward your goal. Then if you get stuck, you can post an MCVE of the specific step you're on. Good luck!

Matter.js calculating force needed

Im trying to apply a force to an object. To get it to move in the angle that my mouseposition is generating relative to the object.
I have the angle
targetAngle = Matter.Vector.angle(myBody.pos, mouse.position);
Now I need to apply a force, to get the body to move along that angle.
What do I put in the values below for the applyForce method?
// applyForce(body, position, force)
Body.applyForce(myBody, {
x : ??, y : ??
},{
x:??, y: ?? // how do I derive this force??
});
What do I put in the x and y values here to get the body to move along the angle between the mouse and the body.
To apply a force to move your object in that direction you need to take the sine and cosine of the angle in radians. You'll want to just pass the object's position as the first vector to not apply torque (rotation).
var targetAngle = Matter.Vector.angle(myBody.pos, mouse.position);
var force = 10;
Body.applyForce(myBody, myBody.position, {
x: cos(targetAngle) * force,
y: sin(targetAngle) * force
});
Also if you need it, the docs on applyForce() are here.
(I understand this question is old, I'm more or less doing this for anyone who stumbles across it)
You can rely on the Matter.Vector module and use it to substract, normalize and multiply positions vectors:
var force = 10;
var deltaVector = Matter.Vector.sub(mouse.position, myBody.position);
var normalizedDelta = Matter.Vector.normalise(deltaVector);
var forceVector = Matter.Vector.mult(normalizedDelta, force);
Body.applyForce(myBody, myBody.position, forceVector);

How do I fix this image (pixel by pixel) distortion issue?

I am attempting to distort an image displayed within a canvas, so it looks like a "planet". However I am struggling to find away to deal with a distortion issue. The only solution coming to mind is to find a way to reduce the radiusDistance variable, the bigger it is. That said, I am unsure how to achieve this. Any suggestions?
Below is the math and objects I am currently using to achieve this:
polarArray = [];
var polar = function(a,r,c){ //polar object, similar to pixel object.
this.a = a; //angle
this.r = r; //radius (distance)
this.color = c; //color, stored using an object containg r,g,b,a variables
};
loopAllPixels(function(loop){//loop through every pixel, stored in a pixel array
var pixel = loop.pixel;
/*each pixel object is structured like this:
pixel {
x,
y,
color {
r,
g,
b,
a
}
}
*/
var angle = pixel.x/360*Math.PI;
var radiusDistance = pixel.y/Math.PI;
polarArray.push(new polar(angle,radiusDistance,pixel.color));//store polar coordinate pixel + colour.
pixel.color = new colorRGBA(255,255,255,255);//set background as white.
});
for (var i=0;i<polarArray.length;i++){//loop through polarArray (polar coordinate pixels + colour)
var p = polarArray[i]; //polar pixel
var x = (p.r*Math.cos(p.a))+(canvas.width/2); //x coordinate
var y = (p.r*Math.sin(p.a))+(canvas.height/2); //y coordinate
if (setpixel(x,y,p.color)==true){ //set pixel at location.
continue;
}
break;
}
updatePixelsToContext();//draw to canvas
And here is the effect it currently produces (note that I flip the image horizontally before applying it to the canvas, and in this example, I set the background with a magenta kind of colour, for better clarity of the issue):
Note:
I am intending for the warping effect, just not the "ripping" of the pixels, caused by not obtaining all the neccessary pixel data required.
Also bear in mind that speed and effeciency isn't my priority here as of yet.

collision detection in javascript game?

My Map array ;;
map[0] = [0,0,0,0,0,0]
map[1] = [0,1,0,1,0,1]
map[2] = [0,0,0,0,0,0]
map[3] = [1,0,1,0,1,0]
map[4] = [0,0,0,0,0,0]
map[5] = [0,1,0,1,0,1]
1= Hurdle
0 = Nothing
i've to detect collision detection b/w player and hurdles in map.
player.x & player.y is the reference from left top .
Each hurdle is 40px of width and length .
i need a roughly concept not codes
You have to normalize player position to the collision map unit as player position is in px units and your collision map is in array index units and then test if the field the player tries to enter is not a hurdle.
function normalizePosition(entity){
return {
x: Math.ceil(entity.pos.x / TILE_WIDTH),
y: Math.ceil(entity.pos.y / TILE_HEIGHT)
}
}
Normalize position will give you entity coordinates on the collision map and next you have to test the actual collision to see what kind of tile is the entity entering
function mapCollision(entity, map){
var mapCoords = normalizePosition(entity),
tileType = map[mapCoords.y][mapCoords.x];
return tileType;
}
It will return the code of tile type on the map for player normalized position in case you wanted to have there different things then just blocks like some kind of slowing down traps or whatever other bear pits. You could then handle different cases where zero would default to accepts player entering the tile.
Hope I didn't tell to much :)
Good luck with your game and if you'll remember I'd be happy if you'd share the effects with me when its done :)
Tom
Update
I made a simple example for better interpretation purpose:
http://fiddle.jshell.net/qFCyn/1/
Use this:
var BLOCK_SIZE = 40; // 40px * 40px blocks
var hurdle = map[player.y/BLOCK_SIZE][player.x/BLOCK_SIZE]
if(hurdle) {
// stuff
} else {
// other stuff
}

Categories