Flutter SDK 설치

먼저 Flutter를 설치하는 방법은 크게 두 가지가 있다.

 

첫 번째는 공식 홈페이지에 들어가서 직접 파일을 다운로드하여 압축을 풀고 환경변수 설정을 하는 것이다.

 

두 번째로는 Visual Studio Code를 활용해서 여기서 Flutter를 설치하는 방법이 있다.

 

해당 내용은 플러터 공식 홈페이지에서도 확인 가능하다.

 

첫 번째 방법

먼저 공식 홈페이지에서 SDK 압축 파일을 다운로드한 다음 적절한 경로에 옮겨두고 압축을 푼다.

이 경로에는 특수 문자나 공백을 포함해선 안되며 또한 권한이 필요한 폴더 내에 위치해서도 안된다.

 

저장한 위치의 경로를 복사해 둔 다음 이 경로 사용자 변수 또는 시스템 변수의 PATH에 등록한다.

Flutter - Env var

 

두 번째 방법

VSCode를 열고 확장 프로그램 마켓을 열고 flutter를 검색해서 가장 상단에 있는 걸 설치한다.

Flutter - VSCode market place

 

프로젝트 생성

플러터 SDK의 설치가 끝났다면 VSCode를 열고 팔레트를 열어서(Ctrl + Shift + P) 새로운 플러터 프로젝트를 생성한다.

 

Flutter - New Project

 

New Project를 선택하면 > 프로젝트 템플릿 > 프로젝트 생성 경로 > 프로젝트 이름

 

프로젝트 템플릿

프로젝트 템플릿은 Application, Empty, Skeleton이 있다.

 

Application은 기본적인 UI 구성 요소가 만들어져 있어 처음에 Flutter의 계층 구조나 State 개념을 파악하는데 괜찮을 듯하다.

 

Empty는 뜻 그대로 기본 main 함수와 MaterailApp()만 작성되어 있는 실행가능한 최소 상태이다.

 

Skeleton은 기본 페이지 구성과 라우팅 구조를 갖춘 템플릿으로 어느 정도 숙련도가 있다면 빠른 작업 진행에 유용할 것 같다.

 

생성 경로

해당 경로에 '프로젝트 이름' 폴더가 생성되고 IDE에서 해당 폴더를 연다. 이름은 경로 설정 후 입력가능하며 기본 이름값이 주어진다.

 

프로젝트 이름

프로젝트 폴더 이름뿐만 아니라 앱의 이름인 pubspec.yml 파일의 name 필드의 값도 해당 이름으로 설정된다. 

 

추가 패키지 설치

Flutter 프로젝트의 생성이 끝났다면 먼저 IDE에서 터미널을 열고, flutter doctor 명령어를 실행시켜 문제가 없는지 확인한다.

 

해당 명령어의 실행이 끝나면 체크 항목과 문제 사항을 볼 수 있는데 여기서 문제가 되는 부분들을 하나씩 해결해 주도록 한다.

 

이미 한 번 작업을 마친 상태였기 때문에 현재는 문제가 발생하지 않지만 일반적으로 색칠한 부분에서 문제가 발생할 것이다.

 

Flutter Doctor

 

Android Studio - 안드로이드 스튜디오가 없다면 요구되는 버전을 확인 후 설치한다.

Android toolchain - 안드로이드 스튜디오의 SDK 매니저에서 Android toolchain을 찾아서 설치한다.

Visual Studio - VS를 버전에 맞게 설치하고 추가 설치 항목에서 develop Windows apps를 설치한다.

 

문제가 모두 해결되었는지 다시 flutter doctor를 실행해서 확인한다.

 

여기까지 완료되었다면 기본적인 준비가 완료되었다.

 

다시 팔레트를 열어서 Flutter: Launch Emulator를 클릭해서 가상 머신을 실행시킨 후 터미널에서 flutter run을 실행시켜 앱을 띄워본다.

 

