디스크에서 프레임별로 게임 프레임을 최소로 압축하는 방법


19

Age of Empire (지도의 건물)와 같은 게임을 개발하고 모든 건물에 애니메이션에 대한 스프라이트 시트가 있습니다. 프레임별로 애니메이션을 사용하여 건물에 애니메이션을 적용하고 있습니다 (다른 방법은 알지 못함). 내가 넣은 이미지로 인해 내 리소스 폴더가 매우 커지고 있음을 알았습니다.

CoC 및 Age of Empires와 같은 게임의 APK 크기는 어떻게 50Mg 미만으로 유지합니까? 게임 개발과 관련하여 여기에 뭔가 빠졌습니까?

고맙습니다

편집 : 내가 직면 한 문제에 대한 추가 정보

애니메이션 드로어 블 객체가 많이 있습니다. 가장 빠르기 때문에이 방법을 선택했으며 원하는 결과를 얻었습니다. 기본적으로 모든 건물은 xml 파일이 8 개의 드로어 블 (8 개의 이미지 = 8 개의 파일)을 나타내는 애니메이션 드로어 블입니다. 투명성으로 인해 모두 PNG입니다. 200 개가 넘는 이미지가 있으므로 apk 크기는 120MB입니다 (파일의 절반을 아직 복사하지 않았습니다). 그것이 바로 프롬프트입니다. 그것을 해결하는 방법이 있어야합니다. 동료 개발자를 도와주세요


apk에서 이미지를 압축하거나 게임 콘텐츠를 분리하는 것이 원하는 것일 수 있습니다.
János Turánszki

확장 파일을 의미합니까? 확장 파일에 다른 밀도 드로어 블 폴더가 없다는 문제. 이것이 게임이하는 일입니까? 프레임 별 애니메이션 (전체 건물 이미지)을하고 있습니다. 아니면 내가 완전히 잘못된 길을 가고
Snake

경우에 대비하여 도움을 주려 이미지 공간을 절약하는 것과 관련하여 답변을 드리겠습니다. 그러나 귀하의 질문은 혼란 스럽습니다. "CoC 및 Age of Empires와 같은 게임의 APK 크기를 50Mg 미만으로 유지하는 방법"과 같은 기술을 실제로 알고 싶은지 확실하지 않습니다. 또는 디스크 공간이 부족한 애니메이션 방식이 적은지 확인하려면 (제목과 같이) 그럴 경우 답변을 삭제하고보다 정확한 답변을 얻을 수 있도록 명확히하십시오.
MAnd

@M 그리고 나는 문제를 더 반영하기 위해 대답을 편집했다
Snake

2
Age of Empires의 경우 아마도 저해상도 (640x480 용으로 설계된 IIRC)와 인덱스 된 이미지 (풀 RGB가 아님)의 조합 일 것입니다.
user253751

답변:


24

많은 양의 무거운 이미지 / 리소스 파일 (질문의 본문에 있음)이있을 때조차도 게임이 디스크 공간을 절약 할 수있는 기술을 알고 싶거나 건물에 대한 애니메이션을 수행하는 디스크 공간이 부족한 방법이 적습니다 (질문 제목에 함축되어 있음).

따라서 이미지가 많을 때 공간을 절약하는 데 도움이되도록이 답변을 여기에 넣겠습니다. 디스크 공간을 절약 할 수있는 애니메이션 기술에 대해서만 관심이있는 경우 알려 주시면 답변을 삭제할 수 있습니다.


비슷한 상황에서 디스크의 공간 절약 측면에서 내가 본 (그리고 한 번 사용한) 두 가지 솔루션은 다음과 같습니다.

1) 하나의 동일한 이미지 내에서 개별 이미지를 연결합니다. 때로는 도움이 될 수 있습니다. 따라서 다음 각 색상 사각형에 대해 4 개의 개별 파일을 저장하는 대신 모든 이미지를 동일한 이미지 내에 나란히 저장합니다 (게임 코드를 통해서만 분할).

여기에 이미지 설명을 입력하십시오

이 예에서 4 개의 서로 다른 PNG 파일에 각각 저장하면 1255 바이트가되고, 모든 파일이 연결된 단일 파일은 451 바이트입니다. 물론, 그것이 얼마나 도움이 될 수 있는지는 사례마다 다르며 이미지에 따라 도움이 될 수 있는지 테스트해야합니다.

2) 리소스 폴더를 압축합니다. 디스크 공간을 절약하는 데 도움이 될 수 있습니다. 그런 다음 게임이 실행될 때 사용하는 압축 형식에 따라 압축 파일에서 원하는 이미지를 압축 해제하거나 가져옵니다. 이 사이트의 위키가 된이 과거 답변을 참조하십시오 : /gamedev//a/37649/72423

