Commit e9b41469 authored by 范雪寒's avatar 范雪寒

feat: 设置单词位置

parent 031ae811
import { Component, ElementRef, ViewChild, OnInit, Input, OnDestroy, HostListener } from '@angular/core';
import {
Label,
MySprite, tweenChange,
} from './Unit';
import { res, resAudio } from './resources';
import { Subject } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
import TWEEN from '@tweenjs/tween.js';
import { MyGame } from "./game/MyGame";
export class PreviewCanvas implements OnInit, OnDestroy {
// 数据
data;
ctx;
wrap;
canvas;
canvasWidth = 1280; // canvas实际宽度
canvasHeight = 720; // canvas实际高度
canvasBaseW = 1280; // canvas 资源预设宽度
canvasBaseH = 720; // canvas 资源预设高度
mx; // 点击x坐标
my; // 点击y坐标
// 资源
rawImages = new Map(res);
rawAudios = new Map(resAudio);
images = new Map();
animationId: any;
winResizeEventStream = new Subject();
audioObj = {};
renderArr;
mapScale = 1;
canvasLeft;
canvasTop;
saveKey = 'ym-2-30';
game;
constructor(wrap, canvas, data) {
this.wrap = wrap;
this.canvas = canvas;
this.data = data;
}
ngOnInit() {
this.game = new MyGame(this);
this.game.initData({
images: this.images,
data: this.data,
});
// 初始化 各事件监听
this.initListener();
// 开始预加载资源
this.load();
}
setSaveFunc(save) {
this.game.setSaveFunc(save);
}
ngOnDestroy() {
window['curCtx'] = null;
window.cancelAnimationFrame(this.animationId);
}
load() {
// 预加载资源
this.loadResources().then(() => {
window["air"].hideAirClassLoading(this.saveKey, this.data);
this.init();
this.update();
});
}
init() {
this.initCtx();
this.initData();
this.initView();
}
initCtx() {
this.canvasWidth = this.wrap.nativeElement.clientWidth;
this.canvasHeight = this.wrap.nativeElement.clientHeight;
this.canvas.nativeElement.width = this.wrap.nativeElement.clientWidth;
this.canvas.nativeElement.height = this.wrap.nativeElement.clientHeight;
this.ctx = this.canvas.nativeElement.getContext('2d');
this.canvas.nativeElement.width = this.canvasWidth;
this.canvas.nativeElement.height = this.canvasHeight;
window['curCtx'] = this.ctx;
}
updateItem(item) {
if (item) {
item.update();
}
}
updateArr(arr) {
if (!arr) {
return;
}
for (let i = 0; i < arr.length; i++) {
arr[i].update(this);
}
}
initListener() {
this.winResizeEventStream
.pipe(debounceTime(500))
.subscribe(data => {
this.renderAfterResize();
});
// ---------------------------------------------
const setParentOffset = () => {
const rect = this.canvas.nativeElement.getBoundingClientRect();
this.canvasLeft = rect.left;
this.canvasTop = rect.top;
console.log('rect = ' + JSON.stringify(rect));
};
const setMxMyByTouch = (event) => {
if (event.touches.length <= 0) {
return;
}
if (this.canvasLeft == null) {
setParentOffset();
}
this.mx = event.touches[0].pageX - this.canvasLeft;
this.my = event.touches[0].pageY - this.canvasTop;
};
const setMxMyByMouse = (event) => {
this.mx = event.offsetX;
this.my = event.offsetY;
};
// ---------------------------------------------
let firstTouch = true;
const touchDownFunc = (e) => {
if (firstTouch) {
firstTouch = false;
removeMouseListener();
}
setMxMyByTouch(e);
this.mapDown(e);
};
const touchMoveFunc = (e) => {
setMxMyByTouch(e);
this.mapMove(e);
};
const touchUpFunc = (e) => {
setMxMyByTouch(e);
this.mapUp(e);
};
const mouseDownFunc = (e) => {
if (firstTouch) {
firstTouch = false;
removeTouchListener();
}
setMxMyByMouse(e);
this.mapDown(e);
};
const mouseMoveFunc = (e) => {
setMxMyByMouse(e);
this.mapMove(e);
};
const mouseUpFunc = (e) => {
setMxMyByMouse(e);
this.mapUp(e);
};
const element = this.canvas.nativeElement;
const addTouchListener = () => {
element.addEventListener('touchstart', touchDownFunc);
element.addEventListener('touchmove', touchMoveFunc);
element.addEventListener('touchend', touchUpFunc);
element.addEventListener('touchcancel', touchUpFunc);
};
const removeTouchListener = () => {
element.removeEventListener('touchstart', touchDownFunc);
element.removeEventListener('touchmove', touchMoveFunc);
element.removeEventListener('touchend', touchUpFunc);
element.removeEventListener('touchcancel', touchUpFunc);
};
const addMouseListener = () => {
element.addEventListener('mousedown', mouseDownFunc);
element.addEventListener('mousemove', mouseMoveFunc);
element.addEventListener('mouseup', mouseUpFunc);
};
const removeMouseListener = () => {
element.removeEventListener('mousedown', mouseDownFunc);
element.removeEventListener('mousemove', mouseMoveFunc);
element.removeEventListener('mouseup', mouseUpFunc);
};
addMouseListener();
addTouchListener();
}
playAudio(key, now = false, callback = null) {
const audio = this.audioObj[key];
if (audio) {
if (now) {
audio.pause();
audio.currentTime = 0;
}
if (callback) {
audio.onended = () => {
callback();
};
}
audio.play();
}
}
loadResources() {
const pr = [];
this.rawImages.forEach((value, key) => {// 预加载图片
const p = this.preload(value)
.then(img => {
this.images.set(key, img);
})
.catch(err => console.log(err));
pr.push(p);
});
return Promise.all(pr);
}
refresh() {
this.canvasWidth = this.wrap.nativeElement.clientWidth;
this.canvasHeight = this.wrap.nativeElement.clientHeight;
this.init();
this.game.refresh();
}
preload(url) {
return new Promise((resolve, reject) => {
const img = new Image();
// img.crossOrigin = "anonymous";
img.onload = () => resolve(img);
img.onerror = reject;
img.src = url;
});
}
renderAfterResize() {
this.canvasWidth = this.wrap.nativeElement.clientWidth;
this.canvasHeight = this.wrap.nativeElement.clientHeight;
this.init();
}
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;
}
addUrlToImages(url) {
this.rawImages.set(url, url);
}
/**
* 初始化数据
*/
initData() {
const sx = this.canvasWidth / this.canvasBaseW;
const sy = this.canvasHeight / this.canvasBaseH;
const s = Math.min(sx, sy);
this.mapScale = s;
this.renderArr = [];
}
/**
* 初始化试图
*/
initView() {
this.game.initView();
}
mapDown(event) {
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 });
}
update() {
// ----------------------------------------------------------
this.animationId = window.requestAnimationFrame(this.update.bind(this));
// 清除画布内容
this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
// tween 更新动画
TWEEN.update();
// ----------------------------------------------------------
this.updateArr(this.renderArr);
}
}
import TWEEN from '@tweenjs/tween.js';
interface AirWindow extends Window {
air: any;
curCtx: any;
}
declare let window: AirWindow;
class Sprite {
x = 0;
y = 0;
color = '';
radius = 0;
alive = false;
margin = 0;
angle = 0;
ctx;
constructor(ctx = null) {
if (!ctx) {
this.ctx = window.curCtx;
} else {
this.ctx = ctx;
}
}
update($event) {
this.draw();
}
draw() {
}
}
export class MySprite extends Sprite {
_width = 0;
_height = 0;
_anchorX = 0;
_anchorY = 0;
_offX = 0;
_offY = 0;
scaleX = 1;
scaleY = 1;
_alpha = 1;
rotation = 0;
visible = true;
skewX = 0;
skewY = 0;
_shadowFlag = false;
_shadowColor;
_shadowOffsetX = 0;
_shadowOffsetY = 0;
_shadowBlur = 5;
_radius = 0;
children = [this];
childDepandVisible = true;
childDepandAlpha = false;
img;
_z = 0;
init(imgObj = null, anchorX: number = 0.5, anchorY: number = 0.5) {
if (imgObj) {
this.img = imgObj;
this.width = this.img.width;
this.height = this.img.height;
}
this.anchorX = anchorX;
this.anchorY = anchorY;
}
setShadow(offX, offY, blur, color = 'rgba(0, 0, 0, 0.3)') {
this._shadowFlag = true;
this._shadowColor = color;
this._shadowOffsetX = offX;
this._shadowOffsetY = offY;
this._shadowBlur = blur;
}
setRadius(r) {
this._radius = r;
}
update($event = null) {
if (!this.visible && this.childDepandVisible) {
return;
}
this.draw();
}
draw() {
this.ctx.save();
this.drawInit();
this.updateChildren();
this.ctx.restore();
}
drawInit() {
this.ctx.translate(this.x, this.y);
this.ctx.rotate(this.rotation * Math.PI / 180);
this.ctx.scale(this.scaleX, this.scaleY);
this.ctx.globalAlpha = this.alpha;
this.ctx.transform(1, this.skewX, this.skewY, 1, 0, 0);
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();
}
}
drawSelf() {
if (this._shadowFlag) {
this.ctx.shadowOffsetX = this._shadowOffsetX;
this.ctx.shadowOffsetY = this._shadowOffsetY;
this.ctx.shadowBlur = this._shadowBlur;
this.ctx.shadowColor = this._shadowColor;
} else {
this.ctx.shadowOffsetX = 0;
this.ctx.shadowOffsetY = 0;
this.ctx.shadowBlur = null;
this.ctx.shadowColor = null;
}
if (this.img) {
this.ctx.drawImage(this.img, this._offX, this._offY);
}
}
updateChildren() {
if (this.children.length <= 0) { return; }
for (const child of this.children) {
if (child === this) {
if (this.visible) {
this.drawSelf();
}
} else {
child.update();
}
}
}
load(url, anchorX = 0.5, anchorY = 0.5) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => resolve(img);
img.onerror = reject;
img.src = url;
}).then(img => {
this.init(img, anchorX, anchorY);
return img;
});
}
addChild(child, z = 1) {
if (this.children.indexOf(child) === -1) {
this.children.push(child);
child._z = z;
child.parent = this;
}
this.children.sort((a, b) => {
return a._z - b._z;
});
if (this.childDepandAlpha) {
child.alpha = this.alpha;
}
}
removeChild(child) {
const index = this.children.indexOf(child);
if (index !== -1) {
this.children.splice(index, 1);
}
}
removeChildren() {
for (let i = 0; i < this.children.length; i++) {
if (this.children[i]) {
if (this.children[i] !== this) {
this.children.splice(i, 1);
i--;
}
}
}
}
_changeChildAlpha(alpha) {
for (const child of this.children) {
if (child !== this) {
child.alpha = alpha;
}
}
}
set alpha(v) {
this._alpha = v;
if (this.childDepandAlpha) {
this._changeChildAlpha(v);
}
}
get alpha() {
return this._alpha;
}
set width(v) {
this._width = v;
this.refreshAnchorOff();
}
get width() {
return this._width;
}
set height(v) {
this._height = v;
this.refreshAnchorOff();
}
get height() {
return this._height;
}
set anchorX(value) {
this._anchorX = value;
this.refreshAnchorOff();
}
get anchorX() {
return this._anchorX;
}
set anchorY(value) {
this._anchorY = value;
this.refreshAnchorOff();
}
get anchorY() {
return this._anchorY;
}
refreshAnchorOff() {
this._offX = -this._width * this.anchorX;
this._offY = -this._height * this.anchorY;
}
setScaleXY(value) {
this.scaleX = this.scaleY = value;
}
getBoundingBox() {
const getParentData = (item) => {
let px = item.x;
let py = item.y;
let sx = item.scaleX;
let sy = item.scaleY;
const parent = item.parent;
if (parent) {
const obj = getParentData(parent);
const _x = obj.px;
const _y = obj.py;
const _sx = obj.sx;
const _sy = obj.sy;
px = _x + item.x * _sx;
py = _y + item.y * _sy;
sx *= _sx;
sy *= _sy;
}
return { px, py, sx, sy };
};
const data = getParentData(this);
const x = data.px + this._offX * Math.abs(data.sx);
const y = data.py + this._offY * Math.abs(data.sy);
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 };
}
}
export class ColorSpr extends MySprite {
r = 0;
g = 0;
b = 0;
createGSCanvas() {
if (!this.img) {
return;
}
const rect = this.getBoundingBox();
if (rect.width <= 1 || rect.height <= 1) {
return;
}
const c = this.ctx.getImageData(rect.x, rect.y, rect.width, rect.height);
for (let i = 0; i < c.height; i++) {
for (let j = 0; j < c.width; j++) {
const x = (i * 4) * c.width + (j * 4);
const r = c.data[x];
const g = c.data[x + 1];
const b = c.data[x + 2];
c.data[x] = this.r;
c.data[x + 1] = this.g;
c.data[x + 2] = this.b;
// c.data[x] = c.data[x + 1] = c.data[x + 2] = (r + g + b) / 3 ;
// // c.data[x + 3] = 255;
}
}
this.ctx.putImageData(c, rect.x, rect.y, 0, 0, rect.width, rect.height);
}
drawSelf() {
super.drawSelf();
this.createGSCanvas();
}
}
export class GrayscaleSpr extends MySprite {
grayScale = 120;
createGSCanvas() {
if (!this.img) {
return;
}
const rect = this.getBoundingBox();
const c = this.ctx.getImageData(rect.x, rect.y, rect.width, rect.height);
for (let i = 0; i < c.height; i++) {
for (let j = 0; j < c.width; j++) {
const x = (i * 4) * c.width + (j * 4);
const r = c.data[x];
const g = c.data[x + 1];
const b = c.data[x + 2];
// const a = c.data[x + 3];
c.data[x] = c.data[x + 1] = c.data[x + 2] = this.grayScale; // (r + g + b) / 3;
// c.data[x + 3] = 255;
}
}
this.ctx.putImageData(c, rect.x, rect.y, 0, 0, rect.width, rect.height);
}
drawSelf() {
super.drawSelf();
this.createGSCanvas();
}
}
export class BitMapLabel extends MySprite {
labelArr;
baseUrl;
setText(data, text) {
this.labelArr = [];
const labelArr = [];
const tmpArr = text.split('');
let totalW = 0;
let h = 0;
for (const tmp of tmpArr) {
const label = new MySprite(this.ctx);
label.init(data[tmp], 0);
this.addChild(label);
labelArr.push(label);
totalW += label.width;
h = label.height;
}
this.width = totalW;
this.height = h;
let offX = -totalW / 2;
for (const label of labelArr) {
label.x = offX;
offX += label.width;
}
this.labelArr = labelArr;
}
}
export class Label extends MySprite {
text: string;
// fontSize:String = '40px';
fontName = 'Verdana';
textAlign = 'left';
fontSize = 40;
fontColor = '#000000';
fontWeight = 900;
_maxWidth;
outline = 0;
outlineColor = '#ffffff';
// _shadowFlag = false;
// _shadowColor;
// _shadowOffsetX;
// _shadowOffsetY;
// _shadowBlur;
_outlineFlag = false;
_outLineWidth;
_outLineColor;
constructor(ctx = null) {
super(ctx);
this.init();
}
refreshSize() {
this.ctx.save();
this.ctx.font = `${this.fontSize}px ${this.fontName}`;
this.ctx.textAlign = this.textAlign;
this.ctx.textBaseline = 'middle';
this.ctx.fontWeight = this.fontWeight;
this._width = this.ctx.measureText(this.text).width;
this._height = this.fontSize;
this.refreshAnchorOff();
this.ctx.restore();
}
setMaxSize(w) {
this._maxWidth = w;
this.refreshSize();
if (this.width >= w) {
this.scaleX *= w / this.width;
this.scaleY *= w / this.width;
}
}
show(callBack = null) {
this.visible = true;
if (this.alpha >= 1) {
return;
}
const tween = new TWEEN.Tween(this)
.to({ alpha: 1 }, 800)
// .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth.
.onComplete(() => {
if (callBack) {
callBack();
}
})
.start(); // Start the tween immediately.
}
// setShadow(offX = 0, offY = 2, blur = 2, color = 'rgba(0, 0, 0, 0.2)') {
//
// this._shadowFlag = true;
// this._shadowColor = color;
// // 将阴影向右移动15px,向上移动10px
// this._shadowOffsetX = 5;
// this._shadowOffsetY = 5;
// // 轻微模糊阴影
// this._shadowBlur = 5;
// }
setOutline(width = 5, color = '#ffffff') {
this._outlineFlag = true;
this._outLineWidth = width;
this._outLineColor = color;
}
drawText() {
// console.log('in drawText', this.text);
if (!this.text) { return; }
// if (this._shadowFlag) {
//
// this.ctx.shadowColor = this._shadowColor;
// // 将阴影向右移动15px,向上移动10px
// this.ctx.shadowOffsetX = this._shadowOffsetX;
// this.ctx.shadowOffsetY = this._shadowOffsetY;
// // 轻微模糊阴影
// this.ctx.shadowBlur = this._shadowBlur;
// }
this.ctx.font = `${this.fontSize}px ${this.fontName}`;
this.ctx.textAlign = this.textAlign;
this.ctx.textBaseline = 'middle';
this.ctx.fontWeight = this.fontWeight;
if (this._outlineFlag) {
this.ctx.lineWidth = this._outLineWidth;
this.ctx.strokeStyle = this._outLineColor;
this.ctx.strokeText(this.text, 0, 0);
}
this.ctx.fillStyle = this.fontColor;
if (this.outline > 0) {
this.ctx.lineWidth = this.outline;
this.ctx.strokeStyle = this.outlineColor;
this.ctx.strokeText(this.text, 0, 0);
}
this.ctx.fillText(this.text, 0, 0);
}
drawSelf() {
super.drawSelf();
this.drawText();
}
}
export class RichTextOld extends Label {
textArr = [];
fontSize = 40;
setText(text: string, words) {
let newText = text;
for (const word of words) {
const re = new RegExp(word, 'g');
newText = newText.replace(re, `#${word}#`);
// newText = newText.replace(word, `#${word}#`);
}
this.textArr = newText.split('#');
this.text = newText;
// this.setSize();
}
refreshSize() {
this.ctx.save();
this.ctx.font = `${this.fontSize}px ${this.fontName}`;
this.ctx.textAlign = this.textAlign;
this.ctx.textBaseline = 'middle';
this.ctx.fontWeight = this.fontWeight;
let curX = 0;
for (const text of this.textArr) {
const w = this.ctx.measureText(text).width;
curX += w;
}
this.width = curX;
this.height = this.fontSize;
this.refreshAnchorOff();
this.ctx.restore();
}
show(callBack = null) {
// console.log(' in show ');
this.visible = true;
// this.alpha = 0;
const tween = new TWEEN.Tween(this)
.to({ alpha: 1 }, 800)
// .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth.
.onComplete(() => {
if (callBack) {
callBack();
}
})
.start(); // Start the tween immediately.
}
drawText() {
// console.log('in drawText', this.text);
if (!this.text) { return; }
this.ctx.font = `${this.fontSize}px ${this.fontName}`;
this.ctx.textAlign = this.textAlign;
this.ctx.textBaseline = 'middle';
this.ctx.fontWeight = 900;
this.ctx.lineWidth = 5;
this.ctx.strokeStyle = '#ffffff';
// this.ctx.strokeText(this.text, 0, 0);
this.ctx.fillStyle = '#000000';
// this.ctx.fillText(this.text, 0, 0);
let curX = 0;
for (let i = 0; i < this.textArr.length; i++) {
const w = this.ctx.measureText(this.textArr[i]).width;
if ((i + 1) % 2 === 0) {
this.ctx.fillStyle = '#c8171e';
} else {
this.ctx.fillStyle = '#000000';
}
this.ctx.fillText(this.textArr[i], curX, 0);
curX += w;
}
}
}
export class RichText extends Label {
disH = 30;
constructor(ctx?: any) {
super(ctx);
// this.dataArr = dataArr;
}
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;
this.ctx.fillStyle = this.fontColor;
const selfW = this.width * this.scaleX;
const chr = this.text.split(' ');
let temp = '';
const row = [];
const w = selfW - 80;
const disH = (this.fontSize + this.disH) * this.scaleY;
for (const c of chr) {
if (this.ctx.measureText(temp).width < w && this.ctx.measureText(temp + (c)).width <= w) {
temp += ' ' + c;
} else {
row.push(temp);
temp = ' ' + c;
}
}
row.push(temp);
const x = 0;
const y = -row.length * disH / 2;
// for (let b = 0 ; b < row.length; b++) {
// this.ctx.strokeText(row[b], x, y + ( b + 1 ) * disH ); // 每行字体y坐标间隔20
// }
if (this._outlineFlag) {
this.ctx.lineWidth = this._outLineWidth;
this.ctx.strokeStyle = this._outLineColor;
for (let b = 0; b < row.length; b++) {
this.ctx.strokeText(row[b], x, y + (b + 1) * disH); // 每行字体y坐标间隔20
}
// this.ctx.strokeText(this.text, 0, 0);
}
// this.ctx.fillStyle = '#ff7600';
for (let b = 0; b < row.length; b++) {
this.ctx.fillText(row[b], x, y + (b + 1) * disH); // 每行字体y坐标间隔20
}
}
drawSelf() {
super.drawSelf();
this.drawText();
}
}
export class LineRect extends MySprite {
lineColor = '#ffffff';
lineWidth = 10;
setSize(w, h) {
this.width = w;
this.height = h;
}
drawLine() {
this.ctx.beginPath();
this.ctx.moveTo(this._offX, this._offY);
this.ctx.lineTo(this._offX + this.width, this._offY);
this.ctx.lineTo(this._offX + this.width, this._offY + this.height);
this.ctx.lineTo(this._offX, this._offY + this.height);
this.ctx.closePath();
this.ctx.lineWidth = this.lineWidth;
// this.ctx.fillStyle = "rgb(2,33,42)"; //指定填充颜色
// this.ctx.fill(); //对多边形进行填充
this.ctx.strokeStyle = this.lineColor; // "#ffffff";
this.ctx.stroke();
}
drawSelf() {
super.drawSelf();
this.drawLine();
}
}
export class ShapeRect extends MySprite {
fillColor = '#FF0000';
setSize(w, h) {
this.width = w;
this.height = h;
// console.log('w:', w);
// console.log('h:', h);
}
drawShape() {
this.ctx.fillStyle = this.fillColor;
this.ctx.fillRect(this._offX, this._offY, this.width, this.height);
}
drawSelf() {
super.drawSelf();
this.drawShape();
}
}
export class ShapeCircle extends MySprite {
fillColor = '#FF0000';
radius = 0;
setRadius(r) {
this.anchorX = this.anchorY = 0.5;
this.radius = r;
this.width = r * 2;
this.height = r * 2;
}
drawShape() {
this.ctx.beginPath();
this.ctx.fillStyle = this.fillColor;
this.ctx.arc(0, 0, this.radius, 0, angleToRadian(360));
this.ctx.fill();
}
drawSelf() {
super.drawSelf();
this.drawShape();
}
}
export class ShapeRectNew extends MySprite {
radius = 0;
fillColor = '#ffffff';
strokeColor = '#000000';
fill = true;
stroke = false;
lineWidth = 1;
setSize(w, h, r) {
this.width = w;
this.height = h;
this.radius = r;
}
setOutLine(color, lineWidth) {
this.stroke = true;
this.strokeColor = color;
this.lineWidth = lineWidth;
}
drawShape() {
const ctx = this.ctx;
const width = this.width;
const height = this.height;
const radius = this.radius;
ctx.save();
ctx.beginPath(0);
// 从右下角顺时针绘制,弧度从0到1/2PI
ctx.arc(width - radius, height - radius, radius, 0, Math.PI / 2);
// 矩形下边线
ctx.lineTo(radius, height);
// 左下角圆弧,弧度从1/2PI到PI
ctx.arc(radius, height - radius, radius, Math.PI / 2, Math.PI);
// 矩形左边线
ctx.lineTo(0, radius);
// 左上角圆弧,弧度从PI到3/2PI
ctx.arc(radius, radius, radius, Math.PI, Math.PI * 3 / 2);
// 上边线
ctx.lineTo(width - radius, 0);
// 右上角圆弧
ctx.arc(width - radius, radius, radius, Math.PI * 3 / 2, Math.PI * 2);
// 右边线
ctx.lineTo(width, height - radius);
ctx.closePath();
if (this.fill) {
ctx.fillStyle = this.fillColor;
ctx.fill();
}
if (this.stroke) {
ctx.lineWidth = this.lineWidth;
ctx.strokeStyle = this.strokeColor;
ctx.stroke();
}
ctx.restore();
}
drawSelf() {
super.drawSelf();
this.drawShape();
}
}
export class MyAnimation extends MySprite {
frameArr = [];
frameIndex = 0;
playFlag = false;
lastDateTime;
curDelay = 0;
loop = false;
playEndFunc;
delayPerUnit = 1;
restartFlag = false;
reverseFlag = false;
addFrameByImg(img) {
const spr = new MySprite(this.ctx);
spr.init(img);
this._refreshSize(img);
spr.visible = false;
this.addChild(spr);
this.frameArr.push(spr);
this.frameArr[this.frameIndex].visible = true;
}
addFrameByUrl(url) {
const spr = new MySprite(this.ctx);
spr.load(url).then(img => {
this._refreshSize(img);
});
spr.visible = false;
this.addChild(spr);
this.frameArr.push(spr);
this.frameArr[this.frameIndex].visible = true;
}
_refreshSize(img: any) {
if (this.width < img.width) {
this.width = img.width;
}
if (this.height < img.height) {
this.height = img.height;
}
}
play() {
this.playFlag = true;
this.lastDateTime = new Date().getTime();
}
stop() {
this.playFlag = false;
}
replay() {
this.restartFlag = true;
this.play();
}
reverse() {
this.reverseFlag = !this.reverseFlag;
this.frameArr.reverse();
this.frameIndex = 0;
}
showAllFrame() {
for (const frame of this.frameArr) {
frame.alpha = 1;
}
}
hideAllFrame() {
for (const frame of this.frameArr) {
frame.alpha = 0;
}
}
playEnd() {
this.playFlag = false;
this.curDelay = 0;
this.frameArr[this.frameIndex].visible = true;
if (this.playEndFunc) {
this.playEndFunc();
this.playEndFunc = null;
}
}
updateFrame() {
if (this.frameArr[this.frameIndex]) {
this.frameArr[this.frameIndex].visible = false;
}
this.frameIndex++;
if (this.frameIndex >= this.frameArr.length) {
if (this.loop) {
this.frameIndex = 0;
} else if (this.restartFlag) {
this.restartFlag = false;
this.frameIndex = 0;
} else {
this.frameIndex--;
this.playEnd();
return;
}
}
this.frameArr[this.frameIndex].visible = true;
}
_updateDelay(delay) {
this.curDelay += delay;
if (this.curDelay < this.delayPerUnit) {
return;
}
this.curDelay -= this.delayPerUnit;
this.updateFrame();
}
_updateLastDate() {
if (!this.playFlag) { return; }
let delay = 0;
if (this.lastDateTime) {
delay = (new Date().getTime() - this.lastDateTime) / 1000;
}
this.lastDateTime = new Date().getTime();
this._updateDelay(delay);
}
update($event: any = null) {
super.update($event);
this._updateLastDate();
}
}
// --------=========== util func =============-------------
export function tweenChange(item, obj, time = 0.8, callBack = null, easing = null, update = null) {
const tween = new TWEEN.Tween(item).to(obj, time * 1000);
if (callBack) {
tween.onComplete(() => {
callBack();
});
}
if (easing) {
tween.easing(easing);
}
if (update) {
tween.onUpdate((a, b) => {
update(a, b);
});
}
tween.start();
return tween;
}
export function rotateItem(item, rotation, time = 0.8, callBack = null, easing = null) {
const tween = new TWEEN.Tween(item).to({ rotation }, time * 1000);
if (callBack) {
tween.onComplete(() => {
callBack();
});
}
if (easing) {
tween.easing(easing);
}
tween.start();
}
export function scaleItem(item, scale, time = 0.8, callBack = null, easing = null) {
const tween = new TWEEN.Tween(item).to({ scaleX: scale, scaleY: scale }, time * 1000);
if (callBack) {
tween.onComplete(() => {
callBack();
});
}
if (easing) {
tween.easing(easing);
}
tween.start();
return tween;
}
export function moveItem(item, x, y, time = 0.8, callBack = null, easing = null) {
const tween = new TWEEN.Tween(item).to({ x, y }, time * 1000);
if (callBack) {
tween.onComplete(() => {
callBack();
});
}
if (easing) {
tween.easing(easing);
}
tween.start();
return tween;
}
export function endShow(item, s = 1) {
item.scaleX = item.scaleY = 0;
item.alpha = 0;
const tween = new TWEEN.Tween(item)
.to({ alpha: 1, scaleX: s, scaleY: s }, 800)
.easing(TWEEN.Easing.Elastic.Out) // Use an easing function to make the animation smooth.
.onComplete(() => {
})
.start();
}
export function hideItem(item, time = 0.8, callBack = null, easing = null) {
if (item.alpha === 0) {
return;
}
const tween = new TWEEN.Tween(item)
.to({ alpha: 0 }, time * 1000)
// .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth.
.onComplete(() => {
if (callBack) {
callBack();
}
});
if (easing) {
tween.easing(easing);
}
tween.start();
}
export function showItem(item, time = 0.8, callBack = null, easing = null) {
if (item.alpha === 1) {
if (callBack) {
callBack();
}
return;
}
item.visible = true;
const tween = new TWEEN.Tween(item)
.to({ alpha: 1 }, time * 1000)
// .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth.
.onComplete(() => {
if (callBack) {
callBack();
}
});
if (easing) {
tween.easing(easing);
}
tween.start();
}
export function alphaItem(item, alpha, time = 0.8, callBack = null, easing = null) {
const tween = new TWEEN.Tween(item)
.to({ alpha }, time * 1000)
// .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth.
.onComplete(() => {
if (callBack) {
callBack();
}
});
if (easing) {
tween.easing(easing);
}
tween.start();
}
export function showStar(item, time = 0.8, callBack = null, easing = null) {
const tween = new TWEEN.Tween(item)
.to({ alpha: 1, scale: 1 }, time * 1000)
// .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth.
.onComplete(() => {
if (callBack) {
callBack();
}
});
if (easing) {
tween.easing(easing);
}
tween.start();
}
export function randomSortByArr(arr) {
const newArr = [];
const tmpArr = arr.concat();
while (tmpArr.length > 0) {
const randomIndex = Math.floor(tmpArr.length * Math.random());
newArr.push(tmpArr[randomIndex]);
tmpArr.splice(randomIndex, 1);
}
return newArr;
}
export function radianToAngle(radian) {
return radian * 180 / Math.PI;
// 角度 = 弧度 * 180 / Math.PI;
}
export function angleToRadian(angle) {
return angle * Math.PI / 180;
// 弧度= 角度 * Math.PI / 180;
}
export function getPosByAngle(angle, len) {
const radian = angle * Math.PI / 180;
const x = Math.sin(radian) * len;
const y = Math.cos(radian) * len;
return { x, y };
}
export function getAngleByPos(px, py, mx, my) {
const x = Math.abs(px - mx);
const y = Math.abs(py - my);
const z = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
const cos = y / z;
const radina = Math.acos(cos); // 用反三角函数求弧度
let angle = Math.floor(180 / (Math.PI / radina) * 100) / 100; // 将弧度转换成角度
if (mx > px && my > py) {// 鼠标在第四象限
angle = 180 - angle;
}
if (mx === px && my > py) {// 鼠标在y轴负方向上
angle = 180;
}
if (mx > px && my === py) {// 鼠标在x轴正方向上
angle = 90;
}
if (mx < px && my > py) {// 鼠标在第三象限
angle = 180 + angle;
}
if (mx < px && my === py) {// 鼠标在x轴负方向
angle = 270;
}
if (mx < px && my < py) {// 鼠标在第二象限
angle = 360 - angle;
}
// console.log('angle: ', angle);
return angle;
}
export function removeItemFromArr(arr, item) {
const index = arr.indexOf(item);
if (index !== -1) {
arr.splice(index, 1);
}
}
export function circleMove(item, x0, y0, time = 2, addR = 360, xPer = 1, yPer = 1, callBack = null, easing = null) {
const r = getPosDistance(item.x, item.y, x0, y0);
let a = getAngleByPos(item.x, item.y, x0, y0);
a += 90;
const obj = { r, a };
item._circleAngle = a;
const targetA = a + addR;
const tween = new TWEEN.Tween(item).to({ _circleAngle: targetA }, time * 1000);
if (callBack) {
tween.onComplete(() => {
callBack();
});
}
if (easing) {
tween.easing(easing);
}
tween.onUpdate((item, progress) => {
// console.log(item._circleAngle);
const r = obj.r;
const a = item._circleAngle;
const x = x0 + r * xPer * Math.cos(a * Math.PI / 180);
const y = y0 + r * yPer * Math.sin(a * Math.PI / 180);
item.x = x;
item.y = y;
// obj.a ++;
});
tween.start();
}
export function getPosDistance(sx, sy, ex, ey) {
const _x = ex - sx;
const _y = ey - sy;
const len = Math.sqrt(Math.pow(_x, 2) + Math.pow(_y, 2));
return len;
}
export function delayCall(callback, second) {
const tween = new TWEEN.Tween(this)
.delay(second * 1000)
.onComplete(() => {
if (callback) {
callback();
}
})
.start();
}
export function formatTime(fmt, date) {
// "yyyy-MM-dd HH:mm:ss";
const o = {
'M+': date.getMonth() + 1, // 月份
'd+': date.getDate(), // 日
'h+': date.getHours(), // 小时
'm+': date.getMinutes(), // 分
's+': date.getSeconds(), // 秒
'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
S: date.getMilliseconds() // 毫秒
};
if (/(y+)/.test(fmt)) { fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length)); }
for (const k in o) {
if (new RegExp('(' + k + ')').test(fmt)) {
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1)
? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)));
}
}
return fmt;
}
export function getMinScale(item, maxLen) {
const sx = maxLen / item.width;
const sy = maxLen / item.height;
const minS = Math.min(sx, sy);
return minS;
}
export function jelly(item, time = 0.7) {
if (item.jellyTween) {
TWEEN.remove(item.jellyTween);
}
const t = time / 9;
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.1, baseSY * 0.9, t],
[baseSX * 0.98, baseSY * 1.02, t * 2],
[baseSX * 1.02, baseSY * 0.98, t * 2],
[baseSX * 0.99, baseSY * 1.01, t * 2],
[baseSX * 1.0, baseSY * 1.0, t * 2],
];
run();
}
export function showPopParticle(img, pos, parent, num = 20, minLen = 40, maxLen = 80, showTime = 0.4) {
for (let i = 0; i < num; i++) {
const particle = new MySprite();
particle.init(img);
particle.x = pos.x;
particle.y = pos.y;
parent.addChild(particle);
const randomR = 360 * Math.random();
particle.rotation = randomR;
const randomS = 0.3 + Math.random() * 0.7;
particle.setScaleXY(randomS * 0.3);
const randomX = Math.random() * 20 - 10;
particle.x += randomX;
const randomY = Math.random() * 20 - 10;
particle.y += randomY;
const randomL = minLen + Math.random() * (maxLen - minLen);
const randomA = 360 * Math.random();
const randomT = getPosByAngle(randomA, randomL);
moveItem(particle, particle.x + randomT.x, particle.y + randomT.y, showTime, () => {
}, TWEEN.Easing.Exponential.Out);
// scaleItem(particle, 0, 0.6, () => {
//
// });
scaleItem(particle, randomS, 0.6, () => {
}, TWEEN.Easing.Exponential.Out);
setTimeout(() => {
hideItem(particle, 0.4, () => {
}, TWEEN.Easing.Cubic.In);
}, showTime * 0.5 * 1000);
}
}
export function shake(item, time = 0.5, callback = null, rate = 1) {
if (item.shakeTween) {
return;
}
item.shakeTween = true;
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 move4 = () => {
moveItem(item, baseX, baseY, time / 4, () => {
item.shakeTween = false;
if (callback) {
callback();
}
}, easing);
};
const move3 = () => {
moveItem(item, baseX + offX / 4, baseY + offY / 4, time / 4, () => {
move4();
}, easing);
};
const move2 = () => {
moveItem(item, baseX - offX / 4 * 3, baseY - offY / 4 * 3, time / 4, () => {
move3();
}, easing);
};
const move1 = () => {
moveItem(item, baseX + offX, baseY + offY, time / 7.5, () => {
move2();
}, easing);
};
move1();
}
// --------------- custom class --------------------
...@@ -17,4 +17,40 @@ ...@@ -17,4 +17,40 @@
/*//border-radius: 20px;*/ /*//border-radius: 20px;*/
/*//border-width: 2px;*/ /*//border-width: 2px;*/
/*//border-color: #000000;*/ /*//border-color: #000000;*/
}
.border-lite {
border: 2px dashed #ddd;
border-radius: 0.5rem;
padding: 10px;
margin: 10px;
}
.p-image-children-editor {
width: 100%;
height: 95%;
border-radius: 0.5rem;
border: 2px solid #ddd;
.preview-box {
margin: auto;
width: 100%;
height: 100%;
border: 2px dashed #ddd;
border-radius: 0.5rem;
background-color: #fafafa;
text-align: center;
color: #aaa;
.preview-img {
height: 100%;
width: auto;
}
}
} }
\ No newline at end of file
...@@ -49,23 +49,43 @@ ...@@ -49,23 +49,43 @@
</div> </div>
</div> </div>
 <div style="clear:both; height:0; font-size:1px; line-height:0px;"></div>  <div style="clear:both; height:0; font-size:1px; line-height:0px;"></div>
