uniapp首先对战匹配简单实现
首先我们上效果图
该界面帮朋友写的,支持响应式,下面我贴出全部代码
<template><view class="container"><!-- 头部 --><view class="header"><view class="title">魔方对战</view><view class="subtitle">选择模式,开始匹配对手</view></view><!-- 模式选择 --><view class="mode-selection"><view class="mode-card" :class="{ active: selectedMode === '1v1' }"@click="selectMode('1v1')"><view class="mode-icon"><text class="icon">👤</text><text class="icon">👤</text></view><view class="mode-title">1v1 对战</view><view class="mode-desc">{{ useAI ? '与AI对战,练习魔方技巧' : '与一名玩家对战,展示魔方技巧' }}</view></view><view class="mode-card" :class="{ active: selectedMode === '2v2' }"@click="selectMode('2v2')"><view class="mode-icon"><text class="icon">👥</text><text class="icon">👥</text></view><view class="mode-title">2v2 组队</view><view class="mode-desc">{{ useAI ? '与AI队友合作完成挑战' : '与队友合作完成魔方挑战' }}</view></view></view><!-- AI选项 --><view class="ai-option"><text class="ai-label">添加AI对手</text><switch :checked="useAI" @change="toggleAI" color="#fdbb2d" /></view><!-- 匹配按钮 --><button class="match-button" :disabled="isMatching"@click="startMatching">{{ isMatching ? '匹配中...' : '开始匹配' }}</button><!-- 匹配中动画 --><view class="matching-container" v-if="isMatching"><view class="matching-title">寻找对手中</view><view class="loading-dots"><view class="dot"></view><view class="dot"></view><view class="dot"></view></view><view class="wait-time">已等待 {{ waitTime }} 秒</view><view class="players-container"><view class="player"><view class="player-avatar"><text>👤</text></view><text class="player-name">你</text></view></view><button class="cancel-button" @click="cancelMatching">取消匹配</button></view><!-- 房间信息 --><view class="room-container" v-if="roomId"><view class="room-title">匹配成功!</view><view class="room-id">房间号: ROOM-{{ roomId }}</view><view class="players-container"><view class="player"><view class="player-avatar"><text>👤</text></view><text class="player-name">你</text></view><view class="player" :class="{ ai: useAI }"><view class="player-avatar"><text>{{ useAI ? '🤖' : '👤' }}</text></view><text class="player-name">{{ useAI ? 'AI对手' : '玩家2' }}</text></view><view class="player" v-if="selectedMode === '2v2'"><view class="player-avatar"><text>{{ useAI ? '🤖' : '👤' }}</text></view><text class="player-name">{{ useAI ? 'AI队友' : '玩家3' }}</text></view><view class="player" v-if="selectedMode === '2v2'" :class="{ ai: useAI }"><view class="player-avatar"><text>{{ useAI ? '🤖' : '👤' }}</text></view><text class="player-name">{{ useAI ? 'AI对手' : '玩家4' }}</text></view></view><button class="start-button" @click="startGame">开始游戏</button></view></view> </template><script>export default {data() {return {selectedMode: '1v1',useAI: false,isMatching: false,waitTime: 0,roomId: null,matchingInterval: null}},methods: {selectMode(mode) {this.selectedMode = mode;},toggleAI(e) {this.useAI = e.detail.value;},startMatching() {this.isMatching = true;this.waitTime = 0;this.roomId = null;// 模拟匹配过程this.matchingInterval = setInterval(() => {this.waitTime++;// 模拟匹配成功(5秒后)if (this.waitTime === 5) {this.completeMatching();}}, 1000);},cancelMatching() {clearInterval(this.matchingInterval);this.isMatching = false;this.waitTime = 0;uni.showToast({title: '已取消匹配',icon: 'none'});},completeMatching() {clearInterval(this.matchingInterval);this.isMatching = false;// 生成随机房间号this.roomId = Math.floor(1000 + Math.random() * 9000);},startGame() {uni.showToast({title: '游戏开始!即将进入魔方对战房间...',icon: 'success'});// 在实际应用中,这里会跳转到游戏页面setTimeout(() => {this.roomId = null;}, 2000);}}} </script><style>/* 全局样式 */.container {padding: 40rpx 20rpx;display: flex;flex-direction: column;align-items: center;min-height: 100vh;background: linear-gradient(135deg, #1a2a6c, #b21f1f, #fdbb2d);color: #fff;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Helvetica, Arial, sans-serif;}/* 头部样式 */.header {text-align: center;margin: 40rpx 0;width: 100%;}.title {font-size: 48rpx;font-weight: bold;color: #fdbb2d;text-shadow: 0 0 10rpx rgba(253, 187, 45, 0.5);margin-bottom: 20rpx;}.subtitle {font-size: 28rpx;opacity: 0.8;}/* 模式选择样式 */.mode-selection {display: flex;flex-direction: column;width: 100%;margin-bottom: 40rpx;}@media (min-width: 768px) {.mode-selection {flex-direction: row;justify-content: space-between;}}.mode-card {background: rgba(255, 255, 255, 0.1);border-radius: 20rpx;padding: 30rpx;margin-bottom: 30rpx;display: flex;flex-direction: column;align-items: center;transition: all 0.3s;border: 4rpx solid transparent;}@media (min-width: 768px) {.mode-card {width: 45%;margin-bottom: 0;}}.mode-card.active {border-color: #fdbb2d;background: rgba(253, 187, 45, 0.2);transform: translateY(-10rpx);box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.3);}.mode-icon {font-size: 80rpx;margin-bottom: 20rpx;color: #fdbb2d;}.mode-title {font-size: 36rpx;margin-bottom: 15rpx;text-align: center;}.mode-desc {font-size: 24rpx;opacity: 0.8;text-align: center;}/* AI选项样式 */.ai-option {display: flex;align-items: center;justify-content: center;margin-bottom: 40rpx;width: 100%;}.ai-label {font-size: 32rpx;margin-right: 20rpx;}/* 按钮样式 */.match-button {background: linear-gradient(to right, #fdbb2d, #b21f1f);color: white;border: none;border-radius: 50rpx;padding: 25rpx 80rpx;font-size: 32rpx;font-weight: bold;margin: 30rpx 0;box-shadow: 0 10rpx 20rpx rgba(178, 31, 31, 0.4);}.match-button:disabled {background: #555;box-shadow: none;}/* 匹配动画样式 */.matching-container {background: rgba(255, 255, 255, 0.1);border-radius: 20rpx;padding: 40rpx;width: 100%;margin-top: 30rpx;display: flex;flex-direction: column;align-items: center;}.matching-title {font-size: 36rpx;margin-bottom: 30rpx;color: #fdbb2d;}.loading-dots {display: flex;justify-content: center;margin: 30rpx 0;}.dot {width: 20rpx;height: 20rpx;background: #fdbb2d;border-radius: 50%;margin: 0 10rpx;animation: pulse 1.5s infinite ease-in-out;}.dot:nth-child(2) {animation-delay: 0.2s;}.dot:nth-child(3) {animation-delay: 0.4s;}@keyframes pulse {0%, 100% { transform: scale(0.8); opacity: 0.5; }50% { transform: scale(1.2); opacity: 1; }}.wait-time {font-size: 28rpx;margin-bottom: 30rpx;}.players-container {display: flex;justify-content: center;flex-wrap: wrap;margin: 30rpx 0;}.player {display: flex;flex-direction: column;align-items: center;margin: 0 20rpx;}.player-avatar {width: 100rpx;height: 100rpx;border-radius: 50%;background: #1a2a6c;display: flex;justify-content: center;align-items: center;font-size: 40rpx;margin-bottom: 15rpx;border: 4rpx solid #fdbb2d;}.player.ai .player-avatar {background: #b21f1f;}.player-name {font-size: 24rpx;}.cancel-button {background: transparent;border: 2rpx solid #fdbb2d;color: #fdbb2d;padding: 20rpx 50rpx;border-radius: 50rpx;font-size: 28rpx;margin-top: 30rpx;}/* 房间信息样式 */.room-container {background: rgba(255, 255, 255, 0.1);border-radius: 20rpx;padding: 40rpx;width: 100%;margin-top: 30rpx;display: flex;flex-direction: column;align-items: center;}.room-title {font-size: 36rpx;margin-bottom: 20rpx;color: #fdbb2d;}.room-id {font-size: 32rpx;margin-bottom: 40rpx;font-weight: bold;}.start-button {background: #1a2a6c;color: white;border: none;border-radius: 50rpx;padding: 20rpx 60rpx;font-size: 32rpx;font-weight: bold;margin-top: 30rpx;} </style>