x값을 따른 원사이에 있는 최소y값과 최대 y을 계산하고 이를 대칭성을 통해 계산하면 되는 문제이다. 

 

#include <string>
#include <vector>
#include <cmath>
using namespace std;
//한 사분면의 값을 찾아서 4배 시켜주기 
long long solution(int r1, int r2) {
    long long answer = 0;
    
    for(int i=1;i<=r2;i++){
        int maxY = floor(sqrt((long long)r2 * r2 - (long long)i * i));            //최대 Y값 내림해야 경계안쪽의 값까지 구할 수 있다.
        int minY = ceil(sqrt((long long)r1 * r1 - (long long)i * i));             //최소 Y값 올림해야 경계바로 바깥쪽까지의 값을 구할 수 있다.
        
        if(r1<i) minY=0;            //x값이 r1보다 크면 사이이여서 최소y는 0부터 시작
        
        answer+=(maxY-minY+1);      // 
        
    }
    return answer*4;
}

 

1. 프로젝트 생성

프로젝트는 Visual Studio의 Windows 데스크톱 애플리케이션으로 만들어주면 된다.

 

2.필터로 파일정리 

헤더파일도 소스파일안에 필터폴더로 관리하는게 좋다.

 

프리 컴파일 설정

공용으로 쓸 헤더파일을 만들고 그것을 프리 컴파일하도록 설정

 

 

 

Types -자주 사용하게될 여러가지 변수 타입

Values - 윈도우 사이즈같은 고정 변수 값

Struct - 자주 사용하게 될 구조체 타입 저장

pch - 모든 헤더파일을 가지고 있는 헤더

 

3. 프로젝트 속성 변경

 

출력디렉토리 설정 및 라이브러리 추가를 대비하여 라이브러리 받아올 경로 설정

 

 

외부라이브러리 가져올 때 마지막 설정은 설정창에서 할 수 도 있지만 코드로 제어하는게 편하다.

#pragma comment(lib,"d3d11.lib")
#pragma comment(lib,"d3dcompiler.lib")

#ifdef _DEBUG
#pragma comment(lib,"DirectXTex\\DirectXTex_Debug.lib")
#else
#pragma comment(lib,"DirectXTex\\DirectXTex.lib")
#endif

 

코드 정리

  // 기본 메시지 루프입니다: -> GetMessage는 게임에 
  while (GetMessage(&msg, nullptr, 0, 0))
  {
      if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
      {
          TranslateMessage(&msg);
          DispatchMessage(&msg);
      }
  }

//대신 사용할거 

   // 기본 메시지 루프입니다:
   while (msg.message!=WM_QUIT)
   {
       if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
       {
           TranslateMessage(&msg);
           DispatchMessage(&msg);
       }
       else //게임 프레임워크 시작
       {
           game.Update();
           game.Render();
       }
   }

 

게임 클래스를 만들어줘서 그곳에서 만드는 것으로 작동하도록 초기화해주기 

Game.h 및 Game.cpp

#pragma once


class Game
{
public:
	Game();
	~Game();
public:
	void Init(HWND hwnd);		//윈도우 핸들받아줌
	void Update();
	void Render();
private:
	HWND _hwnd;
	uint32 _width = 0;
	uint32 _height = 0;
};
#include "pch.h"
#include "Game.h"

Game::Game()
{
}

Game::~Game()
{
}

void Game::Init(HWND hwnd)
{
	_hwnd = hwnd;
	_width = GWinSizeX;
	_height = GwinSizeY;

	//TODO
}

void Game::Update()
{
}

void Game::Render()
{
}

 

전체코드 

#include "pch.h"
#include "framework.h"
#include "GameCoding.h"
#include "Game.h"

#define MAX_LOADSTRING 100

// 전역 변수:
HINSTANCE hInst;                                // 현재 인스턴스입니다.
HWND hWnd;

// 이 코드 모듈에 포함된 함수의 선언을 전달합니다:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
  

    // 1) 윈도우 창 정보 등록
    MyRegisterClass(hInstance);

    // 2) 윈도우 창 생성
    if (!InitInstance (hInstance, nCmdShow))
        return FALSE;

    Game game;
    game.Init(hWnd);

    MSG msg = {};

    // 기본 메시지 루프입니다:
    while (msg.message!=WM_QUIT)
    {
        if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else //게임 프레임워크 시작
        {
            game.Update();
            game.Render();
        }
    }

    return (int) msg.wParam;
}



