강의

멘토링

로드맵

Inflearn Community Q&A

gosan's profile image
gosan

asked

Web game that lets you learn by following along

Spawn the opponent's character

2번째 로그인 시 원래 있던 캐릭터가 생성되지 않습니다.

Written on

·

256

0

M.match_join이 호출되긴 하는데
PlayerView.js에서 op_code 값이 2가 나오는지 찍어봐도 찍히지 않고 호출되지 않는 거 같습니다.
import React, { useEffect, useState, useRef } from 'react'
import '../App.css';

const PlayView = () => {
    const [isHit, setIsHit] = useState(false)
    const setTimeOutRef = useRef(null);

    useEffect(() => {
      if(!window.pc.app.gameApp) return;
      window.pc.app.gameApp.socket.onmatchdata = (matchState) => {
        let jsonResult = JSON.parse(String.fromCharCode.apply(null, new Uint8Array(matchState.data)))
        switch (matchState.op_code) {
          case 1:
            onPlayerMove(jsonResult)
            break;
          case 2:
            onHandleInitialData(jsonResult)
            break;
          case 3:
            onPlayerSpawn(jsonResult)
            break;
          default:
            break;
        }
      }

    }, [])

    const onPlayerMove = () => {

    }

    const onHandleInitialData = (data) => {
      const myAccountId = window.pc.app.gameApp.user.user_id;
      console.log('onHandleInitialData', data);
      for (const player of data.players) {
        if(myAccountId === player.user_id) {
          continue;
        }
        console.log(player);
        setTimeout(() => {
          onPlayerSpawn(player);
        }, 1000);
      }
    }

    const onPlayerSpawn = (data) => {
      // Create a new player entity.
      let playerEntity = window.pc.app.root.findByName("Player");
      let newPlayerEntity = playerEntity.clone();

      // Put Location into new player entity.
      if(data.position) {
        let position = data.position;
        newPlayerEntity.rigidbody.teleport(position[0], position[1], position[2]);
      } else {
        newPlayerEntity.rigidbody.teleport(0, 3, 0);
      }
      
      // addChild into Root
      newPlayerEntity.enabled = true;
      let sceneRoot = window.pc.app.root.findByName("Root");
      sceneRoot.addChild(newPlayerEntity);
    }
    

    useEffect(() => {
        window.pc.app.on("boxHit", listener);
        return () => {
          window.pc.app.off("boxHit", listener)
        }
        // window.addEventListener("message", listener)
    
        // return () => {
        //   window.removeEventListener("message", listener);
        // }
      }, [])
      
    const listener = (event) => {
    // if(event.origin !== "http://localhost:3000")
    //   return;
    
    clearTimeout(setTimeOutRef.current);
    setIsHit(true);
    setTimeOutRef.current = setTimeout(() => {
        setIsHit(false);
    }, 1000);
    }
    
  return (
    <div>
        {isHit && <div className='Popup'>Box is hit</div> }
    </div>
  )
}

export default PlayView
 
local nk = require("nakama");
local M = {}

local function on_player_move(context, dispatcher, tick, state, message)
	local player = state.presences[message.sender.session_id]
	if player == nil then
		return
	end

	local ok, decode_data = pcall(nk.json_decode, message.data)
	if not ok then
		nk.session_disconnect(message.sender.session_id)
		return
	end

	player.info["position"] = decode_data.position;
	dispatcher.broadcast_message(1, message.data)

end

local function on_player_spawn(context, dispatcher, tick, state, message)
	-- 실제로 매치에 있는 사람이 보낸 것인지 확인. 아니면 return
	local player = state.presences[message.sender.session_id]
	if player == nil then
		return
	end

	dispatcher.broadcast_message(3, message.data)
end

function M.match_init(context, initial_state)
	local state = {
		presences = {},
		empty_ticks = 0
	}
	local tick_rate = 30 -- 1 tick per second = 1 MatchLoop func invocations per second
	local label = ""

	return state, tick_rate, label
end

function M.match_join_attempt(context, dispatcher, tick, state, presence, metadata)
    local acceptuser = true
    return state, acceptuser
end

function M.match_join(context, dispatcher, tick, state, presences)
	for _, presence in ipairs(presences) do
		
		state.presences[presence.session_id] = presence
		state.presences[presence.session_id].info = {
			user_id = presence.user_id,
			position = {0, 3, 0}
		}
	end

	local player_infos = {}
	for _, p in pairs(state.presences) do
		table.insert(player_infos, p.info)
	end

	local player_init_data = {
		players = player_infos,
		tick = tick
	}
	
	dispatcher.broadcast_message(2, nk.json_encode(player_init_data), presences)

	return state
end

function M.match_leave(context, dispatcher, tick, state, presences)
	for _, presence in ipairs(presences) do
		state.presences[presence.session_id] = nil
	end

	return state
end

function M.match_loop(context, dispatcher, tick, state, messages)

	print("messages: ", nk.json_encode(messages))
	for _, message in ipairs(messages) do
		if (message.op_code == 1) then
			local ok = pcall(on_player_move, context, dispatcher, tick, state, message)
			if not ok then
				nk.session_disconnect(message.sender.session_id)
			end
		end
		if (message.op_code == 3) then
			local ok = pcall(on_player_spawn, context, dispatcher, tick, state, message)
			if not ok then
				nk.session_disconnect(message.sender.session_id)
			end
		end
	end

	return state
end

function M.match_terminate(context, dispatcher, tick, state, grace_seconds)
    return state
end

function M.match_signal(context, dispatcher, tick, state, data)
    return state, data
end

return M
react

Answer 1

0

gosan님의 프로필 이미지
gosan
Questioner

아무리 이것저것 바꿔봐도 해결되지 않습니다.

setTimeout 시간 값을 바꿔도 안되고

애초에 

dispatcher.broadcast_message(2, nk.json_encode(player_init_data), presences)
이후 onmatchdata에 진입을 하지 않고 onPlayerSpawn으로 넘어가버립니다.
gosan님의 프로필 이미지
gosan
Questioner

정확한 해결방법은 아니지만 열려있는 브라우저들을 최대한 줄였더니 성공하는 케이스가 있네요... 원인은 모르겠습니다..

John Ahn님의 프로필 이미지
John Ahn
Instructor

답이 늦어서 죄송했습니다 ㅠㅠ !! 
담에 또 안되신다면 저장소 주소와 같이 올려주신다면 직접해보겠습니다!!!

gosan's profile image
gosan

asked

Ask a question