Check if a player can place a block at a said location - java

I am creating a custom anti-cheat. However, I have come to a point where I am quite stumped. I am attempting to detect whether a player can place a block at a said location, but it is becoming increasingly convoluted as I try to make it more reliable for non-cheating players. Currently, I am incorporating a raycast algorithm (usingAxisAllignedBB) whenever a player interacts with a block (PlayerInteractEvent) to see if the player is actually looking at the Block and BlockFace the event says they were. The problem, I believe, is the player's direction is only updated 20 times a second where their frame rate might be much higher. This often causes (about once every 15 or so block places from my testing) the PlayerInteractEvent to be incorrectly canceled.
Raycast Algorithm for finding Block looked at
public static Block getTargetBlock(Location location, Vector direction, double rangeSquared, int maxTrials, TargetMethod targetMethod) {
Location loc = location.clone();
Vector dir = direction.normalize();
final double directionX = direction.getX();
final double directionY = direction.getY();
final double directionZ = direction.getZ();
Block block = loc.getBlock();
for (int i = 0; i <= maxTrials; i++) {
final double locX = loc.getX();
final double locY = loc.getY();
final double locZ = loc.getZ();
double wholeMoreX = wholeMore(locX,directionX);
double moreX = Math.abs(wholeMoreX /directionX);
double wholeMoreY = wholeMore(locY,directionY);
double moreY = Math.abs(wholeMoreY /directionY);
double wholeMoreZ = wholeMore(locZ,directionZ);
double moreZ = Math.abs(wholeMoreZ /directionZ);
if(moreX < moreY && moreX < moreZ){
if(directionX > 0)
block = block.getRelative(BlockFace.EAST);
else {
block = block.getRelative(BlockFace.WEST);
}
}
else if(moreY < moreX && moreY < moreZ){
if(directionY > 0){
block = block.getRelative(BlockFace.UP);
}
else{
block = block.getRelative(BlockFace.DOWN);
}
}
else{
if(directionZ > 0){
block = block.getRelative(BlockFace.SOUTH);
}
else{
block = block.getRelative(BlockFace.NORTH);
}
}
final double scalar = Math.min(Math.min(moreX,moreY),moreZ);
Vector addAmount = dir.clone().multiply(scalar);
loc.add(addAmount);
if(loc.distanceSquared(location) > rangeSquared)
return null;
AxisAlignedBB boundry = getBoundry(block,targetMethod);
if(boundry != null)
if(blockFaceCollide(location,direction,boundry) != null)
return block;
}
return null;
}
However, I doubt this is the issue. From my testing, it works perfectly fine. Thus, I think I must rely on alternative methods. Here are some ideas, but I am not quite sure they are satisfying.
Idea: Near Blocks
I have thought about seeing if the block placed is within a 1 block radius (or possibly shorter if I am looking at closest distance to block from ray) of the block found from the raycast, but this offers too many problems. If a player is moving their cursor from a barrier to a further out area, a false positive for cheating would be fired. On the other hand, players could still build in a fully enclosed area if they had block pillars North, East, South, West but not North-West, North-East, etc.
Idea: A* Path finding Algorithm
If I made points on the ray in the raycast have 0 G-Cost, with G-Cost increasing with distance from the ray and the H-Cost being the closest distance to the targeting block, I feel this could solve this dilemma. I could set a max G-Cost threshold before the PlayerInteractEvent is canceled. The problem, however, is incorporating A* with various AxisAllignedBB of blocks seems difficult. I might be able to create a grid which consists of 100x100x100 points per block, but I am not sure this would be efficient nor best practice.
Idea: See if the player can see the block
This would be highly effective, but I am not sure whether it would be realistic. For this, each time a player places a block I would need to detect which blocks would completely overlap other blocks in the player's interact radius. Taking all the final non-overlapped blocks, I could see if the interacted block contains these. If not, the interaction would be canceled. This seems like it might take a performance hit, and I could see how there could also be some false positives for cheating.

