How can i simulate a multilevel map in a phaser 3 scene? - events

I'm creating a 2d game with a top-down based camera and i was trying to make a map with more than 1 level. I'm getting a lot of problems when the player has to pass from one level to another.
At the moment the transition from one level to the other would take place through two rectangles positioned at the beginning and at the end of the stairs (which are the only points where the player can change levels).
when the player overlaps these two rectangles the setDepth is modified and I would like that when the player rises to the second level then the first level becomes the subject of collision while when it goes down to the first level it deactivates a collision with the first level and activates with the second. This is what I came up with the idea of doing to create a sort of layer manager
that's the code i did for this:
this.map=this.make.tilemap({
key: "map",
tileWidth: 2048,
tileHeight: 1792,
});
this.layer_2=this.map.createLayer("level_2",this.tileset,0,0);
this.layer_3=this.map.createLayer("level_3",this.tileset,0,0);
creating map and layers
this.zone = this.add.zone(256, 455,64,32);
this.physics.world.enable(this.zone);
this.zone2 = this.add.zone(256, 391,64,32);
this.physics.world.enable(this.zone2);
this.layer_2.setCollisionBetween(1,999);
this.layer_3.setCollisionBetween(1,999);
creating the 2 zone and adding collisions
this.physics.add.overlap(this.player,this.zone,()=>{
this.physics.world.removeCollider(this.collider1);
this.player.setDepth(4);
this.physics.world.colliders.add(this.collider2);
console.log("zone1");
});
this.physics.add.overlap(this.player,this.zone2,()=>{
this.physics.world.removeCollider(this.collider2);
this.player.setDepth(6);
this.physics.world.colliders.add(this.collider1);
console.log("zone2");
});
adding the overlap events that switch the collision level
All this works really bad because when the player overlap the rectangle i need to wait like 200 iterations or more of the overlap function for the collision with the next layer to be eliminated and the collision with the previous layer added
I would also appreciate any advice on how to improve the logic of all this.
I hope i was clear, and thanks to every one will watch this and maybe answare me. Thank you so much

Related

Hello, I need advice on making collision for a game I made in processing

I am making a version of the Atari game "Centipede" for my computer science class. I need help creating the collision for my code. I need to make it so when the bullets hit a part of the centipede, the game detects it and the part that got hit goes away.
This is a pretty broad question, but I'll try to help in a general sense.
You need to read up on collision detection.
First you probably want to break your centipede down into individual rectangles. For each rectangle, check whether it's colliding with the bullet.
You might consider point-rectangle collision detection, where you check whether the point is inside the rectangle. This will work if your bullet is a small point.
Or you might consider rectangle-rectangle collision detection, where you check whether two rectangles are overlapping. Use this if your bullets are larger than a point. Even if your bullet is a circle, you can usually get away with this kind of collision detection.
Please try something, and if you get stuck, then please post a MCVE that demonstrates where you're stuck. Good luck.
A simple implementation would be as follows:
1. Designate an array that represents the pixel positions of the centipede
2. Designate another array that represents the pixel positions of the bullet
3. Update each array's values based on the sampling rate of your game and check to see if there is any overlap. (Ideally have this as a separate thread)
4.Any overlap is indicative of a collision, so have some sort of collision handler function, which deletes the part of the centipede hit, that is triggered anytime an overlap event occurs.

A better way to roll dice

