add
无故事王国
2024-05-29 0e9f7cd7a295ff06a5b767d11c5a03d6030c3563
add
5个文件已修改
4个文件已添加
509 ■■■■■ 已修改文件
DolphinEnglishLearnStudent.xcodeproj/project.pbxproj 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Assets.xcassets/Bg/bg_card.imageset/Contents.json 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Assets.xcassets/Bg/bg_card.imageset/bg_card.png 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Assets.xcassets/Bg/bg_card.imageset/bg_card@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_Game_CCell.swift 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_Game_CCell.xib 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_Game_Pocket_CCell.swift 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenGame_1_VC.swift 148 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenGame_2_VC.swift 169 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DolphinEnglishLearnStudent.xcodeproj/project.pbxproj
@@ -51,6 +51,7 @@
        130278992BFD9FBF00DDCE81 /* Home_1_TCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 130278932BFD9FBF00DDCE81 /* Home_1_TCell.swift */; };
        1302789A2BFD9FBF00DDCE81 /* AddressManageTCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 130278942BFD9FBF00DDCE81 /* AddressManageTCell.swift */; };
        1302789B2BFD9FBF00DDCE81 /* GoodsItemTCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 130278952BFD9FBF00DDCE81 /* GoodsItemTCell.swift */; };
        130A2C812C07075B008463B2 /* ListenFight_Game_Pocket_CCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 130A2C7F2C07075B008463B2 /* ListenFight_Game_Pocket_CCell.swift */; };
        1316A22E2C05CE5900BE6CAA /* GameBeginTipView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1316A22D2C05CE5900BE6CAA /* GameBeginTipView.swift */; };
        1316A2302C05CE6100BE6CAA /* GameBeginTipView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1316A22F2C05CE6100BE6CAA /* GameBeginTipView.xib */; };
        133386382C007E91002EE788 /* HomeListenFight_lesson_2_VC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 133386372C007E91002EE788 /* HomeListenFight_lesson_2_VC.swift */; };
@@ -145,6 +146,7 @@
        130278932BFD9FBF00DDCE81 /* Home_1_TCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Home_1_TCell.swift; sourceTree = "<group>"; };
        130278942BFD9FBF00DDCE81 /* AddressManageTCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddressManageTCell.swift; sourceTree = "<group>"; };
        130278952BFD9FBF00DDCE81 /* GoodsItemTCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GoodsItemTCell.swift; sourceTree = "<group>"; };
        130A2C7F2C07075B008463B2 /* ListenFight_Game_Pocket_CCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListenFight_Game_Pocket_CCell.swift; sourceTree = "<group>"; };
        1316A22D2C05CE5900BE6CAA /* GameBeginTipView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameBeginTipView.swift; sourceTree = "<group>"; };
        1316A22F2C05CE6100BE6CAA /* GameBeginTipView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = GameBeginTipView.xib; sourceTree = "<group>"; };
        133386372C007E91002EE788 /* HomeListenFight_lesson_2_VC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeListenFight_lesson_2_VC.swift; sourceTree = "<group>"; };
@@ -398,6 +400,7 @@
                13CDF44B2C056A6900E8D4FD /* ListenFight_lesson_4_CCell.xib */,
                13397D942C05EA9D003440F9 /* ListenFight_Game_CCell.swift */,
                13397D952C05EA9D003440F9 /* ListenFight_Game_CCell.xib */,
                130A2C7F2C07075B008463B2 /* ListenFight_Game_Pocket_CCell.swift */,
            );
            path = CCell;
            sourceTree = "<group>";
@@ -691,6 +694,7 @@
                130278422BFD978900DDCE81 /* Enums.swift in Sources */,
                13EEB8912BFED3F3002996FC /* AwardListView.swift in Sources */,
                130278412BFD978900DDCE81 /* Config.swift in Sources */,
                130A2C812C07075B008463B2 /* ListenFight_Game_Pocket_CCell.swift in Sources */,
                1302784A2BFD979200DDCE81 /* BaseVC.swift in Sources */,
                13A830F52C041B4400BB2F23 /* ListenFight_lesson_3_CCell.swift in Sources */,
                137CB4292BFF505800D32862 /* HomeListenFightVC.swift in Sources */,
