Commit 1eab45d9 authored by 范雪寒's avatar 范雪寒

feat: 主要在实现滚动条

parent 8a51c964
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -4,6 +4,7 @@ import TWEEN from '@tweenjs/tween.js';
interface AirWindow extends Window {
air: any;
curCtx: any;
curImages: any;
}
declare let window: AirWindow;
......@@ -36,7 +37,6 @@ class Sprite {
export class MySprite extends Sprite {
_width = 0;
......@@ -69,6 +69,13 @@ export class MySprite extends Sprite {
img;
_z = 0;
_showRect;
_bitmapFlag = false;
_offCanvas;
_offCtx;
init(imgObj = null, anchorX: number = 0.5, anchorY: number = 0.5) {
......@@ -87,6 +94,10 @@ export class MySprite extends Sprite {
}
setShowRect(rect) {
this._showRect = rect;
}
setShadow(offX, offY, blur, color = 'rgba(0, 0, 0, 0.3)') {
......@@ -103,6 +114,8 @@ export class MySprite extends Sprite {
}
update($event = null) {
if (!this.visible && this.childDepandVisible) {
return;
......@@ -139,21 +152,21 @@ export class MySprite extends Sprite {
if (this._radius) {
const r = this._radius;
const w = this.width;
const h = this.height;
this.ctx.lineTo(-w / 2, h / 2); // 创建水平线
this.ctx.arcTo(-w / 2, -h / 2, -w / 2 + r, -h / 2, r);
this.ctx.arcTo(w / 2, -h / 2, w / 2, -h / 2 + r, r);
this.ctx.arcTo(w / 2, h / 2, w / 2 - r, h / 2, r);
this.ctx.arcTo(-w / 2, h / 2, -w / 2, h / 2 - r, r);
this.ctx.clip();
}
//
// if (this._radius) {
//
// const r = this._radius;
// const w = this.width;
// const h = this.height;
//
// this.ctx.lineTo(-w / 2, h / 2); // 创建水平线
// this.ctx.arcTo(-w / 2, -h / 2, -w / 2 + r, -h / 2, r);
// this.ctx.arcTo(w / 2, -h / 2, w / 2, -h / 2 + r, r);
// this.ctx.arcTo(w / 2, h / 2, w / 2 - r, h / 2, r);
// this.ctx.arcTo(-w / 2, h / 2, -w / 2, h / 2 - r, r);
//
// this.ctx.clip();
// }
}
......@@ -176,10 +189,14 @@ export class MySprite extends Sprite {
if (this.img) {
if (this._showRect) {
const rect = this._showRect;
this.ctx.drawImage(this.img, rect.x, rect.y, rect.width, rect.height, this._offX + rect.x, this._offY + rect.y, rect.width, rect.height);
} else {
this.ctx.drawImage(this.img, this._offX, this._offY);
}
}
}
......@@ -257,6 +274,13 @@ export class MySprite extends Sprite {
}
}
set bitmapFlag(v) {
this._bitmapFlag = v;
}
get bitmapFlag() {
return this._bitmapFlag;
}
set alpha(v) {
this._alpha = v;
if (this.childDepandAlpha) {
......@@ -305,7 +329,6 @@ export class MySprite extends Sprite {
getBoundingBox() {
const getParentData = (item) => {
let px = item.x;
......@@ -343,11 +366,6 @@ export class MySprite extends Sprite {
const width = this.width * Math.abs(data.sx);
const height = this.height * Math.abs(data.sy);
// const x = this.x + this._offX * Math.abs(this.scaleX);
// const y = this.y + this._offY * Math.abs(this.scaleY);
// const width = this.width * Math.abs(this.scaleX);
// const height = this.height * Math.abs(this.scaleY);
return {x, y, width, height};
}
......@@ -759,6 +777,7 @@ export class RichText extends Label {
disH = 30;
offW = 10;
constructor(ctx?: any) {
super(ctx);
......@@ -788,7 +807,7 @@ export class RichText extends Label {
const chr = this.text.split(' ');
let temp = '';
const row = [];
const w = selfW - 80;
const w = selfW - this.offW * 2;
const disH = (this.fontSize + this.disH) * this.scaleY;
......@@ -1020,7 +1039,7 @@ export class MyAnimation extends MySprite {
loop = false;
playEndFunc;
delayPerUnit = 1;
delayPerUnit = 0.07;
restartFlag = false;
reverseFlag = false;
......@@ -1109,8 +1128,9 @@ export class MyAnimation extends MySprite {
this.frameArr[this.frameIndex].visible = true;
if (this.playEndFunc) {
this.playEndFunc();
const func = this.playEndFunc;
this.playEndFunc = null;
func();
}
}
......@@ -1200,7 +1220,7 @@ export function tweenChange(item, obj, time = 0.8, callBack = null, easing = nul
export function rotateItem(item, rotation, time = 0.8, callBack = null, easing = null) {
export function rotateItem(item, rotation, time = 0.8, callBack = null, easing = null, loop = false) {
const tween = new TWEEN.Tween(item).to({ rotation }, time * 1000);
......@@ -1208,7 +1228,14 @@ export function rotateItem(item, rotation, time = 0.8, callBack = null, easing =
tween.onComplete(() => {
callBack();
});
} else if (loop) {
const speed = (rotation - item.rotation) / time;
tween.onComplete(() => {
item.rotation %= 360;
rotateItem(item, item.rotation + speed * time, time, null, easing, true);
});
}
if (easing) {
tween.easing(easing);
}
......@@ -1525,10 +1552,15 @@ export function formatTime(fmt, date) {
return fmt;
}
export function getMinScale(item, maxLen) {
const sx = maxLen / item.width;
const sy = maxLen / item.height;
export function getMinScale(item, maxW, maxH = null) {
if (!maxH) {
maxH = maxW;
}
const sx = maxW / item.width;
const sy = maxH / item.height;
const minS = Math.min(sx, sy);
return minS;
}
......@@ -1571,6 +1603,46 @@ export function jelly(item, time = 0.7) {
run();
}
export function jellyPop(item, time) {
if (item.jellyTween) {
TWEEN.remove(item.jellyTween);
}
const t = time / 6;
const baseSX = item.scaleX;
const baseSY = item.scaleY;
let index = 0;
const run = () => {
if (index >= arr.length) {
item.jellyTween = null;
return;
}
const data = arr[index];
const t = tweenChange(item, {scaleX: data[0], scaleY: data[1]}, data[2], () => {
index ++;
run();
}, TWEEN.Easing.Sinusoidal.InOut);
item.jellyTween = t;
};
const arr = [
[baseSX * 1.3, baseSY * 1.3, t],
[baseSX * 0.85, baseSY * 0.85, t * 1],
[baseSX * 1.1, baseSY * 1.1, t * 1],
[baseSX * 0.95, baseSY * 0.95, t * 1],
[baseSX * 1.02, baseSY * 1.02, t * 1],
[baseSX * 1, baseSY * 1, t * 1],
];
item.setScaleXY(0);
run();
}
export function showPopParticle(img, pos, parent, num = 20, minLen = 40, maxLen = 80, showTime = 0.4) {
......@@ -1672,5 +1744,41 @@ export function shake(item, time = 0.5, callback = null, rate = 1) {
}
export function getMaxScale(item, maxW, maxH) {
const sx = maxW / item.width;
const sy = maxH / item.height;
const maxS = Math.max(sx, sy);
return maxS;
}
export function createSprite(key) {
const image = window.curImages;
const spr = new MySprite();
spr.init(image.get(key));
return spr;
}
export class MyVideo extends MySprite {
element;
initVideoElement(videoElement) {
this.element = videoElement;
this.width = this.element.videoWidth;
this.height = this.element.videoHeight;
this.element.currentTime = 0.01;
}
drawSelf() {
super.drawSelf();
this.ctx.drawImage(this.element, 0, 0, this.width, this.height);
}
}
// --------------- custom class --------------------
export let defaultData = {
tittle: {
word: "C",
text: "listen and select the right word you just heard.",
audio: "tittle"
},
audio: 'total_audio',
questionsTittle: 'A pig and a bin',
tittleAudio: 'total_audio',
questions: [{
questionTittle: '1',
words: "Let 's put the toys into the box. box. box.",
audio: 'question_1',
blocks: [{
idx: 5,
type: 'red',
audio: 'the',
img: 'cave'
}, {
idx: 6,
type: 'bold'
}],
}, {
questionTittle: '2',
words: "Let 's put the toys into the box.",
audio: 'question_1',
blocks: [{
idx: 5,
type: 'red',
audio: 'the',
img: 'cave'
}, {
idx: 6,
type: 'bold'
}],
}, {
questionTittle: '3',
words: "Let 's put the toys into the box.",
audio: 'question_1',
blocks: [{
idx: 5,
type: 'red',
audio: 'the',
img: 'cave'
}, {
idx: 6,
type: 'bold'
}],
}, {
questionTittle: '3',
words: "Let 's put the toys into the box.",
audio: 'question_1',
blocks: [{
idx: 5,
type: 'red',
audio: 'the',
img: 'cave'
}, {
idx: 6,
type: 'bold'
}],
}, {
questionTittle: '3',
words: "Let 's put the toys into the box.",
audio: 'question_1',
blocks: [{
idx: 5,
type: 'red',
audio: 'the',
img: 'cave'
}, {
idx: 6,
type: 'bold'
}],
}, {
questionTittle: '3',
words: "Let 's put the toys into the box.",
audio: 'question_1',
blocks: [{
idx: 5,
type: 'red',
audio: 'the',
img: 'cave'
}, {
idx: 6,
type: 'bold'
}],
}, {
questionTittle: '3',
words: "Let 's put the toys into the box.",
audio: 'question_1',
blocks: [{
idx: 5,
type: 'red',
audio: 'the',
img: 'cave'
}, {
idx: 6,
type: 'bold'
}],
}, {
questionTittle: '3',
words: "Let 's put the toys into the box.",
audio: 'question_1',
blocks: [{
idx: 5,
type: 'red',
audio: 'the',
img: 'cave'
}, {
idx: 6,
type: 'bold'
}],
}, {
questionTittle: '3',
words: "Let 's put the toys into the box.",
audio: 'question_1',
blocks: [{
idx: 5,
type: 'red',
audio: 'the',
img: 'cave'
}, {
idx: 6,
type: 'bold'
}],
}, {
questionTittle: '4',
words: "Let 's go.",
audio: 'question_1',
blocks: [{
idx: 5,
type: 'red',
audio: 'the',
img: 'cave'
}, {
idx: 6,
type: 'bold'
}],
}, {
questionTittle: '',
words: "Let 's put the toys into the box.",
audio: 'question_1',
blocks: [{
idx: 5,
type: 'red',
audio: 'the',
img: 'cave'
}, {
idx: 6,
type: 'bold'
}],
}, {
questionTittle: '5',
words: "Let 's put the toys into the box.",
audio: 'question_1',
blocks: [{
idx: 5,
type: 'red',
audio: 'the',
img: 'cave'
}, {
idx: 6,
type: 'bold'
}],
}, {
questionTittle: '6',
words: "Let 's put the toys into the box.",
audio: 'question_1',
blocks: [{
idx: 5,
type: 'red',
audio: 'the',
img: 'cave'
}, {
idx: 6,
type: 'bold'
}],
}, {
questionTittle: '7',
words: "Let 's put the toys into the box.",
audio: 'question_1',
blocks: [{
idx: 5,
type: 'red',
audio: 'the',
img: 'cave'
}, {
idx: 6,
type: 'bold'
}],
}, {
questionTittle: '8',
words: "Let 's put the toys into the box.",
audio: 'question_1',
blocks: [{
idx: 5,
type: 'red',
audio: 'the',
img: 'cave'
}, {
idx: 6,
type: 'bold'
}],
}, {
questionTittle: '9',
words: "Let 's put the toys into the box.",
audio: 'question_1',
blocks: [{
idx: 5,
type: 'red',
audio: 'the',
img: 'cave'
}, {
idx: 6,
type: 'bold'
}],
}]
};
\ No newline at end of file
import {
MySprite,
Label,
removeItemFromArr,
hideItem,
showItem,
moveItem,
tweenChange,
} from './../Unit';
import TWEEN from '@tweenjs/tween.js';
export class Game {
_parent = null;
_z = 0;
children: any = [this];
constructor(parent) {
this._parent = parent;
}
initData(data) {
}
initView() {
}
_currentPlayingAudioName;
playAudio(key, now = true, callback = null) {
if (this._currentPlayingAudioName != '') {
const audio = this._parent.audioObj[this._currentPlayingAudioName];
if (audio) {
if (now) {
if (!audio.paused) {
audio.pause();
// audio.currentTime = 0;
}
}
}
}
this._currentPlayingAudioName = key;
this._parent.playAudio(key, now, () => {
this._currentPlayingAudioName = '';
if (callback) {
callback();
}
});
}
getAudioObj(key) {
return this._parent.audioObj[key];
}
_editMode = false;
setEditMode(flg) {
this._editMode = flg;
}
isEditMode() {
return this._editMode;
}
_save;
setSaveFunc(save) {
this._save = save;
}
addChild(node, z = 1) {
this._parent.renderArr.push(node);
if (this.children.indexOf(node) === -1) {
this.children.push(node);
node._z = z;
}
this.children.sort((a, b) => {
return a._z - b._z;
});
}
removeChildren() {
for (let i = 0; i < this.children.length; i++) {
if (this.children[i]) {
if (this.children[i] !== this) {
let child = this.children.splice(i, 1);
removeItemFromArr(this._parent.renderArr, child);
i--;
}
}
}
}
removeChild(child) {
const index = this.children.indexOf(child);
if (index !== -1) {
this.children.splice(index, 1);
}
removeItemFromArr(this._parent.renderArr, child);
}
_checkHitPosition(node, pos) {
let rightNode = null;
if (node.visible && node.alpha > 0 && node._touchEnabled && node._checkHitPosition(pos)) {
rightNode = node;
}
if (node.children.length > 1) {
for (var i = 1; i < node.children.length; ++i) {
if (node.children[i] != node) {
let result = this._checkHitPosition(node.children[i], pos);
if (result != null) {
rightNode = result;
}
}
}
}
return rightNode;
}
_currentTouchSprite = null;
_onTouchBegan(pos) {
let result = this._checkHitPosition(this, pos);
if (result == null) {
return;
}
if (result._onTouchBeganListener &&
typeof (result._onTouchBeganListener) == 'function') {
result._onTouchBeganListener(pos);
}
this._currentTouchSprite = result;
}
_onTouchMove(pos) {
if (this._currentTouchSprite == null) {
return;
}
if (this._currentTouchSprite._onTouchMoveListener &&
typeof (this._currentTouchSprite._onTouchMoveListener) == 'function') {
this._currentTouchSprite._onTouchMoveListener(pos);
}
}
_onTouchEnd(pos) {
if (this._currentTouchSprite == null) {
return;
}
if (this._currentTouchSprite._checkHitPosition(pos)) {
if (this._currentTouchSprite._onTouchEndListener &&
typeof (this._currentTouchSprite._onTouchEndListener) == 'function') {
this._currentTouchSprite._onTouchEndListener(pos);
}
this._currentTouchSprite = null;
} else {
if (this._currentTouchSprite._onTouchCancelListener &&
typeof (this._currentTouchSprite._onTouchCancelListener) == 'function') {
this._currentTouchSprite._onTouchCancelListener(pos);
}
this._currentTouchSprite = null;
}
}
getChildByName(name) {
for (var i = 1; i < this.children.length; ++i) {
let node = this.children[i];
if (node.getName() == name) {
return node;
}
}
return null;
}
seekChildByName(name) {
let result = this.getChildByName(name);
if (result == null) {
for (var i = 1; i < this.children.length; ++i) {
let node = this.children[i];
if (typeof (node.seekChildByName) == 'function') {
result = node.seekChildByName(name);
if (result != null) {
return result;
}
}
}
}
return result;
}
getScreenSize() {
return {
width: this._parent.canvasWidth,
height: this._parent.canvasHeight
};
}
getDefaultScreenSize() {
return {
width: this._parent.canvasBaseW,
height: this._parent.canvasBaseH
};
}
getFullScaleXY() {
let screenSize = this.getScreenSize();
let defaultSize = this.getDefaultScreenSize();
return Math.max(screenSize.height / defaultSize.height, screenSize.width / defaultSize.width);
}
_showMode = false;
showModeOn() {
this._showMode = true;
}
showModeOff() {
this._showMode = false;
}
isShowMode() {
return this._showMode;
}
}
// 节点名
class Nameable {
_parent = null;
constructor(parent) {
this._parent = parent;
}
_name = 'name';
setName(name) {
this._name = name;
}
getName() {
return this._name;
}
getChildByName(name) {
for (var i = 1; i < this._parent.children.length; ++i) {
let node = this._parent.children[i];
if (node.getName() == name) {
return node;
}
}
return null;
}
seekChildByName(name) {
let result = this.getChildByName(name);
if (result == null) {
for (var i = 1; i < this._parent.children.length; ++i) {
let node = this._parent.children[i];
if (typeof (node.seekChildByName) == 'function') {
result = node.seekChildByName(name);
if (result != null) {
return result;
}
}
}
}
return result;
}
}
class UserData {
// 用户自定义数据
userData = {};
get(key) {
return this.userData[key];
}
set(key, value) {
this.userData[key] = value;
}
}
export class MyLabel extends Label {
_nameable = new Nameable(this);
setName(name) {
this._nameable.setName(name);
}
getName() {
return this._nameable.getName();
}
getChildByName(name) {
return this._nameable.getChildByName(name);
}
seekChildByName(name) {
return this._nameable.seekChildByName(name);
}
// 位置
setPosition(x: any = 0, y = undefined) {
if (y !== undefined) {
this.x = x;
this.y = y;
} else {
this.x = x.x;
this.y = x.y;
}
}
setPositionX(x = 0) {
this.x = x;
}
setPositionY(y = 0) {
this.y = y;
}
_userData = new UserData();
get(key) {
return this._userData.get(key);
}
set(key, value) {
this._userData.set(key, value);
}
_touchEnabled = false;
// _swallowTouches = false; // TODO:多重触摸以后用到了再说
_onTouchBeganListener = null;
_onTouchMoveListener = null;
_onTouchEndListener = null;
_onTouchCancelListener = null;
addTouchBeganListener(func) {
this._touchEnabled = true;
this._onTouchBeganListener = func;
}
addTouchMoveListener(func) {
this._touchEnabled = true;
this._onTouchMoveListener = func;
}
addTouchEndListener(func) {
this._touchEnabled = true;
this._onTouchEndListener = func;
}
addTouchCancelListener(func) {
this._touchEnabled = true;
this._onTouchCancelListener = func;
}
_checkHitPosition(pos) {
const rect = this.getBoundingBox();
if (this._checkPointInRect(pos.x, pos.y, rect)) {
return true;
}
return false;
}
_checkPointInRect(x, y, rect) {
if (x >= rect.x && x <= rect.x + rect.width) {
if (y >= rect.y && y <= rect.y + rect.height) {
return true;
}
}
return false;
}
drawText() {
if (!this.text) {
return;
}
this.ctx.font = `${this.fontSize}px ${this.fontName}`;
this.ctx.textAlign = this.textAlign;
this.ctx.textBaseline = 'middle';
this.ctx.fontWeight = this.fontWeight;
let x = -(this.anchorX) * this._width;
let y = 0;
if (this._outlineFlag) {
this.ctx.lineWidth = this._outLineWidth;
this.ctx.strokeStyle = this._outLineColor;
this.ctx.strokeText(this.text, x, y);
}
this.ctx.fillStyle = this.fontColor;
if (this.outline > 0) {
this.ctx.lineWidth = this.outline;
this.ctx.strokeStyle = this.outlineColor;
this.ctx.strokeText(this.text, x, y);
}
this.ctx.fillText(this.text, x, y);
// console.log('汪汪汪: ' + this.scaleX * this.anchorX);
// console.log('汪汪汪: ' + this._width);
}
}
export class TouchSprite extends MySprite {
_nameable = new Nameable(this);
setName(name) {
this._nameable.setName(name);
}
getName() {
return this._nameable.getName();
}
getChildByName(name) {
return this._nameable.getChildByName(name);
}
seekChildByName(name) {
return this._nameable.seekChildByName(name);
}
_touchEnabled = false;
// _swallowTouches = false; // TODO:多重触摸以后用到了再说
_onTouchBeganListener = null;
_onTouchMoveListener = null;
_onTouchEndListener = null;
_onTouchCancelListener = null;
addTouchBeganListener(func) {
this._touchEnabled = true;
this._onTouchBeganListener = func;
}
addTouchMoveListener(func) {
this._touchEnabled = true;
this._onTouchMoveListener = func;
}
addTouchEndListener(func) {
this._touchEnabled = true;
this._onTouchEndListener = func;
}
addTouchCancelListener(func) {
this._touchEnabled = true;
this._onTouchCancelListener = func;
}
_checkHitPosition(pos) {
const rect = this.getBoundingBox();
if (this._checkPointInRect(pos.x, pos.y, rect)) {
return true;
}
return false;
}
_checkPointInRect(x, y, rect) {
if (x >= rect.x && x <= rect.x + rect.width) {
if (y >= rect.y && y <= rect.y + rect.height) {
return true;
}
}
return false;
}
// 位置
setPosition(x: any = 0, y = undefined) {
if (y !== undefined) {
this.x = x;
this.y = y;
} else {
this.x = x.x;
this.y = x.y;
}
}
setPositionX(x = 0) {
this.x = x;
}
setPositionY(y = 0) {
this.y = y;
}
// 用户自定义数据
_userData = new UserData();
get(key) {
return this._userData.get(key);
}
set(key, value) {
this._userData.set(key, value);
}
}
export function blinkItem(item: TouchSprite, time = 0.7) {
let interval = item.get('_blinkInterval');
if (interval) {
clearInterval(interval);
}
interval = setInterval(() => {
showItem(item, time, () => {
hideItem(item, time);
});
}, time * 2 * 1000);
item.set('_blinkInterval', interval);
}
export function stopBlinkItem(item: TouchSprite) {
let interval = item.get('_blinkInterval');
if (interval) {
clearInterval(interval);
}
item.set('_blinkInterval', null);
item.alpha = 0;
}
export function RandomInt(a, b = 0) {
let max = Math.max(a, b);
let min = Math.min(a, b);
return Math.floor(Math.random() * (max - min) + min);
}
export function shake(item, time = 0.5, rate = 1) {
let shakeSelf = function(item, time, callback, rate) {
const offX = 15 * item.scaleX * rate;
const offY = 15 * item.scaleX * rate;
const baseX = item.x;
const baseY = item.y;
const easing = TWEEN.Easing.Sinusoidal.InOut;
const move2 = () => {
moveItem(item, baseX, baseY, time * 9 / 16, () => {
if (callback) {
callback();
}
}, easing);
};
const move1 = () => {
moveItem(item, baseX + offX, baseY + offY, time * 7 / 16, () => {
move2();
}, easing);
};
move1();
}
shakeSelf(item, time, shake.bind(this, item, time, rate), rate);
}
export async function asyncDelayTime(time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(123);
}, time * 1000);
})
}
export async function asyncTweenChange(node, obj, time, easing) {
return new Promise((resolve, reject) => {
tweenChange(node, obj, time, () => {
resolve();
}, easing);
});
}
\ No newline at end of file
import {
Game,
TouchSprite,
RandomInt,
MyLabel,
blinkItem,
stopBlinkItem,
asyncDelayTime,
asyncTweenChange,
} from './Game';
import {
Label,
jelly,
showPopParticle,
tweenChange,
rotateItem,
scaleItem,
delayCall,
hideItem,
showItem,
moveItem,
shake,
ShapeRect,
} from './../Unit';
import TWEEN from '@tweenjs/tween.js';
import { defaultData } from './DefaultData';
export class MyGame extends Game {
images = null;
data = null;
status = null;
initData(data) {
this.images = data.images;
this.status = {};
if (!data.data || Object.is(data.data, {}) || !data.data.tittle) {
this.data = defaultData;
} else {
this.data = data.data;
let imgUrlList = [];
let audioUrlList = [];
imgUrlList = imgUrlList.filter((data) => data != null && data != '');
audioUrlList.push(this.data.audio);
audioUrlList.push(this.data.tittle.audio);
audioUrlList.push(...this.data.questions.map(question => question.audio));
audioUrlList.push(...this.data.questions.map(question => question.blocks.map(block => block.audio)).flat(Infinity));
audioUrlList = audioUrlList.filter((data) => data != null && data != '');
this.preLoadData(imgUrlList, audioUrlList);
}
}
preLoadData(imgUrlList, audioUrlList) {
imgUrlList.forEach((data) => {
this._parent.addUrlToImages(data);
});
audioUrlList.forEach((data) => {
this._parent.addUrlToAudioObj(data);
});
}
initView() {
// 初始化背景
this.initBg();
// 初始化标题
this.initTittle();
// 初始化中间部分
this.initMiddle();
// 游戏开始
this.gameStart();
}
bg = null;
initBg() {
this.removeChild(this.getChildByName('bg'));
let screenSize = this.getScreenSize();
let defaultSize = this.getDefaultScreenSize();
let bgSized1 = new TouchSprite();
bgSized1.init(this.images.get('Img_bg'));
bgSized1.anchorX = 0.5;
bgSized1.anchorY = 1;
bgSized1.setPosition(screenSize.width / 2, screenSize.height);
bgSized1.setScaleXY(this.getFullScaleXY());
this.addChild(bgSized1);
// 背景
let bg = new TouchSprite();
bg.init(this.images.get('Img_bg'));
bg.setScaleXY(this._parent.mapScale);
bg.alpha = 0;
bg.anchorX = 0.5;
bg.anchorY = 0;
bg.setPosition(screenSize.width / 2, 0);
bg.setName('bg');
this.addChild(bg);
this.bg = bg;
let bgMask = new TouchSprite();
bgMask.init(this.images.get('Img_bg'));
bgMask.setScaleXY(this._parent.mapScale);
bgMask.anchorX = 0.5;
bgMask.anchorY = 0;
bgMask.setPosition(screenSize.width / 2 + bg.width * this._parent.mapScale, 0);
bgMask.setName('bgMask');
this.addChild(bgMask);
let bgMask2 = new TouchSprite();
bgMask2.init(this.images.get('Img_bg'));
bgMask2.setScaleXY(this._parent.mapScale);
bgMask2.anchorX = 0.5;
bgMask2.anchorY = 0;
bgMask2.setPosition(screenSize.width / 2, (bg.height - 50) * this._parent.mapScale);
bgMask2.setName('bgMask2');
this.addChild(bgMask2);
const bgRect = new ShapeRect();
bgRect.setSize(57, 65);
bgRect.fillColor = '#f8c224';
const sx = screenSize.width / this._parent.canvasBaseW;
bgRect.setScaleXY(sx);
bgRect.x = 65 * sx;
bgRect.alpha = 0;
this._parent.renderArr.push(bgRect);
this.bgRect = bgRect;
}
bgRect = null;
getTittleBlockPositionX() {
return this.bgRect.x + 28.5 * this.bgRect.scaleX;
}
initTittle() {
let tittleLongBlock = new TouchSprite();
tittleLongBlock.init(this.images.get('Img_tittle_bg'));
tittleLongBlock.setScaleXY(this._parent.mapScale);
tittleLongBlock.setPositionX(this.getScreenSize().width / 2);
tittleLongBlock.setPositionY(31 * this._parent.mapScale);
tittleLongBlock.scaleX = this.getScreenSize().width / tittleLongBlock.width;
this.addChild(tittleLongBlock);
// 标题字母背景
let tittleWordBg = new TouchSprite();
tittleWordBg.init(this.images.get('Img_tittleBg'));
tittleWordBg.setScaleXY(this._parent.mapScale);
tittleWordBg.setPosition(this.getTittleBlockPositionX(), 31 * this._parent.mapScale);
this.addChild(tittleWordBg);
// 标题字母
let tittleWord = new MyLabel();
tittleWord.fontSize = 48;
tittleWord.fontName = 'BerlinSansFBDemi-Bold';
tittleWord.fontColor = '#ab5b22';
tittleWord.text = this.data.tittle.word;
tittleWord.anchorX = 0.5;
tittleWord.anchorY = 0.5;
tittleWord.setPosition(0, 0);
tittleWordBg.addChild(tittleWord);
tittleWord.refreshSize();
// 标题文字
let questionLabel = new MyLabel();
questionLabel.fontSize = 36;
questionLabel.fontName = 'FuturaBT-Bold';
questionLabel.fontColor = '#000000';
questionLabel.text = this.data.tittle.text;
questionLabel.anchorX = 0;
questionLabel.anchorY = 0.5;
questionLabel.setPosition(50, 0);
questionLabel.addTouchBeganListener(() => {
this.onClickTittle();
});
tittleWordBg.addChild(questionLabel);
questionLabel.refreshSize();
}
initMiddle() {
this.createQuestions();
this.createScrollBar();
this.createTittle();
this.createWholeAudioBtn();
}
createTittle() {
// 标题文字
let tittleLabel = new MyLabel();
tittleLabel.fontSize = 48;
tittleLabel.fontName = 'BerlinSansFBDemi-Bold';
tittleLabel.fontColor = '#70401e';
tittleLabel.text = this.data.questionsTittle;
tittleLabel.anchorX = 0.5;
tittleLabel.anchorY = 0.5;
tittleLabel.setPosition(0, 120);
tittleLabel.addTouchBeganListener(() => {
this.playAudio(this.data.tittleAudio);
});
this.bg.addChild(tittleLabel);
tittleLabel.refreshSize();
}
scrollBaseNode;
createQuestions() {
let scrollViewBg = new TouchSprite();
scrollViewBg.init(this.images.get('Img_white'));
scrollViewBg.scaleX = 1200 / scrollViewBg.width;
scrollViewBg.scaleY = 580 / scrollViewBg.height;
scrollViewBg.setPosition(0, this.bg.height / 2 + 100);
scrollViewBg.addTouchBeganListener(this.onScrollViewBgTouchBegan.bind(this));
scrollViewBg.addTouchMoveListener(this.onScrollViewBgTouchMoved.bind(this));
scrollViewBg.alpha = 0.1;
scrollViewBg.setName('scrollViewBg');
this.bg.addChild(scrollViewBg);
let scrollBaseNode = new TouchSprite();
scrollBaseNode.init(this.images.get('Img_white'));
scrollBaseNode.anchorX = 0.5;
scrollBaseNode.anchorY = 0;
this.bg.addChild(scrollBaseNode);
this.scrollBaseNode = scrollBaseNode;
console.log('this.data.questions.length = ' + this.data.questions.length);
this.data.questions.forEach((question, idx) => {
let baseNode = new TouchSprite();
baseNode.setPositionX(120 - this.bg.width / 2);
baseNode.setPositionY(idx * 85 + 200);
baseNode.setName('question_' + idx);
scrollBaseNode.addChild(baseNode);
let labelList = [];
if (question.words != '') {
question.words.match(/(([a-z]|[A-Z]|[0-9]|'|-|&|_)+|.)/g).forEach((word, wordIdx) => {
let block = question.blocks.find(block => block.idx == wordIdx);
let posX = labelList.reduce((offsetX, label, labelIdx) => {
if (labelIdx < wordIdx) {
return offsetX + label.width;
} else {
return offsetX;
}
}, 0);
let questionLabel = new MyLabel();
questionLabel.fontSize = 42;
questionLabel.fontName = 'MMTextBook';
questionLabel.fontColor = '#070408';
questionLabel.text = word;
let match = word.match(/(([a-z]|[A-Z]|[0-9])+)/);
if (match && block && block.type == 'bold') {
questionLabel.fontName = 'MMTextBook-Bold';
}
if (match && block && block.type == 'red') {
questionLabel.fontColor = '#c8161e';
questionLabel.set('audio', block.audio);
questionLabel.addTouchBeganListener(() => this.onClickWord(questionLabel));
let labelImg = new TouchSprite();
labelImg.init(this.images.get(block.img));
}
questionLabel.refreshSize();
questionLabel.setPositionX(posX + questionLabel.width / 2);
baseNode.addChild(questionLabel, 2);
labelList.push(questionLabel);
});
}
if (question.questionTittle != '') {
let questionTittle = new MyLabel();
questionTittle.fontSize = 42;
questionTittle.fontName = 'MMTextBook';
questionTittle.fontColor = '#070408';
questionTittle.text = question.questionTittle + '. ';
questionTittle.anchorX = 1;
questionTittle.anchorY = 0.5;
questionTittle.refreshSize();
baseNode.addChild(questionTittle);
}
if (question.audio != '') {
let offsetX = labelList.reduce((offsetX, label) => { return offsetX + label.width }, 0);
this._createSpeacker(
this.images.get('Btn_s_play'),
this.images.get('Btn_s_pause'),
baseNode,
{
x: offsetX + 50,
y: 0
},
this.getAudioObj(question.audio)
);
}
});
}
onClickWord(block) {
if (block.get('moved')) {
return;
}
block.set('moved', true);
block.setScaleXY(3);
tweenChange(block, { scaleX: 1, scaleY: 1 }, 0.5, () => {
this.playAudio(block.get('audio'));
}, TWEEN.Easing.Cubic.In);
tweenChange(block, { alpha: 1 }, 0.5, null, TWEEN.Easing.Quintic.In);
}
createScrollBar() {
if (this.data.questions.length <= 6) {
return;
}
let scrollBg = new TouchSprite();
scrollBg.init(this.images.get('Img_scroll_bg'));
scrollBg.setPositionX(this.bg.width / 2 - 150);
scrollBg.setPositionY(this.bg.height / 2 + 60);
scrollBg.setName('scrollBg');
scrollBg.scaleY = (this.bg.height - 240) / scrollBg.height;
this.bg.addChild(scrollBg);
let scrollBar = new TouchSprite();
scrollBar.init(this.images.get('Img_scroll_bar'));
scrollBar.anchorY = 0;
scrollBar.scaleY = (6 / this.data.questions.length) * scrollBg.height * scrollBg.scaleY / scrollBar.height;
scrollBar.setPositionX(this.bg.width / 2 - 150);
scrollBar.setPositionY(183);
scrollBar.setName('scrollBar');
scrollBar.addTouchBeganListener(this.onScrollBarTouchBegan.bind(this));
scrollBar.addTouchMoveListener(this.onScrollBarTouchMoved.bind(this));
this.bg.addChild(scrollBar);
let bgMaskRight = new TouchSprite();
bgMaskRight.init(this.images.get('Img_bg'));
bgMaskRight.setPositionX(this.bg.width - 143);
bgMaskRight.setPositionY(this.bg.height / 2 + 60);
this.bg.addChild(bgMaskRight);
let bgMaskUp = new TouchSprite();
bgMaskUp.init(this.images.get('Img_bg'));
bgMaskUp.setPositionX(0);
bgMaskUp.setPositionY(0 - 190);
this.bg.addChild(bgMaskUp);
let bgMaskDown = new TouchSprite();
bgMaskDown.init(this.images.get('Img_bg'));
bgMaskDown.setPositionX(0);
bgMaskDown.setPositionY(this.bg.height * 2 - 190);
bgMaskDown.alpha = 1;
this.bg.addChild(bgMaskDown);
}
updateScrollBar(rate) {
let scrollBg = this.bg.getChildByName('scrollBg');
let scrollBar = this.bg.getChildByName('scrollBar');
scrollBar.setPositionY(183 + (scrollBg.height * scrollBg.scaleY - scrollBar.height * scrollBar.scaleY - 8) * rate);
}
updateScrollView(rate) {
this.scrollBaseNode.setPositionY(((this.data.questions.length - 6) * -85) * rate);
}
onScrollViewBgTouchBegan(touchPos) {
this.scrollBaseNode.set('beginPos', { x: this.scrollBaseNode.x, y: this.scrollBaseNode.y });
this.scrollBaseNode.set('beginTouchPos', touchPos);
}
onScrollViewBgTouchMoved(touchPos) {
let beginPos = this.scrollBaseNode.get('beginPos');
let beginTouchPos = this.scrollBaseNode.get('beginTouchPos');
let rate = (beginPos.y + (touchPos.y - beginTouchPos.y)) / (-85 * (this.data.questions.length - 6));
rate = Math.min(Math.max(rate, 0), 1);
this.updateScrollView(rate);
this.updateScrollBar(rate);
}
onScrollBarTouchBegan(pos) {
let scrollBar = this.bg.getChildByName('scrollBar');
scrollBar.set('beginPos', { x: scrollBar.x, y: scrollBar.y });
scrollBar.set('beginTouchPos', pos);
}
onScrollBarTouchMoved(touchPos) {
let scrollBg = this.bg.getChildByName('scrollBg');
let scrollBar = this.bg.getChildByName('scrollBar');
let beginPos = scrollBar.get('beginPos');
let beginTouchPos = scrollBar.get('beginTouchPos');
let rate = (beginPos.y + (touchPos.y - beginTouchPos.y) - 183) / (scrollBg.height * scrollBg.scaleY - scrollBar.height * scrollBar.scaleY - 8);
rate = Math.min(Math.max(rate, 0), 1);
this.updateScrollView(rate);
this.updateScrollBar(rate);
}
createWholeAudioBtn() {
let pos = {
x: this.bg.width / 2 - 70,
y: this.bg.height - 100
};
this._createSpeacker(
this.images.get('Btn_play'),
this.images.get('Btn_pause'),
this.bg,
pos,
this.getAudioObj(this.data.audio)
);
}
_createSpeacker(playImg, pauseImg, parentNode, pos, audio) {
const speaker = new TouchSprite();
speaker.init(playImg);
speaker.setPosition(pos);
speaker.addTouchBeganListener(() => this._onClickSpeaker(speaker));
parentNode.addChild(speaker);
const speakerPause = new TouchSprite();
speakerPause.init(pauseImg);
speakerPause.setPosition(pos);
speakerPause.addTouchBeganListener(() => this._onClickSpeakerPause(speakerPause));
speakerPause.alpha = 0;
parentNode.addChild(speakerPause);
speaker.set('_audio', audio);
speaker.set('_speakerPause', speakerPause);
speakerPause.set('_audio', audio);
speakerPause.set('_speaker', speaker);
}
_currentSpeaker;
_onClickSpeaker(speaker) {
const audio = speaker.get('_audio');
if (!audio) {
return;
}
if (this._currentSpeaker) {
this._onClickSpeakerPause(this._currentSpeaker.get('_speakerPause'), true);
}
const speakerPause = speaker.get('_speakerPause');
audio.onended = () => {
this._showSpeaker(speaker, speakerPause);
this._currentSpeaker = null;
};
audio.play();
this._currentSpeaker = speaker;
this._showPauser(speaker, speakerPause);
jelly(speaker);
jelly(speakerPause);
}
_onClickSpeakerPause(speakerPause, unJellyFlg = false) {
const audio = speakerPause.get('_audio');
if (!audio) {
return;
}
audio.pause();
const speaker = speakerPause.get('_speaker');
this._showSpeaker(speaker, speakerPause);
if (!unJellyFlg) {
jelly(speaker);
jelly(speakerPause);
}
}
_showSpeaker(speaker, speakerPause) {
tweenChange(speaker, { alpha: 1 }, 0.3);
tweenChange(speakerPause, { alpha: 0 }, 0.3);
}
_showPauser(speaker, speakerPause) {
tweenChange(speaker, { alpha: 0 }, 0.3);
tweenChange(speakerPause, { alpha: 1 }, 0.3);
}
printCurrentStatus() {
console.log(JSON.stringify(this.status));
}
onClickTittle() {
this.playAudio(this.data.tittle.audio);
}
gameStart() {
this.playIncomeAudio();
this.income();
}
playIncomeAudio() {
this.playAudio('audio_new_page');
}
income() {
this.data.questions.forEach(async (question, idx) => {
let baseNode = this.bg.seekChildByName('question_' + idx);
baseNode.setPositionX(120 + this.bg.width / 2);
baseNode.setPositionY(idx * 85 + 200);
await asyncDelayTime(0.1 * idx);
await asyncTweenChange(baseNode, {
x: 120 - this.bg.width / 2,
y: idx * 85 + 200
}, 0.5, TWEEN.Easing.Quadratic.Out);
});
}
}
......@@ -11,9 +11,47 @@
@font-face
{
font-family: 'MMTextBook-Bold';
src: url("../../assets/font/MMTextBook-Bold.otf") ;
}
@font-face
{
font-family: 'MMTextBook';
src: url("../../assets/font/MMTextBook.otf") ;
}
@font-face
{
font-family: 'BRLNSDB';
src: url("../../assets/font/BRLNSDB.TTF") ;
}
@font-face
{
font-family: 'BerlinSansFBDemi-Bold';
src: url("../../assets/font/BerlinSansFBDemi-Bold.TTF") ;
}
@font-face
{
font-family: 'FuturaBT-Bold';
src: url("../../assets/font/FuturaBT-Bold.TTF") ;
}
@font-face
{
font-family: 'CenturyGothic';
src: url("../../assets/font/CenturyGothic.TTF") ;
}
@font-face
{
font-family: 'CenturyGothic-Bold';
src: url("../../assets/font/CenturyGothic-Bold.TTF") ;
}
<div class="game-container" #wrap>
<canvas id="canvas" #canvas></canvas>
</div>
<span style="font-family: MMTextBook-Bold">&nbsp;</span>
<span style="font-family: MMTextBook">&nbsp;</span>
\ No newline at end of file
......@@ -12,6 +12,7 @@ import {debounceTime} from 'rxjs/operators';
import TWEEN from '@tweenjs/tween.js';
import {MyGame} from "./game/MyGame";
......@@ -57,7 +58,7 @@ export class PlayComponent implements OnInit, OnDestroy {
canvasLeft;
canvasTop;
saveKey = 'test_0011';
saveKey = 'ym-2-32';
btnLeft;
......@@ -69,6 +70,8 @@ export class PlayComponent implements OnInit, OnDestroy {
curPic;
game;
@HostListener('window:resize', ['$event'])
onResize(event) {
this.winResizeEventStream.next();
......@@ -86,7 +89,13 @@ export class PlayComponent implements OnInit, OnDestroy {
if (data && typeof data == 'object') {
this.data = data;
}
// console.log('data:' , data);
this.game = new MyGame(this);
this.game.initData({
images: this.images,
data: this.data,
});
// 初始化 各事件监听
this.initListener();
......@@ -432,10 +441,10 @@ export class PlayComponent implements OnInit, OnDestroy {
*/
initDefaultData() {
if (!this.data.pic_url) {
this.data.pic_url = 'assets/play/default/pic.jpg';
this.data.pic_url_2 = 'assets/play/default/pic.jpg';
}
// if (!this.data.pic_url) {
// this.data.pic_url = 'assets/play/default/pic.jpg';
// this.data.pic_url_2 = 'assets/play/default/pic.jpg';
// }
}
......@@ -444,8 +453,8 @@ export class PlayComponent implements OnInit, OnDestroy {
*/
initImg() {
this.addUrlToImages(this.data.pic_url);
this.addUrlToImages(this.data.pic_url_2);
// this.addUrlToImages(this.data.pic_url);
// this.addUrlToImages(this.data.pic_url_2);
}
......@@ -455,11 +464,15 @@ export class PlayComponent implements OnInit, OnDestroy {
initAudio() {
// 音频资源
this.addUrlToAudioObj(this.data.audio_url);
this.addUrlToAudioObj(this.data.audio_url_2);
// this.addUrlToAudioObj(this.data.audio_url);
// this.addUrlToAudioObj(this.data.audio_url_2);
for (let item of this.rawAudios) {
if (item[0] != item[1]) {
// 音效
this.addUrlToAudioObj('click', this.rawAudios.get('click'), 0.3);
this.addUrlToAudioObj(item[0], this.rawAudios.get(item[0]), 0.3);
}
}
}
......@@ -491,88 +504,7 @@ export class PlayComponent implements OnInit, OnDestroy {
* 初始化试图
*/
initView() {
this.initPic();
this.initBottomPart();
}
initBottomPart() {
const btnLeft = new MySprite();
btnLeft.init(this.images.get('btn_left'));
btnLeft.x = this.canvasWidth - 150 * this.mapScale;
btnLeft.y = this.canvasHeight - 100 * this.mapScale;
btnLeft.setScaleXY(this.mapScale);
this.renderArr.push(btnLeft);
this.btnLeft = btnLeft;
const btnRight = new MySprite();
btnRight.init(this.images.get('btn_right'));
btnRight.x = this.canvasWidth - 50 * this.mapScale;
btnRight.y = this.canvasHeight - 100 * this.mapScale;
btnRight.setScaleXY(this.mapScale);
this.renderArr.push(btnRight);
this.btnRight = btnRight;
}
initPic() {
const maxW = this.canvasWidth * 0.7;
const pic1 = new MySprite();
pic1.init(this.images.get(this.data.pic_url));
pic1.x = this.canvasWidth / 2;
pic1.y = this.canvasHeight / 2;
pic1.setScaleXY(maxW / pic1.width);
this.renderArr.push(pic1);
this.pic1 = pic1;
const label1 = new Label();
label1.text = this.data.text;
label1.textAlign = 'center';
label1.fontSize = 50;
label1.fontName = 'BRLNSDB';
label1.fontColor = '#ffffff';
pic1.addChild(label1);
const pic2 = new MySprite();
pic2.init(this.images.get(this.data.pic_url_2));
pic2.x = this.canvasWidth / 2 + this.canvasWidth;
pic2.y = this.canvasHeight / 2;
pic2.setScaleXY(maxW / pic2.width);
this.renderArr.push(pic2);
this.pic2 = pic2;
this.curPic = pic1;
}
btnLeftClicked() {
this.lastPage();
}
btnRightClicked() {
this.nextPage();
this.game.initView();
}
lastPage() {
......@@ -620,39 +552,15 @@ export class PlayComponent implements OnInit, OnDestroy {
mapDown(event) {
if (!this.canTouch) {
return;
}
if ( this.checkClickTarget(this.btnLeft) ) {
this.btnLeftClicked();
return;
}
if ( this.checkClickTarget(this.btnRight) ) {
this.btnRightClicked();
return;
}
if ( this.checkClickTarget(this.pic1) ) {
this.pic1Clicked();
return;
}
if ( this.checkClickTarget(this.pic2) ) {
this.pic2Clicked();
return;
}
this.game._onTouchBegan({x:this.mx,y:this.my});
}
mapMove(event) {
this.game._onTouchMove({x:this.mx,y:this.my});
}
mapUp(event) {
this.game._onTouchEnd({x:this.mx,y:this.my});
}
......
const res = [
// ['bg', "assets/play/bg.jpg"],
['btn_left', "assets/play/btn_left.png"],
['btn_right', "assets/play/btn_right.png"],
// ['text_bg', "assets/play/text_bg.png"],
['Img_tittleBg', "assets/play/Img_tittleBg.png"],
['Img_tittle_bg', "assets/play/Img_tittle_bg.png"],
['Img_bg', "assets/play/Img_bg.png"],
['Img_bg_blue', "assets/play/Img_bg_blue.png"],
['Btn_pause', "assets/play/Btn_pause.png"],
['Btn_play', "assets/play/Btn_play.png"],
['Btn_s_pause', "assets/play/Btn_s_pause.png"],
['Btn_s_play', "assets/play/Btn_s_play.png"],
['Img_line', "assets/play/Img_line.png"],
['Img_white', "assets/play/Img_white.jpg"],
['Img_scroll_bg', "assets/play/Img_scroll_bg.png"],
['Img_scroll_bar', "assets/play/Img_scroll_bar.png"],
];
const resAudio = [
['click', "assets/play/music/click.mp3"],
['audio_new_page', "assets/play/audio_new_page.mp3"],
['into', "assets/play/default/into.mp3"],
['let', "assets/play/default/let.mp3"],
['put', "assets/play/default/put.mp3"],
['the', "assets/play/default/the.mp3"],
['tittle', "assets/play/default/tittle.mp3"],
['question_1', "assets/play/default/question_1.mp3"],
['total_audio', "assets/play/default/total_audio.mp3"],
];
export {res, resAudio};
export { res, resAudio };
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment