Java游戏后台案例

wen java案例 2

本文目录导读:

Java游戏后台案例

  1. 游戏后台管理系统(完整案例)
  2. 使用说明

我来提供一个完整的Java游戏后台案例,包含常见的功能模块。

游戏后台管理系统(完整案例)

项目结构

game-backend/
├── pom.xml
├── src/main/java/com/game/backend/
│   ├── GameBackendApplication.java
│   ├── config/
│   │   ├── SecurityConfig.java
│   │   └── RedisConfig.java
│   ├── controller/
│   │   ├── PlayerController.java
│   │   ├── GameController.java
│   │   ├── RechargeController.java
│   │   └── AdminController.java
│   ├── service/
│   │   ├── PlayerService.java
│   │   ├── GameService.java
│   │   ├── RechargeService.java
│   │   └── StatsService.java
│   ├── repository/
│   │   ├── PlayerRepository.java
│   │   ├── GameRepository.java
│   │   └── RechargeRepository.java
│   ├── entity/
│   │   ├── Player.java
│   │   ├── GameRoom.java
│   │   └── RechargeRecord.java
│   ├── dto/
│   │   ├── PlayerDTO.java
│   │   ├── RechargeDTO.java
│   │   └── StatsDTO.java
│   └── utils/
│       ├── JwtUtil.java
│       └── Result.java

pom.xml 依赖配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.0</version>
    </parent>
    <groupId>com.game</groupId>
    <artifactId>game-backend</artifactId>
    <version>1.0.0</version>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>2.0.25</version>
        </dependency>
    </dependencies>
</project>

实体类

// Player.java - 玩家实体
package com.game.backend.entity;
import lombok.Data;
import javax.persistence.*;
import java.time.LocalDateTime;
@Data
@Entity
@Table(name = "players")
public class Player {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(unique = true, nullable = false)
    private String username;
    @Column(nullable = false)
    private String password;
    private String nickname;
    @Column(name = "gold_coins")
    private Integer goldCoins = 0;
    @Column(name = "diamonds")
    private Integer diamonds = 0;
    @Column(name = "level")
    private Integer level = 1;
    @Column(name = "experience")
    private Integer experience = 0;
    @Column(name = "last_login_time")
    private LocalDateTime lastLoginTime;
    @Column(name = "create_time")
    private LocalDateTime createTime;
    private Integer status = 1; // 1:正常 0:封禁
}
// GameRoom.java - 游戏房间实体
package com.game.backend.entity;
import lombok.Data;
import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.List;
@Data
@Entity
@Table(name = "game_rooms")
public class GameRoom {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(name = "room_name")
    private String roomName;
    private Integer type; // 1:快速赛 2:排位赛 3:娱乐赛
    private Integer status; // 0:等待中 1:游戏中 2:已结束
    @Column(name = "max_players")
    private Integer maxPlayers;
    @Column(name = "current_players")
    private Integer currentPlayers = 0;
    @Column(name = "base_stake")
    private Integer baseStake; // 基础底注
    @Column(name = "create_time")
    private LocalDateTime createTime;
}
// RechargeRecord.java - 充值记录实体
package com.game.backend.entity;
import lombok.Data;
import javax.persistence.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
@Entity
@Table(name = "recharge_records")
public class RechargeRecord {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(name = "player_id")
    private Long playerId;
    @Column(name = "order_no")
    private String orderNo;
    private BigDecimal amount; // 充值金额
    private Integer diamonds; // 获得钻石数
    private Integer status; // 0:处理中 1:成功 2:失败
    @Column(name = "pay_type")
    private String payType; // ALIPAY/WECHAT/APPLE
    @Column(name = "create_time")
    private LocalDateTime createTime;
    @Column(name = "pay_time")
    private LocalDateTime payTime;
}

仓储层

// PlayerRepository.java
package com.game.backend.repository;
import com.game.backend.entity.Player;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface PlayerRepository extends JpaRepository<Player, Long> {
    Player findByUsername(String username);
    boolean existsByUsername(String username);
    @Query("SELECT p FROM Player p WHERE p.status = 1 ORDER BY p.diamonds DESC")
    List<Player> findTopPlayers();
    @Modifying
    @Query("UPDATE Player p SET p.goldCoins = :goldCoins WHERE p.id = :id")
    void updateGoldCoins(@Param("id") Long id, @Param("goldCoins") Integer goldCoins);
    @Modifying
    @Query("UPDATE Player p SET p.diamonds = p.diamonds + :diamonds WHERE p.id = :id")
    void addDiamonds(@Param("id") Long id, @Param("diamonds") Integer diamonds);
}
// GameRepository.java
package com.game.backend.repository;
import com.game.backend.entity.GameRoom;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface GameRepository extends JpaRepository<GameRoom, Long> {
    List<GameRoom> findByStatus(Integer status);
    List<GameRoom> findByType(Integer type);
    @Query("SELECT COUNT(g) FROM GameRoom g WHERE g.status = 1")
    Long countActiveGames();
}

