카트라이더 개선 방안

이미지
카트라이더: 드리프트 서비스 종료 2025년 6월 16일, 디렉터 님께서 카트라이더: 드리프트 서비스 종료를 공지하셨습니다. 유저들의 많은 불만을 잠재우지 못하고 결국 좋지 않은 결과를 초래하였습니다. 카트라이더: 드리프트의 실패 요인은 여러 가지가 있지만, 제 생각에는 승부에 걸맞지 않는 게임의 가벼운 분위기 가 가장 크다고 생각합니다. 카트라이더는 캐주얼한 분위기와 함께 남녀노소 모두가 가볍게 즐길 수 있는 쉬운 게임이지만, 결국 메인이 되는 컨텐츠는  실력을 통한 경쟁 입니다. 다양한 카트바디와 함께 각자의 전략을 통해 상대를 이겨서 만족감을 얻는 게임입니다. 원작 카트에서는 카트바디가 다양했고, 성능도 각각 달라서 전술에 맞게 카트를 선택하고 상대방과의 심리전과 고도의 집중력을 필요로하는 피지컬이 요구되어서 승부를 보는 맛이 있었습니다. 이와 반대로 카트라이더: 드리프트의 카트바디 대부분의 성능이 비슷비슷하고 큰 차별점이 없었습니다. 최근엔 기어를 통한 업그레이드로 카트바디 마다 능력치는 다르게 할 수 있었지만 카트바디의 개성이 업그레이드 되진 않았다고 생각합니다. 특히 아이템전의 경우 원작 카트에서는 황금 미사일, 얼음 물폭탄 등 카트바디 마다 특수 기능이 존재했지만 카드맆에서는 그렇지 않기 때문에 게임 플레이의 다양성이 부족하고 다이나믹한 장면을 연출할 수 없었습니다.(캐릭터 스킬 패치가 있긴 했지만...) (또한 개인적으로 아쉬웠던건 부스터 디자인이 모두 변신 없이 단번에 출력되는 형식이었고 카트가 다 비슷비슷하게 생겼던 것 같습니다.) 게임 구성이 전반적으로 심플하고, 가벼웠습니다. 이것이 실패 요인이라고 생각합니다. 개인적인 생각으로, 디렉터님은 폴 가이즈 게임을 본받아 카트라이더: 드리프트의 방향성을 정한 것이 아닌가 싶습니다.(업 앤 다운 패치를 통해 더욱 확신을 가진 생각입니다) 게임 자체를 심플하게 만들어 누구나 접근성이 좋게 만들려고 하셨던 것 같습니다. 그래서 페이투윈 문화 지양, 게임 초반 당시 채팅 기능의 부재를 조금은 ...

Firebender를 이용하여 안드로이드 스튜디오에서 AI에게 도움 받기

이미지
최근 Cursor와 같이 AI에게 어시스턴트를 받으며 생산성을 높이는 개발이 트렌드가 되었습니다. 개발자가 코딩을 하는 행위가 많이 줄어들었고 덕분에 많은 유명 인사들이 개발자는 사라질 것이라고 예측하고 있습니다. AI가 있어서 편하긴 하지만 제가 쓸모 없어질 수 있다는 미래에 조금 씁쓸하네요. 플러터 개발을 처음 시작한 분들이 'vscode와 안드로이드 스튜디오중에 뭐가 더 나은가요?' 라는 질문을 하고는 합니다. 저의 경우 안드로이드 스튜디오나 인텔리제이같은 IDE를 선호하는 편입니다. 자동완성이 빠르니까요! 그런데 Cursor의 경우 vscode를 fork하기 때문에 저같은 안드로이드 스튜디오를 사용하는 개발자들은 조금 난처하게 되었습니다. 하지만 최근에 Firebender가 등장했습니다! 안드로이드 스튜디오에서도 AI에게 어시스턴트를 받을 수 있게 되었습니다. Firebender Firebender는 안드로이드 스튜디오와 인텔리제이에서 사용 가능합니다. 설치 플러그인에서 firebender를 검색 후 설치하면 됩니다. 이렇게 firebender가 생깁니다! 모델 저 모델들을 무료로 사용할 수 있습니다. 사용 firebender.json 루트 프로젝트에 firebender.json을 작성하셔서 rules, mcpServers 등 다양한 옵션을 넣을 수 있습니다.

프로젝트 사면초가