I have a game that requires the player to roll two die. As this is a multiplayer game, the way I currently do this is have 6 animations (1 for each die's outcome). When the player clicks a button, it sends a request to my server code. My server code determines the die's outcome and sends the results to the client. The client then plays the corresponding animations.
This works ok, but has some issues. For instance, if the server sends back two of the same values (two 6's, for example) then the animations don't work correctly. As both animations are the same, they overlay each other, and it looks like only one die was rolled.
Is there a better way to do this? Instead of animations, using "real" dice? If that's the case, I always need to be sure to "pre-determine" the outcome of the dice roll, on the server. I also need to make sure the dice don't fall off the table or jostle any of the other player pieces on the board.
thanks for any ideas.
The server only needs to care about the value result, not running physics calculations.
Set up 12 different rolling animations:
Six for the first die
Six for the second die
Each one should always end with the same modeled face pointing upwards (the starting position isn't relevant, only the ending position). For the latter steps you'll probably want to adjust the model's UV coordinates to use a very tall or very wide texture (or just a slice of a square one). So not like this but rather all in a line 1-2-3-4-5-6.
The next step is picking a random animation to play. You've already got code to run a given animation, just set it to pick randomly instead of based on the die-roll-value from the server:
int animNum = Mathf.Floor(Random.Next()*6);
Finally, the fun bit. Adjusting the texture so that the desired face shows when the animation is done. I'm going to assume that you arrange your faces along the top edge of your square texture. Material.SetTextureOffset().
int showFace = Mathf.Floor(Random.Next()*6); //this value should come from the server
die.renderer.material.SetTextureOffset(1f/6 * showFace,0);
This will set the texture offset such that the desired face will show on top. You'll even be able to see it changing in the inspector. Because of the UVs being arranged such that each face uses the next chunk over and because textures will wrap around when reaching the edge (unless the texture is set to Clamp in its import settings: you don't want this here).
Note that this will cause a new material instance to be instantiated (which is not very performant). If you want to avoid this, you'll have to use a material property block instead.
You could simulate the physics on the server, keep track of the positions and the orientations of the dice for the duration of the animation, and then send the data over to the client. I understand it's a lot of data for something so simple, but that's one way you can get the rolls to appear realistic and synced between all clients.
If only Unity's physics was deterministic that would be a whole lot easier.

Plat former Game - A realistic path-finding algorithm

I am making a game and i have come across a hard part to implement into code. My game is a tile-bases platformer with lots of enemies chasing you. basically, in theory, I want my enemies to be able to, every frame/second/2 seconds, find the realistic, and shortest path to my player. I originally thought of A-star as a solution, but it leads the enemies to paths that defy gravity, which is not good. Also, multiple enemies will be using it every second to get the latest path, and then walk the first few tiles of it. So they will be discarding the rest of the path every second, and just following the first few tiles of it. I know this seems like a lot, to calculate a new path every second, all at the same time, if their is more than one enemy, but I don't know any other way to achieve what i want.
This is a picture of what I want:
Explanation: The green figure is the player, the red one is an enemy. the grey tiles are regular, open, nothing there tiles, the brown tiles being ones that you can stand on. And finally the highlighted yellow tiles represents the path that i want my enemy to be able to find, in order to realistically get to the player.
SO, the question is: What realistic path-finding algorithm can i use to acquire this? While keeping it fast?
EDIT*
I updated the picture to represent the most complicated map that their could be. this map represents what the player of my game actually sees, they just use WASD and can move around and they see themselves move through this 2d plat-former view. Their will be different types of enemies, all with different speeds and jump heights. but all will have enough jump height and speed to make the jumps in this map, and maneuver through it. The maps are generated by simply reading an XML file that has the level data in it. the data is then parsed and different types of tiles are placed in the tile holding sprite, acording to what the XML says. EX( XML node: (type="reg" graphic="grass2" x="5" y="7") and so the x and y are multiplied by the constant gridSize (like 30 or something) and they are placed down accordingly. The enemies get their frame-by-frame instruction from an AI class attached to them. This class is responsible for producing this path and return the first direction to the enemy, this should only happen every second or so, so that the enemies don't follow a old, wrong path. Please let me know if you understand my concept, and you have some thought/ideas or maybe even the answer that i'm looking for.
ALSO: the physics in this game is separate from the pathfinding, they work just fine, using a AABB vs AABB concept (the player and enemies also being AABBs).
The trick with using A* here is how you link tiles together to form available paths. Take for example the first gap the red player would need to cross. The 'link' to the next platform (aka brown tile to the left) is actually a jump action, not a move action. Additionally, it's up to you to determine how the nodes connect together; I'd add a heavy penalty when moving from a gray tile over a brown tile to a gray tile with nothing underneath just for starters (without discouraging jumps that open a shortcut).
There are two routes I see personally: running a quick prediction of how far the player can jump and where they'd jump and adjusting how the algorithm determines node adjacency or accept the path and determine when parts of the path "hang" in the air (no brown tile immediately below) and animate the enemy 'jumping' to the next part of the path. The trick is handling things when the enemy may pass through brown tiles in the even the path isn't a parabola.
I am not versed in either solution; just something I've thought about.
You need to give us the most complicated case of map, player and enemy behaviour (including jumping up and across speed) that you are going to either automatically create or manually create so we can give relevant advice. The given map is so simple, put the map in an 2-dimensional array and then the initial player location as an element of that map and then first test whether lower number column on the same row is occupied by brown if not put player there and repeat until false then same row higher column and so on to move enemy.
Update: from my reading of the stage generation- its sometime you create- not semi-random.
My suggestion is the enemy creates clones of itself with its same AI but invisible and each clone starts going in different direction jump up/left/right/jump diagonal right/left and every time it succeeds it creates a new clone- basically a genetic algorithm. From the map it seems an enemy never need to evaluate one path over another just one way fails to get closer to the player's initial position and other doesn't.

Need algorithm to draw overlapping rectangles

I need help with efficiently drawing/culling a series of opaque rectangles, in other words, this is a stack of index cards on a desk. The specifics are:
no rotations, so everything is simple integer coordinates, axis-aligned
cards are fully opaque
cards can have any integer X,Y position
all cards are the same size
I have a list of the cards in z-order
I think I have (essentially) two choices:
1) brute force painter's approach, where all cards within the desktop viewport are fully drawn, in reverse z-order. Pros: simple. Cons: a) requires an off-screen buffer to avoid flicker, b) potentially lots of time wasted on drawing expensive areas of each card when that area might end up being obscured, worst-case being the entire card getting covered.
2) an algorithm that generates a list of visible (or obscured) rectangles for every card, such that only visible portions are ever drawn.
Choice 2 is where I need advice, especially in terms of algorithms, and pro's and con's of a "smarter" draw cycle.
Any language/platform agnostic advice is appreciated. If it matters, this will be implemented on MS Windows.
Am open to any suggestions, including hybrid approaches. I realize a precise answer is likely very dependent on the particulars of the code, but I'd be happy even with generalized concepts at this point!
Additional notes: It will be possible to have thousands of cards stacked on top of each other, so I'm highly motivated to avoid a purely brute force painter's approach - at least without some sort of pre-processing to cull out fully obscured cards. The same goes for lots of cards that were closely tiled, worse case being only their borders showing - I would like to skip painting the complex innards in those cases, if possible.
What about painting only the contour line of each card from the bottom most to the top most? Then you can do a flood fill to paint inside of the contours. This way you would repaint only a few pixels corresponding to the borders where there are intersections.
Edit: Uploaded images to help me explain the idea.
The first step is mark the borders of the cards assigning their Z-order (top left image). This way, there are overwrites, but only on borders which are a little amount of pixels.
After that, you can paint the texture of the cards (lowest Z-order first) following two rules:
You start from the border and paint the blanks until reach a border;
If the border's Z-order is the current one, you paint it;
If the border's Z-order found is less than the current Z-order, you continue painting as it were a blank one;
Otherwise, you found a border with greater Z-order, so you skip that block;
Next card.
Hope it helps :)
OK, here's some loose pseudo code for how I think this problem can be solved.
Begin with a z-order sorted list of the cards. Each card has a list of visible rects (explained later), that needs to start out with just one rect, set to the card's full bounding box. The loop is begun with the lowest z-order card first.
Cards.SortZOrder();
foreach Card in Cards do
Card.ResetVisibleRects; // VisibleRects.DeleteAll; VisibleRects.Add(BoundingBox);
CurrentCard = Cards.Last;
TestCard = CurrentCard;
The idea here is that we're going to work upwards from our "current" card, and see what effect each higher card has on it. There are 3 possibilities as we test each higher card. It either completely misses, completely obscures, or partially obscures. For a complete miss, we ignore the test card, since it doesn't affect our current card. For a complete obscure, our current card gets culled. A partial overlap is where the list of visible rectangles comes in, since partial overlap can (potentially) split the lower rectangle into two. (It's easy to see how this plays out if you just grab two playing cards, or index cards. The top one causes the bottom one to either adjust one of it's sides, if they share any edge, or it causes the bottom one to split into two rects if they share no edges.)
Caveat: This is VERY unoptimized, unrolled code ... just for talking about the principles. And yes, I'm about to use "goto" ... mock me if you must.
[GetNextCard]
TestCard = Cards.NextHighest(TestCard);
[OverlapTest]
// Test the overlap of TestCard against all our VisibleRects.
// The first time through this test, CurrentCard will have only one
// rect in the VisibleRect list, but that rect may get split up later.
// OverlapTests() checks each rect in the VisibleRects list, and
// creates an Overlap record for any of the rects that do overlap,
// like: Overlap.RectIndex, Overlap.Type. It also summarizes the
// results into the .Summary field.
Result = CurrentCard.OverlapTests(TestCard);
case Result.Summary
none:
goto [GetNextCard];
complete:
CurrentCard.Culled = true;
// we're now done with this CurrentCard, so we move upwards
CurrentCard = TestCard;
goto [GetNextCard]
partial:
// since there was some overlap, we need to adjust,
// split, or delete some or all of our visible rectangles.
// (we won't delete them all, that would have been caught above)
foreach Overlap in Result.Overlaps
R = CurrentCard.VisibleRects[Overlap.RectIndex];
case Overlap.Type
partial: CurrentCard.SplitOrAdjust(R, TestCard);
complete: CurrentCard.Delete(R);
end case
// so we've either added new rects, or deleted some, but either
// way, we're done with this test card. We leave CurrentCard
// where it is and loop to look at the next higher card.
goto [GetNextCard]
The testing is done when CurrentCard = Cards.First since the topmost card is always fully visible.
Just a couple more thoughts here ...
I think this would be fairly straightforward in real code. The most complicated thing about it would be splitting a rectangle into two, and given the fact that it's all integer math, even that is trivial.
Also, this doesn't have to be performed every paint cycle. It only needs to be done when there's any change in contents, position, or z-order.
After a pass up the list, you're left with a paint-ready list of cards, each non-culled card having at least one rectangle that can potentially fall within the display's clipping/dirty region. When you paint a card you can examine its list of visible rectangles, and potentially be able to skip drawing portions of the card that might be expensive to render.

