简体   繁体   中英

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM