Reputation: 331
Ok so I have been experimenting with java for a few weeks now, following both in class, and online tutorials. I made a simple game where squares fall towards the bottom of the screen, while the player controls a small ball, only moving on the x-axis and trys to avoid them.
The problem that I am having is that the squares start out falling too fast. Right now I have them set as follows:
ix = 0;
iy = 1;
Then in my move() method, I have the following:
hitbox.x += ix;
hitbox.y += iy;
In this example, ix and iy are both integers.
My first assumption was to change the ints to floats, then use:
ix= 0;
iy = 0.5;
and then:
hitbox.x += ix;
hitbox.y += 0.5f;
But this just freezes the objects in their tracks . I believe that this is because cords are taken as integers, so I figured that if I modified my getX() and getY() methods, maybe I could manipulate them somehow to use decimal numbers? But I am not quite sure how to. Any help/hints/solutions to this problem would be Greatly appreciated.
Here is some revelent code, let me know if anymore is needed!
Enemy Manager:
public class EnemyManager {
private int amount;
private List<Enemy> enemies = new ArrayList<Enemy>();
private GameInJavaOne instance;
public EnemyManager(GameInJavaOne instance, int a){
this.amount = a;
this.instance = instance;
spawn();
}
private void spawn(){
Random random = new Random();
int ss = enemies.size();
// If the current amount of enemies is less than the desired amount, we spawn more enemies.
if(ss < amount){
for(int i = 0; i < amount - ss; i++){
enemies.add(new Enemy(instance, random.nextInt(778), random.nextInt(100)+1));
}
// If its greater than the desired number of enemies, remove them.
}else if (ss > 20){
for(int i = 0; i < ss - amount; i++){
enemies.remove(i);
}
}
}
public void draw(Graphics g){
update();
for(Enemy e : enemies) e.draw(g);
}
private void update() {
boolean re = false;
for(int i = 0; i < enemies.size(); i ++){
if(enemies.get(i).isDead()){
enemies.remove(i);
re = true;
}
}
if(re) spawn();
}
public boolean isColliding(Rectangle hitbox){
boolean c =false;
for(int i = 0; i < enemies.size(); i ++){
if(hitbox.intersects(enemies.get(i).getHitbox())) c = true;
}
return c;
}
}
Entity:
public abstract class Entity {
protected int x, y, w, h;
protected boolean removed = false;
public Entity(int x, int y){
this.x = x;
this.y = y;
}
public void Draw(Graphics g){
}
public int getX() { return x; }
public int getY() { return y; }
public int getH() { return h; }
public int getW() { return w; }
}
and the enemy class:
public class Enemy extends Entity{
private Rectangle hitbox;
private int ix, iy;
private boolean dead = false;
private GameInJavaOne instance;
public Enemy(GameInJavaOne instance, int x, int y){
super(x, y);
this.instance = instance;
hitbox = new Rectangle(x, y, 32, 32);
ix = 0;
iy = 1;
}
private void move(){
if(instance.getStage().isCollided(hitbox)){
iy =0;
dead = true;
}
hitbox.x += ix;
hitbox.y += iy;
}
public boolean isDead() {return dead;}
public Rectangle getHitbox() {return hitbox; }
public void draw(Graphics g){
move();
g.setColor(Color.MAGENTA);
g.fillRect(hitbox.x, hitbox.y, hitbox.height, hitbox.width);
}
}
Upvotes: 1
Views: 1008
Reputation: 17226
You are using a Rectangle
class to represent the position of your box (even though you call it the hitbox), Rectangle
does indeed have members x
and y
which are integers and so when you call
rectangle.x+=0.5f;
What you are really calling is rectangle.x+=(int)0.5f;
and (int)0.5f==0
.
The Rectangle
class is simply inappropriate for holding the position of the box if you want float precision. Consider holding the box's real position as a double or float and casting to int to render it.
So your rendering code would become;
g.fillRect((int)positionX,(int)positionY, hitbox.height, hitbox.width);
where positionX
and positionY
are doubles. (You could also use Vector2d
if you'd prefer to keep x
and y
together)
Entity
class with x
,y
,w
and h
and yet never use them, this seems dangerous, why are you extending Entity
but recreating your own positional code.Upvotes: 1