//
//  함수: MyRegisterClass()
//
//  용도: 창 클래스를 등록합니다.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEXW wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);
    //밑의 정보를 이용
    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_GAMECODING));
    wcex.hCursor        = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = NULL;     //옵션메뉴
    wcex.lpszClassName  = L"GameCoding";        //이 키를 이용하여 등록
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassExW(&wcex);
}

//
//   함수: InitInstance(HINSTANCE, int)
//
//   용도: 인스턴스 핸들을 저장하고 주 창을 만듭니다.
//
//   주석:
//
//        이 함수를 통해 인스턴스 핸들을 전역 변수에 저장하고
//        주 프로그램 창을 만든 다음 표시합니다.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)        //키를 바탕으로 정보를 통해 창을 만들어줌
{
   hInst = hInstance; // 인스턴스 핸들을 전역 변수에 저장합니다.

   //윈도우 사이즈 조절 
   RECT windowRect = { 0,0,GWinSizeX,GwinSizeY };
   //메뉴는 사이즈에 공간에 포함하지 않도록
   ::AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, false);

   //나중에도 써야해서 전역변수로 만들어주기
   hWnd = CreateWindowW(L"GameCoding", L"Client", WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, windowRect.right-windowRect.left,windowRect.bottom-windowRect.top, 0, nullptr, nullptr, hInstance, nullptr);

   if (!hWnd)
   {
      return FALSE;
   }

   //::은 사용자 정의x 표준에서 가져옴
   ::ShowWindow(hWnd, nCmdShow);
   ::UpdateWindow(hWnd);

   return TRUE;
}

//
//  함수: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  용도: 주 창의 메시지를 처리합니다.
//
//  WM_COMMAND  - 애플리케이션 메뉴를 처리합니다.
//  WM_PAINT    - 주 창을 그립니다.
//  WM_DESTROY  - 종료 메시지를 게시하고 반환합니다.
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            // 메뉴 선택을 구문 분석합니다:
            switch (wmId)
            {
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
        break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            // TODO: 여기에 hdc를 사용하는 그리기 코드를 추가합니다...
            EndPaint(hWnd, &ps);
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

 

결과 화면

무슨 물체를 띄우든 렌더링 파이프라인을 한번 거쳐야해서 함수가 많고 복잡하다

 

'게임공부 > Directx11' 카테고리의 다른 글

[Directx11]4. 삼각형 그리기  (1) 2024.07.01
[Directx11]3.장치초기화  (0) 2024.06.27
[Directx11]그래픽스OT  (0) 2024.06.25
[Directx11]2.랜더링 파이프라인2  (0) 2024.06.21
[Directx11]1. 렌더링 파이프라인-1  (0) 2024.06.19

https://www.youtube.com/watch?v=Bu-CiOvvYgY&list=PLiSlOaRBfgkcPAhYpGps16PT_9f28amXi&index=18

오늘은 슬롯을 클릭했을 때 나오는 리스트목록을 클릭했을 때 해당 아이템이 슬롯에 표시되는 것을 구현해보자

 

1.캐릭터에 Spring Arm 및 SceneCaptureComponent2D추가 해주기 - 장비화면에서 가운데 캐릭터가 보일 수 있도록

 

이것을 통해 액터만 카메라에 보이게 한다. 배경 벽 제외 -> 캐릭터만 보일 수 있도록

Spring Arm 회전을 줘서 플레이어 앞에 위치하도록
렌더 모드를 변경하여 원하는 것만 해당 카메라에 보여줄 수 있도록 캐릭터가 생성될 때 해당액터의 부분만 보이도록 설정
고정된 카메라이고 멈추지않도록 하기위해 콜리전테스트실행 비활성화

 

SceneCaptureComponent2D의 텍스처 타킷을 장비 시스템 UI 폴더에 새롭게 만들어준다.

 

그리고 실행시켜보면 

게임실행 시 텍스처화면

이런식으로  해당 액터만 나오게 된다.

하늘을 지우기 위해

만들어진 텍스처를 우클릭해서 새 머터리얼 생성을 한 뒤 도메인과 모드를 바꿔주고 함수 흐름을 이렇게 바꿔주면 

 

머터리얼 설정
위의 설정이 적용된 화면

 

이제 만든 텍스처를 장비시스템 UI에 붙여주면 된다. 

가운데에 딱 맞게 이미지가 줄어들지 않도록 Scale Box를 만든 뒤 자식으로 넣어준다. 

이때 가운데에 맞도록 정렬값은 0.5 0.5가 되도록 설정한다.

인벤토리 UI설정


또한 SpringArm의 길이를 줄여서 UI를 켰을 때 적당한 크기로 캐릭터가 나오도록 조절해준다.

그리고 인벤토리 UI를 켰을 때는 UI를 켰다는 효과를 주기위해 뒤에 배경은 Blur처리와 불투명하게 이미지를 깔아준다.

이때 앵커는 모두를 덮어쓸 수 있도록 하며 나머지 값들은 0으로 해준다. 

 

2. 슬롯 선택시 적용되게 기능 추가

일단 Equipable Slot 그래프에 현재 장비한 슬롯 변수를 초기화해주는 코드를 추가해준다. 

그리고 장비슬롯에 선택된 장비의 이미지가 들어올 수 있도록 이미지를 추가해준다.

 

장비 UI의 그래프에서 커스텀 이벤트를 추가해서 해당 장비슬롯에 선택한 장비의 이미지가 들어올 수 있도록 만들어주고 이것을 Item Slot에서 호출하도록 한다. 

Equipment UI의 커스텀 이벤트-> 해당하는 아이템을 찾아서 그 아이템의 이미지로 장비슬롯의 이미지를 바꿔준다.
장비 UI에서 마지막에 장비슬롯의 Item 변수를 초기화 해주는 부분
아이템슬롯 그래프에서 만약 클릭했을 때 클릭한 아이템으로 커스텀이벤트 호출

 

완성!

https://school.programmers.co.kr/learn/courses/30/lessons/176962

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

이 문제에서 중요한 점은

1.시간순으로 과제를 정렬

2.stack 안에 pair 자료형으로 멈춰진 과제를 저장할 변수를 지정

3.과제를 진행하면서 멈춘 과제를 저장하고 할 수 있는 과제를 진행

-> stack과 pair를 적절히 잘 써야한다.

#include <string>
#include <vector>
#include <algorithm>
#include <stack>
using namespace std;

int Timecalc(string  t) {
    return (60 * stoi(t.substr(0, 2))) + stoi(t.substr(3));
}
//시간순으로 넣고 만약 겹치는거 처리
bool cmp(vector<string> a, vector<string> b) {
    return Timecalc(a[1]) < Timecalc(b[1]);
}
vector<string> solution(vector<vector<string>> plans) {
    vector<string> answer;
    stack<pair<string, int>> pause_plan;

    sort(plans.begin(), plans.end(), cmp);        //시간순으로 정렬

    int curTime = Timecalc(plans[0][1]);
    int nextTime = Timecalc(plans[1][1]);
    int SumSub = 0;           //지금까지 수행한 과제합
    while (SumSub < plans.size() || !pause_plan.empty()) {
        //만약 정지해둔 과제가 있다면
        if (!pause_plan.empty()) {
            //만약 마지막순서의 과제까지 다 했다면 멈춰둔 과제 수행
            if (SumSub == plans.size()) {
                answer.push_back(pause_plan.top().first);
                pause_plan.pop();
                continue;
            }
            //만약 다음에 수행해야할 과제까지 시간이 남아있다면
            if (curTime < nextTime) {
                int pauseTime = pause_plan.top().second;      //과제 수행해야하는 시간
                int availableTime = nextTime - curTime;        //과제 수행가능 시간

                if (pauseTime <= availableTime) {       //만약 남은 시간동안 멈춘과제를 수행가능하다면
                    answer.push_back(pause_plan.top().first);
                    pause_plan.pop();
                    curTime += pauseTime;
                }
                else {
                    pause_plan.top().second = pauseTime - availableTime;
                    curTime = nextTime;
                }
                continue;
            }
        }
        curTime = Timecalc(plans[SumSub][1]) + stoi(plans[SumSub][2]);      //과제수행
        nextTime = SumSub + 1 >= plans.size() ? 1440 : Timecalc(plans[SumSub + 1][1]);

        if (curTime > nextTime) {       //만약 과제수행하는 중에 새로운 과제가 들어온다면
            pause_plan.push({ plans[SumSub][0],curTime - nextTime });       //과제명 : 과제수행완료까지 남은시간
            curTime = nextTime;
        }
        else {
            answer.push_back(plans[SumSub][0]);
        }

        SumSub++;
    }


    return answer;
}

https://www.inflearn.com/course/directx11-%EA%B2%8C%EC%9E%84%EA%B0%9C%EB%B0%9C-%EB%8F%84%EC%95%BD%EB%B0%98/dashboard

 

[게임 프로그래머 도약반] DirectX11 입문 | Rookiss - 인프런

Rookiss | 게임 프로그래머 공부에 있어서 필수적인 DirectX 11 지식을 초보자들의 눈높이에 맞춰 설명하는 강의입니다., [사진][사진] [사진] 게임 개발자는 Unreal, Unity만 사용할 줄 알면 되는 거 아닌

www.inflearn.com

 

1. CPU vs GPU

CPU : 고급인력 - 연산 중심, 범용적으로 모든 업무를 담당

GPU : 연산 중심 - ALU가 엄청 많지만 저장하는 공간은 비교적 작다

ex) 울트라 vs 저글링 -> 퀄리티 vs 수량

-> 중요한 연산은 cpu가 복잡하지 않지만 많은 연산은 gpu

gpu 사용되는 곳 - 암호화, 게임, 인공지능

 

Q) 서버  프로그래밍에서 mmorpg를 개발하고 있다면 gpu 사용할까?

A) 사용하지 않는다. 무조건 gpu를 쓴다고 좋은게 아니다. 병렬로 처리한 값을 다시 받아야하기도 하고

각 업무가 독립적이여야한다. 다시 동기화해서 받아오는 것도 어렵다.

클라이언트에서는 당연히 사용된다.

 

RAM,SSD- 데이터 저장

ALU - 코어. Cache - 임시 저장

 

2.게임 화면

800 x 600 -> 픽셀들의 조합 

물체 - 많은 삼각형들의 조합 - 많은 연산 - gpu가 적

 

unity

기존 물체 - 로컬 영역- 좌표고정

게임씬에 배치 - 월드  좌표 - 좌표 이동, 회전 가능

카메라

-뷰포트에 따라 달라진다. -> 어떻게 보는

-조명에 따라 달라진다.

-실시간 렌더링- 실시간 움직임에 따라 보이는 것이 바뀌어야 한다.

 

3.GPU 랜더링 파이프라인

 

파란부분 - 코딩 불가 - 옵션으로 제어

녹색 - 코딩으로 제어 가능

※기억해야할 것 -Input-Assembler , Vertex Shader, Rasterizer,Pixel Shader, Output-Merger

 

Input-Assembler

-물체에 대한 기하학적인 정보를 받아준다. 

Vertex Shader

-정점에 대한 연산 - 로컬영역에 있는 물체 - 월드좌표에 어떻게 배치할지

-행렬연산- 정점 단위 

Rasterizer

-삼각형- 정점단위- 보간하는 연산

-내부영역이면 보간 진행

Pixel Shader

-픽셀 단위 - 조명에 따른 색상을 결정

-셰이더가 그림의 풍을 정한다.

Output-Merger

-결과물을 보여준다.

 

랜더링, 코어와 관련된 기능들을 작업해둔 뒤 모아서 만든 툴 셋 - 게임 엔진

 

'게임공부 > Directx11' 카테고리의 다른 글

[Directx11]4. 삼각형 그리기  (1) 2024.07.01
[Directx11]3.장치초기화  (0) 2024.06.27
[Directx11]2.초기설정  (0) 2024.06.26
[Directx11]2.랜더링 파이프라인2  (0) 2024.06.21
[Directx11]1. 렌더링 파이프라인-1  (0) 2024.06.19

https://www.youtube.com/watch?v=XmLDDoZTeWs&list=PLiSlOaRBfgkcPAhYpGps16PT_9f28amXi&index=17

오늘은 인벤토리에서 슬롯을 클릭했을 때 가지고 있는 아이템리스트가 뜨는 기능을 구현해볼 것이다.

 

1. 아이템리스트가 나올 UI 