DolphinEnglishLearnStudent/Assets.xcassets/Bg/bg_card.imageset/Contents.json
New file
@@ -0,0 +1,22 @@
{
  "images" : [
    {
      "filename" : "bg_card.png",
      "idiom" : "universal",
      "scale" : "1x"
    },
    {
      "filename" : "bg_card@2x.png",
      "idiom" : "universal",
      "scale" : "2x"
    },
    {
      "idiom" : "universal",
      "scale" : "3x"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  }
}
DolphinEnglishLearnStudent/Assets.xcassets/Bg/bg_card.imageset/bg_card.png
DolphinEnglishLearnStudent/Assets.xcassets/Bg/bg_card.imageset/bg_card@2x.png
DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_Game_CCell.swift
@@ -9,9 +9,39 @@
class ListenFight_Game_CCell: UICollectionViewCell {
                @IBOutlet weak var view_container: UIView!
                @IBOutlet weak var view_top: UIView!
                @IBOutlet weak var img_state: UIImageView!
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
                                img_state.alpha = 0
    }
                func setState(state:Fight_lessonType){
                                switch state {
                                                case .success:
                                                                img_state.image = UIImage(named: "icon_success")
                                                                UIView.animate(withDuration: 0.6, delay: 0, usingSpringWithDamping: 0.3, initialSpringVelocity: 0.4, options: .layoutSubviews) {
                                                                                self.img_state.alpha = 1
                                                                                self.img_state.transform = .init(scaleX: 1, y: 1)
                                                                }
                                                case .fail:
                                                                img_state.image = UIImage(named: "icon_fail")
                                                                UIView.animate(withDuration: 0.6, delay: 0, usingSpringWithDamping: 0.3, initialSpringVelocity: 0.4, options: .layoutSubviews) {
                                                                                self.img_state.alpha = 1
                                                                                self.img_state.transform = .init(scaleX: 1, y: 1)
                                                                }
                                                case .none:
                                                                img_state.alpha = 0
                                                                img_state.transform = .init(scaleX: 0.1, y: 0.1)
                                }
                }
                override func layoutSubviews() {
                                super.layoutSubviews()
                                view_top.jq_addCorners(corner: [.topLeft,.topRight], radius: 8)
                                jq_cornerRadius = 8
                }
}
DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_Game_CCell.xib
@@ -4,21 +4,83 @@
    <dependencies>
        <deployment identifier="iOS"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22684"/>
        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
        <capability name="System colors in document resources" minToolsVersion="11.0"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
    <objects>
        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
        <collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="_ListenFight_Game_CCell" id="gTV-IL-0wX" customClass="ListenFight_Game_CCell" customModule="DolphinEnglishLearnStudent" customModuleProvider="target">
            <rect key="frame" x="0.0" y="0.0" width="50" height="50"/>
            <rect key="frame" x="0.0" y="0.0" width="165" height="210"/>
            <autoresizingMask key="autoresizingMask"/>
            <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
                <rect key="frame" x="0.0" y="0.0" width="50" height="50"/>
                <rect key="frame" x="0.0" y="0.0" width="165" height="210"/>
                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
                <subviews>
                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="YTs-C9-W1k">
                        <rect key="frame" x="5" y="5" width="155" height="200"/>
                        <subviews>
                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Mmn-Bf-5Vy">
                                <rect key="frame" x="0.0" y="0.0" width="155" height="40"/>
                                <color key="backgroundColor" red="0.83137254901960778" green="0.82352941176470584" blue="0.80392156862745101" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                <constraints>
                                    <constraint firstAttribute="height" constant="40" id="E9b-fE-KSJ"/>
                                </constraints>
            </view>
            <viewLayoutGuide key="safeArea" id="ZTg-uK-7eu"/>
            <point key="canvasLocation" x="61" y="20"/>
                            <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="qVZ-4r-nXX">
                                <rect key="frame" x="0.0" y="40" width="155" height="160"/>
                            </imageView>
                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="NUh-6J-pQi">
                                <rect key="frame" x="121" y="166" width="34" height="34"/>
                                <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
                                <state key="normal" image="icon_fullScreen"/>
                            </button>
                            <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="icon_success" translatesAutoresizingMaskIntoConstraints="NO" id="dMD-2P-QwE">
                                <rect key="frame" x="49.5" y="74" width="56" height="56"/>
                                <constraints>
                                    <constraint firstAttribute="height" constant="56" id="StM-MP-u9g"/>
                                    <constraint firstAttribute="width" constant="56" id="Y6Z-pZ-azs"/>
                                </constraints>
                            </imageView>
                        </subviews>
                        <color key="backgroundColor" systemColor="systemBackgroundColor"/>
                        <constraints>
                            <constraint firstItem="Mmn-Bf-5Vy" firstAttribute="top" secondItem="YTs-C9-W1k" secondAttribute="top" id="1Sn-gn-FxE"/>
                            <constraint firstItem="dMD-2P-QwE" firstAttribute="centerX" secondItem="qVZ-4r-nXX" secondAttribute="centerX" id="4uB-mE-grS"/>
                            <constraint firstAttribute="trailing" secondItem="Mmn-Bf-5Vy" secondAttribute="trailing" id="5Nt-bJ-JBK"/>
                            <constraint firstAttribute="trailing" secondItem="NUh-6J-pQi" secondAttribute="trailing" id="LIg-1l-i3u"/>
                            <constraint firstAttribute="trailing" secondItem="qVZ-4r-nXX" secondAttribute="trailing" id="PZ7-rB-ouR"/>
                            <constraint firstItem="Mmn-Bf-5Vy" firstAttribute="leading" secondItem="YTs-C9-W1k" secondAttribute="leading" id="bJw-qs-aXN"/>
                            <constraint firstItem="qVZ-4r-nXX" firstAttribute="top" secondItem="Mmn-Bf-5Vy" secondAttribute="bottom" id="grT-zb-2jJ"/>
                            <constraint firstItem="qVZ-4r-nXX" firstAttribute="leading" secondItem="YTs-C9-W1k" secondAttribute="leading" id="sxq-IC-gv7"/>
                            <constraint firstAttribute="bottom" secondItem="qVZ-4r-nXX" secondAttribute="bottom" id="vUB-b9-xLp"/>
                            <constraint firstAttribute="bottom" secondItem="NUh-6J-pQi" secondAttribute="bottom" id="vgf-mV-ruR"/>
                            <constraint firstItem="dMD-2P-QwE" firstAttribute="top" secondItem="Mmn-Bf-5Vy" secondAttribute="bottom" constant="34" id="yju-Cd-yGg"/>
                        </constraints>
                    </view>
                </subviews>
            </view>
            <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
            <constraints>
                <constraint firstItem="YTs-C9-W1k" firstAttribute="leading" secondItem="gTV-IL-0wX" secondAttribute="leading" constant="5" id="7F2-TZ-ITp"/>
                <constraint firstAttribute="bottom" secondItem="YTs-C9-W1k" secondAttribute="bottom" constant="5" id="NS4-Iw-Buc"/>
                <constraint firstItem="YTs-C9-W1k" firstAttribute="top" secondItem="gTV-IL-0wX" secondAttribute="top" constant="5" id="bKs-J5-I38"/>
                <constraint firstAttribute="trailing" secondItem="YTs-C9-W1k" secondAttribute="trailing" constant="5" id="bdG-vi-hhI"/>
            </constraints>
            <size key="customSize" width="165" height="210"/>
            <connections>
                <outlet property="img_state" destination="dMD-2P-QwE" id="asa-h2-2Ut"/>
                <outlet property="view_container" destination="YTs-C9-W1k" id="SRu-Wj-Ued"/>
                <outlet property="view_top" destination="Mmn-Bf-5Vy" id="Pdc-oD-g5f"/>
            </connections>
            <point key="canvasLocation" x="101.34146341463415" y="60.50847457627119"/>
        </collectionViewCell>
    </objects>
    <resources>
        <image name="icon_fullScreen" width="34" height="34"/>
        <image name="icon_success" width="80" height="81"/>
        <systemColor name="systemBackgroundColor">
            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
        </systemColor>
    </resources>
</document>
DolphinEnglishLearnStudent/Moudle/Home/Listen/CCell/ListenFight_Game_Pocket_CCell.swift
New file
@@ -0,0 +1,62 @@
//
//  ListenFight_Game_Pocket_CCell.swift
//  DolphinEnglishLearnStudent
//
//  Created by 无故事王国 on 2024/5/29.
//
import UIKit
class ListenFight_Game_Pocket_CCell: UICollectionViewCell {
                private lazy var mask_img:UIImageView = {
                                let image = UIImageView(image: UIImage(named: "bg_card"))
                                return image
                }()
                private lazy var answer_img:UIImageView = {
                                let image = UIImageView()
                                image.jq_cornerRadius  = 10
                                image.backgroundColor = .red
                                return image
                }()
                override init(frame: CGRect) {
                                super.init(frame: frame)
                                addSubview(answer_img)
                                answer_img.snp.makeConstraints { make in
                                                make.edges.equalToSuperview()
                                }
                                addSubview(mask_img)
                                mask_img.snp.makeConstraints { make in
                                                make.edges.equalToSuperview()
                                }
                                let mask_tap = UITapGestureRecognizer(target: self, action: #selector(toFromAction))
                                mask_img.addGestureRecognizer(mask_tap)
                                mask_img.isUserInteractionEnabled = true
                                let answer_tap = UITapGestureRecognizer(target: self, action: #selector(toBackAction))
                                answer_img.addGestureRecognizer(answer_tap)
                                answer_img.isUserInteractionEnabled = true
                }
                required init?(coder: NSCoder) {
                                fatalError("init(coder:) has not been implemented")
                }
                @objc func toFromAction(){
                                UIView.transition(from: mask_img, to: answer_img, duration: 0.6, options: [.transitionFlipFromLeft,.showHideTransitionViews]) { _ in
                                }
                }
                @objc func toBackAction(){
                                UIView.transition(from: answer_img, to: mask_img, duration: 0.6,options: [.transitionFlipFromRight,.showHideTransitionViews]){ _ in
                                }
                }
}
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenGame_1_VC.swift
@@ -11,6 +11,31 @@
                private var viewModel = FightAnswerViewModel()
                private lazy var label_class:UILabel = {
                                let label = UILabel()
                                label.textColor = .white
                                label.text = "1"
                                label.textAlignment = .center
                                label.font = UIFont.init(name: "Impact", size: 21)
                                return label
                }()
                private lazy var label_hint:UILabel = {
                                let label = UILabel()
                                label.textColor = UIColor(hexStr: "#EE1111")
                                label.text = "请在10s内选择答案!"
                                label.textAlignment = .center
                                label.font = .systemFont(ofSize: 14, weight: .medium)
                                return label
                }()
                private lazy var view_studyHandleView:StudyHandleView = {
                                let studyHandleView = StudyHandleView.jq_loadNibView()
                                studyHandleView.view_choose.isHidden = true
                                return studyHandleView
                }()
                private lazy var collectionView:UICollectionView = {
                                let flowLayout = UICollectionViewFlowLayout()
                                let w = (JQ_ScreenW - 35 * 2 - 12) / 4.0
@@ -24,12 +49,15 @@
                                return collection
                }()
                private var timer:Timer?
                private var times:Int = 10
    override func viewDidLoad() {
        super.viewDidLoad()
                                ChooseLevelView.show { level in
                                                GameBeginTipView.show {
                                                                self.startTimer()
                                                }
                                }
    }
@@ -37,9 +65,44 @@
                override func setUI() {
                                super.setUI()
                                let view_class_title = UIView()
                                view_class_title.jq_cornerRadius = 16
                                view_class_title.backgroundColor = UIColor(hexStr: "#FBCF0F")
                                view.addSubview(view_class_title)
                                view_class_title.snp.makeConstraints { make in
                                                make.top.equalTo(self.view.safeAreaLayoutGuide.snp.top).offset(40)
                                                make.left.equalToSuperview().offset(40)
                                                make.height.equalTo(32)
                                                make.width.greaterThanOrEqualTo(32)
                                }
                                view_class_title.addSubview(label_class)
                                label_class.snp.makeConstraints { make in
                                                make.left.equalTo(11)
                                                make.right.equalTo(-12)
                                                make.centerY.equalToSuperview()
                                }
                                view.addSubview(view_studyHandleView)
                                view_studyHandleView.snp.makeConstraints { make in
                                                make.left.equalTo(view_class_title.snp.right).offset(12)
                                                make.centerY.equalTo(view_class_title)
                                                make.width.equalTo(159)
                                                make.height.equalTo(52)
                                }
                                view.addSubview(label_hint)
                                label_hint.snp.makeConstraints { make in
                                                make.left.equalTo(view_studyHandleView.snp.right).offset(23)
                                                make.centerY.equalTo(view_class_title)
                                                make.height.equalTo(20)
                                }
                                collectionView.delegate = self
                                collectionView.dataSource = self
                                collectionView.showsVerticalScrollIndicator = false
                                collectionView.jq_addShadows(shadowColor: UIColor.black.withAlphaComponent(0.1), corner: 8, radius: 10, offset: CGSize(width: 0, height: 2), opacity: 1)
                                collectionView.backgroundColor = .clear
                                view.addSubview(collectionView)
                                collectionView.snp.makeConstraints { make in
@@ -47,21 +110,98 @@
                                                make.left.right.equalToSuperview()
                                                make.bottom.equalToSuperview()
                                }
                                view.layoutIfNeeded()
                }
                private func startTimer(){
                                if timer == nil{
                                                timer = Timer(timeInterval: 1.0, target: self, selector: #selector(runloopTime), userInfo: nil, repeats: true)
                                }
                                timer?.fire()
                                RunLoop.current.add(timer!, forMode: .default)
                }
                @objc private func runloopTime(){
                                times -= 1
                                label_hint.text = "请在\(times)s内选择答案!"
                                if times == 0{
                                                timer?.fireDate = .distantFuture
                                                DispatchQueue.main.asyncAfter(deadline: .now()+3) {
                                                                self.times = 10
                                                                self.timer?.fireDate = .distantPast
                                                }
                                }
                }
                private func nextQuesAction(){
                }
                private func answerQuestion(){
                                view.layoutIfNeeded()
                                var answerType:Fight_lessonType = .none
                                answerType = .success
                                switch answerType {
                                                case .success:
                                                                viewModel.answerType.accept(.success)
                                                                collectionView.reloadData()
                                                                if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "_ListenFight_Game_CCell", for: viewModel.selectIndex.value!) as? ListenFight_Game_CCell{
                                                                                let newRect = cell.contentView.convert(cell.bounds, from: self.collectionView)
                                                                                let x = abs(newRect.origin.x) + self.collectionView.contentInset.left + 5
                                                                                let y = abs(newRect.origin.y) + 99 + 5
                                                                                let layout = self.collectionView.collectionViewLayout as! UICollectionViewFlowLayout
                                                                                let copyView = view_studyHandleView.copyView()
                                                                                copyView.view_choose.isHidden = true
                                                                                view.addSubview(copyView)
                                                                                UIView.animate(withDuration: 0.5) {
                                                                                                copyView.frame = CGRect(x: x, y: y, width: layout.itemSize.width - 10, height: 40)
                                                                                } completion: { _ in
                                                                                                DispatchQueue.main.asyncAfter(deadline: .now()+0.5) {
                                                                                                                self.viewModel.answerType.accept(.none)
                                                                                                                self.collectionView.reloadData()
                                                                                                                self.times = 11
                                                                                                                self.nextQuesAction()
                                                                                                }
                                                                                }
                                                                }
                                                case .fail:
                                                                viewModel.answerType.accept(.fail)
                                                                collectionView.reloadData()
                                                                DispatchQueue.main.asyncAfter(wallDeadline: .now()+2.5) {
                                                                                self.viewModel.answerType.accept(.none)
                                                                                self.collectionView.reloadData()
                                                                                self.times = 11
                                                                                self.nextQuesAction()
                                                                }
                                                case .none:
                                                                break
                                }
                }
}
extension HomeListenGame_1_VC:UICollectionViewDelegate{
                func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
                                viewModel.selectIndex.accept(indexPath)
                                answerQuestion()
                }
}
extension HomeListenGame_1_VC:UICollectionViewDataSource{
                func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
                                let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "_ListenFight_Game_CCell", for: indexPath) as! ListenFight_Game_CCell
                                cell.backgroundColor = .jq_randomColor
                                cell.contentView.backgroundColor = .jq_randomColor
                                if viewModel.selectIndex.value == indexPath{
                                                cell.setState(state: viewModel.answerType.value)
                                }else{
                                                cell.setState(state: .none)
                                }
                                return cell
                }