그러나 또한 것을 명심 각각의 압축 형식이 다소 유리한 사용하는 이미지 파일의 종류에 따라 할 수있다 : 자원의 피를 두 번 압축을

압축에 대한 자세한 내용 : 이미지 압축 기술의 최첨단?


마지막으로, 각 상황에 어떤 유형의 이미지를 사용해야하는지 생각하고 싶을 수도 있습니다. 어떤 이미지 형식이 메모리 효율성이 더 좋습니까? PNG, JPEG 또는 GIF?


정보 주셔서 감사합니다. 하나의 파일에 물건을 넣어서 파일 크기를 절반으로 줄일 수 있었던 것은 이상합니다. 나는 하루가 끝날 때 같은 픽셀 수와 공간을 사용한다고 생각했습니다. 더 나은 답변을 위해 내 질문을 편집했습니다
Snake

@Snake 따라서 편집 한 내용에 따라 제 답변이 도움이 될 것입니다. 이미지를 연결하고 압축하면 폴더 크기가 크게 줄어들 수 있습니다. 두 가지 기술 모두 일부 유형의 게임에서 정기적으로 사용됩니다. 연결에 대해서는 항상 놀라운 속임수입니다. 직접 해보십시오. 한 애니메이션 시퀀스의 이미지를 나란히 놓고 최종 크기를 개별 이미지의 합계와 비교하십시오. 그런 다음 귀하의 경우에 도움이되는지 확인할 수 있습니다. 압축의 경우 PNG의 경우 효과가 떨어지지 만 최종 폴더의 크기를 줄이려는 노력은 여전히 ​​가치가 있습니다.
MAnd

@Snake 한 가지 관찰 : 그러나 연결하는 것이 때때로 가치가 없거나 최종 크기를 약간 증가시킵니다. 그러나 종종 바람직한 감소를 제공 할 수 있습니다. 그것은 모두 당신의 이미지에 달려 있습니다
MAnd

나는 두 가지 기술을 모두 시도한 것을 기억하며 감소율은 10 % 미만이었습니다. 압축은 PNG에서 중요하지 않다는 것을 알고 있지만 연결을 시도합니다. 그렇기 때문에 다른 게임이 내 게임보다 훨씬 더 많은 그래픽을 가지고 있기 때문에 다른 게임에서 어떻게해야하는지 물었습니다.
Snake

이미지가 가득 찬 폴더를 압축 할 수 없습니다. 이미지는 이미 압축되어 있고 반복 가능한 시퀀스가 ​​많지 않아야합니다. 만약 그렇다면, 그 추가적인 압축 레이어는 이미지 코덱의 일부가 될 것입니다.
corsiKa

9

TexturePacker 를 사용해 볼 것을 제안합니다.

  • 모든 이미지를 드래그 앤 드롭하여 포장 할 수 있습니다.
  • 다른 압축을 적용 할 수 있습니다. 예를 들어 메모리를 덜 소비하는 인덱스 된 PNG를 사용하십시오. 표준 PNG 파일에 비해 최대 70 % 더 적습니다.
  • 각 건물의 이름 + 위치를 포함하는 파일 데이터 파일을 만들 수 있습니다
  • 무료 버전은 이미 스프라이트 시트를 작성하기에 충분할 수 있습니다.

AndEngine, Cocos2d-x 또는 LibGdx와 같은 게임 개발 프레임 워크를 사용하십니까? => 없음

모든 이미지를 동시에로드해야합니까? 대상 장치에서 대규모 RAM 문제가 발생하는 것처럼 들립니다.


업데이트 : 뱀은 나에게 이미지를 보냈다. 약속 한대로 여기에 공개하지 않으므로 메모리 사용을 줄이는 방법을 보여주기 위해 직접 예술을 만들었습니다.

원본 이미지에서는 이미지의 한 부분 만 움직이고있었습니다. 나는 이것을 보여주기 위해 집에 새를 뒀다.

여기에 이미지 설명을 입력하십시오

기본적으로 완전한 애니메이션을 시트에 포장하는 것은 큰 메모리 낭비입니다. 정적 부품과 움직이는 부품을 분리해야합니다.

공전:

여기에 이미지 설명을 입력하십시오

애님 01 :

여기에 이미지 설명을 입력하십시오

Anim02 :

여기에 이미지 설명을 입력하십시오

이미지에서 새의 원래 위치를 유지하십시오 . 이것이 바로 위에 빈 공간이있는 이유입니다. 애니메이션을 정렬하려면 이것이 필요합니다.

이제 TexturePacker 에서 이미지를 드래그하고 다음 파라미터를 선택하십시오

  • 데이터 형식 : JSON 해시 (또는 원하는 경우 XML)
  • 트림 모드 : 트림 (사각형을 만듭니다)
  • 픽셀 형식 : INDEXED 8 비트-8 비트 PNG 생성 (약 70 % 적은 메모리)
  • 회전 허용 : false
  • 데이터의 파일 이름을 입력하십시오

이미지를 포장하는 TexturePacker

그 결과 이제 스프라이트 시트와 JSON 설명 파일이라는 두 개의 파일을 얻게됩니다.

"house_anim_01.png":
{
    "frame": {"x":351,"y":246,"w":110,"h":79},
    "rotated": false,
    "trimmed": true,
    "spriteSourceSize": {"x":67,"y":8,"w":110,"h":79},
    "sourceSize": {"w":400,"h":400},
    "pivot": {"x":0.5,"y":0.5}
},

중요한 부분은 framespriteSourceSize 입니다.

프레임은 당신에게 스프라이트 시트의 원래 스프라이트의 위치를 제공합니다.

spriteSourceSize 는 이미지를 그리는 데 필요한 오프셋 (자르기 때문에 남은 이미지 부분)을 제공합니다.

간단한 의사 코드 그리기 루틴은 다음과 같습니다.

drawImage(spritename, posX, posX)
{
    data    = sheetData[spritename]
    offsetX = data.spriteSourceSize.x
    offsetY = data.spriteSourceSize.y
    frameX  = data.frame.x
    frameY  = data.frame.y
    width   = data.frame.w
    height  = data.frame.h
    screen.draw(sheetImage, posX+offsetX, posY+offsetY, width, height)
}

그래픽 시스템의 피벗 포인트 / 원점에 따라 오프셋 계산을 조정해야 할 수도 있습니다. 위의 루틴은 원점이 왼쪽 상단 인 좌표계를 가정합니다.

그런 다음 간단히 2 패스로 집을 그립니다.

draw("background", 100, 100);
draw("anim_01", 100, 100);

이미지가 이미 정렬되었으므로 오프셋에 신경 쓸 필요가 없습니다.


다른 사람들이 무시하고있는 RAM 사용에 대한 관찰에 +1
Dan Hulme

@Andreas 나는 그것을 확인할 것입니다. 고맙습니다. 나를 비웃지 않지만 엔진을 사용하지 않습니다. 주로 애니메이션과 드로어 블로 이루어지며 매력처럼 작동합니다. 메모리에 모든 이미지를로드하지 않는 것이 현명하지 않습니다. 현재 표시에 필요한 이미지 만로드합니다. 위의 제안이 표준 Android SDK에서 작동한다고 생각하십니까?

1
그렇습니다. TexturePacker에는 스프라이트 트리밍을위한 두 가지 모드가 있습니다 : 사각형과 다각형. 등각 투영 이미지를 사용하는 경우 패킹 측면에서 다각형 메쉬에서 큰 이점을 얻을 수 있습니다. 문제는 텍스처 삼각형 또는 마스크가있는 사각형을 그릴 수 있는지 여부입니다. 그렇지 않은 경우에도 사각형을 계속 사용할 수 있습니다. dropbox를 사용하고 codeandweb에서-> 지원 링크를 보내려면 이미지를 보내 주시면됩니다. co.kr 나는 그것들을 공유하지 않을 것입니다-포장을 개선하기 위해 우리가 할 수있는 일에 관심이 있습니다.
Andreas Löw

@ AndreasLöw 죄송합니다. 귀하의 의견에 대한 알림을받지 못했습니다. 방금 봤어 도움을 주셔서 감사합니다. 나는 당신에게 무언가를 보낼 것이고 아마도 당신은 내가해야 할 것에 빛을 비출 수 있습니다. ..kinda는 내가 liittle experiece에있는 무언가에 갇히게되고 아마 당신은 빛을 비출 수있다. 곧 연락 드리겠습니다
Snake

7

사용할 수있는 몇 가지 포인터는 다음과 같습니다.

  1. 모든 배경 및 비 투명 이미지가 PNG 형식이 아닌지 확인하십시오
  2. 애니메이션이 1,2,3,4,5,6 인 경우 모든 애니메이션 루프 가능을 시도하십시오.이 숫자는 애니메이션의 프레임 번호 인 1,2,3,4,3,2,1처럼 만들어보십시오. 그것은 많은 도움이됩니다
  3. 많은 이미지가 동일하고 색상 만 다른 경우 (일반적으로 UI 버튼, m 입자 애니메이션, 게임 코인) 하나의 흰색 이미지를 가져 와서 색상을 동적으로 변경하십시오
  4. 매우 중요한 이미지로 .apk를 만든 다음 서버에서 모든 것을로드하고 전화 메모리에 보관하십시오.

이 포인터가 도움이되기를 바랍니다.

추신 : 나는이 포인터가 유용하지 않은 경우 정확한 게임 내용과 사과를 알지 못하기 때문에 일반적인 아이디어를 제공합니다.


1) 모든 이미지를 압축합니다. 2) 가능한 한 자주 타일을 사용합니다. 3) 이미지를 더 큰 이미지로 연결하고이를 텍스처링을위한 uv 맵으로 사용
Anthony Raimondo

좋은 제안입니다. 고맙습니다. 가장 중요한 점은 4라고 생각합니다. 그러나 그렇다면 다른 drawable 폴더에 폴더를 넣고 R.drawable.image1과 같이 참조하는 방법은 무엇입니까? 내가 혼란스러워하는 곳
Snake

4

많은 게임이 그래픽 자산을 .apk에 보관하지 않습니다. UI 그래픽 및 게임 코드와 같은 "기본"만 포함하고 게임이 설치되면 나머지 자산을 다운로드합니다. 이는 .apk가 저해상도 및 고해상도 자산을 모두 포함하지 않도록 디스플레이 해상도에 따라 다른 그래픽 리소스를 사용하는 게임의 경우 특히 그렇습니다.

다른 응답자가 제공하는 최적화 옵션과 .apk 자체와는 별도로 게임 그래픽을 제공해야하는지 여부를 모두 살펴 봐야합니다.


서버 (또는 확장 파일)에서 그래픽을 얻는 데 문제가 없지만 R.drawable.x로 참조 할 수 있도록 드로어 블 폴더에 넣는 방법은 무엇입니까? 내 (많은) XML의 대부분은 R을 사용하여 참조하기 때문에 .drawable

AFAIK, 당신은 할 수 없습니다. 한 가지 해결 방법은 리소스 ID에 연결된 리소스 파일 이름의 해시 테이블을 유지하고 AssetManager를 사용하여 해당 ID를 기반으로 파일을 가져 오는 것이지만이 경로로 이동하면 .xml 파일을 다시 작업해야 할 수도 있습니다.
Sandalfoot

4

나는 비슷한 질문을 찾기 위해이 사이트를 방문했으며 실제로 귀하의 질문에 대한 답변과 다른 질문에 대한 몇 가지 좋은 자료가 있습니다.

애니메이션 프레임이있는 애니메이션 3D 모델 또는 스프라이트 인 2D 애니메이션을 살펴보아야 합니까? 다른 유형의 애니메이션에 대한 토론. 게임 최적화에 도움이되었습니다. 또한 사용중인 API 또는 사용중인 엔진을 알려주지 않습니다. 그것만으로도 큰 차이를 만들 수 있습니다 : 안드로이드 프레임 별 PNG 애니메이션

그 외에도 압축 경로를 사용하면 압축 방법에 중요한 차이가있을 수 있습니다. 특히 압축 유형 간에는 약간의 차이가 있으며 모바일 장치에 가장 적합한 경로에 대한 몇 가지 특수한 논쟁이 있습니다. 특히 모바일을 고려할 경우 RAM 사용 및로드에 대한 CPU 낭비도 가장 중요합니다. 참조 : http://www.gamasutra.com/blogs/AlexandruVoica/20130419/190833/Why_efficiency_is_key_in_texture_compression_standards_for_mobile_graphics.php?print=1


Bennton에게 감사합니다. 사실 게임 개발에 익숙하지 않습니다. 도구 / 생산성에 기반한 많은 앱을 개발했습니다. 그러나 게임은 없습니다. 그래서 나는 첫 게임을하고 엔진을 사용하지 않습니다. AnimationDrawables 만 사용하고 있으며 잘 작동합니다. 그것은 APK의 크기에 불과합니다

Bennton, 당신이 제안한 마지막 링크는 특히 흥미 롭습니다. 공유해 주셔서 감사합니다! 내 대답에서 마지막 파일을 살펴보십시오. 이는 파일 유형에 따라 다른 압축 문제를 해결합니다. 실제로 PNG와 같은 이미 압축 된 이미지 유형 또는 더 압축되지 않은 이미지 유형에서 더 잘 작동하는 압축 유형이있는 것 같습니다. 각 사례에 대한 실험은 항상 각 상황에 가장 적합한 것이 무엇인지 확인하는 가장 좋은 방법입니다.
MAnd
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.