質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.02%
Pug

Pug(旧Jade)とは、HTMLを書くためのテンプレートエンジン。タグで囲む必要がないなど記述を省略できるため、HTMLの記述が簡単になります。ファイル分割も可能で、変数やループなど便利な機能も備わっています。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Socket.IO

Socket.IOはNode.js上で動くライブラリであり、すべてのブラウザとモバイルデバイスでリアルタイムのアプリを作動させる事を目的としています。

Express

ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

Q&A

受付中

ボードゲームの駒の座標をsocket.ioで伝達処理したい。

mariko68311
mariko68311

総合スコア10

Pug

Pug(旧Jade)とは、HTMLを書くためのテンプレートエンジン。タグで囲む必要がないなど記述を省略できるため、HTMLの記述が簡単になります。ファイル分割も可能で、変数やループなど便利な機能も備わっています。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Socket.IO

Socket.IOはNode.js上で動くライブラリであり、すべてのブラウザとモバイルデバイスでリアルタイムのアプリを作動させる事を目的としています。

Express

ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

1回答

0グッド

0クリップ

658閲覧

投稿2022/02/15 15:30

私は通信対戦ができるボードゲームの作成をしているのですが、相手の駒と自分の駒の座標をsocket.ioを駆使して伝達し、通信対戦を実現したいと考えているのですが、どのようにして伝達処理をかけばいいかわかりません。誰かわかる方はいらっしゃいませんか?

発生している問題

下に表記していますが、型組になるであろうものまではできたのですが、
ここから何を書き足していけばいいかがわかりません。
根本からちがう可能性もありますが、

該当のソースコード

一部プログラムは関係ないため省いて記載しています。

js

1//server.js 2const socketPerRoom = 2 3let socketCount = 0 4 5io.on("connection", (socket) => { 6 console.log(`connection socket.id: ${socket.id}`) 7 socket.on("join", () => { 8 socketCount++ 9 const room = `room${Math.ceil(socketCount / socketPerRoom)}` 10 const num = socketCount % 2 11 // ソケットをルームに追加する 12 socket.join(room) 13 console.log(`join socket.id: ${socket.id}, socket.rooms: ${JSON.stringify([...socket.rooms])}`) 14 // ルーム全体に送信する(最大2つのソケット) 15 io.to(room).emit("joined", socket.id, room, num) 16 }) 17 //駒の座標を送る(予定) 18 socket.on("koma", (barr, warr) => { 19 io.sockets.emit("sou", barr, warr) 20 }) 21})

pug

1//play1.pug 2script(src="https://cdn.socket.io/4.4.1/socket.io.min.js", integrity="sha384-fKnu0iswBIqkjxrhQCTZ7qlLHOFEgNkRmK2vaO/LbTZSXdJfAu6ewRBdwHPhBo/H", crossorigin="anonymous") 3 4script. 5var barr = [1101,1102,1103,1104,1105,1106,1205,1204,1203,1202,1201]; 6var warr = [2107,2108,2109,2110,2111,2112,2211,2210,2209,2208,2207]; 7 8socket.emit("koma", warr); 9 socket.on("sou", (barr) => { 10 11 });

pug

1//play2.pug 2script(src="https://cdn.socket.io/4.4.1/socket.io.min.js", integrity="sha384-fKnu0iswBIqkjxrhQCTZ7qlLHOFEgNkRmK2vaO/LbTZSXdJfAu6ewRBdwHPhBo/H", crossorigin="anonymous") 3 4script. 5var barr = [1101,1102,1103,1104,1105,1106,1205,1204,1203,1202,1201]; 6var warr = [2107,2108,2109,2110,2111,2112,2211,2210,2209,2208,2207]; 7 8socket.emit("koma", barr); 9 socket.on("sou", (warr) => { 10 11 });

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

回答1

0

イベントのemitonの流れは大丈夫そうですね。

細かい処理に関しまして、いくつかコードのコメントとして書いてみました。

js

1// server.js 2//駒の座標を送る(予定) 3socket.on("koma", (barr, warr) => { 4 io.sockets.emit("sou", barr, warr) 5 // `io.sockets.emit`だとルーム内ではなく全体に送信されてしまいますので、ルームを指定して送信することになると思います。 6 // この時のルームの名前は、駒の座標と一緒にクライアントから送信してもらう形とかになると思います。 7 // io.to(room).emit("sou", barr, warr) 8})

pug

1//- play1.pug 2//- サーバー側の「koma」ではbarrとwarrの2つの引数を受け取ることになっていますので、クライアント側からもbarrとwarrの2つの引数を送信します(「sou」も同様です)。 3//- socket.emit("koma", barr, warr); 4//- socket.on("sou", (barr, warr) => { 5socket.emit("koma", warr); 6socket.on("sou", (barr) => { 7 8});

イベントの引数については次のページが参考になると思います。
Basic emit
https://socket.io/docs/v4/emitting-events/#basic-emit


前の質問の段階でちょっと問題があったようでして、
クライアント側のSocket.IOのインスタンス(socket変数)はページ遷移してしまうと消えてしまいます。
同じルームに2人が追加されたのに、ページ遷移すると同じルームの人として扱うことができなくなってしまいます。
インスタンスの生成のオプションがあるか調べましたが、次のリンクにはそのような内容は見当たりませんでした。

Client options (IO factory options)
https://socket.io/docs/v4/client-options/

基本的にはSocket.IO接続したら、ページ遷移せずに、シングルページで扱う実装方針が良い印象でした。

play1.pugとplay2.pugは見た目や動きが全く異なるものになるでしょうか?
共通の実装にすると問題が出てしまいますでしょうか?

追記(2022/02/17)

matching.pugから/playに遷移して、サーバー側でplay1.pugとplay2.pugに振り分けるサンプルを作ってみました。
play1.pugとplay2.pugの初期表示時にSocket.IOで接続してルームに追加します。
上の方にあるテキストボックスを入力して、ボタンをクリックすると駒の座標を送信します。
(テストのためbarr、warr配列の1つ目だけを入れ替えて送信してみました)
サーバー側では駒の座標を受け取って、ルームの中の人にそれらの情報を送信します。

js

1// app.js 2const express = require("express") 3const { createServer } = require("http") 4const { Server } = require("socket.io") 5 6const app = express() 7const httpServer = createServer(app) 8const io = new Server(httpServer, { /* options */ }) 9const port = 3000 10 11app.set("view engine", "pug") 12 13app.get("/", (req, res) => { 14 res.render("index", { title: "Hey", message: "Hello there!" }) 15}) 16 17app.get("/matching", (req, res) => { 18 res.render("matching") 19}) 20 21const socketPerRoom = 2 22let socketCount = 0 23 24app.get("/play", (req, res) => { 25 // ルームを決定してplay1.pugとplay2.pugに振り分ける 26 socketCount++ 27 const room = `room${Math.ceil(socketCount / socketPerRoom)}` 28 const num = socketCount % 2 === 1 ? 1 : 2 29 const playView = `play${num}` 30 res.render(playView, { room, num }) 31}) 32 33io.on("connection", (socket) => { 34 console.log(`connection socket.id: ${socket.id}`) 35 socket.on("join", (room, num) => { 36 socket.join(room) 37 console.log(`join socket.id: ${socket.id}, socket.rooms: ${JSON.stringify([...socket.rooms])}`) 38 io.to(room).emit("joined", socket.id, room, num) 39 }) 40 socket.on("koma", (barr, warr, room, num) => { 41 console.log(`barr: ${barr}, warr: ${warr}, room: ${room}, num: ${num}`) 42 io.to(room).emit("sou", barr, warr, num) 43 }) 44}) 45 46httpServer.listen(port, () => { 47 console.log(`Example app listening on port ${port}`) 48})

pug

1//- matching.pug 2html 3 head 4 meta(charset="utf-8") 5 title= "matching" 6 body 7 h1= "matching" 8 a(href="play") フリーマッチングする

pug

1//- play1.pug 2html 3 head 4 meta(charset="utf-8") 5 title= "play1" 6 script(src="https://cdn.socket.io/4.4.1/socket.io.min.js", integrity="sha384-fKnu0iswBIqkjxrhQCTZ7qlLHOFEgNkRmK2vaO/LbTZSXdJfAu6ewRBdwHPhBo/H", crossorigin="anonymous") 7 body 8 h1= "play1" 9 div 10 input#text1(type="text", value="1234") 11 div 12 button#button1(type="button") 送信する 13 ul#ul1 14 li= "接続中です。ルーム:" + room + "、プレイヤー:" + num 15 script. 16 window.addEventListener("DOMContentLoaded", () => { 17 //-- ビューのローカル変数をJavaScriptで参照する 18 const room = "#{room}" 19 const num = #{num} 20 21 const socket = io() 22 socket.on("connect", () => { 23 append(`接続しました。ソケットID:${socket.id}`) 24 }) 25 socket.on("disconnect", () => { 26 console.log(`disconnect: ${socket.id}`) 27 }) 28 socket.on("joined", (socketId, roomName, playerNum) => { 29 append(`ルームに追加されました。ソケットID:${socketId}、ルーム:${roomName}、プレイヤー:${playerNum}`) 30 }) 31 32 var barr = [1101,1102,1103,1104,1105,1106,1205,1204,1203,1202,1201]; 33 var warr = [2107,2108,2109,2110,2111,2112,2211,2210,2209,2208,2207]; 34 const button1 = document.querySelector("#button1") 35 button1.addEventListener("click", () => { 36 // プレイヤー1はbarrの要素の1つ目を変更して送信 37 const text1 = document.querySelector("#text1") 38 const b = [text1.value, ...barr.slice(1)] 39 socket.emit("koma", b, warr, room, num) 40 }) 41 socket.on("sou", (retbarr, retwarr, retnum) => { 42 append(`プレイヤー${retnum}が送信しました。${retbarr}、${retwarr}`) 43 barr = retbarr 44 warr = retwarr 45 }) 46 47 //- サーバーに送信する(ルームに追加するためのイベント) 48 socket.emit("join", room, num) 49 const append = text => { 50 const li1 = document.createElement('li') 51 li1.textContent = text 52 const ul1 = document.querySelector("#ul1") 53 ul1.append(li1) 54 } 55 })

pug

