Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement enemies #14

Open
johnthagen opened this issue Jan 2, 2017 · 9 comments
Open

Implement enemies #14

johnthagen opened this issue Jan 2, 2017 · 9 comments
Assignees

Comments

@johnthagen
Copy link
Owner

No description provided.

@johnthagen johnthagen added this to the 2.0 milestone Jan 2, 2017
@mcdenhoed mcdenhoed self-assigned this Feb 4, 2017
@mcdenhoed
Copy link
Collaborator

mcdenhoed commented Feb 4, 2017

Initial try at implementation can be found in the enemy branch

@mcdenhoed
Copy link
Collaborator

mcdenhoed commented Feb 4, 2017

@johnthagen Any thoughts on how I broke this out (minus the obviously stand-in parts like rendering)? Not sure how idiomatic it is.

@mcdenhoed
Copy link
Collaborator

Updated the logic in 1e03596 to account for the fact that the canvas is a torus.

@mcdenhoed
Copy link
Collaborator

@johnthagen Check out the new push on enemy. Merged in the traits you wrote, also changed how they work a tiny bit. I feel like there has to be a better way to share more code, but this is what I have for now. Due to the architectural changes, I can't think of a clean way to feed the enemy the player's position, so it's just accelerating toward a fixed point right now.

@johnthagen
Copy link
Owner Author

@mcdenhoed First off, I love how you can see the enemies' thrusters now. So funny watching it make tons of little corrections 😄

Tiny thing, I think you accidentally checked in game.rs.bk. rustfmt makes these if you using --write-mode replace instead of --write-mode overwrite

Ah, I see what you did with the update function.

pub fn update<T: Updateable>(x: &mut T, args: UpdateArgs) {
    x.update_location();
    x.update_logic(args);
}

And then:

update(&mut self.player, args);
update(&mut self.enemy, args);

Couldn't update() be part of the Updateable trait? In fact, traits can have default implementations so you can still share this code. (See: http://rustbyexample.com/trait.html)

And then Game could just call:

player.update(args)
enemy.update(args)

I think it makes a little more sense to take &mut self than <T: Updateable>, but I see what you did there! :) In fact, I think you actually just created a trait method the manual way.

I do like the idea of having private trait methods that get called in a default trait implementation to try to reuse code.

@mcdenhoed
Copy link
Collaborator

I guess my thought was, if we do end up having large lists of things, would it be easier to call "update" on an updateable thing than to call the "update" method of an updatable thing? The second seems like an OOP pattern, and the first seemed to me to be more idiomatic. I can change that back though. Still not sure how we can cleanly get shared code for something like position updates with this system. Trait default implementations are still limited to calling other methods defined/guaranteed by the trait, so I feel like our hands are still tied there.

@johnthagen
Copy link
Owner Author

I guess my thought was, if we do end up having large lists of things, would it be easier to call "update" on an updateable thing than to call the "update" method of an updatable thing?

They really are functionally equivalent, so I think it's really just semantics. To me it seemed slightly more idiomatic to keep all of the related functionality within a single trait, but agree one is more object/type based and the other more procedural/functional.

One nice thing is that no matter which way, if we have large lists of Updateable types, we can pass them into generic functions that take <T: Updateable> (like your current implementation) and Rust will generate the vtable dispatch.

Trait default implementations are still limited to calling other methods defined/guaranteed by the trait, so I feel like our hands are still tied there.

Absolutely, the only thing I can really think of is that we have to model the problem with composition. Instead of Player and Enemy being a special type of Actor, they need to both contain an Actor and the Actor type implements the shared code on itself.

Since enemies are quite a bit more complex than the weapon #5 and asteroids #7 , maybe we should try those out first and see what kinds of shared code comes out of that.

Also, I've had good luck asking this kind of question on https://users.rust-lang.org/ so we could try that too.

@mcdenhoed
Copy link
Collaborator

I might try readding the actor code then

@johnthagen johnthagen removed this from the 2.0 milestone Jun 8, 2017
@johnthagen
Copy link
Owner Author

@mcdenhoed Is the enemy branch still valid at this point? Should we delete it for now, or is there still useful code in it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants