Game collision detection between many objects? - java

I'm trying to understand how to implement collision detection between multiple object.
My project detects the collision between the objects but it crashes immediately after.
This is my main class with the JFrame and Main Loop:
public class Window {
public static void main(String[] args){
GamePanel gamepanel = new GamePanel();
JFrame f = new JFrame("Multiple Collision Detection");
f.setSize(400, 400);
f.add(gamepanel);
f.setVisible(true);
f.setResizable(false);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLocationRelativeTo(null);
while(true){
gamepanel.repaint();
gamepanel.update();
try{
Thread.sleep(10);
}catch(Exception e){
System.out.println("Main Loop Error");
}
}
}
}
Then i have two classes, one for the player and one for the enemy:
PLAYER:
public class Player {
int x = 175, y = 175, w = 50, h = 50, dx = 0, dy = 0;
Rectangle rect;
public void paint(Graphics g) {
rect = new Rectangle(x, y, w, h);
g.setColor(Color.black);
g.fillRect(rect.x, rect.y, rect.width, rect.height);
g.setColor(Color.CYAN);
g.drawRect(x, y, w, h);
}
public void setDx(int dx) {
this.dx = dx;
}
public void setDy(int dy) {
this.dy = dy;
}
public void move() {
x += dx;
y += dy;
}
public void update() {
move();
}
}
ENEMY:
public class Enemy {
int x, y, w = 35, h = 35;
Rectangle rect;
public Enemy(int x, int y) {
this.x = x;
this.y = y;
}
public void paint(Graphics g) {
rect = new Rectangle(x, y, w, h);
g.setColor(Color.red);
g.fillRect(rect.x, rect.y, rect.width, rect.height);
}
public void update() {
}
}
I've the EnemyManager class that draws more than one enemy (in this case 3) through a List:
public class EnemyManager {
Player player = new Player();
Rectangle playerrect;
Rectangle enemyrect;
List<Enemy> enemies = new ArrayList<Enemy>();
public void paint(Graphics g) {
enemies.add(new Enemy(20, 20));
enemies.add(new Enemy(320, 20));
enemies.add(new Enemy(20, 320));
for (Enemy e : enemies) {
e.paint(g);
}
}
public void update() {
}
}
Finally i've the GamePanel class that draws the Graphics from the other classes (Player and EnemyManager):
public class GamePanel extends JPanel implements KeyListener{
Player player = new Player();
EnemyManager enemymanager = new EnemyManager();
public void paint(Graphics g){
g.setColor(Color.LIGHT_GRAY);
g.fillRect(0, 0, 400, 400);
player.paint(g);
enemymanager.paint(g);
}
public void checkPlayerEnemyCollision(){
for(Enemy e : enemymanager.enemies){
if(e.rect.intersects(player.rect)){
System.out.println("Collision");
}
}
}
public void update(){
addKeyListener(this);
setFocusable(true);
player.update();
enemymanager.update();
checkPlayerEnemyCollision();
}
#Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_W){
player.setDy(-2);
}
if(e.getKeyCode() == KeyEvent.VK_S){
player.setDy(2);
}
if(e.getKeyCode() == KeyEvent.VK_A){
player.setDx(-2);
}
if(e.getKeyCode() == KeyEvent.VK_D){
player.setDx(2);
}
if(e.getKeyCode() == KeyEvent.VK_ESCAPE){
System.exit(0);
}
}
#Override
public void keyReleased(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_W){
player.setDy(0);
}
if(e.getKeyCode() == KeyEvent.VK_S){
player.setDy(0);
}
if(e.getKeyCode() == KeyEvent.VK_A){
player.setDx(0);
}
if(e.getKeyCode() == KeyEvent.VK_D){
player.setDx(0);
}
}
}
When the game detects a collision between the player and an enemy, it prints "Collision" to the console but after that it crashes with this error:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at GamePanel.checkPlayerEnemyCollision(GamePanel.java:22)
at GamePanel.update(GamePanel.java:34)
at Window.main(Window.java:20)
Anyone knows what is the problem and maybe how to solve it?
Thanks in advance.

