5Y32O2B2GTH2UHFA3NO4ZY673XNHT3W4DQADFMK4LMKLSXMZKHGQC
println!("Hello, world!");
App::new()
.add_plugins((
DefaultPlugins.set(ImagePlugin::default_nearest()),
InputManagerPlugin::<PlayerAction>::default(),
// PixelCameraPlugin,
EguiPlugin,
))
.add_plugins(AcerolaGame0)
.run()
}
struct AcerolaGame0;
impl Plugin for AcerolaGame0 {
fn build(&self, app: &mut App) {
app.add_systems(Startup, spawn_player)
.add_systems(Update, check_actions);
}
}
#[derive(Actionlike, PartialEq, Eq, Hash, Clone, Copy, Debug, Reflect)]
enum PlayerAction {
Move,
LightAttack,
HeavyAttack,
// Dash variants, both should just enable dash, but one
// needs to be held, while the other toggles dash on and off
HoldDash,
ToggleDash,
// X axis - switching between cards
// +Y axis - above deadzone, use card
// -Y axis - above deadzone, held, exhaust hand
Hand,
}
#[derive(Component)]
struct Player;
#[derive(Bundle)]
struct PlayerBundle {
player: Player,
input_manager_bundle: InputManagerBundle<PlayerAction>,
}
fn default_input_map() -> InputMap<PlayerAction> {
let mut map = InputMap::default();
map.insert(PlayerAction::Move, DualAxis::left_stick());
map.insert(PlayerAction::Move, VirtualDPad::wasd());
map.insert(PlayerAction::LightAttack, KeyCode::KeyZ);
map.insert(PlayerAction::HeavyAttack, KeyCode::KeyX);
map.insert(PlayerAction::HoldDash, KeyCode::ShiftLeft);
map.insert(PlayerAction::ToggleDash, KeyCode::KeyC);
map.insert(PlayerAction::Hand, DualAxis::right_stick());
map.insert(PlayerAction::Hand, VirtualDPad::arrow_keys());
map
}
fn spawn_player(mut commands: Commands) {
commands.spawn(PlayerBundle {
player: Player,
input_manager_bundle: InputManagerBundle::with_map(default_input_map()),
});
fn check_actions(
query: Query<&ActionState<PlayerAction>, With<Player>>,
mut contexts: EguiContexts,
) {
egui::Window::new("Action State").show(contexts.ctx_mut(), |ui| {
let action_state = query.single();
if let Some(dad) = action_state.clamped_axis_pair(&PlayerAction::Move) {
ui.label(format!("X movement: {}", dad.x()));
ui.label(format!("Y movement: {}", dad.y()));
} else {
ui.label("!! Move action not (properly) bound !!");
}
if let Some(hand_dad) = action_state.clamped_axis_pair(&PlayerAction::Hand) {
_ = hand_dad;
ui.label("Hand action connected!");
} else {
ui.label("!! Hand action not (properly) bound !!");
}
});
}
run:
cargo run --features bevy/dynamic_linking
# Acerola Jam 0 Game - Bevy edition
I like Rust _way_ too much.
Anyways, Bevy.
## What's the game?
The idea is a card battler roguelike.
You are a character running around SOMEPLACE (using WASD or a joystick).
You have 3 actions other than movement:
- someway of toggling or activating a faster movement (running)
- light attack (Z)
- heavy attack (X)
The only way to do special moves is through your deck, which
Left and Right arrows switch the card in your hand, and Up uses the currently
selected card. Double-pressing down will _exhaust_ your hand, discarding
all the cards within it.
Stats:
- damage - how much damage does your light attack do?
heavy attack is 1.5x - 2x this, and all card damage scales off this
or is set.
- draw - the number of seconds it takes after you have exhausted your hand
to draw a new, full hand
- shuffle - the number of seconds it takes after your deck has been
exhausted to shuffle your discards and create a new deck
- size - the number of cards you can hold in your hand. If
this is _greater_ than the number of cards in your deck, your
draw and shuffle times are x0.75.
### Control Schemes
The "default" one is:
- Movement (WASD)
- Attacks (light, heavy) (Z, X)
- Dash (press) (shift)
- Hand Switch (Left, Right) (LeftArrow, RightArrow)
- Hand Use (Up)
- Hand Exhaust (Hold DownArrow)
An alternative scheme I'd want to also support is:
- Movement (left mouse button, using delta from center)
- Attacks (light, heavy) (A, S)
- Dash (press) (right mouse button, instead of left)
- Hand Switch (Left, Right) (Q, E)
- Hand Use (W)
- Hand Exhaust (Hold D)
### Card Ideas
Ideally, the card's display should only consist of a colored box
with some representative symbols on it. The only common symbols are:
- an arrow, this represents that the character must be moving
in some direction in order to use the card. marked by (M)
The available colors are:
- red - offensive, tends to move forward {R}
- blue - defensive, tends to lock in place {B}
- yellow - avoiding, tends to move backwards {Y}
These are meant to give you an idea at a glance what kind of
movement can be expected of your character when using the card.
The first card you get is:
- (M) {R} Dash - move forward 5 units, dealing 400% damage to anyone
in the way
A more complicated card might be:
- {B} Marryuk's Shield - Lock 3, (Dizzy) if hit 4 times. If you were
hit exactly 3 times when unlocking, deal 600% damage to all within
9 units.
### Stealing Cards
A central mechanic is stealing cards. (This is my impl of the theme in
gameplay, as you are the only one in game that is capable of
doing this _without using a card_.)
Opponents will drop a card when you defeat them. You may choose to
pick it up or not, but for bosses, you will automatically record
the card they drop.
The only technically "roguelite" element of the game
so far is that we will keep a record of which cards you got from which
enemies. _This is the only way to have information about cards._ Cards
you haven't seen will be unknown to you.
The card you steal is a random card that opponent was using, and you can only
steal specific cards by attacking an opponent with a light attack _while
they are using that card_. If you defeat an enemy, the card you get if
you decide to pick it up _is random_.
bevy_egui = "0.25.0"
bevy_smooth_pixel_camera = "0.3.0"
leafwing-input-manager = { version = "0.13.3", features = ["egui"] }
bevy_ecs_ldtk = { version = "0.9.0" }
[patch.crates-io]
bevy_ecs_tilemap = { git = "https://github.com/rparrett/bevy_ecs_tilemap/", branch = "bevy13" }
bevy_ecs_ldtk = { git = "https://github.com/theshortcut/bevy_ecs_ldtk", branch = "bevy-0.13" }
name = "arboard"
version = "3.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1faa3c733d9a3dd6fbaf85da5d162a2e03b2e0033a90dceb0e2a90fdd1e5380a"
dependencies = [
"clipboard-win",
"core-graphics",
"image",
"log",
"objc",
"objc-foundation",
"objc_id",
"parking_lot",
"thiserror",
"windows-sys 0.48.0",
"x11rb",
]
[[package]]
]
[[package]]
name = "bevy_ecs_ldtk"
version = "0.9.0"
source = "git+https://github.com/theshortcut/bevy_ecs_ldtk?branch=bevy-0.13#ef466f3a963f4720eceeb7cd1fc97933fbe6cb64"
dependencies = [
"bevy",
"bevy_ecs_ldtk_macros",
"bevy_ecs_tilemap",
"derive-getters",
"derive_more",
"hex",
"paste",
"path-clean",
"regex",
"serde",
"serde_json",
"thiserror",
[[package]]
name = "ecolor"
version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03cfe80b1890e1a8cdbffc6044d6872e814aaf6011835a2a5e2db0e5c5c4ef4e"
dependencies = [
"bytemuck",
]
[[package]]
name = "egui"
version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "180f595432a5b615fc6b74afef3955249b86cfea72607b40740a4cd60d5297d0"
dependencies = [
"ahash",
"epaint",
"nohash-hasher",
]
name = "epaint"
version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77b9fdf617dd7f58b0c8e6e9e4a1281f730cde0831d40547da446b2bb76a47af"
dependencies = [
"ab_glyph",
"ahash",
"bytemuck",
"ecolor",
"emath",
"nohash-hasher",
"parking_lot",
]
[[package]]
[[package]]
name = "leafwing-input-manager"
version = "0.13.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "def515aa1461ed6ed5d55d53cea6c7149a3076c331cfea1d920682884bfaf839"
dependencies = [
"bevy",
"bevy_egui",
"derive_more",
"itertools",
"leafwing_input_manager_macros",
"serde",
]
[[package]]
name = "leafwing_input_manager_macros"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d065e4f0771d9cc597e76d648da18476ad01fd50cd60ee585ee500f9cd8d696"
dependencies = [
"proc-macro-crate 3.1.0",
"proc-macro2",
"quote",
"syn 2.0.52",
]
]
[[package]]
name = "webbrowser"
version = "0.8.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "82b2391658b02c27719fc5a0a73d6e696285138e8b12fba9d4baa70451023c71"
dependencies = [
"core-foundation",
"home",
"jni 0.21.1",
"log",
"ndk-context",
"objc",
"raw-window-handle 0.5.2",
"url",
"web-sys",
[target.x86_64-unknown-linux-gnu]
linker = "clang"
rustflags = [
"-Clink-arg=-fuse-ld=lld", # Use LLD Linker
]
# NOTE: you must install [Mach-O LLD Port](https://lld.llvm.org/MachO/index.html) on mac. you can easily do this by installing llvm which includes lld with the "brew" package manager:
# `brew install llvm`
[target.x86_64-apple-darwin]
rustflags = [
"-Clink-arg=-fuse-ld=/usr/local/opt/llvm/bin/ld64.lld", # Use LLD Linker
]
[target.aarch64-apple-darwin]
rustflags = [
"-Clink-arg=-fuse-ld=/opt/homebrew/opt/llvm/bin/ld64.lld", # Use LLD Linker
]
# This needs "rustup component add llvm-tools(-preview)" and maybe nightly?
[target.x86_64-pc-windows-msvc]
linker = "rust-lld.exe" # Use LLD Linker
rustflags = ["-Zshare-generics=n"]