10分钟开发一个游戏服务器

 

前言

  安利一个游戏服务器框架colyseus,使用起来十分简单,只需要一丢丢的代码就可以实现一个状态同步的服务器,10分钟主题,废话不多说,Let’s Rock!

安装&项目设置

  • 使用npm初始化项目
npm i -g typescript
npm init -y
tsc --init
npm i colyseus
npm i express @types/express @types/node @types/redis

编程ING

先码一遍代码比看着纸想有用. —–鲁迅

  • 入口文件 在主目录下新建一个index.ts文件
import { GameRoom } from './room/GameRoom';
import { Server } from 'colyseus';
import express from 'express';
import http from 'http';

const app = express();

// 初始化游戏服务器
const gameServer = new Server({
    server: http.createServer(app)
});

// 注册房间服务器
gameServer.register('game', GameRoom);

// 开始监听端口
gameServer.listen(3000);
console.log('server is on');
  • 新建一个文件夹room 新建一个GameRoom.ts文件
import { Room, Client } from 'colyseus';
import { PlayerState } from '../entity/PlayerState';

export class GameRoom extends Room<PlayerState> {
    // 房间内的最大人数
    maxClients: number = 2;

    // 房间初始化方法
    onInit(options: any) {
        console.log('ChatRoom onInit');
        // 设置需要更新的状态
        this.setState(new PlayerState());
        // 设置发送频率
        this.setPatchRate(50);
    }

    // 消息收取方法
    onJoin(client: Client) {
        this.state.addPlayer(client);
    }

    // 消息收取方法
    onLeave(client: Client) {
        this.state.removePlayer(client);
    }

    // 消息收取方法
    onMessage(client: Client, data: any): void {
        this.state.movePlayer(client, data.x, data.y);
    }

}
  • 新建一个文件夹entity 新建文件PlayerState.ts和Player.ts

  • PlayerState.ts

import { EntityMap, Client } from 'colyseus';
import { Player } from './Player';

export class PlayerState {
    // EntityMap是colyseus的对象实体模板
    players: EntityMap<Player> = {};

    /**
     * 添加新用户的方法
     *
     * @param {Client} client
     * @memberof PlayerState
     */
    addPlayer(client: Client) {
        let player = new Player(0, 0);
        this.players[client.sessionId] = player;
    }

    /**
     * 删除一个用户的方法
     *
     * @param {Client} client
     * @memberof PlayerState
     */
    removePlayer (client: Client) {
        delete this.players[ client.sessionId ];
    }

    /**
     * 移动用户的方法
     *
     * @param {Client} client
     * @param {number} [x=0]
     * @param {number} [y=0]
     * @memberof PlayerState
     */
    movePlayer(client: Client, x: number = 0, y: number = 0) {
        this.players[client.sessionId].x += x;
        this.players[client.sessionId].y += y;
        if(x > 0){
            this.players[client.sessionId].dir = true;
        } else {
            this.players[client.sessionId].dir = false;
        }
    }
}
  • Player.ts
import { randomChineseName } from '../Utils'
export class Player {
    public name: string;  // 名称
    public x: number;    // x轴的位置
    public y: number;   // y轴的位置
    public dir: boolean; // 玩家的方向(左 false 右 true) 简单定义
    constructor( x: number,  y: number,name?: string) {
        this.x = x;
        this.y = y;
        this.name = name || randomChineseName();
        this.dir = true;
    }
}
  • 根目录新建一个Utils.ts的文件
  • 一些基础工具方法写在这里
  • 现在又一个随机返回一个中文名称的方法
const NAMES: Array<string> = [
    '断笔画墨',
    '默然相爱',
    '旅人不扰',
    '多余温情',
    '云中谁忆',
    '残雪冰心',
    '末世岛屿',
    '桑榆非晚',
    '扉匣与桔',
    '木槿暖夏',
    '空城旧梦',
];

/**
 * 返回随机的中文名
 * 
 * @export
 * @returns {string}
 */
export function randomChineseName(): string {
    return NAMES[~~(NAMES.length * Math.random())];
}

简单分析

  • 不正确的图像架构

  • 一个游戏服务器下面可以开N个房间Room
  • Room中存在一个state的对象,发生变化时候同步到Room下的客户端
  • 使得客户端的状态保持一致
  • 这个就是colyseus实现的状态同步服务器

启动服务器

tsc && node ./dist/index.js

简单的客户端

源码地址:https://gitee.com/limo/simple_server

