floating-games-sdk 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/package.json +44 -0
  2. package/src/FloatingGames.tsx +25 -0
  3. package/src/assets/fonts/Creepster-Regular.ttf +0 -0
  4. package/src/assets/images/android-icon-background.png +0 -0
  5. package/src/assets/images/android-icon-foreground.png +0 -0
  6. package/src/assets/images/android-icon-monochrome.png +0 -0
  7. package/src/assets/images/blocks-icon.png +0 -0
  8. package/src/assets/images/bright-rubber-puzzles-blue.png +0 -0
  9. package/src/assets/images/close.png +0 -0
  10. package/src/assets/images/eriri.png +0 -0
  11. package/src/assets/images/favicon.png +0 -0
  12. package/src/assets/images/first-play.png +0 -0
  13. package/src/assets/images/game-over.gif +0 -0
  14. package/src/assets/images/game-pad.png +0 -0
  15. package/src/assets/images/game-pad2.png +0 -0
  16. package/src/assets/images/game-page-bg1.png +0 -0
  17. package/src/assets/images/hands-down-bg.png +0 -0
  18. package/src/assets/images/icon.png +0 -0
  19. package/src/assets/images/lets-play.gif +0 -0
  20. package/src/assets/images/lucky-day.gif +0 -0
  21. package/src/assets/images/maths.png +0 -0
  22. package/src/assets/images/not-playing.png +0 -0
  23. package/src/assets/images/number-puzzle-select.png +0 -0
  24. package/src/assets/images/number-puzzle-selector.png +0 -0
  25. package/src/assets/images/pause-clock.png +0 -0
  26. package/src/assets/images/pause-icon.png +0 -0
  27. package/src/assets/images/play-icon.png +0 -0
  28. package/src/assets/images/play-now.gif +0 -0
  29. package/src/assets/images/play-play.png +0 -0
  30. package/src/assets/images/play.png +0 -0
  31. package/src/assets/images/quit-game.png +0 -0
  32. package/src/assets/images/quit-icon.png +0 -0
  33. package/src/assets/images/quit.png +0 -0
  34. package/src/assets/images/review-win-selector.png +0 -0
  35. package/src/assets/images/select-bg.png +0 -0
  36. package/src/assets/images/select-logo.png +0 -0
  37. package/src/assets/images/spin-wheel-select.png +0 -0
  38. package/src/assets/images/spin-wheel-selector.png +0 -0
  39. package/src/assets/images/splash-icon.png +0 -0
  40. package/src/assets/images/start-button.png +0 -0
  41. package/src/assets/images/start-game.png +0 -0
  42. package/src/assets/images/stop-quit.png +0 -0
  43. package/src/assets/images/waiting-for-you.gif +0 -0
  44. package/src/assets/sounds/selector-music.mp3 +0 -0
  45. package/src/assets/sounds/timeup-sound.wav +0 -0
  46. package/src/components/atoms/Amount.tsx +48 -0
  47. package/src/components/atoms/FloatingMenu.tsx +119 -0
  48. package/src/components/atoms/ShimmerHR.tsx +64 -0
  49. package/src/components/atoms/UseAnimatedCounter.tsx +31 -0
  50. package/src/components/games/Chain.tsx +26 -0
  51. package/src/components/games/GameItem.tsx +38 -0
  52. package/src/components/games/GameSelectorScreen.tsx +221 -0
  53. package/src/components/games/GameSplash.tsx +44 -0
  54. package/src/components/games/HangingSign.tsx +75 -0
  55. package/src/components/games/SplashScreen.tsx +69 -0
  56. package/src/components/games/number-puzzle/DragTile.tsx +65 -0
  57. package/src/components/games/number-puzzle/GameScreen.tsx +597 -0
  58. package/src/components/games/number-puzzle/PuzzleSplash.tsx +50 -0
  59. package/src/components/games/number-puzzle/TileComponent.tsx +47 -0
  60. package/src/components/games/review-and-win/EmojiTracker.tsx +96 -0
  61. package/src/components/games/review-and-win/GameScreen.tsx +135 -0
  62. package/src/components/games/review-and-win/Tile.tsx +60 -0
  63. package/src/components/games/spin-wheel/SpinAndWin.tsx +507 -0
  64. package/src/components/payment/CheckoutScreen.tsx +50 -0
  65. package/src/components/payment/FundAccount.tsx +281 -0
  66. package/src/components/payment/Payment.tsx +45 -0
  67. package/src/components/reusables/AppSelect.tsx +70 -0
  68. package/src/components/reusables/CountdownTimer.tsx +116 -0
  69. package/src/components/reusables/FloatingButton.tsx +71 -0
  70. package/src/components/reusables/SoundPlayer.ts +28 -0
  71. package/src/components/utils/shuffle.ts +48 -0
  72. package/src/context/GameContext.tsx +15 -0
  73. package/src/index.tsx +5 -0
  74. package/src/modals/BottomSheetModal.tsx +38 -0
  75. package/src/modals/GameOverModal.tsx +76 -0
  76. package/src/modals/PauseModal.tsx +95 -0
  77. package/src/navigation/GameNavigator.tsx +48 -0
