FreeKill/qml/Pages/RoomElement/CardItem.qml
notify c6d883eccf Standard skills (#48)
* huatuo

* biyue

* gender of player

* let tablepile smaller

* card emotions

* remove getOtherPlayers

* guicai

* skill audio

* card audio

* death audio

* bgm

* damage sound

* local bgm

* add more skill audio

* android: dont link to quickcontrol2

* android: fix ifndef

* yield only when need

* modify cpp according to clazy

* reduce malloc times

* revert yield

* qingguo

* fix back to lobby

* use compact json in cpp

* notifySkillInvoke animation

* util: string2json

* losehp; tablepile fix

* judge result animation

* add scrollbar for logedit

* add lock on waitForReply

* fix: virtual jink has no effect

* tiandu

* fix: duplicated cards when related to equiparea

* ui: disable okcancel when replying

* ui: disable invaild card when responding

* game: skill & card use history

* game: more judge on vsskill's canUse

* luoyi

* login page i18n

* i18n for server error message

* tuxi

* expand equip area when needed

* add footnote to cards from pile

* ui: only filter CanUseCard when playing

* expand equip when responding

* prompt

* prompt for askforchoice

* guanxing

* fix guanxing

* tieqi

* liuli

* doc for trigger skill

* xiaoji

* lianying

* fanjian

* rende

* add skill's subclass

* TODO: add tmd skill functions for other cards

* paoxiao

* qicai

* guose

* yiji (WIP)
2023-01-29 18:11:41 +08:00

256 lines
5.1 KiB
QML

import QtQuick
import Qt5Compat.GraphicalEffects
import "../skin-bank.js" as SkinBank
/* Layout of card:
* +--------+
* num -|5 |
* suit-|s |
* | img |
* | |
* |footnote|
* +--------+
*/
Item {
id: root
width: 93
height: 130
// properties for the view
property string suit: "club"
property int number: 7
property string name: "slash"
property string subtype: ""
property string color: "" // only use when suit is empty
property string footnote: "" // footnote, e.g. "A use card to B"
property bool footnoteVisible: false
property bool known: true // if false it only show a card back
property bool enabled: true // if false the card will be grey
property alias card: cardItem
property alias glow: glowItem
function getColor() {
if (suit != "")
return (suit == "heart" || suit == "diamond") ? "red" : "black";
else return color;
}
// properties for animation and game system
property int cid: 0
property bool selectable: true
property bool selected: false
property bool draggable: false
property bool autoBack: true
property int origX: 0
property int origY: 0
property real origOpacity: 1
property bool isClicked: false
property bool moveAborted: false
property alias goBackAnim: goBackAnimation
property int goBackDuration: 500
property bool busy: false // whether there is a running emotion on the card
signal toggleDiscards()
signal clicked()
signal doubleClicked()
signal thrown()
signal released()
signal entered()
signal exited()
signal moveFinished()
signal generalChanged() // For choose general freely
signal hoverChanged(bool enter)
RectangularGlow {
id: glowItem
anchors.fill: parent
glowRadius: 8
spread: 0
color: "#88FFFFFF"
cornerRadius: 8
visible: false
}
Image {
id: cardItem
source: known ? (name != "" ? SkinBank.CARD_DIR + name : "")
: (SkinBank.CARD_DIR + "card-back")
anchors.fill: parent
fillMode: Image.PreserveAspectCrop
}
Image {
id: suitItem
visible: known
source: suit != "" ? SkinBank.CARD_SUIT_DIR + suit : ""
x: 3
y: 19
width: 21
height: 17
}
Image {
id: numberItem
visible: known
source: (suit != "" && number > 0) ? SkinBank.CARD_DIR
+ "number/" + root.getColor() + "/" + number : ""
x: 0
y: 0
width: 27
height: 28
}
Image {
id: colorItem
visible: known && suit == ""
source: (visible && color != "") ? SkinBank.CARD_SUIT_DIR + "/" + color : ""
x: 1
}
GlowText {
id: footnoteItem
text: footnote
x: 6
y: parent.height - height - 6
width: root.width - x * 2
color: "#E4D5A0"
visible: footnoteVisible
wrapMode: Text.WrapAnywhere
horizontalAlignment: Text.AlignHCenter
font.family: fontLibian.name
font.pixelSize: 14
glow.color: "black"
glow.spread: 1
glow.radius: 1
//glow.samples: 12
}
Rectangle {
visible: !root.selectable
anchors.fill: parent
color: Qt.rgba(0, 0, 0, 0.5)
opacity: 0.7
}
MouseArea {
anchors.fill: parent
drag.target: draggable ? parent : undefined
drag.axis: Drag.XAndYAxis
hoverEnabled: true
onReleased: function(mouse) {
root.isClicked = mouse.isClick;
parent.released();
if (autoBack)
goBackAnimation.start();
}
onEntered: {
parent.entered();
if (draggable) {
glow.visible = true;
root.z++;
}
}
onExited: {
parent.exited();
if (draggable) {
glow.visible = false;
root.z--;
}
}
onClicked: {
selected = selectable ? !selected : false;
parent.clicked();
}
}
ParallelAnimation {
id: goBackAnimation
PropertyAnimation {
target: root
property: "x"
to: origX
easing.type: Easing.OutQuad
duration: goBackDuration
}
PropertyAnimation {
target: root
property: "y"
to: origY
easing.type: Easing.OutQuad
duration: goBackDuration
}
SequentialAnimation {
PropertyAnimation {
target: root
property: "opacity"
to: 1
easing.type: Easing.OutQuad
duration: goBackDuration * 0.8
}
PropertyAnimation {
target: root
property: "opacity"
to: origOpacity
easing.type: Easing.OutQuad
duration: goBackDuration * 0.2
}
}
onStopped: {
if (!moveAborted)
root.moveFinished();
}
}
function setData(data)
{
cid = data.cid;
name = data.name;
suit = data.suit;
number = data.number;
color = data.color;
}
function toData()
{
let data = {
cid: cid,
name: name,
suit: suit,
number: number,
color: color
};
return data;
}
function goBack(animated)
{
if (animated) {
moveAborted = true;
goBackAnimation.stop();
moveAborted = false;
goBackAnimation.start();
} else {
x = origX;
y = origY;
opacity = origOpacity;
}
}
function destroyOnStop()
{
root.moveFinished.connect(function(){
root.destroy();
});
}
}