Commit 4244b24f authored by Chen Jiping's avatar Chen Jiping

完成模板开发

parent 3695f7ce
...@@ -128,5 +128,8 @@ ...@@ -128,5 +128,8 @@
} }
} }
}, },
"defaultProject": "ng-template-generator" "defaultProject": "ng-template-generator",
} "cli": {
"analytics": "882c12b6-e63d-4a1e-8be1-2de06114c519"
}
}
\ No newline at end of file
<div class="model-content"> <div class="model-content">
<div nz-row>
<div nz-col nzOffset='4'>
<div style="position: absolute; left: 200px; top: 100px; width: 800px;"> <h1 nz-title>课程练习内容编辑</h1>
</div>
<input type="text" nz-input [(ngModel)]="item.text" (blur)="save()"> </div>
<div nz-row>
<app-upload-image-with-preview <div nz-col [nzSpan]="15" nzOffset="3">
[picUrl]="item.pic_url" <div nz-form>
(imageUploaded)="onImageUploadSuccess($event, 'pic_url')" <nz-form-item>
></app-upload-image-with-preview> <nz-form-label [nzSpan]="6" nzFor="exercises">练习题内容</nz-form-label>
<nz-form-control [nzSpan]="6">
<app-audio-recorder <button nz-button nzType="dashed" class="add-btn" id="add-btn" (click)="addExercisesItem()">
[audioUrl]="item.audio_url" <i nz-icon nzType="plus-circle" nzTheme="outline"></i>添加
(audioUploaded)="onAudioUploadSuccess($event, 'audio_url')" </button>
></app-audio-recorder> </nz-form-control>
<app-custom-hot-zone></app-custom-hot-zone> </nz-form-item>
<app-upload-video></app-upload-video> <div>
<app-lesson-title-config></app-lesson-title-config> <div *ngFor="let it of item.exercisesArr;let i = index" style="padding: 0.5vw;">
<div class="border">
<nz-divider nzText="练习-{{i+1}}" nzOrientation="left"></nz-divider>
<nz-form-item>
<nz-form-label [nzSpan]="6" nzFor="it.audio_url">发音</nz-form-label>
<nz-form-control [nzSpan]="6">
<app-audio-recorder id="it.audio_url"
[audioUrl]="it.audio_url"
(audioUploaded)="onImageUploadSuccess($event, it, 'audio_url')">
</app-audio-recorder>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label [nzSpan]="6" nzFor="it.answers">答案</nz-form-label>
<nz-form-control [nzSpan]="6">
<button nz-button nzType="dashed" class="add-btn" id="add-btn"
(click)="addAnswerItem(it.answers, it)" [disabled]="it.answers.length == 3 ? true : false">
<i nz-icon nzType="plus-circle" nzTheme="outline"></i>添加
</button>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<div nz-col [nzSpan]="22" nzOffset="1">
<nz-table #answersTable [nzData]="it.answers" [nzHideOnSinglePage]="true" [nzBordered]="true" [nzNoResult]=''>
<thead>
<tr>
<th>序号</th>
<th>答案类型</th>
<th>备选答案</th>
<th>是否正确</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let data of answersTable.data;let j = index">
<td>{{j+1}}</td>
<td>
<nz-select [(ngModel)]="data.contentType" nzPlaceHolder="请选择" (ngModelChange)="setAnswerType($event, data)">
<nz-option nzValue="T" nzLabel="文字"></nz-option>
<nz-option nzValue="P" nzLabel="图片"></nz-option>
</nz-select>
</td>
<td>
<div *ngIf="data.contentType == 'P'">
<app-upload-image-with-preview
style="width: 100%"
[picUrl]="data.pic_url"
(imageUploaded)="onImageUploadSuccess($event, data, 'pic_url')"
></app-upload-image-with-preview>
</div>
<div *ngIf="data.contentType == 'T'">
<input type="text" nz-input placeholder="请录入备选答案" [(ngModel)]="data.text" (blur)="save()">
</div>
</td>
<td>
<nz-switch [ngModel]="data.right" nzCheckedChildren="是" nzUnCheckedChildren="否" (ngModelChange)="setAnswerRight($event, data)"></nz-switch>
</td>
<td>
<button nz-button nzType="danger" (click)="delAnswerItem(it.answers, j, it)" [disabled]="it.answers.length == 2 ? true : false"><i nz-icon nzType="delete" nzTheme="outline"></i>删除</button>
</td>
</tr>
</tbody>
</nz-table>
</div>
</nz-form-item>
<nz-form-item>
<button style="margin: 10px;" nz-button nzType="danger" (click)="delExercisesItem(i)">
<span>删除</span>
</button>
</nz-form-item>
</div>
</div>
</div>
</div>
</div>
</div> </div>
</div> </div>
...@@ -10,7 +10,7 @@ import {Component, EventEmitter, Input, OnDestroy, OnChanges, OnInit, Output, Ap ...@@ -10,7 +10,7 @@ import {Component, EventEmitter, Input, OnDestroy, OnChanges, OnInit, Output, Ap
export class FormComponent implements OnInit, OnChanges, OnDestroy { export class FormComponent implements OnInit, OnChanges, OnDestroy {
// 储存数据用 // 储存数据用
saveKey = "test_0011"; saveKey = "DF-L211";
// 储存对象 // 储存对象
item; item;
...@@ -24,6 +24,8 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy { ...@@ -24,6 +24,8 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
this.item = {}; this.item = {};
this.item.exercisesArr = [];
// 获取存储的数据 // 获取存储的数据
(<any> window).courseware.getData((data) => { (<any> window).courseware.getData((data) => {
...@@ -58,19 +60,19 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy { ...@@ -58,19 +60,19 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
* 储存图片数据 * 储存图片数据
* @param e * @param e
*/ */
onImageUploadSuccess(e, key) { onImageUploadSuccess(e, item, key) {
this.item[key] = e.url; item[key] = e.url;
this.save(); this.save();
} }
/** /**
* 储存音频数据 * 储存音频数据
* @param e * @param e
*/ */
onAudioUploadSuccess(e, key) { onAudioUploadSuccess(e, item, key) {
this.item[key] = e.url; item[key] = e.url;
this.save(); this.save();
} }
...@@ -93,5 +95,100 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy { ...@@ -93,5 +95,100 @@ export class FormComponent implements OnInit, OnChanges, OnDestroy {
}, 1); }, 1);
} }
/**
* 获取缺省的练习题内容
*/
getDefaultExercisesItem(){
let exercises = {
audio_url:"",
answers:[]
}
for(let i = 0; i < 2; ++ i){
let answer = this.getDefaultAnswer();
exercises.answers.push(answer);
}
return exercises;
}
getDefaultAnswer(){
let answer = {
contentType:"T",
text:"",
pic_url:"",
right:true
};
return answer;
}
/**
* 添加练习
*/
addExercisesItem(){
let exercises = this.getDefaultExercisesItem();
this.item.exercisesArr.push(exercises);
this.save();
}
delExercisesItem(index){
if (index !== -1) {
this.item.exercisesArr.splice(index, 1);
this.save();
}
}
setAnswerType(e, item){
if(e == 'P'){
item.text = "";
}
else if(e == 'T'){
item.pic_url = "";
}
else{
item.text = "";
item.pic_url = "";
}
this.save();
}
setAnswerRight(e, item){
item.right = e;
this.save();
}
/**
* 添加答案
*/
addAnswerItem(answers, exercises){
let answer = this.getDefaultAnswer();
exercises.answers = [...answers, answer];
this.save();
}
/**
* 删除答案
* @param answers
* @param index
*/
delAnswerItem(answers, index, practice){
if (index !== -1) {
answers.splice(index, 1);
practice.answers = [...answers];
this.save();
}
}
} }
import {
MySprite, tweenChange,
ShapeRect
} from './Unit';
export class AudioAnimation {
private x = 0;
private y = 0;
images = new Map();
bg : ShapeRect;
scaleX = 1;
scaleY = 1;
playPic1;
playPic2;
playPic3;
curAudio;
playing = false;
hideFlag = true;
/**
* 设置播放帧图片
* @param images
*/
constructor(images) {
this.images = images;
}
setXY(x, y){
this.x = x;
this.y = y;
}
/**
* 初始化图
* @param parent 图片显示父对象
* @param scaleX
* @param sacleY
* @param show 是否直接显示
*/
initPic(parent, scaleX: number, sacleY: number, show: boolean) {
if (!parent) {
return;
}
const bg = new ShapeRect();
const getAudioPic = (index) => {
const playPic = new MySprite();
playPic.init(this.images.get("icon_laba" + index));
playPic.scaleX = scaleX;
playPic.scaleY = sacleY;
playPic.alpha = 0;
playPic.x = playPic.getBoundingBox().width / 2;
playPic.y = playPic.getBoundingBox().height / 2;
bg.addChild(playPic);
return playPic;
};
const playPic1 = getAudioPic(1);
if (show) {
playPic1.alpha = 1;
this.hideFlag = false;
}
else {
playPic1.alpha = 0;
this.hideFlag = true;
}
this.playPic1 = playPic1;
const playPic2 = getAudioPic(2);
this.playPic2 = playPic2;
const playPic3 = getAudioPic(3);
this.playPic3 = playPic3;
bg.setSize(playPic1.getBoundingBox().width, playPic1.getBoundingBox().height);
bg.alpha = 0;
this.bg = bg;
bg.x = this.x;
bg.y = this.y;
if (parent instanceof Array) {
parent.push(bg);
}
else {
parent.addChild(bg);
}
}
/**
* 显示播放状态
*/
showPlayStauts() {
this.hideFlag = false;
const setPause = () => {
if(this.hideFlag){
this.playPic1.alpha = 0;
}
else{
this.playPic1.alpha = 1;
}
this.playPic2.alpha = 0;
this.playPic3.alpha = 0;
}
const show1 = () => {
if (this.playing) {
this.playPic1.alpha = 0;
this.playPic2.alpha = 1;
this.playPic3.alpha = 0;
setTimeout(() => {
show2();
}, 500);
}
else {
setPause();
}
};
const show2 = () => {
if (this.playing) {
this.playPic1.alpha = 0;
this.playPic2.alpha = 0;
this.playPic3.alpha = 1;
setTimeout(() => {
show3();
}, 500);
}
else {
setPause();
}
};
const show3 = () => {
if (this.playing) {
this.playPic1.alpha = 1;
this.playPic2.alpha = 0;
this.playPic3.alpha = 0;
setTimeout(() => {
show1();
}, 500);
}
else {
setPause();
}
};
show1();
}
/**
*
* @param audio 播放音频
* @param callback
*/
playAudio(audio, callback = null) {
//console.log(audio);
if (!audio) {
return;
}
this.curAudio = audio;
audio.onended = () => {
this.playing = false;
if (callback) {
callback();
}
};
audio.play();
this.playing = true;
this.showPlayStauts();
}
/**
*
* @param reset 是否重置
* @param callback 暂停后执行方法
*/
pauseAudio(reset = false, callback = null) {
const audio = this.curAudio;
if (audio) {
this.playing = false;
if (reset) {
audio.currentTime = 0;
}
audio.pause();
if (callback) {
callback();
}
}
}
/**
* 隐藏音频播放动画
* @param reset 是否重置
*/
hide(reset = false) {
this.hideFlag = true;
this.pauseAudio(reset);
this.playPic1.alpha = 0;
this.playPic2.alpha = 0;
this.playPic3.alpha = 0;
}
/**
* 显示播放动画
*/
show(){
this.hideFlag = false;
this.playPic1.alpha = 1;
this.playPic2.alpha = 0;
this.playPic3.alpha = 0;
}
}
\ No newline at end of file
/**
*
* @param audio 音频
* @param now true-重新开始播放,flase-继续播放
* @param callback
*/
export function playAudio(audio, now = false, callback = null) {
if (audio) {
if (now) {
audio.pause();
audio.currentTime = 0;
}
if (callback) {
audio.onended = () => {
callback();
};
}
audio.play();
}
}
/**
* 暂停播放音频
* @param audio 音频
* @param reset 暂停是否重置:true-是,false-否
* @param callback
*/
export function pauseAudio(audio, reset = false, callback = null) {
if (audio) {
if (reset) {
audio.currentTime = 0;
}
audio.pause();
if (callback) {
callback();
}
}
}
\ No newline at end of file
import {
ShapeRect,
MySprite,
tweenChange,
shake
} from './Unit';
import {
pauseAudio,
playAudio
} from './AudioUtil'
export class Box {
name: string;
/**图片框 */
picBox: MySprite;
picBoard: ShapeRect;
/**文本框 */
wordBox: MySprite;
wordBoard: ShapeRect;
/**框发光图片 */
boxLightPic: MySprite;
/**背景 */
boxBg: ShapeRect;
curBox;
images = new Map();
scaleX = 1;
scaleY = 1;
answer;
inited = false;
wrongAudio;
rightAudio;
showed = false;
initX = 0;
initY = 0;
moveout = false;
constructor(name, images) {
this.images = images;
this.name = name;
}
setScaleXY(scale) {
this.scaleX = this.scaleY = scale;
}
init() {
if (this.inited) {
return;
}
const picBox = new MySprite();
picBox.init(this.images.get('box_pic'));
picBox.scaleX = this.scaleX;
picBox.scaleY = this.scaleY;
picBox.alpha = 0;
this.picBox = picBox;
const wordBox = new MySprite();
wordBox.init(this.images.get('box_word'));
wordBox.scaleX = this.scaleX;
wordBox.scaleY = this.scaleY;
wordBox.alpha = 0;
this.wordBox = wordBox;
const boxLight = new MySprite();
boxLight.init(this.images.get('box_light'));
boxLight.scaleX = this.scaleX;
boxLight.scaleY = this.scaleY;
boxLight.alpha = 0;
this.boxLightPic = boxLight;
let width = picBox.getBoundingBox().width;
let height = picBox.getBoundingBox().height;
const bg = new ShapeRect();
bg.setSize(width, height);
bg.alpha = 0;
this.boxBg = bg;
const picBoard = new ShapeRect();
picBoard.setSize(width, height);
picBoard.alpha = 0;
picBoard.x = 0;
picBoard.y = 0;
this.picBoard = picBoard;
this.boxBg.addChild(picBoard);
picBox.x = width / 2;
picBox.y = height / 2;
bg.addChild(picBox);
wordBox.x = picBox.x;
wordBox.y = picBox.y;
bg.addChild(wordBox);
const wordBoard = new ShapeRect();
wordBoard.setSize(width, height);
wordBoard.alpha = 0;
wordBoard.x = 0;
wordBoard.y = 0;
this.wordBoard = wordBoard;
this.boxBg.addChild(wordBoard);
boxLight.x = picBox.x;
boxLight.y = picBox.y - 20 * this.scaleY;
bg.addChild(boxLight);
this.inited = true;
}
showBox(answer, callback = null) {
if (!answer) {
return;
}
if (!this.inited) {
this.init();
}
const show = () => {console.log('show answer......');
let lastAnswer = this.answer ? this.answer : null;
this.answer = answer;
this.boxLightPic.alpha = 0;
const showAnswer = () => {
let x = (this.boxBg.width - this.answer.getWidth()) / 2;
let y = 22 * this.scaleY;
let sX = x;
let sY = this.boxBg.height + this.answer.getHeight();
if (this.answer.contentType == 'T') {
this.wordBoard.addChild(this.answer.bg);
}
else {
this.picBoard.addChild(this.answer.bg);
}
this.answer.moveIn(sX, sY, x, y, () => {
if (callback) {
callback();
}
});
this.showed = true;
};
if (answer.contentType == 'T') {
if (!this.curBox) {
this.curBox = this.wordBox;
this.show(() => {
showAnswer();
});
}
else if (this.curBox == this.wordBox) {
lastAnswer.moveOut(lastAnswer.bg.x, lastAnswer.bg.y, () => {
this.wordBoard.removeChild(lastAnswer.bg);
showAnswer();
});
}
else {
this.hide(lastAnswer, () => {
this.curBox = this.wordBox;
this.wordBox.alpha = 1;
showAnswer();
})
}
}
else {
if (!this.curBox) {
this.curBox = this.picBox;
this.show(() => {
showAnswer();
});
}
else if (this.curBox == this.picBox) {
lastAnswer.moveOut(lastAnswer.bg.x, lastAnswer.bg.y, () => {
this.picBoard.removeChild(lastAnswer.bg);
});
showAnswer();
}
else {
this.hide(lastAnswer, () => {
this.curBox = this.picBox;
this.picBox.alpha = 1;
showAnswer();
})
}
}
};
if (this.moveout) {
this.moveIn(() => {
show();
});
}
else {
show();
}
}
hide(answer, callback = null) {
this.boxLightPic.alpha = 0;
if (this.curBox && this.showed) {
this.showed = false;
if (answer) {
answer.moveOut(answer.bg.x, answer.bg.y, () => {
if (answer.contentType == 'T') {
this.wordBoard.removeChild(answer.bg);
}
else {
this.picBoard.removeChild(answer.bg);
}
let tBox = this.curBox;
tBox.alpha = 0;
this.curBox = null;
if (callback) {
callback();
}
});
}
else {
let tBox = this.curBox;
tBox.alpha = 0;
this.curBox = null;
if (callback) {
callback();
}
}
}
else {
if (callback) {
callback();
}
}
}
show(callback = null) {
if (this.curBox) {
this.curBox.alpha = 1;
if (callback) {
callback();
}
}
else {
if (callback) {
callback();
}
}
}
click(callback = null,wrongCallback = null) {
if (!this.showed) {
return;
}
if (!this.answer) {
this.showWrong();
return false;
}
if (this.answer.right) {
this.answer.selected = true;
this.boxLightPic.alpha = 1;
playAudio(this.rightAudio, true, () => {
});
if (callback) {
callback();
}
return true;
}
else {
this.showWrong();
if(wrongCallback){
wrongCallback();
}
return false;
}
}
private showWrong() {
this.boxLightPic.alpha = 1;
playAudio(this.wrongAudio, true, () => {
this.boxLightPic.alpha = 0;
});
shake(this.boxBg);
}
moveOut(callback = null) {
this.initX = this.boxBg.x;
this.initY = this.boxBg.y;
this.moveout = true;
tweenChange(this.boxBg, { y: this.boxBg.y + this.boxBg.height }, 0.3, () => {
if (this.answer) {
if (this.answer.contentType == 'T') {
this.wordBoard.removeChild(this.answer.bg);
}
else {
this.picBoard.removeChild(this.answer.bg);
}
}
if (callback) {
callback();
}
});
}
moveIn(callback = null) {
tweenChange(this.boxBg, { y: this.initY }, 0.3, callback);
}
}
\ No newline at end of file
import {
ShapeRect,
MySprite,
tweenChange
} from './Unit';
import{
playAudio
} from './AudioUtil';
export class Buttion {
bg;
up;
down;
scaleX = 1;
scaleY = 1;
images = new Map();
audio;
curStatus;
constructor(images) {
this.images = images;
}
setScaleXY(scale) {
this.scaleX = this.scaleY = scale;
}
init(upImgKey, downImgKey) {
const bg = new ShapeRect();
bg.alpha = 0;
this.bg = bg;
const up = new MySprite();
up.init(this.images.get(upImgKey));
up.scaleX = this.scaleX;
up.scaleY = this.scaleY;
up.x = up.getBoundingBox().width / 2;
up.y = up.getBoundingBox().height / 2;
this.up = up;
bg.addChild(up);
this.curStatus = up;
const down = new MySprite();
down.init(this.images.get(downImgKey));
down.scaleX = this.scaleX;
down.scaleY = this.scaleY;
down.alpha = 0;
down.x = up.x;
down.y = up.y;
this.down = down;
bg.addChild(down);
bg.setSize(up.getBoundingBox().width, up.getBoundingBox().height);
}
click(callback = null) {
playAudio(this.audio, true, callback);
this.up.alpha = 0;
this.down.alpha = 1;
this.curStatus = this.down;
setTimeout(() => {
this.resetStatus();
}, 100);
}
resetStatus(){
this.up.alpha = 1;
this.down.alpha = 0;
this.curStatus = this.up;
}
hide(time = 0.3, callback = null){
tweenChange(this.curStatus, { alpha: 0 }, time, ()=>{
if(callback){
callback();
}
});
}
}
\ No newline at end of file
import {
ShapeRect,
MySprite,
tweenChange,
Label
} from './Unit';
export class Exercise{
exercise;
_listeningAudio;
answers = [];
constructor(exercise){
this.exercise = exercise;
}
addAnswer(answer : Answer){
this.answers.push(answer);
}
set listeningAudio(audio){
this._listeningAudio = audio;
}
get listeningAudio(){
return this._listeningAudio;
}
}
export class Answer{
bg;
/**内容类型:T-文本,P-图片;默认为文本 */
contentType;
/**内容 */
contentSprite: MySprite;
answerContent;
scaleX = 1;
scaleY = 1;
images = new Map();
inited = false;
right = false;
selected = false;
constructor(images, answerContent){
this.images = images;
this.answerContent = answerContent;
}
setScaleXY(scale) {
this.scaleX = this.scaleY = scale;
}
init() {
if (this.inited) {
return;
}
this.right = this.answerContent.right;
const bg = new ShapeRect();
bg.setSize(this.getWidth(), this.getHeight());
bg.alpha = 0;
this.bg = bg;
this.setContent(bg);
}
/**
* 设置答案卡片内容
* @param parItem
*/
setContent(parItem) {
//图片存在,则渲染图片
if (this.answerContent.pic_url) {
const content_pic = new MySprite();
content_pic.init(this.images.get(this.answerContent.pic_url));
content_pic.alpha = 1;
let w = content_pic.width;
let h = content_pic.height;
let scale = Math.min((parItem.height - 15 * this.scaleX) / h, (parItem.width - 15 * this.scaleY) / w);
//如果小于1,则缩放图片
if(scale < 1){
content_pic.setScaleXY(scale);
}
content_pic.x = this.getWidth() / 2;
content_pic.y = this.getHeight() / 2;
parItem.addChild(content_pic);
this.contentType = 'P';
this.contentSprite = content_pic;
}
else {
let content_val = new Label();
content_val.text = this.answerContent.text;
content_val.textAlign = 'middle';
content_val.fontSize = 66;
content_val.fontName = "arial";
content_val.fontColor = "#FBEB4F";
content_val.setOutline(3, '#315305');
content_val.alpha = 0;
content_val.refreshSize();
content_val.setMaxSize(parItem.width - 60 * this.scaleX);
content_val.x = (this.getWidth() - content_val.getBoundingBox().width) / 2;
content_val.y = this.getHeight() / 2;
parItem.addChild(content_val);
this.contentType = 'T';
this.contentSprite = content_val;
}
}
getWidth(){
return 234 * this.scaleX;
}
getHeight(){
return 178 * this.scaleY;
}
/**
* 从指定位置移动到新位置
* @param sX 左上角x坐标
* @param sY 左上角Y坐标
* @param toX 左上角x坐标
* @param toY 左上角Y坐标
* @param callback
*/
moveIn(sX, sY, toX, toY, callback = null) {
if (this.contentType == 'T') {
this.bg.x = toX;
this.bg.y = toY;
tweenChange(this.contentSprite, { alpha: 1 }, 0.4, callback);
}
else if (this.contentType == 'P') {
this.contentSprite.alpha = 1;
this.bg.x = sX;
this.bg.y = sY;
let newToX = toX;
let newToY = toY;
tweenChange(this.bg, { x: newToX, y: newToY }, 0.2, callback);
}
}
/**
* 从当前位置移到指定位置
* @param toX 左上角x坐标
* @param toY 左上角Y坐标
* @param callback
*/
moveOut(toX, toY, callback = null) {
if (this.contentType == 'T') {
this.bg.x = toX;
this.bg.y = toY;
tweenChange(this.contentSprite, { alpha: 0 }, 0.3, callback);
}
else if (this.contentType == 'P') {
this.bg.x = toX;
this.bg.y = toY;
tweenChange(this.contentSprite, { alpha: 0 }, 0.3, callback);
}
}
reset(){
this.selected = false;
}
}
\ No newline at end of file
import {
MySprite, tweenChange,
ShapeRect
} from './Unit';
import {
pauseAudio,
playAudio
} from './AudioUtil'
export class Handclap {
bg: ShapeRect;
leftHand: MySprite;
rightHand: MySprite;
audio;
playing = false;
init(leftHandImgObj, rightHandImgObj, scaleX: number, sacleY: number) {
const leftHand = new MySprite();
leftHand.init(leftHandImgObj);
leftHand.scaleX = scaleX;
leftHand.scaleY = sacleY;
this.leftHand = leftHand;
const rightHand = new MySprite();
rightHand.init(rightHandImgObj);
rightHand.scaleX = scaleX;
rightHand.scaleY = sacleY;
this.rightHand = rightHand;
let height = Math.max(rightHand.getBoundingBox().height, leftHand.getBoundingBox().height);
let width = leftHand.getBoundingBox().width + rightHand.getBoundingBox().width;
const bg = new ShapeRect();
bg.setSize(width, height);
bg.alpha = 0;
this.bg = bg;
rightHand.x = leftHand.getBoundingBox().width + rightHand.getBoundingBox().width / 2;
rightHand.y = height/2;
bg.addChild(rightHand);
leftHand.x = leftHand.getBoundingBox().width/ 2;
leftHand.y = height/2;
bg.addChild(leftHand);
}
getWidth(){
return this.bg.getBoundingBox().width;
}
getHight(){
return this.bg.getBoundingBox().height;
}
play(callback = null){
//播放音效
playAudio(this.audio, false, ()=>{
this.playing = false;
if(callback){
callback();
}
});
const applaud = () => {
if(this.playing){
let scaleX = this.leftHand.scaleX;
let leftHandX = this.leftHand.x;
tweenChange(this.leftHand, {x: leftHandX + 60 * scaleX}, 0.1, () => {
tweenChange(this.leftHand, {x: leftHandX}, 0.1, ()=>{
setTimeout(() => {
applaud();
}, 50);
});
});
let rightHandX = this.rightHand.x;
tweenChange(this.rightHand, {x: rightHandX - 60 * scaleX}, 0.1, () => {
tweenChange(this.rightHand, {x: rightHandX}, 0.1, ()=>{
});
});
}
}
this.playing = true;
//鼓掌
applaud();
}
/**
* 停止鼓掌
* @param callback
*/
stop(callback = null){
this.playing = false;
pauseAudio(this.audio, true);
if(callback){
callback();
}
}
}
\ No newline at end of file
import {
MySprite,
moveItem,
removeItemFromArr,
rotateItem
} from './Unit';
export class Petal {
renderArr = [];
images;
ctx;
playing = true;
tempRenderArr = [];
constructor(renderArr, images, ctx) {
this.renderArr = renderArr;
this.images = images;
this.ctx = ctx;
this.tempRenderArr = [];
}
stop(callback = null) {
this.playing = false;
const checkFinish = () => {
if (this.tempRenderArr.length == 0) {
if (callback) {
callback();
}
}
else {
setTimeout(() => {
checkFinish();
}, 100);
}
}
checkFinish();
}
/**
* 显示结束花瓣
* @param rect {x,y,width, height} 花瓣显示位置及大小
* @param mapScale
* @param timeout 花瓣显示间隔
* @param kinds 花瓣种类,即花瓣图片样式数组个数
*/
showPetal(rect, mapScale: number, timeout: number, kinds = 9) {
if (!this.playing) {
return;
}
const petal = this.getPetal(rect, mapScale, kinds);
this.renderArr.push(petal);
this.tempRenderArr.push(petal);
let toY = rect.y + rect.height;
moveItem(petal, petal.x, toY + petal.height * petal.scaleY, petal['time'], () => {
removeItemFromArr(this.renderArr, petal);
removeItemFromArr(this.tempRenderArr, petal);
});
rotateItem(petal, petal['tr'], petal['time']);
setTimeout(() => {
this.showPetal(rect, mapScale, timeout);
}, timeout);
}
/**
* 得到花瓣
* @param rect
* @param mapScale
* @param kinds
*/
private getPetal(rect, mapScale, kinds) {
const petal = new MySprite(this.ctx);
const id = Math.ceil(Math.random() * kinds);
petal.init(this.images.get('petal_' + id));
const randomS = (Math.random() * 0.4 + 0.6) * mapScale;
petal.setScaleXY(randomS);
const randomR = Math.random() * 360;
petal.rotation = randomR;
const randomX = rect.x + Math.random() * rect.width;
petal.x = randomX;
petal.y = rect.y - petal.height / 2 * petal.scaleY;
const randomT = 0.5 + Math.random() * 2;
petal['time'] = randomT;
let randomTR = 360 * Math.random(); // - 180;
if (Math.random() < 0.5) { randomTR *= -1; }
petal['tr'] = randomTR;
return petal;
}
}
\ No newline at end of file
import {
MySprite, tweenChange,
ShapeRect,
Label
} from './Unit';
import {
playAudio
} from './AudioUtil';
export class Player {
/**背景 */
bg;
playerPic;
/**汗水 */
sweatPic;
//图片数组
images = new Map();
scaleX = 1;
scaleY = 1;
initX = 0;
initY = 0;
sweatAudio;
pullAudio;
car: ShapeRect;
cargos = [];
constructor(images) {
this.images = images;
}
setScaleXY(scale) {
this.scaleX = this.scaleY = scale;
}
init() {
const playerPic = new MySprite();
playerPic.init(this.images.get('player'));
playerPic.scaleX = this.scaleX;
playerPic.scaleY = this.scaleY;
playerPic.x = playerPic.getBoundingBox().width / 2;
playerPic.y = playerPic.getBoundingBox().height / 2;
this.playerPic = playerPic;
let width = playerPic.getBoundingBox().width;
let height = playerPic.getBoundingBox().height;
const bg = new ShapeRect();
bg.setSize(width, height);
bg.alpha = 0;
this.bg = bg;
const car = new ShapeRect();
car.setSize(160 * this.scaleX, 10 * this.scaleY);
car.x = 20 * this.scaleX;
car.y = 90 * this.scaleY;
car.alpha = 0;
this.car = car;
bg.addChild(car);
bg.addChild(playerPic);
const sweatPic = new MySprite();
sweatPic.init(this.images.get('sweat'));
sweatPic.scaleX = this.scaleX;
sweatPic.scaleY = this.scaleY;
sweatPic.x = 300 * this.scaleX + sweatPic.getBoundingBox().width / 2;
sweatPic.y = 20 * this.scaleY + sweatPic.getBoundingBox().height / 2;
sweatPic.alpha = 0;
this.sweatPic = sweatPic;
bg.addChild(sweatPic);
}
pullCar(toX: number, toY: number, callback = null, time = 0.3, ) {
playAudio(this.pullAudio, true);
tweenChange(this.bg, { x: toX, y: toY }, time, () => {
if (callback) {
callback();
}
})
}
reset() {
this.bg.x = this.initX;
this.bg.y = this.initY;
}
flowSweat(callback = null) {
playAudio(this.sweatAudio, true);
this.sweatPic.alpha = 1;
let y = this.sweatPic.y;
tweenChange(this.sweatPic, { y: y + 30 * this.scaleY }, 0.3, () => {
this.sweatPic.alpha = 0;
this.sweatPic.y = y;
if (callback) {
callback();
}
});
}
getCargoY = (x, b) => {
//斜率
let k = 0.195;
let c = - b * this.scaleY;
let y = k * x + c;
return -y;
}
loading(cargo) {
if (!cargo) {
return;
}
let x = 10 * this.scaleX;
let length = this.cargos.length;
if ( length > 0) {
if(length % 4 != 0){
let lastCargo = this.cargos[length - 1];
x = lastCargo.x;
x += lastCargo.getBoundingBox().width;
}
else{
x = 10 * this.scaleX + Math.floor(length / 4) * 5 * this.scaleX;
}
}
let startY = Math.floor(length / 4) * 15 * this.scaleY;
let c = Math.random() * this.car.height;
let y = this.getCargoY(x, c) - startY;
cargo.x = x - cargo.getBoundingBox().width / 2;
cargo.y = y - cargo.getBoundingBox().height / 2;
this.cargos.push(cargo);
this.car.addChild(cargo, -length);
}
unloading() {
this.car.removeChildren();
this.cargos = [];
}
}
\ No newline at end of file
import {
MySprite, tweenChange,
ShapeRect,
Label
} from './Unit';
export class Stage {
/**背景 */
bg;
/**舞台 */
stage: ShapeRect;
//图片数组
images = new Map();
scaleX = 1;
scaleY = 1;
prompt;
leftDoor;
rightDoor;
constructor(images){
this.images = images;
}
setScaleXY(scale){
this.scaleX = this.scaleY = scale;
}
init(){
const stage_box = new MySprite();
stage_box.init(this.images.get('stage_box'));
stage_box.scaleX = this.scaleX;
stage_box.scaleY = this.scaleY;
let width = stage_box.getBoundingBox().width;
let height = stage_box.getBoundingBox().height;
const bg = new ShapeRect();
bg.setSize(width, height);
bg.alpha = 0;
this.bg = bg;
const stage_bg = new MySprite();
stage_bg.init(this.images.get('stage_bg'));
stage_bg.scaleX = this.scaleX;
stage_bg.scaleY = this.scaleY;
stage_bg.x = width / 2;
stage_bg.y = 52 * this.scaleY + stage_bg.getBoundingBox().height / 2;
bg.addChild(stage_bg);
const stage = new ShapeRect();
stage.setSize(width, height);
stage.alpha = 0;
this.stage = stage;
stage.x = 0;
stage.y = 0;
bg.addChild(stage);
let prompt = new Label();
prompt.text = '0/0';
prompt.textAlign = 'middle';
prompt.fontSize = 66;
prompt.fontName = "BRLNSDB";
prompt.fontColor = "#F2CE29";
prompt.setOutline(3, '#93490B');
prompt.setShadow(0, 4, 3.0, '#A6643F');
prompt.scaleX = this.scaleX;
prompt.scaleY = this.scaleY;
prompt.refreshSize();
prompt.x = 120 * this.scaleX;
prompt.y = 116 * this.scaleY + prompt.getBoundingBox().height / 2;
this.prompt = prompt;
bg.addChild(prompt);
//初始化门
this.initDoor();
stage_box.x = width / 2;
stage_box.y = height /2;
bg.addChild(stage_box);
const left = new MySprite();
left.init(this.images.get('bg_1'));
left.scaleX = this.scaleX;
left.scaleY = this.scaleY;
left.x = - left.getBoundingBox().width / 2;
left.y = height - left.getBoundingBox().height/ 2;
bg.addChild(left);
const right = new MySprite();
right.init(this.images.get('bg_1'));
right.scaleX = this.scaleX;
right.scaleY = this.scaleY;
right.x = bg.width + left.getBoundingBox().width / 2;
right.y = left.y;
bg.addChild(right);
}
private initDoor(){
const leftDoor = new MySprite();
leftDoor.init(this.images.get('doorleft'), 0);
leftDoor.scaleX = this.scaleX;
leftDoor.scaleY = this.scaleY;
leftDoor.x = 75 * this.scaleX;
leftDoor.y = 51 * this.scaleY + leftDoor.getBoundingBox().height / 2;
this.bg.addChild(leftDoor);
this.leftDoor = leftDoor;
const rightDoor = new MySprite();
rightDoor.init(this.images.get('doorright'), 1);
rightDoor.scaleX = this.scaleX;
rightDoor.scaleY = this.scaleY;
rightDoor.x = leftDoor.x + leftDoor.getBoundingBox().width * 2;
rightDoor.y = leftDoor.y;
this.bg.addChild(rightDoor);
this.rightDoor = rightDoor;
leftDoor.scaleX = 0;
rightDoor.scaleX = 0;
}
setPromptText(text){
this.prompt.text = text;
}
closeDoor(callback = null){
tweenChange(this.leftDoor, {scaleX : this.scaleX}, 2, callback);
tweenChange(this.rightDoor, {scaleX : this.scaleX}, 2);
}
openDoor(callback = null){
tweenChange(this.leftDoor, {scaleX : 0}, 2, callback);
tweenChange(this.rightDoor, {scaleX : 0}, 2);
}
}
\ No newline at end of file
...@@ -17,3 +17,8 @@ ...@@ -17,3 +17,8 @@
src: url("../../assets/font/BRLNSDB.TTF") ; src: url("../../assets/font/BRLNSDB.TTF") ;
} }
@font-face
{
font-family: 'arial';
src: url("../../assets/font/arial.ttf") ;
}
\ No newline at end of file
This diff is collapsed.
const res = [ const res = [
// ['bg', "assets/play/bg.jpg"], ['bg_1', "assets/play/bg_1.png"],
['btn_left', "assets/play/btn_left.png"], ['stage_bg', "assets/play/stage_bg.png"],
['btn_right', "assets/play/btn_right.png"], ['stage_box', "assets/play/stage_box.png"],
// ['text_bg', "assets/play/text_bg.png"], ['icon_laba1', 'assets/play/icon_laba1.png'],
['icon_laba2', 'assets/play/icon_laba2.png'],
['icon_laba3', 'assets/play/icon_laba3.png'],
['icon_laba3', 'assets/play/icon_laba3.png'],
['icon_laba3', 'assets/play/icon_laba3.png'],
['btn_restart_down', 'assets/play/btn_restart_down.png'],
['btn_restart_up', 'assets/play/btn_restart_up.png'],
['box_light', 'assets/play/box_light.png'],
['box_pic', 'assets/play/box_pic.png'],
['box_word', 'assets/play/box_word.png'],
['doorleft', 'assets/play/doorleft.png'],
['doorright', 'assets/play/doorright.png'],
['left_hand', 'assets/play/left_hand.png'],
['right_hand', 'assets/play/right_hand.png'],
['lemon', 'assets/play/lemon.png'],
['player', 'assets/play/player.png'],
['sweat', 'assets/play/sweat.png'],
['petal_1', "assets/play/petal_1.png"],
['petal_2', "assets/play/petal_2.png"],
['petal_3', "assets/play/petal_3.png"],
['petal_4', "assets/play/petal_4.png"],
['petal_5', "assets/play/petal_5.png"],
['petal_6', "assets/play/petal_6.png"],
['petal_7', "assets/play/petal_7.png"],
['petal_8', "assets/play/petal_8.png"],
['petal_9', "assets/play/petal_9.png"],
['petal_10', "assets/play/petal_10.png"],
['petal_11', "assets/play/petal_11.png"],
['petal_12', "assets/play/petal_12.png"],
['petal_13', "assets/play/petal_13.png"],
['petal_14', "assets/play/petal_14.png"],
['petal_15', "assets/play/petal_15.png"]
]; ];
...@@ -12,7 +47,14 @@ const res = [ ...@@ -12,7 +47,14 @@ const res = [
const resAudio = [ const resAudio = [
['click', "assets/play/music/click.mp3"], ['click', "assets/play/music/click.mp3"],
['right', "assets/play/music/right.mp3"],
['wrong', "assets/play/music/wrong.mp3"],
['handclap', 'assets/play/music/handclap.mp3'],
['win', 'assets/play/music/win.mp3'],
['pull', "assets/play/music/pull.mp3"],
['lemon', 'assets/play/music/lemon.mp3'],
['sweat', 'assets/play/music/sweat.mp3'],
['clickBtn', 'assets/play/music/clickBtn.mp3']
]; ];
export {res, resAudio}; export {res, resAudio};
This diff is collapsed.
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