Skip to content

Add a scale mode for modern pixel-art games #7494

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions Core/GDCore/Project/Project.h
Original file line number Diff line number Diff line change
Expand Up @@ -374,12 +374,14 @@ class GD_CORE_API Project {
void SetVerticalSyncActivatedByDefault(bool enable) { verticalSync = enable; }

/**
* Return the scale mode used by the game (usually "linear" or "nearest").
* Return the scale mode used by the game (usually "linear", "magnified" or
* "nearest").
*/
const gd::String& GetScaleMode() const { return scaleMode; }

/**
* Set the scale mode used by the game (usually "linear" or "nearest").
* Set the scale mode used by the game (usually "linear", "magnified" or
* "nearest").
*/
void SetScaleMode(const gd::String& scaleMode_) { scaleMode = scaleMode_; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,8 @@ namespace gdjs {
const isOutsideCanvas =
canvasRight < 0 ||
canvasBottom < 0 ||
canvasLeft > runtimeGame.getGameResolutionWidth() ||
canvasTop > runtimeGame.getGameResolutionHeight();
canvasLeft > runtimeGame.getRenderingResolutionWidth() ||
canvasTop > runtimeGame.getRenderingResolutionHeight();
if (isOutsideCanvas) {
this._form.style.display = 'none';
return;
Expand Down
43 changes: 29 additions & 14 deletions Extensions/TextObject/textruntimeobject-pixi-renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ namespace gdjs {
_fontManager: any;
_text: PIXI.Text;
_justCreated: boolean = true;
_upscaleRatio: integer = 1;

constructor(
runtimeObject: gdjs.TextRuntimeObject,
Expand Down Expand Up @@ -47,7 +48,7 @@ namespace gdjs {
const style = this._text.style;
style.fontStyle = this._object._italic ? 'italic' : 'normal';
style.fontWeight = this._object._bold ? 'bold' : 'normal';
style.fontSize = this._object._characterSize;
style.fontSize = this._object._characterSize * this._upscaleRatio;
style.fontFamily = fontName;
if (this._object._useGradient) {
style.fill = this._getGradientHex();
Expand All @@ -62,15 +63,15 @@ namespace gdjs {
// @ts-ignore
style.align = this._object._textAlign;
style.wordWrap = this._object._wrapping;
style.wordWrapWidth = this._object._wrappingWidth;
style.wordWrapWidth = this._object._wrappingWidth * this._upscaleRatio;
style.breakWords = true;
style.stroke = gdjs.rgbToHexNumber(
this._object._outlineColor[0],
this._object._outlineColor[1],
this._object._outlineColor[2]
);
style.strokeThickness = this._object._isOutlineEnabled
? this._object._outlineThickness
? this._object._outlineThickness * this._upscaleRatio
: 0;
style.dropShadow = this._object._shadow;
style.dropShadowColor = gdjs.rgbToHexNumber(
Expand All @@ -79,13 +80,16 @@ namespace gdjs {
this._object._shadowColor[2]
);
style.dropShadowAlpha = this._object._shadowOpacity / 255;
style.dropShadowBlur = this._object._shadowBlur;
style.dropShadowBlur = this._object._shadowBlur * this._upscaleRatio;
style.dropShadowAngle = gdjs.toRad(this._object._shadowAngle);
style.dropShadowDistance = this._object._shadowDistance;
style.dropShadowDistance =
this._object._shadowDistance * this._upscaleRatio;
const extraPaddingForShadow = style.dropShadow
? style.dropShadowDistance + style.dropShadowBlur
? this._object._shadowDistance + this._object._shadowBlur
: 0;
style.padding = Math.ceil(this._object._padding + extraPaddingForShadow);
style.padding =
Math.ceil(this._object._padding + extraPaddingForShadow) *
this._upscaleRatio;

// Prevent spikey outlines by adding a miter limit
style.miterLimit = 3;
Expand Down Expand Up @@ -117,7 +121,6 @@ namespace gdjs {
this._text.position.x = this._object.x + this._text.width / 2;
this._text.anchor.x = 0.5;
}
this._text.position.y = this._object.y + this._text.height / 2;

const alignmentY =
this._object._verticalTextAlignment === 'bottom'
Expand Down Expand Up @@ -181,43 +184,55 @@ namespace gdjs {
return gradient;
}

/**
* Set the text object upscale ratio.
* @param upscaleRatio The new upscale ratio for the text object.
* @see gdjs.RuntimeGame.getZoomFactor
*/
setUpscaleRatio(upscaleRatio: integer): void {
this._upscaleRatio = upscaleRatio;
this._text.scale.x = this._object.getScaleX() / this._upscaleRatio;
this._text.scale.y = this._object.getScaleY() / this._upscaleRatio;
this.updateStyle();
}

/**
* Get x-scale of the text.
*/
getScaleX(): float {
return this._text.scale.x;
return this._object.getScaleX();
}

/**
* Get y-scale of the text.
*/
getScaleY(): float {
return this._text.scale.y;
return this._object.getScaleY();
}

/**
* Set the text object scale.
* @param newScale The new scale for the text object.
*/
setScale(newScale: float): void {
this._text.scale.x = newScale;
this._text.scale.y = newScale;
this._text.scale.x = newScale / this._upscaleRatio;
this._text.scale.y = newScale / this._upscaleRatio;
}

/**
* Set the text object x-scale.
* @param newScale The new x-scale for the text object.
*/
setScaleX(newScale: float): void {
this._text.scale.x = newScale;
this._text.scale.x = newScale / this._upscaleRatio;
}

/**
* Set the text object y-scale.
* @param newScale The new y-scale for the text object.
*/
setScaleY(newScale: float): void {
this._text.scale.y = newScale;
this._text.scale.y = newScale / this._upscaleRatio;
}

destroy() {
Expand Down
42 changes: 19 additions & 23 deletions Extensions/TextObject/textruntimeobject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ namespace gdjs {
this.onCreated();
}

updateFromObjectData(
override updateFromObjectData(
oldObjectData: TextObjectData,
newObjectData: TextObjectData
): boolean {
Expand Down Expand Up @@ -214,7 +214,7 @@ namespace gdjs {
return true;
}

getNetworkSyncData(): TextObjectNetworkSyncData {
override getNetworkSyncData(): TextObjectNetworkSyncData {
return {
...super.getNetworkSyncData(),
str: this._str,
Expand Down Expand Up @@ -242,7 +242,7 @@ namespace gdjs {
};
}

updateFromNetworkSyncData(
override updateFromNetworkSyncData(
networkSyncData: TextObjectNetworkSyncData
): void {
super.updateFromNetworkSyncData(networkSyncData);
Expand Down Expand Up @@ -317,15 +317,15 @@ namespace gdjs {
}
}

getRendererObject() {
override getRendererObject() {
return this._renderer.getRendererObject();
}

update(instanceContainer: gdjs.RuntimeInstanceContainer): void {
override update(instanceContainer: gdjs.RuntimeInstanceContainer): void {
this._renderer.ensureUpToDate();
}

onDestroyed(): void {
override onDestroyed(): void {
super.onDestroyed();
this._renderer.destroy();
}
Expand All @@ -345,6 +345,12 @@ namespace gdjs {
}
}

override onGameZoomFactorChanged(): void {
this._renderer.setUpscaleRatio(
this.getRuntimeScene().getGame().getZoomFactor()
);
}

/**
* Update the rendered object position.
*/
Expand All @@ -353,27 +359,17 @@ namespace gdjs {
this._renderer.updatePosition();
}

/**
* Set object position on X axis.
*/
setX(x: float): void {
override setX(x: float): void {
super.setX(x);
this._updateTextPosition();
}

/**
* Set object position on Y axis.
*/
setY(y: float): void {
override setY(y: float): void {
super.setY(y);
this._updateTextPosition();
}

/**
* Set the angle of the object.
* @param angle The new angle of the object
*/
setAngle(angle: float): void {
override setAngle(angle: float): void {
super.setAngle(angle);
this._renderer.updateAngle();
}
Expand Down Expand Up @@ -499,14 +495,14 @@ namespace gdjs {
/**
* Get width of the text.
*/
getWidth(): float {
override getWidth(): float {
return this._wrapping ? this._wrappingWidth : this._renderer.getWidth();
}

/**
* Get height of the text.
*/
getHeight(): float {
override getHeight(): float {
return this._renderer.getHeight();
}

Expand Down Expand Up @@ -685,11 +681,11 @@ namespace gdjs {
}
}

setWidth(width: float): void {
override setWidth(width: float): void {
this.setWrappingWidth(width);
}

getDrawableY(): float {
override getDrawableY(): float {
return (
this.getY() -
(this._verticalTextAlignment === 'center'
Expand Down
4 changes: 4 additions & 0 deletions GDJS/Runtime/CustomRuntimeObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,10 @@ namespace gdjs {
*/
onDestroy(parent: gdjs.RuntimeInstanceContainer) {}

override onGameZoomFactorChanged() {
this._instanceContainer.onGameZoomFactorChanged();
}

override updatePreRender(parent: gdjs.RuntimeInstanceContainer): void {
this._instanceContainer._updateObjectsPreRender();
this.getRenderer().ensureUpToDate();
Expand Down
9 changes: 9 additions & 0 deletions GDJS/Runtime/RuntimeInstanceContainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,15 @@ namespace gdjs {
return this._allInstancesList;
}

/**
* Called when the game zoom factor is changed to adapt to a new resolution.
*/
onGameZoomFactorChanged(): void {
for (const instance of this.getAdhocListOfAllInstances()) {
instance.onGameZoomFactorChanged();
}
}

/**
* Update the objects before launching the events.
*/
Expand Down
Loading