I'm writing a bomberman game in Java and I have already wrote the code for the map of the game (which contains tiles), the players (and their movement in the map) and now I am stuck in the code for the bomb explosion.
I have a Map class which contains a 2d array of Tiles, which can contain Players, Blocks and Bombs.
The Player object have a method dropBomb who calls the method receiveBomb from the Map object (every Player has the reference of the Map object) with the position of the bomb and the bomb. When the Map method receiveBomb is called, the map put the bomb in the correct Tile.
My problem is in the explosion of the bomb. Who should care about it? The bomb itself? If it is, should the bomb have the reference for the Tile that contains it? Until now my tile haven't need the Map reference.
One possibility that I thought is to have the Tile reference inside the Bomb object, so, when the bomb explodes (and the bomb knows when it should explode) it calls a method in the tile object for the explosion and the tile calls a method in the map. By the way, I don't know this is a good idea. What should I do?
public class Tile {
private boolean available; //if the tile is not occupied by a indestructible block or bomb
private List<Entity> entities; //you can have more than one player at a tile
public boolean receiveEntity(Entity entity) {
boolean received = false;
if (available) {
this.entities.add(entity);
received = true;
if (entity instanceof Block || entity instanceof Bomb) {
available = false;
}
}
return received;
}
public boolean removePlayer(Player player) {
return entities.remove(player);
}
}
Player class:
public class Player implements Entity {
private Map gameMap;
private int posX;
private int posY;
private int explosionRange; //the explosion range for bombs
public Player(int posX, int posY, Map gameMap) {
this.gameMap = gameMap;
this.posX = posX;
this.posY = posY;
this.explosionRange = 1;
}
public void dropBomb() {
gameMap.receiveBomb(new Bomb(explosionRange), posX, posY);
}
}
Map class:
public class Map {
private Grid<Tile> tileGrid;
private int width;
private int height;
public Map(int width, int height, BuildingStrategy buildingStrategy) {
this.width = width;
this.height = height;
this.tileGrid = new Grid<Tile>(width, height);
buildingStrategy.buildMap(this);
}
public void receiveBomb(Bomb bomb, int posX, int posY) {
tileGrid.get(posX, posY).receiveEntity(bomb);
}
}
I have omitted the movement methods, because the movement is already fine.
I have always learned, and live by the rule "the table paints itself". The painter might choose the color and call the method, the floor might decide how the leaks and splatter is shown, but the table paints itself.
Back to your issue: the bomb explodes itself. This way you can have different effects of different bombs. The bomb has an effect on the tile, and the tile reacts to that.
Example: A bomb has a force and a type of explosion. The bomb, (occupying one and one tile only I think?) will 'give' it's effect to a tile.
Now it's the tile that deals with distributing this force. Lets say you have several kinds of bombs, one power (lets say a number between 1 and 10), and two type (lets say normal, incendiary, freeze).
Now your bomb explodes, and because your avatar is a level 5 fire-mage, your bombs are of power 4 and type incendiary. So you say to your tile: I explode with power 4 and I am setting you on fire!
Now the tile comes in to play. Any tile that gets 'touched' by the force of an explosion needs to call it's "Exploded" function to do stuff. If it is also on fire, there is more to do in the "onFire" function
What tiles are 'exploded' comes from force. Normal tiles with force 4 will give the expotion off to all squares within a range of 4, but if it is a special tile (it knows that from itself), like a mountain tile, it might not be able to advance with that force.
Tile 1 explodes with 4 and gives it to adjacent tiles with force 3. One of those tiles might be a wall, so doens't do anything further. Another is a normal tile, and explodes, and continues giving it forward with force 2, etc. If it is a 'water' tile, the explosion is pushed ofrward, but the fire isn't, etc
so:
bomb explodes itself and gives calls the tiles explosion function
tile is exploded and pushes explosion forward according to tile-type.
subsequent tiles explode because of this.
In the end it might look like most of the work is done by the tiles, and this is probably even the case. but the first steps: the calculation of the force, type, and the first calls are from the bomb. The bomb explodes. And then the explosion has an effect on the tile. The tile handles that, and if needed propagates it.
Your Map should be responsible for the explosion, as it is for every other tile on the map. After all, what is an explosion if not for another tile-type that disappears after a few seconds?
When your game loop calls the update method on the Map object your map should figure out:
What tile is the bomb on
Ask the bomb how far the reach is
Figure out what's in the adjacent tiles that the bomb can reach
Think of your design as a series of events, taken care of one by one in the game loop before eventually being drawn. When your bomb is dropped, it raises an event to the Map in the form of recieveBomb() with the Map being the event controller.
I believe this question fits better in a discussion format and not a Q&A format. It's hard to tell you what is the "correct design" without understanding the overall architecture.
The Map should be the responsible one for handling a bomb explosion.
I would suggest having a queue in the Map, that contains all the bombs present. Also, your bombs should have a timer (i.e., CreationTime) so that as bombs get pushed into the queue, you check each bomb in the queue for how long they have been in there and if applicable "explode" them.
Add a ExplodeBomb function in the Map that checks all 4 directions and handle the tiles accordingly.
Related
I am currently working on a 2d game in which a player sprite pushes other sprites around on the screen.
My current code (within subclass):
//x and y being the co-ords i want this object to move to (e.g 50 pixels
right of its starting point etc.)
public Boolean move(float x, float y, int delta) {
this.setx(x);
}
How do i make the object move say 50 pixels every 1 second? or alternatively every x frames.
I've tried using delta but that results in smooth motion which is much harder to control for my particular needs.
Any help would be much appreciated
Your approach to accomplish it with the deltas is right. Assuming you have your move method inside your update method and call it in there (or implementing it in a similar way). One way you could achieve these would be the following:
class YourGameStateWithUpdateRenderInit extends BasicGameOrWhatever{
//Global variables for updating movement eacht second.
float myDelta = 0; // your current counter
float deltaMax = 1000; // 1 second, determines how often your object should move
public void update(...){
objectToMove.move(50,50,delta); //The object which contains the move method and you move it by 50 x/y per second.
}
}
Inside your objectToMove class you have your move method:
public Boolean move(float x, float y, float pDelta) {
myDelta += pDelta;
if(myDelta >= deltaMax){
this.setx(x);
myDelta = 0;
}
}
This should work for an update every second. However this implementation is not really good or precise since as you stated you probably have that move method in a sub class or something similar. So you need to adapt it to your needs, but i hope you get the idea behind it. I think it demonstrates the purpose of counting an class attribute up by the delta values until a certain value (e.g. 1000 for 1 second) and after that set it back to zero.
I'm trying to make a small game in Java, swing, and I can't figure out a good way to solve my problem. I've got two arrays, first of Crate objects
public class Crate {
private static ImageIcon crate = new ImageIcon(Player.class.getResource("/Images/crate.jpg"));
private int x=0;
private int y=0;
private static int Xdisplacement;
private static int Ydisplacement;
private int id;
//getters and setters n stuff
second one is of a Tile objects.
public class Tile {
private static ImageIcon tile = new ImageIcon(Player.class.getResource("/Images/tile.jpg"));
private int x=0;
private int y=0;
private boolean hasBox=false;
//getters and setters n stuff
I would like to check if all Crates are placed on Tiles. I mean it doesn't matter which box is on which tile, there are few boxes, few tiles, and each box should be placed on a tile, doesn't matter which box on which tile. In the game, player walks and move crates around, so their coords change. Tiles coords do not change (if it may help). This is gonna be my stop condition. The game is over when crates are placed on tiles.
I suppose making a loop inside another loop and then checking every single field of every single object isn't a good solution? So are there any other ways to do so?
A complete design is beyond the scope of StackOverflow, but you will probably want to use the model-view-controller pattern, illustrated here. The answer includes a very simple example game and cites a more complex game involving players on a tiled grid.
Addendum: In the particular case of checking grid occupants after a move, the example cited uses nested loops to check the current state against a copy in the method RCModel#moveBots().
I got this code that gets x,y positions from a motion sensor tracking a hand. The app draws a circle in the middle of the screen and then detects whether the hand is outside the circle. While the hand is outside the circle, a function checks the distance of the hand from the center of the circle. I'm attempting to store the distance data while the hand is outside of the circle in a linked list.
I need to get both the top 5 largest values and the duration for each time the hand is outside the circle.
Here's my code thus far; I've left out a bunch of the code for setting up the motion sensor just for simplicity, so this is semi-pseudo code. In any case, my main issue is getting the values I need from the list. I have the circle class included as well. I do the outside of the circle calculation and how far outside of calculation inside of my circle class.
Please let me know if this makes sense! The motion sensor is reading in data at 200 fps, so efficiency is factor here. On top of that, I am only expecting the hand, going back and forth, to be outside of the circle for a few seconds at a time.
import java.util.*;
LinkedList<Integer> values;
public void setup()
{
size(800, 300);
values = new LinkedList<Integer>();
HandPosition = new PVector(0, 0); //This is getting x,y values from motion sensor
aCircle = new Circle(); //my class just draws a circle to center of screen
aCircle.draw();
}
public void draw()
{
if (aCircle.isOut(HandPosition)) /* detects if movement is outside of circle. Would it make more sense for this to be a while loop? I also need to start a timer as soon as this happens but that shouldn't be hard */
{
values.add(aCircle.GetDistance(HandPosition)); //gets how far the hand is from center of circle and adds it to linked list. Allegedly at least, I think this will work.
/*So I need to get the 5 largest value from inside of my linked list here.
I also need to start a timer*/
}
}
class Circle {
PVector mCenter;
int mRadius;
Circle()
{
// initialize the center position vector
mCenter = new PVector(0,0);
mRadius = 150;
mCenter.set((width/2),(height/2));
}
boolean isOut(PVector Position) //detects if hand position is outside of circle
{
return mCenter.dist(Position) <= mRadius;
}
float GetDistance(PVector Position) //detects how far the hand is from the center of circle
{
return mCenter.dist(Position);
}
void draw() {
ellipse(mCenter.x, mCenter.y, mRadius, mRadius);
}
}
I'm new to Processing as well so don't hold back if any of this works.
You can use Collections.sort(List); here, then take last five element from the list.
Collection.Sort()
I'm making apong game, in a boolean method in the Paddle class I want to determine if the ball touching any of the two paddles, I'm struggling of finding the proper logic...
here are the variables:
// instance variables
private Screen theScreen;
private MyroRectangle theRectangle;
private int topLeftX;
private int topLeftY;
// constants
private final int HEIGHT = 100; //the paddle's fixed height
private final int WIDTH = 5; //the paddle's fixed width
private final int PIXELS_PER_MOVE = 20; //the number of pixels a paddle can move either up or down in one timestep
here is the method: * this method is just to determine if the ball touch or not it doesn't do anything with bounce the ball back
public boolean isTouching(Ball b)
{
boolean t = false;
if ((theScreen.getWidth()-(b.getX() + b.getRadius())) >= theScreen.getWidth()-theRectangle.getCenterX() )
{
t= true;
}
return t;
also I tried:
if ((b.getX() > theRectangle.getCenterX()/2) && (b.getY() < theRectangle.getCenterY()/2))
==========
** the methods of the ball class that might be needed:
getX()
getY()
getRadius()
==============
** the Rectangle class:
getCenterX()
getCenterY()
===============
** the Screen class:
getWidth()
getHeight()
I just want to determine at least on of the conditions then I can figure out the rest of them.
In my junior year in college I worked on a Collision detection system algorithm for the windows phone. It is hardly perfect but it was EXTREMELY efficient and can be adapted to a majority of games.
The way that it worked was pretty simple. There were two types of objects; Collidable objects (such as enemies or buildings) and Objects that you wish to check for collisions with these collidable objects.
I had this idea when I was going through a data structures class and we spoke about Linked Lists. I thought what if each link was a collidable object that you could stick your game objects that were already created in it. Then as the game objects moved around you would have a lightweight way of checking their locations for collisions. Thus my system was born.
Basically what it comes down to is using
C (or the distance between to points) = SqrRoot(A^2 + B^2) - radius of ball
this formula should look very familiar to you.
You can see the full answer on this question:
Java More Resourceful Collision Detection
This problem can be seen as solving the question if two 2d-areas, the paddle (a rectangle) and the ball (a circle) intersect. You can just google/wiki formulas for that.
If you don't want to go into the math for solving the problem through geometry, package java.awt.geom contains classes that can do the calculations for you, namely java.awt.Area. You would just create Area instances for paddle and ball and then call the intersects() method to know if they collided.
in libgdx game
I want to touchDown and then drag somewhere and then on the release (touchUp) apply a directional force based on the distance and direction from the target body. When you touchdown the target body stays still and then on touchup the force is applied along the desired trajectory.
(very similar to Angry birds - where you get to see the trajectory in dotted lines for the target body when you hold hack the slingshot - I want to do the same)
So I guess that this might not be the hardest thing to do but given a few options Im leaning towards using a MouseJointDef but its an immediate force applied (i.e. the target moves immediately - I want it to stay still and then once the touchup event happens then apply the force)
Whats the easiest way to draw the trajectory also? Im using Box2D also.
Create a class that inherits InputAdapter class, then create an instance of it and register it to listen the touch inputs.
Gdx.input.setInputProcessor(inputAdapter);
There are 3 methods to handle the touch events touch_down, touch_dragged and touch_up that you have to override.
In touch_down, check the touching position to whether is in the birds area or not. If it is, make a boolean flag true.
In touch_dragged, check the flag above and if it was true, calculate the distance of the touch position relative to the bird shooting center and the shooting angle.
In touch_up, you can order to shoot with the calculated amounts by calling
body2shoot.applyLinearImpulse(impulse, body2shoot.getWorldCenter());
There is no need to MouseJointDef to move the body2shoot. Just set the transform of body2shoot in touching position to be dragged in each cycle of render.
For calculating the trajectory I wrote a class like this:
public class ProjectileEquation
{
public float gravity;
public Vector2 startVelocity = new Vector2();
public Vector2 startPoint = new Vector2();
public ProjectileEquation()
{ }
public float getX(float t)
{
return startVelocity.x*t + startPoint.x;
}
public float getY(float t)
{
return 0.5f*gravity*t*t + startVelocity.y*t + startPoint.y;
}
}
and for drawing it just I set the startPoint and startVelocity and then in a loop I give a t (time) incrementally and call getX(t) and getY(t).