아이템 리스트캔버스에 검은색 이미지 배경이미지와 Vertical Box를 추가해준다. 

UI구성

2.장착 슬롯에 OnclickEvent 추가해주기

장착 슬롯을 클릭했을 때 가지고 있는 장비 목록이 뜰 수 있도록 해준다.  

뜰 때 마우스 클릭한 곳에서 UI가 뜨도록 만들어준다.

Equipment_Slots Onclick Event

만약 버튼이 아닌 다른 곳을  누른다면 해당 리스트가 사라지도록 해준다.

리스트패널 사라지게 하는 기능

 

3.아이템 리스트 가져오고 Item Slot에 추가해준 뒤 Vertical Box의 자식으로 위젯 만들어주기\

BPC_EquipmentSystem에서 아이템 리스트를 가져온 뒤 가진 아이템의 수에 맞게 Vertical Box의 자식으로 추가해줘 리스트에서 보일 수 있게한다.

위젯초기화 흐름도

4. 아이템 슬롯 UI

아이템 리스트에 아이템당 하나의 슬롯을 가지게 되는데 이 슬롯UI는 

캔버스/Horizontal Box,버튼/이미지, 텍스트 구성으로 무기의 아이콘, 이름 그리고 아이템슬롯이 클릭 가능하게 하였다.

아이템 슬롯UI
Horizontal Box에서 각 요소는 채우기를 해주어야 클릭 시 모든 요소가 클릭표시가 될 수 있다.

https://www.youtube.com/watch?v=EzQbMtk1hZ0&list=PLiSlOaRBfgkcPAhYpGps16PT_9f28amXi&index=16

오늘은 장비메뉴 UI를 만들어보자

1.메뉴 UI제작

UI는 유저인터페이스/위젯블루프린터/사용자위젯으로 만들어주었다.

 

UI구성요소

UI는 켄버스와 왼쪽위에 장비 메뉴라는 글자,

캐릭터 이미지가 들어올 이미지칸, 양쪽에 인벤토리 장비가 들어올 Vertical Box를 만들어주었다. 

이때 Vertical Box의 앵커는 각 Vertical 박스의 모서리에 위치하도록했다. 이때 앵커의 위치가 정확히 모서리는 아니여도 괜찮다.

 

2. 메뉴 호출

메뉴호출은 IA_EquipmentMenu라는 키를 추가해주고 이 키에 이벤트를 추가하는 방식으로 만들었다.

메뉴호출 이벤트

주요한 내용은

메뉴창이 열려있는지 확인할 Bool 변수와 Equipment Widget을 생성하고 이를 변수로 지정해준 뒤 제거할 때는 Remove from Parent를 통해 제거해 준다. 

메뉴가 열릴때는 마우스커서 표시를 하게 해주고 Set Input Mode Game and UI를 켜서 위젯 클릭을 할 수 있게 해주고 Set Movement mode 를 None으로 만들어서 움직이지 못하게 해준다.

메뉴가 닫힐때는 이와 반대로 마우스 커서표시를 끄고 Set Input Mode Game 만을 작동하게해 UI 클릭을 못하게 하고 Set Movement mode를 Walking으로 변경해준다.

 

3.슬롯UI만들기

슬롯또한 유저인터페이스/위젯블루프린터/사용자위젯으로 만들어주었다.

내부에는 Border box/Button으로 구성하여 사용자가 클릭했을 때 아이템 리스트가 뜰 수 있도록 하였다.

슬롯UI

4.메뉴 UI완성

메뉴 UI에 Vertical Box에 Slot UI를 두개 씩 넣어준다.

이때 첫번째 꺼에는 중앙정렬을 하고 위쪽 패딩을 50 넣어주고

두번째 꺼에도 중앙정렬을 하고 위쪽 패딩은 250을 넣어준다.

밑은 패딩값과 완성된 UI이다.

UI구
패딩값(위, 아래)

https://school.programmers.co.kr/learn/courses/30/lessons/140107

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

최대점 0,d d,0 안에서 정의되는 점의 개수를 구하면 되는 문제이다.

생각해보자면 d인 원안에서 정의되는 정수 점의 개수를 구하면 된다. 

