289 lines
9.5 KiB
HTML
289 lines
9.5 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||
<title>{{GAME_TITLE}}</title>
|
||
<script src="https://game-cdn.poki.com/scripts/v2/poki-sdk.js"></script>
|
||
<script src="https://code.playcanvas.com/playcanvas-stable.min.js"></script>
|
||
<style>
|
||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||
html, body {
|
||
width: 100%;
|
||
height: 100%;
|
||
overflow: hidden;
|
||
background: #0a0a1a;
|
||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||
}
|
||
#game-container {
|
||
width: 100%;
|
||
height: 100%;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
}
|
||
canvas {
|
||
display: block;
|
||
box-shadow: 0 0 40px rgba(0, 100, 255, 0.3);
|
||
}
|
||
/* Poki SDK 要求:防止页面滚动 */
|
||
body { position: fixed; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div id="game-container">
|
||
<canvas id="application"></canvas>
|
||
</div>
|
||
|
||
<script>
|
||
// ============================================
|
||
// Poki SDK 集成框架
|
||
// ============================================
|
||
class PokiManager {
|
||
constructor() {
|
||
this.initialized = false;
|
||
this.audioEnabled = true;
|
||
}
|
||
|
||
async init() {
|
||
try {
|
||
await PokiSDK.init();
|
||
console.log('✅ Poki SDK 初始化成功');
|
||
this.initialized = true;
|
||
|
||
// 游戏加载完成
|
||
PokiSDK.gameLoadingFinished();
|
||
|
||
// 禁用页面滚动
|
||
this.disableScroll();
|
||
} catch (err) {
|
||
console.warn('⚠️ Poki SDK 初始化失败:', err);
|
||
this.initialized = false;
|
||
}
|
||
}
|
||
|
||
disableScroll() {
|
||
window.addEventListener('keydown', (e) => {
|
||
if (['ArrowDown', 'ArrowUp', ' '].includes(e.key)) {
|
||
e.preventDefault();
|
||
}
|
||
});
|
||
window.addEventListener('wheel', (e) => e.preventDefault(), { passive: false });
|
||
}
|
||
|
||
// 游戏开始
|
||
gameplayStart() {
|
||
if (this.initialized) {
|
||
PokiSDK.gameplayStart();
|
||
}
|
||
}
|
||
|
||
// 游戏暂停/结束
|
||
gameplayStop() {
|
||
if (this.initialized) {
|
||
PokiSDK.gameplayStop();
|
||
this.showAd();
|
||
}
|
||
}
|
||
|
||
// 显示广告
|
||
async showAd() {
|
||
if (!this.initialized) return;
|
||
|
||
try {
|
||
await PokiSDK.commercialBreak(() => {
|
||
// 暂停音频
|
||
this.audioEnabled = false;
|
||
});
|
||
// 恢复音频
|
||
this.audioEnabled = true;
|
||
} catch (err) {
|
||
console.warn('广告播放失败:', err);
|
||
}
|
||
}
|
||
|
||
// 奖励广告
|
||
async showRewardedAd(size = 'medium') {
|
||
if (!this.initialized) return false;
|
||
|
||
try {
|
||
const success = await PokiSDK.rewardedBreak({
|
||
size: size,
|
||
onStart: () => { this.audioEnabled = false; }
|
||
});
|
||
this.audioEnabled = true;
|
||
return success;
|
||
} catch (err) {
|
||
this.audioEnabled = true;
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
|
||
// ============================================
|
||
// PlayCanvas 游戏框架
|
||
// ============================================
|
||
class GameFramework {
|
||
constructor() {
|
||
// 固定竖屏分辨率
|
||
this.width = 480;
|
||
this.height = 640;
|
||
|
||
// 初始化 PlayCanvas
|
||
this.canvas = document.getElementById('application');
|
||
this.app = new pc.Application(this.canvas, {
|
||
mouse: new pc.Mouse(this.canvas),
|
||
touch: new pc.TouchDevice(this.canvas),
|
||
elementInput: new pc.ElementInput(this.canvas)
|
||
});
|
||
|
||
this.app.start();
|
||
this.app.setCanvasFillMode(pc.FILLMODE_NONE);
|
||
this.app.setCanvasResolution(pc.RESOLUTION_AUTO);
|
||
|
||
// 响应式调整
|
||
this.resize();
|
||
window.addEventListener('resize', () => this.resize());
|
||
|
||
// Poki 管理器
|
||
this.poki = new PokiManager();
|
||
|
||
// 游戏状态
|
||
this.state = 'loading'; // loading, menu, playing, paused, gameover
|
||
this.score = 0;
|
||
|
||
// 初始化
|
||
this.init();
|
||
}
|
||
|
||
resize() {
|
||
const container = document.getElementById('game-container');
|
||
const aspect = this.width / this.height;
|
||
const containerAspect = container.clientWidth / container.clientHeight;
|
||
|
||
let canvasWidth, canvasHeight;
|
||
if (containerAspect > aspect) {
|
||
canvasHeight = container.clientHeight;
|
||
canvasWidth = canvasHeight * aspect;
|
||
} else {
|
||
canvasWidth = container.clientWidth;
|
||
canvasHeight = canvasWidth / aspect;
|
||
}
|
||
|
||
this.canvas.style.width = canvasWidth + 'px';
|
||
this.canvas.style.height = canvasHeight + 'px';
|
||
this.app.resizeCanvas(canvasWidth, canvasHeight);
|
||
}
|
||
|
||
async init() {
|
||
// 创建基础场景
|
||
this.createScene();
|
||
|
||
// 初始化 Poki
|
||
await this.poki.init();
|
||
|
||
// 切换到菜单
|
||
this.showMenu();
|
||
}
|
||
|
||
createScene() {
|
||
// 创建相机
|
||
const camera = new pc.Entity('camera');
|
||
camera.addComponent('camera', {
|
||
clearColor: new pc.Color(0.04, 0.04, 0.1),
|
||
projection: pc.PROJECTION_ORTHOGRAPHIC,
|
||
orthoHeight: this.height / 2
|
||
});
|
||
camera.setPosition(0, 0, 10);
|
||
this.app.root.addChild(camera);
|
||
this.camera = camera;
|
||
|
||
// 创建灯光
|
||
const light = new pc.Entity('light');
|
||
light.addComponent('light', {
|
||
type: 'directional',
|
||
color: new pc.Color(1, 1, 1),
|
||
intensity: 1
|
||
});
|
||
light.setEulerAngles(45, 30, 0);
|
||
this.app.root.addChild(light);
|
||
|
||
// 创建2D渲染层(用于UI)
|
||
this.createUI();
|
||
}
|
||
|
||
createUI() {
|
||
// 由子类实现
|
||
}
|
||
|
||
// 状态切换
|
||
showMenu() {
|
||
this.state = 'menu';
|
||
this.poki.gameplayStop();
|
||
}
|
||
|
||
startGame() {
|
||
this.state = 'playing';
|
||
this.score = 0;
|
||
this.poki.gameplayStart();
|
||
}
|
||
|
||
pauseGame() {
|
||
if (this.state === 'playing') {
|
||
this.state = 'paused';
|
||
this.poki.gameplayStop();
|
||
}
|
||
}
|
||
|
||
resumeGame() {
|
||
if (this.state === 'paused') {
|
||
this.state = 'playing';
|
||
this.poki.gameplayStart();
|
||
}
|
||
}
|
||
|
||
gameOver() {
|
||
this.state = 'gameover';
|
||
this.poki.gameplayStop();
|
||
}
|
||
|
||
// 工具方法:创建精灵
|
||
createSprite(name, x, y, width, height, color) {
|
||
const entity = new pc.Entity(name);
|
||
entity.addComponent('render', {
|
||
type: 'plane'
|
||
});
|
||
entity.setLocalScale(width, 1, height);
|
||
entity.setPosition(x, y, 0);
|
||
|
||
// 创建材质
|
||
const material = new pc.StandardMaterial();
|
||
material.diffuse = color;
|
||
material.update();
|
||
entity.render.material = material;
|
||
|
||
return entity;
|
||
}
|
||
|
||
// 工具方法:创建文字
|
||
createText(text, x, y, options = {}) {
|
||
const entity = new pc.Entity('text');
|
||
entity.addComponent('element', {
|
||
type: 'text',
|
||
text: text,
|
||
fontSize: options.fontSize || 32,
|
||
color: options.color || new pc.Color(1, 1, 1),
|
||
anchor: new pc.Vec4(0.5, 0.5, 0.5, 0.5),
|
||
pivot: new pc.Vec2(0.5, 0.5)
|
||
});
|
||
entity.setPosition(x, y, 0);
|
||
return entity;
|
||
}
|
||
}
|
||
|
||
// 启动游戏(由具体游戏实现)
|
||
// const game = new MyGame();
|
||
</script>
|
||
</body>
|
||
</html>
|