Initial commit

This commit is contained in:
Rocks011
2025-12-10 17:47:15 +08:00
commit 94fb922f1f
50 changed files with 1059 additions and 0 deletions

52
js/runtime/background.js Normal file
View File

@@ -0,0 +1,52 @@
import Sprite from '../base/sprite';
import { SCREEN_WIDTH, SCREEN_HEIGHT } from '../render';
const BACKGROUND_IMAGE_SRC = 'images/bg.jpg';
const BACKGROUND_WIDTH = 512;
const BACKGROUND_HEIGHT = 512;
const BACKGROUND_SPEED = 2;
/**
* 游戏背景类
* 提供 update 和 render 函数实现无限滚动的背景功能
*/
export default class BackGround extends Sprite {
constructor() {
super(BACKGROUND_IMAGE_SRC, SCREEN_WIDTH, SCREEN_HEIGHT);
}
update() {
// 背景不再滚动
}
/**
* 背景图重绘函数
* 绘制一张静态图片
*/
render(ctx) {
ctx.drawImage(
this.img,
0,
0,
this.width,
this.height,
0,
0,
SCREEN_WIDTH,
SCREEN_HEIGHT
);
// 绘制第二张背景
ctx.drawImage(
this.img,
0,
0,
this.width,
this.height,
0,
BACKGROUND_HEIGHT,
SCREEN_WIDTH,
SCREEN_HEIGHT
);
}
}

111
js/runtime/gameinfo.js Normal file
View File

@@ -0,0 +1,111 @@
import Emitter from '../libs/tinyemitter';
import { SCREEN_WIDTH, SCREEN_HEIGHT } from '../render';
const atlas = wx.createImage();
atlas.src = 'images/Common.png';
export default class GameInfo extends Emitter {
constructor() {
super();
this.btnArea = {
startX: SCREEN_WIDTH / 2 - 40,
startY: SCREEN_HEIGHT / 2 - 100 + 180,
endX: SCREEN_WIDTH / 2 + 50,
endY: SCREEN_HEIGHT / 2 - 100 + 255,
};
// 绑定触摸事件
wx.onTouchStart(this.touchEventHandler.bind(this))
}
setFont(ctx) {
ctx.fillStyle = '#ffffff';
ctx.font = '20px Arial';
}
render(ctx) {
this.renderGameScore(ctx, GameGlobal.databus.score); // 绘制当前分数
// 游戏结束时停止帧循环并显示游戏结束画面
if (GameGlobal.databus.isGameOver) {
this.renderGameOver(ctx, GameGlobal.databus.score); // 绘制游戏结束画面
}
}
renderGameScore(ctx, score) {
this.setFont(ctx);
ctx.fillText(score, 10, 30);
}
renderGameOver(ctx, score) {
this.drawGameOverImage(ctx);
this.drawGameOverText(ctx, score);
this.drawRestartButton(ctx);
}
drawGameOverImage(ctx) {
ctx.drawImage(
atlas,
0,
0,
119,
108,
SCREEN_WIDTH / 2 - 150,
SCREEN_HEIGHT / 2 - 100,
300,
300
);
}
drawGameOverText(ctx, score) {
this.setFont(ctx);
ctx.fillText(
'游戏结束',
SCREEN_WIDTH / 2 - 40,
SCREEN_HEIGHT / 2 - 100 + 50
);
ctx.fillText(
`得分: ${score}`,
SCREEN_WIDTH / 2 - 40,
SCREEN_HEIGHT / 2 - 100 + 130
);
}
drawRestartButton(ctx) {
ctx.drawImage(
atlas,
120,
6,
39,
24,
SCREEN_WIDTH / 2 - 60,
SCREEN_HEIGHT / 2 - 100 + 180,
120,
40
);
ctx.fillText(
'重新开始',
SCREEN_WIDTH / 2 - 40,
SCREEN_HEIGHT / 2 - 100 + 205
);
}
touchEventHandler(event) {
const { clientX, clientY } = event.touches[0]; // 获取触摸点的坐标
// 当前只有游戏结束时展示了UI所以只处理游戏结束时的状态
if (GameGlobal.databus.isGameOver) {
// 检查触摸是否在按钮区域内
if (
clientX >= this.btnArea.startX &&
clientX <= this.btnArea.endX &&
clientY >= this.btnArea.startY &&
clientY <= this.btnArea.endY
) {
// 调用重启游戏的回调函数
this.emit('restart');
}
}
}
}

32
js/runtime/music.js Normal file
View File

@@ -0,0 +1,32 @@
let instance;
/**
* 统一的音效管理器
*/
export default class Music {
bgmAudio = wx.createInnerAudioContext();
shootAudio = wx.createInnerAudioContext();
boomAudio = wx.createInnerAudioContext();
constructor() {
if (instance) return instance;
instance = this;
this.bgmAudio.loop = true; // 背景音乐循环播放
this.bgmAudio.autoplay = true; // 背景音乐自动播放
this.bgmAudio.src = 'audio/bgm.mp3';
this.shootAudio.src = 'audio/bullet.mp3';
this.boomAudio.src = 'audio/boom.mp3';
}
playShoot() {
this.shootAudio.currentTime = 0;
this.shootAudio.play();
}
playExplosion() {
this.boomAudio.currentTime = 0;
this.boomAudio.play();
}
}