100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > 前端实现双人联机版俄罗斯方块小游戏2(实现双人联机)

前端实现双人联机版俄罗斯方块小游戏2(实现双人联机)

时间:2022-12-25 20:37:55

相关推荐

前端实现双人联机版俄罗斯方块小游戏2(实现双人联机)

基于websocket实现双人联机俄罗斯方块游戏,逻辑思路整理如下

思路整理1.游戏开始,双方都收到start消息,同时调用start方法2.start方法中,调用game.init方法,同时发送init消息给server,server收到后会转发给另一个游戏玩家3.另一个游戏玩家在remote.js中接收init,会驱动对方去调用start方法(next消息同init消息)整体代码local.jsremote.jswsServer.jsscript.js

思路整理

1.游戏开始,双方都收到start消息,同时调用start方法

socket.on('start', function () {document.getElementById('waiting').inneHTML = '';start();});

2.start方法中,调用game.init方法,同时发送init消息给server,server收到后会转发给另一个游戏玩家

game.init(doms, type, dir);socket.emit('init', {type: type,dir: dir});bindKeyEvent();var t = generateType();var d = generateDir();game.performNext(t, d);socket.emit('next', {type: t,dir: d})//wsServer.js中 server收到消息socket.on('init', function (data) {// 接收消息后,将其匹配给另一个socketif (socket.clientCount % 2 == 0) {socketMap[socket.clientCount - 1].emit('init', data);} else {socketMap[socket.clientCount + 1].emit('init', data);}});

3.另一个游戏玩家在remote.js中接收init,会驱动对方去调用start方法(next消息同init消息)