<div style="float: left; width: 100%">
<app-custom-hot-zone
[bgItem]="{}"
[isHasRect]="false"
[isHasText]="false"
[item]="item"
[hotZoneItemArr]="item.targets"
[refreshCaller]="caller"
(save)="saveData($event)"
>
</app-custom-hot-zone>
<!-- <app-preview <div class="border">
<span style="height: 30px; font-size: 18px;">单词:</span>
></app-preview> --> <br>
<div *ngFor="let it of item.targets; let i = index" style="float: left; width: 350px;">
<div class="border-lite" style="width: 300px; float: left;">
<app-upload-image-with-preview
[picUrl]="it.targetImg"
(imageUploaded)="onTargetImgUploadSuccess($event, i)"
></app-upload-image-with-preview>
<span style="height: 30px; font-size: 18px;">发音:</span>
<app-audio-recorder
[audioUrl]="it.targetAudio"
(audioUploaded)="onTargetAudioUploadSuccess($event, i)"
></app-audio-recorder>
<div style="float: none; padding-top: 30px;">
<button style="width: 100%; height: 45px; float: none;" nz-button nzType="dashed" class="add-btn" (click)="deleteTarget(i)">
删除
</button>
</div>
</div>
</div>
<div style="width: 300px; float: left; height: 280px; padding: 20px;" nz-col nzSpan="8" class="add-btn-box" >
<button style=" margin: auto; width: 100%; height: 100%;" nz-button nzType="dashed" class="add-btn" (click)="addTarget()">
<i nz-icon nzType="plus-circle" nzTheme="outline"></i>
Add
</button>
</div>
 <div style="clear:both; height:0; font-size:1px; line-height:0px;"></div>
