I was hoping that I could get some help with the problem that I'm having right now.
Basically I have some bullets, and then I have a group of enemies that move with velocity. The enemies have different sprites and basically I want to assign a value per sprite type. It works, for example, if I say if a diamond is generated and collides with a bullet you get 10 points, but the strange behavior is when it collides, since all enemies on screen give the 10 points and they all get destroyed, not just the one.
Also if the 10 point sprite is not on screen, no points are given which is normal.
Please find my code below and I would appreciate any help given. Thanks.
//here is my bullets group
createBullets: function(){
//Bullets
this.bullets = this.add.group();
this.bullets.enableBody = true;
this.bullets.physicsBodyType = Phaser.Physics.P2JS;
this.bullets.createMultiple(500, 'bullet', 0, false);
this.bullets.setAll('anchor.x', 0.5);
this.bullets.setAll('anchor.y', 0.5);
this.bullets.setAll('outOfBoundsKill', true);
this.bullets.setAll('checkWorldBounds', true);
},
///here are my enemies
addOneFigura: function(x, y) {
this.figuras = this.add.group();
//these are sprites
this.figuritas = ["figura1","figura2","figura3","figura4","figura5","figura6"];
this.figurita = this.figuritas[Math.floor(Math.random()*6)];
this.figura = this.add.sprite(x,y,this.figurita);
this.figuras.add(this.figura);
this.physics.p2.enable(this.figura, false);
this.figura.body.velocity.y = 75;
this.figura.checkWorldBounds = true;
this.figura.outOfBoundsKill = true;
this.figura.body.setCollisionGroup(this.figurasCG);
this.figura.body.collides(this.bulletsCG, this.collisionBulletMatch, this);
},
//and lastly this is my collision function
collisionBulletMatch: function(figurita, figuritapega) {
if (this.figurita != this.figuritapega){
this.score += 10;
this.scoreText.text = this.score;
this.resetFigura();
}
}
So basically when they collide the whole figuras group disappears instead of just the one colliding.
I'll readily admit I haven't done much with P2 physics in Phaser, but the immediate thing that comes to mind is that while you're calling resetFigura you're not passing in a figure (figura). Without seeing the initialization of the variable I can't be sure, but I think you want to change your function to something like the following:
resetFigura: function(figura) {
figura.sprite.kill();
},
This should be called via this.resetFigura(figuritapega); in collisionBulletMatch.
If it's not in the resetFigura call, I would also recommend taking a look at the official P2 Physics collision group example; I was able to get that up and running fairly quickly. It does have a single player character, but if you simplify your bullets to one you might be able to figure out your issue.
Related
I try to draw 2D texts for my 3D world objects with libgdx's camera.project function but have a weird problem.
See the pics below:
As you can see in the pictures, all is well in picture 1 but when I turn around 180 degrees the ball's name (codename 1) is be drawing the blank space also (picture 2). I couldn't get what the problem is and after hours of thinking decided to ask here.
Please help me.
My code is:
public static void drawNames(){
TheGame.spriteBatch.begin();
for(int i = 0; i < TheGame.playerMap.size; i++){
Player ply = TheGame.playerMap.getValueAt(i);
if(!ply.isAlive)
continue;
TheGame.tmpVec.set(ply.getPos().x, ply.getPos().y, ply.getPos().z);
TheGame.cam.project(TheGame.tmpVec);
TheGame.fontArialM.draw(TheGame.spriteBatch, ply.name, TheGame.tmpVec.x, TheGame.tmpVec.y, 0, Align.center, false);
}
TheGame.spriteBatch.end();
}
This is because if you project something that is behind the camera it still gets valid screen coordinates from the project method.
Consider the following that prints the screen coordinates of two world coordinates
PerspectiveCamera camera = new PerspectiveCamera(60, 800, 600);
camera.position.set(0, 0, -10);
camera.lookAt(0, 0, 0);
camera.update();
Vector3 temp = new Vector3();
Vector3 p1 = new Vector3(1, 0, 10); // This is in front of the camera, slightly to the right
Vector3 p2 = new Vector3(0, 0, -100); // This is behind of the camera
camera.project(temp.set(p1));
System.out.println("p1 is at screen " + temp);
if (camera.frustum.pointInFrustum(p1))
System.out.println("p1 is visible to the camera");
else
System.out.println("p1 is not visible to the camera");
camera.project(temp.set(p2));
System.out.println("p2 is at screen " + temp);
if (camera.frustum.pointInFrustum(p2))
System.out.println("p2 is visible to the camera");
else
System.out.println("p2 is not visible to the camera");
In your code, before rendering the text you need to check if the ply.getPos() vector is visible to the camera, and only render the text if it is.
if (TheGame.cam.frustum.pointInFrustum(ply.getPos()) {
TheGame.tmpVec.set(ply.getPos().x, ply.getPos().y, ply.getPos().z);
TheGame.cam.project(TheGame.tmpVec);
TheGame.fontArialM.draw(TheGame.spriteBatch, ply.name, TheGame.tmpVec.x, TheGame.tmpVec.y, 0, Align.center, false);
}
Note that there are other ways to cull things behind the camera that might be more efficient for you.
I am coding a game with #PhaserJS and I want to delete only one sprite in a group of sprites everytime the player is touched by the AI sprites which decrements the number of lifes by one, so in the create function i have
lifes = game.add.group();
for(i = 0; i < 3; i++){
j = i + 1;
life = game.add.sprite(20 * j, 20, 'life');
lifes.add(life);
}
lifes.fixedToCamera = true;
Then in the update function I just try to remove one sprite when it collides
function hitNinja (ninja, ronins) {
lifes.kill();
}
The problem is that it supress all the group of sprites that is displayed at the top of the screen like in the image bellow
Life x 3
In your example lifes is the whole group, so calling kill() on it will destroy it along with everything it's in it. If you want to act upon individual elements of the group, you should iterate over them in some way.
function hitNinja (ninja, ronins) {
var children = lifes.getAll();
children[children.length - 1].kill();
}
Keep in mind that kill() is a method you'd use if you want to 'revive' the sprite later on; otherwise, destroy() might be the saner choice.
Reference for Phaser.Group.
Hello I am trying to limit how much a user can drag within Gamemaker.
I have created two views within a room.
The first view is the full room width and size 1250x768
The second view is the area which i would like the user to be able to zoom into and drag which is 955x465. x and y position is 40 by 170.
Currently i have set up the zoom for the second view which is:
vmx=(mouse_x-X)-omx;
omx=(mouse_x-X);
vmy=(mouse_y-Y)-omy;
omy=(mouse_y-Y);
if mouse_wheel_up() && view_wview[1] > 600 {
center_of_space_x=view_xview[1]+view_wview[1]/2;
center_of_space_y=view_yview[1]+view_hview[1]/2;
view_wview[1]-=view_wview[1]*0.15;
view_hview[1]-=view_hview[1]*0.15;
view_xview[1]=center_of_space_x-view_wview[1]/2;
view_yview[1]=center_of_space_y-view_hview[1]/2;
}
if mouse_wheel_down(){
view_xview[1] = 40;
view_yview[1] = 170;
view_wview[1] = 955;
view_hview[1] = 465;}
Below is the code for the drag:
if (mouse_check_button_pressed(mb_left)) {
drag_x = mouse_x
drag_y = mouse_y
}
// update:
if (mouse_check_button(mb_left)) && view_wview[1] < 700 {
// actual dragging logic:
view_xview[1] = drag_x - (mouse_x - view_xview[1])
view_yview[1] = drag_y - (mouse_y - view_yview[1])
// make sure view doesn't go outside the room:
view_xview[1] = max(0, min(view_xview[1], room_width - view_wport[1]))
view_yview[1] = max(0, min(view_yview[1], room_height - view_hview[1]))
So the limit works for the view to not leave the room but i want it not to leave the specific view which has been set up.
Please help
I have modified my code to use a clamp function which works but it is not a clean solution:
view_xview[1] = clamp(view_xview[1],40,400);
view_yview[1] = clamp(view_yview[1],170,500);
The user has to be fully zoomed in to have the view restricted. If he is not then they can still see other areas of the room :(
EDIT: I may have misunderstood your question, I will leave the below code for reference if it helps you solve the problem a bit differently.
I would probably check that mouse_x and mouse_y are not outside the view you want.
if (mouse_x > view_limit_x || mouse_y > view_limit_y)
{
return; // Or continue or break however your language of choice goes.
}
If you cannot do a return statement, wrapping your code in a reverse logic of above should work fine.
Old Post:
I am not 100% familiar with game maker. I would implement something like this by skipping the drag logic every x frames. Say you are updating at 60fps, and you want the drag to be 6 times slower, you just need to only update the logic 10 x per frame.
const int framesToSkip = 6;
int frameCount = 0;
update()
{
// Will only call when framecount = 0, 6, 12, 18 etc.
if (frameCount % framesToSkip == 0)
{
// Drag Logic.
}
frameCount++;
}
This way drag logic only occurs 1/6 the rate as before. You could also change this around to happen the first x amount of frames and then skip for the rest (but this may appear a bit choppy).
For a project I'm trying to draw a moving line in Phaser. I initially drew it using game.debug.geom(line), but that is not really the right way to do it, since it doesn't allow for styling, and because the debugger takes a toll in performance.
Reading the docs, it seems to me that the way to do it would be with a Phaser.Graphics object, but I haven't been able to get it to work. As an example, I tried making a line move as the hand of a clock, with one end fixed and the other moving around it.
I thought it would be fine to create the Graphics object in the middle and then in update use reset to clear it and bring it back to the center, and then lineTo to make the rest of the line. But instead what I get is a line coming outwards from the centre, and then a ring.
Picture for sadness:
I made a pen with my attempts. The code is repeated below. What I would like to have is a line (lines?) coming from the center of the circle to the points in the circumference.
Is a Graphics object the best way to do that? How do I do it?
Demo.prototype = {
create: function() {
this.graphics = game.add.graphics(
game.world.centerX,
game.world.centerY
);
this.graphics.lineStyle(2, 0xffd900);
this.counter = 0;
this.step = Math.PI * 2 / 360;
this.radius = 80;
},
update: function() {
this.graphics.reset(
this.game.world.centerX,
this.game.world.centerY
);
var y = this.radius * Math.sin(this.counter);
var x = this.radius * Math.cos(this.counter);
this.graphics.lineTo(x, y);
this.counter += this.step;
}
};
You may want to check out this Phaser game called Cut It (not my game btw, found it here).
It also draws a variable length dotted line by cleverly using the Phaser.TileSprite, and then changing its width.
TileSprite draws a repeating pattern, and you can use this to draw a line by drawing one bitmap of a linepart segment, use that as background of the TileSprite and make the height of the TileSprite the same as the height of the bitmap.
You can take a look at the game's source code, it's compressed and minified but still somewhat readable. You can look for the variable called cut_line.
I finally understood that the coordinates taken by the Phaser.Graphics object are local, respective to the object's internal coordinate system. Using moveTo(0, 0) has the desired result of moving the object's drawing pointer back to its origin (and not, as I initially thought, to the origin of the game world). Using reset(0, 0), on the other hand, would have the effect of moving the object's origin to the world's origin.
As for deleting the previous lines, the only method I've found is to manually clear the object's graphicsData Array (short of calling destroy() and creating an entirely new object, which is probably not a very good idea).
Replacing the code in the original question with this does the trick:
Demo.prototype = {
create: function() {
this.graphics = game.add.graphics(
game.world.centerX,
game.world.centerY
);
this.graphics.lineStyle(2, 0xffd900);
this.counter = 0;
this.step = Math.PI * 2 / 360;
this.radius = 80;
},
update: function(){
// Erases the previous lines
this.graphics.graphicsData = [];
// Move back to the object's origin
// Coordinates are local!
this.graphics.moveTo( 0, 0 );
var y = this.radius * Math.sin(this.counter);
var x = this.radius * Math.cos(this.counter);
this.graphics.lineTo(x, y);
this.counter += this.step;
}
};
As you see in the picture above, billy, our little orange dressed man, is going off the screen to the left and appearing on the right side.
This is what I want to happen, however, I can't seem to replicate this effect (I got the picture with some modifications in Paint.net).
Basically, if the players x position is negative, it should wrap to the other side. If the x is larger than the width, it should wrap over to the left side.
Draw it two times when you need it.
void Draw(SpriteBacth batch)
{
batch.Draw(Player.texture, Player.Position, player.Source, player.Color);
if (Player.X <0)
{
bacth.Draw(Player.texture, Player.Position + ScreenHorizontalSize, player.Source, Player.Color);
}
else if (Player.X + Player.Size.Width> ScreenHorizontalSize.Width)
{
bacth.Draw(Player.texture, Player.Position - ScreenHorizontalSize, player.Source, Player.Color);
}
}
void Update()
{
if (Player.X < -Player.Size.Width) Player.X += ScreenHorizontalSize.Width;
if (Player.X > ScreenHorizontalSize.Width) Player.X -= ScreenHorizontalSize.Width;
}
Of course you have to take in mind this when you check for colliding with player, you will have to check in the two positions too.