Skip to content

Commit

Permalink
feat:make screen effect feature
Browse files Browse the repository at this point in the history
  • Loading branch information
limuy2022 committed Jul 12, 2024
1 parent 1c7c7ef commit 05dd84d
Show file tree
Hide file tree
Showing 11 changed files with 156 additions and 82 deletions.
4 changes: 2 additions & 2 deletions gdrust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions gdrust/src/bullets/star_wrath_bullet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ use rand::{thread_rng, Rng};
use std::f32::consts::PI;

use crate::player::Player;
use crate::utils::screen_effects::ScreenEffects;
use crate::utils::split_to_vec;
use crate::{debug_check, godot_debug_assert};
use crate::{debug_check, get_global, godot_debug_assert};

#[derive(GodotClass)]
#[class(base=Area2D)]
Expand Down Expand Up @@ -107,13 +108,13 @@ impl StarWrathBullet {
let mut obj = obj.get_parent().unwrap().cast::<Player>();
obj.bind_mut().hit(1);
// 关闭碰撞检测
self.get_collison()
self.get_collision()
.set_deferred("disabled".into(), true.to_variant());
}
}

#[debug]
fn get_collison(&mut self) -> Gd<CollisionShape2D> {
fn get_collision(&mut self) -> Gd<CollisionShape2D> {
self.base_mut().get_node_as("CollisionShape2D")
}
}
67 changes: 4 additions & 63 deletions gdrust/src/fight.rs
Original file line number Diff line number Diff line change
@@ -1,90 +1,31 @@
use crate::debug_check;
use crate::fight_items::sword::{SwordManager, START};
use godot::classes::{Control, IControl, Timer};
use crate::{debug_check, get_global};
use godot::classes::{Control, IControl};
use godot::obj::WithBaseField;
use godot::prelude::*;
use rand::Rng;

#[derive(GodotClass)]
#[class(base = Control)]
struct Fight {
base: Base<Control>,
shake_times: i32,
origin_offset: Vector2,
shake_delta: f32,
}

#[godot_api]
impl IControl for Fight {
fn init(base: Base<Control>) -> Self {
Self {
base,
shake_times: 0,
origin_offset: Vector2::ZERO,
shake_delta: 0.0,
}
Self { base }
}

fn ready(&mut self) {
debug_check!(self);
self.shake(3.0, 1.0);
get_global!(self, screen_effects).bind_mut().shake(3.0, 1.0);
self.start_fight();
}
}