이때 x를 k의 배수로 d까지 순회하면서 피타고라스 정리를 통해 y의 최댓값을 구하고 이에 따른 정수 점이 몇개나오는 지 몫 나눗셈을 통해 구하면된다.

이때 y가 0일때도 고려해야해서 마지막에 1을 더해준다. 

#include <string>
#include <vector>
#include <cmath>

using namespace std;
//최대점 0,d d,0 안에서 정의되는 점의 개수 
long long solution(int k, int d) {
    long long answer = 0;
    for(long long x=0;x<=d;x+=k){           //x에 따른 y값 계산
        int maxy=sqrt((long long)d*d-(long long)x*x);       //x값에 따른 y의 최대값 계산-> 피타고라스 정리
        answer+=(maxy/k)+1;         //y의 최대값에 따른 x의 갯수 계산-> 좌표 개수 
        //+1의 이유: y가 0일때도 포함시키려고
    }
    return answer;
}

https://www.youtube.com/watch?v=ugiNsb9pc8k&list=PLiSlOaRBfgkcPAhYpGps16PT_9f28amXi&index=15

인벤토리 시스템

1. 무기 구조체 만들어주기 -S_Weapons

무기는 이름, 데미지, 필요레벨,아이콘 등을 가지고 있어야한다.

※무기 타입은 enum으로 선언해주기

2.아이템데이터(S_Slots)- 데이터 테이블 열 핸들 타입으로 구조체 만들기

각 아이템 객체를 가지고있음

3. 데이터 테이블 만들어주기 DB_Weapons

무기에 대한 정보를 가지고있을 데이터 테이블 만들기

4. 무기 객체 만들어주기 BP_Weapon

- 스태틱 매쉬와 아이템데이터 변수를 가지고 있음

이를 통해 아이템 정의해준다. 

Construction Script 게임동안 계속 실행된다.

객체의 정보에 따라 데이터 테이블의 아이템의 정보를 가져와서 그에 맞는 스태틱매쉬로 바뀌게 해준다

계층으로 접근하는 것보다 2번 구조체로 분할하는것이 좋다.
아이템마다 달라지는 스태틱 매쉬

5.Equipment System 만들어주기 - 액터컴포넌트

Add Weapon 함수로 무기 가져올 수 있게 

변수- weaponSlots - S_slots 구조체 -  키 눌렀을 때 가져올 수 있도록

고르는 키 추가해주기 E 

5-1. 무기 줍는로직 만들기

키를 눌렀을 때 만약 무기가 탐지된다면 추가해주기

아이템을 줍는 로직

 

아이템이 성공적으로 배열에 추가되었다!

 

https://school.programmers.co.kr/learn/courses/30/lessons/134239

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

문제가 길어서 잘 읽어야한다.

과정을 정리하자면

1. 우박수열을 계산

2. 우박수열에 해당하는 값에 따른 각각의 넓이 계산

3. 주어진 범위에 따른 넓이의 합으로 정적분 계산

조건 : 시작값이 끝점보다 커서 유효하지 않은 구간인지 검사 

나는 여기서 우박수열이 수행된 횟수만큼만 넓이를 계산하고 계산을 정적분 범위도 이 값을 통해 계산해주었다.

#include <string>
#include <vector>

using namespace std;

vector<double> solution(int k, vector<vector<int>> ranges) {
    vector<double> answer;
    vector<double> tmp;
    vector<double> sum;
    int n=k;
    int cnt=0;          //우박수열이 수행된 횟수
    tmp.push_back(n);
    //우박수열 계산
    while (n != 1) {
        if (n % 2 == 0) {
            n /= 2;
            cnt++;
        } else {
            n = n * 3 + 1;
            cnt++;
        }
        if(n<1){
            break;
        }else{
           tmp.push_back(n); 
        }  
    }
    //각가의 넓이 계산
    for(int i=0;i<cnt;i++){
        sum.push_back((tmp[i]+tmp[i+1])/2);
    }
    //정적분 계산
    for(int i=0;i<ranges.size();i++){
        double tmpsum=0;
        if(ranges[i][0]<=cnt+ranges[i][1]){
             for(int j=ranges[i][0];j<cnt+ranges[i][1];j++){
            tmpsum+=sum[j];
            }
            answer.push_back(tmpsum);
        }else{
            answer.push_back(-1);
        }  
    }
    return answer;
}

+ Recent posts