|
@@ -2,8 +2,8 @@
|
|
|
<div class="game-container">
|
|
|
<canvas id="canvas" @mousedown="handleMouseDown" @mouseup="handleMouseUp" @touchstart="handleTouchStart"
|
|
|
@touchend="handleTouchEnd"></canvas>
|
|
|
- <!-- <canvas ref="canvasRef" :width="clientObj.width" :height="clientObj.height"
|
|
|
- style="position:fixed;left: 0; top: 0;"></canvas> -->
|
|
|
+ <canvas ref="canvasRef" :width="clientObj.width" :height="clientObj.height"
|
|
|
+ style="position:fixed;left: 0; top: 0;"></canvas>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
@@ -28,12 +28,13 @@ const data = reactive<any>({
|
|
|
boxes: [],//四个点坐标
|
|
|
proportion: null,//人框和屏幕比例
|
|
|
myThrow: 0,//0放下1举投
|
|
|
+ direction: null,//跑动
|
|
|
});
|
|
|
|
|
|
-const { bodyposeData, bodyposeState, parameter, deviceInfo, againNum, againTimer, wsState, clientObj, boxes, proportion, myThrow } = toRefs(data);
|
|
|
+const { bodyposeData, bodyposeState, parameter, deviceInfo, againNum, againTimer, wsState, clientObj, boxes, proportion, myThrow, direction } = toRefs(data);
|
|
|
|
|
|
/**
|
|
|
- * 输出犯规
|
|
|
+ * 监听投篮
|
|
|
*/
|
|
|
watch(
|
|
|
() => myThrow.value,
|
|
@@ -53,6 +54,26 @@ watch(
|
|
|
{ immediate: true }
|
|
|
);
|
|
|
|
|
|
+/**
|
|
|
+ * 监听投篮
|
|
|
+ */
|
|
|
+watch(
|
|
|
+ () => direction.value,
|
|
|
+ (newData, oldData) => {
|
|
|
+ nextTick(() => {
|
|
|
+ if (newData > oldData) {
|
|
|
+ gameState.keyRight = true;
|
|
|
+ gameState.keyLeft = false;
|
|
|
+ } else {
|
|
|
+ gameState.keyLeft = true;
|
|
|
+ gameState.keyRight = false;
|
|
|
+
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ { immediate: true }
|
|
|
+);
|
|
|
+
|
|
|
/**
|
|
|
* 初始化
|
|
|
*/
|
|
@@ -194,7 +215,7 @@ const getCanvas = () => {
|
|
|
let rightA = bodyposeData.value[5][1];//左肩Y
|
|
|
let leftB = bodyposeData.value[10][1];//右手Y
|
|
|
let rightB = bodyposeData.value[9][1];//左手Y
|
|
|
- let bizi = bodyposeData.value[0][1];//左手Y
|
|
|
+ let bizi = bodyposeData.value[0][1];//鼻子Y
|
|
|
|
|
|
if (leftB > leftA || rightB > rightA || leftB > bizi || rightB > bizi) {
|
|
|
myThrow.value = 1;
|
|
@@ -234,6 +255,7 @@ const getCanvas = () => {
|
|
|
// console.log("原始坐标:", originalPoints);
|
|
|
// console.log("缩放后坐标:", postData);
|
|
|
|
|
|
+ direction.value = postData[0][0] - offset.x - (94/2);//鼻子X
|
|
|
//绘制头部
|
|
|
const point1 = { x: postData[4][0], y: postData[4][1] };
|
|
|
const point2 = { x: postData[3][0], y: postData[3][1] };
|
|
@@ -316,6 +338,9 @@ const gameState = reactive({
|
|
|
keyRight: false,
|
|
|
spaceShoot: false, // 空格键投篮状态
|
|
|
exitTimer: null, // 用于存储退出定时器ID
|
|
|
+ bounceHeight: 20, // 拍球高度
|
|
|
+ bounceSpeed: 2, // 拍球速度
|
|
|
+ bouncePhase: 0, // 拍球相位(0-2π)
|
|
|
});
|
|
|
|
|
|
// 篮筐类
|
|
@@ -452,6 +477,7 @@ class PopText {
|
|
|
game.drawText(ctx, this.string, this.x + 15, this.y);
|
|
|
ctx.globalAlpha = 1;
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
|
|
|
// 工具函数:绘制旋转图像
|
|
@@ -481,7 +507,7 @@ const handleTouchEnd = () => {
|
|
|
};
|
|
|
|
|
|
// 键盘事件处理函数
|
|
|
-const handleKeyDown = (event: KeyboardEvent) => {
|
|
|
+const handleKeyDown = (event: any) => {
|
|
|
if (gameState.state !== 'play') return;
|
|
|
|
|
|
if (event.key === 'ArrowLeft') {
|
|
@@ -494,7 +520,7 @@ const handleKeyDown = (event: KeyboardEvent) => {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
-const handleKeyUp = (event: KeyboardEvent) => {
|
|
|
+const handleKeyUp = (event: any) => {
|
|
|
if (event.key === 'ArrowLeft') {
|
|
|
gameState.keyLeft = false;
|
|
|
} else if (event.key === 'ArrowRight') {
|
|
@@ -628,10 +654,12 @@ const update = (delta) => {
|
|
|
|
|
|
// 键盘控制篮球移动
|
|
|
if (gameState.keyLeft) {
|
|
|
- gameState.ballX -= gameState.ballVel * delta;
|
|
|
+ //gameState.ballX -= gameState.ballVel * delta;
|
|
|
+ gameState.ballX = direction.value;
|
|
|
}
|
|
|
if (gameState.keyRight) {
|
|
|
- gameState.ballX += gameState.ballVel * delta;
|
|
|
+ //gameState.ballX += gameState.ballVel * delta;
|
|
|
+ gameState.ballX = direction.value;
|
|
|
}
|
|
|
|
|
|
// 边界检查
|
|
@@ -743,6 +771,7 @@ const update = (delta) => {
|
|
|
|
|
|
// 更新篮球角度
|
|
|
gameState.ballAngle += 100 * delta;
|
|
|
+
|
|
|
}
|
|
|
|
|
|
// 游戏结束状态处理
|
|
@@ -850,10 +879,27 @@ const draw = () => {
|
|
|
drawText(ctx, '成绩:' + gameState.score, clientObj.value.width / 2, 400, 50);
|
|
|
ctx.textAlign = 'center';
|
|
|
|
|
|
- // 游戏结束后2秒自动退出
|
|
|
- if (!gameState.exitTimer) {
|
|
|
- gameState.exitTimer = setTimeout(() => {
|
|
|
- // 退出游戏,这里可以根据实际需求调整,比如返回主菜单或跳转到其他页面
|
|
|
+ // 游戏结束后2秒自动退出
|
|
|
+ if (!gameState.exitTimer) {
|
|
|
+ gameState.exitTimer = setTimeout(() => {
|
|
|
+ // 退出游戏,这里可以根据实际需求调整,比如返回主菜单或跳转到其他页面
|
|
|
+ gameState.gameOver = false;
|
|
|
+ gameState.started = false;
|
|
|
+ gameState.score = 0;
|
|
|
+ gameState.time = 60;
|
|
|
+ gameState.balls = [];
|
|
|
+ gameState.state = 'menu';
|
|
|
+ gameState.click = false;
|
|
|
+ gameState.exitTimer = null;
|
|
|
+
|
|
|
+ // 如果需要跳转到其他页面,可以使用路由
|
|
|
+ // router.push('/');
|
|
|
+ }, 2000);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 保留点击退出的功能
|
|
|
+ if (gameState.click) {
|
|
|
+ clearTimeout(gameState.exitTimer);
|
|
|
gameState.gameOver = false;
|
|
|
gameState.started = false;
|
|
|
gameState.score = 0;
|
|
@@ -862,24 +908,7 @@ const draw = () => {
|
|
|
gameState.state = 'menu';
|
|
|
gameState.click = false;
|
|
|
gameState.exitTimer = null;
|
|
|
-
|
|
|
- // 如果需要跳转到其他页面,可以使用路由
|
|
|
- // router.push('/');
|
|
|
- }, 2000);
|
|
|
- }
|
|
|
-
|
|
|
- // 保留点击退出的功能
|
|
|
- if (gameState.click) {
|
|
|
- clearTimeout(gameState.exitTimer);
|
|
|
- gameState.gameOver = false;
|
|
|
- gameState.started = false;
|
|
|
- gameState.score = 0;
|
|
|
- gameState.time = 60;
|
|
|
- gameState.balls = [];
|
|
|
- gameState.state = 'menu';
|
|
|
- gameState.click = false;
|
|
|
- gameState.exitTimer = null;
|
|
|
- }
|
|
|
+ }
|
|
|
}
|
|
|
};
|
|
|
|