@@ -0,0 +1,96 @@
1
+ // components/EmojiTracker.tsx
2
+ import React from 'react';
3
+ import { StyleSheet, Text, View } from 'react-native';
4
+ import { Amount } from '../../atoms/Amount';
5
+
6
+ type Props = {
7
+ counts: { [key: string]: number }, // how many times player opened
8
+ maxCounts: { [key: string]: number }, // how many slots to show (max 3)
9
+ emojiValues: { [key: string]: number } // values for each emoji
10
+ }
11
+
12
+ const EMOJIS = ['😀', '🔥', '⭐'];
13
+
14
+ export default function EmojiTracker({ counts, maxCounts, emojiValues }: Props) {
15
+ return (
16
+ <View style={ styles.container }>
17
+ { EMOJIS.map(emoji => {
18
+ const max = maxCounts[emoji] || 3; // always show up to 3 slots
19
+
20
+ return (
21
+ <View key={ emoji } style={ styles.row }>
22
+ { [...Array(max)].map((_, i) => {
23
+ const active = counts[emoji] > i;
24
+ return (
25
+ <View key={ i }
26
+ style={ [styles.box, active && styles.active, counts[emoji] >= 3 && styles.won] }>
27
+ <Text style={ styles.emoji }>{ emoji }</Text>
28
+ </View>
29
+ )
30
+ }) }
31
+
32
+ <View style={ styles.pointCover }>
33
+ <Text style={ {
34
+ color: counts[emoji] >= 3 ? '#0ff35e' : '#f6e573',
35
+ fontWeight: 900,
36
+ fontSize: 23,
37
+ marginHorizontal: 4
38
+ } }>=</Text>
39
+ <Text style={ counts[emoji] >= 3 ? styles.points1 : styles.points2 }>
40
+ <Amount
41
+ value={ emojiValues[emoji] } // numeric value
42
+ fontSize={ 23 }
43
+ color={ counts[emoji] >= 3 ? '#0ff35e' : '#f6e573' }
44
+ />
45
+ </Text>
46
+ { /*<Text style={{color:'#fff'}}>{counts[emoji] >= 3 && '💰'}</Text>*/ }
47
+ </View>
48
+ </View>
49
+ )
50
+ }) }
51
+ </View>
52
+ )
53
+ }
54
+
55
+ const styles = StyleSheet.create({
56
+ container: { marginBottom: 8 },
57
+ row: { flexDirection: 'row', alignItems: 'center', marginBottom: 8 },
58
+ box: {
59
+ width: 50, height: 50,
60
+ borderWidth: 4, borderColor: '#999',
61
+ justifyContent: 'center', alignItems: 'center',
62
+ marginHorizontal: 5, borderRadius: 50
63
+ },
64
+ active: { borderColor: 'gold' },
65
+ emoji: { fontSize: 20 },
66
+ points1: {
67
+ marginLeft: 4,
68
+ fontSize: 20,
69
+ fontWeight: 'bold',
70
+ color: '#0ff35e',
71
+ // backgroundColor:'#fff',
72
+ // width: '60%'
73
+ },
74
+ points2: {
75
+ marginLeft: 4,
76
+ fontSize: 20,
77
+ fontWeight: 'bold',
78
+ color: '#f6e573',
79
+ // backgroundColor:'#fff',
80
+ // alignSelf:'center'
81
+ },
82
+ won: { borderColor: '#0ff35e' },
83
+ pointCover: {
84
+ display: 'flex',
85
+ flexDirection: 'row',
86
+ // borderWidth: 3,
87
+ // borderRadius: 8,
88
+ // borderColor: '#0ff35e',
89
+ // paddingHorizontal: 3,
90
+ // paddingVertical: 10,
91
+ alignItems: 'center',
92
+ // width: '50%',
93
+ alignSelf: 'center',
94
+ // justifyContent:'center'
95
+ }
96
+ });
@@ -0,0 +1,135 @@
1
+ // components/GameScreen.tsx
2
+ import React, {useState} from 'react';
3
+ import {Alert, FlatList, StyleSheet, Text, TouchableOpacity, View} from 'react-native';
4
+ import EmojiTracker from './EmojiTracker';
5
+ import Tile from './Tile';
6
+ import {createBoard, TileData} from '../../utils/shuffle';
7
+
8
+ export default function GameScreen({navigation}: any) {
9
+
10
+ const [tiles, setTiles] = useState<TileData[]>(createBoard());
11
+ const [reviewsLeft, setReviewsLeft] = useState(5);
12
+
13
+ const [counts, setCounts] = useState<{ [key: string]: number }>({
14
+ '😀': 0, '🔥': 0, '⭐': 0
15
+ });
16
+
17
+ // Tracker max slots always 3
18
+ const [maxCounts, setMaxCounts] = useState<{ [key: string]: number }>({
19
+ '😀': 3, '🔥': 3, '⭐': 3
20
+ });
21
+
22
+ // Function to restart game
23
+ const restartGame = () => {
24
+ setTiles(createBoard());
25
+ setReviewsLeft(6);
26
+ setCounts({'😀': 0, '🔥': 0, '⭐': 0});
27
+ }
28
+
29
+ const openTile = (index: number) => {
30
+ if (reviewsLeft === 0) {
31
+ Alert.alert('Reviews', 'No reviews left!');
32
+ return
33
+ }
34
+
35
+ const newTiles = [...tiles];
36
+ if (newTiles[index].opened) return;
37
+
38
+ newTiles[index].opened = true;
39
+ setTiles(newTiles);
40
+
41
+ const emoji = newTiles[index].type;
42
+
43
+ setCounts(prev => {
44
+ const newCount = prev[emoji] + 1;
45
+
46
+ // Trigger alert when any emoji reaches 3 occurrences
47
+ if (newCount === 3) {
48
+ Alert.alert('Match!', `You opened 3 ${emoji} tiles!`);
49
+ }
50
+
51
+ return {
52
+ ...prev,
53
+ [emoji]: newCount
54
+ }
55
+ });
56
+
57
+ setReviewsLeft(prev => prev - 1);
58
+ }
59
+
60
+ return (
61
+ <>
62
+
63
+ <View style={{marginTop: 50, paddingVertical: 10, paddingHorizontal: 20, alignSelf: 'center'}}>
64
+ <EmojiTracker counts={counts} maxCounts={maxCounts} emojiValues={{'😀': 25000, '🔥': 1500, '⭐': 1000}}/>
65
+ </View>
66
+
67
+ <View style={styles.container}>
68
+
69
+ <Text style={{
70
+ color: '#0ff35e',
71
+ paddingHorizontal: 40,
72
+ paddingVertical: 16,
73
+ fontWeight: '600',
74
+ fontSize: 13
75
+ }}>
76
+ Enjoy the Challenge!{'\n'}
77
+ Test your memory, match the emojis, and watch your points climb with each successful match!
78
+ </Text>
79
+
80
+ <Text style={styles.text}>Reviews Left: {reviewsLeft}</Text>
81
+
82
+ <FlatList
83
+ scrollEnabled={false}
84
+ data={tiles}
85
+ numColumns={4}
86
+ keyExtractor={(item) => item.id.toString()}
87
+ renderItem={({item, index}) => {
88
+ return (
89
+ <Tile tile={item} disabled={reviewsLeft === 0} onPress={() => openTile(index)}/>
90
+ )
91
+ }}
92
+ />
93
+
94
+ <View
95
+ style={{flexDirection: 'row', marginBottom: 50}}>
96
+ <TouchableOpacity style={[styles.restartBtn, {marginEnd: 30}]} onPress={restartGame}>
97
+ <Text style={styles.btnText}>Restart</Text>
98
+ </TouchableOpacity>
99
+
100
+ <TouchableOpacity style={styles.backBtn} onPress={() => navigation.replace('GameSelector')}>
101
+ <Text style={styles.btnText}>Back</Text>
102
+ </TouchableOpacity>
103
+ </View>
104
+
105
+ </View>
106
+ </>
107
+ )
108
+ }
109
+
110
+ const styles = StyleSheet.create({
111
+ container: {
112
+ flex: 1,
113
+ // paddingTop: 0,
114
+ alignItems: 'center',
115
+ backgroundColor: '#222'
116
+ },
117
+ text: {fontSize: 18, marginVertical: 10, color: '#fff'},
118
+ restartBtn: {
119
+ // marginTop: 20,
120
+ paddingHorizontal: 30,
121
+ paddingVertical: 12,
122
+ backgroundColor: 'gold',
123
+ borderRadius: 10
124
+ },
125
+ backBtn: {
126
+ // position:"absolute",
127
+ // top:40,
128
+ // left:20,
129
+ paddingHorizontal: 20,
130
+ paddingVertical: 10,
131
+ backgroundColor: '#888',
132
+ borderRadius: 8
133
+ },
134
+ btnText: {fontSize: 16, fontWeight: 'bold'}
135
+ });
@@ -0,0 +1,60 @@
1
+ // components/Tile.tsx
2
+ import React, {useRef} from 'react';
3
+ import {Alert, Animated, StyleSheet, Text, TouchableOpacity} from 'react-native';
4
+ import {TileData} from '../../utils/shuffle';
5
+
6
+ type Props = {
7
+ tile: TileData,
8
+ onPress: () => void,
9
+ disabled?: boolean
10
+ }
11
+
12
+ export default function Tile({tile, onPress, disabled}: Props) {
13
+
14
+ const rotate = useRef(new Animated.Value(0)).current;
15
+
16
+ const flip = () => {
17
+ // If tile is disabled, show alert instead of opening
18
+ if (disabled) {
19
+ Alert.alert('Notice', 'You cannot open this tile right now!');
20
+ return;
21
+ }
22
+
23
+ // Already opened tile
24
+ if (tile.opened) return;
25
+
26
+ // Start flip animation
27
+ Animated.timing(rotate, {
28
+ toValue: 1,
29
+ duration: 400,
30
+ useNativeDriver: true
31
+ }).start();
32
+
33
+ onPress();
34
+ }
35
+
36
+ const rotateY = rotate.interpolate({
37
+ inputRange: [0, 1],
38
+ outputRange: ['0deg', '180deg']
39
+ });
40
+
41
+ return (
42
+ <TouchableOpacity activeOpacity={0.8} onPress={flip}>
43
+ <Animated.View style={[styles.tile, {transform: [{rotateY}]}]}>
44
+ <Text style={styles.emoji}>{tile.opened ? tile.type : 'e'}</Text>
45
+ </Animated.View>
46
+ </TouchableOpacity>
47
+ )
48
+ }
49
+
50
+ const styles = StyleSheet.create({
51
+ tile: {
52
+ width: 70, height: 70,
53
+ backgroundColor: '#444',
54
+ margin: 2,
55
+ justifyContent: 'center',
56
+ alignItems: 'center',
57
+ borderRadius: 10
58
+ },
59
+ emoji: {fontSize: 30}
60
+ });