Skip to content

Commit

Permalink
Adde blend mode
Browse files Browse the repository at this point in the history
  • Loading branch information
mflerackers committed Feb 1, 2025
1 parent c90c348 commit a18a138
Show file tree
Hide file tree
Showing 16 changed files with 255 additions and 45 deletions.
79 changes: 79 additions & 0 deletions examples/blend.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// @ts-check

// Adding game objects to screen

// Start a KAPLAY game
kaplay();

// Load a sprite asset from "sprites/bean.png", with the name "bean"
loadSprite("bean", "/sprites/bean.png");
loadSprite("ghosty", "/sprites/ghosty.png");

onDraw(() => {
drawSprite({
sprite: "bean",
pos: vec2(100, 200),
blend: BlendMode.Normal,
});
drawSprite({
sprite: "bean",
pos: vec2(150, 200),
blend: BlendMode.Add,
});
drawSprite({
sprite: "bean",
pos: vec2(200, 200),
blend: BlendMode.Multiply,
});
drawSprite({
sprite: "bean",
pos: vec2(250, 200),
blend: BlendMode.Screen,
});

drawCircle({
radius: 25,
pos: vec2(125, 300),
color: rgb(128, 128, 128),
blend: BlendMode.Normal,
});
drawCircle({
radius: 25,
pos: vec2(175, 300),
color: rgb(128, 128, 128),
blend: BlendMode.Add,
});
drawCircle({
radius: 25,
pos: vec2(225, 300),
color: rgb(128, 128, 128),
blend: BlendMode.Multiply,
});
drawCircle({
radius: 25,
pos: vec2(275, 300),
color: rgb(128, 128, 128),
blend: BlendMode.Screen,
});
});

add([
sprite("bean"),
pos(100, 400),
blend(BlendMode.Normal),
]);
add([
sprite("bean"),
pos(150, 400),
blend(BlendMode.Add),
]);
add([
sprite("bean"),
pos(200, 400),
blend(BlendMode.Multiply),
]);
add([
sprite("bean"),
pos(250, 400),
blend(BlendMode.Screen),
]);
4 changes: 2 additions & 2 deletions examples/frames.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ loadSpriteAtlas("/examples/sprites/dungeon.png", {
bouncy: {
frames: [8, 5, 0, 3, 2, 3, 0, 5],
speed: 10,
loop: true
}
loop: true,
},
},
},
});
Expand Down
28 changes: 28 additions & 0 deletions src/components/draw/blend.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { BlendMode, type Comp } from "../../types";

/**
* The {@link blend `blend()`} component.
*
* @group Component Types
*/
export interface BlendComp extends Comp {
blend: BlendMode;
}

export function blend(blend: BlendMode): BlendComp {
return {
id: "color",
blend: blend ?? BlendMode.Normal,
inspect() {
return `blend: ${
this.blend == BlendMode.Normal
? "normal"
: this.blend == BlendMode.Add
? "add"
: this.blend == BlendMode.Multiply
? "multiply"
: "screen"
}`;
},
};
}
1 change: 1 addition & 0 deletions src/components/draw/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from "./blend";
export * from "./circle";
export * from "./color";
export * from "./drawon";
Expand Down
25 changes: 16 additions & 9 deletions src/components/draw/sprite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,9 @@ export function sprite(
}
const frames = [];
if (anim.from === undefined || anim.to === undefined) {
throw new Error("Sprite anim 'from' and 'to' must be defined if 'frames' is not defined");
throw new Error(
"Sprite anim 'from' and 'to' must be defined if 'frames' is not defined",
);
}
const frameSeqLength = Math.abs(anim.to - anim.from) + 1;
for (let i = 0; i < frameSeqLength; i++) {
Expand All @@ -249,7 +251,7 @@ export function sprite(
}
}
return frames;
}
};