I'd suggest to create a method that informs if Player and block intersects.
Sample Code
public static final double ONE_UNIT = 1.0;
public static final double ZERO_UNIT = 0.0;
public static Location getPlayerBlockIntersection(Player player, Block target) {
if (player == null || target == null) {
return null;
}
double minX = target.getX();
double minY = target.getY();
double minZ = target.getZ();
double maxX = minX + ONE_UNIT;
double maxY = minY + ONE_UNIT;
double maxZ = minZ + ONE_UNIT;
Location origin = player.getEyeLocation();
double originX = origin.getX();
double originY = origin.getY();
double originZ = origin.getZ();
Vector dir = origin.getDirection();
double dirX = dir.getX();
double dirY = dir.getY();
double dirZ = dir.getZ();
double divX = ONE_UNIT / dirX;
double divY = ONE_UNIT / dirY;
double divZ = ONE_UNIT / dirZ;
double t0 = ZERO_UNIT;
double t1 = Double.MAX_VALUE;
double imin, imax, iymin, iymax, izmin, izmax;
if (dirX >= ZERO_UNIT) {
imin = (minX - originX) * divX;
imax = (maxX - originX) * divX;
} else {
imin = (maxX - originX) * divX;
imax = (minX - originX) * divX;
}
if (dirY >= ZERO_UNIT) {
iymin = (minY - originY) * divY;
iymax = (maxY - originY) * divY;
} else {
iymin = (maxY - originY) * divY;
iymax = (minY - originY) * divY;
}
if ((imin > iymax) || (iymin > imax)) {
return null;
}
if (iymin > imin) {
imin = iymin;
}
if (iymax < imax) {
imax = iymax;
}
if (dirZ >= ZERO_UNIT) {
izmin = (minZ - originZ) * divZ;
izmax = (maxZ - originZ) * divZ;
} else {
izmin = (maxZ - originZ) * divZ;
izmax = (minZ - originZ) * divZ;
}
if ((imin > izmax) || (izmin > imax)) {
return null;
}
if (izmin > imin) {
imin = izmin;
}
if (izmax < imax) {
imax = izmax;
}
if ((imin >= t1) || (imax <= t0)) {
return null;
}
// check this baby and see if both objects represent an intersection:
Location intersection = origin.add(dir.multiply(imin));
return intersection;
}

I'm not sure if this works. But I thought about using the BlockPlaceEvent and check when the Block is placed if the Player is looking at that block.
#EventHandler
public void blockplace(BlockPlaceEvent event){
Player p = event.getPlayer();
int x = p.getLocation().getDirection().getBlockX();
int y = p.getLocation().getDirection().getBlockY();
int z = p.getLocation().getDirection().getBlockZ();
Location lookingLoc = new Location(p.getWorld(),x,y,z);
if (!event.getBlockPlaced().getLocation().equals(lookingLoc)){
//flag player...
}
}
Feel free to leave recommendations.

I read the question a couple times to be sure. If I understand the premise,
you wish to verify when an interaction occurs that the player is
looking at the block being interacted with. I take it that you want to prevent "auto-build" mods or
the like that may fake such events.
The validation should be straightforward using Player.getTargetBlock().
If the block returned by getTargetBlock() is the same as that reported
by PlayerInteractEvent you should be reasonably confident that the player is
looking at the block.

Related

A* Pathfinding problems Processing(Java)

