java swing实战——baba is you(游戏围墙绘制)

3.1.4 绘制游戏边界GameClosure

GameClosure即外围边界,即下图中阴影部分

在设计中,我们以上图中每个小的单元格作为游戏绘制的一个单元,

 

在制作游戏中,作者在网上找了许多素材,最终使用24*24的游戏素材,因此每个单元格为了适应素材其width与height均设置为24px.(游戏素材已放置与阿里云盘中)

因此,我们将GameClosure抽象为一个Closure的集合,每个Closure包含坐标(x,y),宽width、高height

于是,在domain中新建Closure类

/**
 * 外围墙体
 */
public class Closure {
    private int x, y, width, height;
​
    public Closure(int x, int y) {
        this.x = x;
        this.y = y;
        width = 24;
        height = 24;
    }
​
    public int getX() {
        return x;
    }
​
    public void setX(int x) {
        this.x = x;
    }
​
    public int getY() {
        return y;
    }
​
    public void setY(int y) {
        this.y = y;
    }
        public int getWidth() {
        return width;
    }
​
    public void setWidth(int width) {
        this.width = width;
    }
​
    public int getHeight() {
        return height;
    }
​
    public void setHeight(int height) {
        this.height = height;
    }
}

而GameClosure需要一个Closure的集合

/**
 * 绘制外围墙体
 */
public class GameClosure {
    private List<Closure> closureList;
​
    /**
     * 构造方法,初始化墙体集合
     */
    public GameClosure() {
    }
​
    /**
     * 绘制墙体
     * @param graphics
     */
    public void draw(Graphics graphics) {
    }
    
}

其中,GameClosure()构造方法要完成closreList的初始化,以及地图元素的添加,可以结合下图,理解代码

    /**
     * 构造方法,初始化墙体集合
     */
    public GameClosure() {
        closureList = new ArrayList<>();
        for (int i = 0; i < 19; i++) {
            closureList.add(new Closure(i*24, 1*24));
            closureList.add(new Closure(i*24,18*24));
        }
        for (int i = 1; i < 18; i++) {
            closureList.add(new Closure(0,i*24));
            closureList.add(new Closure(18*24,i*24));
        }
    }

对于图形位置坐标的计算,大家可以根据自己运行结果进行调整,作者在本次重构中,意外发现y坐标轴因该从1开始,因此坐标体系与之前略有差异。但是不影响游戏实现,大家经过微调,是可以做出满意的图形。

draw()函数即可将closureList中的元素全部绘制出来,这里我们依旧是绘制矩形

    /**
     * 绘制墙体
     * @param graphics
     */
    public void draw(Graphics graphics) {
        graphics.setColor(Color.red);
        for (int i = 0; i < closureList.size(); i++) {
            Closure closure = closureList.get(i);
            graphics.fillRect(closure.getX(),closure.getY(),closure.getWidth(),closure.getWidth());
        }
    }

同GameBackground一样,我们在GameFrame中,初始化,并且在paint()中调用,运行可得到如下界面:

 

此时,游戏画面不断地闪动,我们采用双缓存机制,解决该问题

即在GameFrame中,实例化BufferedImage(该代码参考尚学堂视频)

  // 双缓存
    private BufferedImage bufferedImage = new BufferedImage(DEFAULT_WIDTH, DEFAULT_HEIGHT, BufferedImage.TYPE_4BYTE_ABGR);
    /**
     * 重绘方法
     */
    @Override
    public void paint(Graphics g) {
        Graphics graphics = bufferedImage.getGraphics();
        gameBackground.draw(graphics);
        gameClosure.draw(graphics);
        g.drawImage(bufferedImage,0,0,null);
    }

至此,我们完成边界绘制,并且解决画面闪动问题。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>