1//- play2.pug 2html 3 head 4 meta(charset="utf-8") 5 title= "play2" 6 script(src="https://cdn.socket.io/4.4.1/socket.io.min.js", integrity="sha384-fKnu0iswBIqkjxrhQCTZ7qlLHOFEgNkRmK2vaO/LbTZSXdJfAu6ewRBdwHPhBo/H", crossorigin="anonymous") 7 body 8 h1= "play2" 9 div 10 input#text1(type="text", value="2234") 11 div 12 button#button1(type="button") 送信する 13 ul#ul1 14 li= "接続中です。ルーム:" + room + "、プレイヤー:" + num 15 script. 16 window.addEventListener("DOMContentLoaded", () => { 17 //-- ビューのローカル変数をJavaScriptで参照する 18 const room = "#{room}" 19 const num = #{num} 20 21 const socket = io() 22 socket.on("connect", () => { 23 append(`接続しました。ソケットID:${socket.id}`) 24 }) 25 socket.on("disconnect", () => { 26 console.log(`disconnect: ${socket.id}`) 27 }) 28 socket.on("joined", (socketId, roomName, playerNum) => { 29 append(`ルームに追加されました。ソケットID:${socketId}、ルーム:${roomName}、プレイヤー:${playerNum}`) 30 }) 31 32 var barr = [1101,1102,1103,1104,1105,1106,1205,1204,1203,1202,1201]; 33 var warr = [2107,2108,2109,2110,2111,2112,2211,2210,2209,2208,2207]; 34 const button1 = document.querySelector("#button1") 35 button1.addEventListener("click", () => { 36 // プレイヤー2はwarrの要素の1つ目を変更して送信 37 const text1 = document.querySelector("#text1") 38 const w = [text1.value, ...warr.slice(1)] 39 socket.emit("koma", barr, w, room, num) 40 }) 41 socket.on("sou", (retbarr, retwarr, retnum) => { 42 append(`プレイヤー${retnum}が送信しました。${retbarr}、${retwarr}`) 43 barr = retbarr 44 warr = retwarr 45 }) 46 47 //- サーバーに送信する(ルームに追加するためのイベント) 48 socket.emit("join", room, num) 49 const append = text => { 50 const li1 = document.createElement('li') 51 li1.textContent = text 52 const ul1 = document.querySelector("#ul1") 53 ul1.append(li1) 54 } 55 })

動かした時のイメージです。
2つのウィンドウを用意して、それぞれmatching.pugを表示、それぞれ「フリーマッチングする」をクリックしてページ遷移します。
イメージ説明

投稿2022/02/16 00:11

編集2022/02/17 06:27
退会済みユーザー

退会済みユーザー

総合スコア0

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

mariko68311

2022/02/16 02:25 編集

いえ、変わるのは駒の向きくらいですね。 チェスとかでいう白側と黒側の位置が変わる感じです。 向きのリバース表示については、 var direflag=true;//向き管理 という変数で行っています。 これはIF文でtrueとfalseをそれぞれに送る処理を書けば大丈夫でしょうか、、、
mariko68311

2022/02/16 02:33

ちなみに、今ページ遷移で使っていたscript文はこんな感じです。 //matching.pug script. window.addEventListener("DOMContentLoaded", () => { const button1 = document.querySelector("#button1") button1.addEventListener("click", () => { //- Socket.IO接続 const socket = io() socket.on("connect", () => { //- 接続した時のイベント //- ソケットのIDをコンソールと画面のリストに出力する console.log(`connect: ${socket.id}`) const li1 = document.createElement('li') //- li1.textContent = `connect socket.id: ${socket.id}` const ul1 = document.querySelector("#ul1") ul1.append(li1) }) socket.on("disconnect", () => { console.log(`disconnect: ${socket.id}`) }) socket.on("joined", (socketId, room, flg) => { //- ルームに追加した時のイベント //- ルームに追加されたソケットのIDとルームの名前をコンソールと画面のリストに出力する console.log(`joined socketId: ${socketId}, room: ${room}`) const li1 = document.createElement('li') //- li1.textContent = `joined socketId: ${socketId}, room: ${room}, flg: ${flg}` const ul1 = document.querySelector("#ul1") ul1.append(li1) if(flg == 1){ window.location.href = "/play1"; //- window.close() }else if(flg == 0){ window.location.href = "/play2"; //- window.close() } }) //- サーバーに送信する(ルームに追加するためのイベント) socket.emit("join") }) })
退会済みユーザー

退会済みユーザー

2022/02/16 03:44

> チェスとかでいう白側と黒側の位置が変わる感じです。 手前から攻めていくような見た目になるのですね。 混乱させてしまうかもしれませんが、すみません。 play1.pugとplay2.pugは無理に共通にする必要はないかもしれません。 > ちなみに、今ページ遷移で使っていたscript文はこんな感じです。 //matching.pug このmatching.pugの中で行なっているSocket.IO接続を、play1.pugとplay2.pug側に移動するようなイメージなると思います。
mariko68311

2022/02/16 04:28

と、いうと今までmatching.pugに書いていた記述をそのままそれぞれのplay.pugにコピーしたら大丈夫ですかね?
退会済みユーザー

退会済みユーザー

2022/02/16 05:37

> と、いうと今までmatching.pugに書いていた記述をそのままそれぞれのplay.pugにコピーしたら大丈夫ですかね? 具体的な画面遷移やmatching.pugの内容を把握しきれていないかもしれませんが、 そのままコピーで大丈夫と思います。 質問は編集できますので(質問欄の方がコードが見やすいですので)、 一度、ページ遷移なしでSocket.IO接続している状態のコードをご記載いただいた方が良いかもしれません。 それをベースに、タイトルにある「ボードゲームの駒の座標をsocket.ioで伝達処理したい。」の具体的な内容が回答できると思います。
mariko68311

2022/02/16 06:12

matching.pugの全体図のことを言われているのならこうなると思います。 doctype html html head meta(charset="UTF-8") link(rel="stylesheet", href="./css/style_matching.css") title マッチング設定 script(src="https://cdn.socket.io/4.4.1/socket.io.min.js", integrity="sha384-fKnu0iswBIqkjxrhQCTZ7qlLHOFEgNkRmK2vaO/LbTZSXdJfAu6ewRBdwHPhBo/H", crossorigin="anonymous") body // マイページの位置を整えるためのタグ ul(id="ul1" style="list-style: none;") p.margin p.sctitle マッチング設定 table.tablecenter tr // フリーマッチングボタン td(rowspan="2") form .freecenter img(src="./images/matching/FreeMatching.jpg", value="join", id="button1", alt="フリーマッチングする") // 部屋を作るボタン td .pu-box label(for="pu-on") .btn-open1 img(src="./images/matching/MakeARoom.jpg", alt="部屋を作成する") input#pu-on(type="checkbox") .pu // ポップアップの中身 .pu-content .popdate table.tablecenter // パスワードを設定しない tr td(rowspan="2", width="50") form(name="Form1", method="post", action="#") input#passout(type="radio", name="pass", value="1", style="transform: scale(3.0);", onClick="InRoompass()", checked) td.choicetitle label(for="passout") | パスワードを設定しない tr td.infor ※フリーマッチングを選択したユーザとマッチングします // パスワードを設定する tr td(rowspan="2", width="50") input#passin(type="radio", name="pass", value="2", style="transform: scale(3.0);", onClick="InRoompass()") td.choicetitle label(for="passin") | パスワードを設定する tr td input#roompass.in(type="password", name="roompassword") // ポップアップ内のボタン .popbutton label.icon-close(for="pu-on") img.layer-img(src="./images/matching/return.jpg", alt="マッチング設定画面へ戻る") form#piSet(action="/waitingformatching_room") .delete input(type="image", src="./images/matching/decision.jpg", alt="部屋を作成する") // ./ポップアップの中身 ここまで tr // 部屋を探すボタン td .pu-box label(for="pu-on2") .btn-open2 img(src="./images/matching/FindARoom.jpg", alt="部屋を探す") input#pu-on2(type="checkbox") .pu2 // ポップアップの中身 .pu-content .popdate table.tablecenter // 部屋IDの入力 tr td p.intext 部屋ID tr td input#roomid.in(type="text", name="roomid") // パスワードの入力 tr td p.intext パスワード tr td input#roompass.in(type="text", name="roompassword") // ポップアップ内のボタン .popbutton label.icon-close(for="pu-on2") img.layer-img(src="./images/matching/return.jpg", alt="マッチング設定画面へ戻る") form#piSet(action="/waitingformatching _moveplay") .delete input(type="image", src="./images/matching/decision.jpg", alt="部屋に入る") // ./ポップアップの中身 ここまで // ゲームモード選択に戻るボタン form(action="/waitingformatching_room") .center input(type="image", src="./images/matching/ReturnToGameModeSelection.jpg", alt="ゲームモード選択に戻る") script(type="text/javascript"). function InRoompass() { if ( document.Form1["pass"][1].checked ) { document . Form1["roompassword"] . disabled = false; } else { document . Form1["roompassword"] . disabled = true; document.getElementById("roompass").value = ""; } } window.onload = InRoompass; script. window.addEventListener("DOMContentLoaded", () => { const button1 = document.querySelector("#button1") button1.addEventListener("click", () => { //- Socket.IO接続 const socket = io() socket.on("connect", () => { //- 接続した時のイベント //- ソケットのIDをコンソールと画面のリストに出力する console.log(`connect: ${socket.id}`) const li1 = document.createElement('li') //- li1.textContent = `connect socket.id: ${socket.id}` const ul1 = document.querySelector("#ul1") ul1.append(li1) }) socket.on("disconnect", () => { console.log(`disconnect: ${socket.id}`) }) socket.on("joined", (socketId, room, flg) => { //- ルームに追加した時のイベント //- ルームに追加されたソケットのIDとルームの名前をコンソールと画面のリストに出力する console.log(`joined socketId: ${socketId}, room: ${room}`) const li1 = document.createElement('li') //- li1.textContent = `joined socketId: ${socketId}, room: ${room}, flg: ${flg}` const ul1 = document.querySelector("#ul1") ul1.append(li1) //- if(flg == 1){ //- window.location.href = "/play1"; //- //- window.close() //- }else if(flg == 0){ //- window.location.href = "/play2"; //- //- window.close() //- } }) //- サーバーに送信する(ルームに追加するためのイベント) socket.emit("join") }) }) audio(preload="auto", autoplay, loop) source(src="./mp3/Start.mp3")
退会済みユーザー

退会済みユーザー

2022/02/16 06:54

!!・・インデントやシンタックスハイライトなしのコードは厳しいですね・・ サーバー側で勝手にルームを割り当てるのは、「フリーマッチングする」のためなのですかね。 ボタンをクリックした時の処理でSocket.IO接続をしていると思いますが、 この処理をplay1.pug、play2.pugの中で行います。 (ページ遷移前であるmatching.pugの中で行なってしまうと、遷移後のページで同じ人として扱われなくなってしまうためです) `button1.addEventListener("click", () => {` Socket.IOはページ遷移してしまうと、遷移前の情報が失われてしまいますので、 その辺りの技術的な制約を踏まえた上で、画面遷移を設計しないといけないと思いました。
mariko68311

2022/02/16 07:04

