react-achievements 1.3.1 → 1.3.3
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.
- package/README.md +309 -100
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,161 +1,370 @@
|
|
|
1
|
-
|
|
1
|
+
<h1 align="center">🏆 React-Achievements 🏆</h1>
|
|
2
2
|
|
|
3
|
-
A flexible and customizable achievement system for React applications.
|
|
4
3
|
|
|
5
|
-
|
|
4
|
+
A flexible and customizable achievement system for React applications, perfect for adding gamification elements to your projects.
|
|
6
5
|
|
|
7
|
-
|
|
6
|
+
<h2 align="center">🚀 Installation</h2>
|
|
8
7
|
|
|
9
|
-
`
|
|
8
|
+
Install `react-achievements` using npm or yarn:
|
|
10
9
|
|
|
10
|
+
```bash
|
|
11
|
+
npm install react-achievements
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
or
|
|
11
15
|
|
|
12
|
-
|
|
16
|
+
```bash
|
|
17
|
+
yarn add react-achievements
|
|
18
|
+
```
|
|
13
19
|
|
|
14
|
-
|
|
20
|
+
<h2 align="center">🎮 Usage</h2>
|
|
15
21
|
|
|
16
|
-
|
|
22
|
+
Let's walk through setting up a simple RPG-style game with achievements using React-Achievements.
|
|
17
23
|
|
|
18
|
-
|
|
24
|
+
<h3 align="center">🛠 Set up the AchievementProvider</h3>
|
|
19
25
|
|
|
20
|
-
|
|
26
|
+
First, wrap your app or a part of your app with the AchievementProvider:
|
|
27
|
+
|
|
28
|
+
```jsx
|
|
29
|
+
import React from 'react';
|
|
21
30
|
import { AchievementProvider } from 'react-achievements';
|
|
22
31
|
import achievementConfig from './achievementConfig';
|
|
32
|
+
import Game from './Game';
|
|
33
|
+
|
|
34
|
+
const initialState = {
|
|
35
|
+
level: 1,
|
|
36
|
+
experience: 0,
|
|
37
|
+
monstersDefeated: 0,
|
|
38
|
+
questsCompleted: 0
|
|
39
|
+
};
|
|
23
40
|
|
|
24
41
|
function App() {
|
|
25
42
|
return (
|
|
26
|
-
<AchievementProvider
|
|
27
|
-
{
|
|
43
|
+
<AchievementProvider
|
|
44
|
+
config={achievementConfig}
|
|
45
|
+
initialState={initialState}
|
|
46
|
+
badgesButtonPosition="top-right"
|
|
47
|
+
>
|
|
48
|
+
<Game />
|
|
28
49
|
</AchievementProvider>
|
|
29
50
|
);
|
|
30
51
|
}
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
The `initialState` prop should contain the current state of your metrics. For example:
|
|
34
52
|
|
|
35
|
-
|
|
36
|
-
const initialState = {
|
|
37
|
-
transactions: [
|
|
38
|
-
{ id: 1, amount: 100 },
|
|
39
|
-
{ id: 2, amount: 200 }
|
|
40
|
-
]
|
|
41
|
-
};
|
|
53
|
+
export default App;
|
|
42
54
|
```
|
|
43
55
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
Create a file (e.g., `achievementConfig.js`) to define your achievements:
|
|
56
|
+
<h3 align="center">📝 Create an achievement configuration</h3>
|
|
47
57
|
|
|
58
|
+
Create a file (e.g., achievementConfig.js) to define your achievements:
|
|
48
59
|
|
|
49
60
|
```javascript
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
import
|
|
53
|
-
import image2 from './public/path/to/image2.png';
|
|
61
|
+
import levelUpIcon from './icons/level-up.png';
|
|
62
|
+
import monsterSlayerIcon from './icons/monster-slayer.png';
|
|
63
|
+
import questMasterIcon from './icons/quest-master.png';
|
|
54
64
|
|
|
55
65
|
const achievementConfig = {
|
|
56
|
-
|
|
66
|
+
level: [
|
|
57
67
|
{
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
68
|
+
check: (value) => value >= 10,
|
|
69
|
+
data: {
|
|
70
|
+
id: 'level_10',
|
|
71
|
+
title: 'Novice Adventurer',
|
|
72
|
+
description: 'Reached level 10',
|
|
73
|
+
icon: levelUpIcon
|
|
74
|
+
}
|
|
65
75
|
},
|
|
66
76
|
{
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
+
check: (value) => value >= 50,
|
|
78
|
+
data: {
|
|
79
|
+
id: 'level_50',
|
|
80
|
+
title: 'Seasoned Warrior',
|
|
81
|
+
description: 'Reached level 50',
|
|
82
|
+
icon: levelUpIcon
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
],
|
|
86
|
+
monstersDefeated: [
|
|
87
|
+
{
|
|
88
|
+
check: (value) => value >= 100,
|
|
89
|
+
data: {
|
|
90
|
+
id: 'monster_slayer',
|
|
91
|
+
title: 'Monster Slayer',
|
|
92
|
+
description: 'Defeated 100 monsters',
|
|
93
|
+
icon: monsterSlayerIcon
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
],
|
|
97
|
+
questsCompleted: [
|
|
98
|
+
{
|
|
99
|
+
check: (value) => value >= 50,
|
|
100
|
+
data: {
|
|
101
|
+
id: 'quest_master',
|
|
102
|
+
title: 'Quest Master',
|
|
103
|
+
description: 'Completed 50 quests',
|
|
104
|
+
icon: questMasterIcon
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
]
|
|
77
108
|
};
|
|
78
|
-
```
|
|
79
109
|
|
|
80
110
|
export default achievementConfig;
|
|
81
|
-
|
|
82
|
-
Note: Ensure your icons are located in the public folder of your project.
|
|
83
|
-
|
|
84
|
-
### Customize the badges button location
|
|
85
|
-
|
|
86
|
-
```javascript
|
|
87
|
-
<AchievementProvider
|
|
88
|
-
config={achievementConfig}
|
|
89
|
-
badgesButtonPosition="bottom-right"
|
|
90
|
-
>
|
|
91
|
-
{/* Your app components */}
|
|
92
|
-
</AchievementProvider>
|
|
93
111
|
```
|
|
94
|
-
Specify the position of the badges button:
|
|
95
|
-
Possible values for `badgesButtonPosition` are:
|
|
96
|
-
- 'top-left'
|
|
97
|
-
- 'top-right'
|
|
98
|
-
- 'bottom-left'
|
|
99
|
-
- 'bottom-right'
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
### Use the useAchievement hook
|
|
104
112
|
|
|
105
|
-
|
|
113
|
+
<h3 align="center">🎣 Use the useAchievement hook</h3>
|
|
106
114
|
|
|
107
|
-
|
|
115
|
+
In your game components, use the useAchievement hook to update metrics and trigger achievement checks:
|
|
116
|
+
```jsx
|
|
117
|
+
import React, { useState } from 'react';
|
|
108
118
|
import { useAchievement } from 'react-achievements';
|
|
109
119
|
|
|
110
|
-
function
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
120
|
+
function Game() {
|
|
121
|
+
const { setMetrics, metrics } = useAchievement();
|
|
122
|
+
const [currentQuest, setCurrentQuest] = useState(null);
|
|
123
|
+
|
|
124
|
+
const defeatMonster = () => {
|
|
125
|
+
setMetrics(prevMetrics => {
|
|
126
|
+
const newExperience = prevMetrics.experience + 10;
|
|
127
|
+
const newLevel = Math.floor(newExperience / 100) + 1;
|
|
128
|
+
return {
|
|
129
|
+
...prevMetrics,
|
|
130
|
+
monstersDefeated: prevMetrics.monstersDefeated + 1,
|
|
131
|
+
experience: newExperience,
|
|
132
|
+
level: newLevel > prevMetrics.level ? newLevel : prevMetrics.level
|
|
133
|
+
};
|
|
134
|
+
});
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
const completeQuest = () => {
|
|
138
|
+
setMetrics(prevMetrics => {
|
|
139
|
+
const newExperience = prevMetrics.experience + 50;
|
|
140
|
+
const newLevel = Math.floor(newExperience / 100) + 1;
|
|
141
|
+
return {
|
|
142
|
+
...prevMetrics,
|
|
143
|
+
questsCompleted: prevMetrics.questsCompleted + 1,
|
|
144
|
+
experience: newExperience,
|
|
145
|
+
level: newLevel > prevMetrics.level ? newLevel : prevMetrics.level
|
|
146
|
+
};
|
|
147
|
+
});
|
|
148
|
+
setCurrentQuest(null);
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
const startQuest = () => {
|
|
152
|
+
setCurrentQuest("Defeat the Dragon");
|
|
153
|
+
};
|
|
123
154
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
155
|
+
return (
|
|
156
|
+
<div>
|
|
157
|
+
<h1>My RPG Game</h1>
|
|
158
|
+
<p>Level: {metrics.level}</p>
|
|
159
|
+
<p>Experience: {metrics.experience}</p>
|
|
160
|
+
<p>Monsters Defeated: {metrics.monstersDefeated}</p>
|
|
161
|
+
<p>Quests Completed: {metrics.questsCompleted}</p>
|
|
162
|
+
|
|
163
|
+
<div>
|
|
164
|
+
<h2>Battle Arena</h2>
|
|
165
|
+
<button onClick={defeatMonster}>Fight a Monster</button>
|
|
166
|
+
</div>
|
|
167
|
+
|
|
168
|
+
<div>
|
|
169
|
+
<h2>Quest Board</h2>
|
|
170
|
+
{currentQuest ? (
|
|
171
|
+
<>
|
|
172
|
+
<p>Current Quest: {currentQuest}</p>
|
|
173
|
+
<button onClick={completeQuest}>Complete Quest</button>
|
|
174
|
+
</>
|
|
175
|
+
) : (
|
|
176
|
+
<button onClick={startQuest}>Start a New Quest</button>
|
|
177
|
+
)}
|
|
178
|
+
</div>
|
|
179
|
+
</div>
|
|
180
|
+
);
|
|
127
181
|
}
|
|
182
|
+
|
|
183
|
+
export default Game;
|
|
128
184
|
```
|
|
129
|
-
## Features
|
|
130
185
|
|
|
131
|
-
|
|
186
|
+
<h2 align="center">✨ Features</h2>
|
|
187
|
+
|
|
188
|
+
- Flexible Achievement System: Define custom metrics and achievement conditions for your game or app.
|
|
132
189
|
- Automatic Achievement Tracking: Achievements are automatically checked and unlocked when metrics change.
|
|
133
|
-
- Achievement Notifications: A modal pops up when an achievement is unlocked.
|
|
134
|
-
- Persistent Achievements: Unlocked achievements and metrics are stored in local storage.
|
|
135
|
-
- Achievement Gallery:
|
|
136
|
-
- Confetti Effect: A celebratory confetti effect is displayed when an achievement is unlocked.
|
|
190
|
+
- Achievement Notifications: A modal pops up when an achievement is unlocked, perfect for rewarding players.
|
|
191
|
+
- Persistent Achievements: Unlocked achievements and metrics are stored in local storage, allowing players to keep their progress.
|
|
192
|
+
- Achievement Gallery: Players can view all their unlocked achievements, encouraging completionism.
|
|
193
|
+
- Confetti Effect: A celebratory confetti effect is displayed when an achievement is unlocked, adding to the excitement.
|
|
137
194
|
|
|
138
|
-
|
|
195
|
+
<h2 align="center">🔧 API</h2>
|
|
139
196
|
|
|
140
|
-
|
|
197
|
+
<h3 align="center">🏗 AchievementProvider</h3>
|
|
141
198
|
|
|
142
199
|
#### Props:
|
|
200
|
+
|
|
143
201
|
- `config`: An object defining your metrics and achievements.
|
|
144
202
|
- `initialState`: The initial state of your metrics.
|
|
145
203
|
- `storageKey` (optional): A string to use as the key for localStorage. Default: 'react-achievements'
|
|
146
204
|
- `badgesButtonPosition` (optional): Position of the badges button. Default: 'top-right'
|
|
147
205
|
- `styles` (optional): Custom styles for the achievement components.
|
|
148
206
|
|
|
149
|
-
|
|
207
|
+
<h3 align="center">🪝 useAchievement Hook</h3>
|
|
208
|
+
|
|
209
|
+
#### Returns an object with:
|
|
150
210
|
|
|
151
|
-
Returns an object with:
|
|
152
211
|
- `setMetrics`: Function to update the metrics.
|
|
153
212
|
- `metrics`: Current metrics object.
|
|
154
213
|
- `unlockedAchievements`: Array of unlocked achievement IDs.
|
|
155
214
|
- `showBadgesModal`: Function to manually show the badges modal.
|
|
156
215
|
|
|
157
|
-
|
|
216
|
+
<h2 align="center">🎨 Customization</h2>
|
|
217
|
+
|
|
218
|
+
React-Achievements allows for extensive customization of its appearance. You can override the default styles by passing a `styles` prop to the `AchievementProvider`:
|
|
219
|
+
|
|
220
|
+
```jsx
|
|
221
|
+
const customStyles = {
|
|
222
|
+
achievementModal: {
|
|
223
|
+
overlay: {
|
|
224
|
+
backgroundColor: 'rgba(0, 0, 0, 0.8)',
|
|
225
|
+
},
|
|
226
|
+
content: {
|
|
227
|
+
backgroundColor: '#2a2a2a',
|
|
228
|
+
color: '#ffffff',
|
|
229
|
+
},
|
|
230
|
+
title: {
|
|
231
|
+
color: '#ffd700',
|
|
232
|
+
},
|
|
233
|
+
button: {
|
|
234
|
+
backgroundColor: '#4CAF50',
|
|
235
|
+
},
|
|
236
|
+
},
|
|
237
|
+
badgesModal: {
|
|
238
|
+
// Custom styles for the badges modal
|
|
239
|
+
},
|
|
240
|
+
badgesButton: {
|
|
241
|
+
// Custom styles for the badges button
|
|
242
|
+
},
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
function App() {
|
|
246
|
+
return (
|
|
247
|
+
<AchievementProvider
|
|
248
|
+
config={achievementConfig}
|
|
249
|
+
initialState={initialState}
|
|
250
|
+
styles={customStyles}
|
|
251
|
+
>
|
|
252
|
+
<Game />
|
|
253
|
+
</AchievementProvider>
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### achievementModal
|
|
259
|
+
|
|
260
|
+
Customizes the modal that appears when an achievement is unlocked.
|
|
261
|
+
|
|
262
|
+
```
|
|
263
|
+
achievementModal: {
|
|
264
|
+
overlay: {
|
|
265
|
+
// Styles for the modal overlay (background)
|
|
266
|
+
backgroundColor: 'rgba(0, 0, 0, 0.8)',
|
|
267
|
+
// You can also customize other overlay properties like zIndex, transition, etc.
|
|
268
|
+
},
|
|
269
|
+
content: {
|
|
270
|
+
// Styles for the modal content container
|
|
271
|
+
backgroundColor: '#2a2a2a',
|
|
272
|
+
color: '#ffffff',
|
|
273
|
+
borderRadius: '10px',
|
|
274
|
+
padding: '20px',
|
|
275
|
+
// Add any other CSS properties for the content container
|
|
276
|
+
},
|
|
277
|
+
title: {
|
|
278
|
+
// Styles for the achievement title
|
|
279
|
+
fontSize: '24px',
|
|
280
|
+
fontWeight: 'bold',
|
|
281
|
+
color: '#ffd700',
|
|
282
|
+
},
|
|
283
|
+
icon: {
|
|
284
|
+
// Styles for the achievement icon
|
|
285
|
+
width: '64px',
|
|
286
|
+
height: '64px',
|
|
287
|
+
marginBottom: '10px',
|
|
288
|
+
},
|
|
289
|
+
description: {
|
|
290
|
+
// Styles for the achievement description
|
|
291
|
+
fontSize: '16px',
|
|
292
|
+
marginTop: '10px',
|
|
293
|
+
},
|
|
294
|
+
button: {
|
|
295
|
+
// Styles for the close button
|
|
296
|
+
backgroundColor: '#4CAF50',
|
|
297
|
+
color: 'white',
|
|
298
|
+
padding: '10px 20px',
|
|
299
|
+
border: 'none',
|
|
300
|
+
borderRadius: '5px',
|
|
301
|
+
cursor: 'pointer',
|
|
302
|
+
},
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### badgesModal
|
|
307
|
+
|
|
308
|
+
```
|
|
309
|
+
badgesModal: {
|
|
310
|
+
overlay: {
|
|
311
|
+
// Similar to achievementModal overlay
|
|
312
|
+
},
|
|
313
|
+
content: {
|
|
314
|
+
// Similar to achievementModal content
|
|
315
|
+
},
|
|
316
|
+
title: {
|
|
317
|
+
// Styles for the modal title
|
|
318
|
+
},
|
|
319
|
+
badgeContainer: {
|
|
320
|
+
// Styles for the container holding all badges
|
|
321
|
+
display: 'flex',
|
|
322
|
+
flexWrap: 'wrap',
|
|
323
|
+
justifyContent: 'center',
|
|
324
|
+
},
|
|
325
|
+
badge: {
|
|
326
|
+
// Styles for individual badge containers
|
|
327
|
+
margin: '10px',
|
|
328
|
+
textAlign: 'center',
|
|
329
|
+
},
|
|
330
|
+
badgeIcon: {
|
|
331
|
+
// Styles for badge icons
|
|
332
|
+
width: '50px',
|
|
333
|
+
height: '50px',
|
|
334
|
+
},
|
|
335
|
+
badgeTitle: {
|
|
336
|
+
// Styles for badge titles
|
|
337
|
+
fontSize: '14px',
|
|
338
|
+
marginTop: '5px',
|
|
339
|
+
},
|
|
340
|
+
button: {
|
|
341
|
+
// Styles for the close button (similar to achievementModal button)
|
|
342
|
+
},
|
|
343
|
+
}
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
### badgesButton
|
|
348
|
+
|
|
349
|
+
```
|
|
350
|
+
badgesButton: {
|
|
351
|
+
// Styles for the floating badges button
|
|
352
|
+
position: 'fixed',
|
|
353
|
+
padding: '10px 20px',
|
|
354
|
+
backgroundColor: '#007bff',
|
|
355
|
+
color: '#ffffff',
|
|
356
|
+
border: 'none',
|
|
357
|
+
borderRadius: '5px',
|
|
358
|
+
cursor: 'pointer',
|
|
359
|
+
zIndex: 1000,
|
|
360
|
+
// You can add more CSS properties as needed. These are just regular CSS
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
This allows you to match the achievement system's look and feel to your game or application's theme.
|
|
158
366
|
|
|
367
|
+
<h2 align="center">📄 License</h2>
|
|
159
368
|
MIT
|
|
160
369
|
|
|
161
|
-
|
|
370
|
+
React-Achievements provides a comprehensive achievement system for React applications, perfect for adding gamification elements to your projects. Whether you're building a game, an educational app, or any interactive experience, this package offers an easy way to implement and manage achievements, enhancing user engagement and retention.
|