Files
nanocode/happy-games/templates/playcanvas-poki-template.html
T
Ubuntu 32b43f85bd a
2026-07-03 16:58:28 +08:00

289 lines
9.5 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!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>