티스토리 뷰

학습/AWS

어디까지 했더라

aigoia 2024. 8. 24. 16:18

 

 

 카폐에서 9시 마감시간이 되서 마무리를 못하고 집에 갔다. 마져 마무리를 해보도록 한다. 

 

 아마도 그 서버로 어디에 랜덤하게 생성될지를 넘겨줘서 그 결과 값을 받아와서 생성을 하는 걸 만들어야 할꺼다. 

 

const grid = new THREE.GridHelper(15, 15);
 
서버
const x = Math.floor(Math.random() * 7 );
const z = Math.floor(Math.random() * 7 );
clientList[newPlayer] = new Vector3(x, 0.5, z);
 
 일단 그리드가 너무 커서 어디에 생성이 됬는지 도통 찾지를 못해서 이렇게 해준다. 
 
클라이언트
socket.on('playerAdd', clientList => {
  let playerFound = {};
  console.log(`(${Object.values(clientList[thisID])})`);

  for (let id in clientList) {
    const player = new THREE.Mesh(geometry, material);
    scene.add(player);
    const playerData = clientList[id];
    console.log(`Position data: (${playerData.x}, ${playerData.y}, ${playerData.z})`);
    player.position.set(playerData.x, playerData.y, playerData.z);
    playerList[thisID] = player;
    playerFound[this] = true;
  }
 
  for (let id in clientList)
  {
    if (!playerFound[id]){
      scene.remove(playerList[id])
      delete playerList[id];
    }
  }
});
 
서버
io.on('connect', socket => {
  const newPlayer = socket.id;

  const x = Math.floor(Math.random() * 7 );
  const z = Math.floor(Math.random() * 7 );
  clientList[newPlayer] = new Vector3(x, 0.5, z);
 
  console.log(`new player ${newPlayer} is connected!`);
  console.log(`(${Object.values(clientList[newPlayer])})`);
  console.log(``);

  socket.emit('playerAdd', clientList);
});

 

 

 이렇게 해주면 문제가 다시 새로고침을 해줄때마다 새로 생성이 된다는 거다. 그래서 디스커낵트를 할때마다 서버쪽에서 생성을 지워주는 걸 만들어야 한다. 

 

클라이언트 

socket.on('playerSet', clientList => {
  let playerFound = {};

  for (let id in clientList) {
    if (clientList[id] !== undefined) {
      const player = new THREE.Mesh(geometry, material);
      scene.add(player);
      const playerData = clientList[id];
      console.log(`Position data: (${playerData.x}, ${playerData.y}, ${playerData.z})`);
      player.position.set(playerData.x, playerData.y, playerData.z);
      playerList[id] = player;
      playerFound[id] = true;
    }
  }
 
  for (let id in clientList)
  {
    if (!playerFound[id]){
      scene.remove(playerList[id])
      delete playerList[id];
    }
  }
});
 
서버 
 
io.on('connect', socket => {
  const newPlayer = socket.id;

  const x = Math.floor(Math.random() * 7 );
  const z = Math.floor(Math.random() * 7 );
  clientList[newPlayer] = new Vector3(x, 0.5, z);
 
  console.log(`new player ${newPlayer} is connected! (${Object.values(clientList[newPlayer])})`);
  console.log(`Current number of players: " + ${Object.keys(clientList).length}`);
  console.log(``);

  socket.emit('playerSet', clientList);

  socket.on('disconnect', () => {
    const outPlayer = socket.id;

  if (!clientList[outPlayer]) {
    console.warn(`No player found for socket ID: ${outPlayer}`);
    return;
  }
 
  delete clientList[outPlayer];

  console.log(`${outPlayer} is disconnected!`);
  console.log(`Current number of players: " + ${Object.keys(clientList).length}`);
  console.log(``);

  io.emit('playerSet', clientList);
  });
});

 

 
 이런식으로 하면 된다. 잘 작동한다 이제 이동하는 메카니즘을 서버에서 구현을 하도록 한다. 그리고 클라이언트에서는 그 결과 같은 받아와서 보여주기만 할뿐 클라이언트에서 움직이는 것은 아니다. 

 

 거의 다왔다. 아직 카페가 마감하려면 시간이 있으니 여기서 한번 끊고 쉬었다가 다시 와서 작업을 하도록 한다.

 

 클라이언트

window.addEventListener('keydown', (event) => {
  console.log(event.key);
  socket.emit('userInput', event.key);
});
 
서버 
 
socket.on('userInput', key => {
  console.log(key);
});

 

 클라이언트는 키를 넘겨주기만 하고 실질적인 게임 메카니즘은 서버에서 구현한다. 

 