I'm quite new to programming though following a bunch of tutorials I've ended up with this code to deal with the pathfinding of a small game I'm trying to make.
If works for small and straight paths but not for complex routes (it freezes and closedSet.size() gets larger than 70000 in a grid that is only 54 * 46).
Note that wall is true depending on the height of the colliding tiles, so it may be true coming from a point but false coming from another. Is that the problem?
import java.util.*;
int heuristic(int x,int y,int x_,int y_){
int dstX = abs(x - x_);
int dstY = abs(y - y_);
if(dstX > dstY){
return 14*dstY + 10*(dstX - dstY);
}else{
return 14*dstX + 10*(dstY - dstX);
}
}
boolean wall(int x, int y, int x_, int y_){
Tile tileS = getTile(x, y);
Tile tileCurr = getTile(x_, y_);
if(abs(tileS.altitude - tileCurr.altitude) > 1 || tileS.altitude < 1){
return true;
}else{
return false;
}
}
ArrayList<PVector> findPath(int startx, int starty, int endx, int endy){
Queue<Spot> openSet = new PriorityQueue<Spot>(fComparator);
ArrayList<Spot> closedSet = new ArrayList<Spot>();
Spot start = new Spot(startx, starty);
Spot end = new Spot(endx, endy);
Spot current = start;
openSet.add(start);
while(!openSet.isEmpty()){
current = openSet.poll();
closedSet.add(current);
println(closedSet.size());
if (current.x == end.x && current.y == end.y) {
break;
}
ArrayList<Spot> successors = new ArrayList<Spot>();
for(int i = 0; i < collidingTiles.size(); i++){
JSONObject difference = collidingTiles.getJSONObject(i);
/*JSONArray such as
[{x: -1, y: -1},{x: 0, y: -1},...](not including {x:0, y:0})
*/
int x_ = difference.getInt("x");
int y_ = difference.getInt("y");
int x = x_ + current.x;
int y = y_ + current.y;
if(x >= 0 && x <= map.columns && y >= 0 && y <= map.rows){
Spot s = new Spot(x, y);
successors.add(s);
}
}
for(Spot s: successors){
if (!closedSet.contains(s) && !wall(s.x, s.y, current.x, current.y)) {
int tempG = current.g + heuristic(s.x, s.y, current.x, current.y);
if(tempG < s.g || !openSet.contains(s)){
s.g = tempG;
s.h = heuristic(s.x, s.y, end.x, end.y);
s.f = s.g + s.h;
s.parent = current;
if (!openSet.contains(s)) {
openSet.add(s);
}
}
}
}
successors.clear();
}
ArrayList<PVector> path = new ArrayList<PVector>();
Spot temp = current;
PVector tile = new PVector(temp.x + 0.5, temp.y + 0.5);
path.add(tile);
while (temp.parent != null) {
tile = new PVector(temp.parent.x + 0.5, temp.parent.y + 0.5);
path.add(0, tile);
temp = temp.parent;
}
return path;
}
class Spot{
int x, y;
int f, g, h = 0;
Spot parent;
Spot(int x_, int y_){
x = x_;
y = y_;
}
}
Comparator<Spot> fComparator = new Comparator<Spot>() {
#Override
int compare(Spot s1, Spot s2) {
return s1.f - s2.f;
}
};
Any recommendations or minor changes are also appreciated.
closedSet.size() gets larger than 70000 in a grid that is only 54 * 46
Your code does implement some logic that says
"if a node is closed, don't process it again", and
"if the node is already in the open set, compare G scores"
But in both cases it does not work, because Spot does not implement equals, and therefore contains is comparing for reference equality and it will always be false. So, implement Spot.equals. Specifically, make it compare only x and y, because f/g/h/parent are allowed to be different for nodes that are considered equal for this purpose.
Even when it works, using contains on an ArrayList and a PriorityQueue is not so good for performance. For the closed list, it is easy to use a HashSet (of course, also implement Spot.hashCode, in some way that depends only on x and y). For the open list, getting rid of slow contains is more work. One trick you can use is manually maintaining a binary heap, and additionally have a HashMap which maps an x,y pair to the index in the heap where the corresponding node is located. The reason for manually maintaining a heap is that the HashMap must be updated whenever nodes are moved in the queue, and the normal PriorityQueue does not have such functionality.
The way that finding successors works also worries me from a performance perspective, but I cannot see the details.
Note that wall is true depending on the height of the colliding tiles, so it may be true coming from a point but false coming from another. Is that the problem?
That's fine, A* can tolerate a spot being reachable from one side but not an other. What it cannot natively take into account is if the direction a spot was reached from affects which successors that node has, but that does not happen here.

plotting points along a straight line from a random start position

