ZetCode

Java游戏基础

最后修改于 2023 年 1 月 10 日

在本部分 Java 2D 游戏教程中,我们将介绍创建游戏所需的一些基础知识。我们将创建一个基本应用程序,绘制一个甜甜圈,并显示一张图片。

关于

这是 Java 2D 游戏教程。它面向初学者。本教程将教您使用 Java 编程语言和 Swing GUI 工具包进行 2D 游戏编程的基础知识。本教程中使用的图像可以在此处下载。

应用程序

在本教程中,我们将展示每个游戏的骨架。

Board.java
package com.zetcode;

import javax.swing.JPanel;

public class Board extends JPanel {

    public Board() {}
}

Board 是游戏发生所在的面板。

Application.java
package com.zetcode;

import java.awt.EventQueue;
import javax.swing.JFrame;

public class Application extends JFrame {
    
    public Application() {

        initUI();
    }

    private void initUI() {

        add(new Board());

        setSize(250, 200);

        setTitle("Application");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }    
    
    public static void main(String[] args) {
        
        EventQueue.invokeLater(() -> {
            Application ex = new Application();
            ex.setVisible(true);
        });
    }
}

这是游戏的入口点。我们在这里有 main 方法。

add(new Board());

在这里,我们将 Board 放入 JFrame 容器的中心。

setSize(250, 200);

此行设置窗口的大小。

setDefaultCloseOperation(EXIT_ON_CLOSE);

点击关闭按钮时,这将关闭应用程序。这不是默认行为。

setLocationRelativeTo(null);

null 传递给 setLocationRelativeTo() 方法会将窗口置于屏幕中央。

public static void main(String[] args) {
    
    EventQueue.invokeLater(() -> {
        Application ex = new Application();
        ex.setVisible(true);
    });
}

我们创建一个代码示例的实例,并使其在屏幕上可见。

甜甜圈

棋盘上的对象要么是图像,要么是使用 Java 2D API 提供的绘图工具绘制的。在下一个示例中,我们将绘制一个甜甜圈形状。

Board.java
package com.zetcode;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import javax.swing.JPanel;

public class Board extends JPanel {

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        drawDonut(g);
    }

    private void drawDonut(Graphics g) {

        Graphics2D g2d = (Graphics2D) g;

        RenderingHints rh
                = new RenderingHints(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);

        rh.put(RenderingHints.KEY_RENDERING,
                RenderingHints.VALUE_RENDER_QUALITY);

        g2d.setRenderingHints(rh);

        Dimension size = getSize();
        double w = size.getWidth();
        double h = size.getHeight();

        Ellipse2D e = new Ellipse2D.Double(0, 0, 80, 130);
        g2d.setStroke(new BasicStroke(1));
        g2d.setColor(Color.gray);

        for (double deg = 0; deg < 360; deg += 5) {
            AffineTransform at
                    = AffineTransform.getTranslateInstance(w/2, h/2);
            at.rotate(Math.toRadians(deg));
            g2d.draw(at.createTransformedShape(e));
        }
    }
}

绘图在 paintComponent() 方法内部完成。

private void drawDonut(Graphics g) {
...
}

将实际绘图委托给特定方法是一个良好的编程实践。

Graphics2D g2d = (Graphics2D) g;

Graphics2D 类扩展了 Graphics 类。它提供了对几何、坐标变换、颜色管理和文本布局更高级别的控制。

RenderingHints rh
        = new RenderingHints(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

rh.put(RenderingHints.KEY_RENDERING,
        RenderingHints.VALUE_RENDER_QUALITY);

g2d.setRenderingHints(rh);

渲染提示用于使绘图更加流畅。

Dimension size = getSize();
double w = size.getWidth();
double h = size.getHeight();

我们获取窗口的高度和宽度。我们需要它们来将甜甜圈形状居中在窗口上。

Ellipse2D e = new Ellipse2D.Double(0, 0, 80, 130);
g2d.setStroke(new BasicStroke(1));
g2d.setColor(Color.gray);

在这里我们创建椭圆。

for (double deg = 0; deg < 360; deg += 5) {
    AffineTransform at
            = AffineTransform.getTranslateInstance(w/2, h/2);
    at.rotate(Math.toRadians(deg));
    g2d.draw(at.createTransformedShape(e));
}

在这里,椭圆被旋转 72 次以创建甜甜圈形状。

Donut.java
package com.zetcode;

import java.awt.EventQueue;
import javax.swing.JFrame;

public class DonutExample extends JFrame {
    
    public DonutExample() {

        initUI();
    }

    private void initUI() {

        add(new Board());

        setSize(330, 330);

        setTitle("Donut");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }    
    
    public static void main(String[] args) {
        
        EventQueue.invokeLater(() -> {
            DonutExample ex = new DonutExample();
            ex.setVisible(true);
        });
    }
}

这是主类。

绘制图像

当我们创建电脑游戏时,我们经常处理图像。在下一个示例中,我们将加载一张图像并在棋盘上绘制它。如果您找不到图像文件,请查看Java 中的显示图像教程

Board.java
package com.zetcode;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JPanel;

public class Board extends JPanel {

    private Image bardejov;

    public Board() {

        initBoard();
    }
    
    private void initBoard() {
        
        loadImage();
        
        int w = bardejov.getWidth(this);
        int h =  bardejov.getHeight(this);
        setPreferredSize(new Dimension(w, h));        
    }
    
    private void loadImage() {
        
        ImageIcon ii = new ImageIcon("src/resources/bardejov.png");
        bardejov = ii.getImage();        
    }

    @Override
    public void paintComponent(Graphics g) {

        g.drawImage(bardejov, 0, 0, null);
    }
}

我们在棋盘上绘制城镇图像。图像绘制在 paintComponent() 方法内部。

ImageIcon ii = new ImageIcon("src/resources/bardejov.png");

我们创建一个 ImageIcon

bardejov = ii.getImage();

我们从 ImageIcon 中获取一个 Image

g.drawImage(bardejov, 0, 0, null);

我们在窗口上绘制图像。

int w = bardejov.getWidth(this);
int h =  bardejov.getHeight(this);
setPreferredSize(new Dimension(w, h));

我们确定图像的宽度和高度。棋盘面板的首选大小设置为图像的尺寸。通过与 JFramepack() 方法配合,窗口的大小刚好足够显示图像。

ImageExample.java
package com.zetcode;

import java.awt.EventQueue;
import javax.swing.JFrame;

public class ImageExample extends JFrame {

    public ImageExample() {

        initUI();
    }

    private void initUI() {

        add(new Board());

        pack();

        setTitle("Bardejov");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }

    public static void main(String[] args) {

        EventQueue.invokeLater(() -> {
            ImageExample ex = new ImageExample();
            ex.setVisible(true);
        });
    }
}

这是示例的主类。

Image
图:图像

在本章中,我们介绍了一些 Java 游戏编程的基础知识。