IDE의 이 버튼을 눌러도 실행을 시킬 수 있다.

Flutter - Run

 

Flutter - Run with vm

 

애뮬레이터를 추가하려면 안드로이드 스튜디오의 디바이스 매니저에서 추가하면 된다.

728x90
반응형

Player

Input System을 활용해서 간단한 플레이어를 만들어 본다.

 

구현할 기능은 Move, Sprint

 

디바이스는 키보드, Invoke C Sharp Events로 작업한다.

 

Move

Input Action에서 WASD의 입력을 받아서 플레이어 이동으로 처리한다.

 

Input Action - Move

 

Input Action에서 WASD키를 조합하여 Move 액션을 만든다.

 

스크립트에서 PlayerInput의 onActionTriggered 이벤트에 OnActionTriggered 함수를 리스너로 등록하고, OnActionTriggered 함수 안에서 각 액션에 대한 처리를 한다.

 

private PlayerInput playerInput;
private Vector2 moveInput;

private void Awake()
{
	...
    playerInput = GetComponent<PlayerInput>();
    playerInput.onActionTriggered += OnActionTriggered;
    ...
}

...


private void OnActionTriggered(InputAction.CallbackContext context)
{
    if (context.action.name == "Move" && context.performed)
    {
        OnMove(context);
    }
}

...

public void OnMove(InputAction.CallbackContext context)
{
    moveInput = context.ReadValue<Vector2>();
}

 

WASD 키 입력에 따라서 moveInput의 값이 수시로 업데이트되고 플레이어의 움직임을 관리하는 함수에서 moveInput 값을 사용해서 처리한다.

 

확실한 입력이 있을 때 만 처리하기 위해서 performed 인 경우를 체크한다.

 

Sprint

달리기를 위한 기능으로 눌린 상태에서 더 빠르게 움직이도록 한다.

Input Action - Sprint

 

Left Shift 키와 바인딩하여 누르고 있을 때 달리고 떼면 다시 걷도록 한다. 이 입력을 위해서 Press And Release로 키 입력을 받는다.

 

private void OnActionTriggered(InputAction.CallbackContext context)
{
	...
    
    if (context.action.name == "Sprint" && context.performed)
    {
        OnSprint(context);
    }

    ...
}

public void OnSprint(InputAction.CallbackContext context)
{
    isSprint = context.ReadValue<float>() == 1;
    currentSpeed = isSprint ? moveSpeed * 2f : moveSpeed;
    Debug.Log("On Sprint");
}

 

눌림 상태는 float 값으로 들어오며 눌리면 1 떼면 0으로 콜백이 들어온다.

 

이 값을 달리는 상태를 변경하는 플래그로 사용해서 처리한다.

 

간단하게 조작 로직을 구현해서 본다.

 

Player - Move&Sprint

 

728x90
반응형

'Develop > Unity' 카테고리의 다른 글

Input System - Player Input  (0) 2025.04.11
Input System - Input Actions  (0) 2025.04.10
InputSystem 기본 사용법  (0) 2025.03.25
유니티 기본 물리 샘플  (0) 2025.03.21
구글 계정 연동  (1) 2025.02.28

1번 행렬 덧셈

문제

N * M 크기의 두 행렬 A와 B가 주어졌을 때, 두 행렬을 더하는 프로그램을 작성하시오.

 

입력

첫째 줄에 행렬의 크기 N과 M이 주어진다. 둘째 줄부터 N개의 줄에 행렬 A의 원소 M개가 차례대로 주어진다.

이어서 N개의 줄에 행렬 B의 원소 M개가 차례대로 주어진다. N과 M은 100보다 작거나 같고, 행렬의 원소는 절댓값이 100보다 작거나 같은 정수이다.

 

출력

첫째 줄부터 N개의 줄에 행렬 A와 B를 더한 행렬을 출력한다. 행렬의 각 원소는 공백으로 구분한다.

 

C++