paint is called from the event dispatcher thread. You modify the list in this method
event dispatcher thread
-> GamePanel.paint
-> EnemyManager.paint
-> enemies.add
However you use a iterator of the list through the "foreach" loop in GamePanel.checkPlayerEnemyCollision:
for(Enemy e : enemymanager.enemies)
But the iterator of ArrayList fails, if you modify the list after the iterator is created with the exception you got.
Since the list modification and the iterator can are used from different threads they can easyly interfere, e.g.:
main thread creates iterator
main thread reads a few elements
event dispatcher thread calls paint
event dispatcher thread adds Enemy to list
main thread calls tries to get a element from the iterator -> exception
Your design is a bit flawed:
You have little control, when paint is called and as the method name suggests it's used for painting. Don't change the data in this method, just draw it.
Redesign your program keeping that in mind (maybe read a tutorial first, e.g. this one).
You will still need to read the Enemy list from a different thread than the one that modifies the list. Use the get method of the list instead of the iterator and keep in mind, that the list size can change so you will need to synchronize things a bit. This could be done effectively, if the threads "reserve" a specific index range that they are allowed to access.

I tried your program but couldn't get anything to move, using the keys A, W, S, D. However, I do get a concurrent mod exception like you said, right at the point of a for loop.
Try changing all enhanced loops to normal for loops. For example, in the part
for (Enemy e : enemies) {
e.paint(g);
}
change to:
for (int i = 0; i < enemies.size(); i++)
enemies.get(i).paint(g);
After doing this, I didn't get the error any longer.
Enhanced for loops give you error if you do certain things to an array at certain times. But I'm not sure why in this case, because I'm not too familiar with how graphics work behind the scenes in Java.

You're getting the ConcurrentModificationException, which means you're attempting to modify a collection in one thread while iterating over it in another (this can also happen within a single thread if you attempt to modify the collection while iterating, but that's not what's happening here).
This all stems from the fact you're not paying attention to which thread your events are happening in. You've got two active threads, whether you realize it or not.
Thread #1 is the programs Main thread, which is where the app starts from
Thread #2 is the Swing EDT, where all of your user actions initiate from.
It looks like you're trying to update your domain model from the Main thread while iterating over collections from the Swing EDT. You either need to synchronize access or make all your updates perform on the EDT by wrapping it in an invoke later:
SwingUtilities.invokeLater(new Runnable(){
public void run(){
gamepanel.repaint();
gamepanel.update();
}
});
Note that I don't know that simply using the above snippet in a loop+Thread.sleep is the correct action in this case, as I haven't gone through all your logic. At the very least you should read a tutorial on Swing threading.

Related

Having trouble making object move without flickering in Java