DolphinEnglishLearnStudent/Moudle/Home/Listen/VC/HomeListenGame_2_VC.swift
@@ -9,11 +9,178 @@
class HomeListenGame_2_VC: BaseVC {
                private var viewModel = FightAnswerViewModel()
                private lazy var label_time:UILabel = {
                                let label = UILabel()
                                label.textColor = UIColor(hexStr: "#EE1111")
                                label.text = "0s"
                                label.font = UIFont.init(name: "Impact", size: 36)
                                return label
                }()
                private lazy var collectionView:UICollectionView = {
                                let flowLayout = UICollectionViewFlowLayout()
                                let w = (JQ_ScreenW - 40 * 2 - 30) / 4.0
                                flowLayout.itemSize = CGSize(width: w, height: w * 0.675)
                                flowLayout.minimumInteritemSpacing = 10
                                flowLayout.minimumLineSpacing = 20
                                flowLayout.scrollDirection = .vertical
                                let collection = UICollectionView(frame: .zero, collectionViewLayout: flowLayout)
                                collection.contentInset = UIEdgeInsets(top: 101, left: 40, bottom: 0, right: 40)
                                collection.register(ListenFight_Game_Pocket_CCell.self, forCellWithReuseIdentifier: "_ListenFight_Game_Pocket_CCell")
                                return collection
                }()
                private var timer:Timer?
                private var times:Int = 600
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
                                startTimer()
    }
                override func setUI() {
                                super.setUI()
                                let label_surplusTitle = UILabel()
                                label_surplusTitle.textColor = UIColor.black
                                label_surplusTitle.text = "答题剩余时间:"
                                label_surplusTitle.font = .systemFont(ofSize: 14, weight: .medium)
                                view.addSubview(label_surplusTitle)
                                label_surplusTitle.snp.makeConstraints { make in
                                                make.left.equalTo(40)
                                                make.top.equalTo(self.view.safeAreaLayoutGuide.snp.top).offset(46)
                                                make.height.equalTo(20)
                                }
                                view.addSubview(label_time)
                                label_time.snp.makeConstraints { make in
                                                make.left.equalTo(label_surplusTitle.snp.right).offset(0)
                                                make.centerY.equalTo(label_surplusTitle)
                                                make.height.equalTo(44)
                                }
                                collectionView.delegate = self
                                collectionView.dataSource = self
                                collectionView.showsVerticalScrollIndicator = false
                                collectionView.jq_addShadows(shadowColor: UIColor.black.withAlphaComponent(0.1), corner: 8, radius: 10, offset: CGSize(width: 0, height: 2), opacity: 1)
                                collectionView.backgroundColor = .clear
                                view.addSubview(collectionView)
                                collectionView.snp.makeConstraints { make in
                                                make.top.equalTo(self.view.safeAreaLayoutGuide.snp.top)
                                                make.left.right.equalToSuperview()
                                                make.bottom.equalToSuperview()
                                }
                                view.layoutIfNeeded()
                }
                private func startTimer(){
                                if timer == nil{
                                                timer = Timer(timeInterval: 1.0, target: self, selector: #selector(runloopTime), userInfo: nil, repeats: true)
                                }
                                timer?.fire()
                                RunLoop.current.add(timer!, forMode: .default)
                }
                @objc private func runloopTime(){
                                times -= 1
                                label_time.text = "\(times)s"
                                if times == 0{
                                                timer?.fireDate = .distantFuture
                                                DispatchQueue.main.asyncAfter(deadline: .now()+3) {
                                                                self.times = 10
                                                                self.timer?.fireDate = .distantPast
                                                }
                                }
                }
                private func nextQuesAction(){
                }
                private func answerQuestion(){
                                view.layoutIfNeeded()
                                var answerType:Fight_lessonType = .none
                                answerType = .success
                                switch answerType {
                                                case .success:
                                                                viewModel.answerType.accept(.success)
                                                                collectionView.reloadData()
                                                case .fail:
                                                                viewModel.answerType.accept(.fail)
                                                                collectionView.reloadData()
                                                                DispatchQueue.main.asyncAfter(wallDeadline: .now()+2.5) {
                                                                                self.viewModel.answerType.accept(.none)
                                                                                self.collectionView.reloadData()
                                                                }
                                                case .none:
                                                                break
                                }
                }
}
extension HomeListenGame_2_VC:UICollectionViewDelegate{
                func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
                                viewModel.selectIndex.accept(indexPath)
                                _ = self.collectionView.dequeueReusableCell(withReuseIdentifier: "_ListenFight_Game_Pocket_CCell", for: indexPath) as! ListenFight_Game_Pocket_CCell
                }
}
extension HomeListenGame_2_VC:UICollectionViewDataSource{
                func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
                                let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "_ListenFight_Game_Pocket_CCell", for: indexPath) as! ListenFight_Game_Pocket_CCell
                                return cell
                }
                func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
                                return 12
                }
}
extension HomeListenGame_2_VC: UICollectionViewDelegateFlowLayout {
                // 实现以下方法以支持转场动画
                func collectionView(_ collectionView: UICollectionView, transitionLayoutForOldLayout fromLayout: UICollectionViewLayout, newLayout toLayout: UICollectionViewLayout) -> UICollectionViewTransitionLayout {
                                return UICollectionViewTransitionLayout(currentLayout: fromLayout, nextLayout: toLayout)
                }
                // 实现以下方法以返回自定义的转场动画控制器
                func collectionView(_ collectionView: UICollectionView, transitionAnimationControllerForOldCell: UICollectionViewCell, newCell: UICollectionViewCell) -> UIViewControllerAnimatedTransitioning? {
                                return FlipAnimationController()
                }
                // FlipAnimationController实现转场动画的具体细节
                class FlipAnimationController: NSObject, UIViewControllerAnimatedTransitioning {
                                func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
                                                return 0.3
                                }
                                func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
                                                guard let fromView = transitionContext.view(forKey: UITransitionContextViewKey.from) else { return }
                                                guard let toView = transitionContext.view(forKey: UITransitionContextViewKey.to) else { return }
                                                let containerView = transitionContext.containerView
                                                // 初始化动画参数
                                                toView.frame = transitionContext.finalFrame(for: transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)!)
                                                containerView.addSubview(toView)
                                                // 翻牌动画
                                                UIView.transition(from: fromView, to: toView, duration: transitionDuration(using: transitionContext), options: [.transitionFlipFromLeft]) { completed in
                                                                transitionContext.completeTransition(completed)
                                                }
                                }
                }
}