Smusl commited on
Commit
b742fd9
·
verified ·
1 Parent(s): 0276fa8

Upload pages/index.js with huggingface_hub

Browse files
Files changed (1) hide show
  1. pages/index.js +218 -0
pages/index.js ADDED
@@ -0,0 +1,218 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useState, useEffect } from 'react'
2
+ import Head from 'next/head'
3
+
4
+ export default function Home() {
5
+ const [players, setPlayers] = useState([
6
+ { id: 1, name: 'Player1', x: 100, y: 200, hasStick: true },
7
+ { id: 2, name: 'Player2', x: 400, y: 200, hasStick: false },
8
+ { id: 3, name: 'Player3', x: 250, y: 350, hasStick: false }
9
+ ])
10
+ const [selectedPlayer, setSelectedPlayer] = useState(null)
11
+ const [messages, setMessages] = useState([])
12
+ const [gameStarted, setGameStarted] = useState(false)
13
+
14
+ const handlePlayerClick = (clickedPlayer) => {
15
+ if (!selectedPlayer || !gameStarted) return
16
+
17
+ if (selectedPlayer.id === clickedPlayer.id) {
18
+ setSelectedPlayer(null)
19
+ return
20
+ }
21
+
22
+ if (selectedPlayer.hasStick) {
23
+ const distance = Math.sqrt(
24
+ Math.pow(clickedPlayer.x - selectedPlayer.x, 2) +
25
+ Math.pow(clickedPlayer.y - selectedPlayer.y, 2)
26
+ )
27
+
28
+ if (distance <= 150) {
29
+ const newMessage = {
30
+ id: Date.now(),
31
+ from: selectedPlayer.name,
32
+ to: clickedPlayer.name,
33
+ text: `Вы ударили палкой игрока ${clickedPlayer.name}`
34
+ }
35
+ setMessages(prev => [newMessage, ...prev].slice(0, 5))
36
+
37
+ setPlayers(prev => prev.map(p =>
38
+ p.id === selectedPlayer.id ? { ...p, hasStick: false } :
39
+ p.id === clickedPlayer.id ? { ...p, hasStick: true } : p
40
+ ))
41
+ }
42
+ }
43
+ setSelectedPlayer(null)
44
+ }
45
+
46
+ const movePlayer = (playerId, newX, newY) => {
47
+ setPlayers(prev => prev.map(p =>
48
+ p.id === playerId ? { ...p, x: newX, y: newY } : p
49
+ ))
50
+ }
51
+
52
+ const handleKeyPress = (e) => {
53
+ if (!selectedPlayer || !gameStarted) return
54
+
55
+ const step = 20
56
+ let newX = selectedPlayer.x
57
+ let newY = selectedPlayer.y
58
+
59
+ switch(e.key) {
60
+ case 'ArrowUp':
61
+ case 'w':
62
+ newY = Math.max(50, newY - step)
63
+ break
64
+ case 'ArrowDown':
65
+ case 's':
66
+ newY = Math.min(450, newY + step)
67
+ break
68
+ case 'ArrowLeft':
69
+ case 'a':
70
+ newX = Math.max(50, newX - step)
71
+ break
72
+ case 'ArrowRight':
73
+ case 'd':
74
+ newX = Math.min(550, newX + step)
75
+ break
76
+ }
77
+
78
+ movePlayer(selectedPlayer.id, newX, newY)
79
+ setSelectedPlayer(prev => ({ ...prev, x: newX, y: newY }))
80
+ }
81
+
82
+ useEffect(() => {
83
+ window.addEventListener('keydown', handleKeyPress)
84
+ return () => window.removeEventListener('keydown', handleKeyPress)
85
+ }, [selectedPlayer, gameStarted])
86
+
87
+ return (
88
+ <>
89
+ <Head>
90
+ <title>Stick Battle Game</title>
91
+ <meta name="description" content="Hit players with sticks!" />
92
+ </Head>
93
+
94
+ <div className="min-h-screen bg-gradient-to-br from-green-50 to-blue-50 p-4">
95
+ <div className="max-w-6xl mx-auto">
96
+ <header className="bg-white rounded-lg shadow-md p-4 mb-6">
97
+ <div className="flex justify-between items-center">
98
+ <h1 className="text-2xl font-bold text-gray-800">Stick Battle Game</h1>
99
+ <a
100
+ href="https://huggingface.co/spaces/akhaliq/anycoder"
101
+ target="_blank"
102
+ rel="noopener noreferrer"
103
+ className="text-blue-600 hover:text-blue-800 underline"
104
+ >
105
+ Built with anycoder
106
+ </a>
107
+ </div>
108
+ </header>
109
+
110
+ <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
111
+ <div className="lg:col-span-2">
112
+ <div className="bg-white rounded-lg shadow-md p-6">
113
+ <div className="mb-4 flex justify-between items-center">
114
+ <h2 className="text-xl font-semibold text-gray-700">Game Arena</h2>
115
+ <button
116
+ onClick={() => setGameStarted(!gameStarted)}
117
+ className={`px-4 py-2 rounded font-medium transition-colors ${
118
+ gameStarted
119
+ ? 'bg-red-500 hover:bg-red-600 text-white'
120
+ : 'bg-green-500 hover:bg-green-600 text-white'
121
+ }`}
122
+ >
123
+ {gameStarted ? 'Stop Game' : 'Start Game'}
124
+ </button>
125
+ </div>
126
+
127
+ <div className="relative bg-gradient-to-b from-green-100 to-green-200 rounded-lg h-96 border-4 border-green-400 overflow-hidden">
128
+ {gameStarted && (
129
+ <>
130
+ {players.map(player => (
131
+ <div
132
+ key={player.id}
133
+ onClick={() => handlePlayerClick(player)}
134
+ className={`absolute cursor-pointer transition-all duration-200 transform hover:scale-110 ${
135
+ selectedPlayer?.id === player.id ? 'ring-4 ring-blue-400' : ''
136
+ }`}
137
+ style={{ left: `${player.x}px`, top: `${player.y}px` }}
138
+ >
139
+ <div className="relative">
140
+ <div className={`w-12 h-12 rounded-full flex items-center justify-center text-white font-bold shadow-lg ${
141
+ selectedPlayer?.id === player.id ? 'bg-blue-600' : 'bg-purple-600'
142
+ }`}>
143
+ {player.name[0]}
144
+ </div>
145
+ {player.hasStick && (
146
+ <div className="absolute -right-6 top-4 text-2xl transform rotate-45">
147
+ 🏏
148
+ </div>
149
+ )}
150
+ <div className="text-xs text-center mt-1 font-semibold text-gray-700">
151
+ {player.name}
152
+ </div>
153
+ </div>
154
+ </div>
155
+ ))}
156
+ </>
157
+ )}
158
+
159
+ {!gameStarted && (
160
+ <div className="flex items-center justify-center h-full">
161
+ <p className="text-gray-600 text-lg">Click "Start Game" to begin!</p>
162
+ </div>
163
+ )}
164
+ </div>
165
+
166
+ {gameStarted && (
167
+ <div className="mt-4 p-3 bg-blue-50 rounded border border-blue-200">
168
+ <p className="text-sm text-blue-700">
169
+ <strong>How to play:</strong> Click a player to select, use arrow keys or WASD to move.
170
+ Hit other players when you have the stick (🏏)!
171
+ </p>
172
+ </div>
173
+ )}
174
+ </div>
175
+ </div>
176
+
177
+ <div className="lg:col-span-1">
178
+ <div className="bg-white rounded-lg shadow-md p-6">
179
+ <h2 className="text-xl font-semibold text-gray-700 mb-4">Battle Log</h2>
180
+ <div className="space-y-2 max-h-96 overflow-y-auto">
181
+ {messages.length === 0 ? (
182
+ <p className="text-gray-500 text-sm italic">No hits yet...</p>
183
+ ) : (
184
+ messages.map(msg => (
185
+ <div key={msg.id} className="p-3 bg-gray-50 rounded border-l-4 border-red-400">
186
+ <p className="text-sm font-medium text-gray-700">{msg.from}</p>
187
+ <p className="text-xs text-gray-600 mt-1">{msg.text}</p>
188
+ </div>
189
+ ))
190
+ )}
191
+ </div>
192
+ </div>
193
+
194
+ <div className="bg-white rounded-lg shadow-md p-6 mt-6">
195
+ <h2 className="text-xl font-semibold text-gray-700 mb-4">Players</h2>
196
+ <div className="space-y-2">
197
+ {players.map(player => (
198
+ <div key={player.id} className="flex items-center justify-between p-2 bg-gray-50 rounded">
199
+ <div className="flex items-center space-x-2">
200
+ <div className="w-8 h-8 bg-purple-600 rounded-full flex items-center justify-center text-white text-sm font-bold">
201
+ {player.name[0]}
202
+ </div>
203
+ <span className="text-sm font-medium text-gray-700">{player.name}</span>
204
+ </div>
205
+ {player.hasStick && (
206
+ <span className="text-xl">🏏</span>
207
+ )}
208
+ </div>
209
+ ))}
210
+ </div>
211
+ </div>
212
+ </div>
213
+ </div>
214
+ </div>
215
+ </div>
216
+ </>
217
+ )
218
+ }