Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 |
Tags
- Websocket
- 빙고
- 수강관리앱
- Redis
- Get
- HTTP
- Redux
- 이벤트 루프
- 호이스팅
- 채팅앱
- 클로저
- NoSQL
- socket.io
- JQuery
- MONGOOSE
- 채팅 앱
- 스코프
- 크롤링
- MongoDB
- 데이터 엔지니어
- 공 피하기 게임
- 크롬확장앱
- 모듈
- 프로토타입패턴
- react
- post
- Firebase
- npm
- node.js
- crud
Archives
- Today
- Total
개발로그
socket.io를 이용한 빙고 게임 구현 본문
채팅 앱에 이어 빙고 게임도 socket.io를 이용해 구현해보자!

📌 빙고 게임 기능
1. 유저 이름 입력받기
2. 접속 중인 유저 이름 출력
3. 한 명이 게임을 시작하려 하면 막기, 알림 출력 (두 명 이상)
4. 게임 진행을 위해 턴 넘기기
5. 자기 턴이 아닐 경우 진행 불가능, 알림 출력
6. 숫자가 선택되면 상대방에게 알림 출력
7. 선택된 숫자에 글자 효과 주기
8. 게임이 진행 중일 때 상대방이 떠난 경우, 게임을 종료시키고 알림 출력하기
server.js
var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var path = require('path');
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', (req, res) => {
res.render('main', { title: '온라인 빙고 게임', username: req.query.username });
});
var users = {};
var user_count = 0;
var turn_count = 0;
io.on('connection', function(socket){
console.log('user connected : ', socket.id);
socket.on('join', function (data) {
var username = data.username;
socket.username = username;
users[user_count] = {};
users[user_count].id = socket.id;
users[user_count].name = username;
users[user_count].turn = false;
user_count++;
io.emit('update_users', users, user_count);
});
socket.on('game_start', function (data) {
socket.broadcast.emit("game_started", data);
users[turn_count].turn = true;
io.emit('update_users', users);
});
socket.on('select', function (data) {
socket.broadcast.emit("check_number", data);
users[turn_count].turn = false;
turn_count++;
if(turn_count >= user_count) {
turn_count = 0;
}
users[turn_count].turn = true;
io.sockets.emit('update_users', users);
});
socket.on('disconnect', function() {
console.log('user disconnected : ', socket.id, socket.username);
for(var i=0; i<user_count; i++){
if(users[i].id == socket.id)
delete users[i];
}
user_count--;
io.emit('update_users', users, user_count);
io.emit('user_gone');
});
});
http.listen(3000, function(){
console.log('server on!');
});
main.js
var bingo = {
is_my_turn: Boolean,
socket: null,
init: function(socket){
var self = this;
var user_cnt = 0;
this.is_my_turn = false;
socket = io();
socket.on("check_number", function (data) {
self.where_is_it(data.num);
self.print_msg(data.username + "님이 '" + data.num + "'을 선택했습니다.");
});
socket.on("game_started", function(data){
console.log("enter the game_started");
self.print_msg(data.username + " 님이 게임을 시작했습니다.");
$("#start_button").hide();
});
socket.on("update_users", function (data, user_count) {
console.log(data);
user_cnt = user_count;
self.update_userlist(data, socket);
});
socket.on("user_gone", function(){
self.print_msg("참가자 한 명이 게임을 종료했습니다.");
});
//join
$("#un").click(function (){
$("#un").hide();
socket.emit("join", { username: $('#username').val() });
$("#un").hide();
});
var numbers = [];
for(var i=1; i<=25; i++){
numbers.push(i);
}
numbers.sort(function (a,b) {
var temp = parseInt(Math.random() * 10);
var isOddOrEven = temp%2;
var isPosOrNeg = temp > 5 ? 1 : -1;
return (isOddOrEven*isPosOrNeg);
});
$("table.bingo-board td").each(function (i) {
$(this).html(numbers[i]);
$(this).click(function (){
if(user_cnt == 1){
self.print_msg("<알림> 최소 2명부터 게임이 가능합니다.");
}
else{
self.select_num(this, socket);
}
});
});
$("#start_button").click(function () {
if(user_cnt == 1){
self.print_msg("<알림> 최소 2명부터 게임이 가능합니다.");
}
else{
socket.emit('game_start', { username: $('#username').val() });
self.print_msg("<알림> 게임을 시작했습니다.");
$("#start_button").hide();
}
});
},
// init 끝
select_num: function (obj, socket) {
if(this.is_my_turn && !$(obj).attr("checked")) {
//send num to other players
socket.emit("select", { username: $('#username').val(), num: $(obj).text() });
this.check_num(obj);
this.is_my_turn = false;
}
else {
this.print_msg("<알림> 차례가 아닙니다!");
}
},
where_is_it: function (num) {
var self = this;
var obj = null;
$("table.bingo-board td").each(function (i) {
if ($(this).text() == num) {
self.check_num(this);
}
});
},
check_num: function (obj) {
$(obj).css("text-decoration", "line-through");
$(obj).css("color", "lightgray");
$(obj).attr("checked", true);
},
update_userlist: function (data, this_socket) {
var self = this;
$("#list").empty();
console.log(data);
$.each(data, function (key, value) {
var turn = "(-) ";
if(value.turn === true) {
turn = "(*) ";
if(value.id == this_socket.id ) {
self.is_my_turn = true;
}
}
if(value.id == this_socket.id){
$("#list").append("<font color='DodgerBlue'>" + turn + value.name + "<br></font>");
}
else{
$("#list").append("<font color='black'>" + turn + value.name + "<br></font>");
}
});
},
print_msg: function (msg) {
$("#logs").append(msg + "<br />");
$('#logs').scrollTop($('#logs')[0].scrollHeight);
}
};
$(document).ready(function () {
bingo.init();
});
main.pug
extends layout
block content
h1= title
p
font(color='DodgerBlue') #{username}
input#username(type= 'text', value= username)
input#un(type='button' value='참가')
| 님 환영합니다.
#game
#bingo
table.bingo-board
tr
td
td
td
td
td
tr
td
td
td
td
td
tr
td
td
td
td
td
tr
td
td
td
td
td
tr
td
td
td
td
td
#user
#list
#logs
input#start_button(type='button', value='Game Start!')
layout.pug
doctype html
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
script(src='/socket.io/socket.io.js')
script(src='//code.jquery.com/jquery.min.js')
script(src='/javascripts/main.js')
body
center
block content
style.css
body {
padding: 50px;
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
}
a {
color: #00B7FF;
}
#game {
width: 320px;
height: 300px;
}
#bingo {
float: center;
}
#user {
float: center;
}
#list {
border: 1px solid gray;
width: 300px;
height: 100px;
overflow: auto;
margin-bottom: 10px;
}
#logs {
border: 1px solid gray;
width: 300px;
height: 100px;
overflow: auto;
margin-bottom: 10px;
}
.bingo-board {
border-left: 1px solid gray;
border-top: 1px solid gray;
border-spacing: 0px;
margin-bottom: 20px;
text-align: center;
}
.bingo-board td {
width: 35px;
height: 35px;
border-right: 1px solid gray;
border-bottom: 1px solid gray;
}'IT' 카테고리의 다른 글
| Redis에 대해 알아보자! (1) | 2023.10.22 |
|---|---|
| mongoose에 대해 알아보자! (0) | 2023.10.20 |
| socket.io를 이용한 채팅 앱 구현 (0) | 2023.10.09 |
| Node.js에 대해 알아보자! (0) | 2023.09.30 |
| 객체지향 자바스크립트 (0) | 2023.09.29 |