Skip to content
This repository has been archived by the owner on Sep 8, 2024. It is now read-only.

Commit

Permalink
Blood canvas with alpha now works
Browse files Browse the repository at this point in the history
  • Loading branch information
darthdeus committed Jan 27, 2024
1 parent f170b9c commit 092d434
Show file tree
Hide file tree
Showing 7 changed files with 158 additions and 13 deletions.
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# EXAMPLE=animated_text
# EXAMPLE=animated_sprites
# EXAMPLE=alpha_sprite
# EXAMPLE=blood_canvas
EXAMPLE=blood_canvas
# EXAMPLE=bloom
# EXAMPLE=custom_config
# EXAMPLE=cooldowns
Expand All @@ -16,7 +16,7 @@
# EXAMPLE=exr-hdr-image
# EXAMPLE=full_game_loop
# EXAMPLE=framerate_vsync
EXAMPLE=fragment-shader
# EXAMPLE=fragment-shader
# EXAMPLE=music
# EXAMPLE=ldtk
# EXAMPLE=lighting
Expand Down Expand Up @@ -46,8 +46,8 @@ EXAMPLE=fragment-shader
# default: egui-demo
# default: lint
# default: test
default: benchmarks
# default: example
# default: benchmarks
default: example

# FLAGS=--features=blobs,git-version,dev,ldtk,exr
FLAGS=--features=git-version,dev,tracy
Expand Down
48 changes: 43 additions & 5 deletions comfy-core/src/blood_canvas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ impl BloodCanvas {
Self { creator, blocks: HashMap::default() }
}

pub fn get_pixel(&mut self, position: Vec2) -> Color {
let position = position * PIXELS_PER_WORLD_UNIT as f32;
self.get_pixel_internal(position.x as i32, position.y as i32)
}

pub fn set_pixel(&mut self, position: Vec2, color: Color) {
let position = position * PIXELS_PER_WORLD_UNIT as f32;

Expand Down Expand Up @@ -78,6 +83,21 @@ impl BloodCanvas {
}
}

fn get_pixel_internal(&mut self, x: i32, y: i32) -> Color {
let bx = (x as f32 / BLOCK_SIZE as f32).floor() as i32;
let by = (y as f32 / BLOCK_SIZE as f32).floor() as i32;

let block = self.get_block(bx, by);

block.modified = true;
let px = block.image.get_pixel(
(x - bx * BLOCK_SIZE) as u32,
(y - by * BLOCK_SIZE) as u32,
);

Into::<Color>::into(*px)
}

fn set_pixel_internal(&mut self, x: i32, y: i32, color: Color) {
let bx = (x as f32 / BLOCK_SIZE as f32).floor() as i32;
let by = (y as f32 / BLOCK_SIZE as f32).floor() as i32;
Expand Down Expand Up @@ -150,6 +170,8 @@ impl BloodCanvas {
position: Vec2,
source_rect: Option<IRect>,
tint: Color,
flip_x: bool,
flip_y: bool,
) {
let assets = ASSETS.borrow_mut();
let image_map = assets.texture_image_map.lock();
Expand All @@ -173,11 +195,27 @@ impl BloodCanvas {
);

if px.0[3] > 0 {
self.set_pixel(
position + vec2(x as f32, y as f32) / 16.0 -
size_offset / 16.0,
Into::<Color>::into(*px) * tint,
);
let px_pos = position + vec2(x as f32, y as f32) / 16.0 -
size_offset / 16.0;

if tint.a < 1.0 {
let existing = self.get_pixel(px_pos);

let tinted =
Into::<Color>::into(*px) * tint.alpha(1.0);

self.set_pixel(
px_pos,
existing.lerp(tinted, tint.a),
);
} else {
self.set_pixel(
px_pos,
Into::<Color>::into(*px) * tint,
);
}

// self.set_pixel(px_pos, Into::<Color>::into(*px) * tint);
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions comfy-wgpu/src/blood_canvas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ pub fn blood_canvas_blit_at(
position,
source_rect,
tint,
false,
false,
);
}

Expand Down
89 changes: 88 additions & 1 deletion comfy/examples/blood_canvas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,49 @@ use comfy::*;
// _do not be afraid to call these functions_. In both BITGUN and BITGUN Survivors
// we have "meat particles" which are simple objects that write a blood trail as they fly
// on every frame, and it works just fine.
simple_game!("Blood Canvas", update);
simple_game!("Blood Canvas", setup, update);

fn random_blood() -> Color {
static BLOOD_COLOR: Color = Color { r: 0.454, g: 0.113, b: 0.19, a: 1.0 }; // "#411d31"
BLOOD_COLOR.darken(random() * 0.2)
}

struct Player;

fn setup(c: &mut EngineContext) {
// Load the player texture
c.load_texture_from_bytes(
"player",
include_bytes!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/../assets/chicken.png"
)),
);

// Spawn the player entity and make sure z-index is above the grass
commands().spawn((
Transform::position(vec2(25.0, 25.0)),
Player,
AnimatedSpriteBuilder::new()
.z_index(10)
.add_animation("idle", 0.1, true, AnimationSource::Atlas {
name: "player".into(),
offset: ivec2(0, 0),
step: ivec2(16, 0),
size: isplat(16),
frames: 1,
})
.add_animation("walk", 0.05, true, AnimationSource::Atlas {
name: "player".into(),
offset: ivec2(16, 0),
step: ivec2(16, 0),
size: isplat(16),
frames: 6,
})
.build(),
));
}