I am looking for some help with some game code i have inherited from a flight sim. The code below simulates bombs exploding on the ground, it works fine but i am trying to refine it.
At the moment it takes a random value for x and y as a start point and then adds another random value between -20 and 20 to this. It works ok, but doesn't simulate bombs dropping very well as the pattern does not lay along a straight line/
What i would like to achieve though is all x and y points after the first random values, to lay along a straight line, so that the effects called for all appear to lay in a line. It doesn't matter which way the line is orientated.
Thanks for any help
slipper
public static class BombUnit extends CandCGeneric
{
public boolean danger()
{
Point3d point3d = new Point3d();
pos.getAbs(point3d);
Vector3d vector3d = new Vector3d();
Random random = new Random();
Aircraft aircraft = War.GetNearestEnemyAircraft(this, 10000F, 9);
if(counter > 10)
{
counter = 0;
startpoint.set(point3d.x + (double)(random.nextInt(1000) - 500), point3d.y + (double)(random.nextInt(1000) - 500), point3d.z);
}
if(aircraft != null && (aircraft instanceof TypeBomber) && aircraft.getArmy() != myArmy)
{
World.MaxVisualDistance = 50000F;
counter++;
String s = "weapon.bomb_std";
startpoint.x += random.nextInt(40) - 20;
startpoint.y += random.nextInt(40) - 20;
Explosions.generate(this, startpoint, 7F, 0, 30F, !Mission.isNet());
startpoint.z = World.land().HQ(startpoint.x, startpoint.y);
MsgExplosion.send(this, s, startpoint, getOwner(), 0.0F, 7F, 0, 30F);
Engine.land();
int i = Landscape.getPixelMapT(Engine.land().WORLD2PIXX(startpoint.x), Engine.land().WORLD2PIXY(startpoint.y));
if(firecounter < 100 && i >= 16 && i < 20)
{
Eff3DActor.New(null, null, new Loc(startpoint.x, startpoint.y, startpoint.z + 5D, 0.0F, 90F, 0.0F), 1.0F, "Effects/Smokes/CityFire3.eff", 300F);
firecounter++;
}
super.setTimer(15);
}
return true;
}
private static Point3d startpoint = new Point3d();
private int counter;
private int firecounter;
public BombUnit()
{
counter = 11;
firecounter = 0;
Timer1 = Timer2 = 0.05F;
}
}
The code in the question is a mess, but ignoring this and trying to focus on the relevant parts: You can generate a random position for the first point, and a random direction, and then walk along this direction in several steps.
(This still raises the question of whether the direction is really not important. Wouldn't it matter if only the first bomb was dropped in the "valid" area, and the remaining ones outside of the screen?)
However, the relevant code could roughly look like this:
class Bombs
{
private final Random random = new Random(0);
int getScreenSizeX() { ... }
int getScreenSizeY() { ... }
// Method to drop a single bomb at the given position
void dropBombAt(double x, double y) { ... }
void dropBombs(int numberOfBombs, double distanceBetweenBombs)
{
// Create a random position in the screen
double currentX = random.nextDouble() * getScreenSizeX();
double currentY = random.nextDouble() * getScreenSizeY();
// Create a random step size
double directionX = random.nextDouble();
double directionY = random.nextDouble();
double invLength = 1.0 / Math.hypot(directionX, directionY);
double stepX = directionX * invLength * distanceBetweenBombs;
double stepY = directionY * invLength * distanceBetweenBombs;
// Drop the bombs
for (int i=0; i<numberOfBombs; i++)
{
dropBombAt(currentX, currentY);
currentX += stepX;
currentY += stepY;
}
}
}
I am assuming your startpoint is a StartPoint class with x,y,z coordinates as integers in it.
I hope I have understood your problem correctly. It looks like you either want to create a vertical explosion or a horizontal explosion. Since an explosion always occurs on ground, the z coordinate will be zero. Now you can vary one of x or y coordinate to give you a random explosion along a straight line. Whether you choose x or y could be fixed or could be randomized itself. A potential randomized solution below:
public boolean danger() {
// stuff
int orientation = Random.nextInt(2);
if(aircraft != null && (aircraft instanceof TypeBomber) && aircraft.getArmy() != myArmy)
{
// stuff
startPoint = randomizeStartPoint(orientation, startPoint);
// stuff
}
}
StartPoint randomizeStartPoint(int orientation, StartPoint startPoint) {
if(orientation == 0) {
startPoint.x += random.nextInt(40) - 20;
}
else {
startPoint.y += random.nextInt(40) - 20;
}
return startPoint;
}
In response to the image you uploaded, it seems that the orientation of the explosion need not necessarily be horizontal or vertical. So the code I posted above gives a limited solution to your problem.
Since you want any random straight line, your problem boils down to two sub parts:
1. Generate a random straight line equation.
2. Generate random point along this line.
Now, a straight line equation in coordinate geometry is y = mx + c where m is the slope and c is the constant where the line crosses the y-axis. The problem with c is that it gives rise to irrational coordinates. I am assuming you are looking for integer coordinates only, since this will ensure that your points are accurately plotted. (You could do with rational fractions, but then a fraction like 1/3 will still result in loss of accuracy). The best way to get rid of this irrational problem is to get rid of c. So now your straight line always looks like y = mx. So for step one, you have to generate a random m.
Then for step 2, you can either generate a random x or random y. It doesn't matter which one, since either one will result in random coordinates.
Here is a possible code for the solution:
int generateRandomSlope() {
return Random.nextInt(100); // arbitrarily chose 100.
}
int randomizeStartPoint(int m, StartPoint startPoint) { // takes the slope we generated earlier. without the slope, your points will never be on a straight line!
startPoint.x += random.nextInt(40) - 20;
startPoint.y += x * m; // because a line equation is y = mx
return startPoint;
}
public boolean danger() {
// stuff
int m = generateRandomSlope(); // you may want to generate this elsewhere so that it doesn't change each time danger() is called.
if(aircraft != null && (aircraft instanceof TypeBomber) && aircraft.getArmy() != myArmy)
{
// stuff
startPoint = randomizeStartPoint(m, startPoint);
// stuff
}
}
Again, this is not a complete or the best solution.

Android Game Logic - Obsticles

I have been working on android apps for a long time but now I have decided to create a game aside with my pre-calculus final. I have completed the whole code and it works perfectly except one tiny issue. First of the game is based on flying pig(my classmate's face) avoiding top and bottom osticle. I developed an algorithm so that the obsticles are evenly spaced and based on random selection placed either as the top or bottom of the screen but never both at the same time!. The algorithm that needs improvement is in the 3rd code segment!
This is the screenshot of the problem: screenshot here
(My account is new so stackoverflow wont let me to share photos directly)
This is the class that calls updates for all dynamic objects (ship = pig, bacon = bonus item, BM = BarrierManager class's update() which updates the obsticles)
//this will update the resources
void Update(float dt) {
ship.update(dt);
//bumbing
if (!ship.death) {
background.update(dt);
**BM.update(dt);**
for (int i = 0; i % 5 == 0; i++) {
bacon.update(dt, BM.position);
}
}
ArrayList<Point> bacon_point = new ArrayList<Point>(bacon.getArray());
if (ship.bump(bacon_point.get(0), bacon_point.get(1), bacon_point.get(2), bacon_point.get(3))) {
bacon.setX(-200);
bacon.setY(-200);
Message msg = BM.game_panel.game.handler.obtainMessage();
msg.what = 0;
BM.game_panel.game.handler.sendMessage(msg);
}
for (int i = 0; i < BM.TopWalls.size(); i++) {
ArrayList<Point> temp = new ArrayList<Point>(BM.TopWalls.get(i).getArray());
//after we have accest the TopWalls arraylist we can call bump that check TopWalls object's points position with the pig's points
ArrayList<Point> temp2 = new ArrayList<Point>(BM.BottomWalls.get(i).getArray());
//after we have accest the TopWalls arraylist we can call bump that check BottomWalls object's points position with the pig's points
if ((ship.bump(temp.get(0), temp.get(1), temp.get(2), temp.get(3))) || (ship.bump(temp2.get(0), temp2.get(1), temp2.get(2), temp2.get(3))) || ship.death) {
ship.death = true;
game.onStop();
while(f==0) {
MediaPlayer mp = MediaPlayer.create(game, R.raw.explosion_fart);
mp.start();
f++;
}
f++;
Message msg = BM.game_panel.game.handler.obtainMessage();
msg.what = 1;
BM.game_panel.game.handler.sendMessage(msg);
i = BM.TopWalls.size()-1;
if(f == 8){
thread.setRunning(false);
}
}
}
}
In the BarrierManager I have created this update method which takes float dt = MainTheards general time for the game.
TopWalls is ArrayList this ArrayList is composed of top obsticles. Bottom walls is the same but BottomWalls.
//zreb decides if it should create TopWalls or BottomWalls object. This parameter is later transfered to the Barier.update method where I work with it
public void update(float dt){
for (int i=0;i<Num+1; i++) {
int zreb = new Random().nextInt(2);
//{if} to make the spacing bigger
if (i % 5 == 0){
**TopWalls.get(i).update(dt, true, zreb);
BottomWalls.get(i).update(dt, false, zreb);**
if(zreb == 0){
position.set(TopWalls.get(i).getX(), TopWalls.get(i).getY());
}
else{
position.set(BottomWalls.get(i).getX(),BottomWalls.get(i).getY());
}
}
}
}
Now this algoritm in the Barrier.class is where the magic went wrong. This update method takes the float dt mentioned earlier, a boolean variable for determining if the obsticle we work with at that instance is the Top or Bottom, and the zreb random int that determines if the top or bottom obsticle is going to be shown.
//problem! needs to be discussed
public void update(float dt, boolean b, int zreb) {
//checking if the barrier is still there
if (x<-bitmap.getWidth()){
//'b'is passed from the Barriermanager - 'update' method, determining if we have to use monkey-true or farmer-false
int raz = 200;
int vyska = BM.dpos;
//'zreb' helps me to randomly determine if monkey or ballard is going to appear
//here it determines if we are going to have Top or Bottom obsticle in the game
if(zreb == 1) {
vyska = BM.dpos - raz;
}
else {
vyska = BM.dpos + raz;
}
//koniec tohto trienedia
if (b)
{
//setting the y value for the top wall
y = vyska - BM.dl/2 - bitmap.getHeight()/2;
}
else{
//setting the y value for bottom wall
y = vyska + BM.dl/2 + bitmap.getHeight()/2;
}
//setting x-value
x = (int) (x +bitmap.getWidth()*(BM.TopWalls.size()-1));
}
x = (int) (x - BM.game_panel.ShipSpeed*dt);
}
Do you have any idea why this "one-or-the-other" condition is not working properly?
This would help me lot because this error made me deactivate the app from the store.

How can I effectively implement collision for a 2D game?

I just started a new 2D game using Java, LWJGL, and Slick Util but I can't seem to figure out a good way to make collision detection.
If I wanted to, it would be easy to detect collision between 2 entities with the Rectangle intersect method, but it can only check the collision with a certain area you specify.
I have thought that I could make a list of every entity and its coordinates as its created and then run the intersect method through the list, but then it would check for collision with every entity on the entire map for every time the game updated and I think that would be too inefficient.
Does anyone know a more efficient way to create collision detection? If there was some way i could check if there was an entity at every point the character moved that would probably be the best.
If I have not enough information or I made this sound too confusing please tell me and I can try to clarify things. Also as a side question, what are the benefits of using slick util or slick 2D over one another. Thanks for the help!
The usual way to solve this is a scene graph, a hierarchical system of the objects of the game world.
You might want to look at this and this.
Shortened: you logically group your objects under nodes and assign the nodes a bounding rectangle that encompasses all its sub-nodes and leaves(objects). Everything is grouped again under one main node to access the tree. Now you can test a object for collision with a node, usually starting from the main node. If you get a hit you check its sub-nodes and leaves.
This will take some time to implement but can cut down on CPU usage if the tree structure/grouping is done right. It has also the benefit that you can implement local transforms which makes moving objects relative to each other easier.
Because I hate "The usual way", I made an array of all the coordinates and then checked if a single point hit the coordinate.
Here is a slight modification of my code to demonstrate (It is in 3D):
for (CannonBall can : GameServer.ballss){ //Go through all cannonballs
if (can.owner != cl){ //Can.owner is the ship, cl is the player the cannonball is being checked with to see if colliding.
int distancex = (int) (can.x - cl.z);
int distancez = (int) (can.z - cl.x);
final int distancey = (int) (can.y - cl.y);
double xRot = Math.cos(Math.toRadians(cl.rotation)) * (distancex - 0) - Math.sin(Math.toRadians(cl.rotation)) * (distancez - 0) + 0;
double zRot = Math.sin(Math.toRadians(cl.rotation)) * (distancex - 0) - Math.cos(Math.toRadians(cl.rotation)) * (distancez - 0) + 0;
distancex = (int) xRot;
distancez = (int) zRot;
try{
if (true){ //Skip different coordinates for different ships for demonstration purposes
i = GameServer.coords[GameServer.DELTA + distancex][GameServer.DELTA + distancez][GameServer.DELTA + (distancey)];
}
if (i == 1){
if (can.owner != cl){
remcan.add(can);
if (can.type == 0){
double damage = (100 + Math.random()*25);
if (cl.type == 1){
damage/=2;
}
if (cl.type == 2){
damage*=2;
}
cl.damage-=damage;
}
if (can.type == 1){
double damage = (Math.random() * 500);
if (cl.type == 1){
damage/=2;
}
if (cl.type == 2){
damage*=2;
}
cl.damage-=damage;
}else{
double damage = (100 + Math.random()*25);
if (cl.type == 1){
damage/=2;
}
if (cl.type == 2){
damage*=2;
}
cl.damage-=damage;
}
crash = true;
if (cl.damage < 1){
if (!cl.sinking){
cl.sinking = true;
}
}
}
}
}catch (Exception e){
e.printStackTrace();
}
}
GameServer.coords is an int[][][], which is given coordinates like so:
public static int[][][] coords;
public void CollisionSetup(){
try{
File f = new File("res/coords.txt");
String coords = readTextFile(f.getAbsolutePath());
for (int i = 0; i < coords.length();){
int i1 = i;
for (; i1 < coords.length(); i1++){
if (String.valueOf(coords.charAt(i1)).contains(",")){
break;
}
}
String x = coords.substring(i, i1).replace(",", "");
i = i1;
i1 = i + 1;
for (; i1 < coords.length(); i1++){
if (String.valueOf(coords.charAt(i1)).contains(",")){
break;
}
}
String y = coords.substring(i, i1).replace(",", "");;
i = i1;
i1 = i + 1;
for (; i1 < coords.length(); i1++){
if (String.valueOf(coords.charAt(i1)).contains(",")){
break;
}
}
String z = coords.substring(i, i1).replace(",", "");;
i = i1 + 1;
//buildx.append(String.valueOf(coords.charAt(i)));
////System.out.println(x);
////System.out.println(y);
////System.out.println(z);
//x = String.valueOf((int)Double.parseDouble(x));
//y = String.valueOf((int)Double.parseDouble(y));
//z = String.valueOf((int)Double.parseDouble(z));
double sx = Double.valueOf(x);
double sy = Double.valueOf(y);
double sz = Double.valueOf(z);
javax.vecmath.Vector3f cor = new javax.vecmath.Vector3f(Float.parseFloat(x), Float.parseFloat(y), Float.parseFloat(z));
//if (!arr.contains(cor)){
if (cor.y > 0)
arr.add(new javax.vecmath.Vector3f(cor));
if (!ship.contains(new Vector3f((int) sx, (int) sy, (int) sz)))
ship.add(new Vector3f((int) sx, (int) sy, (int) sz));
Float.parseFloat(z)));
}
}
public void setUpPhysics() {
//coords = new int[20][20];
coords = new int[80][80][80];
coords1 = new int[80][80];
//coords[-5 + DELTA][7 + DELTA] = 11;
for (javax.vecmath.Vector3f vec : arr){
coords[DELTA+(int) vec.x][DELTA+(int) vec.z][DELTA + (int) vec.y] = 1; //This is line 124
coords1[DELTA+(int) vec.x][DELTA+(int) vec.z] = 1;
}
}
Though it has limitations on collision interaction, it works for cannonballs colliding with a ship and checking the front of a ship to see if it has hit another ship. Also, it uses barely any CPU.
No idea on the opinions of other programmers on such a method.

Unable to use my method with Slick library

So I made a java game with jumping some time ago and I used this method for all the moving:
double height = 0, speed = 4;
public static final double gravity = 9.81;
double x = 25;
int a;
int y = (int) (500-(height*100));
boolean left = false, right = false, up = false;
public void the_jump() {
long previous = 0, start = 0;
while(true){
start = System.nanoTime();
if(previous != 0 && up){
double delta = start - previous;
height = (height + (delta/1000000000) * speed);
speed -= (delta/1000000000) * gravity;
y = (int) (500-(height * 100));
}
if(left){
x-= 3;
}
if(right){
x+= 3;
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(height < 0){
height = 0;
speed = 4;
up = false;
}
previous = start;
}
}
Now It was okay when I did it all with just JComponents and such, but now when I want to implement it in a Slick enviroment, it fails.
The problem is in the while(true){} loop. If I change it against for(int i = 0; i < 1; i++) loop, then moving left and right will work. But this will not work for the jumping. I could increase the i < 1 to i < 5 and then the jump will work, but at the cost of a lot of performance.
So how would people implement this in slick? Right now I am calling the the_jump(); out in my public void update(GameContainer gc, int t) throws SlickException method, and if I use the while loop, the game will crash.
Slick already loop on update(GameContainer gc, int delta), you have to put all the code located in your while loop into the update method.
Moreover, you get the delta time between two update as parameter, and so not have to calculate it.
Feel free to ask me more question ;)
Off Topic, do you know if Slick2d is still maintain ? I switch to libGDX a few month ago, and I really advice you to test it, it's soooo fun :)

Categories