@kennofizet/rewardplay-frontend 1.0.4 → 1.0.6
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 +18 -1
- package/package.json +2 -2
- package/src/components/MainGame.vue +3 -1
- package/src/components/game/TopMenu.vue +4 -0
- package/src/components/game/rpg/MapEditor.vue +247 -0
- package/src/components/game/rpg/RPGGame.vue +2660 -0
- package/src/components/game/rpg/botAI.js +332 -0
- package/src/components/game/rpg/data/bosses.js +98 -0
- package/src/components/game/rpg/data/classes.js +267 -0
- package/src/components/game/rpg/data/dungeonGenerator.js +119 -0
- package/src/components/game/rpg/data/eclipseClasses.js +186 -0
- package/src/components/game/rpg/data/enemies.js +230 -0
- package/src/components/game/rpg/data/farmData.js +301 -0
- package/src/components/game/rpg/data/items.js +218 -0
- package/src/components/game/rpg/data/maps.js +966 -0
- package/src/components/game/rpg/data/npcs.js +250 -0
- package/src/components/game/rpg/entity.js +128 -0
- package/src/components/game/rpg/farmEngine.js +1838 -0
- package/src/components/game/rpg/gameEngine.js +2070 -0
- package/src/components/game/rpg/skillEffects/SkillEffectBase.js +301 -0
- package/src/components/game/rpg/skillEffects/aoeCircle.js +110 -0
- package/src/components/game/rpg/skillEffects/blinkFlash.js +52 -0
- package/src/components/game/rpg/skillEffects/buffAura.js +64 -0
- package/src/components/game/rpg/skillEffects/castFlash.js +32 -0
- package/src/components/game/rpg/skillEffects/coneBlast.js +126 -0
- package/src/components/game/rpg/skillEffects/debuffWave.js +65 -0
- package/src/components/game/rpg/skillEffects/earthquake.js +119 -0
- package/src/components/game/rpg/skillEffects/fadeOut.js +33 -0
- package/src/components/game/rpg/skillEffects/healRing.js +51 -0
- package/src/components/game/rpg/skillEffects/index.js +22 -0
- package/src/components/game/rpg/skillEffects/lifesteal.js +57 -0
- package/src/components/game/rpg/skillEffects/lightning.js +111 -0
- package/src/components/game/rpg/skillEffects/lineBlast.js +122 -0
- package/src/components/game/rpg/skillEffects/meteor.js +154 -0
- package/src/components/game/rpg/skillEffects/novaRing.js +82 -0
- package/src/components/game/rpg/skillEffects/slashArc.js +121 -0
- package/src/components/game/rpg/skillEffects/summonCircle.js +65 -0
- package/src/components/game/rpg/skillEffects/tornado.js +119 -0
- package/src/components/game/rpg/skillEffects.js +64 -0
- package/src/components/game/rpg/sprites.js +1571 -0
- package/src/components/game/rpg/tiles.js +259 -0
- package/src/pages/game/ManageSettingPage.vue +3 -0
- package/src/pages/game/MapEditorPage.vue +17 -0
- package/src/pages/game/RPGGamePage.vue +17 -0
- package/src/pages/game/manage-setting/SettingMapEditorPage.vue +989 -0
- package/tools/generate_assets.js +737 -0
package/README.md
CHANGED
|
@@ -96,7 +96,24 @@ onMounted(() => {
|
|
|
96
96
|
|
|
97
97
|
Both are required when calling `app.use(RewardPlay, { backendUrl, token })`.
|
|
98
98
|
|
|
99
|
-
### 4.
|
|
99
|
+
### 4. Vite: optimizeDeps
|
|
100
|
+
|
|
101
|
+
If you mount RewardPlay in a separate app with `createApp(RewardPlayPage).use(RewardPlay, { backendUrl, token }).mount(...)`, add the package to Vite’s `optimizeDeps.include` so it uses the same Vue instance and `inject('gameApi')` works:
|
|
102
|
+
|
|
103
|
+
```js
|
|
104
|
+
// vite.config.js (or vite.config.ts)
|
|
105
|
+
export default {
|
|
106
|
+
// ...
|
|
107
|
+
optimizeDeps: {
|
|
108
|
+
include: ['@kennofizet/rewardplay-frontend'],
|
|
109
|
+
// ... rest of your config
|
|
110
|
+
},
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Without this, dev and build can end up with a different Vue instance for the package and `gameApi` may be missing (e.g. “gameApi.... is not a function”)
|
|
115
|
+
|
|
116
|
+
### 5. RewardPlayPage root props (optional)
|
|
100
117
|
|
|
101
118
|
| Prop | Type | Default | Description |
|
|
102
119
|
|------------------|--------|--------|--------------------------------|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kennofizet/rewardplay-frontend",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "RewardPlay frontend package - Token-based API client for RewardPlay",
|
|
5
5
|
"main": "./src/index.js",
|
|
6
6
|
"module": "./src/index.js",
|
|
@@ -49,4 +49,4 @@
|
|
|
49
49
|
"engines": {
|
|
50
50
|
"node": ">=16.0.0"
|
|
51
51
|
}
|
|
52
|
-
}
|
|
52
|
+
}
|
|
@@ -47,7 +47,9 @@ const pageMap = {
|
|
|
47
47
|
'ranking': RankingPage,
|
|
48
48
|
'rules': ComingSoonPage,
|
|
49
49
|
'shop': ShopPage,
|
|
50
|
-
'manage-setting': ManageSettingPage
|
|
50
|
+
'manage-setting': ManageSettingPage,
|
|
51
|
+
'rpg-game': () => import('../pages/game/RPGGamePage.vue'),
|
|
52
|
+
'map-editor': () => import('../pages/game/MapEditorPage.vue')
|
|
51
53
|
}
|
|
52
54
|
|
|
53
55
|
const currentPage = shallowRef(DailyRewardPage) // Default to DailyReward
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="map-editor">
|
|
3
|
+
<div class="editor-sidebar">
|
|
4
|
+
<h3>Tools</h3>
|
|
5
|
+
<div class="tile-selector">
|
|
6
|
+
<div
|
|
7
|
+
v-for="(name, id) in tileNames"
|
|
8
|
+
:key="id"
|
|
9
|
+
class="tile-option"
|
|
10
|
+
:class="{ active: selectedTile == id }"
|
|
11
|
+
@click="selectedTile = parseInt(id)"
|
|
12
|
+
>
|
|
13
|
+
<div class="tile-preview" :style="{ backgroundColor: tileColors[id] }"></div>
|
|
14
|
+
<span>{{ name }}</span>
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
<div class="editor-actions">
|
|
19
|
+
<button @click="saveMap" class="btn-save">Save Map</button>
|
|
20
|
+
<button @click="loadMap" class="btn-load">Load Map</button>
|
|
21
|
+
<button @click="clearMap" class="btn-clear">Clear</button>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<div class="editor-canvas-container">
|
|
26
|
+
<canvas
|
|
27
|
+
ref="canvas"
|
|
28
|
+
@mousedown="startDrawing"
|
|
29
|
+
@mousemove="draw"
|
|
30
|
+
@mouseup="stopDrawing"
|
|
31
|
+
@mouseleave="stopDrawing"
|
|
32
|
+
></canvas>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
</template>
|
|
36
|
+
|
|
37
|
+
<script setup>
|
|
38
|
+
import { ref, onMounted, computed, watch } from 'vue'
|
|
39
|
+
import { TILE_SIZE, TILES, TILE_COLORS, TILE_NAMES } from './tiles'
|
|
40
|
+
|
|
41
|
+
const tileColors = TILE_COLORS
|
|
42
|
+
const tileNames = TILE_NAMES
|
|
43
|
+
|
|
44
|
+
const selectedTile = ref(TILES.GRASS)
|
|
45
|
+
const canvas = ref(null)
|
|
46
|
+
const isDrawing = ref(false)
|
|
47
|
+
|
|
48
|
+
// Map Data
|
|
49
|
+
const mapWidth = 30
|
|
50
|
+
const mapHeight = 20
|
|
51
|
+
const mapTiles = ref(new Array(mapWidth * mapHeight).fill(TILES.EMPTY))
|
|
52
|
+
|
|
53
|
+
let ctx = null
|
|
54
|
+
|
|
55
|
+
onMounted(() => {
|
|
56
|
+
if (canvas.value) {
|
|
57
|
+
canvas.value.width = mapWidth * TILE_SIZE
|
|
58
|
+
canvas.value.height = mapHeight * TILE_SIZE
|
|
59
|
+
ctx = canvas.value.getContext('2d')
|
|
60
|
+
render()
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
const render = () => {
|
|
65
|
+
if (!ctx) return
|
|
66
|
+
|
|
67
|
+
// Clear
|
|
68
|
+
ctx.fillStyle = '#111'
|
|
69
|
+
ctx.fillRect(0, 0, canvas.value.width, canvas.value.height)
|
|
70
|
+
|
|
71
|
+
// Draw Tiles
|
|
72
|
+
for (let i = 0; i < mapTiles.value.length; i++) {
|
|
73
|
+
const x = (i % mapWidth) * TILE_SIZE
|
|
74
|
+
const y = Math.floor(i / mapWidth) * TILE_SIZE
|
|
75
|
+
|
|
76
|
+
const tileId = mapTiles.value[i]
|
|
77
|
+
ctx.fillStyle = tileColors[tileId] || '#000'
|
|
78
|
+
ctx.fillRect(x, y, TILE_SIZE, TILE_SIZE)
|
|
79
|
+
|
|
80
|
+
// Grid
|
|
81
|
+
ctx.strokeStyle = '#333'
|
|
82
|
+
ctx.strokeRect(x, y, TILE_SIZE, TILE_SIZE)
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const getTileIndex = (event) => {
|
|
87
|
+
const rect = canvas.value.getBoundingClientRect()
|
|
88
|
+
const x = Math.floor((event.clientX - rect.left) / TILE_SIZE)
|
|
89
|
+
const y = Math.floor((event.clientY - rect.top) / TILE_SIZE)
|
|
90
|
+
|
|
91
|
+
if (x >= 0 && x < mapWidth && y >= 0 && y < mapHeight) {
|
|
92
|
+
return y * mapWidth + x
|
|
93
|
+
}
|
|
94
|
+
return -1
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const startDrawing = (event) => {
|
|
98
|
+
isDrawing.value = true
|
|
99
|
+
placeTile(event)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const draw = (event) => {
|
|
103
|
+
if (isDrawing.value) {
|
|
104
|
+
placeTile(event)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const stopDrawing = () => {
|
|
109
|
+
isDrawing.value = false
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const placeTile = (event) => {
|
|
113
|
+
const index = getTileIndex(event)
|
|
114
|
+
if (index !== -1) {
|
|
115
|
+
mapTiles.value[index] = selectedTile.value
|
|
116
|
+
render()
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const saveMap = () => {
|
|
121
|
+
const mapData = {
|
|
122
|
+
width: mapWidth,
|
|
123
|
+
height: mapHeight,
|
|
124
|
+
tiles: mapTiles.value
|
|
125
|
+
}
|
|
126
|
+
localStorage.setItem('rpg_map_data', JSON.stringify(mapData))
|
|
127
|
+
alert('Map saved to LocalStorage!')
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const loadMap = () => {
|
|
131
|
+
const saved = localStorage.getItem('rpg_map_data')
|
|
132
|
+
if (saved) {
|
|
133
|
+
try {
|
|
134
|
+
const data = JSON.parse(saved)
|
|
135
|
+
if (data.tiles && data.tiles.length === mapWidth * mapHeight) {
|
|
136
|
+
mapTiles.value = data.tiles
|
|
137
|
+
render()
|
|
138
|
+
alert('Map loaded!')
|
|
139
|
+
} else {
|
|
140
|
+
alert('Saved map size mismatch.')
|
|
141
|
+
}
|
|
142
|
+
} catch (e) {
|
|
143
|
+
console.error(e)
|
|
144
|
+
}
|
|
145
|
+
} else {
|
|
146
|
+
alert('No saved map found.')
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const clearMap = () => {
|
|
151
|
+
if (confirm('Are you sure you want to clear the map?')) {
|
|
152
|
+
mapTiles.value = new Array(mapWidth * mapHeight).fill(TILES.EMPTY)
|
|
153
|
+
render()
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
</script>
|
|
157
|
+
|
|
158
|
+
<style scoped>
|
|
159
|
+
.map-editor {
|
|
160
|
+
display: flex;
|
|
161
|
+
height: 100%;
|
|
162
|
+
padding: 20px;
|
|
163
|
+
gap: 20px;
|
|
164
|
+
color: #fff;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.editor-sidebar {
|
|
168
|
+
width: 250px;
|
|
169
|
+
background: rgba(0,0,0,0.5);
|
|
170
|
+
padding: 15px;
|
|
171
|
+
border-radius: 8px;
|
|
172
|
+
display: flex;
|
|
173
|
+
flex-direction: column;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.tile-selector {
|
|
177
|
+
flex: 1;
|
|
178
|
+
overflow-y: auto;
|
|
179
|
+
margin: 15px 0;
|
|
180
|
+
display: flex;
|
|
181
|
+
flex-direction: column;
|
|
182
|
+
gap: 8px;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.tile-option {
|
|
186
|
+
display: flex;
|
|
187
|
+
align-items: center;
|
|
188
|
+
gap: 10px;
|
|
189
|
+
padding: 8px;
|
|
190
|
+
cursor: pointer;
|
|
191
|
+
border-radius: 4px;
|
|
192
|
+
transition: background 0.2s;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.tile-option:hover {
|
|
196
|
+
background: rgba(255,255,255,0.1);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.tile-option.active {
|
|
200
|
+
background: rgba(33, 150, 243, 0.3);
|
|
201
|
+
border: 1px solid #2196f3;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.tile-preview {
|
|
205
|
+
width: 24px;
|
|
206
|
+
height: 24px;
|
|
207
|
+
border: 1px solid rgba(255,255,255,0.2);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.editor-actions {
|
|
211
|
+
display: flex;
|
|
212
|
+
flex-direction: column;
|
|
213
|
+
gap: 10px;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
.editor-actions button {
|
|
217
|
+
padding: 10px;
|
|
218
|
+
border: none;
|
|
219
|
+
border-radius: 4px;
|
|
220
|
+
cursor: pointer;
|
|
221
|
+
font-weight: bold;
|
|
222
|
+
transition: opacity 0.2s;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
.editor-actions button:hover {
|
|
226
|
+
opacity: 0.9;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
.btn-save { background: #4caf50; color: white; }
|
|
230
|
+
.btn-load { background: #2196f3; color: white; }
|
|
231
|
+
.btn-clear { background: #f44336; color: white; }
|
|
232
|
+
|
|
233
|
+
.editor-canvas-container {
|
|
234
|
+
flex: 1;
|
|
235
|
+
background: #1a1a1a;
|
|
236
|
+
display: flex;
|
|
237
|
+
justify-content: center;
|
|
238
|
+
align-items: center;
|
|
239
|
+
border-radius: 8px;
|
|
240
|
+
overflow: auto;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
canvas {
|
|
244
|
+
background: #000;
|
|
245
|
+
box-shadow: 0 0 20px rgba(0,0,0,0.5);
|
|
246
|
+
}
|
|
247
|
+
</style>
|