Skip to content

Commit

Permalink
Merge pull request #708 from WWAWing/feat/picture-feature-add-wait-pr…
Browse files Browse the repository at this point in the history
…operty

Feat: 【ピクチャ機能】wait プロパティと waitFrame プロパティを実装
  • Loading branch information
aokashi committed Apr 20, 2024
2 parents 1abf153 + 6dde74c commit 075631e
Show file tree
Hide file tree
Showing 11 changed files with 312 additions and 70 deletions.
Binary file modified packages/assets/mapdata/picture_test.dat
Binary file not shown.
13 changes: 10 additions & 3 deletions packages/common-interface/src/wwa_picture.ts
@@ -1,10 +1,14 @@
export interface PictureProperties<N = number> {
pos?: [N, N];
time?: N,
timeFrame?: N;
time?: N | [N] | [N, N];
timeFrame?: N | [N] | [N, N];
// スネークケースになっているだけで、内容は上記と同じ
time_frame?: N;
time_frame?: N | [N] | [N, N];
size?: [N, N];
animTime?: [N, N];
anim_time?: [N, N];
animTimeFrame?: [N, N];
anim_time_frame?: [N, N];
move?: [N, N];
accel?: [N, N];
zoom?: [N, N];
Expand Down Expand Up @@ -37,6 +41,9 @@ export interface PictureProperties<N = number> {
fade?: N;
angle?: N;
rotate?: N;
wait?: N;
waitFrame?: N;
wait_frame?: N;
next?: [N] | [N, N] | [N, N, N],
create?: ([N] | [N, N] | [N, N, N] | [N, N, N, N])[],
// TODO map プロパティの座標で PX と PY を指定するとピクチャ作成時の座標が評価されてしまい、移動後はプレイヤーの位置通りにパーツが配置されない。
Expand Down
17 changes: 7 additions & 10 deletions packages/engine/src/wwa_main.ts
Expand Up @@ -2404,7 +2404,6 @@ export class WWA {
}
this._keyStore.memorizeKeyStateOnControllableFrame();
this._mouseStore.memorizeMouseStateOnControllableFrame();
this.updatePicturesAnimation();
} else if (this._player.isJumped()) {
if (!this._camera.isResetting()) {
this._player.processAfterJump();
Expand All @@ -2415,7 +2414,6 @@ export class WWA {
if (this._player.getPosition().isJustPosition()) {
this._dispatchPlayerAndObjectsStopTimeRequests();
}
this.updatePicturesAnimation();
} else if (this._player.isWaitingMessage()) {

if (!this._messageWindow.isVisible()) {
Expand Down Expand Up @@ -2615,17 +2613,13 @@ export class WWA {
this._objectMovingDataManager.update();
}

this.updatePicturesAnimation();
this._cgManager.picture.updateFrameTimerValue();
this._prevFrameEventExected = false;
if (this._player.getPosition().isJustPosition() && this._camera.getPosition().isScreenTopPosition()) {

if (
!this._shouldTreatWillMessageDisplay(this._pages) && // パーツの接触判定でメッセージが発生しうる場合は、パーツのプレイヤー座標実行をしない
!this._player.isJumped() &&
!this._player.isWaitingMessage() &&
!this._player.isWaitingEstimateWindow() &&
!this._player.isWaitingMoveMacro() &&
!this._player.isFighting()) {
// パーツの接触判定でメッセージが発生しうる場合は、パーツのプレイヤー座標実行をしない
if (!this._shouldTreatWillMessageDisplay(this._pages) && !this._player.isPausing()) {

if (this._player.isPartsAppearedTime()) {
this._player.clearPartsAppearedFlag();
Expand Down Expand Up @@ -5700,7 +5694,7 @@ export class WWA {
}

public canInput(): boolean {
return !this._temporaryInputDisable;
return !this._temporaryInputDisable && !this._cgManager.picture.isWaiting();
}

/*public setWaitTime( time: number): void {
Expand Down Expand Up @@ -5737,6 +5731,9 @@ export class WWA {
* また、カウントダウンも行い、タイムオーバーした場合は消去も行います。
*/
public updatePicturesAnimation(): void {
if (this._player.isPausing()) {
return;
}
this._cgManager.updatePicturesAnimation(this._isMainAnimation());
}

Expand Down
11 changes: 11 additions & 0 deletions packages/engine/src/wwa_parts_player.ts
Expand Up @@ -1275,6 +1275,17 @@ export class Player extends PartsObject {
return this._speedIndex;
}

public isPausing() {
return (
this.isJumped() ||
this.isWaitingMessage() ||
this.isWaitingPasswordWindow() ||
this.isWaitingEstimateWindow() ||
this.isWaitingMoveMacro() ||
this.isFighting()
);
}

constructor(wwa: WWA, pos: Position, camera: Camera, status: Status, em: number, moves: number, gameSpeedIndex: number) {
super(pos);
// どっかで定数化させたい
Expand Down
86 changes: 49 additions & 37 deletions packages/engine/src/wwa_picture/WWAPicture.ts
Expand Up @@ -220,12 +220,15 @@ export default class WWAPicutre {

public updateAllPicturesCache(image: HTMLImageElement, isMainAnimation: boolean) {
this.forEachPictures((picture) => {
if (picture.isNotStarted()) {
return;
}
picture.draw(image, isMainAnimation);
})
}

/**
* decrementPictureDisplayTimeStock の後に実行するようにしてください。
* updatePicturesAnimation の後に実行するようにしてください。
* メッセージ表示中においても常時実行する必要があります。
*/
public updateFrameTimerValue() {
Expand All @@ -241,43 +244,43 @@ export default class WWAPicutre {
const newFrameValue = WWAPicutre._getNowFrameValue();
const frameMs = newFrameValue - this._frameTimerValue;
this.forEachPictures(picture => {
if (picture.hasDisplayTimeStock()) {
picture.decrementDisplayTimeStock(frameMs);
// TODO ネストが深くなってる、そろそろなんとかせねば
if (picture.isDeadlineOver()) {
const layerNumber = picture.layerNumber;
const nextPicturesInfo = picture.getNextPicturePartsInfo();
const mapPictureInfo = picture.appearParts;
const executeScriptFunctionName = picture.executeScriptFunctionName;
const pictureProperties = picture.getNextPictureProperties();
const triggerPartsCoord = picture.getTriggerPartsCoord();
// WWAMain から実行しないと削除した分がセーブデータに残る
this._wwa.deletePictureRegistry(layerNumber);
for (const nextPictureInfo of nextPicturesInfo) {
this._wwa.setPictureRegistry(
nextPictureInfo.layerNumber,
nextPictureInfo.partsNumber,
nextPictureInfo.partsType,
triggerPartsCoord,
nextPictureInfo.connectProperties ? pictureProperties : undefined,
);
}
if (mapPictureInfo !== undefined) {
// TODO ピクチャ機能の数値算出システムに依存しているため、
// 消去時点での座標を計算して配置することができない
// 例えば、消去時点でのプレイヤー位置に任意のパーツを配置とするようなことはできない
// WWA Script 対応後は任意の関数を呼び出す機能で実現できるようになるつもり
this._wwa.setPartsOnPosition(
mapPictureInfo.partsType,
mapPictureInfo.partsNumber,
new Coord(mapPictureInfo.x, mapPictureInfo.y)
);
}
if (executeScriptFunctionName) {
this._wwa.callUserScript(executeScriptFunctionName);
}
return;
picture.tickTime(frameMs);
if (picture.isNotStarted()) {
return;
}
if (picture.isDeadlineOver()) {
const layerNumber = picture.layerNumber;
const nextPicturesInfo = picture.getNextPicturePartsInfo();
const mapPictureInfo = picture.appearParts;
const executeScriptFunctionName = picture.executeScriptFunctionName;
const pictureProperties = picture.getNextPictureProperties();
const triggerPartsCoord = picture.getTriggerPartsCoord();
// WWAMain から実行しないと削除した分がセーブデータに残る
this._wwa.deletePictureRegistry(layerNumber);
for (const nextPictureInfo of nextPicturesInfo) {
this._wwa.setPictureRegistry(
nextPictureInfo.layerNumber,
nextPictureInfo.partsNumber,
nextPictureInfo.partsType,
triggerPartsCoord,
nextPictureInfo.connectProperties ? pictureProperties : undefined,
);
}
if (mapPictureInfo !== undefined) {
// TODO ピクチャ機能の数値算出システムに依存しているため、
// 消去時点での座標を計算して配置することができない
// 例えば、消去時点でのプレイヤー位置に任意のパーツを配置とするようなことはできない
// WWA Script 対応後は任意の関数を呼び出す機能で実現できるようになるつもり
this._wwa.setPartsOnPosition(
mapPictureInfo.partsType,
mapPictureInfo.partsNumber,
new Coord(mapPictureInfo.x, mapPictureInfo.y)
);
}
if (executeScriptFunctionName) {
this._wwa.callUserScript(executeScriptFunctionName);
}
return;
}
if (picture.hasAnimation) {
picture.updateAnimation();
Expand All @@ -286,6 +289,15 @@ export default class WWAPicutre {
});
}

public isWaiting() {
for (const picture of this._pictures.values()) {
if (picture.isWaiting()) {
return true;
}
}
return false;
}

public getPictureRegistryData(): PictureRegistry[] {
return Array.from(this._pictures.values()).map(picture => picture.getRegistryData());
}
Expand Down
57 changes: 41 additions & 16 deletions packages/engine/src/wwa_picture/WWAPictureItem.ts
Expand Up @@ -3,8 +3,16 @@ import { PartsType } from "@wwawing/loader";
import { CacheCanvas } from "../wwa_cgmanager";
import { Coord, WWAConsts } from "../wwa_data";
import * as util from "../wwa_util";
import { adjustPositiveValue, getHorizontalCirclePosition, getHorizontalCorrectionBySizeAnchor, getVerticalCirclePosition, getVerticalCorrectionBySizeAnchor } from "./utils";
import {
getArrayItemFromSingleOrArray,
adjustPositiveValue,
getHorizontalCirclePosition,
getHorizontalCorrectionBySizeAnchor,
getVerticalCirclePosition,
getVerticalCorrectionBySizeAnchor
} from "./utils";
import { NextPicturePartsInfo } from "./typedef";
import { WWATimer } from "./WWATimer";

/**
* 描画用ピクチャインスタンスです。
Expand Down Expand Up @@ -60,9 +68,8 @@ export default class WWAPictureItem {
private _opacity: number;
private readonly _fade: number;
private readonly _hasAnimation: boolean;

private readonly _timeType?: "milisecond" | "frame";
private _displayStockTime?: number;

private _timer: WWATimer;

constructor(private _registry: PictureRegistry, private _canvas: CacheCanvas, externalFile?: HTMLImageElement) {
const { properties } = _registry;
Expand Down Expand Up @@ -103,8 +110,20 @@ export default class WWAPictureItem {

this._updatePictureCache();

this._timeType = properties.time ? "milisecond" : properties.timeFrame ? "frame" : undefined;
this._displayStockTime = properties.time || properties.timeFrame;
this._timer = new WWATimer();
this._timer.addPoint(
"start",
getArrayItemFromSingleOrArray(properties.time, 1, false),
getArrayItemFromSingleOrArray(properties.timeFrame, 1, false)
);
this._timer.addPoint(
"end",
getArrayItemFromSingleOrArray(properties.time, 0, true),
getArrayItemFromSingleOrArray(properties.timeFrame, 0, true)
);
this._timer.addPoint("startAnim", properties.animTime?.[0], properties.animTimeFrame?.[0]);
this._timer.addPoint("endAnim", properties.animTime?.[1], properties.animTimeFrame?.[1]);
this._timer.addPoint("wait", properties.wait, properties.waitFrame);

// Canvas の ctx を色々いじる
this._canvas.ctx.globalAlpha = WWAPictureItem._roundPercentage(this._opacity) / 100;
Expand Down Expand Up @@ -203,6 +222,9 @@ export default class WWAPictureItem {
* アニメーションに応じてピクチャのプロパティを更新します。
*/
public updateAnimation() {
if (this._timer.isNotOver("startAnim", false) || this._timer.isOver("endAnim", false)) {
return;
}
this._posBaseX = this._posBaseX + this._moveX;
this._posBaseY = this._posBaseY + this._moveY;
this._moveX = this._moveX + this._accelX;
Expand Down Expand Up @@ -244,21 +266,24 @@ export default class WWAPictureItem {
);
}

public hasDisplayTimeStock() {
return this._timeType !== undefined && this._displayStockTime !== undefined && this._displayStockTime > 0;
public isNotStarted() {
return this._timer.isNotOver("start", false);
}

public decrementDisplayTimeStock(frameMs: number) {
switch (this._timeType) {
case "milisecond":
this._displayStockTime -= frameMs;
case "frame":
this._displayStockTime -= 1;
}
public tickTime(frameMs: number) {
this._timer.tick(frameMs);
}

public isDeadlineOver() {
return this._displayStockTime <= 0;
return this._timer.isOver("end", false);
}

public isStartTimeOver() {
return this._timer.isOver("start", true);
}

public isWaiting() {
return this._timer.isNotOver("wait", false);
}

public clearCanvas() {
Expand Down

0 comments on commit 075631e

Please sign in to comment.