本文目录导读:

我来提供一个完整的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认证
- 游戏房间管理
- 充值系统
- 排行榜功能
- 玩家数据管理
可以根据实际需求扩展功能,比如添加聊天系统、匹配系统、更多游戏类型等。