</div>
<div class="border" style="height: 80vh">
<span style="height: 30px; font-size: 18px;">单词位置:</span>
<br>
<div class="p-image-children-editor" #wrap>
<canvas class="preview-box" id="canvas" #canvas></canvas>
</div>
</div> </div>
<!-- <!--
<div style="position: absolute; left: 200px; top: 100px; width: 800px;"> <div style="position: absolute; left: 200px; top: 100px; width: 800px;">
......
import { Component, EventEmitter, Input, OnDestroy, OnChanges, OnInit, Output, ApplicationRef, ChangeDetectorRef } from '@angular/core'; import { Component, EventEmitter, ElementRef, Input, ViewChild, OnDestroy, OnChanges, OnInit, Output, ApplicationRef, ChangeDetectorRef } from '@angular/core';
import { PreviewCanvas } from "./PreviewCanvas";
@Component({ @Component({
selector: 'app-form', selector: 'app-form',
...@@ -11,11 +11,7 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy { ...@@ -11,11 +11,7 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
// 储存数据用 // 储存数据用
saveKey = 'ym-2-30'; saveKey = 'ym-2-30';
// 储存对象 item = null;
item;
caller: any = {};
constructor(private appRef: ApplicationRef, private changeDetectorRef: ChangeDetectorRef) { constructor(private appRef: ApplicationRef, private changeDetectorRef: ChangeDetectorRef) {
...@@ -24,7 +20,6 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy { ...@@ -24,7 +20,6 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
deleteCarrot(idx) { deleteCarrot(idx) {
this.item.carrots.splice(idx, 1); this.item.carrots.splice(idx, 1);
this.refreshBackground();
this.save(); this.save();
} }
...@@ -33,7 +28,6 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy { ...@@ -33,7 +28,6 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
carrotImg: '', carrotImg: '',
holeImg: '', holeImg: '',
}); });
this.refreshBackground();
this.save(); this.save();
} }
...@@ -79,21 +73,33 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy { ...@@ -79,21 +73,33 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
} }
addTarget() {
this.item.targets.push({
targetImg: '',
x: 0,
y: -300
});
}
deleteTarget(idx) {
this.item.targets.splice(idx, 1);
this.save();
}
ngOnChanges() { ngOnChanges() {
} }
ngOnDestroy() { ngOnDestroy() {
this.previewCanvas.ngOnDestroy();
} }
previewCanvas;
@ViewChild('wrap', { static: true }) wrap: ElementRef;
@ViewChild('canvas', { static: true }) canvas: ElementRef;
init() { init() {
this.previewCanvas = new PreviewCanvas(this.wrap, this.canvas, this.item);
} this.previewCanvas.ngOnInit();
this.previewCanvas.setSaveFunc(this.save.bind(this));
refreshBackground() {
this.caller.refreshBackground();
} }
...@@ -104,7 +110,11 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy { ...@@ -104,7 +110,11 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
onImageUploadSuccess(e, key, idx) { onImageUploadSuccess(e, key, idx) {
// this.item[key] = e.url; // this.item[key] = e.url;
this.item.carrots[idx][key + 'Img'] = e.url; this.item.carrots[idx][key + 'Img'] = e.url;
this.refreshBackground(); this.save();
}
onTargetImgUploadSuccess(e, idx) {
this.item.targets[idx].targetImg = e.url;
this.save(); this.save();
} }
...@@ -118,20 +128,15 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy { ...@@ -118,20 +128,15 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
this.save(); this.save();
} }
saveData(e) {
this.item.targets = [];
e.hotZoneItemArr.forEach((target) => {
console.log('target.rect = ' + JSON.stringify(target.rect));
this.item.targets.push(target);
});
this.save();
}
// 标题音频 // 标题音频
onTittleAudioUploadSuccess(e, key) { onTittleAudioUploadSuccess(e, key) {
this.item.tittle.audio = e.url; this.item.tittle.audio = e.url;
this.save(); this.save();
} }
onTargetAudioUploadSuccess(e, idx) {
this.item.targets[idx].targetAudio = e.url;
this.save();
}
/** /**
* 储存数据 * 储存数据
...@@ -139,6 +144,7 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy { ...@@ -139,6 +144,7 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
save() { save() {
(<any>window).courseware.setData(this.item, null, this.saveKey); (<any>window).courseware.setData(this.item, null, this.saveKey);
this.refresh(); this.refresh();
this.previewCanvas.refresh();
} }
/** /**
......
export let defaultData = {
tittle: {
word: "C",
text: "listen and select the right word you just heard.",
audio: "tittle"
},
carrots: [{
carrotImg: 'carrot',
holeImg: 'hole',
}, {
carrotImg: 'carrot',
holeImg: 'hole',
}, {
carrotImg: 'carrot',
holeImg: 'hole',
}, {
carrotImg: 'carrot',
holeImg: 'hole',
}, {
carrotImg: 'carrot',
holeImg: 'hole',
}, {
carrotImg: 'carrot',
holeImg: 'hole',
}, {
carrotImg: 'carrot',
holeImg: 'hole',
}, {
carrotImg: 'carrot',
holeImg: 'hole',
}],
targets: []
};
\ 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() {
}
refresh() {
this.removeChildren();
this.initView();
}
_editMode = true;
_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);
this._currentTouchSprite = result;
if (result != null) {
if (result._onTouchBeganListener &&
typeof (result._onTouchBeganListener) == 'function') {
result._onTouchBeganListener(pos);
}
}
}
_onTouchMove(pos) {
if (this._currentTouchSprite != null) {
if (this._currentTouchSprite._checkHitPosition(pos)) {
if (this._currentTouchSprite._onTouchMoveListener &&
typeof (this._currentTouchSprite._onTouchMoveListener) == 'function') {
this._currentTouchSprite._onTouchMoveListener(pos);
}
} else {
if (this._currentTouchSprite._onTouchCancelListener &&
typeof (this._currentTouchSprite._onTouchCancelListener) == 'function') {
this._currentTouchSprite._onTouchCancelListener(pos);
}
this._currentTouchSprite = null;
}
}
}
_onTouchEnd(pos) {
if (this._currentTouchSprite != null) {
if (this._currentTouchSprite._onTouchEndListener &&
typeof (this._currentTouchSprite._onTouchEndListener) == 'function') {
this._currentTouchSprite._onTouchEndListener(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();
}, time * 1000);
})
}
export async function asyncTweenChange(node, obj, time) {
return new Promise((resolve, reject) => {
tweenChange(node, obj, time, () => {
resolve();
});
});
}
\ 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 = [];
this.data.carrots.forEach((carrot) => {
imgUrlList.push(carrot.carrotImg);
imgUrlList.push(carrot.holeImg);
});
this.data.targets.forEach((target) => {
imgUrlList.push(target.targetImg);
});
// audioUrlList.push(this.data.wholeAuido);
// audioUrlList.push(this.data.tittle.audio);
this.preLoadData(imgUrlList, audioUrlList);
}
}
preLoadData(imgUrlList, audioUrlList) {
for (var i = 0; i < imgUrlList.length; ++i) {
this._parent.addUrlToImages(imgUrlList[i]);
}
for (var i = 0; i < audioUrlList.length; ++i) {
this._parent.addUrlToAudioObj(audioUrlList[i]);
}
}
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_bg2'))
bg.setScaleXY(this._parent.mapScale);
bg.alpha = 0;
bg.anchorX = 0.5;
bg.anchorY = 1;
bg.setPosition(screenSize.width / 2, screenSize.height);
bg.setName('bg');
this.addChild(bg);
this.bg = bg;
let bgSized2 = new TouchSprite();
bgSized2.init(this.images.get('Img_bg_ground'));
bgSized2.anchorX = 0.5;
bgSized2.anchorY = 1;
bgSized2.scaleX = (screenSize.width / defaultSize.width) / this._parent.mapScale;
bgSized2.setPosition(0, 0);
this.bg.addChild(bgSized2);
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 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.createHoles();
// 创建胡萝卜
this.createCarrots();
// 创建可选的单词
this.createWords();
}
createCarrots() {
let screenSize = this.getScreenSize();
let defaultSize = this.getDefaultScreenSize();
const length = this.data.carrots.length;
this.data.carrots.forEach((carrot, idx) => {
let carrotSp = new TouchSprite();
carrotSp.init(this.images.get(carrot.carrotImg));
carrotSp.setPositionX(this.bg.width / length * (idx - (length - 1) / 2));
carrotSp.setPositionY(-550);
this.bg.addChild(carrotSp);
});
}
createHoles() {
let screenSize = this.getScreenSize();
let defaultSize = this.getDefaultScreenSize();
const length = this.data.carrots.length;
this.data.carrots.forEach((carrot, idx) => {
let hole = new TouchSprite();
hole.init(this.images.get(carrot.holeImg));
hole.anchorX = 0.5;
hole.anchorY = 0;
hole.setPositionX(this.bg.width / length * (idx - (length - 1) / 2));
hole.setPositionY(-520);
this.bg.addChild(hole);
});
}
createWords() {
let screenSize = this.getScreenSize();
let defaultSize = this.getDefaultScreenSize();
const length = this.data.carrots.length;
this.data.targets.forEach((targetData, idx) => {
let targetSp = new TouchSprite();
targetSp.init(this.images.get(targetData.targetImg));
targetSp.setPositionX(targetData.x);
targetSp.setPositionY(targetData.y);
targetSp.addTouchBeganListener(({ x, y }) => {
this.onTargetSpTouchBengan({ x, y }, targetSp, idx);
});
targetSp.addTouchMoveListener(({ x, y }) => {
this.onTargetSpTouchMoved({ x, y }, targetSp, idx);
});
targetSp.addTouchEndListener(()=>{
this.onTargetSpTouchEnded();
});
this.bg.addChild(targetSp);
});
}
onTargetSpTouchBengan({ x, y }, targetSp, idx) {
targetSp.set('touchStartPos', { x, y });
targetSp.set('startPos', { x: targetSp.x, y: targetSp.y });
}
onTargetSpTouchMoved({ x, y }, targetSp, idx) {
if (this._editMode) {
let screenSize = this.getScreenSize();
let defaultSize = this.getDefaultScreenSize();
let spritePosX = targetSp.get('startPos').x + (x - targetSp.get('touchStartPos').x) / this._parent.mapScale;
let spritePosY = targetSp.get('startPos').y + (y - targetSp.get('touchStartPos').y) / this._parent.mapScale;
targetSp.setPositionX(spritePosX);
targetSp.setPositionY(spritePosY);
this.data.targets[idx].x = spritePosX;
this.data.targets[idx].y = spritePosY;
}
}
onTargetSpTouchEnded() {
if (this._editMode) {
this._save();
}
}
printCurrentStatus() {
console.log(JSON.stringify(this.status));
}
onClickTittle() {
this._parent.playAudio(this.data.tittle.audio);
}
gameStart() {
this.playIncomeAudio();
}
playIncomeAudio() {
this._parent.playAudio('audio_new_page');
}
}
const res = [
['Img_bg', "assets/play/Img_bg.png"],
['Img_bg2', "assets/play/Img_bg2.png"],
['Img_bg_ground', "assets/play/Img_bg_ground.png"],
['Img_tittleBg', "assets/play/Img_tittleBg.png"],
];
const resAudio = [
// ['click', "assets/play/music/click.mp3"],
];
export {res, resAudio};
...@@ -27,6 +27,22 @@ export class Game { ...@@ -27,6 +27,22 @@ export class Game {
} }
playAudio(key, now = false, callback = null) {
this._parent.playAudio(key, now, callback);
}
_editMode = false;
setEditMode(flg) {
this._editMode = flg;
}
isEditMode() {
return this._editMode;
}
_save;
setSaveFunc(save) {
this._save = save;
}
addChild(node, z = 1) { addChild(node, z = 1) {
this._parent.renderArr.push(node); this._parent.renderArr.push(node);
......
...@@ -54,7 +54,7 @@ export class MyGame extends Game { ...@@ -54,7 +54,7 @@ export class MyGame extends Game {
imgUrlList.push(carrot.holeImg); imgUrlList.push(carrot.holeImg);
}); });
this.data.targets.forEach((target) => { this.data.targets.forEach((target) => {
imgUrlList.push(target.pic_url); imgUrlList.push(target.targetImg);
}); });
// audioUrlList.push(this.data.wholeAuido); // audioUrlList.push(this.data.wholeAuido);
// audioUrlList.push(this.data.tittle.audio); // audioUrlList.push(this.data.tittle.audio);
...@@ -101,16 +101,6 @@ export class MyGame extends Game { ...@@ -101,16 +101,6 @@ export class MyGame extends Game {
bgSized1.setScaleXY(this.getFullScaleXY()); bgSized1.setScaleXY(this.getFullScaleXY());
this.addChild(bgSized1); this.addChild(bgSized1);
let bgSized2 = new TouchSprite();
bgSized2.init(this.images.get('Img_bg_ground'));
bgSized2.anchorX = 0.5;
bgSized2.anchorY = 1;
bgSized2.setPosition(screenSize.width / 2, screenSize.height);
bgSized2.scaleX = screenSize.width / defaultSize.width;
bgSized2.scaleY = screenSize.height / defaultSize.height;
this.addChild(bgSized2);
// 背景 // 背景
let bg = new TouchSprite(); let bg = new TouchSprite();
bg.init(this.images.get('Img_bg2')) bg.init(this.images.get('Img_bg2'))
...@@ -124,6 +114,15 @@ export class MyGame extends Game { ...@@ -124,6 +114,15 @@ export class MyGame extends Game {
this.bg = bg; this.bg = bg;
let bgSized2 = new TouchSprite();
bgSized2.init(this.images.get('Img_bg_ground'));
bgSized2.anchorX = 0.5;
bgSized2.anchorY = 1;
bgSized2.scaleX = (screenSize.width / defaultSize.width) / this._parent.mapScale;
bgSized2.setPosition(0, 0);
this.bg.addChild(bgSized2);
const bgRect = new ShapeRect(); const bgRect = new ShapeRect();
bgRect.setSize(57, 65); bgRect.setSize(57, 65);
bgRect.fillColor = '#f8c224'; bgRect.fillColor = '#f8c224';
...@@ -197,7 +196,7 @@ export class MyGame extends Game { ...@@ -197,7 +196,7 @@ export class MyGame extends Game {
let carrotSp = new TouchSprite(); let carrotSp = new TouchSprite();
carrotSp.init(this.images.get(carrot.carrotImg)); carrotSp.init(this.images.get(carrot.carrotImg));
carrotSp.setPositionX(this.bg.width / length * (idx - (length - 1) / 2)); carrotSp.setPositionX(this.bg.width / length * (idx - (length - 1) / 2));
carrotSp.setPositionY(-550 * (screenSize.height / defaultSize.height) / this._parent.mapScale); carrotSp.setPositionY(-550);
this.bg.addChild(carrotSp); this.bg.addChild(carrotSp);
}); });
} }
...@@ -212,7 +211,7 @@ export class MyGame extends Game { ...@@ -212,7 +211,7 @@ export class MyGame extends Game {
hole.anchorX = 0.5; hole.anchorX = 0.5;
hole.anchorY = 0; hole.anchorY = 0;
hole.setPositionX(this.bg.width / length * (idx - (length - 1) / 2)); hole.setPositionX(this.bg.width / length * (idx - (length - 1) / 2));
hole.setPositionY(-520 * (screenSize.height / defaultSize.height) / this._parent.mapScale); hole.setPositionY(-520);
this.bg.addChild(hole); this.bg.addChild(hole);
}); });
} }
...@@ -222,12 +221,14 @@ export class MyGame extends Game { ...@@ -222,12 +221,14 @@ export class MyGame extends Game {
let defaultSize = this.getDefaultScreenSize(); let defaultSize = this.getDefaultScreenSize();
const length = this.data.carrots.length; const length = this.data.carrots.length;
this.data.targets.forEach((targetData, idx) => { this.data.targets.forEach((targetData, idx) => {
console.log('targetData.rect = ' + JSON.stringify(targetData.rect));
let targetSp = new TouchSprite(); let targetSp = new TouchSprite();
targetSp.init(this.images.get(targetData.pic_url)); targetSp.init(this.images.get(targetData.targetImg));
targetSp.setPositionX(targetData.x); targetSp.setPositionX(targetData.x);
// 一通复杂的计算之后得到一个实际的Y坐标 targetSp.setPositionY(targetData.y);
targetSp.setPositionY((targetData.y - defaultSize.height / 2) * (screenSize.height / defaultSize.height) / this._parent.mapScale);
if (!this.isEditMode()) {
targetSp.alpha = 0.001;
}
targetSp.addTouchBeganListener(({ x, y }) => { targetSp.addTouchBeganListener(({ x, y }) => {
this.onTargetSpTouchBengan({ x, y }, targetSp, idx); this.onTargetSpTouchBengan({ x, y }, targetSp, idx);
...@@ -236,29 +237,45 @@ export class MyGame extends Game { ...@@ -236,29 +237,45 @@ export class MyGame extends Game {
this.onTargetSpTouchMoved({ x, y }, targetSp, idx); this.onTargetSpTouchMoved({ x, y }, targetSp, idx);
}); });
targetSp.addTouchEndListener(() => {
this.onTargetSpTouchEnded();
});
this.bg.addChild(targetSp); this.bg.addChild(targetSp);
}); });
} }
editMode = true;
onTargetSpTouchBengan({ x, y }, targetSp, idx) { onTargetSpTouchBengan({ x, y }, targetSp, idx) {
targetSp.set('touchStartPos', { x, y }); if (this.isEditMode()) {
targetSp.set('startPos', { x: targetSp.x, y: targetSp.y }); targetSp.set('touchStartPos', { x, y });
targetSp.set('startPos', { x: targetSp.x, y: targetSp.y });
} else {
tweenChange(targetSp, { alpha: 1 }, 0.2);
this.playAudio('click', true, () => {
this.playAudio(this.data.targets[idx].targetAudio);
});
}
} }
onTargetSpTouchMoved({ x, y }, targetSp, idx) { onTargetSpTouchMoved({ x, y }, targetSp, idx) {
if (this.editMode) { if (!this.isEditMode()) {
let screenSize = this.getScreenSize(); return;
let defaultSize = this.getDefaultScreenSize(); }
let screenSize = this.getScreenSize();
let spritePosX = targetSp.get('startPos').x + (x - targetSp.get('touchStartPos').x) / this._parent.mapScale; let defaultSize = this.getDefaultScreenSize();
let spritePosY = targetSp.get('startPos').y + (y - targetSp.get('touchStartPos').y) / this._parent.mapScale;
targetSp.setPositionX(spritePosX); let spritePosX = targetSp.get('startPos').x + (x - targetSp.get('touchStartPos').x) / this._parent.mapScale;
targetSp.setPositionY(spritePosY); let spritePosY = targetSp.get('startPos').y + (y - targetSp.get('touchStartPos').y) / this._parent.mapScale;
targetSp.setPositionX(spritePosX);
this.data.targets[idx].x = spritePosX; targetSp.setPositionY(spritePosY);
// 一通复杂的计算之后得到一个不随分辨率改变的虚拟Y坐标
this.data.targets[idx].y = spritePosY * this._parent.mapScale / (screenSize.height / defaultSize.height) + defaultSize.height / 2; this.data.targets[idx].x = spritePosX;
this.data.targets[idx].y = spritePosY;
}
onTargetSpTouchEnded() {
if (this.isEditMode()) {
this._save();
} }
} }
......
...@@ -3,8 +3,6 @@ const res = [ ...@@ -3,8 +3,6 @@ const res = [
['Img_bg2', "assets/play/Img_bg2.png"], ['Img_bg2', "assets/play/Img_bg2.png"],
['Img_bg_ground', "assets/play/Img_bg_ground.png"], ['Img_bg_ground', "assets/play/Img_bg_ground.png"],
['Img_tittleBg', "assets/play/Img_tittleBg.png"], ['Img_tittleBg', "assets/play/Img_tittleBg.png"],
['carrot', "assets/play/carrot.png"],
['hole', "assets/play/hole.png"],
]; ];
......
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