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.
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 am following a guide on how to play a flappy bird clone in the LibGdx framework.
-http://www.kilobolt.com/day-5-the-flight-of-the-dead---adding-the-bird.html
I am currently on the part where the author discusses adding the actual bird and the physics behind the bird. He encapsulates the state of the bird with these instance variables
private Vector2 position;
private Vector2 velocity;
private Vector2 acceleration;
private float rotation; // For handling bird rotation
private int width;
private int height;
and he initializes these instance variables or fields inside the constructor
public Bird(float x, float y, int width, int height) {
this.width = width;
this.height = height;
position = new Vector2(x, y);
velocity = new Vector2(0, 0);
acceleration = new Vector2(0, 460);
}
The author explained that the 460 constant acceleration in the y direction is due to gravity, that is earth's gravity causes an object to speed up by 9.8m/s every second or 9.8m/s^2.
When asked how he determined the 460, the author responded, "Acceleration was experimentally determined. Its value does not change."
My question is how would you go about experimenting for this value? What information would you use. I think really understanding the process behind this experimentation would be valuable for developers who are trying to incorporate gravity in their applications.
I think this 460 would be in terms of the game units, where the author, james, earlier defined as cam.setToOrtho(true, 136, 204);
By "experimentally determined," the author just means trying various values until finding something that worked. There's no math or complex magic here. To experiment with it, just change it and run the program again. If you like what you see, use it. If not, adjust it accordingly.
The number of 9.8 m/s² is just a reference to how Earth's gravity works. It has nothing to do with the actual game's implementation.
You could define what real world size will your pixel represent. Then use kinematic formula to calculate what time will take some object to go to the peek and fall back again. Then measure the time of your game object and try to tune up your gravity the way that jump takes approximately the same time as you calculated.
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.
In Java using the acm.graphics GPen is there any way to move the entire drawn sequence of lines? I've read the manual thoroughly and I'm beginning to think it's not possible which brings me to my second question. Are there any other graphics objects in Java that work very similar to a pen that can also be moved. The reason I'm asking is because I've been working on a graphing program that allows mouse gestures to be used to pan around and zoom in and out. After building functionality for implicit functions I realized simply clearing the drawing board and redrawing everything is not going to cut it anymore so I really need to work on more efficient ways to handle intermediate changes of the graph without having to recalculate everything. For example with this or similar code:
GPen p = new GPen();
p.setLocation(100,100); //places the pen on the canvas at 100, 100
p.drawLine(-50,0); //draw a line left 50 pixels
p.drawLine(50,-50); //draw a line right and up 50 pixels each
p.drawLine(0,50); //draw a line down 50 pixels
This would result in a simple right triangle who's bottom right most point is at 100, 100 on a particular canvas. What I need to do is be able to move this same drawn sequence of lines relative to one another to another origin. What I hoping for is a class that has separate methods for setLocation() and move() where setLocation() controls pen position and move() would move the entire object around.
Ok so having received almost no attention on here I've came to the conclusion that such a method just needs to be written from scratch and went ahead and did that. I'm not entirely sure how helpful posting my proprietary code would be but in the event that anybody could use it I'll post the basic idea of it. Since Pen utilities are essentially a bunch of lines and lines are a bunch of from and to's I created an object that I called FPen (for FunctionPen) that accepts the instructions for from and to. While defining FPen you pass it where to start and how far to go however many times you need and that's it. Once you've passed these instructions I created another method called returnGPen(Color c) which will on call use the instructions it has on hand and generate the desired GPen object. When you want to move the entire GPen you can then create a method called adjustOrigin(double oX, double oY); which will calculate a change from a previously recorded origin and this new one and go through the list of instructions and adjust them appropriately.
My needs for this Class are strictly for my Graphing program and are not entirely finished either but it does work for most purposes.
import acm.graphics.GPen;
import java.awt.Color;
import java.util.ArrayList;
public class FPen{
private double relativeCenterX;
private double relativeCenterY;
private ArrayList<Double> fromX = new ArrayList<Double>();
private ArrayList<Double> fromY = new ArrayList<Double>();
private ArrayList<Double> distX = new ArrayList<Double>();
private ArrayList<Double> distY = new ArrayList<Double>();
public FPen(double rX, double rY, double z){
relativeCenterX = rX;
relativeCenterY = rY;
}
public void adjustOrigin(double cX, double cY){
double changeX = relativeCenterX-cX;
double changeY = relativeCenterY-cY;
for(int i = 0; i < fromX.size(); i++){
fromX.set(i,fromX.get(i)+changeX*zoom);
fromY.set(i,fromY.get(i)-changeY*zoom);
}
relativeCenterX = cX;
relativeCenterY = cY;
}
public void clear(){
fromX.clear();
fromY.clear();
distX.clear();
distY.clear();
}
public void drawLine(double fX, double fY, double tX, double tY){
fromX.add(fX);
fromY.add(fY);
distX.add(tX);
distY.add(tY);
}
public GPen returnGPen(Color c){
GPen pen = new GPen();
pen.setColor(c);
for(int i = 0; i < fromX.size(); i++){
pen.setLocation(fromX.get(i),fromY.get(i));
pen.drawLine(distX.get(i),distY.get(i));
}
return pen;
}
}
Of course a unexpected nice thing that came out of this was the idea that I can now quickly benchmark different drawing routines by creating different methods for each and calling what I'm interested in.
I am creating a reversi game for my intro CS class.
I found an error in SearchN() that would cause it to give false playableN flags and created isSame() as a work around.
Now the game is crashing when I attempt a move.
I have the bug isolated to isPlayable() which causes the program to stop running without error message.
I thought it was because the program was searching out of bounds; however, when i run .isPlayable(0,0) it returns a NullPointerException (also something I don't quite know how to get rid of).
So it must be some error with handling un-played spaces.
Anyone have any thoughts?
/**
* a method to return the color of a tile
*#params x y tile coordinates
*/
public Color getColor(int x, int y){
try{
return buttons[x][y].getBackground();
}
catch(ArrayIndexOutOfBoundsException e){
return null;
}
}
/**
* a method to determine whether a tile has been played
*#params x y tile coordinates
*/
public boolean isPlayed(int x, int y){
if(this.isBlack(x,y) || this.isWhite(x,y)){
return true;
}else{
return false;
}
}
/**
* a method to determine whether a tile has a color opposite to a given color
*#params x y c tile coordinates and color to compare
*/
public boolean isOpposite(int x, int y, Color c){
if(this.isPlayed(x,y)){
return(!(this.getColor(x,y).equals(c)));
} else
return false; // this was giving the false playableN flag
}
/**
* a method to determine weather a tile has the same color as the one given
*#params x y c tile coordinates and color to compare
*/
public boolean isSame(int x, int y, Color c){
if(this.isPlayed(x,y)){
return(this.getColor(x,y).equals(c));
}else{
return false;
}
}
/**
* a method used to check tiles north of an attempted play to verify legal moves
*#params x y c tile coordinates and comparing color
*/
public void searchN(int x, int y, int increment, Color c){
if(increment>1 && (this.isSame(x-increment,y, c))){
playableN = true;
leadN = false;
} else {
if(this.isOpposite(x-increment,y,c)){
leadN=true;
}
}
}
/**
* a method used to determine if a tile is playable
*#params x y tile coordinates
*/
public boolean isPlayable(int x, int y){
this.searchN(x,y,1,turnColor);
// search 7 other directions
while(leadN||leadNE||leadE||leadSE||leadS||leadSW||leadW||leadNW){
int i = 2;
if(leadN)
this.searchN(x,y,i,turnColor);
// search 7 other directions
i++;
}
if(playableN||playableNE||playableE||playableSE||playableS||playableSW||playableW||playableNW)
return true;
else
return false;
}
** all tiles are black, white or the default tile color (green) and in a 2D array of JButtons displayed in gridLayout().
I see two ways that a NullPointerException could be happening:
You are getting an ArrayIndexOutOfBoundsException in getColor. In that case you are catching the exception and returning null.
or
getBackground is returning null.
In either case getColor will return null, which causes a NullPointerException to be thrown when you call .equals in isOpposite or isSame.
You should check the result of getColor before attempting to calls .equals on it. Then you should figure out why getBackground is returning null or ArrayIndexOutOfBoundsException is being thrown.
Because #goto10 already gave the direction you need to look, here are some other notes:
You need to learn better separation of concerns. Specifically, you're mixing your display code with your game-rule code. With proper design, almost all programs should be runnable from a command line - a GUI is solely there to help out the end-user.
When you have two (or more) related parameters, you really have a single one - a composite class containing them. For example, your x and y parameters for searching your array really represent one CoordinatePair, Location, or Point instance. Although the likelihood is small here, this will help avoid issues in the future - what happens if somebody accidentally swaps the y and increment parameters in searchN(), for example? Code up an immutable Point class and use that - it'll completely remove that problem:
public final class Point {
// Yes, public variables are almost universally frowned upon, with good reason.
// Here, though, it's kind of the 'point'
public final int x;
public final int y;
// Note: private constructor - can't call this from outside.
private Point(final int x, final int y) {
this.x = x;
this.y = y;
}
// Static factory method for construction instead.
// It is left as an exercise for the reader to implement caching.
public static Point fromCoordinates(final int x, final int y) {
return new Point(x, y);
}
}
You'll need to implement a good .hashCode() and .equals() method to make this work, but what Eclipse (or any of the other good tools) spits out should be good. There are some performance considerations with using immutable objects, but for your needs here it's not an issue.
Strive to make methods have as few side-effects as possible; that is, try to make them modify as little (preferably NO) external state as possible. This includes state that is part of your object (such as leadN) but is not otherwise 'part' of the method. Side-effects make it extremely difficult to 'reason' (figure out what's going on) about the state of an object, and make good testing an actual nightmare. Writing methods that depend solely on the (hopefully immutable) state of the objects passed in, and the immutable state of the 'host' (this) object may be somewhat more difficult, but much more easy to reason about; systems that are almost all (or perhaps completely) immutable are much easier to think about, and you get thread-safety/parallel execution for free.
Your methods .isSame() and .isOpposite() are a bit hacked together because the only difference between a played/unplayed square is it's color. The relevant rule-side code should be unaware of display-side code - there's no such thing as a green-sided piece (there technically isn't a white or a black piece either - there's a piece for player 1, and a piece for player 2. Even in the physical world, it's a display only effect, and rules which read 'white gets 4.5 extra points' really mean 'the player who goes second gets 4.5 extra points'). Also, those two methods don't return inverse results for un-played squares (.isSame() returns false), which isn't logical.
Whenever you have a long list of similar elements (the leadX and playableX variable sets), try and reformat them into an actual list. This would also help immensely if you wanted to make a 3D version... Also, there's a way to use what's known as the Strategy Pattern (along with a hash map or array list) to make moving/searching in different directions far easier.