var bindEvents = function () {socket.on('init', function (data) {// 调用start,接收init消息和传递的参数,实现两个用户相连接(在对方区域中调用了start)start(data.type, data.dir);});socket.on('next', function (data) {// 驱动对方游戏区域也调用performNext函数game.performNext(data.type, data.dir);});}

整体代码

local.js

var Local = function (socket) {// 游戏对象var game;// 时间间隔 200毫秒var INTERVAL = 500;// 定时器var timer = null;// 绑定键盘事件// 时间计数器var timeConut = 0;var time = 0;var bindKeyEvent = function () {document.onkeydown = function (e) {if (e.keyCode == 38) {// 向上game.rotate();socket.emit("rotate");} else if (e.keyCode == 39) {// 向右game.right();socket.emit("right");} else if (e.keyCode == 40) {// 向下game.down();socket.emit("down");} else if (e.keyCode == 37) {// 向左game.left();socket.emit("left");} else if (e.keyCode == 32) {// 空格键game.fall();socket.emit("fall");}};};// 随机生成干扰行var generateBotLine = function (lineNum) {var lines = [];for (var i = 0; i < lineNum; i++) {var line = [];for (var j = 0; j < 10; j++) {line.push(Math.ceil(Math.random() * 2) - 1); // 生成 0 1 随机数}lines.push(line);}return lines;};// 移动var move = function () {timeFunc();// 不能下降再调用if (!game.down()) {// 落下的方块固定game.fixed();socket.emit("fixed");var line = game.checkClear();if (line) {// 行数不为0,则传入addScore函数game.addScore(line);socket.emit("line", line);if (line > 1) {var bottomLines = generataBottomLines(line);socket.emit('bottomLines', bottomLines);}}var gameOver = game.checkGameOver();if (gameOver) {game.gameOver(false);document.getElementById("remote_gameover").innerHTML = "你赢了";socket.emit("lose");stop();} else {var t = generateType();var d = generateDir();game.performNext(t, d);socket.emit("next", {type: t,dir: d,});}} else {socket.emit("down");}};// 计时函数var timeFunc = function () {timeConut = timeConut + 1;if (timeConut == 5) {timeConut = 0;time = time + 1;// 将更新的时间传入界面game.setTime(time);socket.emit("time", time);}};// 随机生成下一个方块var generateType = function () {// 随机生成0-6的整数return Math.ceil(Math.random() * 7) - 1;};// 随机生成旋转次数var generateDir = function () {// 随机生成0-3的整数return Math.ceil(Math.random() * 4) - 1;};// 开始var start = function () {var doms = {gameDiv: document.getElementById("local_game"),nextDiv: document.getElementById("local_next"),timeDiv: document.getElementById("local_time"),scoreDiv: document.getElementById("local_score"),resultDiv: document.getElementById("local_gameover"),};game = new Game();// 定义变量,用websocket将随机方向种类和方向generateType(), generateDir()通过对象形式到init,var type = generateType();var dir = generateDir();game.init(doms, type, dir);socket.emit("init", {type: type,dir: dir,});bindKeyEvent();var t = generateType();var d = generateDir();game.performNext(t, d);socket.emit("next", {type: t,dir: d,});timer = setInterval(move, INTERVAL);};// 结束,关闭计时var stop = function () {if (timer) {clearInterval(timer);timer = null;}document.onkeydown = null;};// 不用导出start了,用socket.on监听start,收到后,通过waiting设置页面显示为空;调用start开始游戏socket.on("start", function () {document.getElementById("waiting").innerHTML = "游戏开始!";start();});socket.on("lose", function () {game.gameOver(true);stop();});socket.on("leave", function () {document.getElementById("local_gameover").innerHTML = "对方掉线啦";document.getElementById("remote_gameover").innerHTML = "已掉线";stop();});socket.on('bottomLines', function (data) {game.addTailLines(data);socket.emit('addTailLines', data);})};

remote.js

var Remote = function (socket) {var game;var bindEvents = function () {socket.on('init', function (data) {// 调用start,接收init消息和传递的参数,实现两个用户相连接(在对方区域中调用了start)start(data.type, data.dir);});socket.on('next', function (data) {// 驱动对方游戏区域也调用performNext函数game.performNext(data.type, data.dir);});socket.on('rotate', function (data) {// 驱动对方游戏区域也调用performNext函数game.rotate();});socket.on('right', function (data) {// 驱动对方游戏区域也调用performNext函数game.right();});socket.on('left', function (data) {// 驱动对方游戏区域也调用performNext函数game.left();});socket.on('down', function (data) {// 驱动对方游戏区域也调用performNext函数game.down();});socket.on('line', function (data) {// 驱动对方游戏区域也调用performNext函数game.checkClear();game.addScore(data);});socket.on('fall', function (data) {// 驱动对方游戏区域也调用performNext函数game.fall();});socket.on('fixed', function (data) {// 驱动对方游戏区域也调用performNext函数game.fixed();});socket.on('time', function (data) {// 驱动对方游戏区域也调用performNext函数game.setTime(data);});socket.on('lose', function (data) {// 驱动对方游戏区域也调用performNext函数game.gameOver(false);});socket.on('addTailLines', function (data) {// 驱动对方游戏区域也调用performNext函数game.addTailLines(data);});}var start = function (type, dir) {var doms = {gameDiv: document.getElementById('remote_game'),nextDiv: document.getElementById('remote_next'),timeDiv: document.getElementById('remote_time'),scoreDiv: document.getElementById('remote_score'),resultDiv: document.getElementById('remote_gameover')}game = new Game();game.init(doms, type, dir);}bindEvents();}

wsServer.js

var app = require("http").createServer();var io = require("socket.io")(app);var PORT = 3000;// 客户端计数var clientCount = 0;// 保存客户端socketvar socketMap = {};app.listen(PORT);var bindListener = function (socket, event) {socket.on(event, function (data) {if (socket.clientNum % 2 == 0) {if (socketMap[socket.clientNum - 1])socketMap[socket.clientNum - 1].emit(event, data);} else {if (socketMap[socket.clientNum + 1])socketMap[socket.clientNum + 1].emit(event, data);}});}io.on("connection", function (socket) {// 用户连接进来后先进行客户加1clientCount++;socket.clientNum = clientCount;socketMap[clientCount] = socket;// 是单数个进来的用户需要等待if (clientCount % 2 == 1) {// 发送wait消息socket.emit("waiting", "等待玩家进入……");} else {if (socketMap[clientCount - 1]) {socket.emit("start");socketMap[(clientCount - 1)].emit("start");} else {socket.emit('leave');}}bindListener(socket, 'init');bindListener(socket, 'next');bindListener(socket, 'rotate');bindListener(socket, 'down');bindListener(socket, 'right');bindListener(socket, 'left');bindListener(socket, 'fall');bindListener(socket, 'fixed');bindListener(socket, 'line');bindListener(socket, 'time');bindListener(socket, 'lose');bindListener(socket, 'bottomLines');bindListener(socket, 'addTailLines');socket.on('disconnect', function () {if (socket.clientNum % 2 == 0) {if (socketMap[socket.clientNum - 1])socketMap[socket.clientNum - 1].emit('leave');} else {if (socketMap[socket.clientNum + 1])socketMap[socket.clientNum + 1].emit('leave');}delete(socketMap[socket.clientNum]);});});console.log("websocket listening on port" + PORT);

script.js

var socket = io('ws://localhost:3000');// 创建local对象并调用,传入socket对象var local = new Local(socket);var remote = new Remote(socket);socket.on('waiting', function (str) {document.getElementById('waiting').innerHTML = str;});

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。