ということは、matching.pugには script. window.addEventListener("DOMContentLoaded", () => { const button1 = document.querySelector("#button1") button1.addEventListener("click", () => { //if文の指定を変更 if(){ window.location.href = "/play1"; //- window.close() }else if(){ window.location.href = "/play2"; //- window.close() } }) }) を残しつつ、遷移した後のpugファイルに //- Socket.IO接続 const socket = io() socket.on("connect", () => { //- 接続した時のイベント //- ソケットのIDをコンソールと画面のリストに出力する console.log(`connect: ${socket.id}`) const li1 = document.createElement('li') //- li1.textContent = `connect socket.id: ${socket.id}` const ul1 = document.querySelector("#ul1") ul1.append(li1) }) socket.on("disconnect", () => { console.log(`disconnect: ${socket.id}`) }) socket.on("joined", (socketId, room, flg) => { //- ルームに追加した時のイベント //- ルームに追加されたソケットのIDとルームの名前をコンソールと画面のリストに出力する console.log(`joined socketId: ${socketId}, room: ${room}`) const li1 = document.createElement('li') //- li1.textContent = `joined socketId: ${socketId}, room: ${room}, flg: ${flg}` const ul1 = document.querySelector("#ul1") ul1.append(li1) }) //- サーバーに送信する(ルームに追加するためのイベント) socket.emit("join") をそれぞれ記入するのが正しい、のでしょうか、?
mariko68311

2022/02/16 07:08 編集

あと、roomを勝手に振り分けるのは「フリーマッチング」をするためという解釈で大丈夫です。 いつかは部屋を作成する、部屋を探す、といった機能を入れたいと思っていますが、まずはフリーマッチングが先ではないかと思いまして。
退会済みユーザー

退会済みユーザー

2022/02/16 07:31

> をそれぞれ記入するのが正しい、のでしょうか、? そのようなイメージです。 ただ、ページ遷移の前にルームを決定しないと、play1.pugに遷移するのか、play2.pugに遷移するのか判断できなそうですね。 ルームの名前を決定する部分はSocket.IOとは切り離して考えても良いと思います。 ルームの名前を返すAPIを用意して(併せてプレイヤーの1番目か2番目かも返すようにして)、Fetch APIなどで取得しても良いと思います。 https://developer.mozilla.org/ja/docs/Web/API/Fetch_API > いつかは部屋を作成する、部屋を探す、といった機能を入れたいと思っていますが、まずはフリーマッチングが先ではないかと思いまして。 コメントありがとうございます。 賛成です。
mariko68311

2022/02/16 07:41 編集

roomの名前をsocket.ioなしで決定して、APIを用意して取得するとなると、その記述先はserver.jsになるでしょうか?今までserver.jsの、 const socketPerRoom = 2 let socketCount = 0 io.on("connection", (socket) => { console.log(`connection socket.id: ${socket.id}`) socket.on("join", () => { socketCount++ const room = `room${Math.ceil(socketCount / socketPerRoom)}` const num = socketCount % 2 // ソケットをルームに追加する socket.join(room) console.log(`join socket.id: ${socket.id}, socket.rooms: ${JSON.stringify([...socket.rooms])}`) // ルーム全体に送信する(最大2つのソケット) io.to(room).emit("joined", socket.id, room, num) }) //駒の座標を送る(予定) socket.on("koma", (barr, warr) => { io.to(room).emit("sou", barr, warr) }) }) の一部分である、 socket.on("join", () => { socketCount++ const room = `room${Math.ceil(socketCount / socketPerRoom)}` const num = socketCount % 2 // ソケットをルームに追加する socket.join(room) console.log(`join socket.id: ${socket.id}, socket.rooms: ${JSON.stringify([...socket.rooms])}`) // ルーム全体に送信する(最大2つのソケット) io.to(room).emit("joined", socket.id, room, num) }) の部分で部屋の名前を作成して振り分けしていると考えていたもので、、、
退会済みユーザー

退会済みユーザー

2022/02/16 07:58

そうですね。 「ソケットをルームに追加する」の直前でルームの名前とプレイヤーの番号を決定していると思います。 この部分を切り出して別のAPIにして、JSONで返すイメージですかね。 `res.send({ room, num })`で返すことができると思いますが、どうでしょうか。
mariko68311

2022/02/16 08:11

直前となると、 socketCount++ const room = `room${Math.ceil(socketCount / socketPerRoom)}` const num = socketCount % 2 を切り出せばいいのでしょうか?今記述してみた感じこうなりました。 socket.on("join", () => { res.send({ room, num }) // ソケットをルームに追加する socket.join(room) console.log(`join socket.id: ${socket.id}, socket.rooms: ${JSON.stringify([...socket.rooms])}`) // ルーム全体に送信する(最大2つのソケット) io.to(room).emit("joined", socket.id, room, num) }) ただ、matching.pug内の画面遷移記述が変わっちゃったのですぐには呼び出せているかの確認が取れません、、、
退会済みユーザー

退会済みユーザー

2022/02/16 08:27

言葉だけで説明するのが難しいですね・・ `socket.on`の中で`res.send({ room, num })`してしまっては問題ですね・・ 動きが理解できない場合は、小さなサンプルアプリを作ってみて確認してみると良いと思います。 `socket.on("join"` ではルームの名前を引数に受け取る形に修正することになると思います。 クライアント側からルームの名前を送信して、そのルームの名前を元にルームに追加する感じですが、一旦、おいておいて。 それとは別に、次のようなAPIを作る感じです。 ```js app.get('/getroom', (req, res) => { socketCount++ const room = `room${Math.ceil(socketCount / socketPerRoom)}` const num = socketCount % 2 res.send({ room, num }) }) ```
mariko68311

2022/02/16 13:35

うーん、、、サンプルを作りたいのはやまやまなのですが休日じゃないとその時間すら確保できるかわからないですね、とりあえず今までjsファイルの socketCount++ const room = `room${Math.ceil(socketCount / socketPerRoom)}` const num = socketCount % 2 で作っていた部分をplay.pugの方で作って、上で書いてもらったプログラムをjsファイルに使って、 io.on("connection", (socket) => { console.log(`connection socket.id: ${socket.id}`) socket.on("join", () => { // ソケットをルームに追加する socket.join(room) console.log(`join socket.id: ${socket.id}, socket.rooms: ${JSON.stringify([...socket.rooms])}`) // ルーム全体に送信する(最大2つのソケット) io.to(room).emit("joined", socket.id, room, num) }) //駒の座標を送る(予定) socket.on("koma", (barr, warr) => { io.to(room).emit("sou", barr, warr) }) }) app.get('/getroom', (req, res) => { socketCount++ const room = `room${Math.ceil(socketCount / socketPerRoom)}` const num = socketCount % 2 res.send({ room, num }) }) と記述するのが正解なんでしょうか、でもこれ、/getroomの中身はjoinの中で記述していたことですよね、となるとclient.jsを作ってそこに app.get('/getroom', (req, res) => { socketCount++ const room = `room${Math.ceil(socketCount / socketPerRoom)}` const num = socketCount % 2 res.send({ room, num }) }) を入れるのが正解なのでしょうか、焦りで頭がこんがらかっているのか理解追いつかなくて申し訳ないです、
退会済みユーザー

退会済みユーザー

2022/02/17 00:20 編集

うまく回答できなくてごめんなさい・・ あれから自分の中でも整理してみまして、matching.pugから画面遷移する部分について、もう少しシンプルにできそうでした。 matching.pugからplay1かplay2かは判断せずに、サーバー側でルームを決定しつつ画面遷移(1か2かを判断しつつ)するのはどうでしょうか。 (matching.pugからフリーマッチングで画面遷移する際は、プレイヤー1もプレイヤー2も"/play"になります) ```js // server.js app.get("/play", (req, res) => { socketCount++ const room = `room${Math.ceil(socketCount / socketPerRoom)}` const num = socketCount % 2 // 1番目は"play1.pug"へ、2番目は"play2.pug"へ const playView = `play${num === 1 ? 1 : 2}` res.render(playView, { room, num }) }) ``` ```pug //- play1.pug html head title= "play1" body h1= "play1" //- pugの中でroomとnumが使えます p= "ルーム:" + room p= "プレイヤー:" + num ``` > 焦りで頭がこんがらかっているのか理解追いつかなくて申し訳ないです、 難しいですけれども、焦らずに、ですね。 自分で理解しないままだと、コメントのやり取りだけで余計な時間がかかってしまうと思いますので、少しずつでも理解してみてください。
mariko68311

2022/02/17 13:15

あわわ、わざわざ新しいサンプルをありがとうございます! >自分で理解しないままだと、コメントのやり取りだけで余計な時間がかかってしまうと思いますので、少しずつでも理解してみてください。 まさしくその通りだと思います。とりあえずいただいたサンプルを組み立ててみて動きについて理解する必要がありそうですね、一回落ち着きます()
退会済みユーザー

退会済みユーザー

2022/02/17 13:56

今日は落ち着いているようでよかったです。 私も合間に作っているだけですので、これが一番良いわけではないですし、問題もあるかもしれません・・ (意味不明なコードがありましたらコメントください)
mariko68311

2022/02/17 16:04

ごめんなさい、夜遅くに失礼します、 Failed to lookup view "index" in views directory とエラーが出てきているので、 app.set("view engine", "pug") app.get("/", (req, res) => { res.render("index", { title: "Hey", message: "Hello there!" }) } が機能しておらず、index.pugがないためこのようなエラーがでてしまっているのだと思います。 なので、index.pugがあるのなら教えていただきたいです。 ちなみに、 app.get("/", (req, res) => { res.render("index", { title: "Hey", message: "Hello there!" }) } をコメントアウトし、 app.get("/", (req, res) => { res.render("matching") }) とすることでmatching.pugに飛ぶことができたのですが、肝心のplay.pugに飛んだあとbarrとwarrの送信がうまくいっていないようでした。どこでやっているのかまでは判断できていませんが、もしかしてplay.pug側のscript文を修正した方が早く解決したりしますか?
退会済みユーザー

退会済みユーザー

2022/02/17 23:19

> なので、index.pugがあるのなら教えていただきたいです。 ごめんなさい、ここは適当で良いのでアップしていませんでした・・ 試したようにmatching.pugに変更してもいいですし、次のようなほぼ空っぽのページでOKです。 ```pug //- index.pug html head title= title body h1= message ``` > 肝心のplay.pugに飛んだあとbarrとwarrの送信がうまくいっていないようでした。 どこまで動いていますか? 「接続中」の文字などは表示されていますでしょうか? ブラウザーのコンソールにエラーメッセージなどは表示されていますでしょうか?
mariko68311

2022/02/18 00:09

なるほど、ほとんど空の状態でよかったんですね、自分で作って大丈夫でしたか、、、ごめんなさい。 写真を貼れないのでメッセージを直接書くのですが、 play1には 接続中です。 接続しました。 ルームに追加されました。 プレイヤー1が送信しました。 と書いてあるのですが、 play2.pugでは 接続中です。 としか書かれていません。遷移はできていてもroomの接続はうまくいっていないということでしょうか。 ちなみにエラー文は一切なしですね、とりあえずindex.pugを入れた状態も動かしてみようと思います。
mariko68311

2022/02/18 00:12

あっ、当たり前でした、index.pugに遷移するため機能がないので"/"の移動先をmatching.pugにするのが懸命みたいですね、気づくのが遅かったです、、、
mariko68311

2022/02/18 00:20

今再度プログラムをコピぺしたら治りました。どうやら一部分のコピペに失敗していただけなようです、ご迷惑をおかけしました。
退会済みユーザー

退会済みユーザー

2022/02/18 00:21

「接続中です。」の部分はスクリプトなしのpug(HTML)の部分ですので、スクリプト自体が動いていないのですかね。 もう一度、ソースコードをコピペしてみたらどうでしょうか? play1とplay2を比較するとbarrとwarrの部分しか差分はないはずですので、play1.pugが動けばplay2.pugも動くと思います。
退会済みユーザー

退会済みユーザー

2022/02/18 00:22

あれれ、入れ違いですみません・・
mariko68311

2022/02/18 00:49

いえいえ、こちらこそ初歩的なミスで申し訳ないです。
mariko68311

2022/02/18 01:39

すみません、またわからないことができてしまいました。 私はてっきり、 matching.pugの a(href="play") フリーマッチングする が押されたときに、app.jsの app.get("/play", (req, res) => { // ルームを決定してplay1.pugとplay2.pugに振り分ける socketCount++ const room = `room${Math.ceil(socketCount / socketPerRoom)}` const num = socketCount % 2 === 1 ? 1 : 2 const playView = `play${num}` res.render(playView, { room, num }) }) が働いて遷移処理を行っているとおもっていたのですがあっていますか? 実は本来のプログラムに組み込もうとしたところ、 matching.pugに form .freecenter img(src="./images/matching/FreeMatching.jpg", value="join", href="playmatch", alt="フリーマッチングする") として、server.jsに app.get("/playmatch", (req, res) => { // ルームを決定してplay1.pugとplay2.pugに振り分ける socketCount++ const room = `room${Math.ceil(socketCount / socketPerRoom)}` const num = socketCount % 2 === 1 ? 1 : 2 const playView = `play${num}` res.render(playView, { room, num }) }) として動かなかったため、私の認識が間違っているのかと思いまして。
mariko68311

2022/02/18 01:46

ちなみに調べてみたところ、href属性はa要素などに使うもの、と分かってはいるのですが、img要素で使うsrc属性は既に画像を指定してしまっているので、そのままhrefを使ったのですが、href属性が使えないのか私の認識が間違っているのかわからないので聞いてみました、
退会済みユーザー

退会済みユーザー

2022/02/18 02:11

> が働いて遷移処理を行っているとおもっていたのですがあっていますか? 大丈夫です、合っています。 > として動かなかったため、私の認識が間違っているのかと思いまして。 imgタグでhref属性は使えないですね。 aタグにする必要もないのですが(ボタンなどでも良いと思います)、次のリンクのような形で画像を表示したリンクにしたりするようです。 画像リンク https://developer.mozilla.org/ja/docs/Web/HTML/Element/img#image_link
mariko68311

2022/02/18 02:16

.freecenter a(href="playmatch") img(src="./images/matching/FreeMatching.jpg", value="join", alt="フリーマッチングする") と記述したら無事に遷移できました!あとはbarrとwarrを飛ばせれば、って感じですね、
mariko68311

2022/02/18 03:44

すみません、上で質問を編集して記述しようとしたのですが無理だったのでここに書きます。 const button1 = document.querySelector("#button1") button1.addEventListener("click", () => { // プレイヤー1はbarrの要素の1つ目を変更して送信 const text1 = document.querySelector("#text1") const b = [text1.value, ...barr.slice(1)] socket.emit("koma", b, warr, room, num) }) のbutton1に成り代わるもの本プログラム内で探していたのですが、 var Cflag=false;がtrueになった瞬間が一番良いとわかりました。(間違っているかもしれません。) ですが、それを呼び出す記述が分からなくなってしまったうえに、trueになる処理はclick.jsにあったため、play.pugの中に書くものではないかもしれないのですが、下記にのせる全体図をみて判断できたりしますか、?やっつけだとは思うのですが、、、
mariko68311

2022/02/18 03:44

// play1.pug doctype html html(lang="ja") head audio(loop, autoplay) source(src="mp3/playBGM.mp3") audio#audio title ALGO MATCH link(rel="icon", type="image/png", href="img/icon.png") meta(http-equiv="content-type", charset="UTF-8") link#stylech(rel="stylesheet", href="css/sample.css") script(src="https://cdn.socket.io/4.4.1/socket.io.min.js", integrity="sha384-fKnu0iswBIqkjxrhQCTZ7qlLHOFEgNkRmK2vaO/LbTZSXdJfAu6ewRBdwHPhBo/H", crossorigin="anonymous") #popWin .pop-win p#battle 弦 p#goresu リザルト詳細へ #sppop .sp-pop-win a#cancel キャンセル a#domove 実行 p#log(style="text-align:left;") #Menupop .Menu-pop p#menu.Menu メニュー p#close.Menu 再開 p#end.Menu 終了 p#pouse.Menu カウントストップ // <p class="Menu" id="direi">1秒</p> body ul#ul1 li= "接続中です。ルーム:" + room + "、プレイヤー:" + num script. const close = document.getElementById('close'); const Menupop = document.getElementById('Menupop'); const end = document.getElementById('end'); const cancel = document.getElementById('cancel'); const domove = document.getElementById('domove'); const direi=document.getElementById('direi'); const goresu=document.getElementById('goresu'); const pouse=document.getElementById('pouse'); pouse.addEventListener('click',()=>{ count_stop(); count_stop2(); }); goresu.addEventListener('click',() => { doc(); }); // direi.addEventListener('click',() => { // if(direitime<10000){ // direitime+=1000; // }else{ // direitime=1000; // } // document.getElementById("direi").innerText =direitime/1000+"秒"; // }); close.addEventListener('click', () => { Menupop.style.display = 'none'; // var h1 = document.getElementById( 'wbaria' ); wbaria.style.position='relative'; // var h1 = document.getElementById( 'wback' ); wback.style.position='relative'; // var h1 = document.getElementById( 'wchange' ); wchange.style.position='relative'; // h1 = document.getElementById( 'passbutton' ); passbutton.style.position='relative'; // h1 = document.getElementById( 'popup' ); popup.style.position='relative'; }); end.addEventListener('click', () => { window.location.href = '../../../../index.html'; }); cancel.addEventListener('click', () => { sppop.style.display = 'none'; Wbariflag=false; Wchangeflag=false; Wbackflag=false; // var h1 = document.getElementById( 'passbutton' ); passbutton.style.position='relative'; // h1 = document.getElementById( 'popup' ); popup.style.position='relative'; }); domove.addEventListener('click', () => { sppop.style.display = 'none'; spmoves(); // var h1 = document.getElementById( 'passbutton' ); passbutton.style.position='relative'; // h1 = document.getElementById( 'popup' ); popup.style.position='relative'; if(Wbariflag==true){ changeId('wbaria',"wbaria2"); msg=msg+"駒バリアを\n実行しました。\n"; document.getElementById("sptext").innerText =msg; } if(Wbackflag==true){ changeId('wback',"wback2"); msg=msg+"駒振り出しを\n実行しました。\n"; document.getElementById("sptext").innerText =msg; } if(Wchangeflag==true){ changeId('wchange',"wchange2"); msg=msg+"駒入れ替えを\n実行しました。\n"; document.getElementById("sptext").innerText =msg; } Wbackflag=false; }); //piece[]空白0, //黒[1(while),2(switch),3(IFelsex2),4(IFelse),5(IF),6(base)] //白[7(while),8(switch),9(IFelsex2),10(IFelse),11(IF),12(base)] var piece=["./images/img1/speace.png","./images/img1/Bwhile.gif","./images/img1/Bswitch.gif","./images/img1/BIFelsex2.gif","./images/img1/BIFelse.gif","./images/img1/BIF.gif","./images/img1/Bbase.gif","./images/img1/while.gif","./images/img1/switch.gif","./images/img1/IFelsex2.gif","./images/img1/IFelse.gif","./images/img1/IF.gif","./images/img1/base.gif"]; var nicepiece=["赤色表示","./images/img1/reverse/nice/niceBwhile.gif","./images/img1/reverse/nice/niceBswitch.gif","./images/img1/reverse/nice/niceBIFelsex2.gif","./images/img1/reverse/nice/niceBIFelse.gif","./images/img1/reverse/nice/niceBIF.gif","./images/img1/reverse/nice/niceBbase.gif","./images/img1/reverse/nice/nicewhile.gif","./images/img1/reverse/nice/niceswitch.gif","./images/img1/reverse/nice/niceIFelsex2.gif","./images/img1/reverse/nice/niceIFelse.gif","./images/img1/reverse/nice/niceIF.gif","./images/img1/reverse/nice/nicebase.gif"]; var rpiece=["./images/img1/speace.png","./images/img1/reverse/rBwhile.gif","./images/img1/reverse/rBswitch.gif","./images/img1/reverse/rBIFelsex2.gif","./images/img1/reverse/rBIFelse.gif","./images/img1/reverse/rBIF.gif","./images/img1/reverse/rBbase.gif","./images/img1/reverse/rwhile.gif","./images/img1/reverse/rswitch.gif","./images/img1/reverse/rIFelsex2.gif","./images/img1/reverse/rIFelse.gif","./images/img1/reverse/rIF.gif","./images/img1/reverse/rbase.gif"]; var rnicepiece=["赤色表示反転","./images/img1/reverse/rnice/rniceBwhile.gif","./images/img1/reverse/rnice/rniceBswitch.gif","./images/img1/reverse/rnice/rniceBIFelsex2.gif","./images/img1/reverse/rnice/rniceBIFelse.gif","./images/img1/reverse/rnice/rniceBIF.gif","./images/img1/reverse/rnice/rniceBbase.gif","./images/img1/reverse/rnice/rnicewhile.gif","./images/img1/reverse/rnice/rniceswitch.gif","./images/img1/reverse/rnice/rniceIFelsex2.gif","./images/img1/reverse/rnice/rniceIFelse.gif","./images/img1/reverse/rnice/rniceIF.gif","./images/img1/reverse/rnice/rnicebase.gif"]; var rbsuccpiece=["./images/img1/succspeace.png","./images/img1/reverse/rsucc/rsuccBwhile.gif","./images/img1/reverse/rsucc/rsuccBswitch.gif","./images/img1/reverse/rsucc/rsuccBIFelsex2.gif","./images/img1/reverse/rsucc/rsuccBIFelse.gif","./images/img1/reverse/rsucc/rsuccBIF.gif","./images/img1/reverse/rsucc/rsuccBbase.gif","./images/img1/reverse/nice/nicewhile.gif","./images/img1/reverse/nice/niceswitch.gif","./images/img1/reverse/nice/niceIFelsex2.gif","./images/img1/reverse/nice/niceIFelse.gif","./images/img1/reverse/nice/niceIF.gif","./images/img1/reverse/nice/nicebase.gif"]; var rwsuccpiece=["./images/img1/succspeace.png","./images/img1/reverse/nice/niceBwhile.gif","./images/img1/reverse/nice/niceBswitch.gif","./images/img1/reverse/nice/niceBIFelsex2.gif","./images/img1/reverse/nice/niceBIFelse.gif","./images/img1/reverse/nice/niceBIF.gif","./images/img1/reverse/nice/niceBbase.gif","./images/img1/reverse/rsucc/rsuccwhile.gif","./images/img1/reverse/rsucc/rsuccswitch.gif","./images/img1/reverse/rsucc/rsuccIFelsex2.gif","./images/img1/reverse/rsucc/rsuccIFelse.gif","./images/img1/reverse/rsucc/rsuccIF.gif","./images/img1/reverse/rsucc/rsuccbase.gif"]; var movepiece=["./images/img1/speace.png","./images/img1/reverse/move/moveBwhile.gif","./images/img1/reverse/move/moveBswitch.gif","./images/img1/reverse/move/moveBIFelsex2.gif","./images/img1/reverse/move/moveBIFelse.gif","./images/img1/reverse/move/moveBIF.gif","./images/img1/reverse/move/moveBbase.gif","./images/img1/reverse/move/movewhile.gif","./images/img1/reverse/move/moveswitch.gif","./images/img1/reverse/move/moveIFelsex2.gif","./images/img1/reverse/move/moveIFelse.gif","./images/img1/reverse/move/moveIF.gif","./images/img1/reverse/move/movebase.gif"]; var order=[[1101,1102,1103,1104,1105,1106,1205,1204,1203,1202,1201],[0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0],[2107,2108,2109,2110,2111,2112,2211,2210,2209,2208,2207]]; var barr = [1101,1102,1103,1104,1105,1106,1205,1204,1203,1202,1201]; var warr = [2107,2108,2109,2110,2111,2112,2211,2210,2209,2208,2207]; var flag=true;//ターン管理 var flag2=true; var direflag=true;//向き管理 var Wflag=true;// var Bflag=true; var Cflag=false;//BASE var Bcnt=0; var Wcnt=0; var Tcnt=0; var sumcnt=0; var sumcnt2=0; var spflag=false; var Wbariflag=false; var Wbariadflag=false; var Bbariflag=false; var Bbariadflag=false; var Wchangeflag=false; var Wchangeadflag=false; var Bchangeflag=false; var Bchangeadflag=false; var Wbackflag=false; var Wbackadflag=false; var Bbackflag=false; var Bbackadflag=false; var likepiceW=0; var likepiceB=0; var change=0; var changei=0; var changej=0; var a=0; var b=0; var spdo=0; var spmsg="特殊命令文"; var logtxt1=""; var logtxt2=""; var whitekill="Wkill["; var blackkill="Bkill["; var msg=""; var ifx=5; var ify=5; var max=2; var min=-2; var spdom=""; var direitime=1000; var direi2=500; var sunrise="プレイヤー1\nVS\nプレイヤー2"; //black var b_switchx=-1; var b_switchy=1; var b_switchx2=1; var b_switchy2=-1; var b_ifelsexx=0; var b_ifelsexy=-2; var b_ifelsexx2=-1; var b_ifelsexy2=-1; var b_ifelsexx3=1; var b_ifelsexy3=-1; var b_ifelsex=0; var b_ifelsey=-1; var b_ifelsex2=-1; var b_ifelsey2=1; var b_whilex=1; var b_whiley=1; var b_ifx=1; var b_ify=-1; //white var w_switchx=1; var w_switchy=-1; var w_switchx2=-1; var w_switchy2=1; var w_ifelsexx=0; var w_ifelsexy=2; var w_ifelsexx2=1; var w_ifelsexy2=1; var w_ifelsexx3=-1; var w_ifelsexy3=1; var w_ifelsex=0; var w_ifelsey=1; var w_ifelsex2=1; var w_ifel
mariko68311

2022/02/18 03:45

// click.js function func1(id){ var numi=parseInt(id/1000000); var numj=parseInt((id/10000)-(numi*100)); var loopflag=false; if(direflag==true){ if(flag==true&&flag2==true&&Wchangeflag==true&&Wchangeadflag==true){ if(change<1){ if(check(order[numi][numj])==2&&order[numi][numj]!=2112){ change+=1; ChangeImage(id,nicepiece[order[numi][numj]%100]); changei=numi; changej=numj; } }else{ if(order[numi][numj]!=order[changei][changej]&&check(order[numi][numj])==2){ // spChange(1,numi,numj,changei,changej); ChangeImage(id,nicepiece[order[numi][numj]%100]); Wchangeflag=false; change=0; flag=false; flag2=false; Tcnt+=1; // reverse(); setTimeout(function(){ spChange(1,numi,numj,changei,changej); count_start2(); },500); setTimeout(function(){blackmoves()},1000); setTimeout(function(){reverse()},1001); } }////////////////// } if((id%10000==2112)&&flag==true&&flag2==true&&Cflag==false&&Wchangeflag==false&&Wbackflag==false&&Wbariflag==false){ Cflag=true; for(var cyclei=numi-1;cyclei<=numi+1;cyclei++){//周囲駒 for(var cyclej=numj-1;cyclej<=numj+1;cyclej++){ if(cyclei>=0&&cyclej>=0&&cyclei<11&&cyclej<11&&order[cyclei][cyclej]!=2112){ if(check(order[cyclei][cyclej])==0){//周囲の確認 ChangeImage(zero(cyclei*1000000+cyclej*10000+order[cyclei][cyclej]),"./images/img1/succspeace.png"); } if(check(order[cyclei][cyclej])==1){ ChangeImage(zero(cyclei*1000000+cyclej*10000+order[cyclei][cyclej]),nicepiece[order[cyclei][cyclej]%100]); } } } } }else if(Cflag==true){//BASE駒 loopflag=true; for(var cyclei=numi-1;cyclei<=numi+1;cyclei++){//周囲に駒があるかどうか for(var cyclej=numj-1;cyclej<=numj+1;cyclej++){ if(cyclei>=0&&cyclej>=0&&cyclei<11&&cyclej<11){ if(order[cyclei][cyclej]==2112&&flag==true&&check(order[numi][numj])!=2){ // audio.src='mp3/clickSE.mp3'; // audio.play(); //audioを再生 loopflag=false; switch(order[numi][numj]%100){ case 1: whitekill=whitekill+"while駒"; break; case 2: whitekill=whitekill+"switch駒"; break; case 3: whitekill=whitekill+"IFelsex2駒"; break; case 4: whitekill=whitekill+"IFelse駒"; break; case 5: whitekill=whitekill+"IF駒"; break; case 6: whitekill=whitekill+"base駒"; break; } ChangeImage(id,piece[12]);//駒を入れ替えて動いているように見せる ChangeImage(zero(cyclei*1000000+cyclej*10000+order[cyclei][cyclej]),piece[0]); changeId(id,zero(numi*1000000+numj*10000+order[cyclei][cyclej])); changeId(zero(cyclei*1000000+cyclej*10000+order[cyclei][cyclej]),zero(cyclei*1000000+cyclej*10000)); order[numi][numj]=order[cyclei][cyclej]; order[cyclei][cyclej]=0; whitemoves();//周囲の駒を動かす document.getElementById("text").innerText = "白のBASE駒\nゲーム中にプレイヤーが任意で動かす駒。周囲1マスいずれかに移動できる。\nこの駒にはプログラムを設定できない。"; flag2=false; // Wflag=true; audio.src='mp3/clickSE.mp3'; audio.play(); //audioを再生 } if(loopflag==false){ cyclei=numi+2; cyclej=numj+2; } } } } Cflag=false; reverse(); } } }
mariko68311

2022/02/18 03:45

// moves.js function func1(id){ var numi=parseInt(id/1000000); var numj=parseInt((id/10000)-(numi*100)); var loopflag=false; if(direflag==true){ if(flag==true&&flag2==true&&Wchangeflag==true&&Wchangeadflag==true){ if(change<1){ if(check(order[numi][numj])==2&&order[numi][numj]!=2112){ change+=1; ChangeImage(id,nicepiece[order[numi][numj]%100]); changei=numi; changej=numj; } }else{ if(order[numi][numj]!=order[changei][changej]&&check(order[numi][numj])==2){ // spChange(1,numi,numj,changei,changej); ChangeImage(id,nicepiece[order[numi][numj]%100]); Wchangeflag=false; change=0; flag=false; flag2=false; Tcnt+=1; // reverse(); setTimeout(function(){ spChange(1,numi,numj,changei,changej); count_start2(); },500); setTimeout(function(){blackmoves()},1000); setTimeout(function(){reverse()},1001); } }////////////////// } if((id%10000==2112)&&flag==true&&flag2==true&&Cflag==false&&Wchangeflag==false&&Wbackflag==false&&Wbariflag==false){ Cflag=true; for(var cyclei=numi-1;cyclei<=numi+1;cyclei++){//周囲駒 for(var cyclej=numj-1;cyclej<=numj+1;cyclej++){ if(cyclei>=0&&cyclej>=0&&cyclei<11&&cyclej<11&&order[cyclei][cyclej]!=2112){ if(check(order[cyclei][cyclej])==0){//周囲の確認 ChangeImage(zero(cyclei*1000000+cyclej*10000+order[cyclei][cyclej]),"./images/img1/succspeace.png"); } if(check(order[cyclei][cyclej])==1){ ChangeImage(zero(cyclei*1000000+cyclej*10000+order[cyclei][cyclej]),nicepiece[order[cyclei][cyclej]%100]); } } } } }else if(Cflag==true){//BASE駒 loopflag=true; for(var cyclei=numi-1;cyclei<=numi+1;cyclei++){//周囲に駒があるかどうか for(var cyclej=numj-1;cyclej<=numj+1;cyclej++){ if(cyclei>=0&&cyclej>=0&&cyclei<11&&cyclej<11){ if(order[cyclei][cyclej]==2112&&flag==true&&check(order[numi][numj])!=2){ // audio.src='mp3/clickSE.mp3'; // audio.play(); //audioを再生 loopflag=false; switch(order[numi][numj]%100){ case 1: whitekill=whitekill+"while駒"; break; case 2: whitekill=whitekill+"switch駒"; break; case 3: whitekill=whitekill+"IFelsex2駒"; break; case 4: whitekill=whitekill+"IFelse駒"; break; case 5: whitekill=whitekill+"IF駒"; break; case 6: whitekill=whitekill+"base駒"; break; } ChangeImage(id,piece[12]);//駒を入れ替えて動いているように見せる ChangeImage(zero(cyclei*1000000+cyclej*10000+order[cyclei][cyclej]),piece[0]); changeId(id,zero(numi*1000000+numj*10000+order[cyclei][cyclej])); changeId(zero(cyclei*1000000+cyclej*10000+order[cyclei][cyclej]),zero(cyclei*1000000+cyclej*10000)); order[numi][numj]=order[cyclei][cyclej]; order[cyclei][cyclej]=0; whitemoves();//周囲の駒を動かす document.getElementById("text").innerText = "白のBASE駒\nゲーム中にプレイヤーが任意で動かす駒。周囲1マスいずれかに移動できる。\nこの駒にはプログラムを設定できない。"; flag2=false; // Wflag=true; audio.src='mp3/clickSE.mp3'; audio.play(); //audioを再生 } if(loopflag==false){ cyclei=numi+2; cyclej=numj+2; } } } } Cflag=false; reverse(); } } }
退会済みユーザー

退会済みユーザー

2022/02/18 04:13

> 下記にのせる全体図をみて判断できたりしますか、? ごめんなさい、ちょっと難しいかもしれません・・ (コメント欄だとインデントも消えてしまって・・、ちゃんと把握しようと思うと時間がかかりそうです・・) 既にこんなに実装されていたのですね。 `Cflag`は駒の状態が変わったことを表すフラグですかね。 そうだとするとtrueになった瞬間が良いというお話は納得します。
mariko68311

2022/02/18 04:25

上で編集しようかとすると更新理由でどれだけ書いてもエラーが出てしまって、、
退会済みユーザー

退会済みユーザー

2022/02/18 04:28

> 上で編集しようかとすると更新理由でどれだけ書いてもエラーが出てしまって、、 どんなエラーですか?
mariko68311

2022/02/18 04:33

>既にこんなに実装されていたのですね。 と、言っても実際にこれを書いたのは私ではないんですけどね、私はこれを作成した方からある程度の動きを聞かされていて、修正をかけている感じです。 >`Cflag`は駒の状態が変わったことを表すフラグですかね。 そうだとするとtrueになった瞬間が良いというお話は納得します。 その解釈で大丈夫です、ありがとうございます!
mariko68311

2022/02/18 04:36

>どんなエラーですか? 30文字以上、10000字以内までで書いてください。みたいなエラーでした、赤色の。 自分で文字数を数えたんですが、明らかに70文字くらいは書いているのになんでだろう、という感じです。内部で制限が書き換わっちゃっているんでしょうかね、、、不具合なら運営さんに言うべきだとは思うのですが。
退会済みユーザー

退会済みユーザー

2022/02/18 04:38

> 30文字以上、10000字以内までで書いてください。みたいなエラーでした、赤色の。 理由欄の文字数のことではなく、本文の文字数かもしれませんね。
mariko68311

2022/02/18 04:46 編集

>理由欄の文字数のことではなく、本文の文字数かもしれませんね。 そういうことでしたか、となるとそもそもコメント欄に書いたpugやjsをすべて更新するのは難しそうですね、、、というより一つも無理ですね、おそらく。
mariko68311

2022/02/18 07:26 編集

すみません、play1.pugが途中で途切れていることに今気づきました。続きを下記にのせておきます。 // play1.pug var b_ifelsey2=1; var b_whilex=1; var b_whiley=1; var b_ifx=1; var b_ify=-1; //white var w_switchx=1; var w_switchy=-1; var w_switchx2=-1; var w_switchy2=1; var w_ifelsexx=0; var w_ifelsexy=2; var w_ifelsexx2=1; var w_ifelsexy2=1; var w_ifelsexx3=-1; var w_ifelsexy3=1; var w_ifelsex=0; var w_ifelsey=1; var w_ifelsex2=1; var w_ifelsey2=-1; var w_whilex=-1; var w_whiley=-1; var w_ifx=-1; var w_ify=1; var tt=0; script(type="text/javascript", src="./js1/diction.js") script(type="text/javascript", src="./js1/spmoves.js") script(type="text/javascript", src="./js1/time.js") script(type="text/javascript", src="./js1/resalt.js") script(type="text/javascript", src="./js1/tenp.js") script(type="text/javascript", src="./js1/blackmoves.js") script(type="text/javascript", src="./js1/whitemoves.js") script(type="text/javascript", src="./js1/ban.js") script(type="text/javascript", src="./js1/dire.js") script(type="text/javascript", src="./js1/pas.js") script(type="text/javascript", src="./js1/moves.js") script(type="text/javascript", src="./js1/click.js") script. window.addEventListener("DOMContentLoaded", () => { //-- ビューのローカル変数をJavaScriptで参照する const room = "#{room}" const num = #{num} const socket = io() socket.on("connect", () => { append(`接続しました。ソケットID:${socket.id}`) }) socket.on("disconnect", () => { console.log(`disconnect: ${socket.id}`) }) socket.on("joined", (socketId, roomName, playerNum) => { append(`ルームに追加されました。ソケットID:${socketId}、ルーム:${roomName}、プレイヤー:${playerNum}`) }) //- //- var barr = [1101,1102,1103,1104,1105,1106,1205,1204,1203,1202,1201]; //- //- var warr = [2107,2108,2109,2110,2111,2112,2211,2210,2209,2208,2207]; //- const button1 = document.querySelector("#button1") //- button1.addEventListener("click", () => { //- // プレイヤー1はbarrの要素の1つ目を変更して送信 //- const text1 = document.querySelector("#text1") //- const b = [text1.value, ...barr.slice(1)] //- socket.emit("koma", b, warr, room, num) //- }) //- socket.on("sou", (retbarr, retwarr, retnum) => { //- append(`プレイヤー${retnum}が送信しました。${retbarr}、${retwarr}`) //- barr = retbarr //- warr = retwarr //- }) //- サーバーに送信する(ルームに追加するためのイベント) socket.emit("join", room, num) const append = text => { const li1 = document.createElement('li') li1.textContent = text const ul1 = document.querySelector("#ul1") ul1.append(li1) } })
mariko68311

2022/02/18 07:27

現状、play1.pugのscript文を入れた後、 //- var barr = [1101,1102,1103,1104,1105,1106,1205,1204,1203,1202,1201]; //- var warr = [2107,2108,2109,2110,2111,2112,2211,2210,2209,2208,2207]; const button1 = document.querySelector("#button1") button1.addEventListener("click", () => { // プレイヤー1はbarrの要素の1つ目を変更して送信 const text1 = document.querySelector("#text1") const b = [text1.value, ...barr.slice(1)] socket.emit("koma", b, warr, room, num) }) socket.on("sou", (retbarr, retwarr, retnum) => { append(`プレイヤー${retnum}が送信しました。${retbarr}、${retwarr}`) barr = retbarr warr = retwarr }) をコメントアウトすることで connection socket.id: GDmz-d72D3pK7aU2AAAB join socket.id: GDmz-d72D3pK7aU2AAAB, socket.rooms: ["GDmz-d72D3pK7aU2AAAB","room1" と正確にログが出ているので、room機能の振り分けまではこれで追加できたと思います。 あとはコメントアウトしている部分の記述をどう変えて、既に上のscript文で書かれているbarrとwarrを呼び出すか、となりそうです。
退会済みユーザー

退会済みユーザー

2022/02/18 09:20

着実に進めているようで何よりです。 > 既に上のscript文で書かれているbarrとwarrを呼び出すか `barr`と`warr`は関数・メソッドではなく、変数なので、「呼び出す」という考え方ではないように思います・・ ここから先、既存の処理と組み合わせるのはちょっと難しいようにも思います。 `Cflag`がtrueになった瞬間に処理するのが良いということで、コールバック関数のような感じで実装することになりそうに思いましたが、 ご自身の実装イメージが既にあるようでしたら、スルーしてください・・ Callback function (コールバック関数) https://developer.mozilla.org/ja/docs/Glossary/Callback_function
mariko68311

2022/02/18 12:48

いえ、全然イメージは湧いていなかったのでめちゃくちゃありがたいです。コールバック関数ですよね、ありがたく参考にさせていただきます()、正直また詰まっておりました、、
mariko68311

2022/02/21 14:44

間が空いてしまってすみません。なぜかパスが通らない部分があってお聞きしたくて。 play1.pugに使っているmove.jsの if(flag == false){ socket.emit("koma", barr, warr, room, num) socket.on("sou", (retbarr, retwarr, retnum) => { append(`プレイヤー${retnum}が送信しました。${retbarr}、${retwarr}`) barr = retbarr warr = retwarr }) socket.emit("join", room, num) const append = text => { const li1 = document.createElement('li') li1.textContent = text const ul1 = document.querySelector("#ul1") ul1.append(li1) } alert(flag); testflg='false'; } と、server.jsの io.on("connection", (socket) => { console.log(`connection socket.id: ${socket.id}`) socket.on("join", (room, num) => { socket.join(room) console.log(`join socket.id: ${socket.id}, socket.rooms: ${JSON.stringify([...socket.rooms])}`) io.to(room).emit("joined", socket.id, room, num) }) socket.on("koma", (barr, warr, room, num) => { console.log(`barr: ${barr}, warr: ${warr}, room: ${room}, num: ${num}`) io.to(room).emit("sou", barr, warr, num) }) }) の部分でmove.jsの"koma"は動くんですが、"sou"の方が動いていなくて、何が原因かわかりますか?私にはちゃんとパスが通っているように見えてしまいまして。
退会済みユーザー

退会済みユーザー

2022/02/21 14:57 編集

> 間が空いてしまってすみません。なぜかパスが通らない部分があってお聞きしたくて。 大丈夫です。 ちゃんと読み切れていないかもしれませんが、、 `socket.on("sou",`が`if(flag == false){`の中に入っているところが気になりますね。 `socket.on`はサーバー側から送られてきた時にだけ自動的に処理してくれるものですので、 `if`の中に記述する必要はないと思います。 というより、Socket.IO接続した時に一度だけ`socket.on`しておくもので、 ユーザーがコマを移動するたびに`socket.on`すると 何度もサーバーからの受信処理を行なってしまう(同じ処理を2回、3回、、、)ことになりそうです。
mariko68311

2022/02/22 03:00

いま、無事パスが通って表示できました。 play1.pugで socket.on("sou", (retbarr, retwarr, retnum) => { append(`プレイヤー${retnum}が送信しました。${retbarr}、${retwarr}`) barr = retbarr warr = retwarr }) socket.emit("join", room, num) const append = text => { const li1 = document.createElement('li') li1.textContent = text const ul1 = document.querySelector("#ul1") ul1.append(li1) } と記述することで治りました。 それと、調べてもよくわからなかったのでお聞きしたいのですが、onとemitを利用して、whitemoves();と言った関数を飛ばすことってできますか?今まで変数を送ることはあっても関数を送ったことはなかったもので、上のゲームのプログラムを作った方が白側の駒を動かす関数を黒側でも動かして見せたいらしくて。リアルタイム通信実現に必須かもなのですが、そもそも関数を飛ばせるのかがわからなくて。
退会済みユーザー

退会済みユーザー

2022/02/22 03:42

> と記述することで治りました。 よかったです。 > onとemitを利用して、whitemoves();と言った関数を飛ばすことってできますか? すごいことを考えますね(私にはそういう発想がありませんでした)。 第一級関数と言われる(その言語の関数がその他の変数と同様に扱われる)らしいですので、可能な気がします。 ちょっと確認してみます。 ですが、可能だとしてもあまりSocket.IOでは使わない方が良さそうな印象です。 素直にクライアント側に共通のスクリプトファイルを作って、play1.pugとplay2.pugから読み込んで使った方が良い気がします。 (その送信したい”関数”がクロージャの形となると、ちょっとそれはSocket.IOでは無理そうな気もします) https://developer.mozilla.org/ja/docs/Glossary/First-class_Function https://developer.mozilla.org/ja/docs/Web/JavaScript/Closures
退会済みユーザー

退会済みユーザー

2022/02/22 04:27

確認してみました。 関数を送信することは可能でした。 (クロージャもOKみたいでした) ただ、ルームに送信すると次のエラーになります(対応していないようです)。 個別のプレイヤー(ソケットごと)に送信する必要があるみたいです。 throw new Error("Callbacks are not supported when broadcasting"); それから、`return`を含む関数を送信しても、受信側で`return`の結果は受け取れないようでした。 抜粋ですが、次のコードで確認しました。 ```js // server.js socket.on("koma", (barr, warr, room, num, func1) => { console.log(`barr: ${barr}, warr: ${warr}, room: ${room}, num: ${num}, func1: ${func1}`) io.to(room).emit("sou", barr, warr, num) // 関数はルームに送信することができないようです socket.emit("soufunc", num, func1) }) ``` ```pug //- play1.pug button1.addEventListener("click", () => { // プレイヤー1はbarrの要素の1つ目を変更して送信 const text1 = document.querySelector("#text1") const b = [text1.value, ...barr.slice(1)] socket.emit("koma", b, warr, room, num, func1) }) socket.on("soufunc", (retnum, retfunc) => { append(`プレイヤー${retnum}が送信しました。${retfunc}`) retfunc(10) }) const localvar = 100 const func1 = (arg) => { console.log(localvar + arg) } ```
mariko68311

2022/02/22 06:25

>確認してみました。 ご確認ありがとうございました。ルームに送信ができないとなると、最初に言っていた「素直にクライアント側に共通のスクリプトファイルを作って、play1.pugとplay2.pugから読み込んで使った方が良い気がします。」を実行する方針がよさそうですかね?
退会済みユーザー

退会済みユーザー

2022/02/22 06:32

> を実行する方針がよさそうですかね? 個人的にはそうするかもしれませんね。 Socket.IOは通信環境に依存してしまいますので、通信異常などを考慮し始めると面倒そうですので、Socket.IOに頼らずに済むのであれば、できるだけSocket.IOを使わない方針にしたいかもしれません。
mariko68311

2022/02/22 07:35 編集

話しあったところ、play1.pugに統一しつつ、使用するjsを共通化することでうまくいくかもしれないとなり、現在試行錯誤中です。
退会済みユーザー

退会済みユーザー

2022/02/22 09:41

> 現在試行錯誤中です。 大変そうですが、頑張ってください。 > 話しあったところ、 mariko68311さんは、お仕事としてこの作業をしているのでしょうか? その場合、コードをコメント欄に公開してしまうことはちょっと問題になりそうですので、適当な内容に変更しておいた方が良い気がしました。
mariko68311

2022/02/24 00:08

仕事ではないのですけど、学校の課題で作っている最中でした。内容変更が必要なら、一度見てもらったコードは消すなど行った方がいいでしょうか?それとも言われた通り一部変更する必要がありますかね?
退会済みユーザー

退会済みユーザー

2022/02/24 00:30

> 一度見てもらったコードは消すなど行った方がいいでしょうか?それとも言われた通り一部変更する必要がありますかね? 学校の課題だったのですね。 お仕事ではないのでしたら、公開することが気にならなければそのままでも良いと思います。
mariko68311

2022/02/24 03:10 編集

わかりました、ありがとうございます。 今はまた、 whitemoves();//白側の駒を動かす関数 を白側でも黒側でも動かせないか、という点に戻ってきてしまっているのですが、この前xg63ex2bさんがサンプルを作ってroomごとに関数を送るのは対応していないと教えてくれたので、socket.ioなしで送れる方法がないか、もしくはsocket.ioありでの関数を送る方法は他にないのか、など色々試してみてはいるのですが、どれも上手くいかず、駒の動きを阻害するだけになってしまいます。 ちなみに、確認したといっていた時のプログラムや第一級関数の例Ⅰ関数を変数へ代入するなどを参考にして以下のプログラムで通らないか試しましたが、全くだめでした。 //click.js whitemoves(); socket.emit("koma", barr, warr, room, num)//白側の駒を黒側に送る const whitemoves = function(){ console.log("white2"); socket.emit("white", num, whitemoves) } //server.js socket.on("koma", (barr, warr, room, num) => { console.log(`barr: ${barr}, warr: ${warr}, room: ${room}, num: ${num}`) io.to(room).emit("sou", barr, warr, num) }) socket.on("white", (num,whitemoves) =>{ console.log("white2") io.to(room).emit("souwhite", num, whitemoves) }) //play1.pug socket.on("sou", (retbarr, retwarr, retnum) => { append(`プレイヤー${retnum}が送信しました。${retbarr}、${retwarr}`) barr = retbarr warr = retwarr }) socket.on("souwhite",(retnum, retwhitemoves) => { append(`プレイヤー${retnum}が送信しました。${retwhitemoves}`) whitemoves = retwhitemoves }) そもそも出る予定のエラー、 throw new Error("Callbacks are not supported when broadcasting"); すら出てません。
退会済みユーザー

退会済みユーザー

2022/02/24 03:47

whitemovesは、その関数の中で、自分自身であるwhitemovesを送信するのですね、ちょっと気になりますが・・ 流れは問題なさそうですね。 ブラウザーのコンソールに「white2」は出力されていますでしょうか? (というかwhitemovesが二重に定義されていてエラーになっているのでしょうか?) > socket.ioなしで送れる方法がないか 具体的な関数の内容がわからないですが、「paly1and2.js」のようなスクリプトファイルを作って、 その中に「whitemoves」関数を移動して、 そのスクリプトファイルをplay1.pugとplay2.pugから読み込むのが素直な気がします。 もしこの方針に修正することが(変数の参照の関係などから)難しいのであれば、 Socket.IOなどを使って関数を送信したとしてもそのままでは動かないと思います。 (Socket.IOで送信する方針の方が修正するのが大変になると思います)
mariko68311

2022/02/24 04:40 編集

>ブラウザーのコンソールに「white2」は出力されていますでしょうか? 出力されてませんね、、、 >そのスクリプトファイルをplay1.pugとplay2.pugから読み込むのが素直な気がします あ、ごめんなさい。今はplay1.pugのみでやっていて、盤を反転することで動かしてます。ちなみにroom分けは問題なくできてます。 >もしこの方針に修正することが(変数の参照の関係などから)難しいのであれば、 Socket.IOなどを使って関数を送信したとしてもそのままでは動かないと思います。 そういうことならやはりsocket.ioなしで考える方が良さそうですね、また模索してみます。
退会済みユーザー

退会済みユーザー

2022/02/24 04:47

> 出力されてませんね、、、 じゃあ、関数をサーバーに送信する前のどこかで処理が止まってしまっているのかもしれませんね。 > あ、ごめんなさい。今はplay1.pugのみでやっていて、盤を反転することで動かしてます。 すみません、ここを認識していませんでした・・ 共通(1つ)のpugファイルになっているのでしたら、whitemovesを呼ぶことは簡単そうに(関数を送信する必要がなさそうに)思いましたけれども、どのあたりが問題になっていますでしょうか?
mariko68311

2022/02/24 06:24

>じゃあ、関数をサーバーに送信する前のどこかで処理が止まってしまっているのかもしれませんね。 そうだと思うので何が原因か探す必要がありそうです。 >共通(1つ)のpugファイルになっているのでしたら、whitemovesを呼ぶことは簡単そうに(関数を送信する必要がなさそうに)思いましたけれども、どのあたりが問題になっていますでしょうか? 私も最初はそう思っていたのですが、確かにログも画面にも現在の段階では座標を互いのroomで送信できていることは確認していて、それでもなぜか駒の動きが動機できていないという状態です。whitemovesがroomごとで動いており、play1.pugと同じものを使っていても別物として扱っているからこうなっている?とは考えてはいます。ちなみに今room分けの処理はこうしていますが、何か関連性はありそうでしょうか。 //server.js app.get("/play1", (req, res) => { socketCount++ const room = `room${Math.ceil(socketCount / socketPerRoom)}` const num = socketCount % 2 if(num == 0){ dir= false }else if(num == 1){ dir = true } res.render("play1", { room, num ,dir}); }); dirはfalseの時に黒駒を下に,trueの時に白駒を下にするといった感じで、盤の反転処理を行っています。
退会済みユーザー

退会済みユーザー

2022/02/24 07:39

> ちなみに今room分けの処理はこうしていますが、何か関連性はありそうでしょうか。 この処理に問題はなさそうですね。 > play1.pugと同じものを使っていても別物として扱っているからこうなっている?とは考えてはいます。 そうですね、、 たとえば、プレイヤー1は自分が白としてwhitemovesを動かして、相手を黒として扱う 反対に、プレイヤー2は自分を黒として扱い、相手が白としてwhitemovesを動かす このあたりが混乱してしまっているのですかね。
mariko68311

2022/02/24 07:54

>このあたりが混乱してしまっているのですかね。 ですね、全くその通りです。ここさえ通ってしまえば通信対戦は実現できるであろうというところで駒の処理を担当しているjsにつなぐwhitemovesがつながらない感じです。もちろん黒側を動かすblackmovesもあるのですが、これに関しては白側と同じ処理をかけば通ると思っているので後回しにしてます。画面を表示しているpugが一緒というだけだからこうなっているのかな?となっていますが、未だにうまく共有する術が見つかりません。
退会済みユーザー

退会済みユーザー

2022/02/24 08:08

> これに関しては白側と同じ処理をかけば通ると思っているので後回しにしてます。 賛成です。 play1.pugに統一した際に、どのような修正をされたのかまで把握できていませんが、、 移動する関数が白と黒で分けられているのでしたら、 自分の関数と、相手の関数で分けておくと分かりやすいのではないかと思いました。 たとえば、 whitemoves、blackmovesを直接使うのではなく、 次のように、最初に自分と相手の関数を分けておくとスッキリするような気がします。 (向きも異なるので、そんな単純な話でもないですかね・・) ```js moveMyself = num === 0 ? whitemoves : blackmoves moveOther = num === 0 ? blackmoves : whitemoves ```
mariko68311

2022/02/24 08:16

>次のように、最初に自分と相手の関数を分けておくとスッキリするような気がします。 というと、moveMyselfとmoveOtherと新たな関数を用意して振り分けて使えばいい、ということでしょうか?すみません、はっきりとはまだ理解できてないです。
mariko68311

2022/02/24 08:18

それと、この関数を使うとしたらやっぱりserver.jsの中でしょうか。
退会済みユーザー

退会済みユーザー

2022/02/24 08:31

> それと、この関数を使うとしたらやっぱりserver.jsの中でしょうか。 いいえ、クライアント側のお話ですよ。 > というと、moveMyselfとmoveOtherと新たな関数を用意して振り分けて使えばいい、ということでしょうか? > すみません、はっきりとはまだ理解できてないです。 ちょっと、内部の実装に入り込みすぎてしまうと思いますので・・ ざっくりの言葉だけでは伝えることが難しいかもしれません。 「振り分けて使えばいい」 というのは、当たっていると思います。 どこでどう振り分けるのか、既存の処理を整理して、修正する必要があると思います。 (ですので、先ほどコメントしたmoveMyselfとmoveOtherに分ければ良いという単純な話ではないかもしれません)
mariko68311

2022/02/24 08:38 編集

今しがたまだ試せていないなかったsocket.io通信を試みていたのですが、 throw new Error("Callbacks are not supported when broadcasting"); がついに出てしまいました。どうやらsocket.ioは使えなさそうです。やっぱり普通に送るしかないんでしょうか、、、
退会済みユーザー

退会済みユーザー

2022/02/24 08:43

> がついに出てしまいました。 おめでとうございます🎉😭 > やっぱり普通に送るしかないんでしょうか、、、 送るというか、Socket.IOは使わない方が良いとは思います・・ ご自身で作成されていないので理解するところが大変だとは思いますが、 サーバーから返ってくるbarrとwarrの駒の情報も逆になるわけですよね。 プレイヤー1はbarrが自分ですし、 プレイヤー2はwarrが自分ですし、 ・・地道な理解が必要そうですかね・・
mariko68311

2022/02/24 08:57

>サーバーから返ってくるbarrとwarrの駒の情報も逆になるわけですよね。 そうですね。同じ駒の処理を使っていても、画面上ではシンメトリーの状態で表示しないとなんですよね。 本当に共有にすごい時間がかかってしまっています。ちなみに、中の動きとしては、 play1.pugに適用しているjsとしてmove.jsがあり、そのmove.js内の処理で function whitemoves(){ があって、その中の処理でwhitemoves.jsを動かしています。 また、click.jsの中のwhitemoves();がmove.jsを動かす関数です。
退会済みユーザー

退会済みユーザー

2022/02/24 09:12

そうですよね、play1.pugとplay2.pugを統合するのは大変だと思います。 whitemovesなどの中を修正する必要がありそうではありますが、、 この中をできるだけ修正しない方針にするとしたら、 自分の駒の情報であるbarrとwarrを逆に持つ感じかと思いました。 プレイヤー1はbarrが自分の駒で(myPiece = barr)、warrが相手の駒で(otherPiece = warr)、 プレイヤー2はwarrが自分の駒で(myPiece = warr)、barrが相手の駒で(otherPiece = barr)、 このような感じで、barrとwarrを直接参照しない感じで考えたらどうでしょうか。 (このようにするとwhitemovesとblackmovesはあまり意識しなくて済みそうに思いました)
mariko68311

2022/02/24 12:11 編集

>自分の駒の情報であるbarrとwarrを逆に持つ感じかと思いました。 なるほど、whitemovesとblackmovesは意識せずにbarrとwarrを使うんですね。そうなるとsocket.ioの記述を変えて送る変数を変更すればうまくいきそう、?
退会済みユーザー

退会済みユーザー

2022/02/24 12:45 編集

> 変えて送る変数を変更すればうまくいきそう、? ちょっと、そんなに単純な話かどうか、わからないところではありますけれども・・ 駒の情報の扱いについて影響しそうなポイントを整理してみました。 これらのポイントについて、各ポイントで情報の扱いが正しいかどうか確認してみると良いかもしれません。 Socket.IOを導入する前の考え方 * play1.pug * * 変数barr自分 * * 変数warr相手 * * whitemoves自分の駒を動かす * * blackmoves相手の駒を動かす * play2.pug * * 変数warr自分 * * 変数barr相手 * * blackmoves自分の駒を動かす * * whitemoves相手の駒を動かす 修正後の考え方 * play1.pug * * プレイヤー1 * * * 変数barr自分 * * * 変数warr相手 * * * whitemoves自分の駒を動かす * * * blackmoves相手の駒を動かす * * * Socket.IOでサーバーに送信(barr自分、warr相手) * * * Socket.IOでサーバーから受信(プレイヤー1が送信した場合はbarr自分・warr相手、プレイヤー2が送信した場合はbarr相手・warr自分) * * プレイヤー2 * * * 変数warr自分 * * * 変数barr相手 * * * blackmoves自分の駒を動かす * * * whitemoves相手の駒を動かす * * * Socket.IOでサーバーに送信(barr自分、warr相手) * * * Socket.IOでサーバーから受信(プレイヤー2が送信した場合はbarr自分・warr相手、プレイヤー1が送信した場合はbarr相手・warr自分) ちょっとこれを整理してみて思ったことは、 一方が駒の情報を送信すると、 それを受けたサーバーはルームの中のプレイヤー全員に駒の情報を送信します。 駒の情報を送信した側は、送信する前に自分の駒の表示を変えますか(whitemovesを実行する)? あるいは、サーバー側に送信して、その後、サーバーから駒の情報が返ってきた時点で駒の表示を変えますか? このあたりの方針も整理した方が良いと思いました。
mariko68311

2022/02/24 12:57

>ちょっと、そんなに単純な話かどうか、わからないところではありますけれども・・ まぁそんな簡単な話じゃありませんよね、、、 >このあたりの方針も整理した方が良いと思いました。 私は後者だと考えていましたが、方針を確定したうえでどのように調整していくかを考えていく必要がありそうですね。といっても、残された時間は少ないためだいぶ急ぐことになりそうですね、、、
退会済みユーザー

退会済みユーザー

2022/02/24 13:37

> 私は後者だと考えていましたが、 そのように統一していく方針であればそれで大丈夫だと思います。 > といっても、残された時間は少ないためだいぶ急ぐことになりそうですね、、、 期限はいつですか?
mariko68311

2022/02/24 14:19

>期限はいつですか? 2月末ですけど、ここの通信周りさえ通ってしまえば大丈夫だと思います。
退会済みユーザー

退会済みユーザー

2022/02/24 14:45

今までの進捗状況から見ても確かに厳しそうですね。 頑張ってください。
mariko68311

2022/02/24 15:18

>頑張ってください。 頑張ります!ちょうど試すことができたので明日試してみて動くといいのですが、、、(学校でないと動作確認ができないのです) 一応、こんな感じにしてみました。 //server.js socket.on("koma", (myPiece, otherPiece, room, num) => { if(num == 0){ myPiece = warr otherPiece = barr }else if(num == 1){ myPiece = barr otherPiece = warr } console.log(`myPiece: ${myPiece}, otherPiece: ${otherPiece}, room: ${room}, num: ${num}`) io.to(room).emit("sou", myPiece, otherPiece, num) }) //click.js socket.emit("koma", myPiece, otherPiece, room, num) //play1.pug socket.on("sou", (retbarr, retwarr, retnum) => { append(`プレイヤー${retnum}が送信しました。${retbarr}、${retwarr}`) myPiece = retbarr otherPiece = retwarr })
退会済みユーザー

退会済みユーザー

2022/02/24 23:47 編集

> (学校でないと動作確認ができないのです) これは厳しいですね、いつでもトライ&エラーできないと進んでいるのかどうかわからないです・・ > 一応、こんな感じにしてみました。 サーバー側で自分の駒と相手の駒を入れ替える方針ですね。 流れは良いと思います。 ・・・と思ったのですが、コメントを訂正します・・・ サーバー側だけで判断するのはダメかもしれませんね。 サーバー側はルームの中のプレイヤー全員に送信するため、 自分の駒、相手の駒という考えを持たないのが自然そうです。 クライアント側で自分の駒、相手の駒を判断した方が良さそうです。
mariko68311

2022/02/25 00:05

>サーバー側だけで判断するのはダメかもしれませんね。 今動かしてみました。 append(`プレイヤー${retnum}が送信しました。${retbarr}、${retwarr}`) が機能してないのでうまく飛んでいないと考えてよさそうです。 >クライアント側で自分の駒、相手の駒を判断した方が良さそうです。 を試そうと思います。
mariko68311

2022/02/25 01:03

play1.pugに if(num == 1){//numが1の時にmyPieceを白、otherPieceを黒と判定 myPiece = warr otherPiece = barr }else if(num == 0){//numが0の時にmyPieceを黒、otherPieceを白と判定 myPiece = barr otherPiece = warr } を入れ込んだらうまくいきました。 connection socket.id: QJti5XANdjMYeM6AAAAD join socket.id: QJti5XANdjMYeM6AAAAD, socket.rooms: ["QJti5XANdjMYeM6AAAAD","room1"] myPiece: 2210,2211,2207,2107,2108,2109,2111,2110,2112,2208,2209, otherPiece: 1101,1102,1103,1104,1105,1106,1205,1204,1203,1202,1201, room: room1, num: 1 connection socket.id: HDJJu3R9IfpcgO8OAAAF join socket.id: HDJJu3R9IfpcgO8OAAAF, socket.rooms: ["HDJJu3R9IfpcgO8OAAAF","room1"] myPiece: 1101,1102,1103,1104,1105,1106,1205,1204,1203,1202,1201, otherPiece: 2107,2108,2109,2110,2111,2112,2211,2210,2209,2208,2207, room: room1, num: 0 とログでmyPieceとotherPieceの中が入れ替わって動いているのを確認しましたが、、、何も画面に変化が起きません。これはもうwhitemove.jsに手を加えるしかないですかね?
退会済みユーザー

退会済みユーザー

2022/02/25 01:08

> これはもうwhitemove.jsに手を加えるしかないですかね? 今、全く手を入れていないのだとしたら、そう思います。 barrとwarrではなく、myPieceとotherPieceで駒の情報を持つように変えてしまったので、myPieceとotherPieceを参照するように変える必要はあると思います。 変数名の置き換えだけですので、それほど大変な修正ではないと思いますが、 そこから先の影響は、なんとも言えないところです・・

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.02%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Pug

Pug(旧Jade)とは、HTMLを書くためのテンプレートエンジン。タグで囲む必要がないなど記述を省略できるため、HTMLの記述が簡単になります。ファイル分割も可能で、変数やループなど便利な機能も備わっています。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

Socket.IO

Socket.IOはNode.js上で動くライブラリであり、すべてのブラウザとモバイルデバイスでリアルタイムのアプリを作動させる事を目的としています。

Express

ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。