新建项目
This commit is contained in:
82
pages/join/join.js
Normal file
82
pages/join/join.js
Normal file
@@ -0,0 +1,82 @@
|
||||
const service = require("../../services/game-service");
|
||||
|
||||
Page({
|
||||
data: {
|
||||
code: "",
|
||||
name: "我",
|
||||
avatar: "我",
|
||||
preview: null,
|
||||
previewHint: "",
|
||||
canJoin: false,
|
||||
submitting: false
|
||||
},
|
||||
|
||||
onLoad(options) {
|
||||
if (options.code) {
|
||||
this.setData({ code: options.code });
|
||||
this.previewRoom(options.code);
|
||||
}
|
||||
},
|
||||
|
||||
onCodeInput(event) {
|
||||
const code = event.detail.value.replace(/\D/g, "").slice(0, 6);
|
||||
this.setData({ code, preview: null, previewHint: "", canJoin: false });
|
||||
if (code.length === 6) this.previewRoom(code);
|
||||
},
|
||||
|
||||
onNameInput(event) {
|
||||
const name = event.detail.value;
|
||||
this.setData({ name, avatar: name.slice(0, 1) || "?" });
|
||||
},
|
||||
|
||||
previewRoom(code) {
|
||||
const preview = service.getRoom(code);
|
||||
let previewHint = "";
|
||||
let canJoin = false;
|
||||
if (!preview) {
|
||||
previewHint = "没有找到这个房间,请检查房间码";
|
||||
} else if (preview.status === "finished") {
|
||||
previewHint = "这场游戏已经结束";
|
||||
} else if (preview.status === "cancelled") {
|
||||
previewHint = "房间已被房主取消";
|
||||
} else if (preview.status !== "waiting") {
|
||||
previewHint = "游戏已经开始,暂时无法加入";
|
||||
} else {
|
||||
const alreadyJoined = preview.players.some(
|
||||
(player) => player.id === service.USER_ID
|
||||
);
|
||||
canJoin = alreadyJoined || preview.players.length < preview.settings.maxPlayers;
|
||||
if (!canJoin) previewHint = "房间人数已满";
|
||||
}
|
||||
this.setData({ preview, previewHint, canJoin });
|
||||
},
|
||||
|
||||
useDemoCode() {
|
||||
this.setData({ code: "731204" });
|
||||
this.previewRoom("731204");
|
||||
},
|
||||
|
||||
join() {
|
||||
if (this.data.submitting) return;
|
||||
if (this.data.code.length !== 6) {
|
||||
wx.showToast({ title: "请输入六位房间码", icon: "none" });
|
||||
return;
|
||||
}
|
||||
if (!this.data.name.trim()) {
|
||||
wx.showToast({ title: "请输入游戏昵称", icon: "none" });
|
||||
return;
|
||||
}
|
||||
if (!this.data.canJoin) {
|
||||
wx.showToast({ title: this.data.previewHint || "当前不能加入房间", icon: "none" });
|
||||
return;
|
||||
}
|
||||
this.setData({ submitting: true });
|
||||
try {
|
||||
const room = service.joinRoom(this.data.code, this.data.name.trim());
|
||||
wx.redirectTo({ url: `/pages/lobby/lobby?code=${room.code}` });
|
||||
} catch (error) {
|
||||
this.setData({ submitting: false });
|
||||
wx.showToast({ title: error.message, icon: "none" });
|
||||
}
|
||||
}
|
||||
});
|
||||
3
pages/join/join.json
Normal file
3
pages/join/join.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"navigationBarTitleText": "加入游戏"
|
||||
}
|
||||
57
pages/join/join.wxml
Normal file
57
pages/join/join.wxml
Normal file
@@ -0,0 +1,57 @@
|
||||
<view class="page join-page">
|
||||
<view class="eyebrow">JOIN THE GAME</view>
|
||||
<view class="title">找到你的队伍</view>
|
||||
<view class="subtitle">向房主索取六位房间码,或直接打开好友分享的小程序卡片。</view>
|
||||
|
||||
<view class="code-card">
|
||||
<view class="code-label">房间码</view>
|
||||
<input
|
||||
type="number"
|
||||
maxlength="6"
|
||||
value="{{code}}"
|
||||
placeholder="000000"
|
||||
focus
|
||||
bindinput="onCodeInput"
|
||||
/>
|
||||
<view class="demo-link" bindtap="useDemoCode">没有房间?使用演示房间 731204</view>
|
||||
</view>
|
||||
|
||||
<view wx:if="{{preview}}" class="card room-preview">
|
||||
<view class="row between">
|
||||
<view>
|
||||
<view class="preview-label">找到房间</view>
|
||||
<view class="card-title">{{preview.name}}</view>
|
||||
</view>
|
||||
<view class="pill">{{preview.players.length}} / {{preview.settings.maxPlayers}} 人</view>
|
||||
</view>
|
||||
<view class="divider"></view>
|
||||
<view class="preview-meta">
|
||||
<text>{{preview.settings.mode === 'infection' ? '感染模式' : '经典模式'}}</text>
|
||||
<text>{{preview.settings.durationMinutes}} 分钟</text>
|
||||
<text>{{preview.settings.radiusMeters}} 米范围</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view wx:if="{{previewHint}}" class="preview-error">{{previewHint}}</view>
|
||||
|
||||
<view class="section-label">你的游戏昵称</view>
|
||||
<view class="name-input">
|
||||
<view class="name-avatar">{{avatar}}</view>
|
||||
<input
|
||||
maxlength="10"
|
||||
value="{{name}}"
|
||||
placeholder="输入昵称"
|
||||
bindinput="onNameInput"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<button
|
||||
class="primary-button join-button"
|
||||
loading="{{submitting}}"
|
||||
disabled="{{submitting || !canJoin}}"
|
||||
bindtap="join"
|
||||
>
|
||||
加入房间
|
||||
</button>
|
||||
<view class="privacy-tip">加入即表示你同意本局安全规则。精确位置不会直接展示给其他玩家。</view>
|
||||
</view>
|
||||
91
pages/join/join.wxss
Normal file
91
pages/join/join.wxss
Normal file
@@ -0,0 +1,91 @@
|
||||
.code-card {
|
||||
margin-top: 44rpx;
|
||||
padding: 34rpx 30rpx;
|
||||
background: #183f31;
|
||||
border-radius: 32rpx;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.code-label {
|
||||
color: rgba(255, 255, 255, 0.66);
|
||||
font-size: 23rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.code-card input {
|
||||
height: 130rpx;
|
||||
color: #d9ef72;
|
||||
font-size: 70rpx;
|
||||
font-weight: 900;
|
||||
letter-spacing: 16rpx;
|
||||
}
|
||||
|
||||
.demo-link {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
font-size: 23rpx;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.preview-label {
|
||||
margin-bottom: 8rpx;
|
||||
color: #1d6b4f;
|
||||
font-size: 22rpx;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.preview-meta {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 24rpx;
|
||||
color: #68726c;
|
||||
font-size: 23rpx;
|
||||
}
|
||||
|
||||
.preview-error {
|
||||
margin-top: 18rpx;
|
||||
padding: 20rpx 24rpx;
|
||||
background: #fff0ee;
|
||||
border-radius: 20rpx;
|
||||
color: #a63b35;
|
||||
font-size: 23rpx;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.name-input {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20rpx;
|
||||
padding: 18rpx 24rpx;
|
||||
background: #fffdf7;
|
||||
border-radius: 24rpx;
|
||||
}
|
||||
|
||||
.name-avatar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 70rpx;
|
||||
height: 70rpx;
|
||||
background: #d9ef72;
|
||||
border-radius: 50%;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.name-input input {
|
||||
flex: 1;
|
||||
height: 70rpx;
|
||||
font-size: 29rpx;
|
||||
}
|
||||
|
||||
.join-button {
|
||||
margin-top: 40rpx;
|
||||
}
|
||||
|
||||
.privacy-tip {
|
||||
padding: 22rpx;
|
||||
color: #7c8580;
|
||||
font-size: 22rpx;
|
||||
line-height: 1.6;
|
||||
text-align: center;
|
||||
}
|
||||
Reference in New Issue
Block a user