return {
id: "sprite",
Expand Down Expand Up @@ -411,21 +413,26 @@ export function sprite(
if (curAnim.pingpong && !anim.pingpong) {
curAnimDir = -1;
curAnim.frameIndex = frames.length - 2;
} else if (curAnim.loop) {
}
else if (curAnim.loop) {
curAnim.frameIndex = 0;
} else {
}
else {
this.frame = frames.at(-1)!;
curAnim.onEnd();
this.stop();
return;
}
} else if (curAnim.frameIndex < 0) {
}
else if (curAnim.frameIndex < 0) {
if (curAnim.pingpong && curAnim.loop) {
curAnimDir = 1;
curAnim.frameIndex = 1;
} else if (curAnim.loop) {
}
else if (curAnim.loop) {
curAnim.frameIndex = frames.length - 1;
} else {
}
else {
this.frame = frames[0];
curAnim.onEnd();
this.stop();
Expand Down Expand Up @@ -465,7 +472,7 @@ export function sprite(
pingpong: false,
speed: 0,
frameIndex: 0,
onEnd: () => { },
onEnd: () => {},
}
: {
name: name,
Expand All @@ -474,7 +481,7 @@ export function sprite(
pingpong: opt.pingpong ?? anim.pingpong ?? false,
speed: opt.speed ?? anim.speed ?? 10,
frameIndex: 0,
onEnd: opt.onEnd ?? (() => { }),
onEnd: opt.onEnd ?? (() => {}),
};

curAnimDir = typeof anim === "number" ? null : 1;
Expand Down
22 changes: 11 additions & 11 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// some default charsets for loading bitmap fonts
export const ASCII_CHARS =
" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
export const DEF_ANCHOR = "topleft";
export const BG_GRID_SIZE = 64;
export const DEF_FONT = "monospace";
Expand All @@ -19,9 +19,9 @@ export const DEF_FONT_FILTER = "linear";
export const LOG_MAX = 8;
export const LOG_TIME = 4;
export const VERTEX_FORMAT = [
{ name: "a_pos", size: 2 },
{ name: "a_uv", size: 2 },
{ name: "a_color", size: 4 },
{ name: "a_pos", size: 2 },
{ name: "a_uv", size: 2 },
{ name: "a_color", size: 4 },
];
const STRIDE = VERTEX_FORMAT.reduce((sum, f) => sum + f.size, 0);
const MAX_BATCHED_QUAD = 2048;
Expand Down Expand Up @@ -92,13 +92,13 @@ vec4 frag(vec2 pos, vec2 uv, vec4 color, sampler2D tex) {
`;
export const COMP_DESC = new Set(["id", "require"]);
export const COMP_EVENTS = new Set([
"add",
"fixedUpdate",
"update",
"draw",
"destroy",
"inspect",
"drawInspect",
"add",
"fixedUpdate",
"update",
"draw",
"destroy",
"inspect",
"drawInspect",
]);
export const DEF_OFFSCREEN_DIS = 200;
// maximum y velocity with body()
Expand Down
1 change: 1 addition & 0 deletions src/game/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ export function getRenderProps(obj: GameObj<any>) {
outline: obj.outline,
shader: obj.shader,
uniform: obj.uniform,
blend: obj.blend,
};
}
3 changes: 2 additions & 1 deletion src/gfx/draw/drawPolygon.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { _k } from "../../kaplay";
import { Color } from "../../math/color";
import { triangulate, Vec2 } from "../../math/math";
import type { DrawPolygonOpt } from "../../types";
import { BlendMode, type DrawPolygonOpt } from "../../types";
import {
popTransform,
pushRotate,
Expand Down Expand Up @@ -103,6 +103,7 @@ export function drawPolygon(opt: DrawPolygonOpt) {
opt.uv ? opt.tex : _k.gfx.defTex,
opt.shader,
opt.uniform ?? undefined,
opt.blend ?? BlendMode.Normal,
);
}

Expand Down
8 changes: 5 additions & 3 deletions src/gfx/draw/drawRaw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Asset, resolveShader, type Uniform } from "../../assets";
import { _k } from "../../kaplay";
import { Vec2, vec2 } from "../../math/math";
import { screen2ndc } from "../../math/various";
import type { Attributes, RenderProps } from "../../types";
import { type Attributes, BlendMode, type RenderProps } from "../../types";
import type { Texture } from "../gfx";
import { height, width } from "../stack";

Expand All @@ -15,6 +15,7 @@ export function drawRaw(
tex?: Texture,
shaderSrc?: RenderProps["shader"],
uniform?: Uniform,
blend?: BlendMode,
) {
const parsedTex = tex ?? _k.gfx.defTex;
const parsedShader = shaderSrc ?? _k.gfx.defShader;
Expand All @@ -35,7 +36,7 @@ export function drawRaw(
for (let i = 0; i < vertLength; i++) {
scratchPt.x = attributes.pos[i * 2];
scratchPt.y = attributes.pos[i * 2 + 1];
transform.transformPoint(scratchPt, scratchPt)
transform.transformPoint(scratchPt, scratchPt);

vv[index++] = scratchPt.x;
vv[index++] = scratchPt.y;
Expand All @@ -54,7 +55,8 @@ export function drawRaw(
shader,
parsedTex,
uniform,
blend ?? BlendMode.Normal,
width(),
height()
height(),
);
}
3 changes: 2 additions & 1 deletion src/gfx/draw/drawTexture.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { DEF_ANCHOR } from "../../constants";
import { Color } from "../../math/color";
import { Quad, Vec2 } from "../../math/math";
import type { DrawTextureOpt, Vertex } from "../../types";
import { BlendMode, type DrawTextureOpt, type Vertex } from "../../types";
import { anchorPt } from "../anchor";
import { drawRaw } from "./drawRaw";
import { drawUVQuad } from "./drawUVQuad";
Expand Down Expand Up @@ -144,6 +144,7 @@ export function drawTexture(opt: DrawTextureOpt) {
opt.tex,
opt.shader,
opt.uniform ?? undefined,
opt.blend ?? BlendMode.Normal,
);
}
else {
Expand Down
3 changes: 2 additions & 1 deletion src/gfx/draw/drawUVQuad.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { DEF_ANCHOR, UV_PAD } from "../../constants";
import { Color, rgb } from "../../math/color";
import { Quad, Vec2 } from "../../math/math";
import type { DrawUVQuadOpt } from "../../types";
import { BlendMode, type DrawUVQuadOpt } from "../../types";
import { anchorPt } from "../anchor";
import {
popTransform,
Expand Down Expand Up @@ -95,6 +95,7 @@ export function drawUVQuad(opt: DrawUVQuadOpt) {
opt.tex,
opt.shader,
opt.uniform ?? undefined,
opt.blend ?? BlendMode.Normal,
);

popTransform();
Expand Down
Loading

0 comments on commit a18a138

Please sign in to comment.