#include <iostream>
#include <vector>
using namespace std;
int main(){
    int n, m;
    cin >> n >> m;
    vector<vector<int>> arr_2d(n, vector<int>(m));
    
    for (int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            cin >> arr_2d[i][j];
        }
    }
    for (int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            int val = 0;
            cin >> val;
            cout << arr_2d[i][j] + val << " ";
        }
        cout << "\n";
    }
}

 

C#

using System;
using System.Collections;
using System.Collections.Generic;
class Program{
    static void Main(string[] args){
        string input = Console.ReadLine();
        string[] input_arr = input.Split();
        int n = int.Parse(input_arr[0]);
        int m = int.Parse(input_arr[1]);
        int[][] arr_2d = new int[n][];
        
        for (int i = 0; i < n; i++){
            arr_2d[i] = new int[m];
        }
        
        for (int i = 0; i < n; i++)
        {
            string[] arr_val = Console.ReadLine().Split();
            for (int j = 0; j < m; j++)
            {
                arr_2d[i][j] = int.Parse(arr_val[j]);
            }
        }
        for (int i = 0; i < n; i++)
        {
            string[] arr_val = Console.ReadLine().Split();
            for (int j = 0; j < m; j++)
            {
                arr_2d[i][j] += int.Parse(arr_val[j]);
                Console.Write(arr_2d[i][j] + " ");
            }
            Console.WriteLine();
        }
    }
}

 

Python

n, m = map(int, input().split())
arr_2d_1 = [list(map(int, input().split())) for _ in range(n)]
arr_2d_2 = [list(map(int, input().split())) for _ in range(n)]
result = [[arr_2d_1[i][j] + arr_2d_2[i][j] for j in range(m)] for i in range(n)]
for row in result:
    print(' '.join(map(str, row)))

 

Node.js

const fs = require('fs');
const input = fs.readFileSync('/dev/stdin', 'utf8').trim().split('\n');
const [n, m] = input[0].split(' ').map(Number);
const arr1 = [];
const arr2 = [];

for (let i = 1; i <= n; i++){
    arr1.push(input[i].split(' ').map(Number));
}

for (let i = n + 1; i <= 2 * n; i++){
    arr2.push(input[i].split(' ').map(Number));
}

var result = [];
for (let i = 0; i < n; i++){
    const row = [];
    for (let j = 0; j < m; j++){
        row.push(arr1[i][j] + arr2[i][j]);
    }
    result.push(row);
}

result.forEach(row => console.log(row.join(' ')));

 

2번 최댓값

문제

<그림 1>과 같이 9×9 격자판에 쓰인 81개의 자연수 또는 0이 주어질 때, 이들 중 최댓값을 찾고 그 최댓값이 몇 행 몇 열에 위치한 수인지 구하는 프로그램을 작성하시오. 예를 들어, 다음과 같이 81개의 수가 주어지면

https://www.acmicpc.net/problem/2566

 

이들 중 최댓값은 90이고, 이 값은 5행 7열에 위치한다.

 

입력

첫째 줄부터 아홉 번째 줄까지 한 줄에 아홉 개씩 수가 주어진다. 주어지는 수는 100보다 작은 자연수 또는 0이다.

 

출력

첫째 줄에 최댓값을 출력하고, 둘째 줄에 최댓값이 위치한 행 번호와 열 번호를 빈칸을 사이에 두고 차례로 출력한다. 최댓값이 두 개 이상인 경우 그중 한 곳의 위치를 출력한다.

 

이차원 배열에 저장하고 순회하면서 가장 큰 숫자를 찾고 그 숫자와 인덱스를 출력하면 되는 문제다. 그런데 이차원 배열을 굳이 만들지 않아도 입력을 처리할 때 바로 큰 수와 인덱스를 찾을 수 있긴 하다. 처음 풀이는 의도에 맞게 풀고 그 이후는 간단한 방법을 사용해 본다.

 

C++