이미지
드디어 저의 사면초가 프로젝트가 완성되었습니다. 군복무 시절, 일이 없어 잔류로 남아있는 일과 시간에는 시간이 잘 가지 않고 심심하기도 해서 보드게임을 즐기곤 했습니다. 각종 보드 게임, 체스, 오목, 장기 등 여러 게임들을 했는데, 저는 그 중 장기가 가장 재미있었습니다. 체스나 오목은 어렸을 때에도 많이 해봤는데, 장기는 태어나서 처음 해봤습니다. 규칙을 아예 모르고 있었습니다. 처음 장기판과 기물들을 자세히 보았더니 예전에 넷마블 알까기 게임이 생각났습니다. 그 게임은 알고 보니 장기판과 장기 기물들을 빌린 거였네요. 전역 후 지금까지도 온라인 게임으로 장기를 두고 있습니다. 장기는 저의 취미로 깊게 자리 잡았습니다. 사면초가( 四面楚歌) '사방에서 초나라 노래가 흘러나온다는 뜻으로, 적에게 완전히 포위되어 희망이 없는 고립무원(孤立無援)의 상태를 이르는 말' 장기는 초한전쟁을 배경으로 만들어진 게임이라고 합니다. 초나라가 한나라와의 전투에서 패배하였고, 한나라가 초나라의 사기를 꺾기 위해서 항복한 초나라 병사들에게 노래를 부르게 했습니다. 초나라의 패왕인 항우가 사방에서 들려오는 초나라의 노래를 듣고  ‘초는 이미 유방에게 넘어간 것인가? 어떻게 포로의 수가 저렇게 많은가!’ 라며  탄식을 하였다고 합니다. 사면초가의 상황을 맞이한거죠. 저의 프로젝트는 한나라의 기물이 지속적으로 부활하면서 초나라의 왕을 노립니다. 유저는 초나라 진영에서 플레이 하고, 초나라는 끊임없이 쳐들어오는 한나라의 공격을 막으면서 최대한 오래 버티는 게임입니다. 그렇게 결국 초나라는 힘이 빠지면서 사방의 한나라 기물들에게 위협받을 것이고, 사면초가의 상황을 맞이한 초나라의 왕은 결국 죽게 됩니다. 메인 스크린 홈 게임 시작, 도움말, 환경 설정으로 이루어진 홈 스크린입니다. 대국에서 사용할 골드를 정하고 포진을 선택하여 게임을 시작할 수 있습니다. 도움말을 통해 게임에 대한 상세한 설명을 참고할 수 있습니다. 환경설정을 통해 효과음 볼륨 조절을 할 수 있습니다. ...

렌더링 된 이미지 크기 구하기

렌더링 된 이미지의 크기를 구하고 싶을 때가 있습니다. 화면의 크기에 따라 반응형으로 이미지의 크기가 변경되고, 이미지의 크기에 따라 다른 위젯의 크기를 변경해 주고 싶을 때가 있습니다. 이미지 크기를 가져오는 법 1. 이미지 위젯에 key를 넣어줘야 합니다. 키를 하나 만들어주세요. /// GlobalKey 를 생성하여 이미지 위젯의 상태를 추적 final GlobalKey imageBoardKey = GlobalKey (); 2. 이미지 위젯에 key를 넣어주세요. Image ( image : imageBoard , key : imageBoardKey , ), 3.  key의 currentContext -> findRenderObject를 통해 RenderBox 객체를 가져옵니다. /// 이미지의 넓이 또는 높이를 이용하여 기물의 위치를 정의 final renderBox = imageBoardKey . currentContext ?. findRenderObject () as RenderBox ; 4. renderBox의 size를 통해 Size 객체를 얻고 width와 height를 구할 수 있습니다. final size = renderBox. size ; 이미지를 미리 로드하기 이미지를 렌더링 하기 위해서 에셋, 네트워크 통신 등 이미지를 읽어와야 합니다. 이 과정은 비동기적으로 이루어지는데, 만약 이미지를 로드 하기 전에 이미지의 크기를 구하려 한다면 size의 width와 height의 크기가 0으로 반환 될 것입니다. 예컨대 StatefulWidget의 initState 함수에 위 단락의 3, 4번과 같이 코드를 작성한다면 이미지의 크기를 구할 수 없을 수도 있습니다. 또는 addPostFrameCallback을 통해 위젯 트리의 완성을 기다려 준다 하더라도 이미지의 로딩 시간이 길면 initState를 통해 크기를 구할 수 없습니다. 초반에 이미지의 크기를 바로 구하고 싶으시다면 이미지를 미리 로드 해야 합니다....

개발자로 전직하기

이미지
과거를 돌아보면 저는 개발자가 되기 위해 인생을 살아온 것은 아니었습니다. 그냥 살다 보니 저의 진로가 개발자로 정해졌습니다. 컴퓨터 게임을 좋아했다 보니까 컴퓨터와 관련된 직업을 갖고 싶다는 생각에... 고등학생이었을 때 C언어를 공부해봤고 그 이후 무지성으로 소프트웨어학과에 진학하게 되었습니다. 소프트웨어학과는 게임과는 크게 상관 없었습니다. 시꺼먼 화면에 이상한 영어 글자를 쓰고 읽는 학과입니다. 코딩은 생각보다 그렇게 재미 없지는 않았습니다. 저의 뇌가 '너 코딩에 재능이 있을수도 있어.' 라고 말해주는 느낌이었죠. 그렇게 C 언어부터 시작해서 자바, 파이썬, 리액트, 뷰, 도커와 쿠버네티스, MySQL, 그리고 지금 저의 주무기가 된 플러터까지.. 학교다니면서 다양한 기술들을 찍먹해봤네요. (물론 지금은 플러터 빼고 다 까먹었습니다!) 예전에는 개발자가 되기 위한 명확한 가이드가 많지 않았던 것 같습니다. 진로를 설정하면서 개발자에 대한 속 시원한 정보를 얻은 적이 없던 것 같습니다. 물론 요즘은 개발자 블로거, 유튜버가 많이 생겨나서 어디서든 손쉽게 정보를 얻을 수 있습니다. 옛날 생각을 하며 개발자에 대한 글을 적어보았습니다. 프로그래밍 첫 입문 전 처음에 윤성우의 열혈 C 프로그래밍이라는... 엄청나게 유명한 C 언어 책을 구매해서 공부했습니다. 변수 선언하기, 조건문, 반복문 등 문법을 배우고 printf 함수를 통해 콘솔에 찍어보는 연습을 하였습니다. 그 이후에는 윤성우의 열혈 자료구조라는... 데이터의 자료구조에 대해 공부하게 되었죠. 자료구조를 만들고... 역시나 콘솔에 찍어보고... 결과를 확인했습니다. 저는 너무 답답했습니다. '대체 이걸로 뭘 할 수 있다는걸까?' 라는 질문만 머릿속에서 맴돌았습니다. 콘솔 찍기를 잘 한다고 해서 웹사이트와 앱을 만들거나, 밥을 지어 먹을 수 있는 전기밥솥을 만들거나, ChatGPT같은 인공지능을 만들 수는 없습니다. 이렇게 배우는게 맞나? 삐뚤어진 다이아몬드 콘솔 찍기 콘...

팩토리 패턴을 응용한 플러터의 클린 아키텍처

이미지
클린 아키텍처 전 아직도 이 그림이 뭔지 하나도 모르겠습니다. 그럼에도 불구하고 여러 블로그를 탐방하며 클린 아키텍처를 최대한 이해하려고 했고, 저만의 클린 코드를 작성해 보았습니다. 클린 아키텍처를 공부하면서 맘에 안들었던 점 폴더 구조가 크게 두가지가 있습니다. Feature-first와 Layer-first 입니다. 최상위에 위치하는 폴더가 앱의 기능 단위인 것과 클린 아키텍처의 Data, Domain, Presentation 계층인 것입니다. 그런데 전... 둘 다 썩 맘에 들지 않았습니다. Feature-first는 기능 단위로 코드 구조가 눈에 확 들어와서 좋긴 한데, 둘 이상의 Feature가 공유하는 코드가 있다면 그게 전부 common 폴더로 모이게 됩니다. 그러면 common 폴더가 비대해지면서 폴더 구조의 체계가 모호해지는 부분이 있습니다. Layer-first는 기능을 수정해야 할 때 폴더를 이리 저리 돌아다녀야 하고... 좀 난잡한 느낌이 듭니다. 그리고 클린 아키텍처를 공부하면서 새롭게 배운 단어들이 생소했습니다. Entity, DTO, Domain, Presentation... 이 단어들을 쓰고 싶지 않았습니다. 뭐 얼마든지 바꾸면 되겠지만, 네이밍 관련해서도 깊게 고민했습니다. 실제로 저와 같이 사이드 프로젝트 진행하는 동료들이 제 프로젝트를 보고 원하는 코드를 찾는 데 좀 어려웠다고 전했습니다. 클린 아키텍처를 잘 모르는 개발자라면 entity가 뭐고, domain이 뭔지 잘 모릅니다. 또한 DTO 클래스의 필요성을 전혀 느끼지 못했습니다. 왜냐하면 Dart에는 factory 생성자가 있기 때문입니다. 굳이 DTO 클래스를 만들지 않더라도 충분히 외부 환경에 유연하게 대응할 수 있겠다고 생각했습니다. 그렇게 고민을 하면서 저만의 클린 코드를 만들게 되었습니다. 먼저, 코드의 세부 구성부터 보여드리겠습니다. 외부 모델 DTO와 내부 모델 Entity -> Model로 통일 데이터 모델의 경우, DTO와 Entity로 나눕니다....