20260420

这次能同步子弹了,碰撞检测血量啥的还有一些其他bug后续再完善。

我敢说这是我这辈子写过最烂最烂的代码,没有之一,看起来就像东拼西凑的,一点章法逻辑都没有,完全是想到啥写啥,目标只有一个:能跑就行。。

依旧展示代码进度:

RectangleMove.vue

  1 <template>
  2   <div class="CanvasContainer">
  3     <canvas width="1000" height="800" ref="backgroundCanvas"></canvas>
  4   </div>
  5 </template>
  6 
  7 <script setup>
  8 import axios from "axios"
  9 import { onMounted, ref } from "vue"
 10 
 11 const backgroundCanvas = ref(null)
 12 let ctx = null
 13 let ws = null
 14 //我的名字
 15 let myName = Date.now()
 16 //玩家集合
 17 const players = []
 18 //子弹集合
 19 const bullets = []
 20 //按键字典
 21 const keys = {
 22   w: false,
 23   a: false,
 24   s: false,
 25   d: false,
 26   mouseX: 0,
 27   mouseY: 0,
 28   mouseDown: false,
 29   mouseLatestDown: 0
 30 }
 31 //按下按键
 32 function keyDown(e) {
 33   if (keys.hasOwnProperty(e.key)) {
 34     keys[e.key] = true
 35   }
 36 }
 37 //松开按键
 38 function keyUp(e) {
 39   if (keys.hasOwnProperty(e.key)) {
 40     keys[e.key] = false
 41   }
 42 }
 43 //鼠标移动
 44 function mouseMove(e) {
 45   keys.mouseX = e.clientX - backgroundCanvas.value.getBoundingClientRect().left;
 46   keys.mouseY = e.clientY - backgroundCanvas.value.getBoundingClientRect().top;
 47 }
 48 //鼠标按下
 49 function mouseDown(e) {
 50   const ts = Date.now()
 51   if (ts - keys.mouseLatestDown >= 1000) {
 52     //新增子弹
 53     const me = players.find(player => player.name == myName)
 54 
 55     //计算方向
 56     const dx = keys.mouseX - me.x
 57     const dy = keys.mouseY - me.y
 58     const dist = Math.sqrt(dx * dx + dy * dy)
 59     const speed = 5
 60 
 61     //保证所有方向速度一致
 62     const vx = (dx / dist) * speed
 63     const vy = (dy / dist) * speed
 64 
 65     const bullet = new Bullet(me.x, me.y, 10, 10, "green", vx, vy, null, myName, Date.now())
 66 
 67     bullets.push(bullet)
 68 
 69     ws.send(JSON.stringify({ type: "bjoin", data: bullet }))
 70 
 71     keys.mouseDown = false
 72     keys.mouseLatestDown = Date.now()
 73   }
 74 
 75 }
 76 //画鼠标准心
 77 function drawMouse() {
 78   const cx = keys.mouseX
 79   const cy = keys.mouseY
 80   const len = 8
 81   const gap = 3
 82 
 83   ctx.strokeStyle = '#fff'
 84   ctx.lineWidth = 2
 85 
 86   ctx.beginPath()
 87   ctx.moveTo(cx, cy - gap - len)
 88   ctx.lineTo(cx, cy - gap)
 89   ctx.moveTo(cx, cy + gap)
 90   ctx.lineTo(cx, cy + gap + len)
 91 
 92   ctx.moveTo(cx - gap - len, cy)
 93   ctx.lineTo(cx - gap, cy)
 94   ctx.moveTo(cx + gap, cy)
 95   ctx.lineTo(cx + gap + len, cy)
 96   ctx.stroke()
 97 }
 98 
 99 //更新位置