클라이언트 

socket.on('playerUpdate', clientList => {
  for (const id in clientList) {
    playerList[id].position.set(clientList[id].x, clientList[id].y, clientList[id].z);
  }
});

 

서버 

const newPlayer = socket.id;

const initX = Math.floor(Math.random() * 7 );
const initZ = Math.floor(Math.random() * 7 );
 
const posistionY = 0.5;
let posistionX = initX;
let posistionZ = initZ;
 
clientList[newPlayer] = new Vector3(posistionX, posistionY, posistionZ);
socket.emit('playerSet', clientList);

console.log(`new player ${newPlayer} is connected! (${Object.values(clientList[newPlayer])})`);
console.log(`Current number of players: " + ${Object.keys(clientList).length}`);
console.log(``);

socket.on('userInput', key => {
  const inputPlayer = socket.id;

  if (key === 'ArrowUp')
  {
    posistionX -= moveSpeed;
  }
  else if (key === 'ArrowDown')
  {
    posistionX += moveSpeed;
  }
   else if (key === 'ArrowRight')
  { 
    posistionZ -= moveSpeed;
  }
  else if (key == 'ArrowLeft')
  {
    posistionZ += moveSpeed;
  }

clientList[inputPlayer] = new Vector3(posistionX, posistionY, posistionZ);
  socket.emit('playerUpdate', clientList);
});
 

 잘움직이는데 다른 오브젝트의 코드까지 반영이 안된다. 머가 문제일려나, 그것까지 해결하면 끝일텐데 말이다. 

 

 그전에 본질적인 문제가 있다. 반영이 되지가 않는다. 

 

 일단 지워지는 것부터 구현을 안하고 넘어갔더라 그거부터 해결하고 가자. 

 

클라이언트 

socket.on('playerOut', outPlayer => {
scene.remove(playerList[outPlayer])
  delete playerList[outPlayer];
  playerFound[outPlayer] = false;
});
 
서버
socket.on('disconnect', () => {
  const outPlayer = socket.id;

  if (!clientList[outPlayer]) {
    console.warn(`No player found for socket ID: ${outPlayer}`);
    return;
  }
 
  delete clientList[outPlayer];

  console.log(`${outPlayer} is disconnected!`);
  console.log(`Current number of players: " + ${Object.keys(clientList).length}`);
  console.log(``);

  socket.broadcast.emit('playerOut', outPlayer);
});
 
 
 이렇게 하면 잘 된다.
 
animate();
function animate() {
requestAnimationFrame(animate);

  for (const id in playerList) {
    if (playerPositionList[id] !== undefined) {
      playerList[id].position.set(
      playerPositionList[id].x,
      playerPositionList[id].y,
      playerPositionList[id].z
    );
  }
}

renderer.render(scene, camera);
}
 

 이렇게 해놓으면 바로 랜더링 되는대로 반영된다. 

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Three.js & Socket.io</title>
    <style>
        body { margin: 0; }
        canvas { display: block; }
    </style>
</head>
<body>
    <script type="module" src="/app.js"></script>
</body>
</html>

 

클라이언트 

import * as THREE from 'three';
import {} from "./app.js";
import { io } from 'socket.io-client'

export const scene = new THREE.Scene();
export const renderer = new THREE.WebGLRenderer();
export const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);

const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshLambertMaterial({ color: 0xe0ffff }); 

export function startClient(params) {
    console.log('Start!')
}

const PORT = 3000;
const socket = io(`http://localhost:${PORT}`);

export let playerList = {};
export let playerPositionList = {};
let playerFound = {};
let thisID;

socket.on('connect', () => {
    thisID = socket.id;
    console.log(`${thisID} + is connected to server!`);
    console.log(``);
});

socket.on('playerSet', clientList => {
    SetPlayer(clientList);
    playerPositionList = clientList;
});

socket.on('playerOut', outPlayer => {
    scene.remove(playerList[outPlayer])
    delete playerList[outPlayer];
    playerFound[outPlayer] = false;
});

socket.on('playerUpdate', clientList => {
    for (const id in clientList) {
        // console.log(clientList[id]);
        playerList[id].position.set(clientList[id].x, clientList[id].y, clientList[id].z);
    }
    playerPositionList = clientList;
});

window.addEventListener('keydown', (event) => {
    socket.emit('userInput', event.key);
});

socket.on('disconnect', () => {
    console.log(`${thisID} + is disconnected to sever!`);
    playerFound[thisID] = false;
    console.log(``);
});

