Flutter Final — Hollow Knight 遊戲介紹 APP

Choco_La
海大 SwiftUI iOS / Flutter App 程式設計
6 min readJun 15, 2024

<<Hollow Knight>>

是由澳大利亞獨立團隊櫻桃遊戲工作室 (Team Cherry)開發的一款 2D 類銀河惡魔城動作冒險遊戲。2017年2月24日首先於Windows平台發售,之後又推出MacOSLinux任天堂SwitchPlayStation 4Xbox One等版本。遊戲的部分開發資金來自於Kickstarter網站的群眾募資,直到2014年底募款結束為止累計金額超過5萬7千多澳元

遊戲故事講述一位小騎士所進行的冒險,他前往探查一座因瘟疫而荒廢多時的地下昆蟲王國聖巢(Hallownest)。小騎士在旅途中探索未知地區、遇到各式各樣的或敵或友的昆蟲、擊敗數十個Boss、學習技能與法術、收集物品和護符,在片段式的文字中解讀各處的歷史、揭開王國的秘密,並在過程中了解自身的使命,最後直面瘟疫的源頭。

這次運用了youtube API以及自己寫的小小爬蟲,成功獲得Boss資訊和查詢音樂。

github:

https://github.com/ChocoLa-1484/flutter_final_hollow_knight

影片Demo

程式片段

讀取boss的資訊,以顯示在畫面

boss.dart

class Boss {
final String name;
final String href;
final String imgSrc;
const Boss({required this.name, required this.href, required this.imgSrc});

factory Boss.fromJson(Map<String, dynamic> json) {
return Boss(
name: json['data-title'],
href: json['data-href'],
imgSrc: json['data-src'],
);
}
}

boss_list_page.dart

Future<void> _fetchBosses() async {
final String response =
await rootBundle.loadString('assets/boss_data.json');
final List<dynamic> data = json.decode(response);
setState(() {
bosses = data.map((json) => Boss.fromJson(json)).toList();
});
}

boss_data.json

[
{
"data-src": "https://static.wikia.nocookie.net/hollowknight/images/e/e6/Broken_Vessel_Icon.png/revision/latest/scale-to-width-down/100?cb=20170511203343",
"data-title": "Broken Vessel",
"data-href": "https://hollowknight.fandom.com/wiki/Broken_Vessel"
},
...
]

Youtube查詢音樂以及播放

video_list_page.dart

Future<void> _fetchVideos({String pageToken = ''}) async {
if (_isLoading) return;
setState(() {
_isLoading = true;
});

final response = await http.get(Uri.parse(
'$baseUrl/search?part=snippet&q=hollow knight music&type=video&key=$apiKey&maxResults=10&pageToken=$pageToken'));

if (response.statusCode == 200) {
final Map<String, dynamic> data = json.decode(response.body);
setState(() {
videos.addAll(data['items']);
_nextPageToken = data['nextPageToken'] ?? '';
_isLoading = false;
});
} else {
throw Exception('Failed to load videos');
}
}
 void _launchURL(Uri url) async {
if (await canLaunchUrl(url)) {
await launchUrl(url);
} else {
throw 'Could not launch $url';
}
}

滑到底轉圈圈

void _scrollListener() {
if (_scrollController.position.pixels ==
_scrollController.position.maxScrollExtent) {
_fetchVideos(pageToken: _nextPageToken);
}
}
ListView.builder(
controller: _scrollController,
itemCount: videos.length + (_isLoading ? 1 : 0),
itemBuilder: (context, index) {
if (index == videos.length) {
return const Center(child: CircularProgressIndicator());
}
...

結語

使用這些要在pubspec.yaml、AndroidManifest加權限,才能launchURL,害我卡了一陣子

--

--