Java AWT 绘制瓷砖 laves gap

Posted

技术标签:

【中文标题】Java AWT 绘制瓷砖 laves gap【英文标题】:Java AWT drawing tiles laves gap 【发布时间】:2021-05-23 13:12:48 【问题描述】:

我正在尝试用 Java 制作基于图块的游戏,但我注意到绘图存在问题。一些图块之间大约有一个像素的间隙,我不确定是什么原因造成的。

这是它的截图:

到目前为止,这是我的代码:

主类:

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);
    

游戏类:

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();
        
    


瓷砖类:

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);
    


【问题讨论】:

【参考方案1】:

你的“游戏”类中有神奇的数字:

    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);
        

而且你的 Tile 类中有更多的幻数:

    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);

当你使用时你也会得到四舍五入:

  x * width / 1000

因此,您在绘画时获得的“x”值并不总是像您期望的那样是 10 的倍数。这可能就是为什么你会得到瓷砖之间的间隙。

您需要从多个类中删除幻数。例如Tile 类应该是自包含的。它应该能够在没有任何幻数的情况下绘制自己。所有信息都应该传递给构造函数中的类。

例如:

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

那么在绘画逻辑中可以使用:

//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);

当你创建你将使用的 Tile 时,在你的 Game 类中:

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

现在Game 类可以完全控制图块的大小和数量。 Tile 类只是自己绘制,并不担心游戏面板的大小。

当然,您必须确保在创建图块时使用合理的值:

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

当框架的高度只有720时,为什么“y”变量会从700开始?

【讨论】:

以上是关于Java AWT 绘制瓷砖 laves gap的主要内容,如果未能解决你的问题,请参考以下文章

Java AWT 图形界面编程Canvas 组件中使用 Graphics 绘图 ① ( AWT 绘图线程 | Component 绘图函数 )

Java AWT 图形界面编程Canvas 组件中使用 Graphics 绘图 ① ( AWT 绘图线程 | Component 绘图函数 )

Java AWT 图形界面编程Canvas 组件中使用 Graphics 绘图 ① ( AWT 绘图线程 | Component 绘图函数 )

JAVA awt 绘制图形

Java AWT如何延迟绘制对象

Java网站登陆验证码的绘制类