#include <iostream>
#include <vector>
using namespace std;
int main(){
    int n = 9;
    vector<vector<int>> arr_2d(n, vector<int>(n, 0));
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            cin >> arr_2d[i][j];
        }
    }
    
    
    int max_val = arr_2d[0][0];
    int max_row = 0;
    int max_col = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (arr_2d[i][j] > max_val) {
                max_val = arr_2d[i][j];
                max_row = i;
                max_col = j;
            }
        }
    }
    cout << max_val << "\n";
    cout << max_row + 1 << " " << max_col + 1;
    
    return 0;
}

 

C#

using System;
class Program{
    static void Main(string[] args){
        int n = 9;
        int maxVal = 0;
        int row = 0;
        int col = 0;
        for (int i = 0; i < n; i++){
            string[] strArr = Console.ReadLine().Split();
            for (int j = 0; j < n; j++){
                int tmpVal = int.Parse(strArr[j]);
                if (tmpVal > maxVal){
                    maxVal = tmpVal;
                    row = i;
                    col = j;
                }
            }
        }
        Console.WriteLine($"{maxVal}");
        Console.WriteLine($"{row + 1} {col + 1}");
    }
}

 

Python

max_val = 0;
col = 0;
row = 0;
for i in range(9):
    arr = list(map(int, input().split()))
    for j in range(9):
        tmp_val = arr[j]
        if max_val < tmp_val:
            max_val = tmp_val
            row = i;
            col = j;
print(f"{max_val}\n{row + 1} {col + 1}")

 

Node.js

const fs = require('fs');
const input = fs.readFileSync('/dev/stdin', 'utf8').trim().split('\n');
let col = 0;
let row = 0;
let max_val = 0;
for (let i = 0; i < 9; i++){
    const arr = input[i].split(' ').map(Number);
    for (let j = 0; j < 9; j++){
        if (arr[j] > max_val){
            max_val = arr[j];
            row = i;
            col = j;
        }
    }
}
console.log(`${max_val}\n${row + 1} ${col + 1}`);

 

3번 세로 읽기

문제

아직 글을 모르는 영석이가 벽에 걸린 칠판에 자석이 붙어있는 글자들을 붙이는 장난감을 가지고 놀고 있다. 이 장난감에 있는 글자들은 영어 대문자 ‘A’부터 ‘Z’, 영어 소문자 ‘a’부터 ‘z’, 숫자 ‘0’부터 ‘9’이다. 영석이는 칠판에 글자들을 수평으로 일렬로 붙여서 단어를 만든다. 다시 그 아래쪽에 글자들을 붙여서 또 다른 단어를 만든다. 이런 식으로 다섯 개의 단어를 만든다. 아래 그림 1은 영석이가 칠판에 붙여 만든 단어들의 예이다.

A A B C D D
a f z z 
0 9 1 2 1
a 8 E W g 6
P 5 h 3 k x
<그림 1>

 

한 줄의 단어는 글자들을 빈칸 없이 연속으로 나열해서 최대 15개의 글자들로 이루어진다. 또한 만들어진 다섯 개의 단어들의 글자 개수는 서로 다를 수 있다. 심심해진 영석이는 칠판에 만들어진 다섯 개의 단어를 세로로 읽으려 한다. 세로로 읽을 때, 각 단어의 첫 번째 글자들을 위에서 아래로 세로로 읽는다. 다음에 두 번째 글자들을 세로로 읽는다. 이런 식으로 왼쪽에서 오른쪽으로 한 자리씩 이동하면서 동일한 자리의 글자들을 세로로 읽어 나간다. 위의 그림 1의 다섯 번째 자리를 보면 두 번째 줄의 다섯 번째 자리의 글자는 없다. 이런 경우처럼 세로로 읽을 때 해당 자리의 글자가 없으면, 읽지 않고 그다음 글자를 계속 읽는다. 그림 1의 다섯 번째 자리를 세로로 읽으면 D1gk로 읽는다. 그림 1에서 영석이가 세로로 읽은 순서대로 글자들을 공백 없이 출력하면 다음과 같다: Aa0aPAf985Bz1EhCz2W3D1gkD6x 칠판에 붙여진 단어들이 주어질 때, 영석이가 세로로 읽은 순서대로 글자들을 출력하는 프로그램을 작성하시오.

 

