提交 202849d6 authored 作者: lidongxu's avatar lidongxu

比较完美的适配版本

上级 3648c936
/**
* 大屏设计稿尺寸,所有渲染在此坐标系下绘制
* SCREEN_WIDTH 固定 375,SCREEN_HEIGHT 根据小游戏端屏幕比例动态调整
* SAFE_AREA_TOP / SAFE_AREA_BOTTOM 从小游戏端实时同步,保证 1:1 还原
*/
export const SCREEN_WIDTH = 375
export let SCREEN_HEIGHT = 667
export const SAFE_AREA_TOP = 0
export const SAFE_AREA_BOTTOM = 0
export let SAFE_AREA_TOP = 0
export let SAFE_AREA_BOTTOM = 0
/**
* 根据小游戏端的屏幕宽高比调整大屏设计稿高度
......@@ -18,3 +19,16 @@ export function configureScreenRatio(ratio) {
if (newHeight === SCREEN_HEIGHT) return
SCREEN_HEIGHT = newHeight
}
/**
* 根据小游戏端传来的安全区域数据,按比例映射到大屏坐标系
* @param {number} safeTop 小游戏端 SAFE_AREA_TOP(像素)
* @param {number} safeBottom 小游戏端 SAFE_AREA_BOTTOM(像素)
* @param {number} srcScreenWidth 小游戏端屏幕宽度(像素)
*/
export function configureSafeArea(safeTop, safeBottom, srcScreenWidth) {
// 小游戏坐标到大屏坐标的缩放比
const scale = srcScreenWidth ? SCREEN_WIDTH / srcScreenWidth : 1
SAFE_AREA_TOP = Math.round((safeTop || 0) * scale)
SAFE_AREA_BOTTOM = Math.round((safeBottom || 0) * scale)
}
......@@ -11,7 +11,7 @@ import { drawShooter } from './renderer/shooter.js'
import { drawGameInfo, drawTeamResultOverlay } from './renderer/gameinfo.js'
import { detectAndCreateBursts, updateAndDrawBursts, clearPrevGrid } from './renderer/explosion.js'
import { drawIdleScreen } from './renderer/idleScreen.js'
import { SCREEN_WIDTH, SCREEN_HEIGHT, configureScreenRatio } from './constants.js'
import { SCREEN_WIDTH, SCREEN_HEIGHT, configureScreenRatio, configureSafeArea } from './constants.js'
const container = document.getElementById('game-container')
const canvas = document.getElementById('game-canvas')
......@@ -198,9 +198,10 @@ function loop() {
const connStatus = getConnectionStatus()
const playerCount = states.length || 1
// 从任意一个玩家的 state 中提取屏幕比例,在渲染前统一配置
// 从任意一个玩家的 state 中提取屏幕比例和安全区域,在渲染前统一配置
if (states.length > 0 && states[0].screenRatio) {
configureScreenRatio(states[0].screenRatio)
configureSafeArea(states[0].safeAreaTop, states[0].safeAreaBottom, states[0].screenWidth)
}
// 按队伍分组
......
......@@ -3,7 +3,7 @@
* 根据 state 中的 grid 二维数组和 pushAnimOffsetY 绘制网格泡泡
*/
import { getBubbleRadius, gridToScreen, drawBubble3D } from './bubble.js'
import { SCREEN_WIDTH, SCREEN_HEIGHT, SAFE_AREA_BOTTOM } from '../constants.js'
import { SCREEN_WIDTH, SCREEN_HEIGHT, SAFE_AREA_TOP, SAFE_AREA_BOTTOM } from '../constants.js'
/**
* 绘制泡泡网格
......@@ -25,9 +25,14 @@ export function drawBubbleGrid(ctx, grid, pushAnimOffsetY = 0) {
}
}
// 绘制危险线(与小游戏端判定逻辑一致)
// 绘制危险线(与小游戏端判定逻辑完全一致)
// 公式: shooterHeight=R*8.2, gameArea=SH-SAT-SAB-shooterHeight, maxRows=floor(gameArea/RH), dangerY=maxRows*RH+SAT
const R = getBubbleRadius()
const dangerY = SCREEN_HEIGHT - SAFE_AREA_BOTTOM - R * 11.2
const ROW_HEIGHT = R * Math.sqrt(3)
const shooterHeight = R * 8.2
const gameAreaHeight = SCREEN_HEIGHT - SAFE_AREA_TOP - SAFE_AREA_BOTTOM - shooterHeight
const maxRows = Math.floor(gameAreaHeight / ROW_HEIGHT)
const dangerY = maxRows * ROW_HEIGHT + SAFE_AREA_TOP
ctx.save()
ctx.strokeStyle = 'rgba(255, 0, 0, 0.7)'
ctx.lineWidth = 2
......
/**
* 射击器渲染(大屏端,仅绘制不含触摸)
* 鸡身体朝向跟随瞄准方向倾斜 + 呼吸浮动 + 弹跳动画
*
* 所有尺寸参数与 minigame-1/js/bubble/shooter.js 保持 1:1 一致
*/
import { SCREEN_WIDTH, SCREEN_HEIGHT, SAFE_AREA_BOTTOM } from '../constants.js'
import { getBubbleRadius, drawBubble3D } from './bubble.js'
const NEXT_SCALE = 0.65
// 鸡朝向参数
// 鸡朝向参数(与小游戏端一致)
const MIN_ANGLE = 15 * Math.PI / 180
const MAX_ANGLE = 165 * Math.PI / 180
const MAX_LEAN_ANGLE = 25 * Math.PI / 180
const LEAN_LERP = 0.15
const BOB_SPEED = 0.03
// 呼吸浮动参数(与小游戏端一致:BOB_SPEED=0.04, BOB_AMOUNT=R*0.2)
const BOB_SPEED = 0.04
// 加载鸡图片
const _chickenImg = new Image()
......@@ -69,12 +72,14 @@ export function drawShooter(ctx, shooterState) {
if (!shooterState) return
const R = getBubbleRadius()
// 以下所有比例系数与 minigame-1/js/bubble/shooter.js 完全一致
const CHICKEN_WIDTH = R * 5
const CHICKEN_HEIGHT = R * 6
const CHICKEN_BOTTOM_MARGIN = R * 0.8
const BUBBLE_TOP_OFFSET = R * 0.4
const NEXT_X_OFFSET = R * 3.2
const NEXT_Y_OFFSET = R * 0.5
const NEXT_X_OFFSET = R * 3.8 // 与小游戏一致(原大屏是 3.2)
const NEXT_Y_OFFSET = R * -1.5 // 与小游戏一致(原大屏是 +0.5)
const BOB_AMOUNT = R * 0.2 // 与小游戏一致(原大屏是 R*0.15)
const x = SCREEN_WIDTH / 2
const chickenBottom = SCREEN_HEIGHT - SAFE_AREA_BOTTOM - CHICKEN_BOTTOM_MARGIN
......@@ -96,10 +101,10 @@ export function drawShooter(ctx, shooterState) {
}
_currentLean += (targetLean - _currentLean) * LEAN_LERP
// 呼吸浮动
// 呼吸浮动(与小游戏端一致)
_bobPhase += BOB_SPEED
if (_bobPhase > Math.PI * 2) _bobPhase -= Math.PI * 2
const bobOffset = Math.sin(_bobPhase) * R * 0.15
const bobOffset = Math.sin(_bobPhase) * BOB_AMOUNT
// 绘制鸡(以底部中心为旋转轴,跟随瞄准方向倾斜)
const bottomY = chickenBottom + bounceOffsetY + bobOffset
......@@ -122,7 +127,7 @@ export function drawShooter(ctx, shooterState) {
drawAimLine(ctx, aimPts)
}
// 下一颗预览泡泡
// 下一颗预览泡泡(与小游戏一致:在鸡底部偏右上方)
const nextR = R * NEXT_SCALE
const nextX = x + NEXT_X_OFFSET
const nextY = chickenBottom + NEXT_Y_OFFSET
......
minigame-1 @ 410a7eb2
Subproject commit 6fe51eaf29c8e38ac9804b5991a841aa88ea235f
Subproject commit 410a7eb26416b3947280d36f1db4e1367756b7b7
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论