#[godot_api()]
#[derive::gen_debug]
impl Fight {
/// 晃动屏幕
/// duration: 持续时间
#[func]
fn shake(&mut self, duration: f64, delta: f32) {
// 根据每次等待时间和总时间算出需要震动多少次
let (camera, mut timer) = self.get_shake_timer();
let wait_time = timer.get_wait_time();
let amount = (duration / wait_time) as i32;
self.shake_delta = f32::max(self.shake_delta, delta);
if self.shake_times != 0 {
self.shake_times += amount;
return;
}
self.origin_offset = camera.get_offset();
self.shake_times = amount;
timer.start();
}

#[debug]
fn get_camera(&self) -> Gd<Camera2D> {
self.base().get_node_as("Camera2D")
}

#[debug]
fn get_shake_timer(&self) -> (Gd<Camera2D>, Gd<Timer>) {
let camera = self.get_camera();
let timer = camera.get_node_as("Shake");
(camera, timer)
}

#[func]
fn shake_timeout(&mut self) {
let (mut camera, mut timer) = self.get_shake_timer();
self.shake_times -= 1;
if self.shake_times == 0 {
// 设回原来的位置
camera.set_offset(self.origin_offset);
timer.stop();
self.shake_delta = 0.0;
return;
}
camera.set_offset(
self.origin_offset
+ Vector2::new(
rand::thread_rng().gen_range(-self.shake_delta..=self.shake_delta),
rand::thread_rng().gen_range(-self.shake_delta..=self.shake_delta),
),
);
}

#[debug]
fn get_end_fight(&self) -> Callable {
self.base().callable("end_fight")
Expand Down
36 changes: 33 additions & 3 deletions gdrust/src/global.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,42 @@
use crate::multi::MultiManager;
use crate::utils::screen_effects::ScreenEffects;
use godot::classes::{INode, Node};
use godot::prelude::*;

#[derive(GodotClass)]
#[class(init, base=Node)]
struct GlobalClass {
#[class(base=Node)]
pub struct GlobalClass {
#[var]
connected_ip: GString,
#[var]
player_name: GString,
#[var]
multi_manager: Option<Gd<MultiManager>>,
#[var]
pub screen_effects: Gd<ScreenEffects>,
base: Base<Node>,
}

#[godot_api()]
impl INode for GlobalClass {}
impl INode for GlobalClass {
fn init(base: Base<Node>) -> Self {
Self {
base,
screen_effects: ScreenEffects::new_alloc(),
connected_ip: GString::default(),
multi_manager: None,
player_name: GString::default(),
}
}

fn ready(&mut self) {
let tmp = self
.get_screen_effects_scene()
.instantiate_as::<ScreenEffects>();
self.base_mut().add_child(tmp.clone().upcast());
self.screen_effects = tmp;
}
}

#[godot_api()]
impl GlobalClass {
Expand All @@ -30,4 +51,13 @@ impl GlobalClass {
}
}
}

fn get_screen_effects_scene(&mut self) -> Gd<PackedScene> {
Gd::from_variant(
&self
.base_mut()
.get_property()
.get("screen_effects_scene".into()),
)
}
}
4 changes: 2 additions & 2 deletions gdrust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ mod cfg;
mod consts;
mod fight;
mod fight_items;
mod global;
pub mod global;
mod multi;
mod player;
mod ui;
Expand All @@ -12,7 +12,7 @@ mod weapons;
mod zenith;

use godot::prelude::*;
use multi::{MultiManager, MultiManagerImpl};
use multi::MultiManagerImpl;
use std::{
panic::{set_hook, PanicInfo},
sync::{Arc, Mutex, OnceLock},
Expand Down
3 changes: 1 addition & 2 deletions gdrust/src/ui/multi_setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ use crate::multi::MessageReceiver;
use crate::{debug_check, get_multi_single};
use derive::gen_debug;
use godot::classes::{Control, IControl};
use godot::engine::{Label, Panel};
use godot::engine::Label;
use godot::prelude::*;
use proto::connect;
use std::mem::swap;

#[derive(GodotClass)]
#[class(base = Control)]
Expand Down
13 changes: 13 additions & 0 deletions gdrust/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod screen_effects;
use godot::prelude::*;

#[macro_export()]
Expand Down Expand Up @@ -30,6 +31,18 @@ macro_rules! debug_check {
};
}

#[macro_export]
macro_rules! get_global {
($sself:ident) => {
$sself
.base()
.get_node_as::<$crate::global::GlobalClass>("/root/Global")
};
($sself:ident, screen_effects) => {
get_global!($sself).bind().screen_effects.clone()
};
}

/// 将传入的弧度转换成单位向量
pub fn split_to_vec(rad: f32) -> Vector2 {
Vector2::new(rad.cos(), rad.sin())
Expand Down
86 changes: 86 additions & 0 deletions gdrust/src/utils/screen_effects.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
use derive::gen_debug;
use godot::{
builtin::Vector2,
classes::{Camera2D, ICamera2D},
engine::Timer,
log::godot_print,
obj::{Base, Gd, WithBaseField},
register::{godot_api, GodotClass},
};
use rand::Rng;

use crate::debug_check;

#[derive(GodotClass)]
#[class(base = Camera2D)]
pub struct ScreenEffects {
shake_times: i32,
shake_delta: f32,
origin_offset: Vector2,
base: Base<Camera2D>,
}

#[godot_api]
impl ICamera2D for ScreenEffects {
fn init(base: Base<Camera2D>) -> Self {
Self {
shake_times: 0,
shake_delta: 0.0,
origin_offset: Vector2::ZERO,
base,
}
}

fn ready(&mut self) {
debug_check!(self)
}
}

#[godot_api]
#[gen_debug]
impl ScreenEffects {
/// 晃动屏幕
/// duration: 持续时间
#[func]
pub fn shake(&mut self, duration: f64, delta: f32) {
// 根据每次等待时间和总时间算出需要震动多少次
let mut timer = self.get_shake_timer();
let wait_time = timer.get_wait_time();
let amount = (duration / wait_time) as i32;
self.shake_delta = f32::max(self.shake_delta, delta);
if self.shake_times != 0 {
self.shake_times += amount;
return;
}
self.origin_offset = self.base().get_offset();
self.shake_times = amount;
godot_print!("timer start");
timer.start();
}

#[debug]
fn get_shake_timer(&self) -> Gd<Timer> {
self.base().get_node_as("Shake")
}

#[func]
fn shake_timeout(&mut self) {
let mut timer = self.get_shake_timer();
self.shake_times -= 1;
if self.shake_times == 0 {
// 设回原来的位置
let tmp = self.origin_offset;
self.base_mut().set_offset(tmp);
timer.stop();
self.shake_delta = 0.0;
return;
}
let rng = -self.shake_delta..=self.shake_delta;
let tmp = self.origin_offset
+ Vector2::new(
rand::thread_rng().gen_range(rng.clone()),
rand::thread_rng().gen_range(rng),
);
self.base_mut().set_offset(tmp);
}
}
7 changes: 0 additions & 7 deletions scenes/fight.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -227,12 +227,5 @@ texture = ExtResource("14_miw1s")
position = Vector2(0, -1)
texture = ExtResource("18_12j3n")

[node name="Camera2D" type="Camera2D" parent="."]
position = Vector2(576, 324)

[node name="Shake" type="Timer" parent="Camera2D"]
wait_time = 0.1

[connection signal="hit_sig" from="Player" to="HealthBar" method="attack"]
[connection signal="timeout" from="Player/Cthulhu" to="Player" method="stop_rush"]
[connection signal="timeout" from="Camera2D/Shake" to="." method="shake_timeout"]
2 changes: 2 additions & 0 deletions scenes/global.gd
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
extends GlobalClass

@onready var screen_effects_scene = preload("res://scenes/utils/screen_effects.tscn")
9 changes: 9 additions & 0 deletions scenes/utils/screen_effects.tscn
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[gd_scene format=3 uid="uid://b601ywspu5w2b"]

[node name="ScreenEffects" type="ScreenEffects"]
position = Vector2(576, 324)

[node name="Shake" type="Timer" parent="."]
wait_time = 0.1

[connection signal="timeout" from="Shake" to="." method="shake_timeout"]

0 comments on commit 05dd84d

Please sign in to comment.