Where Should Collision Detection Code Be?

I'm writing a pong game and I have a ball class that has velocity x, y, positions and all that stuff that every frame is updated by calling #ball.update, this moves the ball forward by its x_vel and Y_vel etc. My question is Should my collision code be in the loop or in the update method of the ball class? Or should it all be in the loop and the ball should not have any control of its position?
The collision detection should not be done in you ball class because it would require the knowledge of all other objects in your game.
Imagine a shooter with many objects and think about what happens if each object would try to calculate the collision on it's own.
There should be a dedicated class that cares about collision detection. This class is notified if any of its supervised objects changed its position. Then it checks for collision and notifies all abjects (not only 2 :) that have a collsion.
Have fun... :)
A Ball class like you described is indeed a good idea. That way you can replicate it if, like in some "breakout" games, you ever want to spawn two or more balls -- or if you want to re-use that code in another game. You can also have a Paddle class with similar X,Y coordinates (or derive both Ball and Paddle from a "ScreenObject" class if they turn out to share many such similar members). Paddle can read a shared variable that gets updated by a thread/event receiving user input.
Simple collisions, such as against walls, can be done in your Ball class based on globally accessible values like the screen dimension extents. Your Update routine can simply reverse one velocity component when that particular wall is hit. You can define and set a delegate/callback in the Ball class to play a sound when the ball bounces. Similarly, Paddle's Update can check the screen size so you can't move the paddle off-screen.
Like TottiW recommended, collision between objects is best done in a parent "manager" class that owns all the objects or has access to their X,Y members or bounding boxes. This is good object-oriented design. Ball and Paddle shouldn't have access to each other's X,Y positions! ...but the manager does. It can also eliminate redundant collision checks. If object A checks to collide with object B, B shouldn't have to subsequently check for collision with A. So really all your manager class needs to do is, for each Paddle, check each Ball's position. This can be further simplified since a Paddle might only move in one direction, say horizontally, at a fixed Y position. Thus your first check can immediately eliminate any Ball.Y < Paddle.Y, for simplistic example (depending on Y's direction).
For games with lots of objects, you don't want to collison-detect every one, just the nearest ones. In that case, the "manager" becomes more of a "scene manager" which keeps linked lists of objects in both X and Y directions. As objects move past other objects, they exchange pointers in the lists, so the lists always stay sorted. That way, for any given object, we know the objects immediately to the left/right/above/below, so we need only do collision checks against those... saving lots of time and making your game run with maximum speed. Maybe you're not to this point, though!
Good luck and like the others have said, have fun with it!
For pong simple matrix operations should be sufficient. A ball class is not needed if there is only one and you use it only for holding a tuple.

Resources