I have looked into Double Buffering and plan on implementing it eventually but as of right now I can't figure out how to use it or anything like it. I am trying to make pong so I plan on adding three objects total but for now I just want to get one object to work smoothly. I'm fairly new to graphics so I don't know entirely what I'm doing and I'm just trying to learn as I go.
Here is my code:
Pong:
public static void main(String[]args) {
JFrame window= new JFrame();
window.setTitle("Pong Game");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setPreferredSize(new Dimension(800,500));
window.pack();
window.setVisible(true);
Ball ball= new Ball();
Paddle player= new Paddle();
window.getContentPane().add(ball);
for(;;) {
ball.move();
//window.setContentPane(ball);
window.setContentPane(player);
player.move();
}
}
Paddles:
double x, y, ymove;
boolean cpu;
public Paddle() {
x=5;
y=180;
ymove=.1;
}
//passing an integer through to make the computer paddle
public Paddle(int a) {
cpu= true;
x=761;
y=180;
ymove=.1;
}
public void paint(Graphics g) {
g.setColor(Color.blue);
g.fillRect((int)x, (int)y, 18, 120);
}
public void move() {
y+=ymove;
if(y>=500-160||y<=0) {
ymove*=-1;
}
}
Ball:
double x, y, xspeed, yspeed;
public Ball() {
x=200;
y=200;
xspeed=0;
yspeed=.1;
}
public void move() {
x+=xspeed;
y+=yspeed;
if(y>=440||y<=0) {
yspeed*=-1;
}
}
public void paint(Graphics g) {
g.setColor(Color.black);
g.fillOval((int)x, (int)y, 20, 20);
}
This Answer is a very very simplified explanation! I recommend checking out this linux journal, which explores something similia.
The main issue, which causes the "flickering" is, that the draw is done "to fast".
Take your main loop:
for(;;) {
ball.move();
window.setContentPane(ball);
window.setContentPane(player);
player.move();
}
This loop updates the positions of the ball and afterwards "adds it to the content pane". While it is drawn, the next image is already added and drawn. This is causing the flickering (again, note: this is very simplified).
The simplest solution to fix the "flickering" is, to let the Thread sleep after it has drawn and "wait" until the draw is finished.
boolean running = true;
int delay = 15; // adjust the delay
while(running) {
ball.move();
player.move();
window.setContentPane(ball);
window.setContentPane(player);
try {
Thread.sleep(delay);
} catch(InterruptedException e) {
// We were interrupted while waiting
// Something "woke us up". Stop the loop.
e.printStackTrace();
running = false;
}
}
This Thread.sleep method let's the current Thread "wait" for the specified time.
The delay can be adjusted to something more practical. You could for example calculate how many frames you want and sleep for that amount.
Another way would be to "time" the updates. This could be done with a timer. Since it is more or less deprecated, i implement it using the ScheduledExecutorService
int delay = 15; // adjust the delay
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool();
scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
public void run() {
ball.move();
player.move();
}
}, delay, TimeUnit.MILLISECONDS)
As of Java8, you might write this using a Lambda like this:
scheduledExecutorService.scheduleAtFixedRate(() -> {
ball.move();
player.move();
}, delay, TimeUnit.MILLISECONDS)
To stop it, you could now call:
scheduledExecutorService.shutdown();
However: There are more sophisticated solutions. One is, as you already noted, the double buffering. But there are also multiple different techniques, that compensate more difficult problems. They use something called page flipping.
The problem you are having is that you have split your paint methods,
if you make one class that is dedicated to doing the painting and you put all of your paints in one paint method it should work without flickering.
I would also recommend looking into making your paint calls run on a timer which lets you decide the refresh rate which usually leads to a smoother experience overall.
Here is an example of my graphics class in my latest game,
class GameGraphics extends JPanel implements ActionListener {
private Timer refreshHZTimer;
private int refreshHZ = 10;
private int frameID = 0;
public GameGraphics(int width, int height) {
setBounds(0,0, width, height);
setVisible(true);
refreshHZTimer = new Timer(refreshHZ, this);
refreshHZTimer.start();
}
#Override
public void actionPerformed(ActionEvent e) {
frameID++;
if (frameID % 100 == 1)
System.out.println("Painting FrameID: " + frameID);
repaint();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
//Init graphics
Graphics2D g2 = (Graphics2D) g;
//Paint stuff here:
}
}
And add this code to your JFrame constructor:
GameGraphics gpu = new GameGraphics(width, height);
frame.add(gpu);

Java 2D game: repaint