function SetPlayer(clientList) {
    for (const id in clientList) {
        if (playerList[id] === undefined )
        {
            const player = new THREE.Mesh(geometry, material);
            scene.add(player);
            console.log(`Position data: (${clientList[id].x}, ${clientList[id].y}, ${clientList[id].z})`);
            playerList[id] = player;
            playerList[id].position.set(clientList[id].x, clientList[id].y, clientList[id].z);
            playerFound[id] = true;   
        }
    }
    
    for (const id in clientList)
    {
        if (!playerFound[id]){
            scene.remove(playerList[id])
            delete playerList[id];
            playerFound[id] = false;
        }
    }

    playerPositionList = clientList;
}

animate();
function animate() {
    requestAnimationFrame(animate);

    for (const id in playerList) {
        if (playerPositionList[id] !== undefined) {
            playerList[id].position.set(
                playerPositionList[id].x,
                playerPositionList[id].y,
                playerPositionList[id].z
            );
        }
    }

    renderer.render(scene, camera);
}

 

서버 

import { Server } from "socket.io";
import express from "express";
import * as http from "http";
import cors from "cors";
import { Vector3 } from "three";

const app = express();
app.use(cors());
const server = http.createServer(app);

const CLIENT = 5173;
const io = new Server(server, {
    cors: {
        origin: `http://localhost:${CLIENT}`,
        methods: ["GET", "POST"]
      }
});

const PORT = 3000;
server.listen(PORT, () => {
  console.log(`Server is running on http://localhost:${PORT}`);
});

const clientList = {};
const moveSpeed = 1;

io.on('connect', socket => {
    const newPlayer = socket.id;

    const initX = Math.floor(Math.random() * 7 );
    const initZ = Math.floor(Math.random() * 7 );
    
    const posistionY = 0.5;
    let posistionX = initX;
    let posistionZ = initZ;
  
    clientList[newPlayer] = new Vector3(posistionX, posistionY, posistionZ);
    socket.emit('playerSet', clientList);
    socket.broadcast.emit('playerSet', clientList);

    console.log(`new player ${newPlayer} is connected! (${Object.values(clientList[newPlayer])})`);
    console.log(`Current number of players: " + ${Object.keys(clientList).length}`);
    console.log(``);    

    socket.on('userInput', key => {
      const inputPlayer = socket.id;

      if (key === 'ArrowUp')
      {
        posistionX -= moveSpeed;
      }
      else if (key === 'ArrowDown')
      {
        posistionX += moveSpeed;
      }
      else if (key === 'ArrowRight')
      {
        posistionZ -= moveSpeed;
      }
      else if (key == 'ArrowLeft')
      {
        posistionZ += moveSpeed;
      }

      clientList[inputPlayer] = new Vector3(posistionX, posistionY, posistionZ);

      socket.emit('playerUpdate', clientList);
      socket.broadcast.emit('playerUpdate', clientList);
    });

    socket.on('disconnect', () => {
      const outPlayer = socket.id;

      if (!clientList[outPlayer]) {
          console.warn(`No player found for socket ID: ${outPlayer}`);
          return;
      }
      
      delete clientList[outPlayer];

      console.log(`${outPlayer} is disconnected!`);
      console.log(`Current number of players: " + ${Object.keys(clientList).length}`);
      console.log(``);

      socket.broadcast.emit('playerOut', outPlayer);
    });
});

 

앱 세팅

import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { startClient, scene, renderer, camera } from './client.js';

renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0xffffff);
document.body.appendChild(renderer.domElement);


camera.position.set(10, 10, 10);
const orbit = new OrbitControls(camera, renderer.domElement);
orbit.update();

const ambientLight = new THREE.AmbientLight(0xffffff, 1);
scene.add(ambientLight);

const directionalLight = new THREE.DirectionalLight(0xffffff, 2);
directionalLight.position.set(10, 20, 10);
directionalLight.castShadow = false;
scene.add(directionalLight);

const grid = new THREE.GridHelper(15, 15);
scene.add(grid);

startClient();

window.addEventListener('resize', () => {
    renderer.setSize(window.innerWidth, window.innerHeight);
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
});

 

요렇게 끝이다. 영상으로 만들어 볼까 고민중이다. 

 

 구분이 안가서 이런걸 추가해 봤다. 

 

'학습 > AWS' 카테고리의 다른 글

영상으로 만들어야지  (0) 2024.08.25
게임 서버 개발의 경우  (0) 2024.08.25
꿈을 꿨는데  (0) 2024.08.23
서너번 반복해 보고  (0) 2024.08.22
웹 게임 서버 만들어 보기  (0) 2024.08.21