입력

총 다섯 줄의 입력이 주어진다. 각 줄에는 최소 1개, 최대 15개의 글자들이 빈칸 없이 연속으로 주어진다. 주어지는 글자는 영어 대문자 ‘A’부터 ‘Z’, 영어 소문자 ‘a’부터 ‘z’, 숫자 ‘0’부터 ‘9’ 중 하나이다. 각 줄의 시작과 마지막에 빈칸은 없다.

 

출력

영석이가 세로로 읽은 순서대로 글자들을 출력한다. 이때, 글자들을 공백 없이 연속해서 출력한다.

 

C++

#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
int main(){
    int max_col = 15;
    string line;
    vector<vector<char>> matrix;
    for (int i = 0; i < 5; i++){
        getline(cin, line);
        vector<char> row(line.begin(), line.end());
        matrix.push_back(row);
    }
    for (int col = 0; col < max_col; col++){
        for (int row = 0; row < matrix.size(); row++){
            if (col < matrix[row].size()){
                cout << matrix[row][col];
            }
        }
    }
    return 0;
}

 

C#

using System;
using System.Collections.Generic;
using System.Linq;
class Program{
    static void Main(string[] args){
        int max_col = 15;
        string line;
        List<List<char>> matrix = new List<List<char>>();
        
        while((line = Console.ReadLine()) != null){
            matrix.Add(line.ToList());
        }

        for (int col = 0; col < max_col; col++){
            for (int row = 0; row < matrix.Count; row++){
                if (matrix[row].Count > col){
                    Console.Write(matrix[row][col]);
                }
            }
        }
    }
}

 

Python

max_row = 5;
max_col = 15;
matrix = [list(input()) for _ in range(max_row)]
for col in range(max_col):
    for row in range(max_row):
        if col < len(matrix[row]):
            print(matrix[row][col], end="")

 

Node.js

const fs = require('fs');
const max_row = 5;
const max_col = 15;
const input = fs.readFileSync('/dev/stdin', 'utf8').trim().split('\n');
for (let col = 0; col < max_col; col++){
    for (let row = 0; row < max_row; row++){
        if (col < input[row].length) {
            process.stdout.write(input[row][col]);    
        }
    }
}

 

4번 색종이

문제

가로, 세로의 크기가 각각 100인 정사각형 모양의 흰색 도화지가 있다. 이 도화지 위에 가로, 세로의 크기가 각각 10인 정사각형 모양의 검은색 색종이를 색종이의 변과 도화지의 변이 평행하도록 붙인다. 이러한 방식으로 색종이를 한 장 또는 여러 장 붙인 후 색종이가 붙은 검은 영역의 넓이를 구하는 프로그램을 작성하시오.

https://www.acmicpc.net/problem/2563

 

예를 들어 흰색 도화지 위에 세 장의 검은색 색종이를 그림과 같은 모양으로 붙였다면 검은색 영역의 넓이는 260이 된다.

 

입력

첫째 줄에 색종이의 수가 주어진다. 이어 둘째 줄부터 한 줄에 하나씩 색종이를 붙인 위치가 주어진다. 색종이를 붙인 위치는 두 개의 자연수로 주어지는데 첫 번째 자연수는 색종이의 왼쪽 변과 도화지의 왼쪽 변 사이의 거리이고, 두 번째 자연수는 색종이의 아래쪽 변과 도화지의 아래쪽 변 사이의 거리이다. 색종이의 수는 100 이하이며, 색종이가 도화지 밖으로 나가는 경우는 없다.

 

출력

첫째 줄에 색종이가 붙은 검은 영역의 넓이를 출력한다.

 