转自https://allknowboy.com/posts/a8be8288/

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
搭建一个简单的TCP服务器可以使用Python的socket库,具体步骤如下: 1. 创建socket对象,指定协议类型和地址族,例如: ``` import socket server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ``` 2. 绑定地址和端口,例如: ``` server_socket.bind(('localhost', 8888)) ``` 3. 开始监听请求,例如: ``` server_socket.listen(5) ``` 4. 接受客户端请求并处理,例如: ``` while True: client_socket, addr = server_socket.accept() print('连接地址:', addr) client_socket.send('欢迎访问服务器!'.encode('utf-8')) client_socket.close() ``` 至此,一个简单的TCP服务器就搭建好了。 接下来,可以开发一个功能完整的游戏,例如像2048一样的数字游戏。具体步骤如下: 1. 定义游戏规则和界面,例如: ``` 游戏规则: 1. 玩家使用方向键控制数字块的移动方向。 2. 相邻且数字相同的块会合并成一个新的块,数字为原来两个块的数字之和。 3. 每次移动后会随机生成一个新的数字块。 4. 当无法移动时,游戏结束。 游戏界面: ┌───┬───┬───┬───┐ │ 2 │ │ │ │ ├───┼───┼───┼───┤ │ │ │ │ │ ├───┼───┼───┼───┤ │ │ │ │ │ ├───┼───┼───┼───┤ │ │ │ │ │ └───┴───┴───┴───┘ ``` 2. 编写游戏逻辑,例如: ``` import random class Game: def __init__(self): self.board = [[0] * 4 for _ in range(4)] self.score = 0 def add_random_block(self): empty_cells = [(i, j) for i in range(4) for j in range(4) if self.board[i][j] == 0] if empty_cells: i, j = random.choice(empty_cells) self.board[i][j] = random.choices([2, 4], weights=[0.9, 0.1])[0] def can_move(self): for i in range(4): for j in range(4): if self.board[i][j] == 0: return True if i < 3 and self.board[i][j] == self.board[i + 1][j]: return True if j < 3 and self.board[i][j] == self.board[i][j + 1]: return True return False def move_left(self): for i in range(4): j = 0 while j < 3: if self.board[i][j] == 0: k = j + 1 while k < 4 and self.board[i][k] == 0: k += 1 if k < 4: self.board[i][j], self.board[i][k] = self.board[i][k], self.board[i][j] if self.board[i][j] != 0 and self.board[i][j] == self.board[i][j + 1]: self.board[i][j] *= 2 self.score += self.board[i][j] self.board[i][j + 1] = 0 j += 1 def move_right(self): for i in range(4): j = 3 while j > 0: if self.board[i][j] == 0: k = j - 1 while k >= 0 and self.board[i][k] == 0: k -= 1 if k >= 0: self.board[i][j], self.board[i][k] = self.board[i][k], self.board[i][j] if self.board[i][j] != 0 and self.board[i][j] == self.board[i][j - 1]: self.board[i][j] *= 2 self.score += self.board[i][j] self.board[i][j - 1] = 0 j -= 1 def move_up(self): for j in range(4): i = 0 while i < 3: if self.board[i][j] == 0: k = i + 1 while k < 4 and self.board[k][j] == 0: k += 1 if k < 4: self.board[i][j], self.board[k][j] = self.board[k][j], self.board[i][j] if self.board[i][j] != 0 and self.board[i][j] == self.board[i + 1][j]: self.board[i][j] *= 2 self.score += self.board[i][j] self.board[i + 1][j] = 0 i += 1 def move_down(self): for j in range(4): i = 3 while i > 0: if self.board[i][j] == 0: k = i - 1 while k >= 0 and self.board[k][j] == 0: k -= 1 if k >= 0: self.board[i][j], self.board[k][j] = self.board[k][j], self.board[i][j] if self.board[i][j] != 0 and self.board[i][j] == self.board[i - 1][j]: self.board[i][j] *= 2 self.score += self.board[i][j] self.board[i - 1][j] = 0 i -= 1 def play(self): while self.can_move(): self.add_random_block() self.print_board() direction = input('请输入方向(上下左右):') if direction == '左': self.move_left() elif direction == '右': self.move_right() elif direction == '上': self.move_up() elif direction == '下': self.move_down() else: print('无效的方向,请重新输入!') print('游戏结束!') print('得分:', self.score) def print_board(self): for i in range(4): print('┌───┬───┬───┬───┐') for j in range(4): print('│{:>3}'.format(self.board[i][j]), end='') print('│') if i == 3: print('└───┴───┴───┴───┘') else: print('├───┼───┼───┼───┤') ``` 3. 调用游戏逻辑,例如: ``` if __name__ == '__main__': game = Game() game.play() ``` 至此,一个功能完整的数字游戏开发完成了。可以将游戏逻辑和TCP服务器结合起来,实现多人在线游戏的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值