fn update(_c: &mut EngineContext) {
draw_text(
"Click anywhere for blooooooooood!",
Expand All @@ -43,4 +79,55 @@ fn update(_c: &mut EngineContext) {
if is_mouse_button_pressed(MouseButton::Left) {
blood_circle_at(mouse_world(), 4, 0.6, random_blood);
}

if is_mouse_button_pressed(MouseButton::Right) {
blood_canvas_blit_at(
texture_id("error"),
mouse_world(),
None,
RED.alpha(0.5),
);
}

clear_background(TEAL);

let dt = delta();

for (_, (_, animated_sprite, transform)) in
world().query::<(&Player, &mut AnimatedSprite, &mut Transform)>().iter()
{
// Handle movement and animation
let mut moved = false;
let speed = 3.0;
let mut move_dir = Vec2::ZERO;

if is_key_down(KeyCode::W) {
move_dir.y += 1.0;
moved = true;
}
if is_key_down(KeyCode::S) {
move_dir.y -= 1.0;
moved = true;
}
if is_key_down(KeyCode::A) {
move_dir.x -= 1.0;
moved = true;
}
if is_key_down(KeyCode::D) {
move_dir.x += 1.0;
moved = true;
}

if moved {
animated_sprite.flip_x = move_dir.x < 0.0;
transform.position += move_dir.normalize_or_zero() * speed * dt;
animated_sprite.play("walk");
} else {
animated_sprite.play("idle");
}

if is_key_pressed(KeyCode::Space) {}

main_camera_mut().center = transform.position;
}
}
4 changes: 3 additions & 1 deletion comfy/src/animated_sprite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,10 @@ impl AnimatedSprite {
pub fn with_blend_mode(self, blend_mode: BlendMode) -> Self {
Self { blend_mode, ..self }
}
}

pub fn to_quad_draw(&self, transform: &Transform) -> QuadDraw {
impl ToQuadDraw for AnimatedSprite {
fn to_quad_draw(&self, transform: &Transform) -> QuadDraw {
let (texture, source_rect) = self.state.current_rect();

QuadDraw {
Expand Down
15 changes: 15 additions & 0 deletions comfy/src/draw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,21 @@ pub struct QuadDraw {
pub y_sort_offset: f32,
}

pub trait ToQuadDraw {
fn to_quad_draw(&self, transform: &Transform) -> QuadDraw;
}

pub fn blood_canvas_blit_quad_draw(quad: QuadDraw) {
BLOOD_CANVAS.get().unwrap().borrow_mut().blit_at(
quad.texture,
quad.transform.position,
quad.source_rect,
quad.color,
quad.flip_x,
quad.flip_y,
);
}

// // TODO: move this into quad
// pub fn draw_collider_p(
// box_texture: TextureHandle,
Expand Down
5 changes: 3 additions & 2 deletions comfy/src/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,10 @@ impl Sprite {
pub fn set_rect(self, source_rect: Option<IRect>) -> Self {
Self { source_rect, ..self }
}
}

pub fn to_quad_draw(&self, transform: &Transform) -> QuadDraw {
impl ToQuadDraw for Sprite {
fn to_quad_draw(&self, transform: &Transform) -> QuadDraw {
QuadDraw {
texture: texture_id(&self.name),
transform: *transform,
Expand All @@ -81,7 +83,6 @@ impl Sprite {
}
}


pub fn fhd_ratio() -> f32 {
1920.0 / 1080.0
}
Expand Down

0 comments on commit 092d434

Please sign in to comment.