오늘의 목표

더보기

✔️ CS 정리

✔️ 개인과제 완성


⏱️ 오늘의 일정

CS 정리

개인과제 완성


📜 CS 정리

IP 주소의 체계, 사설망과 공인망에 대해 정리했다.

2024.10.07 - [CS] - [CS] IP 주소의 체계, 사설망, 공인망

 

[CS] IP 주소의 체계, 사설망, 공인망

IP 주소네트워크에서 통신을 위한 일련의 규칙이자 약속( 통신규약 )들이 존재하며, 이를 프로토콜이라고 부른다.그 중 인터넷 통신을 위한 프로토콜도 존재하는데 대표적인 것이 바로 IP다.IP는

program-yam.tistory.com

 

 

📜 개인 과제 완성

 

10월 7일 정오까지 개인 과제 제출시간이라서 시간에 맞게 제출했다.

 

https://github.com/YamSaeng/DinoRunner

 

GitHub - YamSaeng/DinoRunner

Contribute to YamSaeng/DinoRunner development by creating an account on GitHub.

github.com

 

기존에 설명했던 https://dinorunner.com/ko/

 

크롬 다이노 게임 온라인

T-Rex Dinosaur (Dinosaur Google) - 인터넷이 없을 때 Chrome 브라우저에 숨겨진 게임의 복제본. 시작하려면 스페이스바를 누르십시오. 스페이스바 또는 위쪽 화살표와 아래쪽 화살표(↓)를 사용하여 공룡

dinorunner.com

 

위 게임에서 추가한 부분은 다음과 같다.

Update() {
        this.userScoreUpdateTime -= 15;

        // 1초마다 서버에서 Score 계산
        if (this.userScoreUpdateTime < 0) {
            this.userScoreUpdateTime = USER_SCORE_UPDATE_TIME;

            if (this.users.length > 0) {
                // 접속중인 유저들을 순환하면서 스테이지에 맞게 점수 증가
                this.users.forEach(user => user.Update());

                // HighScore를 갱신
                for (let i = 0; i < this.users.length; i++) {
                    if (this.users[i].score > this.HighScore.score) {
                        this.HighScore.score = this.users[i].score;
                        this.HighScore.userId = this.users[i].userUUID;
                        
                        this.users[i].socket.emit("response", {
                            packetType: S2C_PACKET_TYPE_NEW_HIGH_SCORE,
                            data: { userId: this.HighScore.userId, score: this.HighScore.score }
                        });
                    }                  
                }                
            }
        }       
    }

서버에서 매 시간 1초마다 접속중인 유저들을 순환하면서 점수를 스테이지에 맞게 증가시켜준다.

이처럼 매 시간마다 서버에서 반복하면서 로직을 처리하는 방식에 대한 것을 튜터님에게 따로 물어봤다.

 

지금처럼 접속하는 유저가 적을 경우에는 서버에 부담이 가지 않아 위처럼 구성해도 되지만, 

서버에 접속하는 유저가 많아지면 서버에 부담이 가서 위와 같은 방법은 추천하지 않는다고 피드백을 받았다.

 

대신 점수를 검증하는 부분을 클라가 점수를 쌓기 시작한 시간과 어떤 특정한 점수에 도달했을 때 시간을

서버에 전송해서 서버는 두 시간 차를 토대로 점수를 계산해 인증해주는 방식이 서버에 부담이 가지 않는 방식이라는 말도 추가로 피드백을 받았다.

 

 

나는 기본적으로 서버에서 모든 로직을 담당하고 그냥 클라는 서버에서 처리한 결과를 보여주는 방식으로만 생각하긴 했는데, 물론 내 생각처럼 구성하는 서버도 존재한다고는 했다.

 

아마도.. 위와 같은 부분을 잘 구분( 서버에서 처리할건지, 클라에서 처리할 건지) 하고 설정하는 것이 기술이라고 생각 할 수 있긴 할 것 같다.

 

Update() {
        this.rankingScoreUpdateTime -= 15;
        if (this.rankingScoreUpdateTime < 0) {
            // 업데이트한 랭킹 점수를 접속 중인 유저들에게 전달                        
            this.rankingScoreUpdateTime = RANK_SCORE_UPDATE_TIME;
            let scoreArray = this.users.map((user) => {
                const score = [];
                score.push({
                    userUUID: user.userUUID,
                    score: user.score,
                    currentStage: user.currentStage
                });
                return score;
            });

            this.BroadCast({ packetType: S2C_PACKET_TYPE_RANK_SCORE_UPDATE, data: scoreArray });;
        }
    }

 