I am creating a very simple game for my homework and right now I am solving the following problem:
in this game when you click on the shape (for now it is just a circle) it should dissapear and render a new one somewhere else (you are collecting points when you hit that shapes, that´s the point) and my problem is in the mouseClicked method, i think. I put some control System.out.println() there and everytime when the program reach this method it displays as many prints as there was circles. I mean, if you click on the first circle it displays one print, if you click on the second circle it diplays two prints and so on. Can you help me pls? I just started with the swing and awt and I don´t have much time for thorough study. Thank you so much.
public class Shape extends JPanel implements ActionListener{
Graphics2D g2;
Ellipse2D circle;
Timer t = new Timer(2000, this);
int x, y, count;
JLabel counting;
public Shape(JLabel counting){
this.counting = counting;
}
public void paintComponent(Graphics g){
super.paintComponent(g);
g2 = (Graphics2D)g;
ListenForMouse lForMouse = new ListenForMouse();
addMouseListener(lForMouse);
Random ran = new Random();
int green = ran.nextInt(256);
int red = ran.nextInt(256);
int blue = ran.nextInt(256);
Color randomColor = new Color(green, red, blue);
int wid = ran.nextInt(101) + 50;
x = ran.nextInt(650);
if(x > wid)
x = x - wid;
y = ran.nextInt(600);
if(y > wid)
y = y - wid;
circle = new Ellipse2D.Double(x,y,wid,wid);
t.start();
g2.setColor(randomColor);
g2.fill(circle);
}
#Override
public void actionPerformed(ActionEvent arg0) {
repaint();
}
private class ListenForMouse implements MouseListener{
#Override
public void mouseClicked(MouseEvent e) {
System.out.println("Control before");
if(circle.contains(e.getPoint())){
count++;
counting.setText(Integer.toString(count));
t.stop();
repaint();
System.out.println("Control in");
}
System.out.println("Control out");
}
}
}
This happens, because you add a new mouse listener every time paintComponent is called. You should do this once, inside the constructor.

JAVA: background rendeing over the player?