100 function updatedPosition() {
101   //自己移动
102   players.forEach(player => {
103     if (player.name == myName) {
104       if (keys.w || keys.a || keys.s || keys.d) {
105         if (keys.w) player.y -= player.ySpeed
106         if (keys.s) player.y += player.ySpeed
107         if (keys.a) player.x -= player.xSpeed
108         if (keys.d) player.x += player.xSpeed
109         //发送自己新位置
110         ws.send(JSON.stringify({ type: "pupdate", data: player }))
111       }
112     }
113   })
114   //子弹移动
115   bullets.forEach((bullet, index) => {
116     bullet.x += bullet.xSpeed
117     bullet.y += bullet.ySpeed
118 
119     ws.send(JSON.stringify({ type: "bupdate", data: bullet }))
120 
121     if (bullet.x < 0 || bullet.x > backgroundCanvas.value.width || bullet.y < 0 || bullet.y > backgroundCanvas.value.height) {
122       bullets.splice(index, 1)
123       ws.send(JSON.stringify({ type: "bleave", data: bullet }))
124       console.log(bullet.from + "已移除子弹")
125     }
126 
127   })
128 
129 }
130 //更新事件
131 function updateEvent() {
132 
133 }
134 //
135 function draw() {
136   //清空画布
137   ctx.clearRect(0, 0, backgroundCanvas.value.width, backgroundCanvas.value.height)
138 
139   players.forEach(player => {
140     player.draw()
141   })
142 
143   bullets.forEach(bullet => {
144     bullet.draw()
145   })
146   drawMouse()
147 }
148 //动画
149 function animate() {
150   updatedPosition()
151   updateEvent()
152   draw()
153   requestAnimationFrame(animate)
154 }
155 //初始化
156 onMounted(() => {
157   const canvas = backgroundCanvas.value
158   ctx = canvas.getContext("2d")
159 
160   ws = new WebSocket("ws://192.168.174.97:5000")
161 
162   ws.onopen = () => {
163     const player1 = new Player(0, 0, 60, 60, "red", 2, 2, myName)
164     players.push(player1)
165     ws.send(JSON.stringify({ type: "pjoin", data: player1 }))
166     //绑定按键事件
167     window.addEventListener('keydown', keyDown)
168     window.addEventListener('keyup', keyUp)
169     window.addEventListener('mousemove', mouseMove)
170     window.addEventListener('mousedown', mouseDown)
171     //启动
172     animate()
173   }
174 
175   ws.onmessage = (res) => {
176     const response = JSON.parse(res.data)
177     const data = response.data
178     const type = response.type
179     if (type == "pjoin" || type == "pupdate" || type == "pleave") {
180       const player = new Player(data.x, data.y, data.width, data.height, data.color, data.xSpeed, data.ySpeed, data.name)
181       if (type == "pjoin") {
182         const index = players.findIndex(p => p.name == player.name)
183         if (index != -1) {
184           players[index] = player
185         } else {
186           players.push(player)
187         }
188       } else if (type == "pupdate") {
189         const index = players.findIndex(p => p.name == player.name)
190         if (index != -1) {
191           players[index] = player
192         } else {
193           players.push(player)
194         }
195       }
196     } else if (type == "bjoin" || type == "bupdate" || type == "bleave") {
197       const bullet = new Bullet(data.x, data.y, data.width, data.height, data.color, data.xSpeed, data.ySpeed, data.angle, data.from, data.name)
198       if (type == "bjoin") {
199         if (!bullets.find(b => b.name == bullet.name)) {
200           bullets.push(bullet)
201         }
202       } else if (type == "bupdate") {
203         const index = bullets.findIndex(b => b.name == bullet.name)
204         if (index != -1) {
205           bullets[index] = bullet
206         } else {
207           bullets.push(bullet)
208         }
209       } else if (type == "bleave") {
210         const index = bullets.findIndex(b => b.name == bullet.name)
211         if (index != -1) {
212           bullets.splice(index, 1)
213         }
214       }
215     }
216   }
217 
218 })
219 //玩家类
220 class Player {
221   constructor(x, y, width, height, color, xSpeed, ySpeed, name) {
222     this.x = x
223     this.y = y
224     this.width = width
225     this.height = height
226     this.color = color
227     this.xSpeed = xSpeed
228     this.ySpeed = ySpeed
229     this.name = name
230   }
231 
232   draw() {
233     ctx.fillStyle = this.color
234     ctx.fillRect(this.x - this.width / 2, this.y - this.height / 2, this.width, this.height)
235   }
236 
237 }
238 //子弹类
239 class Bullet {
240   constructor(x, y, width, height, color, xSpeed, ySpeed, angle, from, name) {
241     this.x = x
242     this.y = y
243     this.width = width
244     this.height = height
245     this.color = color
246     this.xSpeed = xSpeed
247     this.ySpeed = ySpeed
248     this.angle = angle
249     this.from = from
250     this.name = name
251   }
252 
253   draw() {
254     ctx.fillStyle = this.color
255     ctx.fillRect(this.x - this.width / 2, this.y - this.height / 2, this.width, this.height)
256   }
257 }
258 </script>
259 
260 <style scoped>
261 .CanvasContainer {
262   display: flex;
263   width: 100vw;
264   height: 100vh;
265   background-color: #000;
266   align-items: center;
267   justify-content: center;
268 }
269 
270 canvas {
271   background-color: #000333;
272   border: red solid 2px;
273   cursor: none;
274 }
275 </style>

