first commit
This commit is contained in:
@@ -0,0 +1,588 @@
|
||||
/**
|
||||
* TeamResultScene.js
|
||||
* 3v3 Team match result screen.
|
||||
* Shows winner, per-player stats (kills/deaths/assists/base damage),
|
||||
* base HP summary, and options to rematch or return to menu.
|
||||
*/
|
||||
|
||||
const {
|
||||
SCREEN_WIDTH,
|
||||
SCREEN_HEIGHT,
|
||||
COLORS,
|
||||
SCENE,
|
||||
NET_MSG,
|
||||
} = require('../base/GameGlobal');
|
||||
const { t } = require('../i18n/I18n');
|
||||
|
||||
// Layout
|
||||
const BTN_WIDTH = Math.min(SCREEN_WIDTH * 0.35, 180);
|
||||
const BTN_HEIGHT = Math.min(36, SCREEN_HEIGHT * 0.07);
|
||||
const BTN_GAP = 14;
|
||||
const CENTER_X = SCREEN_WIDTH / 2;
|
||||
|
||||
// Team colors
|
||||
const TEAM_A_COLOR = '#4A90D9';
|
||||
const TEAM_B_COLOR = '#E94560';
|
||||
|
||||
const TeamResultScene = {
|
||||
_winner: '',
|
||||
_winReason: '',
|
||||
_myTeam: '',
|
||||
_didWin: false,
|
||||
_teamABaseHp: 0,
|
||||
_teamBBaseHp: 0,
|
||||
_stats: {},
|
||||
_players: [],
|
||||
_elapsedTime: 0,
|
||||
_teamId: '',
|
||||
_animTimer: 0,
|
||||
_battleMode: '3v3', // '1v1' or '3v3'
|
||||
|
||||
// Rematch state
|
||||
_rematchRequested: false,
|
||||
_rematchReadyCount: 0,
|
||||
_rematchTotalCount: 0,
|
||||
_networkManager: null,
|
||||
_unsubscribers: [],
|
||||
|
||||
// Button rects
|
||||
_rematchBtnRect: null,
|
||||
_menuBtnRect: null,
|
||||
_adDoubleBtnRect: null,
|
||||
|
||||
// Ad state
|
||||
_adWatched: false,
|
||||
_goldReward: 0,
|
||||
|
||||
// Scroll state for player list
|
||||
_scrollY: 0,
|
||||
|
||||
enter(params) {
|
||||
this._winner = (params && params.winner) || '';
|
||||
this._winReason = (params && params.winReason) || 'base_destroyed';
|
||||
this._myTeam = (params && params.myTeam) || 'A';
|
||||
this._didWin = (params && params.didWin) || false;
|
||||
this._teamABaseHp = (params && params.teamABaseHp) || 0;
|
||||
this._teamBBaseHp = (params && params.teamBBaseHp) || 0;
|
||||
this._stats = (params && params.stats) || {};
|
||||
this._players = (params && params.players) || [];
|
||||
this._elapsedTime = (params && params.elapsedTime) || 0;
|
||||
this._teamId = (params && params.teamId) || '';
|
||||
this._animTimer = 0;
|
||||
this._scrollY = 0;
|
||||
this._battleMode = (params && params.battleMode) || '3v3';
|
||||
this._rematchRequested = false;
|
||||
this._rematchReadyCount = 0;
|
||||
this._rematchTotalCount = 0;
|
||||
this._networkManager = GameGlobal.networkManager;
|
||||
this._adWatched = false;
|
||||
this._goldReward = 0;
|
||||
|
||||
// Calculate and award gold
|
||||
this._calculateAndAwardGold();
|
||||
|
||||
this._setupNetworkEvents();
|
||||
|
||||
const btnY = SCREEN_HEIGHT * 0.88;
|
||||
this._rematchBtnRect = {
|
||||
x: CENTER_X - BTN_WIDTH - BTN_GAP / 2,
|
||||
y: btnY,
|
||||
w: BTN_WIDTH,
|
||||
h: BTN_HEIGHT,
|
||||
};
|
||||
this._menuBtnRect = {
|
||||
x: CENTER_X + BTN_GAP / 2,
|
||||
y: btnY,
|
||||
w: BTN_WIDTH,
|
||||
h: BTN_HEIGHT,
|
||||
};
|
||||
|
||||
// Double reward ad button (above rematch/menu buttons)
|
||||
const adBtnY = btnY - BTN_HEIGHT - BTN_GAP;
|
||||
this._adDoubleBtnRect = {
|
||||
x: CENTER_X - BTN_WIDTH * 0.75,
|
||||
y: adBtnY,
|
||||
w: BTN_WIDTH * 1.5,
|
||||
h: BTN_HEIGHT,
|
||||
};
|
||||
},
|
||||
|
||||
exit() {
|
||||
this._cleanupNetworkEvents();
|
||||
},
|
||||
|
||||
_setupNetworkEvents() {
|
||||
this._cleanupNetworkEvents();
|
||||
const nm = this._networkManager;
|
||||
if (!nm) return;
|
||||
|
||||
const unsubs = [];
|
||||
|
||||
// Listen for rematch ready updates
|
||||
unsubs.push(nm.on(NET_MSG.REMATCH_READY, (data) => {
|
||||
console.log('[TeamResultScene] REMATCH_READY received:', JSON.stringify(data));
|
||||
this._rematchReadyCount = data.readyCount || 0;
|
||||
this._rematchTotalCount = data.totalCount || 0;
|
||||
}));
|
||||
|
||||
// Listen for game start (rematch accepted, new game starting)
|
||||
unsubs.push(nm.on(NET_MSG.GAME_START, (data) => {
|
||||
console.log('[TeamResultScene] GAME_START received for rematch');
|
||||
this._startRematchGame(data);
|
||||
}));
|
||||
|
||||
unsubs.push(nm.on(NET_MSG.TEAM_GAME_START, (data) => {
|
||||
console.log('[TeamResultScene] TEAM_GAME_START received for rematch');
|
||||
this._startRematchGame(data);
|
||||
}));
|
||||
|
||||
this._unsubscribers = unsubs;
|
||||
},
|
||||
|
||||
_cleanupNetworkEvents() {
|
||||
for (const unsub of this._unsubscribers) {
|
||||
if (typeof unsub === 'function') unsub();
|
||||
}
|
||||
this._unsubscribers = [];
|
||||
},
|
||||
|
||||
/**
|
||||
* Calculate and award gold for team match.
|
||||
* @private
|
||||
*/
|
||||
_calculateAndAwardGold() {
|
||||
let gold = 50; // Base reward per requirements
|
||||
|
||||
// Find local player stats
|
||||
const localPlayer = this._players.find(p => p.isLocal);
|
||||
if (localPlayer) {
|
||||
const stats = this._stats[localPlayer.playerId] || {};
|
||||
gold += (stats.kills || 0) * 10;
|
||||
gold += (stats.assists || 0) * 5;
|
||||
}
|
||||
|
||||
// Victory bonus
|
||||
if (this._didWin) {
|
||||
gold += 50;
|
||||
}
|
||||
|
||||
this._goldReward = gold;
|
||||
|
||||
// Award gold
|
||||
if (gold > 0 && GameGlobal.currencyManager) {
|
||||
GameGlobal.currencyManager.addGold(gold);
|
||||
}
|
||||
},
|
||||
|
||||
_startRematchGame(data) {
|
||||
const sm = GameGlobal.sceneManager;
|
||||
if (!sm._scenes.has(SCENE.TEAM_GAME)) {
|
||||
const TeamGameScene = require('./TeamGameScene');
|
||||
sm.register(SCENE.TEAM_GAME, TeamGameScene);
|
||||
}
|
||||
|
||||
const myPlayerId = this._networkManager ? this._networkManager.playerId : 'local';
|
||||
|
||||
sm.switchTo(SCENE.TEAM_GAME, {
|
||||
teamId: data.roomId || this._teamId,
|
||||
roomId: data.roomId || this._teamId,
|
||||
mapId: data.mapId || null,
|
||||
teamA: data.teamA || [],
|
||||
teamB: data.teamB || [],
|
||||
teamABaseHp: data.teamABaseHp,
|
||||
teamBBaseHp: data.teamBBaseHp,
|
||||
myPlayerId,
|
||||
battleMode: data.battleMode || this._battleMode,
|
||||
});
|
||||
},
|
||||
|
||||
update(dt) {
|
||||
this._animTimer += dt;
|
||||
},
|
||||
|
||||
render(ctx) {
|
||||
// Background
|
||||
ctx.fillStyle = COLORS.MENU_BG;
|
||||
ctx.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||
|
||||
// Top accent bar
|
||||
const gradient = ctx.createLinearGradient(0, 0, SCREEN_WIDTH, 0);
|
||||
gradient.addColorStop(0, '#0f3460');
|
||||
gradient.addColorStop(0.5, '#e94560');
|
||||
gradient.addColorStop(1, '#0f3460');
|
||||
ctx.fillStyle = gradient;
|
||||
ctx.fillRect(0, 0, SCREEN_WIDTH, 4);
|
||||
|
||||
// Title
|
||||
ctx.font = 'bold 16px Arial';
|
||||
ctx.textAlign = 'center';
|
||||
ctx.textBaseline = 'middle';
|
||||
ctx.fillStyle = '#AAAAAA';
|
||||
ctx.fillText(t('teamResult.title'), CENTER_X, SCREEN_HEIGHT * 0.05);
|
||||
|
||||
// Winner announcement with pulsing effect
|
||||
let resultText, resultColor;
|
||||
if (this._didWin) {
|
||||
resultText = t('teamResult.victory');
|
||||
resultColor = '#00FF00';
|
||||
} else {
|
||||
resultText = t('teamResult.defeat');
|
||||
resultColor = '#FF4444';
|
||||
}
|
||||
|
||||
const scale = 1 + Math.sin(this._animTimer * 3) * 0.05;
|
||||
ctx.save();
|
||||
ctx.translate(CENTER_X, SCREEN_HEIGHT * 0.13);
|
||||
ctx.scale(scale, scale);
|
||||
ctx.fillStyle = resultColor;
|
||||
ctx.font = 'bold 28px Arial';
|
||||
ctx.fillText(resultText, 0, 0);
|
||||
ctx.restore();
|
||||
|
||||
// Base HP summary
|
||||
const hpY = SCREEN_HEIGHT * 0.2;
|
||||
ctx.font = 'bold 12px Arial';
|
||||
ctx.textAlign = 'center';
|
||||
|
||||
ctx.fillStyle = TEAM_A_COLOR;
|
||||
ctx.fillText(t('teamResult.teamAHp', { hp: this._teamABaseHp }), CENTER_X - 70, hpY);
|
||||
|
||||
ctx.fillStyle = '#AAAAAA';
|
||||
ctx.fillText('vs', CENTER_X, hpY);
|
||||
|
||||
ctx.fillStyle = TEAM_B_COLOR;
|
||||
ctx.fillText(t('teamResult.teamBHp', { hp: this._teamBBaseHp }), CENTER_X + 70, hpY);
|
||||
|
||||
// Win reason
|
||||
let reasonText = t('teamResult.baseDestroyed');
|
||||
if (this._winReason === 'disconnected') {
|
||||
reasonText = t('teamResult.disconnectedReason');
|
||||
}
|
||||
ctx.fillStyle = '#888888';
|
||||
ctx.font = '10px Arial';
|
||||
ctx.fillText(reasonText, CENTER_X, hpY + 16);
|
||||
|
||||
// Player stats table
|
||||
this._renderStatsTable(ctx);
|
||||
|
||||
// Double reward ad button
|
||||
if (!this._adWatched) {
|
||||
this._drawButton(ctx, this._adDoubleBtnRect, t('result.adDouble') || '📺 Double Rewards');
|
||||
}
|
||||
|
||||
// Gold reward display
|
||||
if (this._goldReward > 0) {
|
||||
const goldY = this._adDoubleBtnRect ? this._adDoubleBtnRect.y - 20 : SCREEN_HEIGHT * 0.82;
|
||||
ctx.fillStyle = '#FFD700';
|
||||
ctx.font = 'bold 14px Arial';
|
||||
ctx.textAlign = 'center';
|
||||
const goldLabel = this._adWatched
|
||||
? `🪙 +${this._goldReward} (${t('result.doubled') || '2x!'})`
|
||||
: `🪙 +${this._goldReward}`;
|
||||
ctx.fillText(goldLabel, CENTER_X, goldY);
|
||||
}
|
||||
|
||||
// Buttons
|
||||
if (this._rematchRequested) {
|
||||
// Show waiting state on rematch button
|
||||
const dots = '.'.repeat(Math.floor(this._animTimer * 3) % 4);
|
||||
this._drawButton(ctx, this._rematchBtnRect,
|
||||
t('teamResult.rematchWaiting', { ready: this._rematchReadyCount, total: this._rematchTotalCount }) + dots,
|
||||
true);
|
||||
} else {
|
||||
this._drawButton(ctx, this._rematchBtnRect, t('teamResult.rematch'));
|
||||
}
|
||||
this._drawButton(ctx, this._menuBtnRect, t('teamResult.backMenu'));
|
||||
},
|
||||
|
||||
_renderStatsTable(ctx) {
|
||||
const tableY = SCREEN_HEIGHT * 0.28;
|
||||
const tableW = Math.min(SCREEN_WIDTH * 0.92, 400);
|
||||
const tableX = CENTER_X - tableW / 2;
|
||||
const rowH = 18;
|
||||
const headerH = 22;
|
||||
|
||||
// Sort players: Team A first, then Team B; within team sort by kills desc
|
||||
const teamAPlayers = this._players.filter(p => p.team === 'A');
|
||||
const teamBPlayers = this._players.filter(p => p.team === 'B');
|
||||
|
||||
const sortByKills = (a, b) => {
|
||||
const sa = this._stats[a.playerId] || {};
|
||||
const sb = this._stats[b.playerId] || {};
|
||||
return (sb.kills || 0) - (sa.kills || 0);
|
||||
};
|
||||
teamAPlayers.sort(sortByKills);
|
||||
teamBPlayers.sort(sortByKills);
|
||||
|
||||
// Column positions
|
||||
const cols = {
|
||||
name: tableX + tableW * 0.22,
|
||||
kills: tableX + tableW * 0.48,
|
||||
deaths: tableX + tableW * 0.60,
|
||||
assists: tableX + tableW * 0.72,
|
||||
baseDmg: tableX + tableW * 0.88,
|
||||
};
|
||||
|
||||
// Render Team A section
|
||||
let y = tableY;
|
||||
|
||||
// Team A header
|
||||
ctx.fillStyle = 'rgba(74, 144, 217, 0.15)';
|
||||
ctx.fillRect(tableX, y, tableW, headerH);
|
||||
ctx.fillStyle = TEAM_A_COLOR;
|
||||
ctx.font = 'bold 11px Arial';
|
||||
ctx.textAlign = 'left';
|
||||
ctx.textBaseline = 'middle';
|
||||
ctx.fillText(t('teamResult.teamAHeader') + (this._myTeam === 'A' ? t('teamResult.myTeamSuffix') : ''), tableX + 6, y + headerH / 2);
|
||||
|
||||
// Column headers
|
||||
ctx.fillStyle = '#AAAAAA';
|
||||
ctx.font = '9px Arial';
|
||||
ctx.textAlign = 'center';
|
||||
ctx.fillText(t('teamResult.player'), cols.name, y + headerH / 2);
|
||||
ctx.fillText(t('teamResult.k'), cols.kills, y + headerH / 2);
|
||||
ctx.fillText(t('teamResult.d'), cols.deaths, y + headerH / 2);
|
||||
ctx.fillText(t('teamResult.a'), cols.assists, y + headerH / 2);
|
||||
ctx.fillText(t('teamResult.dmg'), cols.baseDmg, y + headerH / 2);
|
||||
y += headerH;
|
||||
|
||||
// Team A players
|
||||
for (const player of teamAPlayers) {
|
||||
const stats = this._stats[player.playerId] || {};
|
||||
const isLocal = player.isLocal;
|
||||
|
||||
ctx.fillStyle = isLocal ? 'rgba(255, 215, 0, 0.1)' : 'rgba(255,255,255,0.02)';
|
||||
ctx.fillRect(tableX, y, tableW, rowH);
|
||||
|
||||
// Player name
|
||||
ctx.fillStyle = isLocal ? '#FFD700' : '#CCCCCC';
|
||||
ctx.font = isLocal ? 'bold 10px Arial' : '10px Arial';
|
||||
ctx.textAlign = 'center';
|
||||
const name = player.isBot ? t('teamResult.bot') : (player.playerId.length > 10 ? player.playerId.substring(0, 10) + '..' : player.playerId);
|
||||
ctx.fillText(name + (isLocal ? ' ★' : ''), cols.name, y + rowH / 2);
|
||||
|
||||
// Stats
|
||||
ctx.fillStyle = '#FFFFFF';
|
||||
ctx.font = '10px Arial';
|
||||
ctx.fillText(String(stats.kills || 0), cols.kills, y + rowH / 2);
|
||||
ctx.fillText(String(stats.deaths || 0), cols.deaths, y + rowH / 2);
|
||||
ctx.fillText(String(stats.assists || 0), cols.assists, y + rowH / 2);
|
||||
ctx.fillText(String(stats.baseDamage || 0), cols.baseDmg, y + rowH / 2);
|
||||
|
||||
y += rowH;
|
||||
}
|
||||
|
||||
// Separator
|
||||
y += 4;
|
||||
|
||||
// Team B header
|
||||
ctx.fillStyle = 'rgba(233, 69, 96, 0.15)';
|
||||
ctx.fillRect(tableX, y, tableW, headerH);
|
||||
ctx.fillStyle = TEAM_B_COLOR;
|
||||
ctx.font = 'bold 11px Arial';
|
||||
ctx.textAlign = 'left';
|
||||
ctx.fillText(t('teamResult.teamBHeader') + (this._myTeam === 'B' ? t('teamResult.myTeamSuffix') : ''), tableX + 6, y + headerH / 2);
|
||||
|
||||
// Column headers
|
||||
ctx.fillStyle = '#AAAAAA';
|
||||
ctx.font = '9px Arial';
|
||||
ctx.textAlign = 'center';
|
||||
ctx.fillText(t('teamResult.player'), cols.name, y + headerH / 2);
|
||||
ctx.fillText(t('teamResult.k'), cols.kills, y + headerH / 2);
|
||||
ctx.fillText(t('teamResult.d'), cols.deaths, y + headerH / 2);
|
||||
ctx.fillText(t('teamResult.a'), cols.assists, y + headerH / 2);
|
||||
ctx.fillText(t('teamResult.dmg'), cols.baseDmg, y + headerH / 2);
|
||||
y += headerH;
|
||||
|
||||
// Team B players
|
||||
for (const player of teamBPlayers) {
|
||||
const stats = this._stats[player.playerId] || {};
|
||||
const isLocal = player.isLocal;
|
||||
|
||||
ctx.fillStyle = isLocal ? 'rgba(255, 215, 0, 0.1)' : 'rgba(255,255,255,0.02)';
|
||||
ctx.fillRect(tableX, y, tableW, rowH);
|
||||
|
||||
// Player name
|
||||
ctx.fillStyle = isLocal ? '#FFD700' : '#CCCCCC';
|
||||
ctx.font = isLocal ? 'bold 10px Arial' : '10px Arial';
|
||||
ctx.textAlign = 'center';
|
||||
const name = player.isBot ? t('teamResult.bot') : (player.playerId.length > 10 ? player.playerId.substring(0, 10) + '..' : player.playerId);
|
||||
ctx.fillText(name + (isLocal ? ' ★' : ''), cols.name, y + rowH / 2);
|
||||
|
||||
// Stats
|
||||
ctx.fillStyle = '#FFFFFF';
|
||||
ctx.font = '10px Arial';
|
||||
ctx.fillText(String(stats.kills || 0), cols.kills, y + rowH / 2);
|
||||
ctx.fillText(String(stats.deaths || 0), cols.deaths, y + rowH / 2);
|
||||
ctx.fillText(String(stats.assists || 0), cols.assists, y + rowH / 2);
|
||||
ctx.fillText(String(stats.baseDamage || 0), cols.baseDmg, y + rowH / 2);
|
||||
|
||||
y += rowH;
|
||||
}
|
||||
|
||||
// Elapsed time display
|
||||
if (this._elapsedTime > 0) {
|
||||
y += 8;
|
||||
const minutes = Math.floor(this._elapsedTime / 60);
|
||||
const seconds = this._elapsedTime % 60;
|
||||
ctx.fillStyle = '#666666';
|
||||
ctx.font = '10px Arial';
|
||||
ctx.textAlign = 'center';
|
||||
ctx.fillText(
|
||||
t('teamResult.duration', { time: `${minutes}:${seconds.toString().padStart(2, '0')}` }),
|
||||
CENTER_X,
|
||||
y
|
||||
);
|
||||
}
|
||||
|
||||
// MVP highlight (player with most kills)
|
||||
const allPlayers = [...teamAPlayers, ...teamBPlayers];
|
||||
let mvp = null;
|
||||
let maxKills = 0;
|
||||
for (const p of allPlayers) {
|
||||
const s = this._stats[p.playerId] || {};
|
||||
if ((s.kills || 0) > maxKills) {
|
||||
maxKills = s.kills || 0;
|
||||
mvp = p;
|
||||
}
|
||||
}
|
||||
if (mvp && maxKills > 0) {
|
||||
y += 16;
|
||||
ctx.fillStyle = '#FFD700';
|
||||
ctx.font = 'bold 11px Arial';
|
||||
ctx.textAlign = 'center';
|
||||
const mvpName = mvp.isBot ? t('teamResult.bot').replace('🤖 ', '') : mvp.playerId;
|
||||
ctx.fillText(t('teamResult.mvp', { name: mvpName, kills: maxKills }), CENTER_X, y);
|
||||
}
|
||||
|
||||
// Rank points change
|
||||
y += 18;
|
||||
const basePoints = 20;
|
||||
const mvpBonus = 5;
|
||||
if (this._didWin) {
|
||||
const isMvp = mvp && mvp.isLocal;
|
||||
const points = basePoints + (isMvp ? mvpBonus : 0);
|
||||
ctx.fillStyle = '#00FF00';
|
||||
ctx.font = 'bold 11px Arial';
|
||||
ctx.textAlign = 'center';
|
||||
ctx.fillText(t('teamResult.rankUp', { points }) + (isMvp ? t('teamResult.mvpBonus') : ''), CENTER_X, y);
|
||||
} else {
|
||||
ctx.fillStyle = '#FF6347';
|
||||
ctx.font = 'bold 11px Arial';
|
||||
ctx.textAlign = 'center';
|
||||
ctx.fillText(t('teamResult.rankDown', { points: basePoints }), CENTER_X, y);
|
||||
}
|
||||
},
|
||||
|
||||
_drawButton(ctx, rect, label) {
|
||||
if (!rect) return;
|
||||
|
||||
ctx.fillStyle = COLORS.MENU_BTN;
|
||||
ctx.strokeStyle = COLORS.MENU_BTN_BORDER;
|
||||
ctx.lineWidth = 2;
|
||||
|
||||
const r = 6;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(rect.x + r, rect.y);
|
||||
ctx.lineTo(rect.x + rect.w - r, rect.y);
|
||||
ctx.arcTo(rect.x + rect.w, rect.y, rect.x + rect.w, rect.y + r, r);
|
||||
ctx.lineTo(rect.x + rect.w, rect.y + rect.h - r);
|
||||
ctx.arcTo(rect.x + rect.w, rect.y + rect.h, rect.x + rect.w - r, rect.y + rect.h, r);
|
||||
ctx.lineTo(rect.x + r, rect.y + rect.h);
|
||||
ctx.arcTo(rect.x, rect.y + rect.h, rect.x, rect.y + rect.h - r, r);
|
||||
ctx.lineTo(rect.x, rect.y + r);
|
||||
ctx.arcTo(rect.x, rect.y, rect.x + r, rect.y, r);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
ctx.stroke();
|
||||
|
||||
ctx.fillStyle = COLORS.MENU_BTN_TEXT;
|
||||
ctx.font = 'bold 14px Arial';
|
||||
ctx.textAlign = 'center';
|
||||
ctx.textBaseline = 'middle';
|
||||
ctx.fillText(label, rect.x + rect.w / 2, rect.y + rect.h / 2);
|
||||
},
|
||||
|
||||
_hitTest(tx, ty, rect) {
|
||||
if (!rect) return false;
|
||||
return tx >= rect.x && tx <= rect.x + rect.w && ty >= rect.y && ty <= rect.y + rect.h;
|
||||
},
|
||||
|
||||
handleTouch(eventType, e) {
|
||||
if (eventType !== 'touchstart') return;
|
||||
|
||||
const touch = e.touches[0];
|
||||
const tx = touch.clientX;
|
||||
const ty = touch.clientY;
|
||||
|
||||
// Double reward ad button
|
||||
if (!this._adWatched && this._hitTest(tx, ty, this._adDoubleBtnRect)) {
|
||||
const AdManager = require('../managers/AdManager');
|
||||
if (GameGlobal.adManager &&
|
||||
GameGlobal.adManager.canShowScene(AdManager.AD_SCENE.DOUBLE_REWARD)) {
|
||||
GameGlobal.adManager.showRewardedVideoForScene(
|
||||
AdManager.AD_SCENE.DOUBLE_REWARD,
|
||||
(completed) => {
|
||||
if (completed) {
|
||||
this._adWatched = true;
|
||||
// Award bonus gold (double the original reward)
|
||||
if (this._goldReward > 0 && GameGlobal.currencyManager) {
|
||||
GameGlobal.currencyManager.addGold(this._goldReward);
|
||||
this._goldReward *= 2; // Update display
|
||||
}
|
||||
console.log('[TeamResultScene] Double reward ad completed');
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Rematch button -> send rematch request to server (reuse room)
|
||||
if (this._hitTest(tx, ty, this._rematchBtnRect)) {
|
||||
if (!this._rematchRequested) {
|
||||
this._rematchRequested = true;
|
||||
const nm = this._networkManager;
|
||||
console.log(`[TeamResultScene] Rematch clicked. nm=${!!nm}, connected=${nm ? nm.connected : 'N/A'}, teamId=${this._teamId}`);
|
||||
if (nm && nm.connected) {
|
||||
nm.send(NET_MSG.REMATCH, { teamId: this._teamId });
|
||||
console.log('[TeamResultScene] Rematch request sent');
|
||||
} else {
|
||||
// Not connected, fall back to creating a new room
|
||||
this._rematchRequested = false;
|
||||
const sm = GameGlobal.sceneManager;
|
||||
if (this._battleMode === '1v1') {
|
||||
if (!sm._scenes.has(SCENE.PVP_ROOM)) {
|
||||
const RoomScene = require('./RoomScene');
|
||||
sm.register(SCENE.PVP_ROOM, RoomScene);
|
||||
}
|
||||
sm.switchTo(SCENE.PVP_ROOM);
|
||||
} else {
|
||||
if (!sm._scenes.has(SCENE.TEAM_ROOM)) {
|
||||
const TeamRoomScene = require('./TeamRoomScene');
|
||||
sm.register(SCENE.TEAM_ROOM, TeamRoomScene);
|
||||
}
|
||||
sm.switchTo(SCENE.TEAM_ROOM);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Menu button -> disconnect and go to menu
|
||||
if (this._hitTest(tx, ty, this._menuBtnRect)) {
|
||||
// Show interstitial ad when leaving
|
||||
if (GameGlobal.adManager) {
|
||||
GameGlobal.adManager.showInterstitial();
|
||||
}
|
||||
if (GameGlobal.networkManager && GameGlobal.networkManager.connected) {
|
||||
GameGlobal.networkManager.disconnect();
|
||||
}
|
||||
const sm = GameGlobal.sceneManager;
|
||||
sm.switchTo(SCENE.MENU);
|
||||
return;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = TeamResultScene;
|
||||
Reference in New Issue
Block a user