I'm building my first very basic game in JAVA without using any other external libraries.
The problem I got is
You can see that the background is rendered over player how can I fix that
The player rendering code is as follows
#Override
public void render(Graphics g) {
int bulletcount = 0;
//render player
g.setColor(color);
g.fillRect(x,y,32,32);
if(shooting) {
handler.add(new bullet(x + 8, y - 24, ID.bullet, handler));
bulletcount++;
}
}
and the background render code is as follows.
public class background extends GameObject{
private int width;
private Random random = new Random();
public background(int x, int y , ID id,Handler handler){
super(x,y,id,handler);
valy = 2;
width = getWidth(x,800);
}
public void tick() {
y += valy;
if(y>650)
handler.remove(this);
}
public void render(Graphics g) {
g.setColor(Color.white);
g.fillRoundRect(x,y,width,10,1,1);
}
public int getWidth(int x,int width1){
int wid;
while(true){
if((width - x) > 35) {
wid = random.nextInt((width-x-35));
break;
}
else{
x -= 10;
}
}
return wid;
}
}
the main class of game can see the order of flow of execution.
private void render() {
// render the Game
BufferStrategy bs = this.getBufferStrategy();
if(bs == null)
{
this.createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
g.setColor(Color.black);
g.fillRect(0,0,WIDTH,HEIGHT);
handler.render(g);
hod.render(g); //handler is rendering every object in game
g.dispose();
bs.show();
}
private void tick() {
//update Game
handler.tick();
hod.tick();
spawner.tick(); // background is generating in spawner class.
}
I know that telling the problem with this much less code is hard for you all. But I have complete faith in this large and powerful community.
Thanks in advance. Don't hesitate to edit and point out my mistakes Thanks!
If I get the code right, the background is being generated after rendering the player which leads to the background being on top of the player. I would try calling spawner.tick() (where I guess the background is coming from given your code comment) before calling hod.tick(). Hopefully that should resolve this issue.
private void tick() { //update Game
spawner.tick();
handler.tick();
hod.tick();
}
I just had solution!
The problem was in handler.render(g); method:- which is a follows;
private void render(Graphics g){
for(int i =0; i<gameobj.size(); i++){//gameobj is linkedlist of GameObject
GameObject tempobj = gameobj.get(i);
tempobj.render(g);//getting every object and rendering them!
}
The problem was in loop the first object added in the game is player.So , it was getting render first after that the background was getting rendered.
It was a silly mistake.which got right by following change.->
private void render(Graphics g){
for(int i = gameobj.size()-1; i > 0; i--){//gameobj is linkedlist of GameObject
GameObject tempobj = gameobj.get(i);
tempobj.render(g);//getting every object and rendering them! from reverse
}
so, the last object renders first and the first object renders last.
Peace!

Issues with adding images to JFrames

I have been trying to load imageicons into a jframe. I have no idea why this code doesn't work. I have tried using jpanels and jlabels, and also other ways of loading images, but those don't work either. I think because of this it has something to do with my JFrame that I set up . I would like to stay away from jpanels and jlabels, because at least as far as my knowledge goes, they cannot be scaled. If anyone has a solution to adding the images, please tell me. here is the code:
import java.awt.Canvas;
import javax.swing.JFrame;
import java.awt.*;
import javax.swing.ImageIcon;
import java.awt.event.KeyEvent;
import java.awt.Graphics;
public class Base extends Canvas implements Runnable {
private static final long serialVersionUID = 001;
private Image rock1;
private Image rock2;
private Image wood1;
private Thread thread;
private boolean running = (false);
private boolean paused = (false);
int x = 0;
int y = 0;
int z = 512;
private void start() {
if (running)
return;
running = true;
thread = new Thread(this);
}
public void run(){}
public Base(){}
public static void main(String[] Args) {
Base game = new Base();
JFrame frame = new JFrame();
frame.add(game);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800, 600);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setVisible(true);
frame.setTitle("Game");
System.out.println("Running...");
game.start();
game.loadPics();
}
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_A) {
x = x - 5;
}
if (e.getKeyCode() == KeyEvent.VK_D) {
x = x + 5;
}
if (e.getKeyCode() == KeyEvent.VK_SPACE) {
y = y - 5;
}
if (e.getKeyCode() == KeyEvent.VK_SHIFT) {
y = y + 5;
}
if (e.getKeyCode() == KeyEvent.VK_W) {
z = z + 5;
}
if (e.getKeyCode() == KeyEvent.VK_S) {
z = z - 5;
}
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
paused = (true);
}
}
public void loadPics(){
rock1 = new ImageIcon("C\\...\\rock1.png").getImage();
rock2 = new ImageIcon("C\\...\\rock2.png").getImage();
wood1 = new ImageIcon("C\\....\\wood1.png").getImage();
repaint();
}
public void paint(Graphics g){
while(paused = false){
g.drawImage(rock1, x, y, z, z, this);
g.drawImage(rock2, x + 512, y, z, z, this);
g.drawImage(wood1, x, y + 512, z, z, this);
try{
Thread.sleep(16);
}catch(Exception e){}
g.dispose();
}
}
}
Again, I think the problem lies with my JFrame, but I can't be too sure since I am not the most experienced java programmer. Anyway, if you know a solution or what to change, please help.
This statement
while (paused = false){
will always evaluate to false as you're using an assignment expression, so the subsequent calls to drawImage won't occur. You probably meant to use the == operator to compare the primitive boolean value:
while (paused == false){
Don't use paint, Use paintComponent from a subclassed JComponent
Don't call Thread.sleep in any paint method. Swing has its own concurrency mechanisms. Instead of calling Thread.sleep here, you could use a Swing Timer to periodically perform graphical updates.
Aside from that, AWT are heavyweight components are don't render well with lightweight Swing components. Use Key Bindings rather than Key Listeners for Swing applications.
I have had many recurring problems like this and have developed a way to solve this.
First of all, your public class Base needs to be double buffered. Change method paint(Graphics g) to paintComponent(Graphics g). Add a new paint(Graphics g) method and add this code:
public void paint(Graphics g) {
// TODO Auto-generated method stub (IGNORE!!!)
dbi = createImage (getWidth(),getHeight());
dbg = dbi.getGraphics();
paintComponent(dbg);
g.drawImage(dbi , 0 , 0 , this);
}
And at the top of public class Base, add these variables:
private Image dbi;
private Graphics dbg;
This automatically calls paintComponent(Graphics g) and has completed the first step.
Next, remove the try statement in paintComponent() and write this in run()
#Override
public void run() {
try {
while (true) {
Thread.sleep(5); // we want this so the computer doesn't go too fast
}
} catch (Exception e) { // Never have an empty catch statement
System.out.println ("Error! stacktrace: ");
e.printStackTrace();
}
}
The #Override annotation has to be there or it will not repaint.
The next part is crititcal:
before anything else, put super.paint(g); at the top of paintComponent(Graphics g)
and repaint(); at the bottom.
This should have solved it, but there are some potential problems I found;
JFrame initialization
public Base(){
add(game);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(800, 600);
setLocationRelativeTo(null);
setResizable(false);
setVisible(true);
setTitle("Game");
start();
loadPics();
}
public static void main(String[] Args) { // Makes game smoother
Base base = new Base ();
Thread t = new Thread (base);
t.start();
}
Remove private void start() as this does not affect game play.
Check the file directories, as they may be incorrect. Hint: C\ doesn't cut it. It's C:\
Hope it works out and happy coding!

Java Smooth ArrayList Movement

Currently I am double buffering in my program(though you should know) and I have an array-list that stores BufferedImages, and Integers. Currently my code to move the whole arraylist across the screen is:
public static void MoveMap(final double ammount){
Thread t = new Thread(){
public void run(){
for(int i = 0; i < TileHelper.MAIN_LIST.size();i++){
TileHelper.MAIN_LIST.get(i).changeX(ammount*DATA.speed);
}
}
};
t.start();
}
This gets the job done but it doesn't look smooth. Even if I use a number like .25 for the variable amount.(I just noticed I spelt it wrong in my code :O) How do I make nice smooth movement if I have all of my images in this array? Btw If you want to know what isn't smooth with this, it's the fact that this lags and between each image you see a big white space. Any help is apreciated... Thank you!
Rendering code:
public class Main extends JFrame {
public static int worldsize = 1080;
private static final long serialVersionUID = 6149918602875295087L;
public static void main(String args[]){
new Main();
}
TileHelper tiles = new TileHelper(TileHelper.MAIN_LIST);
public Main(){
DATA_IMAGES.initImages();
addDefaultBlocks();
setSize(640,480);
setResizable(false);
setTitle("Stranded");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
createBufferStrategy(2);
GameLoop();
addKeyListener(new KeyListener() {
public void keyTyped(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
switch(key){
case KeyEvent.VK_LEFT:
Movement.MoveMap(3.25);
break;
case KeyEvent.VK_RIGHT:
Movement.MoveMap(-3.25);
break;
case KeyEvent.VK_UP:
DATA.speed++;
break;
case KeyEvent.VK_DOWN:
DATA.speed--;
break;
case KeyEvent.VK_SPACE:
System.out.println(DATA.speed);
break;
}
}
});
}
private void addDefaultBlocks() {
for(int x = -1000/32; x < worldsize/32; x++){
for (int y = -1000/32; y < worldsize/32; y++){
TileHelper.addBlock(DATA_IMAGES.GRASS, x*32, y*32);
}
}
}
public void GameLoop(){
Thread gameloop = new Thread(){
public void run(){
while(true){
RenderInit();
try {
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
gameloop.start();
}
public void RenderInit(){
BufferStrategy buff = getBufferStrategy();
Graphics g = buff.getDrawGraphics();
g.clearRect(0, 0, getWidth(), getHeight());
Render(g);
g.dispose();
buff.show();
Toolkit.getDefaultToolkit().sync();
}
public void Render(Graphics g){
tiles.RenderAll(g);
}
}
I'm assuming you're attempting to make a sidescroller game, and the way I got this to work was to make all objects in the games, a sprite.
I created a Sprite class which contains, x, y, xvelocity, yvelocity attributes as well as getters and setters. When I wanted to scroll, I either set the velocity to the opposite direction temporarily, or moved the x value.
Another method was to keep the original x and y values stored in each sprite, and when drawing to the screen I had a variable called: "offSetX" which was added or subtracted by the sprite's original position to have a unified movement between all sprites on screen.
If this is not what you're looking for, i'll delete this. :)
Note:
I recently modified my old sidescroller game engine and found the last method as the best one, rather than modifying all the x positions on the sprite list. My offSetX variable is a float value and when drawing to the screen I use Math.round(sprite.getX() + offSetX) to get the most accurate position.

Categories

Resources