<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>being_game.log</title>
        <link>https://velog.io/</link>
        <description>복습을 위한 핵심 내용 및 모작 </description>
        <lastBuildDate>Mon, 14 Apr 2025 14:04:13 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>being_game.log</title>
            <url>https://velog.velcdn.com/images/being_game/profile/bf4e1bb6-9faf-4ef1-9e7e-e95c479ed533/social_profile.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. being_game.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/being_game" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[충돌]]></title>
            <link>https://velog.io/@being_game/%EC%B6%A9%EB%8F%8C</link>
            <guid>https://velog.io/@being_game/%EC%B6%A9%EB%8F%8C</guid>
            <pubDate>Mon, 14 Apr 2025 14:04:13 GMT</pubDate>
            <description><![CDATA[<h1 id="충돌-레이어-체크">충돌 레이어 체크</h1>
<p>하나의 level-&gt;32개의 layer
우리는 layer간의 충돌을 나타낼 것 </p>
<p>2d일때는 win API 와 동일한 방법:
32개 layer ,UINT형태 이기 때문에 32x32의 matrix로 비트 연산을 위해 열은 오른쪽부터 시작,
행1열6 과 행6 열1은 같은 연산이므로 대각 방향으로 나눈후  한 쪽은 할 필요 없음.</p>
<h1 id="충돌-이벤트">충돌 이벤트</h1>
<p>충돌체가 서로 붙으면 -begin overlap</p>
<p>붙은것이 떨어지면 -end overlap</p>
<p>충돌한 물체들의 Scritps들이 이벤트 맞는 함수들을 호출.</p>
<h1 id="충돌-체크">충돌 체크</h1>
<p>OBB(회전축을 포함한 충돌체크)</p>
<p>각 충돌체의 2개씩 축을 만듦(충돌체에서의 축들이  서로 평행)</p>
<p><img src="https://velog.velcdn.com/images/being_game/post/ff9c6adb-ce5b-40c8-87e1-c12f821c4a32/image.png" alt=""></p>
<p>4개 축 중 하나를 기준 축으로 둠
기준축에 4개의 축을 투영 (1번 투영-임의로 내가 지은것)
기준축에 각 중점을 이은 벡터도 투영(2번 투영-임의로 내가 지은것)</p>
<p>각 충돌체의 2번 투영 길이의 절반을 각각 더한 길이(겹친 길이 다 더함,보라색)&gt; 1번 투영 길이(파란색) - 충돌 기준 </p>
<p>충돌인 이유: 기준 축에서 두 물체를 가를 기준이 없기 때문
<img src="https://velog.velcdn.com/images/being_game/post/7b9cd6ae-dcb6-49bd-a5e8-81cc3b7b417f/image.png" alt="">
이 위의 과정을 4개 기준 축으로 모두 실행하여 한 번 이라도 충돌이 되면 충돌, 한 번도 충돌 안되면 충돌 아님</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[World 행렬(Transform)]]></title>
            <link>https://velog.io/@being_game/World-%ED%96%89%EB%A0%ACTransform</link>
            <guid>https://velog.io/@being_game/World-%ED%96%89%EB%A0%ACTransform</guid>
            <pubDate>Sat, 05 Apr 2025 17:13:35 GMT</pubDate>
            <description><![CDATA[<h1 id="44-행렬">4*4 행렬</h1>
<p>row_major matrix를 사용해야 gpu에서 행을 우선으로 읽는다 (gpu의 디폴트는 열 우선)</p>
<p><img src="https://velog.velcdn.com/images/being_game/post/a2438eb2-156a-48c4-91b3-cf6f13106bfe/image.png" alt=""></p>
<h1 id="translationscale">translation,Scale</h1>
<p><img src="https://velog.velcdn.com/images/being_game/post/8654d586-1947-4229-98de-8cfdffaba506/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/being_game/post/47c3db6a-5ad2-448a-8bbb-e2b03cb10874/image.png" alt=""></p>
<p>정점 vpos에서 4차원 확장값 0:
회전,스케일 변화만 필요(cordination)</p>
<p>정점 vpos에서 4차원 확장값 1:
위치 이동도 필요할때(normal)</p>
<h1 id="roation">Roation</h1>
<p>기존 각도에서 알파 각도를 회전 했을 때
<img src="https://velog.velcdn.com/images/being_game/post/aa096e1f-b37e-4577-9355-fd3945b8f961/image.png" alt=""></p>
<p>밑에 두식을 2*2 행렬로 만든다고 하면 
<img src="https://velog.velcdn.com/images/being_game/post/6341f5eb-b2d3-427e-afb7-0d573443f968/image.png" alt="">
이것을 토대로 X,Y,Z축 각각 회전행렬 만듬
x축
<img src="https://velog.velcdn.com/images/being_game/post/54cbe77e-9d76-493c-a144-8dda49d01a92/image.png" alt=""></p>
<p>y축
<img src="https://velog.velcdn.com/images/being_game/post/7844d49b-cec7-419e-b5d2-b83568e97ed5/image.png" alt=""></p>
<p>z축</p>
<p><img src="https://velog.velcdn.com/images/being_game/post/40149f9c-8143-475f-9300-e59e58095efb/image.png" alt=""></p>
<h1 id="스자이공부">스자이공부</h1>
<p>scale행렬 -&gt; z축 회전 행렬(자전) -&gt; 이동 행렬-&gt; x축,y축 회전행렬(공전)-&gt;부모 행렬</p>
<p>정확히 순서대로 곱해야 각 행렬이 반영된 
World(Transform)행렬 생성</p>
<h4 id="출처-어소트락-directx11-part2-강좌">출처: 어소트락 DirectX11 part2 강좌</h4>
]]></description>
        </item>
        <item>
            <title><![CDATA[Depthstencil View]]></title>
            <link>https://velog.io/@being_game/Depthstencil-View</link>
            <guid>https://velog.io/@being_game/Depthstencil-View</guid>
            <pubDate>Sat, 05 Apr 2025 15:52:42 GMT</pubDate>
            <description><![CDATA[<h1 id="create-depthstencil-view의-desc">Create Depthstencil view의 Desc</h1>
<p><img src="https://velog.velcdn.com/images/being_game/post/d42eef6f-fca9-4b82-a261-f2ccdc959d94/image.png" alt=""></p>
<h1 id="depth-종류">Depth 종류</h1>
<p>Less : 기존보다 depth가 작아야지만 통과( 디폴트 모드)
Less_equal: 기존보다 작거나 같은거 통과 </p>
<p>Greater: 기존보다 더 커야 통과 </p>
<p>no_test: 테스트를 거치지 않고 바로 통과, 하지만 기록은 함</p>
<p>기존이 없으면 렌더링 안됨 </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Render]]></title>
            <link>https://velog.io/@being_game/Render</link>
            <guid>https://velog.io/@being_game/Render</guid>
            <pubDate>Sun, 23 Feb 2025 16:16:07 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/being_game/post/87f9ea1f-f0e7-4acc-ade0-d2fa6890cc36/image.png" alt=""></p>
<p>렌더링에 필요한 설정</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Shader,blob (CPU에서)]]></title>
            <link>https://velog.io/@being_game/Shader%EC%99%80-blob-CPU%EC%97%90%EC%84%9C</link>
            <guid>https://velog.io/@being_game/Shader%EC%99%80-blob-CPU%EC%97%90%EC%84%9C</guid>
            <pubDate>Sat, 22 Feb 2025 18:27:18 GMT</pubDate>
            <description><![CDATA[<p>vs쉐이더를 만들고 Input layour 을 만든 후 연결시켜야 함</p>
<p>vertax shader 코드 컴파일 한것을 blob에 저장 한후 
blob으로 vertax shader 객체를 만들어냄.</p>
<p>만들어진 버텍스 쉐이더 객체를 컨텍스트 한테  파이프 라인에 설정 하도록 함 </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[DX11 Device초기화 흐름]]></title>
            <link>https://velog.io/@being_game/DX11-%EB%94%94%EB%B0%94%EC%9D%B4%EC%8A%A4</link>
            <guid>https://velog.io/@being_game/DX11-%EB%94%94%EB%B0%94%EC%9D%B4%EC%8A%A4</guid>
            <pubDate>Sat, 22 Feb 2025 18:10:32 GMT</pubDate>
            <description><![CDATA[<p>내림 순</p>
<h1 id="device">Device</h1>
<pre><code>D3d11 라이브러리 객체 생성을 위한 수단, 윈도우 핸들 값 필요</code></pre><h1 id="device-context">Device context</h1>
<pre><code>Shader에 설정을 하기 위한 수단,윈도우 핸들 값 필요</code></pre><h1 id="swapchain">SwapChain</h1>
<pre><code>출력 방법을 설정,윈도우 핸들 값 필요

백버퍼(그림이 그려지는 버퍼)를 생성하고 갖고 있음</code></pre><h1 id="render-target">Render Target</h1>
<pre><code>Swap Chain으로 부터 만들어진 백버퍼를 가리키고 있음,</code></pre><h1 id="viewport-설정">ViewPort 설정</h1>
<pre><code>렌더타겟에 그려진 것을 출력할때 어느 위치에 출력할지 설정해주는 것,
해상도 보다 작게 설정하면 렌더타겟에서 그 위치에 작게 그린 후 출력한다</code></pre><h1 id="render-target-view와-depthstencil-view를-om에-설정">Render Target view와 depthstencil View를 OM에 설정</h1>
<pre><code>버퍼로는 쉐이더에 연결 시킬수 없기 때문에 버퍼를 가르키고 있는 View를 통해
OM 설정

depthstencil 버퍼에는 깊이 관련 정보를 저장.

Render Target 버퍼에는 그림 픽셀 정보 저장, Texture 버퍼인 이유

OM 단계에서 깊이 테스를 거친 후 Render Target에 그린 후 출력 방법에 의해 출력</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[Input layout ,Verxtex Shader]]></title>
            <link>https://velog.io/@being_game/Input-layout-Verxtex-Shader</link>
            <guid>https://velog.io/@being_game/Input-layout-Verxtex-Shader</guid>
            <pubDate>Sat, 22 Feb 2025 17:56:36 GMT</pubDate>
            <description><![CDATA[<p>vs쉐이더를 만들고 Input layour 을 만든 후 연결시켜야 함</p>
<p><img src="https://velog.velcdn.com/images/being_game/post/76668be9-afdb-4558-97f7-4fe30f4c006e/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/being_game/post/52fe72d0-e598-4a44-8d5d-156b715e77cd/image.png" alt="">
Shader VS_IN의 vPos가 레이 아웃0번의 SemanticName을 사용함으로써 
vPos가 레이아웃의 레이 아웃0번을 뜻한다는 것.</p>
<p>레이아웃이 4x4 matrix(인스턴스 정보)를 넘겨주기 위해서 </p>
<p><img src="https://velog.velcdn.com/images/being_game/post/e9f89ad8-cd3b-4222-9fae-02bb32ecc458/image.png" alt=""></p>
<p>위 사진처럼 Byteoffset또 변경 시켜 주면서
SemanticName을 동일시키고 Index를1~4까지 한 후
<img src="https://velog.velcdn.com/images/being_game/post/1bfc03f8-6763-4788-a6f5-7bca3038efdf/image.png" alt="">
SemanticName을 사용하여 Matrix 레이아웃을 사용하면 됨.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[view Port]]></title>
            <link>https://velog.io/@being_game/view-Port</link>
            <guid>https://velog.io/@being_game/view-Port</guid>
            <pubDate>Fri, 21 Feb 2025 18:40:11 GMT</pubDate>
            <description><![CDATA[<p>렌더타겟에 그려진 것을 출력할때 어느 위치에 출력할지 설정해주는 것,
해상도 보다 작게 설정하면 렌더타겟에서 그 위치에 작게 그린 후 출력한다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[뷰,텍스쳐(버퍼)]]></title>
            <link>https://velog.io/@being_game/%EB%B7%B0%ED%85%8D%EC%8A%A4%EC%B3%90%EB%B2%84%ED%8D%BC</link>
            <guid>https://velog.io/@being_game/%EB%B7%B0%ED%85%8D%EC%8A%A4%EC%B3%90%EB%B2%84%ED%8D%BC</guid>
            <pubDate>Fri, 21 Feb 2025 17:32:14 GMT</pubDate>
            <description><![CDATA[<h1 id="view">View:</h1>
<p>텍스쳐와 버퍼를 랜더링 파이프라인에 넘겨주기 위한 수단.</p>
<h1 id="랜더-타겟-텍스쳐-depth-stencil">랜더 타겟 텍스쳐 Depth stencil</h1>
<p>랜더링 파이프라인 최종에 그리기 위해 필요.</p>
<p>스왑체인의 Get Buffer를 통해 렌더 타겟 텍스쳐의 주소를 가져옴. </p>
<p>Depth stencil은 깊이와 스텐실을 기억하는 버퍼.</p>
<p>이 두개를 넘겨 주기 위한 View 또한 필요</p>
<p>Depth stencil 버퍼는 렌더 타겟과 해상도 일치 해야함 </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[스왑체인]]></title>
            <link>https://velog.io/@being_game/%EC%8A%A4%EC%99%91%EC%B2%B4%EC%9D%B8</link>
            <guid>https://velog.io/@being_game/%EC%8A%A4%EC%99%91%EC%B2%B4%EC%9D%B8</guid>
            <pubDate>Fri, 21 Feb 2025 16:37:22 GMT</pubDate>
            <description><![CDATA[<p>스왑체인이 관리하는 버퍼에 그림을 그리고 그것을 윈도우에 송출</p>
<h1 id="렌더타겟-버퍼">렌더타겟 버퍼</h1>
<p>그림을 그리는 목적지,스왑체인이 만들어 지면서 같이 만들어짐 
              만들어질때 출력하는 핸들값을 줘야 함</p>
<h1 id="스왑-이펙트-종류">스왑 이펙트 종류</h1>
<p><img src="https://velog.velcdn.com/images/being_game/post/3483ae52-5247-455e-8eda-5e3adddb46f1/image.png" alt="">
 비트 블록 전송 모델
        DXGI_SWAP_EFFECT_DISCARD    한 번 그려낸 것을 지운다 
        DXGI_SWAP_EFFECT_SEQUENTIAL  지우지 않는다</p>
<p>대칭 이동 프레젠테이션 모델
        DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL  지우지 않는다
        DXGI_SWAP_EFFECT_FLIP_DISCARD    한 번 그려낸 것을 지운다</p>
<h2 id="비트-블록-전송-모델">비트 블록 전송 모델:</h2>
<p>백버퍼를 하나로 유지하고 출력시킬때 화면 복사 , 
          우리가 만든 그림을 계속 복사하고 윈도우에서 타이밍에 맞게 가져가는 것
          프로그램 프레임이 아무리 높아도 DWM(데스크톱 창 관리자)에서  타이밍 맞게
           버퍼가 복사한 그림 중 가장 최신 것을 가져가 출력 
          단점: 테어링 현상(버퍼에서 보낸 장면을 화면에서 그리고 있는데 또 보내버리면
                 나머지 장면이 연속으로 보낸 것에 의해 차이가 생김)
                           테어링 현상을 방지 하기 위해 V-Sync 사용</p>
<h2 id="대칭-이동-프레젠테이션-모델">대칭 이동 프레젠테이션 모델:</h2>
<p>V-Sync 을 활성하 할 수 있는 방법 중 하나, 
            벡 버퍼 2개 필요(그리고 있는 버퍼, DWM이 참조하는 버퍼)
            DWM이 버퍼 주소를 참조해서 그림 가져감
            화면 출력 프레임이 프로그램 프레임과 동일
            (DWM이 출력 그림을 가져가지 않으면 그리는 버퍼에서 다 그려도 제출 버퍼에
            제출 불가능 하기 때문)</p>
<h1 id="대칭-이동-프레젠테이션-모델-get-buffer를-했을때">대칭 이동 프레젠테이션 모델, Get Buffer를 했을때</h1>
<p>DX11:자동적으로 관리하며 그리는 백 버퍼를 자동으로 넘겨줌
DX12:자동으로 넘겨주지 않고 프로그래머가 관리해야 함  </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Single Core]]></title>
            <link>https://velog.io/@being_game/Single-Core</link>
            <guid>https://velog.io/@being_game/Single-Core</guid>
            <pubDate>Fri, 21 Feb 2025 10:41:45 GMT</pubDate>
            <description><![CDATA[<p>힙 영역 Single Core</p>
<pre><code class="language-cpp">class Sc //싱글코어
{
    private:
         static Sc* pSc=nullptr;
    public:
        static Sc* GetSc()
    {

        if(pSc==nullptr)
            pSc=new pSc;
            return pSc;
    }



}

</code></pre>
<p>메모리 영역</p>
<pre><code class="language-cpp">
class Sc //싱글코어
{

    public:
        static Sc* GetSc()
    {
         static pSc;
            return &amp;pSc;
    }

}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[The Archer (Win32API 게임 모작)]]></title>
            <link>https://velog.io/@being_game/The-Archer-Win32API-%EA%B2%8C%EC%9E%84-%EB%AA%A8%EC%9E%91</link>
            <guid>https://velog.io/@being_game/The-Archer-Win32API-%EA%B2%8C%EC%9E%84-%EB%AA%A8%EC%9E%91</guid>
            <pubDate>Sat, 24 Feb 2024 07:41:21 GMT</pubDate>
            <description><![CDATA[<div class="video-container">
    <iframe width="640" height="360" src="https://www.youtube.com/embed/o6L5tKOe9e4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
  </div>

<p>고화질로 시청 가능합니다!
visual studio Win32API만을 사용하여 만들었습니다.
다른 툴은 사용하지 않았습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[오버로딩, 오버라이딩]]></title>
            <link>https://velog.io/@being_game/%EC%98%A4%EB%B2%84%EB%A1%9C%EB%94%A9-%EC%98%A4%EB%B2%84%EB%9D%BC%EC%9D%B4%EB%94%A9</link>
            <guid>https://velog.io/@being_game/%EC%98%A4%EB%B2%84%EB%A1%9C%EB%94%A9-%EC%98%A4%EB%B2%84%EB%9D%BC%EC%9D%B4%EB%94%A9</guid>
            <pubDate>Sat, 13 Jan 2024 18:13:43 GMT</pubDate>
            <description><![CDATA[<h1 id="오버로딩">오버로딩</h1>
<p>동일한 함수 이름에도 매개변수의 타입,개수의 차이를 둬 
함수의 구분을 두는 것</p>
<p>void operator+=(Vec2 _vOther)
{</p>
<pre><code>x += _vOther.x;
y += _vOther.y;</code></pre><p>}</p>
<p>void operator+=(float _float)
{</p>
<pre><code>x += _float;
y += _float;</code></pre><p>}</p>
<h1 id="오버라이딩">오버라이딩</h1>
<p>상속 관계에 있어 base에서 먼저 정의한 함수를 
동일한 이름을 사용해서 재정의 하는 것이다.(이름만 같고 매개변수,리턴값은 다를수 있다.)</p>
<p>class base
{</p>
<p>public:
    void outchar() { std::cout &lt;&lt; &#39;a&#39;; }</p>
<p>};</p>
<p>class derived
    :public base</p>
<p>{</p>
<p>public:
    void outchar() {
        std::cout &lt;&lt; &#39; b&#39;; }
};</p>
<p>오버라이딩한 함수를 호출 하는 방법
1.namespace 활용
2.객체를 통한 호출(함수가 public이어야 함)</p>
<p>상속관계에 같은 멤버 이름이 있다면 네임스페이스(::)을 활용하여 구분 호출 가능</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[FSM]]></title>
            <link>https://velog.io/@being_game/FSM</link>
            <guid>https://velog.io/@being_game/FSM</guid>
            <pubDate>Sat, 13 Jan 2024 17:35:59 GMT</pubDate>
            <description><![CDATA[<h1 id="fsm">FSM</h1>
<p>유한한 상태 기계</p>
<p>오직 프로그래머의 프로그래밍으로 만들어지는 AI</p>
<p>각 조건에 맞게 상태로 움직이는 기계
state 패턴(디자인 패턴)을 활용하여 만든다</p>
<p>ex)몬스터가 순찰 중 순찰 범위 안에 플레이어 들어옴
   -&gt; 플레이어 쫓아가는 상태 on
  -&gt;공격 범위 안에 있으면 공격 상태on
  -&gt;플레이어가  몬스터의 해당 지역에서 벗어나면 다시 자기 자리 돌아가는 상태on</p>
<h1 id="aistate">AI,State</h1>
<p>몬스터들은 순찰,도망,공격,평소상태등의 상태들을 갖고 있으며 
조건에 따른 상태 전환들을 통해 몬스터의 행동들을 구현한다</p>
<p>몬스터는 자기의 AI 주소를 알고 있고 </p>
<p>AI는 자기의 오너인 Monster 주소 와    State 주소를 알고 있으며 </p>
<p>State는 자기의 Owner인 AI 주소를 알고 있다</p>
<p>각기 몬스터 마다 AI를 가지고 있고 AI가 상태들을 갖고 있으며</p>
<p>상태에 조건들에 따라 상태 변경이 필요하면 </p>
<p>state에서 AI로 변경이 필요하다고 요청한다</p>
<p>요청된 next state를  AI에서 교체 작업
void AI::ChangeState(MON_STATE _eNextState)
{
    CState* pNextState=GetState(_eNextState);
    assert(m_pCurState!=pNextState);
    m_pCurState = pNextState;
    m_pCurState-&gt;Enter();
}
하지만 상태가 바뀌는 것도 업데이트에서 일어난다 
따라서 상태가 바뀌는 것은 이벤트에서 처리해야 한다
<img src="https://velog.velcdn.com/images/being_game/post/ac0c9f20-fc57-4a68-ace8-99d4933bb852/image.PNG" alt=""></p>
<h1 id="예시">예시</h1>
<p>평소상태에서  플레이어가 몬스터 인지 범위 안에 들어오면 몬스터가 플레이어 방향으로 쫓아간다 </p>
<h2 id="몬스터와-플레이어-거리-체크">몬스터와 플레이어 거리 체크</h2>
<p> 조건에 해당되면 상태 변환 이벤트 발생</p>
<pre><code class="language-cpp">void CIdleState::update()
{
    //Player의 위치 체크
    CPlayer* pPlayer = (CPlayer*)CSceneMgr::GetInst()-&gt;Get_pCurScene()-&gt;GetPlayer();
    Vec2 vPlayerPos = pPlayer-&gt;GetPos();

    //몬스터의 범위 안에 들어오면 추적상태로 전환
    CMonster* pMonster = GetMonster();
    Vec2 vMonPos = pMonster-&gt;GetPos();

    Vec2 vDiff = vPlayerPos - vMonPos;
    float fLen = vDiff.Lenght();
    //플레이어가 몬스터의 인식범위 안으로 진입
    if (fLen &lt; pMonster-&gt;GetInfo().m_fRecogRange) 
    {
        ChangeAIState(GetAI(), MON_STATE::TRACE);
    }
}</code></pre>
<h2 id="이벤트-실행">이벤트 실행</h2>
<pre><code class="language-cpp">case EVENT_TYPE::CHANGE_AI_STATE:
    {
        //lparam :AI
        //wParam :Next Type
        AI * pAI = (AI*)_eve.lParam;
        MON_STATE eNextState = (MON_STATE)_eve.wParam;
        pAI-&gt;ChangeState(eNextState);

    }</code></pre>
<h2 id="추적">추적</h2>
<pre><code class="language-cpp">void CTraceState::update()
{
    //타겟팅 된 플레이어 추적 
    CPlayer* pPlayer = (CPlayer*)CSceneMgr::GetInst()-&gt;Get_pCurScene()-&gt;GetPlayer();
    Vec2 vPlayerPos = pPlayer-&gt;GetPos();

    Vec2 vMonPos = GetMonster()-&gt;GetPos();
    //플레이어의 방향으로 회전하면서 다가가는 것을 생각 해보기

    Vec2 vMonDir = vPlayerPos - vMonPos;
    vMonDir.Normalize();

    vMonPos += vMonDir*GetMonster()-&gt;GetInfo().m_fSpeed * fDT;
    GetMonster()-&gt;SetPos(vMonPos);

}</code></pre>
<h1 id="팩토리">팩토리</h1>
<p>디자인패턴 종류 중 하나이다
반복되는 것들을 모아서 찍어내기 편하기 위해 하는 디자인
예시
몬스터 타입 enum class로 정의한 다음  케이스로 구분하여 
타입별 스탯으로 적용할 것 들을 다 적어 두었다</p>
<pre><code class="language-cpp">enum class MON_TYPE 
{
    NORMAL,
    RANGE,

};

CMonster* CMonFactory::CreateMonster(MON_TYPE _eType,Vec2 _vPos)
{
    CMonster* pMon = nullptr;
    switch (_eType)
    {
    case MON_TYPE::NORMAL:
    {    pMon = new CMonster;
        pMon-&gt;SetPos(_vPos);

        tMonInfo info = {};
        info.m_fAtt = 10.f;
        info.m_fAttRange = 50.f;
        info.m_fRecogRange = 300.f;
        info.m_fHP = 100.f;
        info.m_fSpeed = 150.f;
        pMon-&gt;SetMonInfo(info);

        AI* pAI = new AI;
        pAI-&gt;AddState(new CIdleState);
        pAI-&gt;AddState(new CTraceState);
        pAI-&gt;SetCurState(MON_STATE::IDLE);
        pMon-&gt;SetAI(pAI);

    }
         break;

    case MON_TYPE::RANGE:
        break;


    }

    assert(pMon);

    return pMon;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[렌더링 최적화]]></title>
            <link>https://velog.io/@being_game/%EB%A0%8C%EB%8D%94%EB%A7%81-%EC%B5%9C%EC%A0%81%ED%99%94</link>
            <guid>https://velog.io/@being_game/%EB%A0%8C%EB%8D%94%EB%A7%81-%EC%B5%9C%EC%A0%81%ED%99%94</guid>
            <pubDate>Sat, 13 Jan 2024 08:09:27 GMT</pubDate>
            <description><![CDATA[<p>렌더링 최적화</p>
<p>현재 scenetool이 타일을 생성하기 때문에 많이 생성한다면 프레임 드랍이 발생</p>
<h1 id="카메라가-찍고-있는-부분만-렌더링">카메라가 찍고 있는 부분만 렌더링</h1>
<p>타일을 일렬로 쭉 배치 했기 때문에 화면안에 들어오는 범위를 알아 낼 수 있다</p>
<p>카메라 LT좌표 알기
LT에 해당하는 타일의 인덱스 알기</p>
<p>화면안에 들어오는 타일 개수 알기</p>
<pre><code class="language-cpp">void CScene::render_tile(HDC _dc)
{
    Vec2 vResolution = CCore::GetInst()-&gt;Get_Resoulution();
    Vec2 vCameraLT=CCamera::GetInst()-&gt;GetCamPos()- (vResolution/2);
    int iCamLTRow =(int)(vCameraLT.y / TILE_SIZE);
    int iCamLTCol = (int)(vCameraLT.x / TILE_SIZE);
    int iCamLTIdx = (iCamLTRow * m_iTileXCount) + iCamLTCol;
    UINT iClient_Row = (int)(vResolution.y / TILE_SIZE);
    UINT iClient_Col = (int)(vResolution.x / TILE_SIZE);    
    const vector&lt;CObject*&gt;&amp;vecTile 
    =CSceneMgr::GetInst()-&gt;Get_pCurScene()-&gt;Get_vecpobj(GROUP_TYPE::Tile);

    //타일의 넓이가 카메라 넓이 보다 작을때
    if (Vec2{ (int)iClient_Row,(int)iClient_Col } 
    &gt;= Vec2{ (int)m_iTileYCount,(int)m_iTileXCount })
    {
        for (size_t j =0; j &lt;vecTile.size(); ++j)
            vecTile[j]-&gt;render(_dc);
    }
    else 
    {    //타일의 넓이가 카메라 넓이 보다 클 때 
        if (iCamLTRow &lt; 0)
            iCamLTRow = 0;
        if (iCamLTCol &lt; 0)
            iCamLTCol = 0;

        for (int i = iCamLTRow; i &lt; iClient_Row + iCamLTRow; ++i)
        {    

            for (int j = iCamLTCol; j &lt; iClient_Col + iCamLTCol; ++j)
                {
                    vecTile[(m_iTileXCount * i) + j]-&gt;render(_dc);
                }
        }
    }


}</code></pre>
<p>통 배경을 쓸때에는 배경화면을 텍스쳐 해놓고 카메라도 따로 텍스쳐 만들고 
배경화면 텍스쳐에 카메라 텍스쳐가 짤라서  사용 하는 것도 하나의 방식 </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Alpha blend]]></title>
            <link>https://velog.io/@being_game/Alpha-blend</link>
            <guid>https://velog.io/@being_game/Alpha-blend</guid>
            <pubDate>Fri, 12 Jan 2024 15:39:38 GMT</pubDate>
            <description><![CDATA[<p>Alpha는 투명도를 나타낸다
255일때 젤 불투명
0일때 투명</p>
<p>Alpha blend는 Alpha값을 써서 두 색상을 섞는 것</p>
<p>물체가 있고 막을 통해 내가 그 물체를 본다 했을때 </p>
<p>가림막 RGB *A (0.5)로 하면
물체의 알파가 0.5 비율이 되면서
알파를 각각 곱한 RGB를 더해서 반투명하게 보이게 한다</p>
<p>서로 곱해준 Alpah의 전체 알파 비율의 합이 1이 되어야 한다</p>
<p>비트맵은 alpha가 따로 존재 하지 않음
따라서 알파를 따로 추가 해줘야 함</p>
<p>이미지 속성-&gt;자세히 -&gt;비트수준이 24비트 라는 건 알파값이 존재 하지 않는 것이다</p>
<h1 id="camera-fade-incamera-fade-out">camera fade in,camera fade out</h1>
<p>페이드 아웃은 점점 불투명 해지다가 검해지는 것 따라서 Alpha가0~255로 가야한다
페이드 인 은 그 반대로
fade in , out을 이벤트로 하여 호출되면 
camera에서 이벤트들을 갖고 있다가 순서대로 처리하는 구조를 가진다 </p>
<pre><code class="language-cpp">void CCamera::render(HDC _dc){
if (m_listCamEffect.empty())//갖고 있는 이벤트들이 없다면
        return;
    tcamEffect&amp; cameffect = m_listCamEffect.front();//젤 앞에 있는 이벤트 참조
    cameffect.m_fCurTime += fDT;//진행 시간 체크
float fRatio = 0.f;

fRatio = cameffect.m_fCurTime / cameffect.m_fDuration;//이벤트 진행 비율

if (CAM_EFFECT::FADE_OUT == cameffect.eEffect)
{

}

if (CAM_EFFECT::FADE_IN == cameffect.eEffect)
{
    fRatio =1-fRatio;

}

    if (fRatio &lt; 0.f)
        fRatio = 0.f;          //fRatio가 dt에 의해 계산되고 
                //진행시간이 최대지정 시간을 넘어간 마지막 프레임까지 렌더를 하기 때문에 설정
        if (fRatio &gt; 1.f)
            fRatio = 1.f;

    Vec2 vResolution = CCore::GetInst()-&gt;Get_Resoulution();

    int iAlpha = (int)(255.f * fRatio);

    BLENDFUNCTION bf = {};
    bf.BlendOp = AC_SRC_OVER;
    bf.BlendFlags = 0;
    bf.AlphaFormat = 0;//내가 만든것이 아닌 전역 알파를 사용하기 때문에 
            //내가 따로 alpha채널을 한 이미지라면 AC_SRC_ALPHA
    bf.SourceConstantAlpha = iAlpha; //알파값을 넣는다

    AlphaBlend(_dc, 0, 0, 
        (int)vResolution.x, (int)vResolution.y
        , m_pVeilTex-&gt;Get_dc(), 0, 0, 
        (int)vResolution.x, (int)vResolution.y, bf);
        if (cameffect.m_fCurTime &gt; cameffect.m_fDuration)//이벤트 진행시간이 최대 지정시간을 넘어섰을때
    {
        m_listCamEffect.pop_front();

    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[파일 입출력]]></title>
            <link>https://velog.io/@being_game/%ED%8C%8C%EC%9D%BC-%EC%9E%85%EC%B6%9C%EB%A0%A5</link>
            <guid>https://velog.io/@being_game/%ED%8C%8C%EC%9D%BC-%EC%9E%85%EC%B6%9C%EB%A0%A5</guid>
            <pubDate>Fri, 12 Jan 2024 05:43:03 GMT</pubDate>
            <description><![CDATA[<h1 id="개념">개념</h1>
<p>저장장치에 있는 데이터들을
RAM에 올려놓고 이것을 우리가 보는것</p>
<p>저장장치에 저장 하지 않으면 RAM에 있던것들은 다 날라간다</p>
<p>scene에서 타일로딩 </p>
<p>scene tool에서 저장(tile을 관리하고 작업하는 곳)</p>
<p>확장자가 다르다 해도 파일 구성이 달라지는 것은 아님
그냥 어떤 류의 파일이다라는 것을 알려주는 것</p>
<p>확장자
하지만 뷰어 프로그램이 실제는 동영상인데
확장자를 봣을때 이미지니까 
이미지로 파일열면 오류가 발생 </p>
<p>그래서 파일과 확장자를 매칭 해줘야 한다</p>
<p>타일은 내 프로그램에서만 사용 하는 것이기 때문에 따로 tile로확장자를 만들어 줬다</p>
<p>이중 포인터
수정할 대상이 포인터라서
포인터를 수정하기 위해 포인터의 포인터를 필요로 한다
이러한 개념을 똑같이 확장해서 삼중,사중 포인터까지 확장 할수 있다</p>
<h1 id="filestream">File,stream</h1>
<p>stream은 저장장치와 프로그램의 연결을 뜻한다
File은 stream을 잡아주는 것
wfopen_s는 이 연결한 File주소를 반환해 준다
반환된것이 nullptr이면 연결실패</p>
<p>File 열고 하고자 하는 것을 끝냈으면 fclose를 해줘야 한다</p>
<p>File 하나가 스트림하나를 대변 한다고 생각하면 된다</p>
<p>wfopen할때 모드가 있다(읽기전용,쓰기 전용,읽기와 쓰기 둘다 등등 여러개)
그냥 w는 문자데이터로 인식 쓰는것
wb 쓰기모드이긴한데 binary로 쓰는것 
 숫자를 적었는데 아스키 코드로 인식하면 의도치 않은 상황발생 가능 ,따라서 wb,wr로 사용
읽기도 마찬가지</p>
<h1 id="savefile">Savefile</h1>
<p>wfopen이 쓰기 모드일 경우 경로에 파일이 없으면 파일을 만들어 버린다
모드에 따라 경로에 파일이 있으면 이어 쓸수 있지만, 보통 덮어 씌어버린다
fwirte를 통해 연결된 스트림에 쓴다</p>
<pre><code class="language-cpp">void CScene_Tool::SaveTile(const wstring&amp; _strconstPath)
{

    FILE* pFile;
    _wfopen_s(&amp;pFile, _strconstPath.c_str(), L&quot;wb&quot;);
    assert(pFile);
    //타일 개수 저장
    UINT iTileXcount = GetTileXCount();
    UINT iTileYcount = GetTileYcount();
    fwrite(&amp;iTileXcount, sizeof(UINT), 1, pFile);
    fwrite(&amp;iTileYcount, sizeof(UINT), 1, pFile);
    //모든 타일들이 개별적으로 저장할 데이터를 로드하게 함
    const vector&lt;CObject*&gt;vecobj = 
    CSceneMgr::GetInst()-&gt;Get_pCurScene()-&gt;Get_vecpobj(GROUP_TYPE::Tile);
    for (size_t i = 0; i &lt; vecobj.size(); ++i)
    {
            ((CTile*)(vecobj[i]))-&gt;Save(pFile);
    }
    fclose(pFile);

}</code></pre>
<h1 id="roadfile">RoadFile</h1>
<p>rb모드 사용
읽기는 경로에 파일이 없으면 nullptr 반환,읽기 실패 
SaveFile과 마찬가지</p>
<pre><code class="language-cpp">void CScene_Tool::LoadTile(const wstring&amp; _strFilePath)
{

FILE* pFile;
_wfopen_s(&amp;pFile, _strFilePath.c_str(), L&quot;rb&quot;);
UINT iTileXcount = GetTileXCount();
UINT iTileYcount = GetTileYcount();
if (pFile != nullptr)
{    
    //타일 개수 저장
        fread(&amp;iTileXcount, sizeof(UINT), 1, pFile);
    fread(&amp;iTileYcount, sizeof(UINT), 1, pFile);
    CreateTile(iTileXcount, iTileYcount);
}
const vector&lt;CObject*&gt;vecobj = CSceneMgr::GetInst()-&gt;Get_pCurScene()-&gt;Get_vecpobj(GROUP_TYPE::Tile);

for (size_t i = 0; i &lt; vecobj.size(); ++i)
{
    ((CTile*)(vecobj[i]))-&gt;Load(pFile);
}
    fclose(pFile);

}</code></pre>
<p>각각의 타일들이 저장할 데이터들이 순서대로 저장 했으니까 
로드 할때도 각각의 타일들이 저장한 것들을 순서대로 로드 할수 있다</p>
<h1 id="save-tile-data">Save Tile data</h1>
<p>저장 위치 경로를 지정하는 윈도우가 이미 있다
윈도우에 사용 되는 구조체 ofn을 채워 넣어야함
ofn.lpstrFilter=L&quot;ALL\0<em>.</em>\0tile\0<em>.tile\0&quot;;
확장자 필터, 확장자 all을 택하면 파일명 뒤에 아무것도 안붙고,
        확장자  tile을 택하면 파일명 뒤에 .tile이 붙게 한다
strTitleFolder += L&quot;title&quot;;
ofn.lpstrInitialDir = strTitleFolder.c_str();//원하는 초기 경로를 const char</em>로 변경하여 넣어준다</p>
<p>modal 방식의 윈도우 창 하나 생성
if (GetSaveFileName(&amp;ofn)) 
{
   SaveTile(szName);
}
<img src="https://velog.velcdn.com/images/being_game/post/089e5350-e184-47fc-a49f-d56dc8ee6244/image.PNG" alt=""></p>
<h1 id="lode-tile-data">Lode Tile data</h1>
<p>로드 될 주소를 선택하는 윈도우에 저장한 주소를 
상대 주소만 짤라서 lodeTile에게 줘야한다
그 이유는 그 윈도우에 저장할때 절대 주소 와
LODE Tile 할때의 절대 주소가 다를수 있기 때문</p>
<pre><code class="language-cpp">    if (GetOpenFileName(&amp;ofn))
    {
        wstring strFilePath = CPathMgr::GetInst()-&gt;GetContentPath();
        wstring strRelativePath = CPathMgr::GetInst()-&gt;GetReativePath(szName);
        strFilePath += strRelativePath;
        LoadTile(strFilePath);
    }</code></pre>
<p><img src="https://velog.velcdn.com/images/being_game/post/01a82a62-06fa-457e-a438-4322204c3ee7/image.PNG" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[UI]]></title>
            <link>https://velog.io/@being_game/UI</link>
            <guid>https://velog.io/@being_game/UI</guid>
            <pubDate>Thu, 11 Jan 2024 14:59:01 GMT</pubDate>
            <description><![CDATA[<h1 id="ui">UI</h1>
<p>카메라의 영향을 받아야 하는 것도 있고
받지 않아야 하는 것도 있다</p>
<p>계층 구조를 가진다
부모ul,자식ul 
그 자식이 자식 ul를 가질수 있다</p>
<p>scene한테는 최상위 부모ul만 넣어준다</p>
<p>부모와 자식을 둘다 알수 있게 쌍방향 연결한다</p>
<h2 id="updaterender">update,render</h2>
<p>본인 업데이트를 하고 자식을 업데이트 시켜준다
rendering 또한 마찬가지이다
void CUI::update_child()
{
    for (size_t i = 0; i &lt; m_vecChildUI.size(); ++i)
        m_vecChildUI[i]-&gt;update();</p>
<p>}
void CUI::update()
{
    update_child();</p>
<p>}</p>
<h2 id="final-update">final update</h2>
<p>자식이 setpos 할때는 부모로 부터 offset할지 set하는 것이다</p>
<pre><code class="language-cpp">CObject::finalupdate();

m_vFinalPos = GetPos();

if (GetParent()) 
{
    Vec2 vParentPos = GetParent()-&gt;GetFinalPos();
    m_vFinalPos += vParentPoss; //자신이 자식이라면 부모 위치를 더한다
}</code></pre>
<h2 id="소멸자">소멸자</h2>
<p>본인이 지워질때 자기의 자식 UI를 지워준다</p>
<h2 id="mouse-on">Mouse On</h2>
<p>마우스가 자기 자신 위에 올라왔는지 확인한다(카메라의 영향에 따라 다름)
final update때 마다 확인</p>
<pre><code class="language-cpp">void CUI::IsMouseOnCheck()
{
    Vec2 MousePos = MOUSE_POS;
    if (m_bAffectedCam)
        MousePos = CCamera::GetInst()-&gt;GetRealPos(MousePos);

    if (MousePos.x &gt;= m_vFinalPos.x &amp;&amp; MousePos.x &lt;= m_vFinalPos.x + GetScale().x
        &amp;&amp; MousePos.y &gt;= m_vFinalPos.y &amp;&amp; MousePos.y &lt;= m_vFinalPos.y + GetScale().y)
    {
        m_bMouseOn = true; 
    }

    else 
    {
        m_bMouseOn = false;
    }

}</code></pre>
<h1 id="panelui">PanelUI</h1>
<p>UI의 자식 UI</p>
<h2 id="생성자">생성자</h2>
<p>UI에서 기본 생성자를 없애고 
카메라 영향을 매개변수로 하는 생성자를 만들었다</p>
<p>부모의 기본 생성자가 없기 때문에
PanelUI는 부모UI의 생성자를 지정해줘야 한다
CPanelUI::CPanelUI()
    :CUI(false),m_bMouseOnDown(false)
{</p>
<p>}</p>
<h1 id="ui이벤트">UI이벤트</h1>
<p>1.마우스가 내 UI에 올라왓을때</p>
<ol start="2">
<li><p>해당 UI를 눌렀을때</p>
</li>
<li><p>해당 UI위에서 떼졌을때</p>
</li>
<li><p>클릭 된 경우
범위 안에서 다운과 업이 발생했을때를 뜻한다</p>
</li>
</ol>
<p>이 4개의 이벤트들을 virtual함수로 하여 자식UI들이 활용 할수 있도록 함</p>
<p>카메라 영향을 받는지 안받는지를 스스로 알아야 한다</p>
<h1 id="ui-mgr">UI Mgr</h1>
<p>UI이벤트들을 체크 해준다
상황 체크 후 이벤트 호출</p>
<pre><code class="language-cpp">if (TargetUI != nullptr) 
{
    if (bLbtnTap)
        {        
                TargetUI-&gt;MouseLbtnDown(); 
        }

    else if (TargetUI-&gt;IsMouseOn() &amp;&amp; TargetUI-&gt;m_bLbtnDown &amp;&amp; bLbtnAway) 
                { 
                    TargetUI-&gt;MouseLbtnClicked(); 
                    TargetUI-&gt;m_bLbtnDown = false; 
                }

    else if (bLbtnAway) { TargetUI-&gt;MouseLbtnUp(); }

}</code></pre>
<h2 id="target-ui-찾기">Target UI 찾기</h2>
<p>자식 UI의 이벤트가 호출되면 
부모 UI의 이벤트는 호출되지 않는다</p>
<ol>
<li>부모 포함 모든 자식 UI들을 검사한다</li>
<li>타겟 UI들 중 계층이 더 낮은 UI일수록 타겟 UI의 우선순위이다</li>
</ol>
<p>레벨순회를 진행해야할 필요가 있다 ,모든 자식을 순회해야 한다</p>
<p>이러한 레벨순회에서는 que자류구조를 사용한다
<img src="https://velog.velcdn.com/images/being_game/post/96dba74d-4608-49d6-bdc5-2422d4ebbf3b/image.PNG" alt=""><img src="https://velog.velcdn.com/images/being_game/post/b16c49b4-9cbb-49fb-ab8f-77bbcb94ff37/image.PNG" alt=""></p>
<p>부모가 먼저 들어간후 꺼낸뒤 자기 자식을 넣은 다음 
들어간 자식 중 첫번째가 나올때 똑같이 자기 자식을 넣는 방식이라면 모든 자식들을 넣을수 있다</p>
<p>리스트를 활용하여 큐처럼 제한하여 만든다</p>
<p>큐안에 아무것도 없을때 순회가 끝난다</p>
<pre><code class="language-cpp">CUI* CUIMgr::GetTargetUI(CUI* _pparentUI)
{
    list&lt;CUI*&gt;quee;
    vecNoneTarget.clear();
    quee.clear();

    quee.push_back(_pparentUI);
    CUI* pTargetUI=nullptr;

    while (!quee.empty()) //타겟인지 체크하기
    {
        //데이터 하나 꺼내기
        CUI*pUI= quee.front();
        quee.pop_front();

        if (pUI-&gt;IsMouseOn())
        {
            pTargetUI = pUI;
            for (size_t i = 0; i &lt; pUI-&gt;m_vecChildUI.size(); ++i)
                quee.push_back(pUI-&gt;m_vecChildUI[i]);

        }

        else { vecNoneTarget.push_back(pUI);}
    }
    //타겟이 아닌 애들은 false로 만들기
    for (size_t i = 0; i &lt; vecNoneTarget.size(); ++i)
    {
        vecNoneTarget[i]-&gt;m_bMouseOn = false;

    }
    return pTargetUI;
}
</code></pre>
<pre><code class="language-cpp">CUI* TargetUI = GetTargetUI(m_pForcusedUI);
        //각 Lbtn 상황에 맞는 함수 실행
    if (TargetUI != nullptr) 
    {
        if (bLbtnTap) 
        { TargetUI-&gt;m_bLbtnDown = true; TargetUI-&gt;MouseLbtnDown(); }

         else if (TargetUI-&gt;IsMouseOn() &amp;&amp; TargetUI-&gt;m_bLbtnDown &amp;&amp; bLbtnAway)
             { 
                TargetUI-&gt;MouseLbtnClicked(); 
                TargetUI-&gt;m_bLbtnDown = false;
             }

        else if (bLbtnAway) { TargetUI-&gt;MouseLbtnUp(); }

    }
</code></pre>
<h2 id="forcused-ui">Forcused UI</h2>
<p>부모UI 중 forcused UI를 찾기</p>
<p>벡터에 쌓인대로 렌더링,
가장 마지막이 가장 바깥쪽에 렌더링</p>
<p>포커싱 받은 얘가 맨 뒤로 가면 된다!</p>
<p>검사 순서와 렌더링 순서는 반대</p>
<p>나중에 눌린얘가 포커스 되는게 맞으므로  검사 순서를 그래도 하는것이 맞다</p>
<p>CUI* CUIMgr::GetForcusedUI()
{</p>
<pre><code>CScene* pCurScene = CSceneMgr::GetInst()-&gt;Get_pCurScene();
vector&lt;CObject*&gt;&amp;vecUI = pCurScene-&gt;Get_vecUI();//현재 씬의 UI그룹벡터 가져오기

vector&lt;CObject*&gt;::iterator Targetiter=vecUI.end();
vector&lt;CObject*&gt;::iterator iter=vecUI.begin();
bool bMousedown = KeySta_Check(KEY::LBTN, KEY_STATE::TAP);
CUI* pUI=nullptr;

if (!bMousedown &amp;&amp; m_pForcusedUI)
    return m_pForcusedUI;
//Tap이 발생 했다는 전제
for (; iter != vecUI.end(); ++iter)//On된 것들 중의 가장 나중의 UI를 찾기
{
    if (((CUI*)(*iter))-&gt;IsMouseOn())
    {
        if (((CUI*)(*iter))-&gt;m_bLbtnTap)
        {
            pUI =(CUI*)(*iter);
            Targetiter = iter;
        }


    }
}    
if (Targetiter == vecUI.end())//찾아도 없으면
    return nullptr;

((CUI*)(*Targetiter))-&gt;m_bLbtnDown = true;

vecUI.erase(Targetiter);//그룹벡터에서 해당 iter erase
vecUI.push_back((CObject*)pUI); //맨 뒤에 넣기


return pUI;</code></pre><p>}</p>
<h2 id="forcused-ui를-바꾸기">forcused UI를 바꾸기</h2>
<p>void CUIMgr::SetFcousedUI(CUI*_pUI)
{
    if (m_pForcusedUI == _pUI|| _pUI == nullptr)
        return;</p>
<pre><code>CScene* pCurScene = CSceneMgr::GetInst()-&gt;Get_pCurScene();
vector&lt;CObject*&gt;&amp; vecUI = pCurScene-&gt;Get_vecUI();
vector&lt;CObject*&gt;::iterator iter = vecUI.begin();
m_pForcusedUI = _pUI;
for (; iter != vecUI.end(); ++iter)
{
    if (m_pForcusedUI == *iter)
    {
        break;
    }
}

vecUI.erase(iter);
vecUI.push_back(m_pForcusedUI);</code></pre><p>}</p>
<h2 id="함수-포인터-사용">함수 포인터 사용</h2>
<p>수 많은 이벤트들의 해당하는 함수를 따로 구현한다면 
클래스마다 오버라이딩을 해줘야 해서 비효율적
함수 포인터로 함수를 받아서 실행 하자
btnUI에서 정의한것</p>
<pre><code class="language-cpp">typedef void (*BTN_FUNC)(DWORD_PTR, DWORD_PTR);

   void SetClickedCallBack(BTN_FUNC _pFunc, DWORD_PTR _param1, DWORD_PTR _param2) 
    {
         m_pFunc=_pFunc;
         m_param1 = _param1;
         m_param2 = _param2;
    }</code></pre>
<pre><code class="language-cpp">//전역함수
void ScenChange(DWORD_PTR, DWORD_PTR) {
    ChangeScene(SCENE_TYPE::START);
}

btnStartUI-&gt;SetClickedCallBack(&amp;ScenChange, 0, 0);
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Tile]]></title>
            <link>https://velog.io/@being_game/Tile</link>
            <guid>https://velog.io/@being_game/Tile</guid>
            <pubDate>Thu, 11 Jan 2024 12:11:52 GMT</pubDate>
            <description><![CDATA[<h1 id="tile">Tile</h1>
<p>출력위치를 좌상단
본인의 위치도 좌상단</p>
<p>2의 제곱 단위픽셀을 타일로 사용하는것이 좋다</p>
<p>32bit 8*6의 타일 이미즈를 사용 한다고 하면</p>
<p>첫번째부터 오른쪽으로 차례로 인덱스가 매겨지고 </p>
<p>행과 열 계산 가능
인덱스/ (열의 최대 개수인 8) = 몇번째 행
인덱스 % (열 최대갯수8) =몇번째 열</p>
<p>타일 이미즈 전체를 픽셀 단위로 나위어 인덱스화 화였다.</p>
<p>값을 입력받는 ui
값을 입력받은 후 tile 생성 </p>
<h1 id="윈도우-처리-방식">윈도우 처리 방식</h1>
<p>모달 
모든 주목을 하나의 윈도우로,다이얼 로그 또한 모달방식    </p>
<p>메인 처리기에서 메세지를 받고 크레에이트 윈도우를 통해 하나 만듦
해당 윈도우 처리기 실행, 엔드 메시지 받으면 그 윈도우의 커널 오브젝트
제거하면서 그 윈도우 제거 
즉 이 윈도우가 return을 하지않으면 다른 윈도우들은 실행이 안됨</p>
<p>모달리스-실시간 윈도우 메세지 받아들이고 처리</p>
<pre><code>크레에이트 윈도우 여러개 한 후, 
메인 cpp의 메세지 처리 루프에 각 윈도우 메세지가 큐에 쌓일 것이고
하나씩 꺼내서 해당 하는 윈도우 주소에 메세지 전달
메세지 들어오면 해당 윈도우의 procedure함수에서 처리     </code></pre><h1 id="리소스-뷰리소스-헤더파일">리소스 뷰,리소스 헤더파일</h1>
<p>리소스뷰에서 다이얼로그를 하나 만든다면 
리소스 헤더파일에 만든거나 변경된 아이디가 #define코드가 추가 됨 
main cpp이 리소스 헤더파일을 참조 하고 있기때문에 메세지 처리 루프에서 인식 할수 있음</p>
<p>리소스 헤더 파일과 리소스뷰를 동시에 열수 없음
헤더파일을 본다는 것은 헤더파일의 문자열을 메모리에 올리는건데 리소스뷰를 연다는 것은
원본은 변경 시킬 수 있다는 것이기 때문에 괴리가 생겨서 막아 놓았음</p>
<p>박스의 버튼에도 아이디가 있다
버튼도 엄밀히 따지면 윈도우이다. 자식 윈도우와 같은 개념.</p>
<h1 id="dialogbox">DialogBox</h1>
<p>윈도우 등록하는 곳에 윈도우 메뉴바 등록 한것 처럼 </p>
<p>윈도우이며 모달 방식 </p>
<p>메인 처리기에서 메시지를 받은 후 </p>
<p>해당 윈도우 이동 한후 마지막 인자의 함수 실행
<img src="https://velog.velcdn.com/images/being_game/post/88569c5a-54fc-409e-b827-db98c737bdeb/image.png" alt=""></p>
<p>리턴값으로 마지막인자의 엔드 다이얼로그 메세지를받을수 있음
<img src="https://velog.velcdn.com/images/being_game/post/b9a0aba7-e80f-43ae-bfbe-5d6407ffc51f/image.PNG" alt=""></p>
<p>위의 캡처는 해당 메세지가 호출된 윈도우의 처리기 함수(메인 윈도우)</p>
<p>여기서 okay or cancel을 리턴
<img src="https://velog.velcdn.com/images/being_game/post/ee90bd18-4311-4676-8f8e-d55fb63c0c1a/image.PNG" alt=""></p>
<p>MAKEINTRESOURCE의 매개변수 문자들이 내가 만든 다이얼로그의 아이디이다</p>
<p>메인 처리기에서 리턴된 반환값을 받고 처리 할수도 있다 라는 것만 알아두기</p>
<p>다이얼로그 리소스뷰에서의 속성에 숫자를 true로 하면 숫자만 받게 한다</p>
<h1 id="다이얼로그에서-입력받은-xy-count수-만큼-타일-생성하기">다이얼로그에서 입력받은 x,y count수 만큼 타일 생성하기</h1>
<p>GetDigItemInt 
실제 입력된것은 문자열이지만 이것을 숫자로 바꿔주는 것</p>
<pre><code class="language-cpp">INT_PTR CALLBACK TileCountProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
 if (LOWORD(wParam) == IDOK)//타일 x,y갯수들의 숫자를 입력하고 ok눌렀을때 
 {
     UINT iXCount    =GetDlgItemInt(hDlg, IDC_EDIT1, nullptr, false);//적은 숫자 받기
     UINT iYCount    =GetDlgItemInt(hDlg, IDC_EDIT2, nullptr, false);
    CScene*pCurScene= CSceneMgr::GetInst()-&gt;Get_pCurScene();//현재씬 받기
    CScene_Tool* pSceneTool = dynamic_cast&lt;CScene_Tool*&gt;(pCurScene);//씬툴로 다운 캐스팅
    assert(pSceneTool);//sceen tool로 다운캐스팅 실패면 assert
    pSceneTool-&gt;DeleteGroup(GROUP_TYPE::Tile);//원래 있던 타일 초기화
    pSceneTool-&gt;CreateTile(iXCount, iYCount);//입력받은 수 만큼 타일 만들기
    EndDialog(hDlg, LOWORD(wParam));

    return (INT_PTR)TRUE;
 }

}</code></pre>
<p>이 CALLBACK형 함수를 메인 cpp의 윈도우 proc함수에서 
다이얼로그 3번째 인자로 넣어주면 메뉴 타이틀에서 실행 가능하다
<img src="https://velog.velcdn.com/images/being_game/post/cd9983b1-db36-42ad-a3f0-14e1abb10948/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Camera]]></title>
            <link>https://velog.io/@being_game/camer</link>
            <guid>https://velog.io/@being_game/camer</guid>
            <pubDate>Wed, 10 Jan 2024 16:43:45 GMT</pubDate>
            <description><![CDATA[<h1 id="camera-기본-개념">Camera 기본 개념</h1>
<p>카메라가 보는 곳이 화면의 중앙</p>
<p>obj pos는 실제 obj의 위치</p>
<p>카메라에 따라 obj이가 보이는 위치가 달라져야 한다.
실 좌표와 출력 좌표가 나뉘어 져야한다</p>
<p>렌더링을 진행 할때만 좌표를 카메라에 따라 달리 해준다</p>
<p>카메라가 있었진 않지만 현재 카메라의 위치는 해상도의 중앙이다
따라서 카메라가 처음 보는 곳이 해상도 중앙 </p>
<p>모든 obj들이 camera를 알고 있어야함, 자식obj헤더에서  카메라헤더 파일참조</p>
<h1 id="render-pos">render pos</h1>
<p>카메라가 움직인다면 
카메라가 해상도 중앙에서 이동한 거리만큼
물체들은 반대쪽으로 이동해야 함</p>
<p>render pos는 실제 위치에서 중앙으로부터 차이를 빼주면 나온다</p>
<pre><code class="language-cpp">Vec2 CCamera::GetRenderPos(Vec2 _vObjPos)
{                      //중앙으로부터의 차이         
    return _vObjPos - m_vDiff;
}</code></pre>
<h1 id="target-camera">target camera</h1>
<p>매 업데이트 마다 타겟 obj의 위치를 카메라 중심으로 한다
void CCamera::update
{
if (m_pTargetObj)
    {
        if (m_pTargetObj-&gt;IsDead())
            m_pTargetObj = nullptr;
        else { m_vLookAt = m_pTargetObj-&gt;GetPos(); }
    }
}</p>
<h1 id="smoooth-follow마우스-클릭-좌표에-따른">smoooth follow(마우스 클릭 좌표에 따른)</h1>
<p><img src="https://velog.velcdn.com/images/being_game/post/a04e0d42-3da8-4dfb-924a-bd996f9067d6/image.PNG" alt="">
마우스 클릭이 발생하면 그 좌표에 카메라가 속력과 함께 이동한다</p>
<h2 id="keymgr-update에서-마우스-pos-얻기">KeyMgr update에서 마우스 pos 얻기</h2>
<p>POINT ptPos = {};
GetCursorPos(&amp;ptPos);//마우스 위치를 컴퓨터 스크린 기준으로 알려줌
현재 윈도우와 스크린의 차이값이 발생
//현재 윈도우기준 값으로 바꿔준다
ScreenToClient(CCore::GetInst()-&gt;GetMainHwnd(),&amp;ptPos);
m_vCurMousPos = Vec2((float)ptPos.x, (float)ptPos.y);</p>
<h2 id="마우스-좌표-렌더링-실-좌표">마우스 좌표 렌더링-&gt;실 좌표</h2>
<p>클라이언트 속 마우스 좌표는 카메라 렌더링 중의 좌표이다 
카메라의 위치는 실 위치를 알아야 하므로 렌더링-&gt;실제 좌표로 바꿔야 한다
Vec2 CCamera::GetRealPos(Vec2 _vObjPos)
{
    return m_vDiff + _vObjPos;
}
마우스 좌 클릭하면 그곳의 실 좌표를 카메라로 하고 이동진행 시간을 0초로 초기화 한다
void SetLookAt(Vec2 _vLook) { m_vLookAt = _vLook; m_frunningtime = 0.f;  }</p>
<h2 id="방향벡터를-알아야-쫓아-갈수-있다">방향벡터를 알아야 쫓아 갈수 있다</h2>
<p>Vec2 vLookDir = (m_vLookAt - m_vPrevLookAt);//쫓아갈 방향 벡터</p>
<h2 id="등속도-카메라-이동-업데이트">등속도 카메라 이동 업데이트</h2>
<pre><code class="language-cpp">void CCamera::CalDiff(){
Vec2 vLookDir = (m_vLookAt - m_vPrevLookAt);//쫓아갈 방향 벡터
    m_frunningtime+=fDT;
    if (m_frunningtime &gt;= m_ftime) 
    { m_vCurLookAt = m_vLookAt; 
    m_frunningtime = 0.f; m_fspeed = 0.f; 
    }
    //이동진행 시간이 목표 시간보다 같거나 클때,위치를 현재 위치를 목적지로 옮긴다
    else
    {    if(m_fspeed==0.f)
        m_fspeed = fdistance / m_ftime;//등속도 지정
        m_vCurLookAt = m_vPrevLookAt + (vLookDir.Normalize() * m_fspeed * fDT);
    }

    m_vDiff = m_vCurLookAt-vCenter ;// 현재 카메라와 화면중앙의 차이
    m_vPrevLookAt = m_vCurLookAt;//현재 지점이 이전 지점이 된다
}

}</code></pre>
]]></description>
        </item>
    </channel>
</rss>