服务层

// PlayerService.java
package com.game.backend.service;
import com.game.backend.dto.PlayerDTO;
import com.game.backend.entity.Player;
import com.game.backend.repository.PlayerRepository;
import com.game.backend.utils.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class PlayerService {
    @Autowired
    private PlayerRepository playerRepository;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private JwtUtil jwtUtil;
    // 注册
    @Transactional
    public Player register(String username, String password) {
        if (playerRepository.existsByUsername(username)) {
            throw new RuntimeException("用户名已存在");
        }
        Player player = new Player();
        player.setUsername(username);
        player.setPassword(passwordEncoder.encode(password));
        player.setCreateTime(LocalDateTime.now());
        player.setStatus(1);
        return playerRepository.save(player);
    }
    // 登录
    public String login(String username, String password) {
        Player player = playerRepository.findByUsername(username);
        if (player == null) {
            throw new RuntimeException("用户不存在");
        }
        if (!passwordEncoder.matches(password, player.getPassword())) {
            throw new RuntimeException("密码错误");
        }
        if (player.getStatus() == 0) {
            throw new RuntimeException("账号已被封禁");
        }
        // 生成JWT令牌
        return jwtUtil.generateToken(player.getId(), player.getUsername());
    }
    // 获取玩家信息
    public PlayerDTO getPlayerInfo(Long playerId) {
        Player player = playerRepository.findById(playerId)
                .orElseThrow(() -> new RuntimeException("玩家不存在"));
        return convertToDTO(player);
    }
    // 获取排行榜
    public List<PlayerDTO> getLeaderboard(int limit) {
        List<Player> players = playerRepository.findTopPlayers();
        return players.stream()
                .limit(limit)
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    // 赚取金币
    @Transactional
    public void addGoldCoins(Long playerId, int amount) {
        Player player = playerRepository.findById(playerId)
                .orElseThrow(() -> new RuntimeException("玩家不存在"));
        player.setGoldCoins(player.getGoldCoins() + amount);
        playerRepository.save(player);
    }
    // 消耗金币
    @Transactional
    public boolean deductGoldCoins(Long playerId, int amount) {
        Player player = playerRepository.findById(playerId)
                .orElseThrow(() -> new RuntimeException("玩家不存在"));
        if (player.getGoldCoins() < amount) {
            return false;
        }
        player.setGoldCoins(player.getGoldCoins() - amount);
        playerRepository.save(player);
        return true;
    }
    // 封禁玩家
    @Transactional
    public void banPlayer(Long playerId) {
        Player player = playerRepository.findById(playerId)
                .orElseThrow(() -> new RuntimeException("玩家不存在"));
        player.setStatus(0);
        playerRepository.save(player);
    }
    private PlayerDTO convertToDTO(Player player) {
        PlayerDTO dto = new PlayerDTO();
        dto.setId(player.getId());
        dto.setUsername(player.getUsername());
        dto.setNickname(player.getNickname());
        dto.setGoldCoins(player.getGoldCoins());
        dto.setDiamonds(player.getDiamonds());
        dto.setLevel(player.getLevel());
        dto.setExperience(player.getExperience());
        dto.setStatus(player.getStatus());
        return dto;
    }
}
// GameService.java
package com.game.backend.service;
import com.game.backend.entity.GameRoom;
import com.game.backend.repository.GameRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
@Service
public class GameService {
    @Autowired
    private GameRepository gameRepository;
    @Autowired
    private PlayerService playerService;
    // 创建房间
    public GameRoom createRoom(GameRoom room) {
        room.setCreateTime(LocalDateTime.now());
        room.setStatus(0);
        room.setCurrentPlayers(0);
        return gameRepository.save(room);
    }
    // 加入房间
    @Transactional
    public boolean joinRoom(Long roomId, Long playerId) {
        GameRoom room = gameRepository.findById(roomId)
                .orElseThrow(() -> new RuntimeException("房间不存在"));
        if (room.getCurrentPlayers() >= room.getMaxPlayers()) {
            return false;
        }
        if (room.getStatus() != 0) {
            return false;
        }
        // 扣除底注
        boolean deducted = playerService.deductGoldCoins(playerId, room.getBaseStake());
        if (!deducted) {
            throw new RuntimeException("金币不足");
        }
        room.setCurrentPlayers(room.getCurrentPlayers() + 1);
        if (room.getCurrentPlayers() >= room.getMaxPlayers()) {
            room.setStatus(1); // 满员开始游戏
        }
        gameRepository.save(room);
        return true;
    }
    // 离开房间
    @Transactional
    public boolean leaveRoom(Long roomId, Long playerId) {
        GameRoom room = gameRepository.findById(roomId)
                .orElseThrow(() -> new RuntimeException("房间不存在"));
        if (room.getCurrentPlayers() > 0) {
            room.setCurrentPlayers(room.getCurrentPlayers() - 1);
            if (room.getCurrentPlayers() == 0) {
                room.setStatus(2); // 房间结束
            } else {
                room.setStatus(0); // 回到等待状态
            }
            gameRepository.save(room);
            return true;
        }
        return false;
    }
    // 获取所有空闲房间
    public List<GameRoom> getAvailableRooms() {
        return gameRepository.findByStatus(0);
    }
    // 获取当前活动房间数
    public long getActiveGameCount() {
        return gameRepository.countActiveGames();
    }
}
// RechargeService.java
package com.game.backend.service;
import com.game.backend.entity.RechargeRecord;
import com.game.backend.repository.PlayerRepository;
import com.game.backend.repository.RechargeRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.UUID;
@Service
public class RechargeService {
    @Autowired
    private RechargeRepository rechargeRepository;
    @Autowired
    private PlayerRepository playerRepository;
    // 创建充值订单
    public RechargeRecord createRechargeOrder(Long playerId, BigDecimal amount) {
        RechargeRecord record = new RechargeRecord();
        record.setPlayerId(playerId);
        record.setOrderNo(generateOrderNo());
        record.setAmount(amount);
        record.setDiamonds(amount.multiply(new BigDecimal("10")).intValue());
        record.setStatus(0);
        record.setCreateTime(LocalDateTime.now());
        return rechargeRepository.save(record);
    }
    // 处理支付回调
    @Transactional
    public void processPayCallback(String orderNo, boolean success) {
        RechargeRecord record = rechargeRepository.findByOrderNo(orderNo);
        if (record == null) {
            throw new RuntimeException("订单不存在");
        }
        record.setStatus(success ? 1 : 2);
        record.setPayTime(LocalDateTime.now());
        rechargeRepository.save(record);
        if (success) {
            // 给玩家添加钻石
            playerRepository.addDiamonds(record.getPlayerId(), record.getDiamonds());
        }
    }
    private String generateOrderNo() {
        return "R" + System.currentTimeMillis() + UUID.randomUUID().toString().substring(0, 6);
    }
}

控制器层

// PlayerController.java
package com.game.backend.controller;
import com.game.backend.dto.PlayerDTO;
import com.game.backend.entity.Player;
import com.game.backend.service.PlayerService;
import com.game.backend.utils.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/api/player")
public class PlayerController {
    @Autowired
    private PlayerService playerService;
    @PostMapping("/register")
    public Result<?> register(@RequestBody Map<String, String> params) {
        try {
            Player player = playerService.register(params.get("username"), params.get("password"));
            return Result.success(player);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    @PostMapping("/login")
    public Result<?> login(@RequestBody Map<String, String> params) {
        try {
            String token = playerService.login(params.get("username"), params.get("password"));
            return Result.success(token);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    @GetMapping("/info/{playerId}")
    public Result<?> getPlayerInfo(@PathVariable Long playerId) {
        try {
            PlayerDTO player = playerService.getPlayerInfo(playerId);
            return Result.success(player);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    @GetMapping("/leaderboard")
    public Result<?> getLeaderboard(@RequestParam(defaultValue = "10") int limit) {
        try {
            List<PlayerDTO> players = playerService.getLeaderboard(limit);
            return Result.success(players);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
}
// GameController.java
package com.game.backend.controller;
import com.game.backend.entity.GameRoom;
import com.game.backend.service.GameService;
import com.game.backend.utils.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/api/game")
public class GameController {
    @Autowired
    private GameService gameService;
    @PostMapping("/createRoom")
    public Result<?> createRoom(@RequestBody GameRoom room) {
        try {
            GameRoom createdRoom = gameService.createRoom(room);
            return Result.success(createdRoom);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    @PostMapping("/joinRoom")
    public Result<?> joinRoom(@RequestBody Map<String, Long> params) {
        try {
            boolean success = gameService.joinRoom(params.get("roomId"), params.get("playerId"));
            return success ? Result.success("加入成功") : Result.error("加入失败");
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    @GetMapping("/availableRooms")
    public Result<?> getAvailableRooms() {
        try {
            List<GameRoom> rooms = gameService.getAvailableRooms();
            return Result.success(rooms);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
    @GetMapping("/activeCount")
    public Result<?> getActiveGameCount() {
        try {
            long count = gameService.getActiveGameCount();
            return Result.success(count);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }
}

工具类

// Result.java - 统一返回对象
package com.game.backend.utils;
import lombok.Data;
@Data
public class Result<T> {
    private Integer code;
    private String message;
    private T data;
    public static <T> Result<T> success(T data) {
        Result<T> result = new Result<>();
        result.setCode(200);
        result.setMessage("success");
        result.setData(data);
        return result;
    }
    public static <T> Result<T> error(String message) {
        Result<T> result = new Result<>();
        result.setCode(500);
        result.setMessage(message);
        return result;
    }
}
// JwtUtil.java - JWT工具类
package com.game.backend.utils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class JwtUtil {
    private String secret = "GameBackendSecretKey";
    private long expiration = 3600L * 24 * 7; // 7天
    public String generateToken(Long playerId, String username) {
        return Jwts.builder()
                .setSubject(username)
                .claim("playerId", playerId)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + expiration * 1000))
                .signWith(SignatureAlgorithm.HS512, secret)
                .compact();
    }
    public Claims parseToken(String token) {
        return Jwts.parser()
                .setSigningKey(secret)
                .parseClaimsJws(token)
                .getBody();
    }
}

配置类

// SecurityConfig.java
package com.game.backend.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .authorizeRequests()
                .antMatchers("/api/player/register", "/api/player/login").permitAll()
                .anyRequest().authenticated()
            .and()
            .httpBasic();
        return http.build();
    }
}

配置文件 application.yml

server:
  port: 8080
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/game_backend?useSSL=false&serverTimezone=UTC
    username: root
    password: yourpassword
    driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
  redis:
    host: localhost
    port: 6379
    database: 0
# 自定义配置
game:
  jwt:
    secret: GameBackendSecretKey
    expiration: 604800
  recharge:
    ratio: 10  # 1元=10钻石

数据库SQL

-- 创建数据库
CREATE DATABASE IF NOT EXISTS game_backend;
-- 玩家表
CREATE TABLE players (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) UNIQUE NOT NULL,
    password VARCHAR(100) NOT NULL,
    nickname VARCHAR(50),
    gold_coins INT DEFAULT 0,
    diamonds INT DEFAULT 0,
    level INT DEFAULT 1,
    experience INT DEFAULT 0,
    last_login_time DATETIME,
    create_time DATETIME,
    status INT DEFAULT 1
);
-- 游戏房间表
CREATE TABLE game_rooms (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    room_name VARCHAR(100),
    type INT,
    status INT,
    max_players INT,
    current_players INT DEFAULT 0,
    base_stake INT,
    create_time DATETIME
);
-- 充值记录表
CREATE TABLE recharge_records (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    player_id BIGINT,
    order_no VARCHAR(50) UNIQUE,
    amount DECIMAL(10,2),
    diamonds INT,
    status INT,
    pay_type VARCHAR(20),
    create_time DATETIME,
    pay_time DATETIME
);

使用说明

API接口测试

# 注册
curl -X POST http://localhost:8080/api/player/register \
  -H "Content-Type: application/json" \
  -d '{"username":"testPlayer","password":"123456"}'
# 登录
curl -X POST http://localhost:8080/api/player/login \
  -H "Content-Type: application/json" \
  -d '{"username":"testPlayer","password":"123456"}'
# 获取玩家信息(需要token)
curl -X GET http://localhost:8080/api/player/info/1 \
  -H "Authorization: Bearer {token}"
# 创建游戏房间
curl -X POST http://localhost:8080/api/game/createRoom \
  -H "Content-Type: application/json" \
  -d '{
    "roomName": "新手房",
    "type": 1,
    "maxPlayers": 4,
    "baseStake": 100
  }'
# 获取可用房间
curl -X GET http://localhost:8080/api/game/availableRooms

启动项目

# 确保MySQL和Redis已启动
# 运行项目
mvn spring-boot:run

这个游戏后台案例涵盖了:

  • 用户注册/登录
  • JWT认证
  • 游戏房间管理
  • 充值系统
  • 排行榜功能
  • 玩家数据管理

可以根据实际需求扩展功能,比如添加聊天系统、匹配系统、更多游戏类型等。

抱歉,评论功能暂时关闭!