You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java初学者求助:如何绘制2D数组并实现可移动玩家角色

嘿,作为Java初学者能尝试动手做2D游戏真的超棒!术语方面完全不用紧张,大家都是从摸不清概念慢慢过来的😉 我帮你把需求拆解成可运行的完整代码,再逐一解释关键部分:

实现2D数组绘制+方向键移动玩家的完整方案

1. 补全并完善你的代码结构

你给出的代码片段不完整,我帮你补全主类和绘图面板类,核心思路是用JPanel做绘图容器,重写paintComponent绘制地图和玩家,用KeyListener处理方向键输入:

主类 Keybarricade

import javax.swing.JFrame;

public class Keybarricade {
    public static void main(String[] args) {
        JFrame obj = new JFrame("我的2D小游戏");
        Playingfield playingfield = new Playingfield();
        
        obj.add(playingfield);
        obj.setSize(400, 400); // 固定窗口大小,方便格子对齐
        obj.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        obj.setResizable(false); // 防止窗口拉伸导致绘图错乱
        obj.setLocationRelativeTo(null); // 让窗口居中显示
        obj.setVisible(true);
        
        // 必须让面板获取键盘焦点,不然按键事件会失效
        playingfield.requestFocus();
    }
}

核心绘图面板 Playingfield

import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class Playingfield extends JPanel implements KeyListener {
    // 用2D数组表示游戏地图:1=灰色障碍物,0=白色空地
    private int[][] gameMap = {
            {1, 1, 1, 1, 1, 1, 1, 1},
            {1, 0, 0, 1, 1, 0, 0, 1},
            {1, 0, 0, 0, 0, 0, 0, 1},
            {1, 1, 0, 1, 1, 0, 1, 1},
            {1, 0, 0, 0, 0, 0, 0, 1},
            {1, 1, 1, 1, 1, 1, 1, 1}
    };
    
    // 玩家初始位置(对应地图数组的索引)
    private int playerX = 1;
    private int playerY = 1;
    // 每个格子的像素大小,方便绘图计算
    private final int TILE_SIZE = 40;

    public Playingfield() {
        this.addKeyListener(this);
        this.setFocusable(true); // 允许面板接收键盘输入
        this.setBackground(Color.BLACK);
    }

    // 重写paintComponent方法,负责绘制所有游戏元素
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        
        // 第一步:绘制2D数组对应的地图
        for (int y = 0; y < gameMap.length; y++) {
            for (int x = 0; x < gameMap[y].length; x++) {
                // 根据数组值设置格子颜色
                if (gameMap[y][x] == 1) {
                    g.setColor(Color.GRAY);
                } else {
                    g.setColor(Color.WHITE);
                }
                // 绘制矩形格子:坐标 = 索引 * 格子大小
                g.fillRect(x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE);
                // 给格子加黑色边框,让地图更清晰
                g.setColor(Color.BLACK);
                g.drawRect(x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE);
            }
        }
        
        // 第二步:绘制玩家(用红色圆形代替简易图标)
        g.setColor(Color.RED);
        // 让玩家居中在格子里:索引*格子大小 + 偏移量
        g.fillOval(playerX * TILE_SIZE + 10, playerY * TILE_SIZE + 10, 20, 20);
    }

    // 处理方向键按下事件,实现玩家移动
    @Override
    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();
        
        // 上方向键:判断不越界+目标格子是空地
        if (key == KeyEvent.VK_UP && playerY > 0 && gameMap[playerY - 1][playerX] == 0) {
            playerY--;
            repaint(); // 重绘界面,更新玩家位置
        }
        // 下方向键
        else if (key == KeyEvent.VK_DOWN && playerY < gameMap.length - 1 && gameMap[playerY + 1][playerX] == 0) {
            playerY++;
            repaint();
        }
        // 左方向键
        else if (key == KeyEvent.VK_LEFT && playerX > 0 && gameMap[playerY][playerX - 1] == 0) {
            playerX--;
            repaint();
        }
        // 右方向键
        else if (key == KeyEvent.VK_RIGHT && playerX < gameMap[playerY].length - 1 && gameMap[playerY][playerX + 1] == 0) {
            playerX++;
            repaint();
        }
    }

    // KeyListener接口必须实现的另外两个方法,暂时用不上
    @Override
    public void keyTyped(KeyEvent e) {}

    @Override
    public void keyReleased(KeyEvent e) {}
}

2. 关键知识点拆解

  • 2D数组绘制逻辑:用嵌套循环遍历gameMap的每个元素,把数组索引转换成屏幕坐标(索引*格子大小),根据数组值绘制不同颜色的格子,这样你只要修改gameMap的内容就能快速修改地图布局。
  • 玩家移动判断:每次按键时会做两个检查:一是玩家不会超出地图边界,二是目标格子不是障碍物(数组值为0),满足条件才更新玩家坐标并调用repaint()触发重绘。
  • 焦点问题:一定要让Playingfield面板获取键盘焦点,不然按键事件会被窗口其他组件拦截,所以主类里加了playingfield.requestFocus(),面板也设置了setFocusable(true)。

3. 适合初学者的小拓展

  • 你可以修改gameMap的内容,添加更多障碍物或者空地,自定义地图形状。
  • 如果想替换玩家图标,用ImageIcon加载本地图片,在paintComponent里用g.drawImage()绘制即可。
  • 要是觉得术语搞混了,随时对着代码查概念,比如paintComponent是Swing的核心绘图方法,KeyListener是键盘事件监听接口,多写几遍就熟了!

内容的提问来源于stack exchange,提问作者MrHiddeS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:46:07