app.js

 1 const express = require('express');
 2 const WebSocket = require('ws')
 3 const cors = require('cors');
 4 const app = express();
 5 
 6 app.use(express.json());
 7 app.use(cors());
 8 
 9 const server = app.listen(5000, () => {
10     console.log(`服务运行在 http://localhost:5000`);
11 });
12 
13 const wss = new WebSocket.Server({server})
14 
15 let clients = []
16 let players = []
17 let bullets = []
18 
19 wss.on('connection', ws => {
20 
21     console.log("新玩家加入游戏")
22 
23     ws.on('message',res => {
24         const response = JSON.parse(res);
25         const data = response.data
26         const type = response.type
27         //判断类型后操作
28         if(type == "pjoin"){
29             //新添玩家
30             clients.push({name:data.name, ws})
31             players.push(data)
32             //给所有老玩家同步新玩家
33             wss.clients.forEach(client => {
34                 client.send(JSON.stringify({type: "pjoin", data: data}))
35             })
36             //给新玩家同步所有老玩家
37             players.forEach(p => {
38                 ws.send(JSON.stringify({type: "pjoin", data: p}))
39             })
40         }else if(type == "pupdate"){
41             //寻找需要更新位置的玩家
42             const index = players.findIndex(p => p.name == data.name)
43             if(index != -1) {
44                 //更新玩家
45                 players[index] = data
46             }
47             //广播给所有玩家位置
48             wss.clients.forEach(client => {
49                 client.send(JSON.stringify({type: "pupdate", data: data}))
50             })
51         }else if(type == "pleave"){
52 
53         }else if(type == "bjoin"){
54             bullets.push(data)
55             wss.clients.forEach(client => {
56                 client.send(JSON.stringify({type: "bjoin", data: data}))
57             })
58         }else if(type == "bupdate"){
59             const index = bullets.findIndex(b => b.name == data.name)
60             if(index != -1) {
61                 bullets[index] = data
62             }
63             wss.clients.forEach(client => {
64                 client.send(JSON.stringify({type: "bupdate", data: data}))
65             })
66         }else if(type == "bleave"){
67             const index = bullets.findIndex(b => b.name == data.name)
68             if(index != -1) {
69                 bullets.splice(index, 1)
70             }
71             wss.clients.forEach(client => {
72                 client.send(JSON.stringify({type: "bleave", data: data}))
73             })
74         }
75     })
76 })

感觉我总有一天会把这个重写一遍的,到时候我绝对要把大部分逻辑写在后端,前端只负责画画

posted @ 2026-04-20 23:13  Leeszz  阅读(13)  评论(0)    收藏  举报