mirror of
https://github.com/Qsgs-Fans/FreeKill.git
synced 2024-11-16 11:42:45 +08:00
parent
4ad61cf70f
commit
139464be14
|
@ -1,6 +1,6 @@
|
|||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
project(FreeKill VERSION 0.0.4)
|
||||
project(FreeKill VERSION 0.0.6)
|
||||
add_definitions(-DFK_VERSION=\"${CMAKE_PROJECT_VERSION}\")
|
||||
|
||||
if (NOT ${CMAKE_SYSTEM_NAME} MATCHES "Emscripten")
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.notify.FreeKill"
|
||||
android:installLocation="preferExternal"
|
||||
android:versionCode="4"
|
||||
android:versionName="0.0.4">
|
||||
android:versionCode="6"
|
||||
android:versionName="0.0.6">
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/sh
|
||||
|
||||
rm -rf res assets
|
||||
rm -rf res/mipmap assets
|
||||
|
||||
if [ ! -e res/mipmap ]; then
|
||||
mkdir -p res/mipmap
|
||||
|
|
BIN
image/lady.png
Normal file
BIN
image/lady.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 208 KiB |
BIN
image/lobby/profile.png
Normal file
BIN
image/lobby/profile.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 34 KiB |
BIN
image/widelogo.png
Normal file
BIN
image/widelogo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.0 KiB |
|
@ -36,8 +36,8 @@
|
|||
<translation>用户名</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Password</source>
|
||||
<translation>密码</translation>
|
||||
<source>Show Password</source>
|
||||
<translation>显示密码</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Join Server</source>
|
||||
|
@ -51,12 +51,56 @@
|
|||
<source>PackageManage</source>
|
||||
<translation>管理拓展包</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Welcome back!</source>
|
||||
<translation>欢迎回来!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Server Addr</source>
|
||||
<translation>服务器IP</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FAQ</source>
|
||||
<translation>常见疑问</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>$LoginFAQ</source>
|
||||
<translation>
|
||||
登录过程中的常见问题:
|
||||
|
||||
1. 怎么联机?
|
||||
将服务器IP输入到指定区域,然后填用户名和密码即可加入服务器。
|
||||
|
||||
2. 怎么注册?
|
||||
无需注册,只要填写好用户名和密码,服务器就会自动为您注册。你的用户名和密码保存在服务端,下次登入还是需要输入一样的用户名和密码。但是无需担心,FK会自动为你记住密码。
|
||||
</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>updated packages for md5</source>
|
||||
<translation>已为您与服务器同步拓展包,请尝试再次连入</translation>
|
||||
</message>
|
||||
</context>
|
||||
|
||||
<context>
|
||||
<name>Splash</name>
|
||||
<message>
|
||||
<source>Free</source>
|
||||
<translation>自由</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Open</source>
|
||||
<translation>开放</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Flexible</source>
|
||||
<translation>可拓展</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Press Any Key...</source>
|
||||
<translation>请按任意键...</translation>
|
||||
</message>
|
||||
</context>
|
||||
|
||||
<context>
|
||||
<name>Logic</name>
|
||||
<message>
|
||||
|
|
|
@ -14,11 +14,13 @@ Fk:loadTranslationTable{
|
|||
["Lobby BG"] = "大厅壁纸",
|
||||
["Room BG"] = "房间背景",
|
||||
["Game BGM"] = "游戏BGM",
|
||||
["Poster Girl"] = "看板娘",
|
||||
|
||||
["Create Room"] = "创建房间",
|
||||
["Room Name"] = "房间名字",
|
||||
["$RoomName"] = "%1的房间",
|
||||
["Player num"] = "玩家数目",
|
||||
["Select general num"] = "选将数目",
|
||||
["Game Mode"] = "游戏模式",
|
||||
["Enable free assign"] = "自由选将",
|
||||
["General Settings"] = "通常设置",
|
||||
|
@ -31,33 +33,67 @@ Fk:loadTranslationTable{
|
|||
["Scenarios Overview"] = "玩法一览",
|
||||
["Replay"] = "录像",
|
||||
["About"] = "关于",
|
||||
["about_freekill_description"] = "<b>关于FreeKill</b><br/>" ..
|
||||
"以便于DIY为首要目的的开源三国杀游戏。<br/>" ..
|
||||
"<br/>项目链接: https://github.com/Notify-ctrl/FreeKill",
|
||||
["about_qt_description"] = "<b>关于Qt</b><br/>" ..
|
||||
"Qt是一个C++图形界面应用程序开发框架,拥有强大的跨平台能力以及易于使用的API。<br/>" ..
|
||||
"<br/>本程序使用Qt 6.2+,主要利用QtQuick开发UI,同时也使用Qt的网络库开发服务端程序。<br/>" ..
|
||||
"<br/>官网: https://www.qt.io",
|
||||
["about_lua_description"] = "<b>关于Lua</b><br/>" ..
|
||||
"Lua是一种小巧、灵活、高效的脚本语言,广泛用于游戏开发中。<br/>" ..
|
||||
"<br/>本程序使用Lua 5.4,利用其完全实现了整个游戏逻辑。<br/>" ..
|
||||
"<br/>官网: https://www.lua.org",
|
||||
["about_ossl_description"] = "<b>关于OpenSSL</b><br/>" ..
|
||||
"OpenSSL是一个开源包,用来提供安全通信与各种加密支持。<br/>" ..
|
||||
"<br/>本程序目前用到了crypto库,以获得RSA加密算法支持。<br/>" ..
|
||||
"<br/>官网: https://www.openssl.org",
|
||||
["about_gplv3_description"] = "<b>关于GPLv3</b><br/>" ..
|
||||
"GNU通用公共许可协议(简称GPL)是一个广泛使用的自由软件许可证条款,它确保广大用户自由地使用、学习、共享或修改软件。<br/>" ..
|
||||
"<br/>由于Qt是按照GPLv3协议开源的库,与此同时本程序用到的readline库也属于GPLv3库,再加上QSanguosha也是以GPLv3协议开源的软件(从中借鉴了不少代码和思路),因此这个项目也使用GPLv3协议开源。<br/>" ..
|
||||
"<br/>官网: https://gplv3.fsf.org",
|
||||
["about_sqlite_description"] = "<b>关于SQLite</b><br/>" ..
|
||||
"SQLite是一个轻量级的数据库,具有占用资源低、运行效率快、嵌入性好等优点。<br/>" ..
|
||||
"<br/>FreeKill使用sqlite3在服务端保存用户的各种信息。<br/>" ..
|
||||
"<br/>官网: https://www.sqlite.org",
|
||||
["about_git2_description"] = "<b>关于Libgit2</b><br/>" ..
|
||||
"Libgit2是一个轻量级的、跨平台的、纯C实现的库,支持Git的大部分核心操作,并且支持几乎任何能与C语言交互的编程语言。<br/>" ..
|
||||
"<br/>FreeKill使用的是libgit2的C API,与此同时使用Git完成拓展包的下载、更新、管理等等功能。<br/>" ..
|
||||
"<br/>官网: https://libgit2.org",
|
||||
["about_freekill_description"] = [[
|
||||
# 关于FreeKill
|
||||
|
||||
以便于DIY为首要目的的开源三国杀游戏。
|
||||
|
||||
项目链接: https://github.com/Notify-ctrl/FreeKill
|
||||
]],
|
||||
["about_qt_description"] = [[
|
||||
# 关于Qt
|
||||
|
||||
Qt是一个C++图形界面应用程序开发框架,拥有强大的跨平台能力以及易于使用的API。
|
||||
|
||||
本程序使用Qt 6.2+,主要利用QtQuick开发UI,同时也使用Qt的网络库开发服务端程序。
|
||||
|
||||
官网: https://www.qt.io
|
||||
]],
|
||||
["about_lua_description"] = [[
|
||||
# 关于Lua
|
||||
|
||||
Lua是一种小巧、灵活、高效的脚本语言,广泛用于游戏开发中。
|
||||
|
||||
本程序使用Lua 5.4,利用其完全实现了整个游戏逻辑。
|
||||
|
||||
官网: https://www.lua.org
|
||||
]],
|
||||
["about_ossl_description"] = [[
|
||||
# 关于OpenSSL
|
||||
|
||||
OpenSSL是一个开源包,用来提供安全通信与各种加密支持。
|
||||
|
||||
本程序目前用到了crypto库,以获得RSA加密算法支持。
|
||||
|
||||
官网: https://www.openssl.org
|
||||
]],
|
||||
["about_gplv3_description"] = [[
|
||||
# 关于GPLv3
|
||||
|
||||
GNU通用公共许可协议(简称GPL)是一个广泛使用的自由软件许可证条款,它确保广大用户自由地使用、学习、共享或修改软件。
|
||||
|
||||
由于Qt是按照GPLv3协议开源的库,与此同时本程序用到的readline库也属于GPLv3库,再加上QSanguosha也是以GPLv3协议开源的软件(从中借鉴了不少代码和思路),因此这个项目也使用GPLv3协议开源。
|
||||
|
||||
官网: https://gplv3.fsf.org
|
||||
]],
|
||||
["about_sqlite_description"] = [[
|
||||
# 关于SQLite
|
||||
|
||||
SQLite是一个轻量级的数据库,具有占用资源低、运行效率快、嵌入性好等优点。
|
||||
|
||||
FreeKill使用sqlite3在服务端保存用户的各种信息。
|
||||
|
||||
官网: https://www.sqlite.org
|
||||
]],
|
||||
["about_git2_description"] = [[
|
||||
# 关于Libgit2
|
||||
|
||||
Libgit2是一个轻量级的、跨平台的、纯C实现的库,支持Git的大部分核心操作,并且支持几乎任何能与C语言交互的编程语言。
|
||||
|
||||
FreeKill使用的是libgit2的C API,与此同时使用Git完成拓展包的下载、更新、管理等等功能。
|
||||
|
||||
官网: https://libgit2.org
|
||||
]],
|
||||
|
||||
["Exit Lobby"] = "退出大厅",
|
||||
|
||||
|
@ -114,6 +150,7 @@ Fk:loadTranslationTable{
|
|||
|
||||
["$GameOver"] = "游戏结束",
|
||||
["$Winner"] = "%1 获胜",
|
||||
["$NoWinner"] = "平局!",
|
||||
["Back To Lobby"] = "返回大厅",
|
||||
}
|
||||
|
||||
|
|
|
@ -67,6 +67,7 @@ end
|
|||
|
||||
function GameLogic:chooseGenerals()
|
||||
local room = self.room
|
||||
local generalNum = room.settings.generalNum
|
||||
local function setPlayerGeneral(player, general)
|
||||
if Fk.generals[general] == nil then return end
|
||||
player.general = general
|
||||
|
@ -78,7 +79,7 @@ function GameLogic:chooseGenerals()
|
|||
local lord_general = nil
|
||||
if lord ~= nil then
|
||||
room.current = lord
|
||||
local generals = Fk:getGeneralsRandomly(3)
|
||||
local generals = Fk:getGeneralsRandomly(generalNum)
|
||||
for i = 1, #generals do
|
||||
generals[i] = generals[i].name
|
||||
end
|
||||
|
@ -88,14 +89,13 @@ function GameLogic:chooseGenerals()
|
|||
end
|
||||
|
||||
local nonlord = room:getOtherPlayers(lord, true)
|
||||
local generals = Fk:getGeneralsRandomly(#nonlord * 3, nil, {lord_general})
|
||||
local generals = Fk:getGeneralsRandomly(#nonlord * generalNum, nil, {lord_general})
|
||||
table.shuffle(generals)
|
||||
for _, p in ipairs(nonlord) do
|
||||
local arg = {
|
||||
(table.remove(generals, 1)).name,
|
||||
(table.remove(generals, 1)).name,
|
||||
(table.remove(generals, 1)).name,
|
||||
}
|
||||
local arg = {}
|
||||
for i = 1, generalNum do
|
||||
table.insert(arg, table.remove(generals, 1).name)
|
||||
end
|
||||
p.request_data = json.encode(arg)
|
||||
p.default_reply = arg[1]
|
||||
end
|
||||
|
|
|
@ -87,6 +87,11 @@ function Room:initialize(_room)
|
|||
|
||||
-- If ret == true, then when err_msg is true, that means no request
|
||||
end
|
||||
|
||||
if not self.game_finished then
|
||||
self:doBroadcastNotify("GameOver", "")
|
||||
self.room:gameOver()
|
||||
end
|
||||
end
|
||||
|
||||
self.players = {}
|
||||
|
@ -274,6 +279,9 @@ function Room:getNCards(num, from)
|
|||
while num > 0 do
|
||||
if #self.draw_pile < 1 then
|
||||
self:shuffleDrawPile()
|
||||
if #self.draw_pile < 1 then
|
||||
self:gameOver("")
|
||||
end
|
||||
end
|
||||
|
||||
local index = from == "top" and 1 or #self.draw_pile
|
||||
|
|
|
@ -6,7 +6,7 @@ local function getWinner(victim)
|
|||
|
||||
if victim.role == "lord" then
|
||||
if #alive == 1 and alive[1].role == "renegade" then
|
||||
winner = "renegede"
|
||||
winner = "renegade"
|
||||
else
|
||||
winner = "rebel"
|
||||
end
|
||||
|
|
|
@ -137,6 +137,171 @@ Fk:loadTranslationTable{
|
|||
[":biyue"] = "结束阶段开始时,你可以摸一张牌。",
|
||||
|
||||
["aaa_role_mode"] = "身份模式",
|
||||
[":aaa_role_mode"] = [========================================[
|
||||
# 身份模式简介
|
||||
|
||||
___
|
||||
|
||||
(原文地址: https://sgs.52pk.com/zl/201205/5299813.shtml )
|
||||
|
||||
你即将开始学习一款集角色扮演、战斗、伪装等要素于一体的多人卡牌游戏。它能让你通过扮演耳熟能详的三国角色,在颠覆性的历史舞台中,演义一段扑朔迷离并充满刺激的较量。你将会充分体验到与玩家博弈的乐趣,它将是你聚会休闲的最佳伙伴,它就是――三国杀。
|
||||
|
||||
___
|
||||
|
||||
## 游戏配件
|
||||
|
||||
游戏需要用到的牌为:身份牌,体力牌,武将牌,游戏牌。
|
||||
|
||||
身份牌8张:1主公,2忠臣,4反贼,1内奸;武将牌25张;游戏牌104张+EX游戏牌4张;体力牌8张。
|
||||
|
||||
___
|
||||
|
||||
## 游戏目标
|
||||
|
||||
玩家的游戏目标是由拿到的身份牌决定的,每种身份的胜利条件如下:
|
||||
|
||||
- 主公:消灭所有的反贼和内奸,平定天下。
|
||||
- 忠臣:不惜一切代价保护主公,胜利条件与主公相同。
|
||||
- 反贼:杀死主公,推翻统治。
|
||||
- 内奸:除掉除自己之外的所有人,成为最后的生还者。
|
||||
|
||||
___
|
||||
|
||||
## 决定身份
|
||||
|
||||
参考下表,抽取等于玩家人数的身份牌:
|
||||
|
||||
| 玩家人数 | 主公 | 忠臣 | 反贼 | 内奸 |
|
||||
| -------- | ---- | ---- | ---- | ---- |
|
||||
| 2 | 1 | 0 | 1 | 0 |
|
||||
| 3 | 1 | 0 | 1 | 1 |
|
||||
| 4 | 1 | 1 | 1 | 1 |
|
||||
| 5 | 1 | 1 | 2 | 1 |
|
||||
| 6 | 1 | 1 | 3 | 1 |
|
||||
| 7 | 1 | 2 | 3 | 1 |
|
||||
| 8 | 1 | 2 | 4 | 1 |
|
||||
|
||||
随机分给每个玩家一张身份牌,抽到主公身份的玩家需立即亮出身份(将主公牌正面朝上放在面前),其它身份的玩家保存好自己的身份牌,不让别的玩家知道自己的身份。
|
||||
|
||||
___
|
||||
|
||||
## 挑选武将
|
||||
|
||||
带有特殊能力的武将牌为游戏提供了丰富的变化和乐趣,但同时也让游戏变得相对复杂,如果是第一次玩三国杀,建议暂且不使用武将牌。请略过这部分,继续看“分发体力牌”。若对三国杀已经有了大致的了解,可以尝试加入武将进行游戏,按如下的步骤挑选武将。
|
||||
|
||||
首先分给获得主公身份的玩家(以下简称主公玩家)“曹操”、“刘备”、“孙权”,和另外随机抽取的2张武将牌,一共5张武将牌。由主公玩家挑选一个武将扮演,并将选好的武将牌展示给其他玩家。
|
||||
|
||||
将剩余的24张武将牌洗混,随机发给其余每位玩家各3张(10人游戏时每人发2张)。接着每人从3张牌里挑选一张扣在自己面前,待所有玩家都挑选好后同时亮出。将剩余未选的武将牌洗混,面朝下放在一旁。
|
||||
|
||||
___
|
||||
|
||||
## 分发体力牌
|
||||
|
||||
拿取对应人物体力上限的体力牌(看阴阳鱼的数量),用武将牌盖住左侧。
|
||||
|
||||
主公在其体力上限的基础上再增加一点(四人游戏时不再额外增加)。
|
||||
|
||||
例如三点体力的角色当主公时,他/她的体力上限就是四点,使用四点体力的体力牌。
|
||||
|
||||
将体力牌置于武将牌下方,露出当前体力值。扣减体力时,将武将牌右移挡住被扣减的体力。
|
||||
|
||||
___
|
||||
|
||||
## 回合流程
|
||||
|
||||
将游戏牌洗混,随机分给每个玩家4张,此为起始手牌(手牌:拿在手里的牌)。
|
||||
|
||||
将剩余游戏牌放在桌子中央,作为牌堆(玩家在游戏中弃置的牌放在一旁,组成弃牌堆,弃牌堆里的牌全部正面朝上放置)。
|
||||
|
||||
进行游戏时,由主公开始,按逆时针方向以回合的方式进行。
|
||||
|
||||
即:每名玩家有一个自己的回合,一名玩家回合结束后,其右边玩家的回合开始,依次轮流进行。
|
||||
|
||||
每个玩家的回合可以分为六个阶段:
|
||||
|
||||
1. 准备阶段
|
||||
|
||||
2. 判定阶段
|
||||
|
||||
3. 摸牌阶段
|
||||
|
||||
4. 出牌阶段
|
||||
|
||||
5. 弃牌阶段
|
||||
|
||||
6. 结束阶段
|
||||
|
||||
下面对这几个阶段进行描述:
|
||||
|
||||
### 准备阶段
|
||||
|
||||
通常可以跳过,有些武将可以使用此阶段的技能。
|
||||
|
||||
### 判定阶段
|
||||
|
||||
若你的面前横置着延时类锦囊,你必须依次对这些延时类锦囊进行判定。
|
||||
|
||||
*若你的面前横置有两种或更多的延时类锦囊,你从最后一个施加给你的锦囊开始判定(最早放置的最后判定)。*
|
||||
|
||||
### 摸牌阶段
|
||||
|
||||
你从牌堆顶摸两张牌。
|
||||
|
||||
*在游戏里,若没有特殊说明,“摸…张牌”指的就是从牌堆最上方摸牌。*
|
||||
|
||||
*当需要摸牌或将要对牌堆产生影响时,牌堆没牌,则立即将弃牌堆洗混后形成新的摸牌堆。*
|
||||
|
||||
### 出牌阶段
|
||||
|
||||
你可以使用0到任意张牌,加强自己或攻击他人,但必须遵守以下两条规则:
|
||||
|
||||
1. 每个出牌阶段仅限使用一次【杀】。
|
||||
|
||||
2. 任何一个玩家面前的判定区或装备区里不能放有两张同名的牌。
|
||||
|
||||
每使用一张牌,即执行该牌之效果,详见“游戏牌详解”。如无特殊说明,游戏牌在使用后均需弃置(放入弃牌堆)。
|
||||
|
||||
### 弃牌阶段
|
||||
|
||||
在出牌阶段中,不想出或没法出牌时,就进入弃牌阶段,此时检查你的手牌数是否超出你当前的体力值(你的手牌上限等于你当前的体力值),每超出一张,需要弃一张手牌。
|
||||
|
||||
### 结束阶段
|
||||
|
||||
通常可以跳过,有些武将可以使用此阶段的技能。
|
||||
|
||||
___
|
||||
|
||||
## 补充说明
|
||||
|
||||
1. 在游戏里,若无特殊说明,摸牌即是说从游戏牌堆顶摸牌。
|
||||
|
||||
2. 玩家在游戏中使用、打出或弃置的游戏牌放在一旁,组成弃牌堆,弃牌堆里的牌全部正面朝上放置。
|
||||
|
||||
3. 当牌堆没牌时,则立即将弃牌堆洗混后形成新的牌堆。
|
||||
|
||||
4. “体力上限”与“当前体力值”不一样,请注意区别。
|
||||
|
||||
___
|
||||
|
||||
## 武将死亡
|
||||
|
||||
当一个武将的体力降到0或更低时,即进入濒死状态,除非自己或他人在此时用【桃】来挽救该武将,否则该武将死亡。武将死亡后,弃置该武将所有牌及判定区里的牌,并亮出身份牌。
|
||||
|
||||
任何人杀死一名反贼(即凶手也是反贼),立即摸三张牌。
|
||||
|
||||
若主公杀死了忠臣,主公需要立即弃掉所有手牌和已装备的牌。
|
||||
|
||||
___
|
||||
|
||||
## 游戏结束
|
||||
|
||||
当以下任意一种情况发生时,游戏立即结束:
|
||||
|
||||
1、主公被杀。此时若内奸是唯一存活的角色(有且仅有一名内奸存活),则内奸获胜,除此之外的情况为反贼获胜(不论反贼角色死活)。
|
||||
|
||||
2、所有的反贼和内奸都已死亡:主公和忠臣(不论死活)都获胜。
|
||||
|
||||
]========================================],
|
||||
}
|
||||
|
||||
-- aux skills
|
||||
|
|
|
@ -16,6 +16,8 @@ QtObject {
|
|||
property var disabledPack: []
|
||||
property string preferedMode
|
||||
property int preferedPlayerNum
|
||||
property int preferredGeneralNum
|
||||
property string ladyImg
|
||||
|
||||
// Player property of client
|
||||
property string serverAddr
|
||||
|
@ -44,6 +46,8 @@ QtObject {
|
|||
disabledPack = conf.disabledPack || [ "test_p_0" ];
|
||||
preferedMode = conf.preferedMode || "aaa_role_mode";
|
||||
preferedPlayerNum = conf.preferedPlayerNum || 2;
|
||||
preferredGeneralNum = conf.preferredGeneralNum || 3;
|
||||
ladyImg = conf.ladyImg || AppPath + "/image/lady";
|
||||
}
|
||||
|
||||
function saveConf() {
|
||||
|
@ -60,6 +64,8 @@ QtObject {
|
|||
conf.disabledPack = disabledPack;
|
||||
conf.preferedMode = preferedMode;
|
||||
conf.preferedPlayerNum = preferedPlayerNum;
|
||||
conf.ladyImg = ladyImg;
|
||||
conf.preferredGeneralNum = preferredGeneralNum;
|
||||
|
||||
Backend.saveConf(JSON.stringify(conf, undefined, 2));
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ Item {
|
|||
Item {
|
||||
Rectangle {
|
||||
anchors.centerIn: parent
|
||||
color: "#88888888"
|
||||
color: "#88EEEEEE"
|
||||
radius: 2
|
||||
width: root.width * 0.8
|
||||
height: root.height * 0.8
|
||||
|
@ -50,7 +50,7 @@ Item {
|
|||
width: parent.width * 0.65
|
||||
text: Backend.translate("about_" + dest + "_description")
|
||||
wrapMode: Text.WordWrap
|
||||
textFormat: Text.RichText
|
||||
textFormat: Text.MarkdownText
|
||||
font.pixelSize: 18
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,92 +1,179 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
Frame {
|
||||
id: join_server
|
||||
Item {
|
||||
width: 960 * 0.8
|
||||
height: 540 * 0.8
|
||||
anchors.centerIn: parent
|
||||
scale: 1.5
|
||||
background: Rectangle {
|
||||
color: "#88888888"
|
||||
radius: 2
|
||||
|
||||
Item {
|
||||
id: left
|
||||
width: 300
|
||||
height: parent.height
|
||||
|
||||
Image {
|
||||
id: lady
|
||||
width: parent.width + 20
|
||||
height: parent.height
|
||||
fillMode: Image.PreserveAspectFit
|
||||
}
|
||||
|
||||
Image {
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 12
|
||||
width: parent.width
|
||||
source: AppPath + "/image/widelogo"
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
spacing: 8
|
||||
ComboBox {
|
||||
id: server_addr
|
||||
model: []
|
||||
editable: true
|
||||
Rectangle {
|
||||
id: right
|
||||
anchors.left: left.right
|
||||
width: parent.width - left.width
|
||||
height: parent.height
|
||||
color: "#88EEEEEE"
|
||||
radius: 16
|
||||
|
||||
onEditTextChanged: {
|
||||
if (model.indexOf(editText) === -1) {
|
||||
passwordEdit.text = "";
|
||||
} else {
|
||||
let data = config.savedPassword[editText];
|
||||
screenNameEdit.text = data.username;
|
||||
passwordEdit.text = data.shorten_password;
|
||||
ColumnLayout {
|
||||
width: parent.width * 0.8
|
||||
height: parent.height * 0.8
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 40
|
||||
//spacing
|
||||
|
||||
Text {
|
||||
text: qsTr("Welcome back!")
|
||||
font.pixelSize: 28
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
|
||||
GridLayout {
|
||||
columns: 2
|
||||
rowSpacing: 20
|
||||
|
||||
Text {
|
||||
text: qsTr("Server Addr")
|
||||
}
|
||||
ComboBox {
|
||||
id: server_addr
|
||||
Layout.fillWidth: true
|
||||
model: []
|
||||
editable: true
|
||||
|
||||
onEditTextChanged: {
|
||||
if (model.indexOf(editText) === -1) {
|
||||
passwordEdit.text = "";
|
||||
} else {
|
||||
let data = config.savedPassword[editText];
|
||||
screenNameEdit.text = data.username;
|
||||
passwordEdit.text = data.shorten_password;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
text: qsTr("Username")
|
||||
}
|
||||
TextField {
|
||||
id: screenNameEdit
|
||||
Layout.fillWidth: true
|
||||
placeholderText: qsTr("Username")
|
||||
text: ""
|
||||
onTextChanged: {
|
||||
passwordEdit.text = "";
|
||||
let data = config.savedPassword[server_addr.editText];
|
||||
if (data) {
|
||||
if (text === data.username) {
|
||||
passwordEdit.text = data.shorten_password;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: showPasswordCheck
|
||||
text: qsTr("Show Password")
|
||||
}
|
||||
TextField {
|
||||
id: passwordEdit
|
||||
Layout.fillWidth: true
|
||||
placeholderText: qsTr("Password")
|
||||
text: ""
|
||||
echoMode: showPasswordCheck.checked ? TextInput.Normal : TextInput.Password
|
||||
passwordCharacter: "*"
|
||||
}
|
||||
}
|
||||
}
|
||||
TextField {
|
||||
id: screenNameEdit
|
||||
placeholderText: qsTr("Username")
|
||||
text: ""
|
||||
onTextChanged: {
|
||||
passwordEdit.text = "";
|
||||
let data = config.savedPassword[server_addr.editText];
|
||||
if (data) {
|
||||
if (text === data.username) {
|
||||
passwordEdit.text = data.shorten_password;
|
||||
|
||||
Button {
|
||||
text: qsTr("Join Server")
|
||||
Layout.fillWidth: true
|
||||
enabled: passwordEdit.text !== ""
|
||||
onClicked: {
|
||||
config.serverAddr = server_addr.editText;
|
||||
config.screenName = screenNameEdit.text;
|
||||
config.password = passwordEdit.text;
|
||||
mainWindow.busy = true;
|
||||
Backend.joinServer(server_addr.editText);
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Button {
|
||||
Layout.preferredWidth: 180
|
||||
text: qsTr("Console start")
|
||||
enabled: passwordEdit.text !== ""
|
||||
onClicked: {
|
||||
config.serverAddr = "127.0.0.1";
|
||||
config.screenName = screenNameEdit.text;
|
||||
config.password = passwordEdit.text;
|
||||
mainWindow.busy = true;
|
||||
Backend.startServer(9527);
|
||||
Backend.joinServer("127.0.0.1");
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("PackageManage")
|
||||
onClicked: {
|
||||
mainStack.push(packageManage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*TextField {
|
||||
id: avatarEdit
|
||||
text: "liubei"
|
||||
}*/
|
||||
TextField {
|
||||
id: passwordEdit
|
||||
placeholderText: qsTr("Password")
|
||||
text: ""
|
||||
echoMode: TextInput.Password
|
||||
passwordCharacter: "*"
|
||||
}
|
||||
Button {
|
||||
text: qsTr("Join Server")
|
||||
enabled: passwordEdit.text !== ""
|
||||
onClicked: {
|
||||
config.serverAddr = server_addr.editText;
|
||||
config.screenName = screenNameEdit.text;
|
||||
config.password = passwordEdit.text;
|
||||
mainWindow.busy = true;
|
||||
Backend.joinServer(server_addr.editText);
|
||||
}
|
||||
}
|
||||
Button {
|
||||
text: qsTr("Console start")
|
||||
enabled: passwordEdit.text !== ""
|
||||
onClicked: {
|
||||
config.serverAddr = "127.0.0.1";
|
||||
config.screenName = screenNameEdit.text;
|
||||
config.password = passwordEdit.text;
|
||||
mainWindow.busy = true;
|
||||
Backend.startServer(9527);
|
||||
Backend.joinServer("127.0.0.1");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
text: qsTr("PackageManage")
|
||||
onClicked: {
|
||||
mainStack.push(packageManage);
|
||||
Text {
|
||||
anchors.left: parent.left
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.leftMargin: 12
|
||||
anchors.bottomMargin: 12
|
||||
text: "FreeKill " + FkVersion
|
||||
font.pixelSize: 16
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Text {
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.rightMargin: 8
|
||||
anchors.bottomMargin: 8
|
||||
text: qsTr("FAQ")
|
||||
color: "blue"
|
||||
font.pixelSize: 24
|
||||
font.underline: true
|
||||
|
||||
TapHandler {
|
||||
onTapped: {
|
||||
errDialog.txt = qsTr("$LoginFAQ");
|
||||
errDialog.open();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,12 +183,17 @@ Item {
|
|||
|
||||
Component.onCompleted: {
|
||||
config.loadConf();
|
||||
|
||||
lady.source = config.ladyImg;
|
||||
|
||||
server_addr.model = Object.keys(config.savedPassword);
|
||||
server_addr.onModelChanged();
|
||||
server_addr.currentIndex = server_addr.model.indexOf(config.lastLoginServer);
|
||||
|
||||
let data = config.savedPassword[config.lastLoginServer];
|
||||
screenNameEdit.text = data.username;
|
||||
passwordEdit.text = data.shorten_password;
|
||||
if (data) {
|
||||
screenNameEdit.text = data.username;
|
||||
passwordEdit.text = data.shorten_password;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import QtQuick
|
|||
import QtQuick.Controls
|
||||
import QtQuick.Window
|
||||
import QtQuick.Layouts
|
||||
import "LobbyElement"
|
||||
import "Logic.js" as Logic
|
||||
|
||||
Item {
|
||||
|
@ -73,8 +74,13 @@ Item {
|
|||
id: roomModel
|
||||
}
|
||||
|
||||
PersonalSettings {
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.centerIn: parent
|
||||
width: childrenRect.width
|
||||
height: parent.height
|
||||
Item {
|
||||
Layout.preferredWidth: root.width * 0.6
|
||||
Layout.fillHeight: true
|
||||
|
@ -82,7 +88,7 @@ Item {
|
|||
width: parent.width * 0.8
|
||||
height: parent.height * 0.8
|
||||
anchors.centerIn: parent
|
||||
color: "#88888888"
|
||||
color: "#88EEEEEE"
|
||||
radius: 16
|
||||
Text {
|
||||
width: parent.width
|
||||
|
@ -101,7 +107,7 @@ Item {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
GridLayout {
|
||||
flow: GridLayout.TopToBottom
|
||||
rows: 4
|
||||
|
@ -163,6 +169,57 @@ Item {
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
Button {
|
||||
text: Backend.translate("Create Room")
|
||||
onClicked: {
|
||||
lobby_dialog.source = "LobbyElement/CreateRoom.qml";
|
||||
lobby_drawer.open();
|
||||
config.observing = false;
|
||||
}
|
||||
}
|
||||
Button {
|
||||
text: Backend.translate("Generals Overview")
|
||||
onClicked: {
|
||||
mainStack.push(mainWindow.generalsOverviewPage);
|
||||
mainStack.currentItem.loadPackages();
|
||||
}
|
||||
}
|
||||
Button {
|
||||
text: Backend.translate("Cards Overview")
|
||||
onClicked: {
|
||||
mainStack.push(mainWindow.cardsOverviewPage);
|
||||
mainStack.currentItem.loadPackages();
|
||||
}
|
||||
}
|
||||
Button {
|
||||
text: Backend.translate("Scenarios Overview")
|
||||
onClicked: {
|
||||
mainStack.push(mainWindow.modesOverviewPage);
|
||||
}
|
||||
}
|
||||
Button {
|
||||
text: Backend.translate("Replay")
|
||||
}
|
||||
Button {
|
||||
text: Backend.translate("About")
|
||||
onClicked: {
|
||||
mainStack.push(mainWindow.aboutPage);
|
||||
}
|
||||
}
|
||||
Button {
|
||||
text: Backend.translate("Exit Lobby")
|
||||
onClicked: {
|
||||
toast.show("Goodbye.");
|
||||
Backend.quitLobby();
|
||||
mainStack.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Drawer {
|
||||
|
|
|
@ -9,7 +9,6 @@ Item {
|
|||
signal finished()
|
||||
|
||||
ColumnLayout {
|
||||
spacing: 20
|
||||
anchors.centerIn: parent
|
||||
|
||||
RowLayout {
|
||||
|
@ -142,6 +141,25 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
anchors.rightMargin: 8
|
||||
spacing: 16
|
||||
Text {
|
||||
text: Backend.translate("Poster Girl")
|
||||
}
|
||||
TextField {
|
||||
text: config.ladyImg
|
||||
}
|
||||
Button {
|
||||
text: "..."
|
||||
onClicked: {
|
||||
fdialog.nameFilters = ["Image Files (*.jpg *.png)"];
|
||||
fdialog.configKey = "ladyImg";
|
||||
fdialog.open();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
anchors.rightMargin: 8
|
||||
spacing: 16
|
||||
|
|
54
qml/Pages/LobbyElement/PersonalSettings.qml
Normal file
54
qml/Pages/LobbyElement/PersonalSettings.qml
Normal file
|
@ -0,0 +1,54 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import "../skin-bank.js" as SkinBank
|
||||
|
||||
Item {
|
||||
id: root
|
||||
width: bg.width
|
||||
height: bg.height
|
||||
|
||||
Image {
|
||||
id: bg
|
||||
x: -32
|
||||
height: 69
|
||||
source: SkinBank.LOBBY_IMG_DIR + "profile"
|
||||
fillMode: Image.PreserveAspectFit
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Item { Layout.preferredWidth: 16 }
|
||||
|
||||
Image {
|
||||
Layout.preferredWidth: 64
|
||||
Layout.preferredHeight: 64
|
||||
source: SkinBank.getGeneralPicture(Self.avatar)
|
||||
sourceSize.width: 250
|
||||
sourceSize.height: 292
|
||||
sourceClipRect: Qt.rect(61, 0, 128, 128)
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "transparent"
|
||||
border.width: 1
|
||||
}
|
||||
}
|
||||
|
||||
Item { Layout.preferredWidth: 8 }
|
||||
|
||||
Text {
|
||||
Layout.alignment: Qt.AlignTop
|
||||
text: Self.screenName
|
||||
font.pixelSize: 22
|
||||
font.family: fontLibian.name
|
||||
color: "#F0DFAF"
|
||||
style: Text.Outline
|
||||
}
|
||||
}
|
||||
|
||||
TapHandler {
|
||||
onTapped: {
|
||||
lobby_dialog.source = "LobbyElement/EditProfile.qml";
|
||||
lobby_drawer.open();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -28,6 +28,7 @@ ColumnLayout {
|
|||
id: playerNum
|
||||
from: 2
|
||||
to: 8
|
||||
value: config.preferedPlayerNum
|
||||
|
||||
onValueChanged: {
|
||||
config.preferedPlayerNum = value;
|
||||
|
@ -58,6 +59,24 @@ ColumnLayout {
|
|||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
anchors.rightMargin: 8
|
||||
spacing: 16
|
||||
Text {
|
||||
text: Backend.translate("Select general num")
|
||||
}
|
||||
SpinBox {
|
||||
id: generalNum
|
||||
from: 3
|
||||
to: 8
|
||||
value: config.preferredGeneralNum
|
||||
|
||||
onValueChanged: {
|
||||
config.preferredGeneralNum = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: freeAssignCheck
|
||||
checked: Debugging ? true : false
|
||||
|
@ -78,6 +97,7 @@ ColumnLayout {
|
|||
enableFreeAssign: freeAssignCheck.checked,
|
||||
gameMode: config.preferedMode,
|
||||
disabledPack: config.disabledPack,
|
||||
generalNum: config.preferredGeneralNum,
|
||||
}])
|
||||
);
|
||||
}
|
||||
|
|
73
qml/Pages/ModesOverview.qml
Normal file
73
qml/Pages/ModesOverview.qml
Normal file
|
@ -0,0 +1,73 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
|
||||
Item {
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
spacing: 10
|
||||
|
||||
ListView {
|
||||
id: listView
|
||||
width: parent.width * 0.2
|
||||
height: parent.height
|
||||
model: ListModel {
|
||||
id: modeList
|
||||
}
|
||||
highlight: Rectangle { color: "lightsteelblue"; radius: 5 }
|
||||
delegate: Item {
|
||||
width: parent.width
|
||||
height: 40
|
||||
|
||||
Text {
|
||||
text: name
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
TapHandler {
|
||||
onTapped: {
|
||||
listView.currentIndex = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
color: "#88EEEEEE"
|
||||
Flickable {
|
||||
width: parent.width - 16
|
||||
height: parent.height - 16
|
||||
anchors.centerIn: parent
|
||||
contentHeight: modeDesc.height
|
||||
ScrollBar.vertical: ScrollBar {}
|
||||
clip: true
|
||||
|
||||
Text {
|
||||
id: modeDesc
|
||||
width: parent.width - 16
|
||||
wrapMode: Text.WordWrap
|
||||
text: Backend.translate(":" + modeList.get(listView.currentIndex).orig_name)
|
||||
textFormat: Text.MarkdownText
|
||||
font.pixelSize: 16
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
text: qsTr("Quit")
|
||||
anchors.bottom: parent.bottom
|
||||
onClicked: {
|
||||
mainStack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
let mode_data = JSON.parse(Backend.callLuaFunction("GetGameModes", []));
|
||||
for (let d of mode_data) {
|
||||
modeList.append(d);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -73,7 +73,7 @@ Item {
|
|||
Layout.fillHeight: true
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "#88888888"
|
||||
color: "#88EEEEEE"
|
||||
}
|
||||
ListView {
|
||||
id: packageList
|
||||
|
|
|
@ -27,8 +27,8 @@ GraphicsBox {
|
|||
|
||||
Item {
|
||||
id: generalArea
|
||||
width: (generalList.count >= 5 ? Math.ceil(generalList.count / 2) : Math.max(3, generalList.count)) * 97
|
||||
height: generalList.count >= 5 ? 290 : 150
|
||||
width: (generalList.count > 8 ? Math.ceil(generalList.count / 2) : Math.max(3, generalList.count)) * 97
|
||||
height: generalList.count > 8 ? 290 : 150
|
||||
z: 1
|
||||
|
||||
Repeater {
|
||||
|
@ -38,8 +38,8 @@ GraphicsBox {
|
|||
Item {
|
||||
width: 93
|
||||
height: 130
|
||||
x: (index % Math.ceil(generalList.count / (generalList.count >= 5 ? 2 : 1))) * 98 + (generalList.count >= 5 && index > generalList.count / 2 && generalList.count % 2 == 1 ? 50 : 0)
|
||||
y: generalList.count < 5 ? 0 : (index < generalList.count / 2 ? 0 : 135)
|
||||
x: (index % Math.ceil(generalList.count / (generalList.count > 8 ? 2 : 1))) * 98 + (generalList.count > 8 && index > generalList.count / 2 && generalList.count % 2 == 1 ? 50 : 0)
|
||||
y: generalList.count <= 8 ? 0 : (index < generalList.count / 2 ? 0 : 135)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ GraphicsBox {
|
|||
spacing: 10
|
||||
|
||||
Text {
|
||||
text: Backend.translate("$Winner").arg(Backend.translate(winner))
|
||||
text: winner !== "" ? Backend.translate("$Winner").arg(Backend.translate(winner)) : Backend.translate("$NoWinner")
|
||||
color: "#E4D5A0"
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ var DELAYED_TRICK_DIR = AppPath + "/image/card/delayedTrick/";
|
|||
var EQUIP_ICON_DIR = AppPath + "/image/card/equipIcon/";
|
||||
var PIXANIM_DIR = AppPath + "/image/anim/"
|
||||
var TILE_ICON_DIR = AppPath + "/image/button/tileicon/"
|
||||
var LOBBY_IMG_DIR = AppPath + "/image/lobby/";
|
||||
|
||||
function getGeneralPicture(name) {
|
||||
let data = JSON.parse(Backend.callLuaFunction("GetGeneralData", [name]));
|
||||
|
|
195
qml/Splash.qml
Normal file
195
qml/Splash.qml
Normal file
|
@ -0,0 +1,195 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
Rectangle {
|
||||
id: splash
|
||||
color: "#EEEEEE"
|
||||
z: 100
|
||||
|
||||
property bool loading: true
|
||||
property alias animationRunning: animation.running
|
||||
|
||||
signal disappearing
|
||||
signal disappeared
|
||||
|
||||
Grid {
|
||||
id: main
|
||||
anchors.centerIn: parent
|
||||
rows: splash.width >= splash.height ? 1 : 2
|
||||
columns: splash.width >= splash.height ? 2 : 1
|
||||
horizontalItemAlignment: Grid.AlignHCenter
|
||||
verticalItemAlignment: Grid.AlignVCenter
|
||||
spacing: 25
|
||||
|
||||
Image {
|
||||
id: logo
|
||||
source: AppPath + "/image/icon.png"
|
||||
width: 96
|
||||
height: width
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
Column {
|
||||
spacing: 6
|
||||
|
||||
Text {
|
||||
id: fktext
|
||||
text: "FreeKill"
|
||||
// color: "#ffffff"
|
||||
font.pixelSize: 40
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
width: parent.width
|
||||
spacing: 8
|
||||
|
||||
Text {
|
||||
id: free
|
||||
text: qsTr("Free")
|
||||
// color: "#ffffff"
|
||||
font.pixelSize: 20
|
||||
opacity: 0
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||
}
|
||||
|
||||
Text {
|
||||
id: open
|
||||
text: qsTr("Open")
|
||||
// color: "#ffffff"
|
||||
font.pixelSize: 20
|
||||
opacity: 0
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||
}
|
||||
|
||||
Text {
|
||||
id: flexible
|
||||
text: qsTr("Flexible")
|
||||
// color: "#ffffff"
|
||||
font.pixelSize: 20
|
||||
opacity: 0
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: text
|
||||
text: qsTr("Press Any Key...")
|
||||
// color: "#ffffff"
|
||||
opacity: 0
|
||||
font.pointSize: 15
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
y: (main.y + main.height + parent.height - height) / 2
|
||||
SequentialAnimation on opacity {
|
||||
id: textAni
|
||||
running: false
|
||||
loops: Animation.Infinite
|
||||
NumberAnimation { from: 0; to: 1; duration: 1600; easing.type: Easing.InOutQuad; }
|
||||
NumberAnimation { from: 1; to: 0; duration: 1600; easing.type: Easing.InOutQuad; }
|
||||
}
|
||||
}
|
||||
|
||||
SequentialAnimation {
|
||||
id: animation
|
||||
running: true
|
||||
|
||||
PauseAnimation {
|
||||
duration: 400
|
||||
}
|
||||
|
||||
ParallelAnimation {
|
||||
NumberAnimation {
|
||||
target: fktext
|
||||
property: "opacity"
|
||||
duration: 500
|
||||
easing.type: Easing.InOutQuad
|
||||
to: 1
|
||||
}
|
||||
|
||||
NumberAnimation {
|
||||
target: logo
|
||||
property: "opacity"
|
||||
duration: 500
|
||||
easing.type: Easing.InOutQuad
|
||||
to: 1
|
||||
}
|
||||
}
|
||||
|
||||
NumberAnimation {
|
||||
target: free
|
||||
property: "opacity"
|
||||
duration: 400
|
||||
easing.type: Easing.InOutQuad
|
||||
to: 1
|
||||
}
|
||||
|
||||
NumberAnimation {
|
||||
target: open
|
||||
property: "opacity"
|
||||
duration: 400
|
||||
easing.type: Easing.InOutQuad
|
||||
to: 1
|
||||
}
|
||||
|
||||
NumberAnimation {
|
||||
target: flexible
|
||||
property: "opacity"
|
||||
duration: 400
|
||||
easing.type: Easing.InOutQuad
|
||||
to: 1
|
||||
}
|
||||
|
||||
|
||||
ScriptAction { script: textAni.start(); }
|
||||
|
||||
PropertyAction { target: splash; property: "loading"; value: false }
|
||||
}
|
||||
|
||||
/*
|
||||
Text {
|
||||
text: qsTr("Powered by Mogara")
|
||||
color: "#f39292"
|
||||
font.pixelSize: 20
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: parent.right
|
||||
}
|
||||
*/
|
||||
|
||||
//--------------------Disappear--------------
|
||||
Behavior on opacity {
|
||||
SequentialAnimation {
|
||||
NumberAnimation { duration: 1200; easing.type: Easing.InOutQuad }
|
||||
ScriptAction { script: disappeared() }
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
acceptedButtons: Qt.AllButtons
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
disappear();
|
||||
}
|
||||
}
|
||||
|
||||
Keys.onPressed: {
|
||||
disappear();
|
||||
event.accepted = true
|
||||
}
|
||||
|
||||
NumberAnimation {
|
||||
id: logoMover
|
||||
target: logo
|
||||
property: "x"
|
||||
to: -splash.width
|
||||
duration: 1000
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
|
||||
function disappear() {
|
||||
disappearing();
|
||||
logoMover.start();
|
||||
opacity = 0;
|
||||
}
|
||||
}
|
|
@ -19,11 +19,9 @@ Rectangle {
|
|||
radius: 16
|
||||
|
||||
opacity: 0
|
||||
color: "#F2808A87"
|
||||
|
||||
Text {
|
||||
id: message
|
||||
color: "white"
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
|
15
qml/main.qml
15
qml/main.qml
|
@ -49,11 +49,13 @@ Item {
|
|||
Component { id: lobby; Lobby {} }
|
||||
Component { id: generalsOverview; GeneralsOverview {} }
|
||||
Component { id: cardsOverview; CardsOverview {} }
|
||||
Component { id: modesOverview; ModesOverview {} }
|
||||
Component { id: room; Room {} }
|
||||
Component { id: aboutPage; About {} }
|
||||
|
||||
property var generalsOverviewPage
|
||||
property var cardsOverviewPage
|
||||
property alias modesOverviewPage: modesOverview
|
||||
property alias aboutPage: aboutPage
|
||||
property bool busy: false
|
||||
property string busyText: ""
|
||||
|
@ -71,7 +73,7 @@ Item {
|
|||
width: parent.width
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "#88888888"
|
||||
color: "#88EEEEEE"
|
||||
}
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
|
@ -198,9 +200,20 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: splashLoader
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (OS !== "Web") {
|
||||
mainStack.push(init);
|
||||
if (!Debugging) {
|
||||
splashLoader.source = "Splash.qml";
|
||||
splashLoader.item.disappeared.connect(() => {
|
||||
splashLoader.source = "";
|
||||
});
|
||||
}
|
||||
} else {
|
||||
mainStack.push(webinit);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include "client.h"
|
||||
#ifndef Q_OS_WASM
|
||||
#include "server.h"
|
||||
#include "packman.h"
|
||||
|
@ -219,6 +220,7 @@ int main(int argc, char *argv[])
|
|||
Pacman = new PackMan;
|
||||
# endif
|
||||
|
||||
engine->rootContext()->setContextProperty("FkVersion", FK_VERSION);
|
||||
engine->rootContext()->setContextProperty("Backend", &backend);
|
||||
engine->rootContext()->setContextProperty("Pacman", Pacman);
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user