Java 2D编程:渲染技术

时间:2014-11-11 00:11:27

标签: java swing rendering

我已经在java编程了一段时间了,我刚刚开始2D图形(游戏开发)。在对游戏进行编码时,我注意到游戏的渲染问题。当我的播放器在屏幕上运行时,像素会出现问题。这就像多人游戏的滞后一样,但几乎没有引人注目。在研究了这个问题后,我没有提出任何解决方案,所以我请求你的帮助。

我的问题:我的游戏渲染效果不佳,我想知道渲染方式是否差。如果是这样,你能指点我任何资源吗?

MY RENDERING CLASS

public class Render extends JPanel implements Runnable{
    int SCREEN_WIDTH,SCREEN_HEIGHT;
    Game game;
    Thread t;

    public Render(int w,int h,Game g){
        this.SCREEN_WIDTH = w;
        this.SCREEN_HEIGHT = h;
        this.game = g;
        this.setDoubleBuffered(true);

    }

    public void run(){
        while(true){
            repaint();
        }
    }

    public void paint(Graphics g){
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.translate(-this.game.getCamera().getX(), -game.getCamera().getY());


        g2d.setColor(Color.black);
        //fill the screen with black
        g2d.fillRect(0, 0, game.getLevelHandler().getLevel().getWidth() * 32, game.getLevelHandler().getLevel().getHeight() * 32);

        /**for(Entity E: game.getObjects()){
            E.draw(g2d);
        }*/
        //send the graphics object to my player...IS THIS OKAY TO DO?
        game.getPlayer().draw(g2d);

    }

    public void start(){
        t = new Thread(this);
        t.start();
    }

}




public class Player extends Entity{
    float dx,dy,moveSpeed;
    boolean jumping, canJump;

    float terminalVelocity,acceleration = 0;
    int GravityCounter,jumps,maxJumps,jumpheight = 0;


    public Player(float x, float y, float w, float h, ObjectID id, Game g) {
        super(x, y, w, h, id, g);
        //gravity
        terminalVelocity += 7;
        acceleration += 0.2;
        moveSpeed += 2.5;

        //jumping
        jumpheight = 40;        
        maxJumps = 2;
        jumps = maxJumps;
    }

    public void tick() {
        dx = 0;
        dy = 0;

        collisions();
        move();

        x += dx;
        y += dy;
    }

    public void collisions(){
    }

        public void move(){
        }
        //the drawing
        public void draw(Graphics2D g) {
            g.setColor(Color.green);
            g.drawRect((int)x, (int)y, (int)w, (int)h);
        }

    }

编辑:可下载链接here ,如果需要进行任何更改,我会尝试更正它。此外,当存在内存泄漏时,是否会发生这种故障?

我因为建议修改了我的代码,这就是我现在所拥有的。

渲染器:

public class Render extends JPanel implements Runnable{
    int SCREEN_WIDTH,SCREEN_HEIGHT;
    Game game;
    Thread t;

    public Render(int w,int h,Game g){
        this.SCREEN_WIDTH = w;
        this.SCREEN_HEIGHT = h;
        this.game = g;
        this.setDoubleBuffered(true);

    }

    public void run(){
        while(true){
            repaint();
            try {
                Thread.sleep(16);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public synchronized void paint(Graphics g){
        Graphics2D g2d = (Graphics2D) g;
        g2d.translate(-this.game.getCamera().getX(), -game.getCamera().getY());


        g2d.setColor(Color.black);
        g2d.fillRect(0, 0, game.getLevelHandler().getLevel().getWidth() * 32,                 game.getLevelHandler().getLevel().getHeight() * 32);

        for(Entity E: game.getObjects()){
            synchronized(E){E.draw(g2d);}
        }

        synchronized(game.getPlayer()){game.getPlayer().draw(g2d);}

     }

    public void start(){
        t = new Thread(this);
        t.start();
    }

}

玩家类没有改变

源代码:here

1 个答案:

答案 0 :(得分:0)

我知道这里发生了什么,因为我在写作的游戏中遇到了完全相同的问题。确实很难找到。您的问题正在发生,因为您在绘制时将xy变量四舍五入。

g.drawRect((int)x, (int)y, (int)w, (int)h);

这导致你的矩形跳了一下。因为看起来您的矩形可以有十进制坐标,所以您需要能够以十进制坐标绘制矩形。有一种非常简单的方法可以做到这一点,但是让我们使用一种无​​论你画的是什么都会起作用的方式。

你需要使用一些转换,我个人喜欢AffineTransform。有很多关于这些的教程,但这是谷歌搜索https://docs.oracle.com/javase/tutorial/2d/advanced/transforming.html的第一个(非文档)结果。我知道你已经在进行一些转换,但这是你添加它们后的draw方法。

public void draw(Graphics2D g) {
        AffineTransform original = g.getTransform(); // keep a copy of the original so that we can restore it
        AffineTransform transform = (AffineTransform)original.clone();
        transform.translate((double)x, (double)y); // translate the transform to the player location, note that x and y can be non-integers here.
        g.transform(transform); // apply the transformation.
        g.setColor(Color.green);
        g.drawRect(0, 0, (int)w, (int)h);
        g.setTransform(original); // restore the original transformation
    }

对于你的其他墙壁和东西,你可以使用这个完全相同的方法。请记住,对象的“屏幕”位置是对象的游戏位置减去相机的游戏位置。祝你的游戏好运。