JavaSwing游戏开发之Camera原理


java 复制代码
package org.timer;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class GameCameraWithObjects extends JPanel implements KeyListener {
    // 游戏世界大小
    private final int worldWidth = 2000;
    private final int worldHeight = 1500;

    // 摄像机位置
    private int cameraX = 0;
    private int cameraY = 0;

    // 摄像机视野大小
    private final int viewWidth = 800;
    private final int viewHeight = 600;

    // 玩家位置
    private int playerX = 400;
    private int playerY = 300;

    // 世界中的对象
    private final List<GameObject> gameObjects = new ArrayList<>();
    private final Random random = new Random();

    public GameCameraWithObjects() {
        setPreferredSize(new Dimension(viewWidth, viewHeight));
        addKeyListener(this);
        setFocusable(true);
        generateGameObjects(50); // 生成 50 个随机对象
    }

    // 生成游戏世界中的随机对象
    private void generateGameObjects(int count) {
        for (int i = 0; i < count; i++) {
            int x = random.nextInt(worldWidth);
            int y = random.nextInt(worldHeight);
            int size = 40; // 随机大小 10-40
//            int size = random.nextInt(30) + 10; // 随机大小 10-40
            Color color = new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255));
            gameObjects.add(new GameObject(x, y, size, color));
        }
    }

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

        // 填充背景
        g.setColor(Color.LIGHT_GRAY);
        g.fillRect(0, 0, viewWidth, viewHeight);

        // 绘制世界边界
        g.setColor(Color.BLACK);
        g.drawRect(-cameraX, -cameraY, worldWidth, worldHeight);

        // 绘制所有对象
        for (GameObject obj : gameObjects) {
            int screenX = obj.x - cameraX;
            int screenY = obj.y - cameraY;

            // 只绘制在视野内的对象
            if (screenX + obj.size > 0 && screenX < viewWidth && screenY + obj.size > 0 && screenY < viewHeight) {
                g.setColor(obj.color);
                g.fillRect(screenX, screenY, obj.size, obj.size);
                g.drawString("("+obj.x+","+obj.y+")", screenX, screenY);
            }
        }

        // 绘制玩家
        g.setColor(Color.RED);
        int screenX = playerX - cameraX;
        int screenY = playerY - cameraY;
        g.fillRect(screenX - 10, screenY - 10, 20, 20);

        // 显示调试信息
        g.setColor(Color.BLACK);
        g.drawString("Camera: (" + cameraX + ", " + cameraY + ")", 10, 20);
        g.drawString("Player: (" + playerX + ", " + playerY + ")", 10, 40);
        g.drawString("Objects: " + gameObjects.size(), 10, 60);
    }

    // 更新摄像机位置
    private void updateCamera() {
//        cameraX = playerX - viewWidth / 2;
        cameraX = Math.max(0, Math.min(playerX - viewWidth / 2, worldWidth - viewWidth));
//        cameraY = Math.max(0, Math.min(playerY - viewHeight / 2, worldHeight - viewHeight));
        cameraY = Math.max(0, Math.min(playerY - viewHeight / 2, worldHeight - viewHeight));
    }

    @Override
    public void keyPressed(KeyEvent e) {
        int speed = 10;

        switch (e.getKeyCode()) {
            case KeyEvent.VK_UP -> playerY = Math.max(0, playerY - speed);
            case KeyEvent.VK_DOWN -> playerY = Math.min(worldHeight, playerY + speed);
            case KeyEvent.VK_LEFT -> playerX = Math.max(0, playerX - speed);
            case KeyEvent.VK_RIGHT -> playerX = Math.min(worldWidth, playerX + speed);
        }

        // 更新摄像机
        updateCamera();
        repaint();
    }

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

    public static void main(String[] args) {
        JFrame frame = new JFrame("Game Camera with Objects");
        GameCameraWithObjects gamePanel = new GameCameraWithObjects();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(gamePanel);
        frame.pack();
        frame.setVisible(true);
    }

    // 内部类表示游戏对象
    private static class GameObject {
        int x, y, size;
        Color color;

        public GameObject(int x, int y, int size, Color color) {
            this.x = x;
            this.y = y;
            this.size = size;
            this.color = color;
        }
    }
}
相关推荐
小七在进步3 小时前
初识C++中的模板
java·开发语言·c++
Wang's Blog3 小时前
Java 项目实战: 交友项目 - SpringCloud 整合 Dubbo 的需求分析与模块规划
java·spring cloud·交友
哦虎!4 小时前
【JavaEE】文件操作IO
java
十年Java程序媛4 小时前
Redis 分布式锁 + GZIP 压缩缓存踩坑|高并发缓存真实线上复盘
java·开发语言·spring boot·redis·分布式·缓存·面试
顽疲4 小时前
Java vue 养老系统源码详解:入住核算单 live-check 缴费入账与预交金收据实践
java·vue.js·python·java 养老·springboot 养老·vue养老
共饮一杯无4 小时前
LiveKit本地录制落盘路径排查与修复实践
java·go·livekit
StevenLdh4 小时前
第八期 · 情绪闯关挑战盒:一个「无惩罚」成就系统的数据建模
java·微信小程序
Wang's Blog5 小时前
Java 项目实战: 交友项目 - 入门案例:编写 Dubbo 服务消费者
java·dubbo·交友
IT研究室5 小时前
最新计算机毕业设计选题推荐-基于spring boot的教育学习平台-网站-文档指导-Java-springboot
java·spring boot·课程设计
亚林瓜子5 小时前
Spring Boot 集成 ip2region 离线 IP 库实战指南
java·spring boot·后端·ip·ip2region