유저들의 점수를 계산하고 나서는 BroadCast를 활용해 유저들의 점수를 접속중인 모든 유저들에게 전달한다.

 

 

keydown = (event) => {
        if (event.code === "Space") {
            this.jumpPressed = true;
        }

        if (event.code === "ArrowLeft") {
            this.speed = -PLAYER_SPEED;
        }

        if (event.code === "ArrowRight") {
            this.speed = PLAYER_SPEED;
        }
    };

 

좌우 키를 입력하면 speed에 값을 줘서 공룡 캐릭터를 움직일 수 있도록 변경했다.

 

keydown = (event) => {       
        // A키를 누르면 불꽃 발사
        if (event.code === "KeyA") {
            if (this.fireAttackTimer <= 0 && this.fireCount > 0) {
                let game = Game.GetInstance();
                if (game != null) {
                    this.fireCount--;
                    game.jobQue.push(new Job(JOB_TYPE_CREATE_OBJECT_FIRE,
                        OBJECT_TYPE_FIRE, this.x, this.y));

                    this.fireAttackTimer = FIRE_ATTACK_TIMER;
                }
            }
        }

        // R키를 누르면 불꽃 발사
        if (event.code === "KeyR") {
            this.fireCount = FIRE_COUNT;
        }
    };

 

'A'키를 입력하면 불꽃을 발사할 수 있도록 하고, R키를 누르면 불꽃을 재장전한다.

 

// 불꽃 관리
class FireController {
    constructor(ctx, scaleRatio, itemController) {
        this.fireId = 1; // 관리중인 fire 구분하기 위한 id 값
        this.fires = [];
        this.ctx = ctx;
        this.canvas = ctx.canvas;
        this.scaleRatio = scaleRatio;
        this.itemController = itemController;
    }

    // 불꽃 생성
    CreateFire(spawnXPosition, spawnYPosition) {
        const newFire = new Fire(this.fireId, this.ctx, this.scaleRatio);
        newFire.SetPosition(spawnXPosition, spawnYPosition);

        this.fires.push(newFire);
        this.fireId++;
    }

    // 불꽃 업데이트
    Update(gameSpeed, deltaTime) {       
        // 충돌한 불꽃이 있으면 제거
        this.fires.forEach((fire)=>{
            if(fire.isCollide == true)
            {
                this.fires = this.fires.filter(collideFire => collideFire.id !== fire.id);
            }
        })

        this.fires.forEach((fire) => {
            fire.update(gameSpeed, deltaTime);
        });
        
        this.fires = this.fires.filter(fire => fire.x < 800);
    }

    // 매개변수로 받은 sprites 배열과 충돌하는지 확인
    CollideWithMultiple(sprites) {
        let isCollider = false;

        for (let i = 0; i < this.fires.length; i++) {
            for (let j = 0; j < sprites.length; j++) {
                // 충돌 여부 확인 하고 기록
                if (this.fires[i].collideWith(sprites[j])) {
                    sprites[j].isCollide = true;
                    this.fires[i].isCollide = true;

                    // 부딪힌 대상 위치에 아이템 생성
                    this.itemController.createItem(sprites[j].x);

                    break;
                }
            }
        }

        return isCollider;
    }

    Draw() {
        this.fires.forEach((fire) => fire.draw());
    }
}

 

불꽃은 위 클래스에 관리하고, 기본적으로는 오른쪽으로만 움직인다.

불꽃은 isCollide라는 변수를 가지고 있고, 해당 변수를 통해 충돌여부를 확인할 수 있다.

 

불꽃과 선인장이 부딪히면, 해당 자리에 아이템을 생성하고 불꽃과 선인장은 사라진다.

 

UpdateObject()
{
        if (this.cactiController.collideWithSingle(this.player)) {     
            Session.GetInstance().SendEvent(C2S_PACKET_TYPE_COLLIDE_CACTUS);                   
        }       

        if(this.itemController.collideWith(this.player)){
            Session.GetInstance().SendEvent(C2S_PACKET_TYPE_GET_ITEM);            
        }
}

 

플레이어가 선인장에 부딪히면 현재 스테이지에 비례하게 점수가 차감된다.

아이템과 부딪히면 점수가 증가한다.

 

🌙 하루를 마치며

1주일간 진행한 개인과제 주차가 끝났다.

10월 8일 오전 10시에 팀 프로젝트 발제가 있을 예정이다.

타워 디펜스( 유니티로 제공 )에 관한 서버를 만들 것이라는 공지를 전달 받았다.

 

이번에도 잘 참여해서 팀프로젝트를 완성할 수 있도록 노력해야겠다.

+ Recent posts