2차원 배열 카테고리의 마지막 문제라서 그런가 단순 값 처리가 아닌 응용이 필요한 문제이다.

100 x 100 크기의 도화지란 배열의 최대 크기를 정한 것으로 [100][100] 크기의 2차원 배열 안에서 이루어지는 작업이다.

색종이는 모두 동일한 크기로 최대 100개까지 붙인다. 색종이 크기는 모두 일정한 10 x 10이며 왼쪽 하단의 꼭짓점에 대한 좌표가 주어진다.

 

당장은 두 가지 방법이 떠오른다.

1. 도화지에서 색종이가 없는 영역 구하기

2. 전체 색종이 개수의 영역에서 겹치는 부분 제외하기

 

2차원 배열의 구조를 기준으로 생각해 본다.

100 x 100 크기에서 입력된 색종이 범위만큼 인덱스를 체크해 놓고 최종적으로 체크한 부분만 계산하면 색종이가 덮은 영역이 나온다.

C++

#include <iostream>
#include <vector>
using namespace std;
int main(){
    int count = 0;
    int matrix[100][100] = {0};
    cin >> count;
    for (int i = 0; i < count; i++){
        int x1, y1, x2, y2 = 0;
        cin >> x1;
        cin >> y1;
        x2 = x1 + 10;
        y2 = y1 + 10;
        for (int x = x1; x < x2; x++){
            for (int y = y1; y < y2; y++){
                matrix[x][y] = -1;
            }
        }
    }
    
    int area = 0;
    for (int row = 0; row < 100; row++){
        for (int col = 0; col < 100; col++){
            if (matrix[row][col] == -1){
                area++;
            }
        }
    }
    cout << area;
    return 0;
}

 

 

중복으로 겹쳐진 부분을 체크하는 부분을 조건을 주고 확인하는 걸 추가해도 될 것 같다.

 

C#

C++로 코드를 쓰면서 방식에 문제가 없으니 좀 더 정리해서 작성해 본다.

using System;
class Program{
    static void Main(string[] args){
        int[,] matrix = new int[100, 100];
        int count = int.Parse(Console.ReadLine()!);
        
        for (int i = 0; i < count; i++){
            string? input = Console.ReadLine();
            if (string.IsNullOrEmpty(input)) return;
            string[] xy = input.Split();
            int x = int.Parse(xy[0]);
            int y = int.Parse(xy[1]);
            
            for (int dx = x; dx < x + 10; dx++){
                for (int dy = y; dy < y + 10; dy++){
                    matrix[dx, dy] = -1;
                }
            }
        }
        
        int area = 0;
        for (int row = 0; row < 100; row++){
            for (int col = 0; col < 100; col++){
                if (matrix[row, col] == -1){
                    area++;
                }
            }
        }
        Console.WriteLine(area);
    }
}

 

Python

count = int(input());
matrix = [[0] * 100 for _ in range(100)]
for _ in range(count):
    x, y = map(int, input().split())
    for dx in range(x, x + 10):
        for dy in range(y, y + 10):
            matrix[dx][dy] = 1
area = sum(row.count(1) for row in matrix)
print(area)

 

Node.js

const fs = require('fs');
const input = fs.readFileSync('/dev/stdin', 'utf8').trim().split('\n');
const count = parseInt(input[0]);
let matrix = Array.from({length : 100 }, () => Array(100).fill(0));
for (let i = 1; i <= count; i++){
    const xy = input[i].split(" ").map(Number);
    const x = xy[0];
    const y = xy[1];
    for (let dx = x; dx < x + 10; dx++){
        for (let dy = y; dy < y + 10; dy++){
            matrix[dx][dy] = 1;
        }
    }
}
let area = 0;
for (let row = 0; row < 100; row++){
    for (let col = 0; col < 100; col++){
        if (matrix[row][col] == 1){
            area++;
        }
    }
}
console.log(area);

 

728x90
반응형

+ Recent posts