简体   繁体   English

Java AWT 拉丝瓷砖拉丝缝隙

[英]Java AWT drawing tiles laves gap

I am trying to make a tile based game in Java and I have noticed a problem with the drawing.我正在尝试在 Java 中制作基于图块的游戏,但我注意到绘图存在问题。 There is about a one pixel gap between some of the tiles and I am not sure what is causing it.一些图块之间大约有一个像素的间隙,我不确定是什么原因造成的。

Here is a screenshot of it:这是它的屏幕截图:

https://i.stack.imgur.com/UbJ2B.png

Here is my code so far:到目前为止,这是我的代码:

Main class:主class:

package Game.main;

import javax.swing.JFrame;

public class Main {
    public static JFrame window;
    public static void main(String[] args) {
        window = new JFrame();
        window.setVisible(true);
        window.setSize(1280, 720);
        window.setTitle("Game");
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Game game = new Game();
        window.add(game);
    }
}

Game class:游戏 class:

package Game.main;

import javax.swing.JPanel;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Color;

import java.util.ArrayList;

import Game.tile.Tile;

public class Game extends JPanel implements Runnable {

    public Game() {
        start();
    }

    boolean running = false;

    int width,height;

    ArrayList<Tile> tiles = new ArrayList<>();

    public void paint(Graphics g1) {
        //cast to graphics2d
        Graphics2D g = (Graphics2D)g1;
        //fill background
        g.setColor(Color.CYAN);
        g.fillRect(0, 0, width, height);
        //draw tiles
        for(int i = 0; i < tiles.size(); i++) {
            tiles.get(i).render(g, width, height);
        }
    }

    private void start() {
        Thread gameThread = new Thread(this);
        gameThread.start();
        //create start tiles
        for(int x = 0; x < 1000; x+=10) {
            for(int y = 700; y < 1000; y+=20) {
                Tile tile = new Tile(x, y);
                tiles.add(tile);
            }
        }
    }

    @Override
    public void run() {
        running = true;
        while(running) {
            //get window width and height
            requestFocus();
            width = Main.window.getWidth();
            height = Main.window.getHeight();
            //redraw current frame
            repaint();
        }
    }
}

Tile class:瓷砖 class:

package Game.tile;

import java.awt.Graphics2D;
import java.awt.Color;

public class Tile {
    public int x,y;
    public int w,h;
    public Tile(int x, int y) {
        this.x = x;
        this.y = y;
        this.w = 10;
        this.h = this.w*2;
    }
    public void render(Graphics2D g, int width, int height) {
        g.setColor(Color.GRAY);
        g.fillRect(this.x*width/1000, this.y*height/1000, this.w*width/1000, this.h*height/1000);
    }
}

You have magic numbers in your "Game" class:您的“游戏”class 中有幻数:

    for(int x = 0; x < 1000; x+=10) {
        for(int y = 700; y < 1000; y+=20) {
            Tile tile = new Tile(x, y);
            tiles.add(tile);
        }

And you have more magic numbers in your Tile class:你的 Tile class 中有更多的幻数:

    this.w = 10;
    this.h = this.w*2;
}
public void render(Graphics2D g, int width, int height) {
    g.setColor(Color.GRAY);
    g.fillRect(this.x*width/1000, this.y*height/1000, this.w*width/1000, this.h*height/1000);
}

You are also going to get rounding when you use:当你使用时,你也会得到四舍五入:

  x * width / 1000

So the "x" value you get when painting will not always be a multiple of 10 like you expect.所以你在绘画时得到的“x”值并不总是像你期望的那样是 10 的倍数。 This is probably why you get the gaps between tiles.这可能就是为什么你会得到瓷砖之间的间隙。

You need to remove the magic numbers from multiple classes.您需要从多个类中删除幻数。 For example the Tile class should be self contained.例如, Tile class 应该是独立的。 It should be able to paint itself without any magic numbers.它应该能够在没有任何幻数的情况下绘制自己。 All the information should be passed to the class in the constructor.所有信息都应传递给构造函数中的 class。

For example:例如:

//public Tile(int x, int y) {
public Tile(int x, int y, int width, int height) {

Then in the painting logic you can use:然后在绘画逻辑中你可以使用:

//public void render(Graphics2D g, int width, int height) {
public void render(Graphics2D g) {
    g.setColor(Color.GRAY);
    //g.fillRect(this.x*width/1000, this.y*height/1000, this.w*width/1000, this.h*height/1000);
    g.drawRect(x, y, width, height);
}

And in you Game class when you create the Tile you would use:在你的游戏 class 当你创建你会使用的瓷砖时:

//Tile tile = new Tile(x, y);
Tile tile = new Tile(x, y, 10, 20);

Now the Game class fully controls the size and number of tiles.现在Game class 完全控制瓷砖的大小和数量。 The Tile class just paints itself and doesn't worry about the size of the Game panel. Tile class 只是自己绘制,不用担心游戏面板的大小。

Of course you have to make sure you use reasonable values when creating the tiles:当然,您必须确保在创建图块时使用合理的值:

    for(int x = 0; x < 1000; x+=10) {
        for(int y = 700; y < 1000; y+=20) {

Why would the "y" variable start at 700 when the height of the frame is only 720?为什么当框架的高度只有 720 时,“y”变量会从 700 开始?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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