├── .gitignore ├── Game-UI-Inspirations ├── Game-UI-Inspirations.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── swiftpm │ │ │ └── Package.resolved │ └── xcshareddata │ │ └── xcschemes │ │ └── Game-UI-Inspirations (iOS).xcscheme ├── Packages │ └── RealityKitContent │ │ ├── Package.realitycomposerpro │ │ ├── ProjectData │ │ │ └── main.json │ │ └── WorkspaceData │ │ │ ├── SceneMetadataList.json │ │ │ └── Settings.rcprojectdata │ │ ├── Package.swift │ │ ├── README.md │ │ └── Sources │ │ └── RealityKitContent │ │ ├── RealityKitContent.rkassets │ │ ├── Scene.usda │ │ └── _PlainMaterial.usda │ │ └── RealityKitContent.swift ├── Shared │ ├── AFKJourney │ │ ├── AFKAscensionTier.swift │ │ ├── AFKDailyQuestList.swift │ │ ├── AFKHero.swift │ │ ├── AFKQuest.swift │ │ ├── AFKQuestView.swift │ │ └── BattleTeamPortrait.swift │ ├── AlanWake │ │ ├── AlanWakeSelectionView.swift │ │ └── GearView.swift │ ├── Arkham │ │ ├── ArkhamAsylumHUD.swift │ │ ├── ArkhamInterviewCollectionView.swift │ │ ├── BatmanLogo.swift │ │ ├── BatmanLogoAnimatedBorder.swift │ │ └── BatmanSelectionView.swift │ ├── AssassinsCreedOrigins │ │ ├── ACONewLocationBanner.swift │ │ ├── ACOQuestView.swift │ │ └── ACOTargetView.swift │ ├── Assets.xcassets │ │ ├── AccentColor.colorset │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── BoyfriendDungeon │ │ └── BDMenuItem.swift │ ├── Celeste │ │ ├── CelesteDeathAnimation.swift │ │ └── CelesteDemo.swift │ ├── Colors.xcassets │ │ ├── Contents.json │ │ ├── dbhLoadingRing.colorset │ │ │ └── Contents.json │ │ ├── genshin │ │ │ ├── Contents.json │ │ │ ├── giBlue-1.colorset │ │ │ │ └── Contents.json │ │ │ ├── giBlue-2.colorset │ │ │ │ └── Contents.json │ │ │ ├── giBlue.colorset │ │ │ │ └── Contents.json │ │ │ ├── giBronze.colorset │ │ │ │ └── Contents.json │ │ │ ├── giBrown.colorset │ │ │ │ └── Contents.json │ │ │ ├── giGold.colorset │ │ │ │ └── Contents.json │ │ │ ├── giGray-1.colorset │ │ │ │ └── Contents.json │ │ │ ├── giGray.colorset │ │ │ │ └── Contents.json │ │ │ ├── giGreen-1.colorset │ │ │ │ └── Contents.json │ │ │ ├── giGreen.colorset │ │ │ │ └── Contents.json │ │ │ ├── giLightBorder.colorset │ │ │ │ └── Contents.json │ │ │ ├── giLightPurple.colorset │ │ │ │ └── Contents.json │ │ │ ├── giNightSky.colorset │ │ │ │ └── Contents.json │ │ │ ├── giOrange-1.colorset │ │ │ │ └── Contents.json │ │ │ ├── giOrange.colorset │ │ │ │ └── Contents.json │ │ │ ├── giPurple-1.colorset │ │ │ │ └── Contents.json │ │ │ ├── giPurple.colorset │ │ │ │ └── Contents.json │ │ │ ├── giStarglitterYellow-1.colorset │ │ │ │ └── Contents.json │ │ │ ├── giStarglitterYellow.colorset │ │ │ │ └── Contents.json │ │ │ └── giWhite.colorset │ │ │ │ └── Contents.json │ │ ├── overwatch │ │ │ ├── Contents.json │ │ │ └── ow2Orange.colorset │ │ │ │ └── Contents.json │ │ └── rdr2 │ │ │ ├── Contents.json │ │ │ ├── rdr2AwardProgressGray.colorset │ │ │ └── Contents.json │ │ │ ├── rdr2Black.colorset │ │ │ └── Contents.json │ │ │ ├── rdr2Bronze.colorset │ │ │ └── Contents.json │ │ │ ├── rdr2Gold.colorset │ │ │ └── Contents.json │ │ │ ├── rdr2Gray-1.colorset │ │ │ └── Contents.json │ │ │ ├── rdr2Gray.colorset │ │ │ └── Contents.json │ │ │ ├── rdr2Minimap.colorset │ │ │ └── Contents.json │ │ │ ├── rdr2Rust.colorset │ │ │ └── Contents.json │ │ │ ├── rdr2Teal.colorset │ │ │ └── Contents.json │ │ │ └── rdr2White.colorset │ │ │ └── Contents.json │ ├── ContentView.swift │ ├── Control │ │ ├── ConsummateV.swift │ │ ├── ConsummateVDemo.swift │ │ ├── ControlQuestMarker.swift │ │ ├── ControlSelectionView.swift │ │ ├── LoadingRingsDemo.swift │ │ ├── LoadingRingsView.swift │ │ ├── LoadingRingsViewModel.swift │ │ ├── Pulsar.swift │ │ └── QuestDescriptionView.swift │ ├── DeathStranding │ │ ├── DeathStrandAnimation.swift │ │ ├── DeathStrandingTitle.swift │ │ └── PorterGradeView.swift │ ├── Demos │ │ ├── AnimatedStrokeStyledCircleDemo.swift │ │ ├── CGAffineTransformDemo.swift │ │ ├── DrStrangeShield.swift │ │ ├── DragonCurveDemo.swift │ │ ├── KiteAnimationDemo.swift │ │ ├── LongPressProgressView.swift │ │ ├── MirroredText2Demo.swift │ │ ├── MirroredTextDemo.swift │ │ ├── OrnateCorners.swift │ │ ├── ProgressBarWithDeltaDemo.swift │ │ ├── SpirolateralAnimationDemo.swift │ │ ├── SpirolateralDemo.swift │ │ ├── SpriteKitDemo.swift │ │ ├── StarPolygonDemo.swift │ │ ├── StrokeStyledCircleDemo.swift │ │ ├── TesselationDemo.swift │ │ ├── TextEffectViewDemo.swift │ │ └── WheelOfFortune.swift │ ├── Destiny2 │ │ ├── Destiny2FastTravelIcon.swift │ │ └── Destiny2FastTravelView.swift │ ├── DetroitBecomeHuman │ │ ├── DBHLoadingView.swift │ │ ├── DBHTitleScreenMenu.swift │ │ └── DBHTitleScreenMenuItem.swift │ ├── Diablo4 │ │ ├── D4Pentagram.swift │ │ └── D4Waypoint.swift │ ├── Emotes │ │ ├── EmoteHeartView.swift │ │ ├── EmoteReuleauxView.swift │ │ └── SwiftUIView.swift │ ├── Extensions │ │ ├── CG+Extensions.swift │ │ ├── CGRect+Extensions.swift │ │ ├── Color+Extensions.swift │ │ ├── Image.swift │ │ ├── Path+Extensions.swift │ │ ├── UIView+Extensions.swift │ │ └── View+Extensions.swift │ ├── FF7R │ │ ├── FF7View.swift │ │ └── FF7ViewFeed.swift │ ├── FFXIV │ │ ├── FFXIVCharacterModel.swift │ │ ├── FFXIVCharacterPointsView.swift │ │ ├── FFXIVCharacterTabView.swift │ │ ├── FFXIVCharacterView.swift │ │ ├── FFXIVTargetView.swift │ │ └── FFXIVWindowHeaderView.swift │ ├── GOTG │ │ ├── FactionBanner.swift │ │ ├── GotgInteractiveItemAlert.swift │ │ ├── GotgSettingsMenu.swift │ │ ├── GuardianFadeTransition.swift │ │ ├── KrakoaFont.swift │ │ └── KreeSymbol.swift │ ├── Game.swift │ ├── Game_UI_InspirationsApp.swift │ ├── GenshinImpact │ │ ├── GIAchievementMenu.swift │ │ ├── GIAchievementView.swift │ │ ├── GIClockView.swift │ │ ├── GIInventoryMenu.swift │ │ ├── GIItem.swift │ │ ├── GIItemRarityBackground.swift │ │ ├── GILoadingProgressBar.swift │ │ ├── GIReward.swift │ │ ├── GISelectionItem.swift │ │ ├── MasterlessStardust.swift │ │ ├── MasterlessStarglitter.swift │ │ ├── Mora.swift │ │ └── Visions │ │ │ └── GIHydro.swift │ ├── GoldenEye │ │ ├── Clock.swift │ │ └── GoldenEyeWatch.swift │ ├── Hades │ │ ├── AphroditeBoon.swift │ │ ├── AresBoon.swift │ │ ├── ArtemisBoon.swift │ │ ├── AthenaBoon.swift │ │ ├── BoonView.swift │ │ ├── ChaosBoon.swift │ │ ├── HadesBoonDemo.swift │ │ ├── HermesBoon.swift │ │ ├── PoseidonBoon.swift │ │ └── ZeusBoon.swift │ ├── HiFiRush │ │ └── HiFiRushBeatBar.swift │ ├── JustCause4 │ │ ├── JustCause4Compass.swift │ │ └── JustCause4CompassBorder.swift │ ├── LostArk │ │ ├── ArcanistIcon.swift │ │ ├── BreathGem.swift │ │ ├── GearHoningSim │ │ │ ├── GearHoningCalculator.swift │ │ │ ├── GearHoningModel.swift │ │ │ ├── GearHoningView.swift │ │ │ ├── lostArkHoningSuccessRates.plist │ │ │ └── requiredMaterials.json │ │ ├── LABardStigmaSkillView.swift │ │ ├── LABossAttackAreaAnimation.swift │ │ ├── LACardAnimation.swift │ │ ├── LACardBack.swift │ │ ├── LAItem.swift │ │ ├── LAMenu.swift │ │ ├── LASecretDungeonFloorPattern.swift │ │ ├── LostArkLogo.swift │ │ ├── LostArkSelectionView.swift │ │ ├── MokokoSeed.swift │ │ ├── PolygonSegmentWrapAnimation.swift │ │ └── TrebleClef.swift │ ├── MGSV │ │ ├── DiamondDogsLogo │ │ │ ├── DiamondDog.swift │ │ │ ├── DiamondDogsLogo.swift │ │ │ ├── DiamondGem.swift │ │ │ ├── MGSViDroidView.swift │ │ │ ├── RibbonBanner.swift │ │ │ └── RibbonShapes.swift │ │ ├── MGSVLoadingView.swift │ │ ├── MGSVLoadingViewModel.swift │ │ └── MGSVMissionTextDemo.swift │ ├── MK11 │ │ ├── KombatKardContentView.swift │ │ ├── KombatKardView.swift │ │ ├── KountdownTimerDemo.swift │ │ ├── KountdownTimerView.swift │ │ ├── KountdownTimerViewModel.swift │ │ ├── KustomizeMenuDemo.swift │ │ ├── MK11Left.swift │ │ ├── MK11SelectionView.swift │ │ └── MenuView.swift │ ├── MassEffect │ │ ├── MEConversationWheel.swift │ │ ├── MEDecryptionMinigame.swift │ │ ├── MEMinigameEngine.swift │ │ └── METalentIcon.swift │ ├── Motion.swift │ ├── MotionEffect.swift │ ├── NoMansSky │ │ └── NMSCraftingMenuItem.swift │ ├── Ori │ │ ├── OriSkill.swift │ │ ├── OriSkillTreeDemo.swift │ │ ├── OriSkillView.swift │ │ └── OriSkillWheel.swift │ ├── Overwatch │ │ ├── OW2 │ │ │ ├── OW2FindingGameAnimation.swift │ │ │ ├── OW2SelectionView.swift │ │ │ └── OW2UltimateMeter.swift │ │ ├── OWDecorPattern.swift │ │ ├── OWPlayerWaitingIcon.swift │ │ ├── OWUltimateMeter.swift │ │ ├── OWUltimateMeterBorder.swift │ │ ├── OWUltimateMeterDemo.swift │ │ ├── OWUltimateReadyView.swift │ │ ├── OverwatchIcon.swift │ │ └── OverwatchLogoDemo.swift │ ├── PapersPlease │ │ └── PapersPleaseSettingsIcon.swift │ ├── Persona5 │ │ ├── P5AnimatedStarParty.swift │ │ ├── P5AnimatedStars.swift │ │ └── Persona5AnimatedMenu.swift │ ├── RDR2 │ │ ├── ElevationMap.swift │ │ ├── RDR2AwardBadge.swift │ │ ├── RDR2AwardItem.swift │ │ ├── RDR2AwardView.swift │ │ ├── RDR2AwardViewModel.swift │ │ ├── RDR2Badgeable.swift │ │ ├── RDR2ConfirmButton.swift │ │ ├── RDR2HUD │ │ │ ├── RDR2Core │ │ │ │ ├── RDR2CoreModel.swift │ │ │ │ ├── RDR2HUDCoreMenu.swift │ │ │ │ ├── RDR2HUDCoreView.swift │ │ │ │ └── RDR2HUDCoreViewModel.swift │ │ │ └── RDR2HUD.swift │ │ ├── RDR2Menu.swift │ │ ├── RDR2MinimapDemo.swift │ │ ├── RDR2MinimapModel.swift │ │ ├── RDR2MinimapView.swift │ │ ├── RDR2MinimapViewModel.swift │ │ ├── RDR2Revolver.swift │ │ ├── RDR2RevolverLoadingAnimation.swift │ │ ├── RDR2ShowdownTitle.swift │ │ └── RDR2Splash.swift │ ├── Reusable │ │ ├── CircularText.swift │ │ ├── DragonCurveBox.swift │ │ ├── EmitterView.swift │ │ ├── InvertedShapeDemo.swift │ │ ├── LineSegmentGroup.swift │ │ ├── LongPressHoldable.swift │ │ ├── MarqueeText.swift │ │ ├── MaskedProgressBar.swift │ │ ├── MotionDemo.swift │ │ ├── PersonProfile.swift │ │ ├── ProgressBar.swift │ │ ├── ProgressBarWithDelta.swift │ │ ├── RandomIndexedTiledShape.swift │ │ ├── Shimmer.swift │ │ ├── SliderLabelView.swift │ │ ├── TestingTiledImageView.swift │ │ ├── TextEffectView.swift │ │ ├── TextEffectViewModel.swift │ │ ├── TextPath.swift │ │ ├── TextShape.swift │ │ ├── TwoTonedIsotoxalPolygon.swift │ │ ├── TypewriterTextView.swift │ │ ├── TypewriterTextViewModel.swift │ │ └── ViewModifiers │ │ │ ├── Pixellate.swift │ │ │ └── Rustify.swift │ ├── SpiderMan │ │ ├── Model │ │ │ ├── SpiderManSkill.swift │ │ │ └── SpiderManSkillModel.swift │ │ ├── ViewModel │ │ │ └── SpiderManSkillViewModel.swift │ │ └── Views │ │ │ ├── Spider.swift │ │ │ ├── SpiderManMask.swift │ │ │ ├── SpiderManSkillDetailView.swift │ │ │ ├── SpiderManSkillLoadingView.swift │ │ │ ├── SpiderManSkillTreeView.swift │ │ │ ├── SpiderManSkillTreeWeb.swift │ │ │ ├── SpiderManSkillView.swift │ │ │ └── SpiderManSkillsMenu.swift │ ├── StarTrekFleetCommand │ │ ├── STFCTutorialArrow.swift │ │ └── StarTrekFleetCommand.swift │ ├── StarWars │ │ ├── JediFallenOrder │ │ │ ├── JFOAlert.swift │ │ │ ├── JFOSaberColorPicker.swift │ │ │ └── SaberColorPicker │ │ │ │ ├── JFOSaberColorItem.swift │ │ │ │ ├── JFOSelectedItemDecoration.swift │ │ │ │ └── SaberHilt.swift │ │ ├── OpeningCrawl.swift │ │ └── SWTOR │ │ │ ├── SWTOREmpireLogo.swift │ │ │ ├── SWTORLogo.swift │ │ │ └── SWTORRepublicLogo.swift │ ├── StardewValley │ │ └── CIFilterView.swift │ ├── Starfox │ │ └── StarfoxShip.swift │ ├── TheLastOfUs │ │ ├── FireflyPendant.swift │ │ ├── FireflySymbol │ │ │ ├── FireflySymbol.swift │ │ │ ├── FireflyTail.swift │ │ │ └── FireflyWing.swift │ │ ├── POIMarker.swift │ │ ├── Skills │ │ │ ├── SkillHealingSpeed.swift │ │ │ ├── SkillIcon.swift │ │ │ ├── SkillMaxHealth.swift │ │ │ ├── SkillSelectionRow.swift │ │ │ ├── SkillVitamin.swift │ │ │ ├── SkillWeaponSway.swift │ │ │ ├── TLOUSkillModel.swift │ │ │ ├── TLOUSkillSelectMenu.swift │ │ │ └── TLOUSkillSelectMenuViewModel.swift │ │ ├── TLOUIcon.swift │ │ ├── TLOUIconDemo.swift │ │ ├── TLOUMainMenuIcon.swift │ │ ├── TLOUMenu.swift │ │ └── TLOUSkillsIcon.swift │ └── arthured.jpg ├── iOS │ └── Info.plist └── macOS │ ├── Info.plist │ └── macOS.entitlements ├── LICENSE └── README.md /Game-UI-Inspirations/Game-UI-Inspirations.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Game-UI-Inspirations.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Game-UI-Inspirations.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "originHash" : "30fd47ed4afd1ff3e2ba6ccfa4fdf0eeb4a037c2cdeebac6db2057e82eb97190", 3 | "pins" : [ 4 | { 5 | "identity" : "shapes", 6 | "kind" : "remoteSourceControl", 7 | "location" : "git@github.com:nutterfi/Shapes.git", 8 | "state" : { 9 | "revision" : "c62078d942821dbcd3e8ec45a77d9963f466e6b3", 10 | "version" : "0.5.1" 11 | } 12 | } 13 | ], 14 | "version" : 3 15 | } 16 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Packages/RealityKitContent/Package.realitycomposerpro/ProjectData/main.json: -------------------------------------------------------------------------------- 1 | { 2 | "pathsToIds" : { 3 | "\/RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/GridMaterial.usda" : "440DE5B4-E4E4-459B-AABF-9ACE96319272", 4 | "\/RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/procedural_sphere_grid.usda" : "34C460AE-CA1B-4348-BD05-621ACBDFFE97", 5 | "\/RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/Scene.usda" : "0A9B4653-B11E-4D6A-850E-C6FCB621626C", 6 | "\/RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/Untitled Scene.usda" : "03E02005-EFA6-48D6-8A76-05B2822A74E9", 7 | "RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/_GridMaterial.usda" : "01A389CE-549D-43D4-8082-422095AD9977", 8 | "RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/_PlainMaterial.usda" : "71393687-2933-4D8A-AC10-8E59942BADC1", 9 | "RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/GridMaterial.usda" : "FBD8436F-6B8B-4B82-99B5-995D538B4704", 10 | "RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/procedural_sphere_grid.usda" : "1CBF3893-ABFD-408C-8B91-045BFD257808", 11 | "RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/Scene.usda" : "26DBAE76-5DD8-47B6-A085-1B4ADA111097", 12 | "RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/Untitled Scene.usda" : "7EF42796-68EE-4330-954D-0853FBBEB57C" 13 | } 14 | } -------------------------------------------------------------------------------- /Game-UI-Inspirations/Packages/RealityKitContent/Package.realitycomposerpro/WorkspaceData/Settings.rcprojectdata: -------------------------------------------------------------------------------- 1 | { 2 | "cameraPresets" : { 3 | 4 | }, 5 | "secondaryToolbarData" : { 6 | "isGridVisible" : true, 7 | "sceneReverbPreset" : -1 8 | }, 9 | "unitDefaults" : { 10 | "°" : "°", 11 | "kg" : "g", 12 | "m" : "cm", 13 | "m\/s" : "m\/s", 14 | "m\/s²" : "m\/s²", 15 | "s" : "s" 16 | } 17 | } -------------------------------------------------------------------------------- /Game-UI-Inspirations/Packages/RealityKitContent/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.7 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "RealityKitContent", 8 | products: [ 9 | // Products define the executables and libraries a package produces, and make them visible to other packages. 10 | .library( 11 | name: "RealityKitContent", 12 | targets: ["RealityKitContent"]), 13 | ], 14 | dependencies: [ 15 | // Dependencies declare other packages that this package depends on. 16 | // .package(url: /* package url */, from: "1.0.0"), 17 | ], 18 | targets: [ 19 | // Targets are the basic building blocks of a package. A target can define a module or a test suite. 20 | // Targets can depend on other targets in this package, and on products in packages this package depends on. 21 | .target( 22 | name: "RealityKitContent", 23 | dependencies: []), 24 | ] 25 | ) -------------------------------------------------------------------------------- /Game-UI-Inspirations/Packages/RealityKitContent/README.md: -------------------------------------------------------------------------------- 1 | # RealityKitContent 2 | 3 | A description of this package. -------------------------------------------------------------------------------- /Game-UI-Inspirations/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/Scene.usda: -------------------------------------------------------------------------------- 1 | #usda 1.0 2 | ( 3 | defaultPrim = "Root" 4 | metersPerUnit = 1 5 | upAxis = "Y" 6 | ) 7 | 8 | def Xform "Root" 9 | { 10 | reorder nameChildren = ["Sphere", "_GridMaterial", "_PlainMaterial"] 11 | rel material:binding = None ( 12 | bindMaterialAs = "weakerThanDescendants" 13 | ) 14 | 15 | def Sphere "Sphere" ( 16 | active = true 17 | prepend apiSchemas = ["MaterialBindingAPI"] 18 | ) 19 | { 20 | rel material:binding = ( 21 | bindMaterialAs = "weakerThanDescendants" 22 | ) 23 | double radius = 0.05 24 | quatf xformOp:orient = (1, 0, 0, 0) 25 | float3 xformOp:scale = (1, 1, 1) 26 | float3 xformOp:translate = (0, 0, 0.0004) 27 | uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] 28 | 29 | def RealityKitComponent "Collider" 30 | { 31 | uint group = 1 32 | uniform token info:id = "RealityKit.Collider" 33 | uint mask = 4294967295 34 | token type = "Default" 35 | 36 | def RealityKitStruct "Shape" 37 | { 38 | float3 extent = (0.2, 0.2, 0.2) 39 | float radius = 0.05 40 | token shapeType = "Sphere" 41 | } 42 | } 43 | 44 | def RealityKitComponent "InputTarget" 45 | { 46 | uniform token info:id = "RealityKit.InputTarget" 47 | } 48 | } 49 | 50 | def "_PlainMaterial" ( 51 | active = true 52 | prepend references = @_PlainMaterial.usda@ 53 | ) 54 | { 55 | float3 xformOp:scale = (1, 1, 1) 56 | uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"] 57 | } 58 | } 59 | 60 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/_PlainMaterial.usda: -------------------------------------------------------------------------------- 1 | #usda 1.0 2 | ( 3 | defaultPrim = "Root" 4 | metersPerUnit = 1 5 | upAxis = "Y" 6 | ) 7 | 8 | def Xform "Root" 9 | { 10 | def Material "PlainMaterial" 11 | { 12 | token outputs:mtlx:surface 13 | token outputs:realitykit:vertex 14 | prepend token outputs:surface.connect = 15 | float2 ui:nodegraph:realitykit:subgraphOutputs:pos = (358.25, 99.5) 16 | float2 ui:nodegraph:realitykit:subgraphOutputs:size = (181.5, 99) 17 | 18 | def Shader "MaterialXPreviewSurface" 19 | { 20 | uniform token info:id = "ND_UsdPreviewSurface_surfaceshader" 21 | token outputs:out 22 | float2 ui:nodegraph:node:pos = (103.75, 99.5) 23 | float2 ui:nodegraph:node:size = (207.5, 199) 24 | } 25 | 26 | def Shader "UsdPreviewSurface" 27 | { 28 | uniform token info:id = "UsdPreviewSurface" 29 | color3f inputs:diffuseColor = (0.89737034, 0.89737034, 0.89737034) ( 30 | colorSpace = "Input - Texture - sRGB - sRGB" 31 | ) 32 | float inputs:metallic = 0.15 33 | float inputs:roughness = 0.5 34 | token outputs:surface 35 | } 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// Bundle for the RealityKitContent project 4 | public let realityKitContentBundle = Bundle.module 5 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/AFKJourney/AFKAscensionTier.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AFKAscensionTier.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 4/13/24. 6 | // 7 | 8 | import Foundation 9 | import SwiftUI 10 | 11 | /// Ascension Tier value of an AFKTeammate 12 | enum AFKAscensionTier { 13 | case rare // bottom, can't be upgraded 14 | case elite // base for upgradeable 15 | case elitePlus 16 | case epic 17 | case epicPlus 18 | case legendary 19 | case legendaryPlus 20 | case mythic 21 | case mythicPlus 22 | case supreme 23 | case supremePlus 24 | case paragon1 25 | case paragon2 26 | case paragon3 27 | case paragon4 28 | } 29 | 30 | extension AFKAscensionTier { 31 | 32 | var backgroundColor: Color { 33 | switch self { 34 | case .rare: 35 | .blue 36 | case .elite, .elitePlus: 37 | .purple 38 | case .supreme, .supremePlus: 39 | .orange 40 | case .epic, .epicPlus: 41 | .arkhamGold 42 | case .legendary, .legendaryPlus: 43 | .alanWakeBlue 44 | case .mythic, .mythicPlus: 45 | .gotgGreen 46 | default: 47 | .white 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/AFKJourney/AFKHero.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AFKHero.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 4/13/24. 6 | // 7 | 8 | import Foundation 9 | 10 | /// Represents a character in AFKJourney 11 | struct AFKHero: Identifiable { 12 | var name: String 13 | var tier: AFKAscensionTier 14 | var `class`: AFKClass 15 | 16 | // Basic Stats 17 | 18 | var hp: Int = 0 19 | var atk: Int = 0 20 | var physDef: Int = 0 21 | var magicDef: Int = 0 22 | 23 | // Offensive Stats 24 | var attackSpeed: Double = .zero 25 | var crit: Double = .zero 26 | var haste: Double = .zero 27 | var defPenetration: Double = .zero 28 | var execution: Double = .zero 29 | var critDamageBoost: Double = .zero 30 | 31 | // Defensive Stats 32 | var vitality: Double = .zero 33 | var lifeDrain: Double = .zero 34 | var critResist: Double = .zero 35 | var rangedDef: Double = .zero 36 | var critDamageDef: Double = .zero 37 | 38 | var id: String { 39 | name 40 | } 41 | } 42 | 43 | enum AFKClass { 44 | case support, mage, warrior, rogue, marksman, tank 45 | } 46 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/AFKJourney/AFKQuest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AFKQuest.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 4/13/24. 6 | // 7 | 8 | import Foundation 9 | 10 | struct AFKQuest: Identifiable { 11 | enum Status { 12 | case inactive 13 | case active 14 | case completed 15 | case rewardObtained 16 | } 17 | 18 | var title: String 19 | var required: Int 20 | var obtained: Int 21 | var status: Status 22 | var value: Int 23 | 24 | var id = UUID() 25 | } 26 | 27 | extension AFKQuest { 28 | static var example: AFKQuest { 29 | AFKQuest(title: "Participate in Arena x1", required: 1, obtained: 0, status: .active, value: 20) 30 | } 31 | 32 | var progress: Double { 33 | Double(obtained) / Double(required) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Arkham/BatmanLogoAnimatedBorder.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BatmanLogoAnimatedBorder.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 1/21/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct BatmanLogoAnimatedBorder: View { 11 | @State private var trim: Float = 0.5 12 | @State private var isAnimating = false 13 | var body: some View { 14 | VStack { 15 | Slider(value: $trim) 16 | BatmanLogo() 17 | .trim(from: 0, to: CGFloat(trim)) 18 | .stroke(style: StrokeStyle(lineWidth: 5, dash: [100, 10], dashPhase: isAnimating ? 110 : 0)) 19 | .animation(.linear(duration: 1).repeatForever(autoreverses: false), value: isAnimating) 20 | .background( 21 | BatmanLogo().fill(Color.black.opacity(0.3)) 22 | ) 23 | } 24 | .task { 25 | isAnimating.toggle() 26 | } 27 | } 28 | } 29 | 30 | struct BatmanLogoAnimatedBorder_Previews: PreviewProvider { 31 | static var previews: some View { 32 | BatmanLogoAnimatedBorder() 33 | .frame(width: 256, height: 256) 34 | .previewLayout(.sizeThatFits) 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Arkham/BatmanSelectionView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BatmanSelectionView.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 11/25/22. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct BatmanSelectionView: View { 11 | var body: some View { 12 | GeometryReader { proxy in 13 | let dim = min(proxy.size.width, proxy.size.height) 14 | ZStack { 15 | Color.gray 16 | Circle() 17 | .inset(by: dim * 0.05) 18 | .foregroundStyle(.white) 19 | BatmanLogo() 20 | .frame(width: dim * 0.9, height: dim * 0.9) 21 | } 22 | .frame(width: proxy.size.width, height: proxy.size.height) 23 | } 24 | } 25 | } 26 | 27 | struct BatmanSelectionView_Previews: PreviewProvider { 28 | static var previews: some View { 29 | BatmanSelectionView() 30 | .frame(width: 256, height: 128) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/BoyfriendDungeon/BDMenuItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BDMenuItem.swift 3 | // Game-UI-Inspirations (iOS) 4 | // 5 | // Created by nutterfi on 6/25/22. 6 | // 7 | 8 | import SwiftUI 9 | import Shapes 10 | 11 | struct BDMenuItem: View { 12 | @State private var animating = false 13 | var body: some View { 14 | GeometryReader { proxy in 15 | let dim = min(proxy.size.width, proxy.size.height) 16 | ZStack { 17 | CutCornerRectangle(cutLength: dim * 0.1) 18 | .foregroundStyle(Color.randomBlue) 19 | CutCornerRectangle(cutLength: dim * 0.1) 20 | .stroke(lineWidth: 10) 21 | 22 | CutCornerRectangle(corners: [.topLeft: dim * 0.1, .bottomRight: dim * 0.2]) 23 | .inset(amount: dim * 0.1) 24 | .stroke(lineWidth: 5) 25 | .overlay( 26 | Heart() 27 | .frame(width: dim * 0.5, height: dim * 0.5) 28 | .padding(dim * 0.2) 29 | .foregroundStyle(.red) 30 | ) 31 | .scaleEffect(animating ? 0.85 : 1) 32 | .animation(Animation.easeInOut(duration: 2).repeatForever(), value: animating ) 33 | } 34 | .task { 35 | animating = true 36 | } 37 | .frame(width: proxy.size.width, height: proxy.size.height) 38 | } 39 | } 40 | } 41 | 42 | struct BDMenuItem_Previews: PreviewProvider { 43 | static var previews: some View { 44 | BDMenuItem() 45 | .frame(width: 200, height: 300) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Celeste/CelesteDemo.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CelesteDemo.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 9/28/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct CelesteDemo: View { 11 | var body: some View { 12 | GeometryReader { proxy in 13 | ZStack { 14 | CelesteDeathAnimation() 15 | } 16 | .background( 17 | LinearGradient(colors: [.purple, .black], startPoint: .topTrailing, endPoint: .bottomLeading) 18 | ) 19 | .frame(width: proxy.size.width, height: proxy.size.height) 20 | } 21 | } 22 | } 23 | 24 | struct CelesteDemo_Previews: PreviewProvider { 25 | static var previews: some View { 26 | CelesteDemo() 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/dbhLoadingRing.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "161", 9 | "green" : "135", 10 | "red" : "101" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.631", 27 | "green" : "0.529", 28 | "red" : "0.396" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/genshin/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/genshin/giBlue-1.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.773", 9 | "green" : "0.631", 10 | "red" : "0.431" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.773", 27 | "green" : "0.631", 28 | "red" : "0.431" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/genshin/giBlue-2.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "148", 9 | "green" : "119", 10 | "red" : "108" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.580", 27 | "green" : "0.467", 28 | "red" : "0.424" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/genshin/giBlue.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "148", 9 | "green" : "119", 10 | "red" : "108" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.580", 27 | "green" : "0.467", 28 | "red" : "0.424" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/genshin/giBronze.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.204", 9 | "green" : "0.478", 10 | "red" : "0.702" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.204", 27 | "green" : "0.478", 28 | "red" : "0.702" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/genshin/giBrown.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.098", 9 | "green" : "0.314", 10 | "red" : "0.537" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.098", 27 | "green" : "0.314", 28 | "red" : "0.537" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/genshin/giGold.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.451", 9 | "green" : "0.910", 10 | "red" : "0.945" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.451", 27 | "green" : "0.910", 28 | "red" : "0.945" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/genshin/giGray-1.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.639", 9 | "green" : "0.639", 10 | "red" : "0.639" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.639", 27 | "green" : "0.639", 28 | "red" : "0.639" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/genshin/giGray.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.467", 9 | "green" : "0.451", 10 | "red" : "0.447" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.467", 27 | "green" : "0.451", 28 | "red" : "0.447" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/genshin/giGreen-1.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.549", 9 | "green" : "0.682", 10 | "red" : "0.416" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.549", 27 | "green" : "0.682", 28 | "red" : "0.416" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/genshin/giGreen.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.443", 9 | "green" : "0.486", 10 | "red" : "0.373" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.443", 27 | "green" : "0.486", 28 | "red" : "0.373" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/genshin/giLightBorder.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "234", 9 | "green" : "211", 10 | "red" : "207" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.918", 27 | "green" : "0.827", 28 | "red" : "0.812" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/genshin/giLightPurple.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "222", 9 | "green" : "185", 10 | "red" : "179" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.871", 27 | "green" : "0.725", 28 | "red" : "0.702" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/genshin/giNightSky.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "111", 9 | "green" : "32", 10 | "red" : "20" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.435", 27 | "green" : "0.125", 28 | "red" : "0.078" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/genshin/giOrange-1.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.306", 9 | "green" : "0.569", 10 | "red" : "0.867" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.306", 27 | "green" : "0.569", 28 | "red" : "0.867" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/genshin/giOrange.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.263", 9 | "green" : "0.424", 10 | "red" : "0.588" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.263", 27 | "green" : "0.424", 28 | "red" : "0.588" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/genshin/giPurple-1.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.745", 9 | "green" : "0.455", 10 | "red" : "0.580" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.745", 27 | "green" : "0.455", 28 | "red" : "0.580" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/genshin/giPurple.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.557", 9 | "green" : "0.376", 10 | "red" : "0.408" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.557", 27 | "green" : "0.376", 28 | "red" : "0.408" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/genshin/giStarglitterYellow-1.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "139", 9 | "green" : "186", 10 | "red" : "208" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.545", 27 | "green" : "0.729", 28 | "red" : "0.816" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/genshin/giStarglitterYellow.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "174", 9 | "green" : "218", 10 | "red" : "234" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.682", 27 | "green" : "0.855", 28 | "red" : "0.918" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/genshin/giWhite.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.859", 9 | "green" : "0.902", 10 | "red" : "0.910" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.859", 27 | "green" : "0.902", 28 | "red" : "0.910" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/overwatch/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/overwatch/ow2Orange.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "51", 9 | "green" : "129", 10 | "red" : "253" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.200", 27 | "green" : "0.506", 28 | "red" : "0.992" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/rdr2/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/rdr2/rdr2AwardProgressGray.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.204", 9 | "green" : "0.204", 10 | "red" : "0.204" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.204", 27 | "green" : "0.204", 28 | "red" : "0.204" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/rdr2/rdr2Black.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.016", 9 | "green" : "0.016", 10 | "red" : "0.016" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.016", 27 | "green" : "0.016", 28 | "red" : "0.016" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/rdr2/rdr2Bronze.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.216", 9 | "green" : "0.302", 10 | "red" : "0.510" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.216", 27 | "green" : "0.302", 28 | "red" : "0.510" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/rdr2/rdr2Gold.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.027", 9 | "green" : "0.773", 10 | "red" : "0.973" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.027", 27 | "green" : "0.773", 28 | "red" : "0.973" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/rdr2/rdr2Gray-1.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.353", 9 | "green" : "0.353", 10 | "red" : "0.353" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.353", 27 | "green" : "0.353", 28 | "red" : "0.353" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/rdr2/rdr2Gray.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.086", 9 | "green" : "0.086", 10 | "red" : "0.086" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.086", 27 | "green" : "0.086", 28 | "red" : "0.086" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/rdr2/rdr2Minimap.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.753", 9 | "green" : "0.839", 10 | "red" : "0.871" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.753", 27 | "green" : "0.839", 28 | "red" : "0.871" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/rdr2/rdr2Rust.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.000", 9 | "green" : "0.004", 10 | "red" : "0.153" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.000", 27 | "green" : "0.004", 28 | "red" : "0.153" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/rdr2/rdr2Teal.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.549", 9 | "green" : "0.584", 10 | "red" : "0.478" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.549", 27 | "green" : "0.584", 28 | "red" : "0.478" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Colors.xcassets/rdr2/rdr2White.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.906", 9 | "green" : "0.906", 10 | "red" : "0.906" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.906", 27 | "green" : "0.906", 28 | "red" : "0.906" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Control/ConsummateV.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ConsummateV.swift 3 | // Control-Loading-Animations 4 | // 5 | // Created by nutterfi on 3/4/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct ConsummateV: View { 11 | // Number of Vs 12 | // linewidth of each V 13 | var count: Int 14 | var lineWidth: CGFloat = 10.0 15 | var body: some View { 16 | GeometryReader { proxy in 17 | let size = proxy.size 18 | let deltaX: CGFloat = size.width * 0.5 / CGFloat(count) 19 | let deltaY: CGFloat = size.height / CGFloat(count) 20 | 21 | ForEach(0.. some View { 17 | VStack(spacing: 0) { 18 | ForEach(0.. CGRect { 6 | let x = magnitude * cos(angle.radians) 7 | let y = magnitude * sin(angle.radians) 8 | return self.offsetBy(dx: x, dy: y) 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Extensions/Image.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Image.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 3/26/24. 6 | // 7 | 8 | import SwiftUI 9 | 10 | extension Image { 11 | init(cgImage: CGImage) { 12 | #if canImport(UIKit) 13 | self.init(uiImage: UIImage(cgImage: cgImage)) 14 | #else 15 | self.init(nsImage: NSImage(cgImage: cgImage, size: CGSize(width: cgImage.width, height: cgImage.height))) 16 | #endif 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Extensions/Path+Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Path+Extensions.swift 3 | // 4 | // Created by nutterfi on 2/27/21. 5 | // 6 | 7 | import SwiftUI 8 | 9 | extension Path { 10 | // an equally spaced collection of points around the path 11 | func equallySpacedPoints(count: Int) -> [CGPoint] { 12 | let dp: CGFloat = 1.0 / CGFloat(count) 13 | var points = [CGPoint]() 14 | let samples = stride(from: 0.0, to: 1.0, by: Double.Stride(dp)) 15 | 16 | samples.forEach { (p) in 17 | let tp = self.trimmedPath(from: CGFloat(p)-dp, to: CGFloat(p)+dp) 18 | points.append(CGPoint(x: tp.boundingRect.midX, y: tp.boundingRect.midY)) 19 | } 20 | return points 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Extensions/UIView+Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Extensions.swift 3 | // SwiftUIShaders 4 | // 5 | // Created by nutterfi on 2/8/22. 6 | // 7 | 8 | import SwiftUI 9 | 10 | #if canImport(UIKit) 11 | import UIKit 12 | 13 | extension UIView { 14 | var renderedImage: UIImage { 15 | let renderer = UIGraphicsImageRenderer(bounds: bounds) 16 | return renderer.image { context in 17 | layer.render(in: context.cgContext) 18 | } 19 | } 20 | } 21 | 22 | extension View { 23 | func uiImage(rect: CGRect) -> UIImage { 24 | let window = UIWindow(frame: rect) 25 | // iOS15 bug introduces offset in rendered image unless ignoring safe areas 26 | let hosting = UIHostingController(rootView: self.edgesIgnoringSafeArea(.all)) 27 | hosting.view.frame = window.frame 28 | window.addSubview(hosting.view) 29 | hosting.view.backgroundColor = .clear 30 | window.makeKeyAndVisible() 31 | return hosting.view.renderedImage 32 | } 33 | } 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/FFXIV/FFXIVCharacterModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FFXIVCharacterModel.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 8/18/22. 6 | // 7 | 8 | import Foundation 9 | 10 | class FFXIVCharacterModel: ObservableObject { 11 | @Published var name: String = "Reu Leaux" 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/FFXIV/FFXIVCharacterPointsView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FFXIVCharacterPointsView.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 8/18/22. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct FFXIVCharacterPointsView: View { 11 | @Binding var totalPoints: Int 12 | @Binding var actualPoints: Int 13 | var color: Color = .green 14 | var title: String 15 | 16 | var body: some View { 17 | VStack(spacing: 0) { 18 | HStack { 19 | Text(title) 20 | Spacer() 21 | Text("\(actualPoints)") 22 | } 23 | color 24 | .frame(height: 10) 25 | HStack { 26 | Spacer() 27 | Text("\(totalPoints)") 28 | } 29 | } 30 | } 31 | } 32 | 33 | struct FFXIVCharacterPointsView_Previews: PreviewProvider { 34 | static var previews: some View { 35 | FFXIVCharacterPointsView( 36 | totalPoints: .constant(178), 37 | actualPoints: .constant(54), 38 | title: "HP" 39 | ) 40 | .frame(width: 256, height: 80) 41 | .previewLayout(.sizeThatFits) 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/FFXIV/FFXIVCharacterTabView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FFXIVCharacterTabView.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 8/18/22. 6 | // 7 | 8 | import SwiftUI 9 | import Shapes 10 | 11 | struct FFXIVCharacterTabView: View { 12 | @Binding var title: String 13 | @Binding var selected: Bool 14 | 15 | var body: some View { 16 | ZStack(alignment: .bottomLeading) { 17 | VStack(spacing: 0) { 18 | Color.black.opacity(0.5) 19 | Color.black.opacity(0.8) 20 | } 21 | .overlay( 22 | Text(title) 23 | .foregroundStyle(.white) 24 | ) 25 | .clipShape( 26 | CutCornerRectangle( 27 | corners: [ 28 | .topLeft : 18, 29 | .bottomLeft : 12, 30 | .topRight : 10, 31 | .bottomRight : 20 32 | ] 33 | ) 34 | ) 35 | // .frame(maxWidth: .infinity) 36 | 37 | Rectangle() 38 | .frame(width: 14, height: 5) 39 | .rotationEffect(.degrees(45)) 40 | .offset(x: 5, y: -5) 41 | .foregroundStyle(selected ? Color.hadesZeusYellow : .gray) 42 | 43 | } 44 | } 45 | } 46 | 47 | struct FFXIVCharacterTabView_Previews: PreviewProvider { 48 | static var previews: some View { 49 | // FFXIVCharacterTabView( 50 | // title: .constant("Attributes"), 51 | // selected: .constant(true) 52 | // ) 53 | // .frame(width: 150, height: 30) 54 | HStack { 55 | FFXIVCharacterTabView(title: .constant("Attributes"), selected: .constant(true)) 56 | 57 | FFXIVCharacterTabView(title: .constant("Profile"), selected: .constant(false)) 58 | 59 | FFXIVCharacterTabView(title: .constant("Classes/Jobs"), selected: .constant(false)) 60 | } 61 | .frame(width: 360, height: 30) 62 | .previewLayout(.sizeThatFits) 63 | 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/FFXIV/FFXIVWindowHeaderView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FFXIVWindowHeaderView.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 8/18/22. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct FFXIVWindowHeaderView: View { 11 | @Binding var title: String 12 | @Binding var description: String 13 | 14 | var body: some View { 15 | HStack { 16 | Text(title) 17 | .foregroundStyle(.white) 18 | 19 | Spacer() 20 | 21 | Text(description) 22 | .foregroundStyle(Color.hadesZeusYellow) 23 | 24 | Button { 25 | print("TODO: Hide window") 26 | } label: { 27 | Image(systemName: "x.circle") 28 | .foregroundStyle(Color.hadesZeusYellow) 29 | } 30 | 31 | } 32 | .padding(1) 33 | .background(Color(red: 66/255, green: 66/255, blue: 66/255)) 34 | .frame(maxWidth: .infinity) 35 | } 36 | } 37 | 38 | struct FFXIVWindowHeaderView_Previews: PreviewProvider { 39 | static var previews: some View { 40 | FFXIVWindowHeaderView( 41 | title: .constant("Character"), 42 | description: .constant("Reu Leuax".uppercased()) 43 | ) 44 | .frame(width: 300) 45 | .previewLayout(.sizeThatFits) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/GOTG/KrakoaFont.swift: -------------------------------------------------------------------------------- 1 | // 2 | // KrakoaFont.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 1/17/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct KrakoaFont: Shape { 11 | var letter: Character 12 | // based on width 13 | let circleSize = 1.0 14 | let squareSize = 1.0/3.0 15 | 16 | func A(rect: CGRect) -> Path { 17 | Path { path in 18 | path.move(to: .zero) 19 | path.addRect( 20 | CGRect( 21 | origin: .zero, 22 | size: .init(width: rect.width * squareSize, height: rect.width * squareSize) 23 | ) 24 | ) 25 | path.addRect( 26 | CGRect( 27 | origin: .init(x: rect.width * 2/3, y: .zero), 28 | size: .init(width: rect.width * squareSize, height: rect.width * squareSize) 29 | ) 30 | ) 31 | path.addRect( 32 | CGRect( 33 | origin: .init(x: rect.width * 1/3, y: rect.height * 4/5), 34 | size: .init(width: rect.width * squareSize, height: rect.width * squareSize) 35 | ) 36 | ) 37 | path.addEllipse(in: .init( 38 | origin: .init(x: .zero, y: rect.height * 1/5), 39 | size: .init(width: rect.width * circleSize, height: rect.width * circleSize)) 40 | ) 41 | } 42 | } 43 | 44 | func path(in rect: CGRect) -> Path { 45 | switch letter.lowercased() { 46 | case "a": 47 | return A(rect: rect) 48 | default: 49 | return Path() 50 | } 51 | } 52 | 53 | } 54 | 55 | struct KrakoaFont_Previews: PreviewProvider { 56 | static var previews: some View { 57 | KrakoaFont(letter: "A") 58 | .stroke() 59 | .frame(width: 30, height:50) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Game.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | enum Game: String, Identifiable, Hashable, CaseIterable { 4 | 5 | var id: String { self.rawValue } 6 | var title: String { id } 7 | 8 | case mgsv = "MGSV" 9 | case control = "Control" 10 | case mk11 = "MK11" 11 | case genshinImpact = "Genshin Impact" 12 | case rdr2 = "RDR2" 13 | case tlou = "The Last of Us" 14 | case overwatch = "Overwatch" 15 | case overwatch2 = "Overwatch 2" 16 | case swtor = "SWTOR" 17 | case hades = "Hades" 18 | case ff14 = "FFXIV" 19 | case detroit = "Detroit: Become Human" 20 | case destiny2 = "Destiny 2" 21 | case celeste = "Celeste" 22 | case spiderMan = "Spider-Man" 23 | case persona5 = "Persona 5" 24 | case lostArk = "Lost Ark" 25 | case stardewValley = "Stardew Valley" 26 | case deathStranding = "Death Stranding" 27 | case ori = "Ori" 28 | case justCause4 = "Just Cause 4" 29 | case alanwake = "Alan Wake" 30 | case arkhamAsylum = "Batman: Arkham Asylum" 31 | case gotg = "Guardians of the Galaxy" 32 | case massEffect = "Mass Effect" 33 | case diablo4 = "Diablo IV" 34 | } 35 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Game_UI_InspirationsApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Game_UI_InspirationsApp.swift 3 | // Shared 4 | // 5 | // Created by nutterfi on 4/13/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | // FIXME: iPad app does not look good! Most of the projects were built in an iPhone and it shows! 11 | // Suggest: iPad landscape ONLY. iPhone landscape _may_ work if we fine-tune the navigation stack a bit, but otherwise 12 | 13 | @main 14 | struct Game_UI_InspirationsApp: App { 15 | var body: some Scene { 16 | WindowGroup { 17 | ContentView() 18 | } 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/GenshinImpact/GIInventoryMenu.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GIInventoryMenu.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 10/14/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct GIInventoryMenu: View { 11 | var body: some View { 12 | ScrollView(.horizontal) { 13 | HStack { 14 | let items: [GIItem] = [ 15 | GIItem(itemType: .character, rarity: .five, name: "Nutterfi", showStars: false), 16 | GIItem(itemType: .mora, rarity: .two, name: "10000"), 17 | GIItem(itemType: .stardust, rarity: .three, name: "23"), 18 | GIItem(itemType: .starglitter, rarity: .one, name: "1"), 19 | GIItem(itemType: .primogem, rarity: .four, name: "1") 20 | ] 21 | 22 | ForEach(items) { item in 23 | GISelectionItem(item: item) 24 | .frame(width: 100, height: 120) 25 | } 26 | } 27 | } 28 | } 29 | } 30 | 31 | struct GIInventoryMenu_Previews: PreviewProvider { 32 | static var previews: some View { 33 | GIInventoryMenu() 34 | .previewLayout(.sizeThatFits) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/GenshinImpact/GIItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GIItem.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 10/14/21. 6 | // 7 | 8 | import Foundation 9 | import SwiftUI 10 | 11 | // Sample types of items obtainable in the game 12 | enum GIItemType { 13 | case character 14 | case mora 15 | case starglitter 16 | case stardust 17 | case primogem // haven't yet defined 18 | } 19 | 20 | struct GIItem: Identifiable { 21 | var id = UUID().uuidString 22 | var itemType: GIItemType 23 | var rarity: GIItemRarity 24 | var name: String 25 | 26 | var showStars: Bool = true 27 | var locked: Bool = false 28 | var new: Bool = false 29 | } 30 | 31 | enum GIItemRarity: Int { 32 | case one = 1, two, three, four, five 33 | 34 | var color: (String, String) { 35 | switch self { 36 | case .one: return ("giGray", "giGray-1") 37 | case .two: return ("giGreen", "giGreen-1") 38 | case .three: return ("giBlue", "giBlue-1") 39 | case .four: return ("giPurple", "giPurple-1") 40 | case .five: return ("giOrange", "giOrange-1") 41 | } 42 | } 43 | } 44 | 45 | struct GIItemView: View { 46 | var item: GIItem 47 | var body: some View { 48 | Group { 49 | switch item.itemType { 50 | case .mora: 51 | Mora() 52 | case .primogem: 53 | TwoTonedIsotoxalPolygon(sides: 2, color1: .white, color2: Color("giBlue")) 54 | case .starglitter: 55 | MasterlessStarglitter() 56 | case .character: 57 | PersonProfile() 58 | .shadow(color: .black, radius: 5, x: 1, y: 1) 59 | 60 | case .stardust: 61 | MasterlessStardust() 62 | } 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/GenshinImpact/GIItemRarityBackground.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GIItemRarityBackground.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 10/14/21. 6 | // 7 | 8 | import SwiftUI 9 | import Shapes 10 | 11 | struct GIItemRarityBackground: View { 12 | var rarity: GIItemRarity 13 | var body: some View { 14 | GeometryReader { proxy in 15 | let dim = min(proxy.size.width, proxy.size.height) 16 | ZStack { 17 | Triquetra(strokeStyle: .init(lineWidth: dim * 0.12), centered: true) 18 | .inset(amount: dim * 0.1) 19 | .foregroundStyle(Color.white.opacity(0.08)) 20 | .rotationEffect(.degrees(180)) 21 | Circle() 22 | .foregroundStyle(.white.opacity(0.08)) 23 | .frame(width: dim * 0.15, height: dim * 0.15) 24 | .offset(x: 0, y: -dim * 0.1) 25 | } 26 | .background( 27 | LinearGradient(colors: [Color(rarity.color.0), Color(rarity.color.1)], startPoint: .topLeading, endPoint: .bottomTrailing) 28 | ) 29 | .frame(width: proxy.size.width, height: proxy.size.height) 30 | } 31 | } 32 | } 33 | 34 | struct GIItemRarityBackground_Previews: PreviewProvider { 35 | static var previews: some View { 36 | GIItemRarityBackground(rarity: .five) 37 | .frame(width: 256, height: 128) 38 | .previewLayout(.sizeThatFits) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/GenshinImpact/GILoadingProgressBar.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GILoadingProgressBar.swift 3 | // 4 | // Created by nutterfi on 2/15/21. 5 | // 6 | 7 | import SwiftUI 8 | 9 | struct GILoadingProgressBar: View { 10 | @State var progress: Float = 0.0 11 | 12 | var body: some View { 13 | VStack { 14 | Slider(value: $progress) 15 | .padding() 16 | 17 | Spacer() 18 | 19 | MaskedProgressBar(progress: progress, backView: Color.gray, frontView: Color.blue, mask: mask) 20 | .frame(width: 200, height: 50) 21 | 22 | Spacer() 23 | } 24 | .padding() 25 | } 26 | 27 | var mask: some View { 28 | let names = ["flame", "drop", "wind", "bolt", "leaf", "snow", "camera.aperture"] 29 | 30 | return HStack { 31 | ForEach(names, id: \.self) { name in 32 | Image(systemName: name) 33 | .resizable() 34 | .scaledToFit() 35 | } 36 | } 37 | } 38 | } 39 | 40 | struct GenshinImpactLoadingProgressBar_Previews: PreviewProvider { 41 | static var previews: some View { 42 | GILoadingProgressBar() 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/GenshinImpact/GIReward.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GIRewardItem.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 10/14/21. 6 | // 7 | 8 | import SwiftUI 9 | import Shapes 10 | 11 | struct GIReward: View { 12 | var item: GIItem 13 | var body: some View { 14 | GeometryReader { proxy in 15 | let dim = min(proxy.size.width, proxy.size.height) 16 | ZStack(alignment: .bottom) { 17 | GIItemRarityBackground(rarity: item.rarity) 18 | 19 | GIItemView(item: item) 20 | .frame(width: dim * 0.8) 21 | 22 | Color.black.opacity(0.5) 23 | .frame(height: dim * 0.25) 24 | Text(item.name) 25 | .font(.custom("GillSans", size: dim * 0.2)) 26 | .foregroundStyle(.white) 27 | } 28 | .clipShape(RoundedRectangle(cornerRadius: 5)) 29 | } 30 | } 31 | } 32 | 33 | struct GIRewardItem_Previews: PreviewProvider { 34 | static var previews: some View { 35 | Group { 36 | GIReward(item: GIItem(itemType: .starglitter, rarity: .five, name: "50")) 37 | .background(Color.gray) 38 | .frame(width: 256, height: 256) 39 | 40 | GIReward(item: GIItem(itemType: .stardust, rarity: .two, name: "1")) 41 | .background(Color.gray) 42 | .frame(width: 256, height: 256) 43 | } 44 | .previewLayout(.sizeThatFits) 45 | 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/GenshinImpact/Mora.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Mora.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 10/21/21. 6 | // 7 | 8 | import SwiftUI 9 | import Shapes 10 | 11 | struct Mora: View { 12 | var body: some View { 13 | GeometryReader { proxy in 14 | let dim = min(proxy.size.width, proxy.size.height) 15 | ZStack { 16 | Circle() 17 | .foregroundStyle(Color("giGold")) 18 | 19 | Circle() 20 | .inset(by: dim * 0.1) 21 | .stroke(Color("giBrown"), lineWidth: dim * 0.03) 22 | 23 | Torx(sides: 3, controlPointInset: 0.35) 24 | .inset(amount: dim * 0.15) 25 | .stroke(Color("giBrown"), lineWidth: dim * 0.02) 26 | .rotationEffect(.radians(.pi)) 27 | 28 | Triquetra(strokeStyle: .init(lineWidth: dim * 0.1), centered: true) 29 | .scaleEffect(0.75) 30 | .foregroundStyle(Color("giGold")) 31 | .shadow(color: Color("giBrown"), radius: 5, x: 5, y: 5) 32 | .offset(x: 0, y: -dim * 0.08) 33 | 34 | } 35 | .overlay( 36 | LinearGradient(colors: [Color("giGold"), Color("giBronze")], startPoint: .topLeading, endPoint: .bottomTrailing) 37 | .rotationEffect(.degrees(25)) 38 | .scaleEffect(1.2) 39 | .opacity(0.6) 40 | .clipShape(Circle()) 41 | ) 42 | .frame(width: proxy.size.width, height: proxy.size.height) 43 | } 44 | } 45 | } 46 | 47 | struct Mora_Previews: PreviewProvider { 48 | static var previews: some View { 49 | 50 | ZStack { 51 | Mora().padding() 52 | } 53 | .frame(width: 512, height: 512) 54 | .background(Color.black) 55 | .previewLayout(.sizeThatFits) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Hades/ZeusBoon.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ZeusBoon.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 5/1/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct ZeusBoon: Shape { 11 | // normalized 12 | private var topRight: CGPoint { CGPoint(x: 0.7, y: 0.15) } 13 | func path(in rect: CGRect) -> Path { 14 | Path { path in 15 | path.move(to: CGPoint(x: topRight.x * rect.width, y: topRight.y * rect.height)) 16 | 17 | path.addLine(to: CGPoint(x: rect.width * 0.52, y: rect.height * 0.45)) 18 | path.addLine(to: CGPoint(x: rect.width * 0.65, y: rect.height * 0.45)) 19 | 20 | // bottom right 21 | path.addLine(to: CGPoint(x: rect.width * 0.55, y: rect.height * 0.8)) 22 | 23 | // bottom left 24 | path.addLine(to: CGPoint(x: rect.width * 0.45, y: rect.height * 0.85)) 25 | path.addLine(to: CGPoint(x: rect.width * 0.5, y: rect.height * 0.6)) 26 | 27 | path.addLine(to: CGPoint(x: rect.width * 0.25, y: rect.height * 0.62)) 28 | 29 | path.addLine(to: CGPoint(x: rect.width * 0.32, y: rect.height * 0.38)) 30 | 31 | path.addLine(to: CGPoint(x: rect.width * 0.2, y: rect.height * 0.4)) 32 | 33 | // top left 34 | path.addLine(to: CGPoint(x: rect.width * 0.25, y: rect.height * 0.1)) 35 | path.closeSubpath() 36 | 37 | } 38 | } 39 | } 40 | 41 | struct ZeusBoon_Previews: PreviewProvider { 42 | static var previews: some View { 43 | ZeusBoon() 44 | .fill(Color.orange) 45 | .frame(width: 100, height: 100) 46 | .border(.black) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/LostArk/GearHoningSim/GearHoningView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GearHoningView.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 5/19/22. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct GearHoningView: View { 11 | var body: some View { 12 | GeometryReader { proxy in 13 | ZStack { 14 | Text("Lost Ark Gear Honing Sim") 15 | } 16 | .frame(width: proxy.size.width, height: proxy.size.height) 17 | .onAppear { 18 | GearHoningCalculator.load() 19 | } 20 | } 21 | } 22 | } 23 | 24 | struct GearHoningView_Previews: PreviewProvider { 25 | static var previews: some View { 26 | GearHoningView() 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/LostArk/GearHoningSim/requiredMaterials.json: -------------------------------------------------------------------------------- 1 | { 2 | "id" : "armor_t1_r1_i320", 3 | 4 | "target" : 5 | { 6 | "gear" : "armor", 7 | "tier" : 1, 8 | "rank" : 1, 9 | "itemLevel" : 320 10 | }, 11 | 12 | "materials" : 13 | { 14 | "silver" : 1500, 15 | "gold" : 0, 16 | "shards" : { 17 | "id" : "harmony_shard", 18 | "count" : 900 19 | }, 20 | "stones" : { 21 | "id" : "destruction_stone_fragment", 22 | "count" : 150 23 | }, 24 | "leapStones" : { 25 | "id" : "harmony_leapstone", 26 | "count" : 2 27 | }, 28 | "fusionMaterials" : null 29 | }, 30 | 31 | "successRate" : 32 | { 33 | "base" : 0.3, 34 | "failureBonusPercentOfBase" : 0.1, 35 | "artisanenergyincreasepercentageperfailure" : 0.1 36 | "additional" : [ 37 | { 38 | "id" : "star_breath", 39 | "rateIncrease" : 0.05, 40 | "maximum" : 2 41 | }, 42 | { 43 | "id" : "solar_grace", // T3 44 | "rateIncrease" : 0.05, 45 | "maximum" : 2 46 | }, 47 | { 48 | "id" : "solar_blessing", // T3 49 | "rateIncrease" : 0.05, 50 | "maximum" : 2 51 | } 52 | ] 53 | } 54 | 55 | } 56 | 57 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/LostArk/LACardAnimation.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LACardAnimation.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 9/10/22. 6 | // 7 | 8 | import SwiftUI 9 | import Shapes 10 | 11 | struct LACardAnimation: View { 12 | @State private var animating = false 13 | var body: some View { 14 | GeometryReader { proxy in 15 | let dim = min(proxy.size.width, proxy.size.height) 16 | ZStack { 17 | LinearGradient(colors: [.blue, .purple], startPoint: .bottomLeading, endPoint: .topTrailing) 18 | ArcanistIcon() 19 | let vertices = ConvexPolygon(sides: 12).vertices(in: proxy.frame(in: .local)) 20 | ForEach(0.. Path { 14 | Path { path in 15 | path.move(to: CGPoint(x: rect.width * 0.01, y: rect.height * 0.01)) 16 | path.addLine(to: CGPoint(x: rect.width * 0.45, y: rect.height * 0.1)) 17 | path.addLine(to: CGPoint(x: rect.width * 0.48, y: rect.height * 0.2)) 18 | path.addLine(to: CGPoint(x: rect.width * 0.48, y: rect.height * 0.95)) 19 | path.addLine(to: CGPoint(x: rect.width * 0.46, y: rect.height * 0.9)) 20 | path.addLine(to: CGPoint(x: rect.width * 0.42, y: rect.height * 0.3)) 21 | path.addLine(to: CGPoint(x: rect.width * 0.4, y: rect.height * 0.25)) 22 | path.addLine(to: CGPoint(x: rect.width * 0.42, y: rect.height * 0.2)) 23 | path.addQuadCurve( 24 | to: CGPoint(x: rect.width * 0.415, y: rect.height * 0.15), 25 | control: CGPoint(x: rect.width * 0.42, y: rect.height * 0.16) 26 | ) 27 | path.addCurve( 28 | to: CGPoint(x: rect.width * 0.15, y: rect.height * 0.25), 29 | control1: CGPoint(x: rect.width * 0.25, y: rect.height * 0.08), 30 | control2: CGPoint(x: rect.width * 0.1, y: rect.height * 0.1) 31 | ) 32 | path.closeSubpath() 33 | } 34 | } 35 | 36 | func path(in rect: CGRect) -> Path { 37 | Path { path in 38 | path.addPath(half(in: rect)) 39 | path.addPath(half(in: rect).scale(x: -1, y: 1).path(in: rect)) 40 | } 41 | } 42 | 43 | } 44 | 45 | struct LostArkLogo_Previews: PreviewProvider { 46 | static var previews: some View { 47 | LostArkLogo() 48 | .fill() 49 | .border(Color.black) 50 | .frame(width: 256, height: 256) 51 | } 52 | } 53 | 54 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/LostArk/LostArkSelectionView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LostArkSelectionView.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 4/21/22. 6 | // 7 | 8 | import SwiftUI 9 | import Shapes 10 | 11 | struct LostArkSelectionView: View { 12 | var embossColor = Color.white 13 | 14 | var body: some View { 15 | GeometryReader { proxy in 16 | let dim = min(proxy.size.width, proxy.size.height) 17 | 18 | ZStack { 19 | LinearGradient(colors: [.purple, .black], startPoint: .top, endPoint: .bottom) 20 | 21 | Diamond() 22 | .stroke(embossColor, lineWidth: dim * 0.05) 23 | .frame(width: dim * 0.9, height: dim * 0.9) 24 | 25 | Diamond() 26 | .inset(amount: dim * 0.1) 27 | .stroke(embossColor, lineWidth: dim * 0.02) 28 | .frame(width: dim * 0.9, height: dim * 0.9) 29 | 30 | LostArkLogo() 31 | .frame(width: dim * 0.9, height: dim * 0.9) 32 | .foregroundStyle(embossColor) 33 | } 34 | .frame(width: proxy.size.width, height: proxy.size.height) 35 | } 36 | } 37 | } 38 | 39 | struct LostArkSelectionView_Previews: PreviewProvider { 40 | static var previews: some View { 41 | LostArkSelectionView() 42 | .frame(width: 256, height: 64) 43 | .previewLayout(.sizeThatFits) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/MGSV/DiamondDogsLogo/DiamondDog.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DiamondDog.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 5/25/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct DiamondDog: Shape { 11 | func path(in rect: CGRect) -> Path { 12 | Path { path in 13 | // start at snout 14 | path.move(to: CGPoint(x: 0, y: rect.height * 0.5)) 15 | path.addLine(to: CGPoint(x: rect.width * 1.5 / 5, y: rect.height * 0.3)) 16 | path.addLine(to: CGPoint(x: rect.width * 2 / 5, y: rect.height * 0.2)) 17 | path.addCurve(to: CGPoint(x: rect.width, y: rect.height * 0.5), 18 | control1: CGPoint(x: rect.width * 0.44, y: rect.height * 0.125), 19 | control2: CGPoint(x: rect.width * 0.85, y: rect.height * -0.15)) 20 | path.addLine(to: CGPoint(x: rect.width * 0.8, y: rect.height * 0.85)) 21 | path.addLine(to: CGPoint(x: rect.width * 0.5, y: rect.height * 0.9)) 22 | path.addLine(to: CGPoint(x: rect.width * 0.45, y: rect.height * 0.75)) 23 | path.addLine(to: CGPoint(x: rect.width * 0.4, y: rect.height * 0.75)) 24 | path.addLine(to: CGPoint(x: rect.width * 0.35, y: rect.height * 0.8)) 25 | path.addLine(to: CGPoint(x: rect.width * 0.15, y: rect.height * 0.8)) 26 | path.closeSubpath() 27 | 28 | 29 | } 30 | } 31 | 32 | } 33 | 34 | struct DiamondDog_Previews: PreviewProvider { 35 | static var previews: some View { 36 | DiamondDog() 37 | .stroke() 38 | .frame(width: 250, height: 200, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/) 39 | .border(Color.black) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/MGSV/DiamondDogsLogo/DiamondDogsLogo.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DiamondDogsLogo.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 5/25/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct DiamondDogsLogo: View { 11 | var body: some View { 12 | GeometryReader { proxy in 13 | let dim = min(proxy.size.width, proxy.size.height) 14 | ZStack { 15 | DiamondGem() 16 | .stroke(Color.black, lineWidth: 5)//dim / 25) 17 | .frame(width: dim, height: dim) 18 | 19 | RibbonBanner(primary: .yellow, secondary: .tlouYellow, lineWidth: dim / 50) 20 | .frame(width: dim, height: dim / 3) 21 | // FIXME: Text needs an arc 22 | // Text("Diamond Dogs".uppercased()) 23 | // .foregroundStyle(.white) 24 | // .font(.largeTitle) 25 | // .offset(x: 0, y: dim / 40) 26 | DiamondDog() 27 | .fill(Color.black) 28 | .frame(width: dim * 0.7, height: dim / 2) 29 | .offset(x: 0, y: -dim / 5) 30 | 31 | } 32 | .frame(width: proxy.size.width, height: proxy.size.height) 33 | } 34 | 35 | } 36 | } 37 | 38 | struct DiamondDogsLogo_Previews: PreviewProvider { 39 | static var previews: some View { 40 | HStack { 41 | DiamondDogsLogo() 42 | .padding() 43 | } 44 | 45 | } 46 | } 47 | 48 | /* 49 | TODO 50 | Text that can be skewed 51 | Refine Dog Picture 52 | Fix weird artifact when filling banner color 53 | Color pattern for diamond 54 | 55 | **/ 56 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/MGSV/DiamondDogsLogo/DiamondGem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DiamondGem.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 5/25/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct DiamondGem: Shape { 11 | 12 | func innerPath(in rect: CGRect) -> Path { 13 | Path { path in 14 | // perimeter 15 | path.move(to: CGPoint(x: rect.midX, y: rect.height)) 16 | path.addLine(to: CGPoint(x: rect.minX, y: rect.height * 0.25)) 17 | path.addLine(to: CGPoint(x: rect.minX + rect.width * 0.25, y: rect.minY)) 18 | path.addLine(to: CGPoint(x: rect.minX + rect.width * 0.75, y: rect.minY)) 19 | path.addLine(to: CGPoint(x: rect.maxX, y: rect.height * 0.25)) 20 | path.closeSubpath() 21 | } 22 | } 23 | 24 | func path(in rect: CGRect) -> Path { 25 | Path { path in 26 | 27 | path.addPath(innerPath(in: rect)) 28 | let newRect = rect.insetBy(dx: rect.width * 0.25, dy: 0) 29 | path.addPath(innerPath(in: newRect)) 30 | 31 | 32 | // interior lines 33 | // horizontal 34 | path.move(to: CGPoint(x: 0, y: rect.height * 0.25)) 35 | path.addLine(to: CGPoint(x: rect.width, y: rect.height * 0.25)) 36 | // vertical 37 | path.move(to: CGPoint(x: rect.width * 0.5, y: rect.height)) 38 | path.addLine(to: CGPoint(x: rect.width * 0.5, y: 0)) 39 | } 40 | } 41 | 42 | } 43 | 44 | struct DiamondGem_Previews: PreviewProvider { 45 | static var previews: some View { 46 | DiamondGem() 47 | .stroke() 48 | .frame(width: 200, height: 200) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/MGSV/DiamondDogsLogo/RibbonBanner.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RibbonBanner.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 5/27/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct RibbonBanner: View { 11 | var primary: Color = .purple 12 | var secondary: Color = .pink 13 | var lineWidth: CGFloat = 1 14 | var stroke: Color = .black 15 | 16 | var body: some View { 17 | ZStack { 18 | RibbonButt() 19 | .fill(primary) 20 | .overlay(RibbonButt().stroke(stroke, lineWidth: lineWidth)) 21 | RibbonBack() 22 | .fill(secondary) 23 | .overlay(RibbonBack().stroke(stroke, lineWidth: lineWidth)) 24 | RibbonButt() 25 | .scale(x: -1) 26 | .fill(primary) 27 | .overlay(RibbonButt().scale(x: -1).stroke(stroke, lineWidth: lineWidth)) 28 | RibbonBack() 29 | .scale(x: -1) 30 | .fill(secondary) 31 | .overlay(RibbonBack().scale(x: -1).stroke(stroke, lineWidth: lineWidth)) 32 | RibbonBelly() 33 | .fill(primary) 34 | .overlay(RibbonBelly().stroke(stroke, lineWidth: lineWidth)) 35 | } 36 | } 37 | } 38 | 39 | struct RibbonBanner_Previews: PreviewProvider { 40 | static var previews: some View { 41 | RibbonBanner(primary: .purple, secondary: .pink, lineWidth: 12) 42 | .padding() 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/MGSV/MGSVLoadingView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MGSVLoadingView.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 5/22/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct MGSVLoadingView: View { 11 | @StateObject private var viewModel = MGSVLoadingViewModel() 12 | var color: Color 13 | var body: some View { 14 | GeometryReader { proxy in 15 | let dim = min(proxy.size.width, proxy.size.height) 16 | ZStack { 17 | let gradient = AngularGradient(gradient: Gradient(colors: [color, Color.clear]), center: .center, startAngle: .degrees(0), endAngle: .degrees(270)) 18 | 19 | // Outer Arcs 20 | Circle() 21 | .trim(from: 0.0, to: 0.15) 22 | .stroke(color, lineWidth: dim * 0.02) 23 | .frame(width: dim * 0.9, height: dim * 0.9) 24 | .rotationEffect(Angle(radians: Double(viewModel.outerRotation))) 25 | 26 | Circle() 27 | .trim(from: 0.5, to: 0.65) 28 | .stroke(color, lineWidth: dim * 0.02) 29 | .frame(width: dim * 0.9, height: dim * 0.9) 30 | .rotationEffect(Angle(radians: Double(viewModel.outerRotation))) 31 | 32 | // Inner Circle 33 | Circle() 34 | .stroke(gradient, lineWidth: dim * 0.12) 35 | .frame(width: dim * 0.65, height: dim * 0.65) 36 | .rotationEffect(Angle(radians: Double(viewModel.innerRotation))) 37 | } 38 | .frame(width: proxy.size.width, height: proxy.size.height) 39 | } 40 | } 41 | } 42 | 43 | struct MGSVLoadingView_Previews: PreviewProvider { 44 | static var previews: some View { 45 | ZStack { 46 | MGSVLoadingView(color: .orange) 47 | } 48 | .background(Color.black) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/MGSV/MGSVLoadingViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MGSVLoadingViewModel.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 5/22/21. 6 | // 7 | 8 | import Foundation 9 | import SwiftUI 10 | 11 | class MGSVLoadingViewModel: ObservableObject { 12 | // ROTATIONS in RADIANS 13 | @Published private(set) var innerRotation: CGFloat = 0.0 14 | @Published private(set) var outerRotation: CGFloat = 0.0 15 | 16 | private var timer: Timer? 17 | private let timeInterval: TimeInterval = 1.0 / 30 18 | private var outerTick: Int = 0 19 | private let tickMax = 15 20 | 21 | private var deltaRotation: CGFloat { 22 | 2 * .pi * CGFloat(timeInterval) 23 | } 24 | 25 | init() { 26 | startTimer() 27 | } 28 | 29 | func startTimer() { 30 | timer = Timer.scheduledTimer(withTimeInterval: timeInterval, repeats: true) { [weak self] (timer) in 31 | guard let s = self else { return } 32 | s.updateRotations() 33 | } 34 | timer?.fire() 35 | } 36 | 37 | private func updateRotations() { 38 | outerTick += 1 39 | if outerTick % tickMax == 0 { 40 | outerRotation -= deltaRotation 41 | } 42 | innerRotation += deltaRotation 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/MGSV/MGSVMissionTextDemo.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MGSVMissionTextDemo.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 7/13/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct MGSVMissionTextDemo: View { 11 | var body: some View { 12 | GeometryReader { proxy in 13 | ZStack { 14 | Color.black.ignoresSafeArea() 15 | VStack { 16 | let text = "Mission Complete - Did the Thing. +10000000 GMP" 17 | TypewriterTextView(foreground: LinearGradient(colors: [.gray, .tlouYellow], startPoint: .leading, endPoint: .trailing), input: text) 18 | } 19 | } 20 | .frame(width: proxy.size.width, height: proxy.size.height) 21 | } 22 | } 23 | } 24 | 25 | struct MGSVMissionTextDemo_Previews: PreviewProvider { 26 | static var previews: some View { 27 | MGSVMissionTextDemo() 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/MK11/KombatKardContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // KombatKardContentView.swift 3 | // 4 | // Created by nutterfi on 3/19/21. 5 | // 6 | 7 | import SwiftUI 8 | import Shapes 9 | 10 | struct KombatKardContentView: View { 11 | @State private var cornerRadius: Float = 0 12 | var body: some View { 13 | VStack { 14 | // 0...1 15 | Slider(value: $cornerRadius) 16 | 17 | Spacer() 18 | 19 | InvertedCornerRectangle(cornerRadius: CGFloat(cornerRadius) * 1000) 20 | .stroke(Color.red, lineWidth: 5) 21 | .frame(width: 200, height: 200) 22 | 23 | Spacer() 24 | } 25 | .padding() 26 | } 27 | } 28 | 29 | struct KombatKardContentView_Previews: PreviewProvider { 30 | static var previews: some View { 31 | KombatKardContentView() 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/MK11/KombatKardView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // KombatKardView.swift 3 | // 4 | // Created by nutterfi on 3/18/21. 5 | // 6 | 7 | import SwiftUI 8 | import Shapes 9 | 10 | struct KombatKardView: View { 11 | var body: some View { 12 | ZStack { 13 | InvertedCornerRectangle(cornerRadius: 20) 14 | .stroke(Color.purple, lineWidth: 10) 15 | .frame(width: 200, height: 300) 16 | Image(systemName: "person.2.circle") 17 | .resizable() 18 | .scaledToFill() 19 | .frame(width: 200, height: 40) 20 | } 21 | } 22 | } 23 | 24 | struct KombatKardView_Previews: PreviewProvider { 25 | static var previews: some View { 26 | KombatKardView() 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/MK11/KountdownTimerDemo.swift: -------------------------------------------------------------------------------- 1 | // 2 | // KountdownTimerDemo.swift 3 | // 4 | // Created by nutterfi on 3/11/21. 5 | // 6 | 7 | import SwiftUI 8 | 9 | struct KountdownTimerDemo: View { 10 | var body: some View { 11 | VStack { 12 | KountdownTimerView() 13 | } 14 | } 15 | } 16 | 17 | struct CountdownTimerDemo_Previews: PreviewProvider { 18 | static var previews: some View { 19 | KountdownTimerDemo() 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/MK11/KountdownTimerView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // KountdownTimerView.swift 3 | // 4 | // Created by nutterfi on 3/11/21. 5 | // 6 | 7 | import SwiftUI 8 | 9 | struct KountdownTimerView: View { 10 | @StateObject private var viewModel = KountdownTimerViewModel() 11 | 12 | var body: some View { 13 | GeometryReader { proxy in 14 | let width = proxy.size.width 15 | let height = proxy.size.height 16 | let dim = min(width, height) 17 | ZStack { 18 | Circle() 19 | .stroke(Color.gray, lineWidth: 5) 20 | .frame(width: dim * 0.95, height: dim * 0.95) 21 | Circle() 22 | .frame(width: dim * 0.9, height: dim * 0.9) 23 | .foregroundStyle(.yellow) 24 | .overlay( 25 | Circle() 26 | .frame(width: dim * 0.8, height: dim * 0.8) 27 | .opacity(0.8) 28 | .blur(radius: 10) 29 | ) 30 | 31 | 32 | Text("\(viewModel.count)") 33 | .foregroundStyle(.white) 34 | .font(.system(size: dim / 2)) 35 | } 36 | .frame(width: width, height: height) 37 | } 38 | .border(Color.black) 39 | } 40 | } 41 | 42 | struct CountdownTimerView_Previews: PreviewProvider { 43 | static var previews: some View { 44 | ZStack { 45 | Color.black 46 | KountdownTimerView() 47 | .frame(width: 200, height: 200) 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/MK11/KountdownTimerViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // KountdownTimerViewModel.swift 3 | // 4 | // Created by nutterfi on 3/11/21. 5 | // 6 | 7 | import Foundation 8 | import Combine 9 | 10 | class KountdownTimerViewModel: ObservableObject { 11 | @Published private(set) var count: Int = 200 12 | 13 | private var timer: Timer? 14 | 15 | init() { 16 | startTimer() 17 | } 18 | 19 | private func startTimer() { 20 | timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [weak self] (timer) in 21 | guard let s = self else { return } 22 | s.count -= 1 23 | } 24 | timer?.fire() 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/MK11/KustomizeMenuDemo.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // KustomizeMenu 4 | // 5 | // Created by nutterfi on 4/1/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | extension Color { 11 | static var mk11Gold: Color { 12 | Color(red: 39.0/255, green: 37.0/255, blue: 11.0/255) 13 | } 14 | } 15 | 16 | struct KustomizeMenuDemo: View { 17 | var body: some View { 18 | ZStack { 19 | Color.red.ignoresSafeArea() 20 | 21 | Capsule() 22 | .glitterBorder(numberOfElements: 100, color: .mk11Gold, useGravity: false) 23 | .frame(width: 200, height: 100) 24 | } 25 | 26 | } 27 | } 28 | 29 | struct KustomizeMenuDemo_Previews: PreviewProvider { 30 | static var previews: some View { 31 | KustomizeMenuDemo() 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/MK11/MK11SelectionView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MK11SelectionView.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 4/23/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | extension Color { 11 | static var kombatYellow: Color { 12 | Color(red: 1, green: 254.0/255, blue: 144.0/255) 13 | } 14 | 15 | static var kombatBrown: Color { 16 | Color(red: 137.0/255, green: 104.0/255, blue: 64.0/255) 17 | } 18 | } 19 | 20 | struct MK11SelectionView: View { 21 | var body: some View { 22 | GeometryReader { proxy in 23 | let max = max(proxy.size.width, proxy.size.height) 24 | let min = min(proxy.size.width, proxy.size.height) 25 | 26 | ZStack { 27 | RadialGradient(gradient: Gradient(colors: [.kombatYellow, .kombatBrown]), center: .center, startRadius: max * 0.1, endRadius: max * 0.35) 28 | 29 | HStack(spacing: 0) { 30 | MK11Left() 31 | .foregroundStyle(.black) 32 | 33 | MK11Right() 34 | .foregroundStyle(.black) 35 | } 36 | .frame(width: min * 0.9 / 1.75, height: min * 0.9) 37 | } 38 | .overlay( 39 | RadialGradient(gradient: Gradient(colors: [.clear, .black]), center: .center, startRadius: max * 0.1, endRadius: max * 0.6) 40 | ) 41 | 42 | .frame(width: proxy.size.width, height: proxy.size.height) 43 | } 44 | 45 | } 46 | } 47 | 48 | struct MK11SelectionView_Previews: PreviewProvider { 49 | static var previews: some View { 50 | MK11SelectionView() 51 | .frame(width: 512, height: 128) 52 | .previewLayout(.sizeThatFits) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/MK11/MenuView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MenuView.swift 3 | // MK11-KombatKard 4 | // 5 | // Created by nutterfi on 3/18/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct MenuView: View { 11 | var body: some View { 12 | HStack(spacing: 30) { 13 | KombatKardView() 14 | .rotation3DEffect( 15 | .init(degrees: 20), 16 | axis: (x: 0.0, y: 1.0, z: 0.0)) 17 | 18 | KombatKardView() 19 | .rotation3DEffect( 20 | .init(degrees: 10), 21 | axis: (x: 0.0, y: 1.0, z: 0.0)) 22 | KombatKardView() 23 | .rotation3DEffect( 24 | .init(degrees: -10), 25 | axis: (x: 0.0, y: 1.0, z: 0.0)) 26 | KombatKardView() 27 | .rotation3DEffect( 28 | .init(degrees: -20), 29 | axis: (x: 0.0, y: 1.0, z: 0.0)) 30 | } 31 | .padding() 32 | 33 | } 34 | } 35 | 36 | struct MenuView_Previews: PreviewProvider { 37 | static var previews: some View { 38 | MenuView() 39 | .previewDevice("iPad (8th generation)") 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/MassEffect/MEConversationWheel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MEConversationWheel.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 5/11/23. 6 | // 7 | 8 | import SwiftUI 9 | import Shapes 10 | 11 | extension View { 12 | func frame(square: Double) -> some View { 13 | self.frame(width: square, height: square) 14 | } 15 | } 16 | 17 | // IDEA! Use this as an overlay for Channel Polls! 18 | struct MEConversationWheel: View { 19 | 20 | var circlePattern: some View { 21 | Circle() 22 | .inset(by: 25) 23 | .stroke(lineWidth: 50) 24 | .subtracting( 25 | StarPolygon(points: 6, density: 3) 26 | .stroke(lineWidth: 10) 27 | ) 28 | .foregroundStyle(Color.jfoCopper) 29 | .frame(square: 256) 30 | } 31 | 32 | var body: some View { 33 | ZStack { 34 | LinearGradient(colors: [.blue, .purple], startPoint: .topLeading, endPoint: .bottomTrailing) 35 | circlePattern 36 | .rotationEffect(.radians(.pi / 3)) 37 | .background( 38 | Circle() 39 | .inset(by: 25) 40 | .stroke(lineWidth: 60) 41 | .offset(y: 2) 42 | ) 43 | .rotation3DEffect(.degrees(30), axis: (x: 1, y: 0, z: 0)) 44 | 45 | } 46 | .scaleEffect(2) 47 | .padding() 48 | } 49 | } 50 | 51 | struct MEConversationWheel_Previews: PreviewProvider { 52 | static var previews: some View { 53 | MEConversationWheel() 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Motion.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Motion.swift 3 | // 4 | // Created by nutterfi on 2/27/21. 5 | // 6 | 7 | import SwiftUI 8 | 9 | typealias VelocityProfile = (Double) -> Double 10 | 11 | struct Velocity { 12 | static var dampedOscillator: VelocityProfile = { t in 13 | cos(t) * exp(t) 14 | } 15 | } 16 | 17 | struct Motion: ViewModifier { 18 | @State var time: Double = 0.0 19 | var duration: Double 20 | var useGravity: Bool 21 | var velocity: Double = Double.random(in: 0...10) 22 | var emissionAngle: Angle = .zero 23 | 24 | func body(content: Content) -> some View { 25 | let animation = Animation.linear(duration: duration) 26 | .repeatForever(autoreverses: false) 27 | .delay(Double.random(in: 0.. Double) // what is this? 14 | var time: Double // seconds 15 | 16 | private let g = 9.81 // m/s^2 17 | 18 | var animatableData: Double { 19 | get { time } 20 | set { time = newValue } 21 | } 22 | 23 | func effectValue(size: CGSize) -> ProjectionTransform { 24 | let gravityOffset: Double = useGravity ? -0.5 * g * time * time : 0 25 | let dx = velocity * time * cos(emissionAngle.radians) //* v(time) 26 | let dy = velocity * time * sin(emissionAngle.radians) + gravityOffset // * v(time) 27 | 28 | let translation = CGAffineTransform(translationX: CGFloat(dx), y: CGFloat(-dy)) 29 | return ProjectionTransform(translation) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/NoMansSky/NMSCraftingMenuItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NMSCraftingMenuItem.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 6/23/22. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct NMSCraftingMenuItem: View { 11 | var title: String = "Breakfast foods are best foods" 12 | var image: String 13 | var color: Color 14 | var body: some View { 15 | GeometryReader { proxy in 16 | let dim = min(proxy.size.width, proxy.size.height) 17 | ZStack { 18 | VStack(spacing: 0) { 19 | MarqueeText(text: title) 20 | .background(Color.white) 21 | .frame(width: dim, height: 50) 22 | color 23 | .overlay( 24 | Image(systemName: image) 25 | .resizable() 26 | .scaledToFit() 27 | .padding() 28 | ) 29 | } 30 | } 31 | .border(Color.white, width: 10) 32 | .frame(width: proxy.size.width, height: proxy.size.height) 33 | } 34 | } 35 | } 36 | 37 | struct NMSCraftingMenuItem_Previews: PreviewProvider { 38 | static var previews: some View { 39 | HStack(spacing: 20) { 40 | NMSCraftingMenuItem(title: "Four score and seven years ago", image: "pencil", color: .red) 41 | .frame(width: 200, height: 300) 42 | 43 | NMSCraftingMenuItem(title: "I want to ride my bicycle", image: "speedometer", color: .blue) 44 | .frame(width: 200, height: 300) 45 | 46 | 47 | NMSCraftingMenuItem(image: "ladybug", color: .green) 48 | .frame(width: 200, height: 300) 49 | } 50 | .padding() 51 | .background(LinearGradient(colors: [.purple, .blue], startPoint: .topLeading, endPoint: .bottomTrailing)) 52 | .previewLayout(.sizeThatFits) 53 | 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Ori/OriSkill.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OriSkill.swift 3 | // Game-UI-Inspirations (iOS) 4 | // 5 | // Created by nutterfi on 6/16/22. 6 | // 7 | 8 | import Foundation 9 | 10 | enum OriSkill: Int, Identifiable, CaseIterable, CustomStringConvertible { 11 | case spiritFlame 12 | case wallJump 13 | case chargeFlame 14 | case doubleJump 15 | case bash 16 | case stomp 17 | case locked7 18 | case locked8 19 | case locked9 20 | case locked10 21 | case locked11 22 | 23 | var id: Int { self.rawValue } 24 | 25 | var description: String { 26 | switch self { 27 | case .spiritFlame: 28 | return "Sprit Flame" 29 | case .wallJump: 30 | return "Wall Jump" 31 | case .chargeFlame: 32 | return "Charge Flame" 33 | case .doubleJump: 34 | return "Double Jump" 35 | case .bash: 36 | return "Bash" 37 | case .stomp: 38 | return "Stomp" 39 | case .locked7, .locked8, .locked9, .locked10, .locked11: 40 | return "Locked" 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Ori/OriSkillTreeDemo.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OriSkillTreeDemo.swift 3 | // Game-UI-Inspirations (iOS) 4 | // 5 | // Created by nutterfi on 6/16/22. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct OriSkillTreeDemo: View { 11 | var body: some View { 12 | GeometryReader { proxy in 13 | let dim = min(proxy.size.width, proxy.size.height) 14 | ZStack { 15 | Color.black.ignoresSafeArea() 16 | LinearGradient(colors: [.black, .green, .blue], startPoint: .topLeading, endPoint: .bottomTrailing) 17 | .ignoresSafeArea() 18 | .opacity(0.35) 19 | 20 | OriSkillWheel() 21 | .frame(width: dim * 0.95, height: dim * 0.95) 22 | 23 | } 24 | .frame(width: proxy.size.width, height: proxy.size.height) 25 | } 26 | } 27 | } 28 | 29 | struct OriSkillTreeDemo_Previews: PreviewProvider { 30 | static var previews: some View { 31 | OriSkillTreeDemo() 32 | .previewInterfaceOrientation(.landscapeLeft) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Overwatch/OW2/OW2SelectionView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OW2SelectionView.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 11/15/22. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct OW2SelectionView: View { 11 | var body: some View { 12 | GeometryReader { proxy in 13 | let dim = min(proxy.size.width, proxy.size.height) 14 | ZStack { 15 | Color.ow2BackgroundBlue 16 | HStack { 17 | OverwatchIcon(primary: Color.ow2Orange, secondary: Color.white) 18 | .frame(width: dim * 0.6) 19 | Color.ow2Orange 20 | .cornerRadius(12) 21 | .overlay( 22 | Text("2") 23 | .font(.system(size: 60)) 24 | .minimumScaleFactor(0.5) 25 | .foregroundStyle(Color.white) 26 | ) 27 | .frame(width: dim * 0.25, height: dim * 0.6) 28 | 29 | } 30 | } 31 | .frame(width: proxy.size.width, height: proxy.size.height) 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Overwatch/OWUltimateMeterBorder.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OWUltimateMeterBorder.swift 3 | // OWUltimateMeterBorder 4 | // 5 | // Created by nutterfi on 7/21/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct OWUltimateMeterBorder: View { 11 | var isReady: Bool = false 12 | 13 | var body: some View { 14 | GeometryReader { proxy in 15 | let dim = min(proxy.size.width, proxy.size.height) 16 | ZStack { 17 | Circle() 18 | .trim(from: 0, to: 0.94) 19 | .rotation(.init(degrees: 101)) 20 | .stroke(Color.gray, lineWidth: 2) 21 | .frame(width: dim * 0.8, height: dim * 0.8) 22 | Circle() 23 | .stroke(Color.gray, lineWidth: 2) 24 | .frame(width: dim * 0.15, height: dim * 0.15) 25 | .offset(x: 0, y: dim * 0.4) 26 | Text("Q") 27 | .font(.custom("AvenirNextCondensed-MediumItalic", size: dim / 9)) 28 | .foregroundStyle(Color.gray) 29 | .offset(x: 0, y: dim * 0.4) 30 | } 31 | .frame(width: proxy.size.width, height: proxy.size.height) 32 | } 33 | } 34 | } 35 | 36 | struct OWUltimateMeterBorder_Previews: PreviewProvider { 37 | static var previews: some View { 38 | OWUltimateMeterBorder() 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Overwatch/OWUltimateMeterDemo.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OWUltimateMeterDemo.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 7/10/21. 6 | // 7 | 8 | import SwiftUI 9 | import Shapes 10 | 11 | struct OWUltimateMeterDemo: View { 12 | @State private var progress: Float = 0 13 | 14 | var body: some View { 15 | GeometryReader { proxy in 16 | let dim = min(proxy.size.width, proxy.size.height) 17 | ZStack { 18 | Color.black.ignoresSafeArea() 19 | Group { 20 | LinearGradient(colors: [.red, .yellow], startPoint: .topTrailing, endPoint: .bottom) 21 | .ignoresSafeArea() 22 | 23 | RadialGradient(gradient: Gradient(colors: [.white, .black]), center: .bottom, startRadius: dim / 4, endRadius: dim) 24 | .ignoresSafeArea() 25 | .opacity(0.4) 26 | 27 | StrokeStyledCircle( 28 | numberOfSegments: 20, 29 | lineWidthRatio: 0.5) 30 | .foregroundStyle(.blue) 31 | .scaleEffect(2.5) 32 | } 33 | .opacity(0.1) 34 | 35 | VStack() { 36 | Slider(value:$progress) 37 | Spacer() 38 | OWUltimateMeter(progress: $progress) 39 | .frame(width: dim * 0.8, height: dim * 0.8) 40 | Spacer() 41 | } 42 | .padding() 43 | 44 | } 45 | .frame(width: proxy.size.width, height: proxy.size.height) 46 | } 47 | } 48 | } 49 | 50 | struct OWUltimateMeterDemo_Previews: PreviewProvider { 51 | static var previews: some View { 52 | OWUltimateMeterDemo() 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Overwatch/OWUltimateReadyView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OWUltimateReadyView.swift 3 | // OWUltimateReadyView 4 | // 5 | // Created by nutterfi on 7/20/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct OWUltimateReadyView: View { 11 | var body: some View { 12 | GeometryReader { proxy in 13 | let dim = min(proxy.size.width, proxy.size.height) 14 | ZStack { 15 | Circle() 16 | .foregroundStyle(.black.opacity(0.3)) 17 | .overlay( 18 | Circle() 19 | .stroke(Color.white, lineWidth: dim * 0.05) 20 | ) 21 | .frame(width: dim * 0.5, height: dim * 0.5) 22 | 23 | Circle() 24 | .stroke(Color(red: 56/255, green: 230/255, blue: 246/255)) 25 | .frame(width: dim * 0.6, height: dim * 0.6) 26 | 27 | Image(systemName: "swift") 28 | .resizable() 29 | .scaledToFit() 30 | .foregroundStyle(.white) 31 | .frame(width: dim * 0.3, height: dim * 0.3) 32 | 33 | OWUltimateMeterBorder() 34 | .frame(width: dim, height: dim) 35 | 36 | } 37 | .frame(width: proxy.size.width, height: proxy.size.height) 38 | } 39 | } 40 | } 41 | 42 | struct OWUltimateReadyView_Previews: PreviewProvider { 43 | static var previews: some View { 44 | OWUltimateReadyView() 45 | .background(Color.black) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Overwatch/OverwatchLogoDemo.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OverwatchLogoDemo.swift 3 | // Game-UI-Inspirations (iOS) 4 | // 5 | // Created by nutterfi on 6/29/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct OverwatchLogoDemo: View { 11 | var body: some View { 12 | VStack { 13 | OverwatchIcon(primary: .white, secondary: .orange) 14 | 15 | let gradient = LinearGradient(colors: [.tlouYellow, .purple], startPoint: .top, endPoint: .bottom) 16 | 17 | OverwatchIcon(primary: gradient, secondary: gradient) 18 | 19 | HStack { 20 | OverwatchIcon(primary: Color.tlouYellow, secondary: Color.tlouYellow) 21 | OverwatchIcon(primary: .blue, secondary: .orange) 22 | OverwatchIcon(primary: .image(Image(systemName: "gear")) , secondary: .orange) 23 | } 24 | .padding() 25 | 26 | } 27 | .padding() 28 | .background(Color.black) 29 | } 30 | } 31 | 32 | struct OverwatchLogoDemo_Previews: PreviewProvider { 33 | static var previews: some View { 34 | OverwatchLogoDemo() 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/PapersPlease/PapersPleaseSettingsIcon.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PapersPleaseSettingsIcon.swift 3 | // Game-UI-Inspirations (iOS) 4 | // 5 | // Created by nutterfi on 9/17/22. 6 | // 7 | 8 | import SwiftUI 9 | import Shapes 10 | 11 | struct PapersPleaseSettingsIcon: View { 12 | var body: some View { 13 | ZStack { 14 | Color.black 15 | StrokeStyledPolygon( 16 | sides: 12, 17 | dashPatternCount: 48, 18 | lineWidthRatio: 0.03 19 | ) 20 | .rotationEffect(.degrees(15)) 21 | Image(systemName: "wrench") 22 | .resizable() 23 | .scaledToFit() 24 | .scaleEffect(0.5) 25 | } 26 | .foregroundStyle(Color.porterlightGreen) 27 | } 28 | } 29 | 30 | struct PapersPleaseSettingsIcon_Previews: PreviewProvider { 31 | static var previews: some View { 32 | PapersPleaseSettingsIcon() 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Persona5/P5AnimatedStarParty.swift: -------------------------------------------------------------------------------- 1 | // 2 | // P5AnimatedStarParty.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 1/15/22. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct P5AnimatedStarParty: View { 11 | var primary: Color = .black 12 | var secondary: Color = .white 13 | var starCount: Int = 30 14 | var body: some View { 15 | GeometryReader { proxy in 16 | let dim = min(proxy.size.width, proxy.size.height) 17 | ZStack { 18 | secondary.ignoresSafeArea() 19 | ForEach(0.. (Color, Color) 12 | } 13 | 14 | extension RDR2Badgeable { 15 | func colors(for rank: String) -> (Color, Color) { 16 | switch rank { 17 | case RDR2Award.Rank.gold: 18 | return (Color("rdr2Gold"), Color("rdr2Rust")) 19 | case RDR2Award.Rank.teal: 20 | return (Color("rdr2Teal"), Color("rdr2Black")) 21 | case RDR2Award.Rank.bronze: 22 | return (Color("rdr2Bronze"), Color("rdr2Black")) 23 | case RDR2Award.Rank.teal: 24 | return (Color("rdr2Teal"), Color("rdr2Black")) 25 | case RDR2Award.Rank.gray: 26 | return (Color("rdr2Gray-1"), Color("rdr2Black")) 27 | default: 28 | return (.white, .black) 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/RDR2/RDR2HUD/RDR2Core/RDR2CoreModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RDR2CoreModel.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 11/9/21. 6 | // 7 | 8 | import Foundation 9 | 10 | struct RDR2CoreModel { 11 | 12 | enum CoreType { 13 | case health 14 | case stamina 15 | case deadeye 16 | } 17 | 18 | var coreLevel: Float 19 | var barLevel: Float 20 | var type: CoreType 21 | } 22 | 23 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/RDR2/RDR2HUD/RDR2Core/RDR2HUDCoreMenu.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RDR2HUDCoreMenu.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 7/23/22. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct RDR2HUDCoreMenu: View { 11 | @StateObject private var viewModel = RDR2HUDCoreViewModel() 12 | var body: some View { 13 | GeometryReader { proxy in 14 | let dim = min(proxy.size.width, proxy.size.height) 15 | ZStack { 16 | Group { 17 | RDR2HUDCoreView(model: viewModel.deadeyeCore) 18 | .angularOffset(magnitude: dim * 0.4, angle: .degrees(270)) 19 | 20 | RDR2HUDCoreView(model: viewModel.healthCore) 21 | .angularOffset(magnitude: dim * 0.41, angle: .degrees(248)) 22 | 23 | RDR2HUDCoreView(model: viewModel.staminaCore) 24 | .angularOffset(magnitude: dim * 0.44, angle: .degrees(226)) 25 | } 26 | .frame(width: dim * 0.13, height: dim * 0.2) 27 | } 28 | .frame(width: proxy.size.width, height: proxy.size.height) 29 | } 30 | 31 | } 32 | } 33 | 34 | struct RDR2HUDCoreMenu_Previews: PreviewProvider { 35 | static var previews: some View { 36 | RDR2HUDCoreMenu() 37 | .previewLayout(.sizeThatFits) 38 | .frame(width: 512, height: 512) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/RDR2/RDR2HUD/RDR2Core/RDR2HUDCoreViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RDR2HUDCoreViewModel.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 11/9/21. 6 | // 7 | 8 | import Foundation 9 | 10 | class RDR2HUDCoreViewModel: ObservableObject { 11 | @Published private(set) var healthCore: RDR2CoreModel 12 | @Published private(set) var staminaCore: RDR2CoreModel 13 | @Published private(set) var deadeyeCore: RDR2CoreModel 14 | 15 | init() { 16 | healthCore = RDR2CoreModel(coreLevel: 0.5, barLevel: 0.25, type: .health) 17 | staminaCore = RDR2CoreModel(coreLevel: 0.2, barLevel: 0.1, type: .stamina) 18 | deadeyeCore = RDR2CoreModel(coreLevel: 0.0, barLevel: 0.75, type: .deadeye) 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/RDR2/RDR2HUD/RDR2HUD.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RDR2HUD.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 11/9/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct RDR2HUD: View { 11 | var mapRotation: Angle = .zero 12 | var body: some View { 13 | GeometryReader { proxy in 14 | let dim = min(proxy.size.width, proxy.size.height) 15 | ZStack { 16 | RDR2MinimapView() 17 | .frame(width: dim * 0.75, height: dim * 0.75) 18 | .rotationEffect(mapRotation) 19 | .offset(x: 0, y: dim * 0.08) 20 | RDR2HUDCoreMenu() 21 | } 22 | .frame(width: proxy.size.width, height: proxy.size.height) 23 | } 24 | } 25 | } 26 | 27 | struct RDR2HUD_Previews: PreviewProvider { 28 | static var previews: some View { 29 | ZStack { 30 | LinearGradient(colors: [.hadesArtemisGreen, .kombatBrown], startPoint: .topTrailing, endPoint: .bottom) 31 | .ignoresSafeArea() 32 | 33 | RDR2HUD(mapRotation: Angle(degrees: 40) 34 | ) 35 | .frame(width: 512, height: 512) 36 | .previewLayout(.sizeThatFits) 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/RDR2/RDR2MinimapDemo.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RDR2MinimapDemo.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 3/13/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct RDR2MinimapDemo: View { 11 | @State private var rotation: CGFloat = 0 12 | var body: some View { 13 | GeometryReader { proxy in 14 | let dim = min(proxy.size.width, proxy.size.height) 15 | ZStack { 16 | LinearGradient(colors: [.hadesArtemisGreen, .kombatBrown], startPoint: .topTrailing, endPoint: .bottom) 17 | .ignoresSafeArea() 18 | 19 | VStack() { 20 | Slider(value: $rotation, in: 0...360) 21 | Spacer() 22 | RDR2HUD(mapRotation: .degrees(rotation)) 23 | .frame(width: dim * 0.8, height: dim * 0.8) 24 | Spacer() 25 | } 26 | .padding() 27 | } 28 | .frame(width: proxy.size.width, height: proxy.size.height) 29 | } 30 | 31 | } 32 | } 33 | 34 | struct MinimapDemo_Previews: PreviewProvider { 35 | static var previews: some View { 36 | RDR2MinimapDemo() 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/RDR2/RDR2MinimapViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RDR2MinimapViewModel.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 3/13/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | class RDR2MinimapViewModel: ObservableObject { 11 | @Published var rotation: Angle = .zero 12 | @Published var playerPosition: CGPoint = .zero 13 | @Published var isRidingHorse: Bool = false 14 | @Published var entities: [Entity] = [] 15 | 16 | static var demo: RDR2MinimapViewModel { 17 | let viewModel = RDR2MinimapViewModel() 18 | viewModel.entities = [NPC(position: CGPoint(x: 30, y: 20), type: .enemy)] 19 | return viewModel 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/RDR2/RDR2RevolverLoadingAnimation.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RDR2RevolverLoadingAnimation.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 10/23/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct RDR2RevolverLoadingView: View { 11 | var body: some View { 12 | GeometryReader { proxy in 13 | let dim = min(proxy.size.width, proxy.size.height) 14 | ZStack(alignment: .bottomTrailing) { 15 | Color.black.ignoresSafeArea() 16 | RDR2RevolverLoadingAnimation() 17 | .foregroundStyle(Color.white) 18 | .frame(width: dim / 5, height: dim / 5) 19 | } 20 | .frame(width: proxy.size.width, height: proxy.size.height) 21 | } 22 | } 23 | } 24 | 25 | struct RDR2RevolverLoadingAnimation: View { 26 | @State private var isAnimating = false 27 | var body: some View { 28 | RDR2Revolver() 29 | .rotationEffect(isAnimating ? .radians(.pi / 4) : .zero) 30 | .onAppear { 31 | withAnimation(Animation.spring().delay(0.25).repeatForever(autoreverses: false)) { 32 | isAnimating.toggle() 33 | } 34 | } 35 | } 36 | } 37 | 38 | struct RDR2RevolverLoadingAnimation_Previews: PreviewProvider { 39 | static var previews: some View { 40 | RDR2RevolverLoadingView() 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Reusable/CircularText.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CircularText.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 12/28/21. 6 | // 7 | 8 | import SwiftUI 9 | import Shapes 10 | 11 | public struct CircularText: View { 12 | public var text: String 13 | public var size: CGFloat 14 | 15 | public init(text: String, size: CGFloat = 24) { 16 | self.text = text 17 | self.size = size 18 | } 19 | public var body: some View { 20 | GeometryReader { proxy in 21 | let dim = min(proxy.size.width, proxy.size.height) 22 | let n = text.count 23 | let rect = proxy.frame(in: .local) 24 | let vertices = ConvexPolygon(sides: n) 25 | .vertices(in: rect) 26 | 27 | ZStack { 28 | ForEach(0.. Path { 15 | Path { path in 16 | lineSegments.forEach { first, second in 17 | var p = Path() 18 | p.move(to: CGPoint(x: first.x * rect.width, y: first.y * rect.height)) 19 | p.addLine(to: CGPoint(x: second.x * rect.width, y: second.y * rect.height)) 20 | p.closeSubpath() 21 | path.addPath(p) 22 | } 23 | } 24 | } 25 | 26 | } 27 | 28 | struct TreeBranch_Previews: PreviewProvider { 29 | static var previews: some View { 30 | LineSegmentGroup(lineSegments: [ 31 | (CGPoint(x: 0, y: 0.25), CGPoint(x: 0.25, y: 0.25)), 32 | (CGPoint(x: 0.25, y: 0.5), CGPoint(x: 0.5, y: 0.5)), 33 | (CGPoint(x: 0.5, y: 0.75), CGPoint(x: 0.75, y: 0.75)), 34 | (CGPoint(x: 0.75, y: 1), CGPoint(x: 1, y: 1)), 35 | ] 36 | ) 37 | .stroke(lineWidth: 10) 38 | .frame(width: 256, height: 256) 39 | .previewLayout(.sizeThatFits) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Reusable/MaskedProgressBar.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MaskedProgressBar.swift 3 | // MaskedProgressBar 4 | // 5 | // Created by nutterfi on 2/15/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct MaskedProgressBar: View { 11 | var progress: Float 12 | var backView: T 13 | var frontView: U 14 | 15 | var mask: V 16 | 17 | var body: some View { 18 | ProgressBar(progress: progress, backView: backView, frontView: frontView) 19 | .mask(mask) 20 | } 21 | } 22 | 23 | struct MaskedProgressBar_Previews: PreviewProvider { 24 | static var previews: some View { 25 | MaskedProgressBar(progress: 0.5, backView: Color.yellow, frontView: Color.blue, mask: Capsule()) 26 | .previewLayout(.sizeThatFits) 27 | .frame(width: 200, height: 100) 28 | .padding() 29 | 30 | MaskedProgressBar(progress: 0.4, backView: Color.yellow, frontView: Color.blue, 31 | mask: HStack { 32 | Text("Hello") 33 | Circle() 34 | Text("World") 35 | Rectangle() 36 | } 37 | ) 38 | .previewLayout(.sizeThatFits) 39 | .frame(height: 100) 40 | .padding() 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Reusable/PersonProfile.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PersonProfile.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 10/19/21. 6 | // 7 | 8 | import SwiftUI 9 | import Shapes 10 | 11 | struct PersonProfile: View { 12 | var body: some View { 13 | GeometryReader { proxy in 14 | let dim = min(proxy.size.width, proxy.size.height) 15 | ZStack() { 16 | Egg(apexAngle: 90) 17 | .scaledToFit() 18 | .rotationEffect(.radians(.pi)) 19 | .frame(width: dim * 0.5) 20 | .offset(x: 0, y: -dim * 0.1) 21 | 22 | VStack () { 23 | Spacer() 24 | UnevenRoundedRectangle(cornerRadii: RectangleCornerRadii(topLeading: dim * 0.25, topTrailing: dim * 0.25)) 25 | .frame(width: dim, height: proxy.size.height * 0.3) 26 | } 27 | 28 | } 29 | .frame(width: proxy.size.width, height: proxy.size.height) 30 | } 31 | } 32 | } 33 | 34 | struct PersonProfile_Previews: PreviewProvider { 35 | static var previews: some View { 36 | Group { 37 | PersonProfile() 38 | .frame(width: 512, height: 128) 39 | 40 | PersonProfile() 41 | .frame(width: 256, height: 256) 42 | 43 | PersonProfile() 44 | .frame(width: 128, height: 150) 45 | } 46 | .previewLayout(.sizeThatFits) 47 | .border(Color.black) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Reusable/ProgressBar.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProgressBar.swift 3 | // MaskedProgressBar 4 | // 5 | // Created by nutterfi on 2/15/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct ProgressBar: View { 11 | var progress: Float 12 | var backView: T 13 | var frontView: U 14 | 15 | var body: some View { 16 | GeometryReader { gr in 17 | backView 18 | .overlay( 19 | frontView 20 | .frame(width: gr.size.width * CGFloat(progress)) 21 | , 22 | alignment: .leading 23 | ) 24 | } 25 | } 26 | } 27 | 28 | struct ProgressBar_Previews: PreviewProvider { 29 | static var previews: some View { 30 | Group { 31 | ProgressBar(progress: 0.25, backView: Color.gray, frontView: Color.green) 32 | .previewLayout(.sizeThatFits) 33 | .frame(width: 200, height: 10) 34 | 35 | ProgressBar(progress: 0.65, backView: Color.red, frontView: LinearGradient(gradient: Gradient(colors: [.white, .yellow]), startPoint: .leading, endPoint: .trailing)) 36 | .previewLayout(.sizeThatFits) 37 | .frame(width: 100, height: 25) 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Reusable/ProgressBarWithDelta.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProgressBarWithDelta.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 5/26/22. 6 | // 7 | 8 | import SwiftUI 9 | 10 | // 1. delta is introduced 11 | // 2. immediately recalculate progress to be original +/- delta 12 | // 3. draw new progress and delta side-by-side 13 | // 4. optionally animate delta growing or shrinking 14 | 15 | struct ProgressBarWithDelta: View { 16 | var progress: Double 17 | var delta: Double 18 | var backView: T 19 | var progressView: U 20 | var deltaView: V 21 | var body: some View { 22 | GeometryReader { proxy in 23 | 24 | let boundedProgress = min(max(0, progress), 1) 25 | let boundedDelta = 1 - boundedProgress 26 | 27 | backView 28 | .overlay( 29 | HStack(spacing: 0) { 30 | progressView 31 | .frame(width: proxy.size.width * CGFloat(boundedProgress)) 32 | deltaView 33 | .frame(width: proxy.size.width * CGFloat(delta > boundedDelta ? boundedDelta : delta)) 34 | } 35 | , 36 | alignment: .leading 37 | ) 38 | } 39 | } 40 | } 41 | 42 | struct ProgressBarWithDelta_Previews: PreviewProvider { 43 | static var previews: some View { 44 | ProgressBarWithDelta( 45 | progress: 2, 46 | delta: 0.15, 47 | backView: Color.gray, 48 | progressView: Color.yellow, 49 | deltaView: Color.orange 50 | ) 51 | .previewLayout(.sizeThatFits) 52 | .frame(width: 350, height: 50) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Reusable/RandomIndexedTiledShape.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | public struct RandomIndexedTiledShape: Shape { 4 | public var shape: Content 5 | public var rows: Int 6 | public var columns: Int 7 | public var unpaintedIndices: [CGPoint] 8 | 9 | public init(shape: Content, rows: Int = 1, columns: Int = 1, unpaintedIndices: [CGPoint] = []) { 10 | self.shape = shape 11 | self.rows = rows 12 | self.columns = columns 13 | self.unpaintedIndices = unpaintedIndices 14 | } 15 | 16 | public func path(in rect: CGRect) -> Path { 17 | Path { path in 18 | let width = rect.width / CGFloat(columns) 19 | let height = rect.height / CGFloat(rows) 20 | for r in 0.. = 0...1 13 | 14 | var minimumValue: String { 15 | String(format: "%.02f", range.lowerBound) 16 | } 17 | 18 | var maximumValue: String { 19 | String(format: "%.02f", range.upperBound) 20 | } 21 | 22 | var body: some View { 23 | VStack(spacing: 4) { 24 | HStack { 25 | Text(label) 26 | Spacer() 27 | Text(String(format: "%.02f", value)) 28 | .monospacedDigit() 29 | } 30 | 31 | Slider( 32 | value: $value, 33 | in: range, 34 | minimumValueLabel: Text(minimumValue).font(.footnote), 35 | maximumValueLabel: Text(maximumValue).font(.footnote) 36 | ) { 37 | Text("whatever") 38 | } 39 | 40 | } 41 | .foregroundStyle(.secondary) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Reusable/TestingTiledImageView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TestingTiledImageView.swift 3 | // Game-UI-Inspirations (iOS) 4 | // 5 | // Created by nutterfi on 7/3/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | // We need the "perfect" SF Symbol OR 11 | // we draw our own image which consists of 12 | // 1. define an area 100 x 100 13 | // 2. draw a circle using a CG context 14 | // 3. store as a UIImage or CGImage 15 | // 4. initialize Image with that image 16 | // 5. tile THAT 17 | 18 | struct TestingTiledImageView: View { 19 | @State private var isAnimating = false 20 | var body: some View { 21 | let image = Image(systemName: isAnimating ? "dot.squareshape.fill" : "1.circle") 22 | .resizable() 23 | 24 | GeometryReader { proxy in 25 | let dim = min(proxy.size.width, proxy.size.height) 26 | ZStack { 27 | Color.yellow.opacity(0.7) 28 | 29 | .mask( 30 | Rectangle() 31 | .fill(.image(image.renderingMode(.template), sourceRect: CGRect(x: 0, y: 0, width: 1, height: 1), scale: 4)) 32 | ) 33 | .frame(width: dim, height: dim) 34 | 35 | } 36 | .frame(width: proxy.size.width, height: proxy.size.height) 37 | .background(Color.red) 38 | 39 | .onAppear { 40 | isAnimating = true 41 | } 42 | } 43 | .animation(Animation.easeInOut(duration: 2), value: isAnimating) 44 | } 45 | } 46 | 47 | struct TestingTiledImageView_Previews: PreviewProvider { 48 | static var previews: some View { 49 | TestingTiledImageView() 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Reusable/TextEffectViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TypewriterTextViewModel.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 7/13/21. 6 | // 7 | 8 | import Foundation 9 | 10 | class TextEffectViewModel: ObservableObject { 11 | 12 | @Published var value: Double = 0 13 | 14 | private let timeInterval: TimeInterval = 0.017 15 | private var timer: Timer? 16 | 17 | func start() { 18 | startTimer() 19 | } 20 | 21 | deinit { 22 | timer?.invalidate() 23 | } 24 | 25 | private func startTimer() { 26 | timer = Timer.scheduledTimer(withTimeInterval: timeInterval, repeats: true) { [weak self] (timer) in 27 | guard let s = self else { return } 28 | s.updateValue() 29 | } 30 | timer?.fire() 31 | } 32 | 33 | private func updateValue() { 34 | value += timeInterval 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Reusable/TextPath.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TextPath.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 2/1/22. 6 | // 7 | 8 | import SwiftUI 9 | import Shapes 10 | 11 | struct TextPath: View { 12 | public var text: String 13 | public var size: CGFloat 14 | public var shape: S 15 | 16 | public init(text: String, shape: S, size: CGFloat = 24) { 17 | self.text = text 18 | self.size = size 19 | self.shape = shape 20 | } 21 | 22 | var body: some View { 23 | GeometryReader { proxy in 24 | let dim = min(proxy.size.width, proxy.size.height) 25 | let rect = proxy.frame(in: .local) 26 | ZStack { 27 | let path = shape.path(in: rect) 28 | let points = path.equallySpacedPoints(count: text.count) 29 | 30 | ForEach(0..: View { 11 | var foreground: T 12 | var input: String 13 | 14 | @StateObject private var viewModel = TypewriterTextViewModel() 15 | var body: some View { 16 | GeometryReader { proxy in 17 | ZStack { 18 | HStack { 19 | Text(viewModel.text) 20 | .font(.largeTitle) 21 | .foregroundStyle(foreground) 22 | Spacer() 23 | } 24 | .padding() 25 | } 26 | .frame(width: proxy.size.width, height: proxy.size.height) 27 | } 28 | .onAppear { 29 | viewModel.input = input 30 | viewModel.start() 31 | } 32 | } 33 | } 34 | 35 | struct TypewriterTextView_Previews: PreviewProvider { 36 | static var previews: some View { 37 | TypewriterTextView(foreground: Color.purple, input: "Hello, World!") 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Reusable/TypewriterTextViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TypewriterTextViewModel.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 7/13/21. 6 | // 7 | 8 | import Foundation 9 | 10 | class TypewriterTextViewModel: ObservableObject { 11 | var input: String = "" 12 | 13 | @Published var text: String = "" 14 | @Published var index: Int = 0 15 | 16 | private let timeInterval: TimeInterval = 0.1 17 | private var timer: Timer? 18 | 19 | init(input: String = "") { 20 | self.input = input 21 | } 22 | 23 | func start() { 24 | index = 0 25 | startTimer() 26 | } 27 | 28 | private func startTimer() { 29 | timer = Timer.scheduledTimer(withTimeInterval: timeInterval, repeats: true) { [weak self] (timer) in 30 | guard let s = self else { return } 31 | s.updateIndex() 32 | } 33 | timer?.fire() 34 | } 35 | 36 | private func updateIndex() { 37 | 38 | index += 1 39 | if index >= input.count { 40 | timer?.invalidate() 41 | DispatchQueue.main.asyncAfter(deadline: .now() + 5) { 42 | self.text = "" 43 | } 44 | } 45 | let mySubstring = input.prefix(index) 46 | text = String(mySubstring) 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Reusable/ViewModifiers/Pixellate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Pixellate.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 5/28/22. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct Pixellate: ViewModifier { 11 | @State private var context = CIContext() 12 | @State private var filter = CIFilter.pixellate() 13 | @State private var result: Image? 14 | 15 | func body(content: Content) -> some View { 16 | AnyView(content) 17 | .overlay( 18 | VStack { 19 | if let result { 20 | result 21 | .resizable() 22 | .scaledToFit() 23 | } 24 | } 25 | ) 26 | .task { 27 | self.loadImage(content) 28 | } 29 | 30 | } 31 | 32 | func loadImage(_ content: Content) { 33 | DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { 34 | let renderer = ImageRenderer(content: content) 35 | guard let image = renderer.cgImage else { return } 36 | 37 | let ciInputImage = CIImage(cgImage: image) 38 | filter.setValue(ciInputImage, forKey: kCIInputImageKey) 39 | guard let filteredImage = filter.outputImage else { return } 40 | 41 | // make the image from the context 42 | if let cgFilteredImage = context.createCGImage(filteredImage, from: filteredImage.extent) { 43 | result = Image(cgImage: cgFilteredImage) 44 | } 45 | } 46 | } 47 | } 48 | 49 | extension View { 50 | func pixellate() -> some View { 51 | modifier(Pixellate()) 52 | } 53 | } 54 | 55 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/Reusable/ViewModifiers/Rustify.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Rustify.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 4/29/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct RustifierStyle { 11 | static let one = "lasso.sparkles" 12 | static let two = "trash.circle.fill" 13 | static let three = "paperplane.fill" 14 | } 15 | 16 | struct Rustifier: ViewModifier { 17 | 18 | var blur: CGFloat = .zero 19 | var startRadius: CGFloat = 0.2 20 | var endRadius: CGFloat = 1.0 21 | var style: String = RustifierStyle.one 22 | 23 | func body(content: Content) -> some View { 24 | GeometryReader { proxy in 25 | let dim = max(proxy.size.width, proxy.size.height) 26 | ZStack { 27 | content 28 | .overlay( 29 | RadialGradient(gradient: Gradient(colors: [.kombatBrown, .green]), center: .center, startRadius: dim * startRadius, endRadius: dim * endRadius) 30 | .mask( 31 | Image(systemName: style) 32 | .resizable() 33 | .scaledToFit() 34 | .blur(radius: blur) 35 | ) 36 | .mask(content) 37 | ) 38 | } 39 | .frame(width: proxy.size.width, height: proxy.size.height) 40 | } 41 | } 42 | } 43 | 44 | extension View { 45 | func rustify(blur: CGFloat, style: String) -> some View { 46 | modifier(Rustifier(blur: blur, style: style)) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/SpiderMan/Model/SpiderManSkill.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SpiderManSkill.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 12/10/21. 6 | // 7 | 8 | import Foundation 9 | 10 | enum SpiderManSkillType: String { 11 | case venom 12 | case combat 13 | case camoflauge 14 | } 15 | 16 | /// The basic skill building block. 17 | struct SpiderManSkill: Identifiable { 18 | var id: String 19 | var type: SpiderManSkillType 20 | var name: String 21 | var description: String 22 | var behavior: Any? // upgrades to player state 23 | } 24 | 25 | extension SpiderManSkill { 26 | static var sample: SpiderManSkill { 27 | SpiderManSkill( 28 | id: "venom1", 29 | type: .venom, 30 | name: "Venom Jump", 31 | description: "Pressing L1 + X launches nearby enemies into the air, disarming and Venom Stunning them.", 32 | behavior: nil 33 | ) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/SpiderMan/ViewModel/SpiderManSkillViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SpiderManSkillViewModel.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 12/7/21. 6 | // 7 | 8 | import Foundation 9 | import Combine 10 | 11 | class SpiderManSkillViewModel: ObservableObject { 12 | @Published private(set) var model: SpiderManSkillModel 13 | @Published private(set) var selectedSkillId: String = SpiderManSkill.sample.id 14 | 15 | var selectedSkillState: SpiderManSkillState { 16 | skillState(with: selectedSkillId) ?? SpiderManSkillState.sample 17 | } 18 | 19 | init() { 20 | model = SpiderManSkillModel() 21 | model.buildTrees() 22 | } 23 | 24 | func skillState(with id: String) -> SpiderManSkillState? { 25 | model.skills[id] 26 | } 27 | 28 | func selectSkill(id: String) { 29 | selectedSkillId = id 30 | } 31 | 32 | func skillStates(skillType: SpiderManSkillType) -> [SpiderManSkillState] { 33 | model.skillStates(skillType: skillType) 34 | } 35 | 36 | func unlockSkill(id: String) { 37 | model.unlockSkill(id: id) 38 | } 39 | 40 | func isSkillUnlockable(id: String) -> Bool { 41 | model.isSkillUnlockable(id: id) 42 | } 43 | 44 | } 45 | 46 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/StarWars/JediFallenOrder/SaberColorPicker/JFOSaberColorItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JFOSaberColorItem.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 5/4/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct JFOSaberColorItem: View { 11 | var saberColor: Color = .blue 12 | var isSelected: Bool = false 13 | @State private var isAnimating: Bool = false 14 | 15 | var body: some View { 16 | ZStack { 17 | 18 | let rotation: CGFloat = saberColor == .green ? 45 : 55 19 | 20 | // Background color 21 | if isSelected { 22 | JFOSelectedItemDecoration() 23 | .rotationEffect(.degrees(isAnimating ? 360 : .zero)) 24 | .animation(.linear(duration: 20).repeatForever(autoreverses: false), value: isAnimating) 25 | .onAppear { 26 | isAnimating = true 27 | } 28 | .onDisappear { 29 | isAnimating = false 30 | } 31 | } 32 | 33 | Circle() 34 | .stroke(Color.gray, lineWidth: 3) 35 | .shadow(color: .gray, radius: 5) 36 | 37 | Group { 38 | LinearGradient(colors: [saberColor, .white, saberColor], startPoint: .leading, endPoint: .trailing) 39 | .rotationEffect(.degrees(rotation)) 40 | SaberHilt() 41 | .rotation(.degrees(rotation)) 42 | .offset(x: 0, y: 10) 43 | .shadow(color: .white, radius: 2, x: 1) 44 | } 45 | .clipShape(Circle().inset(by: 3)) 46 | 47 | 48 | } 49 | .frame(width: 84, height: 84) 50 | 51 | } 52 | 53 | } 54 | 55 | struct JFOSaberColorItem_Previews: PreviewProvider { 56 | static var previews: some View { 57 | JFOSaberColorItem() 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/StarWars/JediFallenOrder/SaberColorPicker/JFOSelectedItemDecoration.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JFOSelectedItemDecoration.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 5/4/23. 6 | // 7 | 8 | import SwiftUI 9 | import Shapes 10 | 11 | // TODO: remove inset and reorganize the layout of the item+overlay 12 | struct JFOSelectedItemDecoration: View { 13 | var body: some View { 14 | ZStack { 15 | StrokeStyledCircle( 16 | numberOfSegments: 1, 17 | dashPattern: [10, 1, 4, 1, 7, 1, 1, 0], 18 | lineWidth: 2 19 | ) 20 | .inset(amount: -10) 21 | .foregroundStyle(Color.jfoCopper) 22 | .shadow(color: .white, radius: 1) 23 | } 24 | } 25 | } 26 | 27 | struct JFOSelectedItemDecoration_Previews: PreviewProvider { 28 | static var previews: some View { 29 | JFOSelectedItemDecoration() 30 | .padding(20) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/StarWars/JediFallenOrder/SaberColorPicker/SaberHilt.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SaberHilt.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 5/4/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct SaberHilt: Shape { 11 | func path(in rect: CGRect) -> Path { 12 | Path { path in 13 | path.move(to: CGPoint(x: rect.minX + 0.25 * rect.width, y: rect.maxY)) 14 | 15 | // LEFT part of hilt 16 | path.addLine(to: .init(x: path.currentPoint!.x, y: rect.height * 0.5)) 17 | path.addLine(to: .init(x: path.currentPoint!.x + 0.15 * rect.width, y: rect.height * 0.65)) 18 | path.addLine(to: .init(x: path.currentPoint!.x, y: rect.maxY)) 19 | path.addLine(to: .init(x: path.currentPoint!.x + 0.12 * rect.width, y: rect.maxY)) 20 | path.addLine(to: .init(x: path.currentPoint!.x, y: rect.height * 0.5)) 21 | path.addLine(to: .init(x: path.currentPoint!.x + 0.11 * rect.width, y: rect.height * 0.55)) 22 | path.addLine(to: .init(x: path.currentPoint!.x, y: rect.maxY)) 23 | 24 | path.closeSubpath() 25 | } 26 | } 27 | 28 | } 29 | 30 | 31 | struct SaberHilt_Previews: PreviewProvider { 32 | static var previews: some View { 33 | SaberHilt() 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/StarWars/SWTOR/SWTOREmpireLogo.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SWTOREmpireLogo.swift 3 | // SWTOREmpireLogo 4 | // 5 | // Created by nutterfi on 8/10/21. 6 | // 7 | 8 | import SwiftUI 9 | import Shapes 10 | 11 | struct SWTOREmpireLogo: View { 12 | var color: Color 13 | var body: some View { 14 | GeometryReader { proxy in 15 | let dim = min(proxy.size.width, proxy.size.height) 16 | ZStack { 17 | StrokeStyledPolygon( 18 | sides: 6, 19 | dashPatternCount: 6, 20 | dashPattern: [7, 3], 21 | lineWidthRatio: dim * 0.8 * 0.0001, 22 | dashPhaseRatio: 0.36, 23 | lineCap: .round, 24 | lineJoin: .round 25 | ) 26 | .foregroundStyle(color) 27 | .frame(width: dim, height: dim) 28 | 29 | StrokeStyledCircle( 30 | numberOfSegments: 6, 31 | dashPattern: [1, 3], 32 | lineWidthRatio: 1, 33 | dashPhaseRatio: 0.63 34 | ) 35 | .foregroundStyle(color) 36 | .frame(width: dim, height: dim) 37 | .mask( 38 | ConvexPolygon(sides: 6) 39 | ) 40 | 41 | ConvexPolygon(sides: 6) 42 | .foregroundStyle(color) 43 | .frame(width: dim * 0.5, height: dim * 0.5) 44 | } 45 | .frame(width: proxy.size.width, height: proxy.size.height) 46 | } 47 | } 48 | } 49 | 50 | struct SWTOREmpireLogo_Previews: PreviewProvider { 51 | static var previews: some View { 52 | SWTOREmpireLogo(color: .purple) 53 | .frame(width: 256, height: 256) 54 | .padding() 55 | .border(Color.purple) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/StarWars/SWTOR/SWTORLogo.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SWTORLogo.swift 3 | // SWTORLogo 4 | // 5 | // Created by nutterfi on 8/3/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct SWTORLogo: View { 11 | var color: Color 12 | var body: some View { 13 | GeometryReader { proxy in 14 | let dim = min(proxy.size.width, proxy.size.height) 15 | ZStack { 16 | Circle() 17 | .stroke(color, lineWidth: dim / 20) 18 | .frame(width: dim * 0.9, height: dim * 0.9) 19 | 20 | SWTOREmpireLogo(color: color) 21 | .frame(width: dim * 0.8, height: dim * 0.8) 22 | } 23 | .frame(width: proxy.size.width, height: proxy.size.height) 24 | } 25 | } 26 | } 27 | 28 | struct SWTORLogo_Previews: PreviewProvider { 29 | static var previews: some View { 30 | SWTORLogo(color: Color.red) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/TheLastOfUs/FireflySymbol/FireflySymbol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FireflySymbol.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 5/7/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct FireflySymbol: View { 11 | var body: some View { 12 | GeometryReader { proxy in 13 | let dim = min(proxy.size.width, proxy.size.height) 14 | ZStack { 15 | HStack { 16 | FireflyWing() 17 | FireflyWing() 18 | .scale(x: -1, y: 1) 19 | } 20 | .frame(width: dim * 0.75, height: dim * 0.25) 21 | .offset(x: 0, y: -dim * 0.1) 22 | 23 | HStack { 24 | FireflyTail() 25 | FireflyTail() 26 | .scale(x: -1, y: 1) 27 | } 28 | .frame(width: dim * 0.2, height: dim * 0.4) 29 | .offset(x: 0, y: dim * 0.13) 30 | } 31 | .frame(width: proxy.size.width, height: proxy.size.height) 32 | } 33 | } 34 | } 35 | 36 | struct FireflySymbol_Previews: PreviewProvider { 37 | static var previews: some View { 38 | FireflySymbol() 39 | .foregroundStyle(.red) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/TheLastOfUs/FireflySymbol/FireflyTail.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FireflyTail.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 4/24/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct FireflyTail: Shape { 11 | func path(in rect: CGRect) -> Path { 12 | let start = CGPoint(x: rect.width, y: 0.15 * rect.height) 13 | return Path { path in 14 | path.move(to: start) 15 | path.addLine(to: CGPoint(x: rect.width, y: rect.height)) 16 | path.addLine(to: CGPoint(x: rect.width * 0.8, y: rect.height * 0.9)) 17 | path.addLine(to: CGPoint(x: rect.width * 0.8, y: rect.height * 0.3)) 18 | path.addLine(to: CGPoint(x: rect.width * 0.333, y: rect.height * 0.5)) 19 | path.addLine(to: CGPoint(x: rect.width * 0.7, y: rect.height * 0.15)) 20 | path.addLine(to: CGPoint(x: 0, y: rect.height * 0.25)) 21 | path.addLine(to: CGPoint(x: rect.width * 0.7, y: 0)) 22 | path.addQuadCurve(to: start, control: CGPoint(x: rect.width * 0.7, y: rect.height * 0.1)) 23 | } 24 | } 25 | 26 | 27 | } 28 | 29 | struct FireflyTail_Previews: PreviewProvider { 30 | static var previews: some View { 31 | FireflyTail() 32 | .fill(Color.black) 33 | .frame(width: 50, height: 200) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/TheLastOfUs/FireflySymbol/FireflyWing.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FireflyWing.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 4/24/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct FireflyWing: Shape { 11 | func path(in rect: CGRect) -> Path { 12 | Path { path in 13 | path.move(to: CGPoint(x: rect.width, y: rect.height * 0.2)) 14 | path.addLine(to: CGPoint(x: rect.width, y: rect.height * 0.4)) 15 | path.addLine(to: CGPoint(x: rect.width * 0.666, y: rect.height)) 16 | path.addLine(to: CGPoint(x: rect.width * 0.333, y: rect.height * 0.8)) 17 | path.addLine(to: CGPoint(x: rect.width * 0.9, y: rect.height * 0.4)) 18 | path.addLine(to: CGPoint(x: rect.width * 0.9, y: rect.height * 0.35)) 19 | path.addLine(to: CGPoint(x: rect.width * 0.2, y: rect.height * 0.5)) 20 | path.addLine(to: CGPoint(x: 0, y: rect.height * 0.24)) 21 | path.addLine(to: CGPoint(x: rect.width * 0.05, y: rect.height * 0.2)) 22 | path.addLine(to: CGPoint(x: rect.width * 0.95, y: rect.height * 0.2)) 23 | path.addLine(to: CGPoint(x: rect.width * 0.85, y: 0)) 24 | path.closeSubpath() 25 | } 26 | } 27 | 28 | 29 | } 30 | 31 | struct FireflyWing_Previews: PreviewProvider { 32 | static var previews: some View { 33 | FireflyWing() 34 | .fill() 35 | .frame(width: 200, height: 100) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/TheLastOfUs/Skills/SkillHealingSpeed.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SkillHealingSpeed.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 5/11/21. 6 | // 7 | 8 | import SwiftUI 9 | import Shapes 10 | 11 | struct SkillHealingSpeed: View { 12 | var color: Color = .white 13 | var body: some View { 14 | GeometryReader { proxy in 15 | let dim = min(proxy.size.width, proxy.size.height) 16 | ZStack { 17 | color 18 | .frame(width: dim / 2, height: dim / 10) 19 | 20 | color 21 | .frame(width: dim / 10, height: dim / 2) 22 | 23 | HStack(spacing: dim / 60) { 24 | Group { 25 | ConvexPolygon(sides: 3) 26 | ConvexPolygon(sides: 3) 27 | } 28 | .foregroundStyle(color) 29 | .frame(width: dim / 10) 30 | } 31 | .offset(x: dim / 5, y: dim / 5) 32 | } 33 | .frame(width: proxy.size.width, height: proxy.size.height) 34 | .offset(x: -dim / 20, y: 0) 35 | } 36 | } 37 | } 38 | 39 | struct SkillHealingSpeed_Previews: PreviewProvider { 40 | static var previews: some View { 41 | VStack { 42 | SkillHealingSpeed(color: .purple) 43 | .frame(width: 200, height: 200) 44 | .border(Color.black) 45 | 46 | SkillHealingSpeed() 47 | .frame(width: 200, height: 200) 48 | } 49 | .background(Color.gray) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/TheLastOfUs/Skills/SkillIcon.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SkillIcon.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 5/15/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct SkillIconType { 11 | static let maximumHealth = "maximumHealth" 12 | static let healingSpeed = "healingSpeed" 13 | static let weaponSway = "weaponSway" 14 | } 15 | 16 | struct SkillIcon: View { 17 | var icon: String = SkillIconType.maximumHealth 18 | var body: some View { 19 | GeometryReader { proxy in 20 | ZStack { 21 | Circle() 22 | .stroke(Color.white, lineWidth: 3) 23 | .background(Circle().foregroundStyle(.black)) 24 | 25 | Group { 26 | switch icon { 27 | case SkillIconType.maximumHealth: 28 | SkillMaxHealth() 29 | case SkillIconType.healingSpeed: 30 | SkillHealingSpeed() 31 | case SkillIconType.weaponSway: 32 | SkillWeaponSway() 33 | default: 34 | Circle() 35 | } 36 | } 37 | 38 | } 39 | .frame(width: proxy.size.width, height: proxy.size.height) 40 | } 41 | } 42 | } 43 | 44 | struct SkillIcon_Previews: PreviewProvider { 45 | static var previews: some View { 46 | SkillIcon() 47 | .frame(width: 256, height: 256) 48 | .previewLayout(.sizeThatFits) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/TheLastOfUs/Skills/SkillMaxHealth.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SkillMaxHealth.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 5/8/21. 6 | // 7 | 8 | import SwiftUI 9 | import Shapes 10 | 11 | struct SkillMaxHealth: View { 12 | var primary: Color = .white 13 | var secondary: Color = .black 14 | var body: some View { 15 | GeometryReader { proxy in 16 | let dim = min(proxy.size.width, proxy.size.height) 17 | ZStack { 18 | Heart() 19 | .fill(primary) 20 | .frame(width: dim * 0.7, height: dim * 0.7) 21 | 22 | secondary 23 | .frame(width: dim / 3, height: dim / 10) 24 | 25 | secondary 26 | .frame(width: dim / 10, height: dim / 3) 27 | } 28 | .frame(width: proxy.size.width, height: proxy.size.height) 29 | } 30 | } 31 | } 32 | 33 | struct SkillMaxHealth_Previews: PreviewProvider { 34 | static var previews: some View { 35 | VStack { 36 | SkillMaxHealth(primary: .purple, secondary: .yellow) 37 | .frame(width: 200, height: 200) 38 | .border(Color.black) 39 | 40 | SkillMaxHealth() 41 | .frame(width: 200, height: 200) 42 | } 43 | .background(Color.gray) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/TheLastOfUs/Skills/SkillVitamin.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SkillVitamin.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 5/6/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct SkillVitamin: View { 11 | var color: Color 12 | var body: some View { 13 | GeometryReader { proxy in 14 | let dim = min(proxy.size.width, proxy.size.height) 15 | ZStack { 16 | MaskedProgressBar(progress: 0.5, backView: Color.clear, frontView: color, mask: Capsule()) 17 | .frame(width: dim * 0.7, height: dim * 0.3) 18 | .overlay( 19 | Capsule() 20 | .stroke(color, lineWidth: dim / 30) 21 | ) 22 | .rotationEffect(Angle(degrees: -25)) 23 | } 24 | .frame(width: proxy.size.width, height: proxy.size.height) 25 | } 26 | } 27 | } 28 | 29 | struct SkillVitamin_Previews: PreviewProvider { 30 | static var previews: some View { 31 | SkillVitamin(color: .red) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/TheLastOfUs/Skills/SkillWeaponSway.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SkillWeaponSway.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 5/11/21. 6 | // 7 | 8 | import SwiftUI 9 | import Shapes 10 | 11 | struct SkillWeaponSway: View { 12 | var color: Color = .white 13 | var body: some View { 14 | GeometryReader { proxy in 15 | let dim = min(proxy.size.width, proxy.size.height) 16 | ZStack { 17 | Circle() 18 | .inset(by: dim / 10) 19 | .trim(from: 0.48, to: 0.78) 20 | .stroke(lineWidth: dim / 20) 21 | 22 | Circle() 23 | .inset(by: 2 * dim / 10) 24 | .trim(from: 0.5, to: 0.75) 25 | .stroke(lineWidth: dim / 20) 26 | 27 | Circle() 28 | .inset(by: dim / 10) 29 | .trim(from: 0.48, to: 0.78) 30 | .stroke(lineWidth: dim / 20) 31 | .rotation(Angle(radians: .pi)) 32 | 33 | Circle() 34 | .inset(by: 2 * dim / 10) 35 | .trim(from: 0.5, to: 0.75) 36 | .stroke(lineWidth: dim / 20) 37 | .rotation(Angle(radians: .pi)) 38 | } 39 | .foregroundStyle(color) 40 | .frame(width: proxy.size.width, height: proxy.size.height) 41 | } 42 | } 43 | } 44 | 45 | struct SkillWeaponSway_Previews: PreviewProvider { 46 | static var previews: some View { 47 | VStack { 48 | SkillWeaponSway(color: .purple) 49 | .frame(width: 200, height: 200) 50 | .border(/*@START_MENU_TOKEN@*/Color.black/*@END_MENU_TOKEN@*/) 51 | 52 | SkillWeaponSway() 53 | .frame(width: 200, height: 200) 54 | } 55 | .background(Color.gray) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/TheLastOfUs/Skills/TLOUSkillModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TLOUSkillModel.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 5/15/21. 6 | // 7 | 8 | import Foundation 9 | 10 | struct TLOUSkillModel: Identifiable { 11 | var id: String 12 | var currentLevel: Int // starts at 0 13 | var pointCost: [Int] 14 | 15 | var nextLevelCost: Int { 16 | guard currentLevel < pointCost.count else { return 0 } 17 | return pointCost[currentLevel] 18 | } 19 | 20 | var levelsAvailable: Int { 21 | pointCost.count 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/TheLastOfUs/Skills/TLOUSkillSelectMenuViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TLOUSkillSelectMenuViewModel.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 5/15/21. 6 | // 7 | 8 | import Foundation 9 | 10 | class TLOUSkillSelectMenuViewModel: ObservableObject { 11 | @Published private(set) var skills: [TLOUSkillModel] = [] 12 | @Published private(set) var points: Int = 285 13 | 14 | init() { 15 | skills.append(TLOUSkillModel(id: SkillIconType.maximumHealth, currentLevel: 1, pointCost: [50, 100])) 16 | 17 | skills.append(TLOUSkillModel(id: SkillIconType.healingSpeed, currentLevel: 0, pointCost: [30, 60, 90])) 18 | 19 | skills.append(TLOUSkillModel(id: SkillIconType.weaponSway, currentLevel: 1, pointCost: [50, 100])) 20 | } 21 | 22 | func title(for id: String) -> String { 23 | switch id { 24 | case SkillIconType.maximumHealth: 25 | return "Maximum Health" 26 | case SkillIconType.healingSpeed: 27 | return "Healing Speed" 28 | case SkillIconType.weaponSway: 29 | return "Weapon Sway" 30 | default: 31 | return "" 32 | } 33 | } 34 | 35 | func purchase(skillID: String) { 36 | guard let index = skills.firstIndex(where: {$0.id == skillID}) 37 | else { return } 38 | guard skills[index].nextLevelCost <= points else { return } 39 | points -= skills[index].nextLevelCost 40 | 41 | if skills[index].currentLevel < skills[index].levelsAvailable { 42 | skills[index].currentLevel += 1 43 | } 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/TheLastOfUs/TLOUIcon.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TLOUIcon.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 4/20/21. 6 | // 7 | 8 | import SwiftUI 9 | import Shapes 10 | 11 | struct TLOUIcon: View { 12 | var body: some View { 13 | GeometryReader { proxy in 14 | let dim = min(proxy.size.width, proxy.size.height) 15 | ZStack { 16 | Rectangle() 17 | .stroke(Color.gray, lineWidth: dim / 30) 18 | .frame(width: dim, height: dim) 19 | UnevenRoundedRectangle(cornerRadii: RectangleCornerRadii(topLeading: 100, bottomTrailing: 100)) 20 | .frame(width: dim * 0.85, height: dim * 0.85) 21 | .foregroundStyle(.tlouSecondary) 22 | 23 | Circle() 24 | .frame(width: dim * 0.73, height: dim * 0.73) 25 | Image(systemName: "hand.raised.fill") 26 | .resizable() 27 | .scaledToFit() 28 | .frame(width: dim * 0.5, height: dim * 0.5) 29 | .foregroundStyle(.tlouSecondary) 30 | } 31 | .background(Color(red: 46.0/255, green: 47.0/255, blue: 45.0/255)) 32 | .frame(width: proxy.size.width, height: proxy.size.height) 33 | } 34 | } 35 | } 36 | 37 | struct TLOUIcon_Previews: PreviewProvider { 38 | static var previews: some View { 39 | TLOUIcon() 40 | .frame(width: 200, height: 300) 41 | .padding() 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/TheLastOfUs/TLOUIconDemo.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TLOUIconDemo.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 4/23/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct TLOUIconDemo: View { 11 | var body: some View { 12 | VStack { 13 | 14 | HStack { 15 | TLOUSkillsIcon(pointsAvailable: true) 16 | .frame(width: 100, height: 100) 17 | 18 | TLOUSkillsIcon(pointsAvailable: false) 19 | .frame(width: 100, height: 100) 20 | 21 | TLOUIcon() 22 | .frame(width: 100, height: 100) 23 | } 24 | 25 | HStack { 26 | POIMarker(markerType: POIMarkerType.dialogue) 27 | .frame(width: 100, height: 200) 28 | POIMarker(markerType: POIMarkerType.objectInteract) 29 | .frame(width: 100, height: 200) 30 | } 31 | 32 | FireflyPendant() 33 | .frame(width: 150, height: 200) 34 | } 35 | } 36 | } 37 | 38 | struct TLOUIconDemo_Previews: PreviewProvider { 39 | static var previews: some View { 40 | TLOUIconDemo() 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/TheLastOfUs/TLOUMainMenuIcon.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TLOUMainMenuIcon.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 10/28/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct TLOUMainMenuIcon: View { 11 | var body: some View { 12 | ZStack { 13 | Color.black.ignoresSafeArea() 14 | VStack(alignment: .leading, spacing: -18) { 15 | Group { 16 | Text("THE") 17 | Text("LAST") 18 | Text("OF US") 19 | } 20 | .font(.custom("AvenirNextCondensed-Medium", size: 32)) 21 | } 22 | .foregroundStyle(.white) 23 | .background(Color.black.frame(maxWidth: .infinity)) 24 | 25 | LinearGradient(colors: [.black.opacity(0.9), .clear], startPoint: .bottomLeading, endPoint: .topTrailing) 26 | } 27 | } 28 | } 29 | 30 | struct TLOUMainMenuIcon_Previews: PreviewProvider { 31 | static var previews: some View { 32 | TLOUMainMenuIcon() 33 | .frame(width: 256, height: 128) 34 | .previewLayout(.sizeThatFits) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/TheLastOfUs/TLOUSkillsIcon.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TLOUSkillsIcon.swift 3 | // Game-UI-Inspirations 4 | // 5 | // Created by nutterfi on 5/4/21. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct TLOUSkillsIcon: View { 11 | @State private var isAnimating: Bool = false 12 | var pointsAvailable: Bool 13 | 14 | var body: some View { 15 | GeometryReader { proxy in 16 | let scaleFactor: CGFloat = isAnimating ? 1.1 : 1 17 | let dim = min(proxy.size.width, proxy.size.height) 18 | ZStack { 19 | RadialGradient(gradient: Gradient(colors: [ Color.black.opacity(0.7), Color.gray.opacity(0.7)]), center: .center, startRadius: dim * 0.5 * 0.4, endRadius: dim) 20 | .frame(width: dim, height: dim) 21 | 22 | SkillVitamin(color: pointsAvailable ? .tlouYellow : .white) 23 | .frame(width: scaleFactor * dim, height: scaleFactor * dim) 24 | .offset(x: 0, y: dim / 12) 25 | 26 | Rectangle() 27 | .stroke(Color.gray, lineWidth: dim / 30) 28 | .frame(width: dim, height: dim) 29 | 30 | } 31 | .animation(Animation.easeInOut(duration: 0.75).repeatForever(), value: isAnimating) 32 | .frame(width: proxy.size.width, height: proxy.size.height) 33 | } 34 | .onAppear { 35 | isAnimating = pointsAvailable 36 | } 37 | } 38 | } 39 | 40 | struct TLOUSkillsIcon_Previews: PreviewProvider { 41 | static var previews: some View { 42 | VStack { 43 | TLOUSkillsIcon(pointsAvailable: true) 44 | .padding() 45 | 46 | TLOUSkillsIcon(pointsAvailable: false) 47 | .padding() 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/Shared/arthured.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nutterfi/swiftui-gameui-inspirations/c7ecfe4f16e43cc6d28f325a212e3cf0850543e2/Game-UI-Inspirations/Shared/arthured.jpg -------------------------------------------------------------------------------- /Game-UI-Inspirations/iOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | 28 | UIApplicationSupportsIndirectInputEvents 29 | 30 | UILaunchScreen 31 | 32 | UIRequiredDeviceCapabilities 33 | 34 | armv7 35 | 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationLandscapeLeft 39 | UIInterfaceOrientationLandscapeRight 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/macOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | 26 | 27 | -------------------------------------------------------------------------------- /Game-UI-Inspirations/macOS/macOS.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 nutterfi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # swiftui-gameui-inspirations 2 | SwiftUI projects celebrating inspirational UI from video games 3 | --------------------------------------------------------------------------------