Created
June 23, 2025 11:00
-
-
Save nandakoryaaa/85b39a678d59cb6e089d91a4483b70ce to your computer and use it in GitHub Desktop.
Implementing display object list, drawabe & behaviour traits for abstract game in Rust
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#[derive (Copy, Clone)] | |
struct Rect { | |
w: u32, | |
h: i32 | |
} | |
struct Renderer { | |
canvas: u32 // not used | |
} | |
impl Renderer { | |
fn drawBitmap(&mut self, handle: u32) { | |
println!("drawing Bitmap {}", handle); | |
} | |
fn drawRect(&mut self, rect: Rect) { | |
println!("drawing Rect {}x{}", rect.w, rect.h); | |
} | |
} | |
trait Drawable { | |
fn draw(&self, renderer: &mut Renderer); | |
} | |
struct DrawableBitmap { | |
handle: u32 | |
} | |
struct DrawableRect { | |
rect: Rect | |
} | |
impl Drawable for DrawableBitmap { | |
fn draw(&self, renderer: &mut Renderer) { | |
renderer.drawBitmap(self.handle); | |
} | |
} | |
impl Drawable for DrawableRect { | |
fn draw(&self, renderer: &mut Renderer) { | |
renderer.drawRect(self.rect); | |
} | |
} | |
trait Behaviour { | |
fn update(&mut self, gmo_data: &mut GMOData); | |
} | |
struct BehaviourMove { | |
speed: i32 | |
} | |
struct BehaviourWait { | |
count: i32 | |
} | |
impl Behaviour for BehaviourMove { | |
fn update(&mut self, gmo_data: &mut GMOData) { | |
gmo_data.x += self.speed; | |
println!("behaviour: Speed {}", gmo_data.x); | |
} | |
} | |
impl Behaviour for BehaviourWait { | |
fn update(&mut self, gmo_data: &mut GMOData) { | |
self.count += 1; | |
println!("behaviour: Wait {}", self.count); | |
} | |
} | |
#[derive (Copy, Clone)] | |
struct StageObject<'a> { | |
x: i32, | |
y: i32, | |
drawable: &'a dyn Drawable, | |
} | |
struct GMOData { | |
x: i32, | |
y: i32 | |
} | |
struct GameObject<'a> { | |
data: GMOData, | |
sto_index: usize, | |
behaviour: &'a mut dyn Behaviour | |
} | |
struct STOEntry<'a> { | |
prev: usize, | |
next: usize, | |
sto: StageObject<'a> | |
} | |
struct STOList<'a> { | |
used_list: Vec<STOEntry<'a>>, | |
free_list: Vec<usize>, | |
capacity: usize, | |
cnt: usize, | |
first: usize, | |
last: usize | |
} | |
impl<'a> STOList<'a> { | |
fn create(capacity: usize) -> Self { | |
STOList { | |
used_list: Vec::with_capacity(capacity), | |
free_list: Vec::with_capacity(capacity), | |
capacity: capacity, | |
cnt: 0, | |
first: 0, | |
last: 0 | |
} | |
} | |
fn add(&mut self, sto: StageObject<'a>) -> usize { | |
let mut index: usize = self.used_list.len(); | |
let mut stoe = STOEntry { | |
prev: self.last, | |
next: index, | |
sto: sto | |
}; | |
if self.free_list.len() == 0 { | |
if (index >= self.capacity) { | |
return index; | |
} | |
self.used_list.push(stoe); | |
} else { | |
if let Some(val) = self.free_list.pop() { | |
index = val; | |
stoe.next = index; | |
self.used_list[index] = stoe; | |
} | |
} | |
self.used_list[self.last].next = index; | |
self.last = index; | |
self.cnt += 1; | |
index | |
} | |
fn del(&mut self, index: usize) { | |
if index >= self.used_list.len() { | |
return; | |
} | |
let prev = self.used_list[index].prev; | |
let next = self.used_list[index].next; | |
if index == self.first { | |
self.first = next; | |
} else { | |
self.used_list[prev].next = next; | |
} | |
if index == self.last { | |
self.last = prev; | |
} else { | |
self.used_list[next].prev = prev; | |
} | |
self.free_list.push(index); | |
self.cnt -= 1; | |
} | |
} | |
struct Stage<'a> { | |
w: u32, | |
h: u32, | |
sto_list: STOList<'a> | |
} | |
impl<'a> Stage<'a> { | |
fn add_child(&mut self, sto: StageObject<'a>) -> usize { | |
return self.sto_list.add(sto); | |
} | |
fn remove_child(&mut self, index: usize) { | |
self.sto_list.del(index); | |
} | |
fn draw(&self, renderer: &mut Renderer) { | |
if self.sto_list.cnt == 0 { | |
return; | |
} | |
let mut index = self.sto_list.first; | |
while (true) { | |
let sto = self.sto_list.used_list[index].sto; | |
sto.drawable.draw(renderer); | |
if index == self.sto_list.last { | |
break; | |
} | |
index = self.sto_list.used_list[index].next; | |
} | |
} | |
} | |
fn process_game_objects(game_objects: &mut [GameObject]) { | |
for gmo in game_objects.iter_mut() { | |
gmo.behaviour.update(&mut gmo.data); | |
} | |
} | |
pub fn main() | |
{ | |
let mut renderer = Renderer { canvas: 0 /* not used */}; | |
// testing Stage | |
let mut stage = Stage { | |
w: 800, | |
h: 600, | |
sto_list: STOList::create(128) | |
}; | |
let sto_bitmap = stage.add_child( | |
StageObject { x: 0, y: 0, drawable: &DrawableBitmap { handle: 5 }} | |
); | |
let sto_rect = stage.add_child( | |
StageObject { x: 0, y: 0, drawable: &DrawableRect { rect: Rect { w:10, h:10 }}} | |
); | |
stage.draw(&mut renderer); | |
// testing game objects | |
let mut game_objects: [GameObject; 2] = [ | |
GameObject { data: GMOData { x: 0, y: 0}, sto_index: sto_bitmap, behaviour: &mut BehaviourMove { speed: 10 } }, | |
GameObject { data: GMOData { x: 0, y: 0}, sto_index: sto_rect, behaviour: &mut BehaviourWait { count: 0 } } | |
]; | |
process_game_objects( | |
&mut game_objects | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment