[๐ฃ์ง๋ฌธ]
Flutter Flame ๊ฐ๋ฐ์ ์์ผ๋ฉด ์ง๋ฌธ ์ข ๋๋ฆด๊ฒ์ค
์ต๋ช
(121.157)
2022-09-07 23:12
์ถ์ฒ 0
๋ฌดํ๋๋ก ์ฐ์ธก์ผ๋ก ์ด๋ํ๋ฉด์ย ์งํ ์์ฑํ๋ ๊ธฐ๋ฅ์ ๋ง๋ค๊ณ ์๋๋ฐ
performance monitor๋ก ํ์ธํ๋ฉด Raster(GPU) Thread์์ ์ด๋ฐ๊ธ ๋ ? Jank๊ฐ ๋ฐ์ํจ.
๊ทธ๋์ ์ด๋์ด ๋ถ๋๋ฝ๋ค๊ฐ ํ๋ฒ์ฉ ๋๊น.
๊ธฐ๋ฅ์๋ ๋ณ๊ฑฐ ์๊ณ sprite๋ 1๊ฐ๋ง instance๋ก loadํ๊ณ ๊ทธ sprite๋ก SpriteComponent Pool์ ์์ฑํ๊ณ
์ด๋ ์ ๋งจ ์์ ๋ ๋๋ง๋ sprite๋ฅผ ๋งจ ๋ค๋ก ๋ณด๋ด์ฃผ๋ ์ค.
์ฐ์ธก ์ด๋์ camera๊ฐ followComponent() ์ค์ธ PositionComponent์ position.x์ ๊ฐ์ ๋ํ๋ ์ค.
๋ค๋ฅธ๊ฑฐ ๋ค ์ฃผ์ํ๊ณ ์ด ๊ธฐ๋ฅ๋ง ํด๋ max 22.7ms/frame์ด ๋ฐ์ ใ
.
๋๋ฐ์ด์ค ๋ฌธ์ ์ธ๊ฐ ํด์
LG Q9 One, Galaxy S10 Note ๋น๊ตํ๋๋ฐ S10์ด ๋ ๋ฐ์ํ๊ธด ํจ...
๋ณด๋ค ์ต์ ํํ๋ ๋ฐฉ๋ฒ์ด ์์๊น์?
๋ฐ์ ์ฝ๋
import
'package:flame/components.dart';
import
'package:flame/flame.dart';
import
'package:flame/game.dart';
import
'package:flutter/material.dart' hide Image
;
import
'package:flutter/services.dart';
void main() {
runApp(const App());
}
class App extends StatelessWidget
{
const App({Key
? key
}) : super(key
: key
);
@override
Widget
build(BuildContext context
) {
SystemChrome
.setPreferredOrientations([
DeviceOrientation
.landscapeLeft
,
DeviceOrientation
.landscapeRight
,
]);
return MaterialApp(
routes
: <String
, WidgetBuilder
>{
'/': (BuildContext context
) {
return Scaffold(
body
: Center(
child
: ElevatedButton(
onPressed
: () => Navigator
.pushNamed(context
, '/game'),
child
: const Text('Start'),
)),
);
},
'/game': (BuildContext context
) {
return const Scaffold(
body
: Center(child
: GameScreen()),
);
},
},
);
}
}
class GameScreen extends StatelessWidget
{
const GameScreen({Key
? key
}) : super(key
: key
);
@override
Widget
build(BuildContext context
) {
return GameWidget(game
: MyGame());
}
}
class MyGame extends FlameGame
{
final Grid grid
= Grid();
final EndlessMap endlessMap
= EndlessMap();
final Runner runner
= Runner();
double speed
= 100.0;
@override
Future
<void>? onLoad() {
add(grid
);
add(endlessMap
);
add(runner
);
return super
.onLoad();
}
}
/// Camera follows the runner.
class Runner extends PositionComponent with HasGameRef
<MyGame
> {
@override
Future
<void>? onLoad() {
gameRef
.camera
.followComponent(this);
return super
.onLoad();
}
@override
void update(double dt
) {
x
+= gameRef
.speed
* dt
;
super
.update(dt
);
}
}
/// Set the size of tile and grid
class Grid extends Component with HasGameRef
<MyGame
> {
late
int rows
= 10;
late
int columns
;
late
int mapColumns
;
late
double tileSize
;
@override
void onGameResize(Vector2 size
) {
tileSize
= (size
.y
/ rows
).floorToDouble();
columns
= (size
.x
/ tileSize
).ceil();
mapColumns
= columns
+ 2;
super
.onGameResize(size
);
}
}
/// Generate terrains endlessly
class EndlessMap extends PositionComponent with HasGameRef
<MyGame
> {
late final Sprite terrainSprite
;
late final List
<SpriteComponent
> terrainSpritePool
;
int firstTerrainIndex
= 0;
// Init terrain sprite
@override
Future
<void> onLoad() async
{
terrainSprite
= Sprite(
await Flame
.images
.load('terrains.png'),
srcPosition
: Vector2(4.0, 0.0),
srcSize
: Vector2(32.0, 32.0 * 10),
);
terrainSpritePool
= List
.generate(
gameRef
.grid
.mapColumns
,
(index
) => SpriteComponent(sprite
: terrainSprite
),
);
for (var i
= 0; i
< terrainSpritePool
.length
; i
++) {
terrainSpritePool
[i
].size
.x
= gameRef
.grid
.tileSize
;
terrainSpritePool
[i
].position
= Vector2(
i
* gameRef
.grid
.tileSize
,
gameRef
.grid
.tileSize
,
);
add(terrainSpritePool
[i
]);
}
return super
.onLoad();
}
@override
void update(double dt
) {
final dx
= gameRef
.speed
* dt
;
final lastTerrainIndex
= firstTerrainIndex
== 0
? terrainSpritePool
.length
- 1
: firstTerrainIndex
- 1;
// When the first terrain is behind the camera,
if (terrainSpritePool
[firstTerrainIndex
].position
.x
+
gameRef
.grid
.tileSize
<=
gameRef
.camera
.position
.x
+ dx
) {
// Move the first terrain to the end
terrainSpritePool
[firstTerrainIndex
].size
.x
= gameRef
.grid
.tileSize
;
terrainSpritePool
[firstTerrainIndex
].position
= Vector2(
terrainSpritePool
[lastTerrainIndex
].position
.x
+ gameRef
.grid
.tileSize
,
gameRef
.grid
.tileSize
,
);
firstTerrainIndex
= (firstTerrainIndex
+ 1) % terrainSpritePool
.length
;
}
super
.update(dx
);
}
}
์ง๋ฌธ์ ๋ํ ๋ต์ ์๋๋ฐ ์ง๊ธ์ด๋ผ๋ ๊ฐ์ํ๋ฉด ์๊ฐ์ ์ ์ฝํ ์์๋ค ๊ฒ์ด์ผ.. ๋๋ ํ๋ฌํฐ์ฑ์ ์ ์ผ๋ก ์ผ์ง๋ง ์ด๊ฑด ์๋๋ค
ใ ใ ใ ใ ์ญ์ ๊ฒ์ ์ ์ฉ ์์ง์ผ๋ก ๊ฐ์ํ์ผ ํ๋ ใ
ํ๋ฌํฐ๋ ์ ์ ์ธ ๊ฒ์๋ง ๋ง๋๋ ๊ฒ์ผ๋ก...