묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
C++ IOCP서버와 Unity Client 연동 관련
안녕하세요. 제가 C++을 이용한 IOCP서버와 Unity C# Client 연동해서 게임을 제작해야하는 상황에 있습니다. 사실 C++로 구현된 서버인줄 알고 구매했는데 C# 서버에 대한 강의인거 같더라구요.. C++서버와 C#을 사용하는 Unity와의 연동 그리고 Unity 자체에 대한 이해도 부족 이것이 저의 가장 큰 걱정거리인데요. 이 강의를 들어면 Unity 서버에 대한 이해도가 생겨서 C++로 독자 서버를 구축하는데 있어서 괜찮을까요??.. 그리고 여쭤보고 싶은것이 있습니다 ㅠㅠ 서버도 배운지 얼마 안되고 더더욱 Unity는 잘 몰르는데 프로젝트는 진행해야하고 처음 서버 설계 과정부터 궁금한 점이 너무 많았고 검색을 해도 잘 나오지 않아서 어려움이 많았고 항상 궁금해했는데 도움을 주시면 정말 감사하겠습니다.. 1. C++을 이용한 IOCP 서버와 Unity C# Client 연동을 위해서 어떠한 것을 고려하고 작업을 해야하는지가 궁금합니다. Byte Stream 외에도 고려해야할 부분이 뭐가 있을까요? 2. Visual Studio와 Unity 연동 이라는 것이 Visual Studio에서 서버를 키고 Unity Client를 키면 접속이 되게 하면 끝인건가요? 처음 기본 환결설정에 대해서도 궁금합니다. 3. Unity는 사실상 싱글 스레드만을 사용할 수 있는 것으로 알고 있습니다. 멀티 스레드가 지원된다고는 하나 유니티 객체에 접근하는 순간 에러가 난다고 알고 있습니다 (주워 들은 내용인데 맞는지는 모르겠습니다) 그런데 멀티스레드 사용이 필요하게 될 경우 유니티에서는 단순한 연산 작업외에는 멀티스레드를 사용하면 안되는 것인가요? 코루틴 이라는 기능이 멀티쓰레드와 비슷하다고 알고 있는데 멀티스레드 기능을 코루틴이 대체해서 사용하면 되는건가요? 4. IOCP서버를 이용하는데 싱글스레드?? 제가 C++ IOCP서버를 구현해야 하는데 이 이유에 대해 타당하게 설명을 해야하는데 저부터가 의문이 듭니다. IOCP를 사용하긴 할건데 Unity에서 멀티쓰레드를 사용하지 못한다면 IOCP로 하는것이 의미가 있을까에 대한 의문입니다. 3번 질문과 연관이 되는 질문이긴 한데요.. 간략하게 제가 만들어야 하는 게임을 설명드리자면 RPG와 FPS 장르가 합쳐진 RPS 게임으로 다중접속이 필요합니다. FPS게임이기는 하나 반응에 민감한 전통 FPS 방식은 아니라 매 프레임마다 패킷을 전송은 하지 않아도 됩니다(TCP를 사용할 것이라는 뜻이기도 합니다) 어느정도 많은 인원의 동시접속을 받아야 하기 때문에 IOCP를 사용하긴 할 것인데 이 부분에 대해서 궁금합니다. 5. 1000명이 접속하더라도 로비에 모여서 4명의 플레이어가 파티를 맺고 4명의 플레이어가 오픈월드 및 던전에 들어가게 됩니다. 즉, 유저 입장에서 보기에는 4명의 파티만을 위한 1개의 오픈월드가 펼쳐지는 것이고, 서버 입장에서는 그러한 오픈월드가 250개가(250x4 = 1000명) 펼쳐지게 되는 것입니다. (Ex.배틀 그라운드) 이러한 게임을 만들고자 할 때 게임 서버를 처음에 어떤식으로 설계해야할지 잘 모르겠고 막막합니다.. 서버와 DB를 연동하는 방법은 간략하게 배워서 DB를 사용해야한다는 점은 알겠는데 그 외의 부분에 있어서 어떤식으로 구현을 해야할지 궁금합니다. 처음부터 너무 많은 질문을 적었는데 죄송합니다. 궁금한게 너무 많았는데 질문이라도 할 수 있는 상황이 생겨서 너무 길게 적게 되었네요. 질문에 대한 도움을 주시면 정말로 감사하겠습니다..!
-
미해결홍정모의 따라하며 배우는 C++
array를 함수의 파라미터로 넣어주는게 이해가 잘 안가요
교수님 array를 함수의 파라미터로 넣어주는 부분이 좀 어려운데 다시 한번 설명을 부탁드립니다 지난시간 6.2배열기초부분에서 설명해주셨는데 형식만봐서는 배열이지만 문법상 포인터다 설명해주셨는데 array를 함수의 파라미터로 왜 넣는거죠? 이유가 궁금합니다
-
해결됨[리뉴얼] 처음하는 MongoDB(몽고DB) 와 NoSQL(빅데이터) 데이터베이스 부트캠프 [입문부터 활용까지] (업데이트)
인덱스 생성의 목적에 대한 질문입니다.
인덱스를 생성하여 활용하는 것이 부분 문자열 검색을 위한 목적이라고 하셨는데 부분 문자열이라는게 단위가 "글자"가 아닌 "단어"인가요? 예를 들어, 출연 영화를 텍스트로 인덱스를 생성했을 때 "영어토익반" 이라고 검색을 하면 "삼진그룹 영어토익반" 데이터가 출력이 되는데 "영어" 라고 검색을 하면 데이터 출력이 안되더라고요. 제가 이해한 것이 확실한지 알고 싶어서 질문드립니다.
-
해결됨홍정모의 따라하며 배우는 C++
결과 3:35 부분의미
안녕하세요 교수님 main함수안에 const int num_students = 5; 쓰고 시작하는데 이 뜻이 메모리 5개 빌릴거야 하는 뜻의 array 맞나요? 그리고 for문안에 들어가는 total_score += score[i] ; 의 의미가 헷갈리는데 설명해주시면 정말 도움이될것 같아요 감사합니다
-
해결됨안드로이드 모바일 앱 모의해킹과 시큐어코딩
오류가 나요.
삭제된 글입니다
-
미해결윤재성의 Kotlin 기반 안드로이드 앱 개발 Part1 - UI Programming
CustomAdapter 강사님 소스를 viewBinding으로
https://github.com/pulmuone/CustomAdapter adapter부분을 viewBinding으로 해봤습니다. rowView.run {} 이 기능(?)은 vb.net 에서 봤는데 코틀린이 단순화 하려고 많이 노력했네요.
-
미해결자바스크립트 비기너: 튼튼한 기본 만들기
이 강의로 string에 대한 이해가 넓어졌습니다.
와.. 이번 length 프로퍼티가 어떻게 생성되는지 내부적으로 어떤 구조를 통해서 length를 불러오는지 알게되서 너무 기쁘고 신기합니다. 평소에 아무 생각없이 사용하던 빌트인 함수였을 뿐인데 내부적으로 이런 루트를 통해서 호출하고 있던 거였군요.. 명강의 정말 감사합니다!! ( _ _ )bb
-
미해결스프링 시큐리티
User 클래스
안녕하세요 좀헷갈리는 부분이있습니다. WebSecurityConfigurerAdapter에서는 config 메소드에 순차적으로 인증을 확인하는데 이때 Role 부분이 UserDetails가 맞죠? 로그인을하고 그게맞다면 UserDetails가 반환되며 그 반환된 것은 Entity에 UserDetails를 상속한것이구요. 그럼 순서가 그렇게 반환되어서 authentication Manager까지 올라가고 cofing 메소드가 호출되어 그 Userdetails의 Role을 확인하면서 인가를 하는것인가요? 즉, config 메소드가 어느시점에 호출되는지와 그 호출되었으면 Userdetails를 상속한 클래스를 대상으로 인증을하는건지 궁금합니다. 강의잘보고있습니다 감사합니다.
-
해결됨스프링 부트 개념과 활용
spring-boot-autoconfigure에 대해서 자세히 알고 싶습니다.
본 강의에서 프로젝트 모듈 중에 'Xxx-Spring-Boot-Autoconfigure 모듈: 자동 설정, Xxx-Spring-Boot-Starter 모듈: 필요한 의존성 정의' 에 대해 가볍게 넘어가셨는데, 본 강의에서 실습한 프로젝트 중 spring.factories 파일을 설정한 Xxx-Spring-Boot-Starter 프로젝트는 저 둘 중에 어디에 해당하는 건가요?? ~Starter 모듈과 ~Autoconfigure 모듈의 상세한 차이점을 알고 싶습니다!
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 쇼핑몰 사이트 만들기[전체 리뉴얼]
첫 시작 하는데 npm install 시 오류가 납니다 ㅠㅠ
Boiler Plate 깔고 npm install 시 아래와 같은 오류가 납니다 ㅠㅠ 원인이 무엇일까요? PS E:\node_\boilerplate-mern-stack-master> npm install > bcrypt@3.0.8 install E:\node_\boilerplate-mern-stack-master\node_modules\bcrypt > node-pre-gyp install --fallback-to-build node-pre-gyp WARN Using needle for node-pre-gyp https download node-pre-gyp WARN Tried to download(404): https://github.com/kelektiv/node.bcrypt.js/releases/download/v3.0.8/bcrypt_lib-v3.0.8-node-v83-win32-x64-unknown.tar.gz node-pre-gyp WARN Pre-built binaries not found for bcrypt@3.0.8 and node@14.15.0 (node-v83 ABI, unknown) (falling back to source compile with node-gyp) gyp ERR! find Python gyp ERR! find Python Python is not set from command line or npm configuration gyp ERR! find Python Python is not set from environment variable PYTHON gyp ERR! find Python checking if "python" can be used gyp ERR! find Python - "python" is not in PATH or produced an error gyp ERR! find Python checking if "python2" can be used gyp ERR! find Python - "python2" is not in PATH or produced an error gyp ERR! find Python checking if "python3" can be used gyp ERR! find Python - "python3" is not in PATH or produced an error gyp ERR! find Python checking if the py launcher can be used to find Python 2 gyp ERR! find Python - "py.exe" is not in PATH or produced an error gyp ERR! find Python checking if Python is C:\Python27\python.exe gyp ERR! find Python - "C:\Python27\python.exe" could not be run gyp ERR! find Python checking if Python is C:\Python37\python.exe gyp ERR! find Python - "C:\Python37\python.exe" could not be run gyp ERR! find Python gyp ERR! find Python ********************************************************** gyp ERR! find Python You need to install the latest version of Python. gyp ERR! find Python Node-gyp should be able to find and use Python. If not, gyp ERR! find Python you can try one of the following options: gyp ERR! find Python - Use the switch --python="C:\Path\To\python.exe" gyp ERR! find Python (accepted by both node-gyp and npm) gyp ERR! find Python - Set the environment variable PYTHON gyp ERR! find Python - Set the npm configuration variable python: gyp ERR! find Python npm config set python "C:\Path\To\python.exe" gyp ERR! find Python For more information consult the documentation at: gyp ERR! find Python https://github.com/nodejs/node-gyp#installation gyp ERR! find Python ********************************************************** gyp ERR! find Python gyp ERR! configure error gyp ERR! stack Error: Could not find any Python installation to use gyp ERR! stack at PythonFinder.fail (C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\lib\find-python.js:307:47) gyp ERR! stack at PythonFinder.runChecks (C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\lib\find-python.js:136:21) gyp ERR! stack at PythonFinder.<anonymous> (C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\lib\find-python.js:225:16) gyp ERR! stack at PythonFinder.execFileCallback (C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\lib\find-python.js:271:16) gyp ERR! stack at exithandler (child_process.js:315:5) gyp ERR! stack at ChildProcess.errorhandler (child_process.js:327:5) gyp ERR! stack at ChildProcess.emit (events.js:315:20) gyp ERR! stack at Process.ChildProcess._handle.onexit (internal/child_process.js:275:12) gyp ERR! stack at onErrorNT (internal/child_process.js:465:16) gyp ERR! stack at processTicksAndRejections (internal/process/task_queues.js:80:21) gyp ERR! System Windows_NT 10.0.18363 gyp ERR! command "C:\\Program Files\\nodejs\\node.exe" "C:\\Program Files\\nodejs\\node_modules\\npm\\node_modules\\node-gyp\\bin\\node-gyp.js" "configure" "--fallback-to-build" "--module=E:\\node_\\boilerplate-mern-stack-master\\node_modules\\bcrypt\\lib\\binding\\bcrypt_lib.node" "--module_name=bcrypt_lib" "--module_path=E:\\node_\\boilerplate-mern-stack-master\\node_modules\\bcrypt\\lib\\binding" "--napi_version=7" "--node_abi_napi=napi" "--napi_build_version=0" "--node_napi_label=node-v83" gyp ERR! cwd E:\node_\boilerplate-mern-stack-master\node_modules\bcrypt gyp ERR! node -v v14.15.0 gyp ERR! node-gyp -v v5.1.0 gyp ERR! not ok node-pre-gyp ERR! build error node-pre-gyp ERR! stack Error: Failed to execute 'C:\Program Files\nodejs\node.exe C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\bin\node-gyp.js configure --fallback-to-build --module=E:\node_\boilerplate-mern-stack-master\node_modules\bcrypt\lib\binding\bcrypt_lib.node --module_name=bcrypt_lib --module_path=E:\node_\boilerplate-mern-stack-master\node_modules\bcrypt\lib\binding --napi_version=7 --node_abi_napi=napi --napi_build_version=0 --node_napi_label=node-v83' (1) node-pre-gyp ERR! stack at ChildProcess.<anonymous> (E:\node_\boilerplate-mern-stack-master\node_modules\node-pre-gyp\lib\util\compile.js:83:29) node-pre-gyp ERR! stack at ChildProcess.emit (events.js:315:20) node-pre-gyp ERR! stack at maybeClose (internal/child_process.js:1048:16) node-pre-gyp ERR! stack at Process.ChildProcess._handle.onexit (internal/child_process.js:288:5) node-pre-gyp ERR! System Windows_NT 10.0.18363 node-pre-gyp ERR! command "C:\\Program Files\\nodejs\\node.exe" "E:\\node_\\boilerplate-mern-stack-master\\node_modules\\node-pre-gyp\\bin\\node-pre-gyp" "install" "--fallback-to-build" node-pre-gyp ERR! cwd E:\node_\boilerplate-mern-stack-master\node_modules\bcrypt node-pre-gyp ERR! node -v v14.15.0 node-pre-gyp ERR! node-pre-gyp -v v0.14.0 node-pre-gyp ERR! not ok Failed to execute 'C:\Program Files\nodejs\node.exe C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\bin\node-gyp.js configure --fallback-to-build --module=E:\node_\boilerplate-mern-stack-master\node_modules\bcrypt\lib\binding\bcrypt_lib.node --module_name=bcrypt_lib --module_path=E:\node_\boilerplate-mern-stack-master\node_modules\bcrypt\lib\binding --napi_version=7 --node_abi_napi=napi --napi_build_version=0 --node_napi_label=node-v83' (1) npm WARN react-redux@5.1.2 requires a peer of react@^0.14.0 || ^15.0.0-0 || ^16.0.0-0 but none is installed. You must install peer dependencies yourself. npm WARN react-redux@5.1.2 requires a peer of redux@^2.0.0 || ^3.0.0 || ^4.0.0-0 but none is installed. You must install peer dependencies yourself. npm WARN react-boiler-plate@1.0.0 No repository field. npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.12 (node_modules\fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.12: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"}) npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! bcrypt@3.0.8 install: `node-pre-gyp install --fallback-to-build` npm ERR! Exit status 1 npm ERR! npm ERR! Failed at the bcrypt@3.0.8 install script. npm ERR! This is probably not a problem with npm. There is likely additional logging output above. npm ERR! A complete log of this run can be found in: npm ERR! C:\Users\cdg\AppData\Roaming\npm-cache\_logs\2020-12-06T16_48_01_155Z-debug.log
-
미해결[리뉴얼] 파이썬입문과 크롤링기초 부트캠프 [파이썬, 웹, 데이터 이해 기본까지] (업데이트)
객체지향 문법 질문 드립니다.
11:04 객체 attribute값을 바꾸기 위해 quad1.height=10 quad1.width=10 등으로 객체 호출하셨지요. 그런데 string.split()처럼 객체 이름. method이름(인자)가 공식 아닌가요?? 그러면 quad1. quad_name() 이어야 할 것 같은데, 왜 메서드 (quad_name) 대신 인자(height, width)가 들어갔는지 궁금합니다.
-
해결됨프로그래밍 시작하기 : 파이썬 입문 (Inflearn Original)
Hint 부분관련해서 질문 드립니다.
def tot_length1(word: str, num: int) -> int: def tot_length2(word: str, num: int) -> None: 여기서 맨우측 int와 none의 차이는 무엇인가요?? 또한 word:str, num:int라고 선언한 것은 word에 들어가는 인자는 str값이라는 것을 확인해줌으로 써 혹시나 하는 형 변환을 방지시켜주는 역할을 하는 것인가요??
-
미해결쉽고 자연스럽게 배워보는 Javascript 입문 - 코드스쿼드 마스터즈 코스 레벨1
질문 있습니다!
안녕하세요 선생님, 꾸준하게 강의 듣고 있는데 이번 연습문제가 너무 어렵게 느껴져서 함수, input태그를 써서 조건문에서 풀었던 소수판별 프로그램 먼저 익히려고 하는데요, 77, 81같은 숫자를 입력했을 때 조건문이 먹히지가 않아서 질문 드립니다. 어떤 부분을 어떻게 수정해야 할지 모르겠는데 힌트 부탁드립니다..! <!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>소수판별 프로그램</title> </head> <body> <h1>소수판별 프로그램입니다.</h1> 입력할 숫자 : <input type="text" id="num"> <button onclick = "display()"> 확인</button> <script> function display(){ var strN = document.getElementById("num").value; var n = Number(strN); for(i = 2; i < n; i++){ if(n % i === 0){ console.log(n + "은 소수가 아닙니다."); break; } else{ console.log(n + "은 소수입니다."); } } } </script> </body> </html> 함수, 객체 부터 내용이 어려워졌는데 포기하지 않겠습니다ㅜ
-
미해결반응형 웹사이트 포트폴리오(Architecture Agency)
질문있습니다.
선생님 안녕하세요! 강의를 듣다가 award 부분에 스크롤이 도달했을 때 opacity : 0 이었다가 opacity : 1로 스르륵 나타나게 하고싶은데 js를 모르겠어요 ㅠㅠ 혹시 알려주실 수 있으실까요?
-
미해결타입스크립트 입문 - 기초부터 실전까지
마지막강의
코로나관련 게시물 프로젝트가 업데이트 예정과 강의소개에서 사라졌던데 강의계획에서 사라진것인가요?
-
해결됨[리뉴얼] 처음하는 MongoDB(몽고DB) 와 NoSQL(빅데이터) 데이터베이스 부트캠프 [입문부터 활용까지] (업데이트)
6:30 윈도우즈의 몽고DB 실행
sudo service mongod start 명령이 맥 운영체제에서 brew services start mongodb와 동일한 명령어라 생각해도 될까요? sudo service mongod start 으로 실행시키고 진행했는데 선생님의 강의대로 특별히 오류메시지가 뜨지는 않았어요.
-
미해결[백문이불여일타] 데이터 분석을 위한 기초 SQL
해커랭크에서 문제풀다가 이해가 안되서 여쭤봅니다.
안녕하세요 선생님. 아래 문제 풀어보았는데 틀린이유를 도무지 모르겠어서 여쭤봅니다 알려주시면 감사하겠습니다 ㅜ
-
미해결윤재성의 Kotlin 기반 안드로이드 앱 개발 Part1 - UI Programming
ScrollChangeListener관련
강의에는 scrollX, oldScrollX 이렇게 파라미터가 되어 있어서 보기 편한데 최신 버전에는 아래와 같이 되서 불편합니다. 자동 생성된 파라미터를 이전 버전처럼 생성되게 할 수 있나요? val listener1 = object : View.OnScrollChangeListener { override fun onScrollChange(p0: View?, p1: Int, p2: Int, p3: Int, p4: Int) { when(p0?.id) { R.id.scroll1 -> { } } }}
-
미해결애플 웹사이트 인터랙션 클론!
강사님 질문있습니다.
main.add.js파일을 복붙해서 넣었는데 오류가 발생되어서 제 아무리 찾아봐도 어디서 오타인지를 못찾아서 도움을 요청하려고 글을 남깁니다. 오류는 콘솔로그에 Uncaught TypeError: Cannot read property 'style' of null at playAnimation (main.js:257) at scrollLoop (main.js:355) at main.js:361 라고 뜹니다. 제 스스로 찾아야하는데 도움부탁드립니다. 우선 제 js코드를 올려드리겠습니다. (() => { let yOffset = 0; //window.pageYOffset 대신 쓸 변수 let prevScrollHeight = 0; // 현재 스크롤 위치(yOffset)보다 이전에 위치한 스크롤 섹션들의 스크롤 높이값의 합 let currentScene = 0; // 현재 활성화된(눈 앞에 보고있는) 씬(scroll-section) let enterNewScene = false; // 새로운 scene이 시작된 순간 true const sceneInfo = [{ // 0 type: 'sticky', heightNum: 5, // 브라우저 높이의 5배로 scrollHeight 세팅 scrollHeight: 0, objs: { container: document.querySelector('#scroll-section-0'), messageA: document.querySelector('#scroll-section-0 .main-message.a'), messageB: document.querySelector('#scroll-section-0 .main-message.b'), messageC: document.querySelector('#scroll-section-0 .main-message.c'), messageD: document.querySelector('#scroll-section-0 .main-message.d') }, values: { messageA_opacity_in: [0, 1, { start: 0.1, end: 0.2 }], messageB_opacity_in: [0, 1, { start: 0.3, end: 0.4 }], messageC_opacity_in: [0, 1, { start: 0.5, end: 0.6 }], messageD_opacity_in: [0, 1, { start: 0.7, end: 0.8 }], messageA_translateY_in: [20, 0, { start: 0.1, end: 0.2 }], messageB_translateY_in: [20, 0, { start: 0.3, end: 0.4 }], messageC_translateY_in: [20, 0, { start: 0.5, end: 0.6 }], messageD_translateY_in: [20, 0, { start: 0.7, end: 0.8 }], messageA_opacity_out: [1, 0, { start: 0.25, end: 0.3 }], messageB_opacity_out: [1, 0, { start: 0.45, end: 0.5 }], messageC_opacity_out: [1, 0, { start: 0.65, end: 0.7 }], messageD_opacity_out: [1, 0, { start: 0.85, end: 0.9 }], messageA_translateY_out: [0, -20, { start: 0.25, end: 0.3 }], messageB_translateY_out: [0, -20, { start: 0.45, end: 0.5 }], messageC_translateY_out: [0, -20, { start: 0.65, end: 0.7 }], messageD_translateY_out: [0, -20, { start: 0.85, end: 0.9 }] } }, { // 1 type: 'normal', // heightNum: 5, // type normal에서는 필요 없음 scrollHeight: 0, objs: { container: document.querySelector('#scroll-section-1') } }, { // 2 type: 'sticky', heightNum: 5, scrollHeight: 0, objs: { container: document.querySelector('#scroll-section-2'), messageA: document.querySelector('#scroll-section-2 .a'), messageB: document.querySelector('#scroll-section-2 .b'), messageC: document.querySelector('#scroll-section-2 .c'), pinB: document.querySelector('#scroll-section-2 .b .pin'), pinC: document.querySelector('#scroll-section-2 .c .pin') }, values: { messageA_translateY_in: [20, 0, { start: 0.15, end: 0.2 }], messageB_translateY_in: [30, 0, { start: 0.6, end: 0.65 }], messageC_translateY_in: [30, 0, { start: 0.87, end: 0.92 }], messageA_opacity_in: [0, 1, { start: 0.25, end: 0.3 }], messageB_opacity_in: [0, 1, { start: 0.6, end: 0.65 }], messageC_opacity_in: [0, 1, { start: 0.87, end: 0.92 }], messageA_translateY_out: [0, -20, { start: 0.4, end: 0.45 }], messageB_translateY_out: [0, -20, { start: 0.68, end: 0.73 }], messageC_translateY_out: [0, -20, { start: 0.95, end: 1 }], messageA_opacity_out: [1, 0, { start: 0.4, end: 0.45 }], messageB_opacity_out: [1, 0, { start: 0.68, end: 0.73 }], messageC_opacity_out: [1, 0, { start: 0.95, end: 1 }], pinB_scaleY: [0.5, 1, { start: 0.6, end: 0.65 }], pinC_scaleY: [0.5, 1, { start: 0.87, end: 0.92 }] } }, { // 3 type: 'sticky', heightNum: 5, scrollHeight: 0, objs: { container: document.querySelector('#scroll-section-3'), canvasCaption: document.querySelector('.canvas-caption') }, values: { } } ]; function setLayout() { // 각 스크롤 섹션의 높이 세팅 for (let i = 0; i < sceneInfo.length; i++) { if (sceneInfo[i].type === 'sticky') { sceneInfo[i].scrollHeight = sceneInfo[i].heightNum * window.innerHeight; } else if (sceneInfo[i].type === 'normal') { sceneInfo[i].scrollHeight = sceneInfo[i].objs.container } sceneInfo[i].objs.container.style.height = `${sceneInfo[i].scrollHeight}px`; } yOffset = window.pageYOffset; let totalScrollHeight = 0; for (let i = 0; i < sceneInfo.length; i++) { totalScrollHeight += sceneInfo[i].scrollHeight; if (totalScrollHeight >= yOffset) { currentScene = i; break; } } document.body.setAttribute('id', `show-scene-${currentScene}`); } function calcValues(values, currentYOffset) { let rv; //현재 씬(스크롤섹션)에서 스크롤된 범위를 비율로 구하기 const scrollHeight = sceneInfo[currentScene].scrollHeight; const scrollRatio = currentYOffset / scrollHeight; if (values.length === 3) { //start ~ end 사이에 애니메이션 실행 const partScrollStart = values[2].start * scrollHeight; const partScrollEnd = values[2].end * scrollHeight; const partScrollHeight = partScrollEnd - partScrollStart; if (currentYOffset >= partScrollStart && currentYOffset <= partScrollEnd) { rv = (currentYOffset - partScrollStart) / partScrollHeight * (values[1] - values[0]) + values[0]; } else if (currentYOffset < partScrollStart) { rv = values[0]; } else if (currentYOffset > partScrollEnd) { rv = values[1]; } } else { rv = scrollRatio * (values[1] - values[0]) + values[0]; } return rv; } function playAnimation() { const objs = sceneInfo[currentScene].objs; const values = sceneInfo[currentScene].values; const currentYOffset = yOffset - prevScrollHeight; const scrollHeight = sceneInfo[currentScene].scrollHeight; const scrollRatio = currentYOffset / scrollHeight; switch (currentScene) { case 0: // console.log('0 play') if (scrollRatio <= 0.22) { // in objs.messageA.style.opacity = calcValues(values.messageA_opacity_in, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageA.style.opacity = calcValues(values.messageA_opacity_out, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_out, currentYOffset)}%, 0)`; } if (scrollRatio <= 0.42) { // in objs.messageB.style.opacity = calcValues(values.messageB_opacity_in, currentYOffset); objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageB.style.opacity = calcValues(values.messageB_opacity_out, currentYOffset); objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_out, currentYOffset)}%, 0)`; } if (scrollRatio <= 0.62) { // in objs.messageC.style.opacity = calcValues(values.messageC_opacity_in, currentYOffset); objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageC.style.opacity = calcValues(values.messageC_opacity_out, currentYOffset); objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_out, currentYOffset)}%, 0)`; } if (scrollRatio <= 0.82) { // in objs.messageD.style.opacity = calcValues(values.messageD_opacity_in, currentYOffset); objs.messageD.style.transform = `translate3d(0, ${calcValues(values.messageD_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageD.style.opacity = calcValues(values.messageD_opacity_out, currentYOffset); objs.messageD.style.transform = `translate3d(0, ${calcValues(values.messageD_translateY_out, currentYOffset)}%, 0)`; } break; case 2: // console.log('2 play'); if (scrollRatio <= 0.32) { // in objs.messageA.style.opacity = calcValues(values.messageA_opacity_in, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageA.style.opacity = calcValues(values.messageA_opacity_out, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_out, currentYOffset)}%, 0)`; } if (scrollRatio <= 0.67) { // in objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_in, currentYOffset)}%, 0)`; objs.messageB.style.opacity = calcValues(values.messageB_opacity_in, currentYOffset); objs.pinB.style.transform = `scaleY(${calcValues(values.pinB_scaleY, currentYOffset)})`; } else { // out objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_out, currentYOffset)}%, 0)`; objs.messageB.style.opacity = calcValues(values.messageB_opacity_out, currentYOffset); objs.pinB.style.transform = `scaleY(${calcValues(values.pinB_scaleY, currentYOffset)})`; } if (scrollRatio <= 0.93) { // in objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_in, currentYOffset)}%, 0)`; objs.messageC.style.opacity = calcValues(values.messageC_opacity_in, currentYOffset); objs.pinC.style.transform = `scaleY(${calcValues(values.pinC_scaleY, currentYOffset)})`; } else { // out objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_out, currentYOffset)}%, 0)`; objs.messageC.style.opacity = calcValues(values.messageC_opacity_out, currentYOffset); objs.pinC.style.transform = `scaleY(${calcValues(values.pinC_scaleY, currentYOffset)})`; } break; case 3: // console.log('3 play'); break; } } function scrollLoop() { enterNewScene = false; prevScrollHeight = 0; for (let i = 0; i < currentScene; i++) { prevScrollHeight += sceneInfo[i].scrollHeight; } if (yOffset > prevScrollHeight + sceneInfo[currentScene].scrollHeight) { enterNewScene = true; currentScene++; document.body.setAttribute('id', `show-scene-${currentScene}`); } if (yOffset < prevScrollHeight) { if (currentScene === 0) return // 브라우저 바운스 효과로 인해 마이너스가 되는 것을 방지(모바일) enterNewScene = true; currentScene--; document.body.setAttribute('id', `show-scene-${currentScene}`); } if (enterNewScene) return; playAnimation(); } window.addEventListener('scroll', () => { yOffset = window.pageYOffset; scrollLoop(); }); //window.addEventListener('DOMContentLoaded', setLayout); window.addEventListener('load', setLayout); window.addEventListener('resize', setLayout); })();
-
미해결프로그래밍 시작하기 : 파이썬 입문 (Inflearn Original)
file 옵션
안녕하세요. print(a,file=b)라고 하면 파일 옵션이 a를 b에 쓴다고 설명해주셨는데 이 부분이 어떤 의미인지 잘 이해가 가지 않아서요, python file 옵션으로 검색해봐도 file open에 대한 내용이 주로 나오는데 추가적인 설명 부탁드릴 수 있을까요?