Jump to content
  • Advertisement
Sign in to follow this  
dzeligman

Implementing "mind control"

This topic is 3622 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

So I decided that something like mind control could be interesting to implement. My idea for it in my 2d shooter is essentially its a tractor beam. I would use simple ray tracing from the ship to nearest enemy to "lock-on" to it. When locked on the player's movement will be locked. And the user will now control the movement and firing mechanisms of the enemy ship. Now in terms of actually implementing this solution I'm a little lost. Right now my player doesnt know anything about its enemies. Enemies dont know about other enemies and the enemy shots arent checked to collide against other enemies. Right now I'm thinking that I would pass the computed move vector to the enemy as well as bool for isFiring. Now where this pass occurs I'm not sure if the player should directly call the update upon which its controlling or something else. Also the enemies default movement and firing mechanisms would need to be disabled/overriden if it is mindcontrolled. I'm thinking that it needs some separate state for whether it is in control or not. Just looking for some tips and advice :)

Share this post


Link to post
Share on other sites
Advertisement

class EnemyShip
{
private:
bool m_isControlled;
Vector m_position;
bool m_shooting;

public:
void update()
{
if(!m_isControlled)
{
fly_freely_and_shoot_randomly();
}
else
{
IKeyboardHandler kb;
get_keyboard_event(&kb);

catch_player_input(kb);
}
}

void catch_player_input(IKeyboardHandler handle)
{
if(handle.keyboard.normal_keys.LEFT == 0)
{
fly(EVENT::LEFT);
}
/*nlah blah blah*/
...
..
}

void set_is_controlled(bool set)
{
m_isControlled = set;
}

....
..
}

class Player
{
private:
bool m_isControlling;

...
..
public:

void grab_enemy (void )
{
EnemyShip* ship = grab_ship_from_raycasting; //return the ship
ship->set_is_controlled(true);
this->set_is_controlling(true);
}

...
...
}




Get the idea? I had to cut this short, but I hope I helped.

Share this post


Link to post
Share on other sites
Even better:


interface IObject
{
virtual void Move();
virtual void Shoot();
}

interface IController
{
virtual void WhatToDoNext(IObject);
}

class AI_Controller : IController
{
void WhatToDoNext(IObject obj) { /* Do AI things */ }
}

class Keyboard_Controller : IController
{
void WhatToDoNext(IObject obj) { /* Do player things */ }
}

class Debrained_Controller : IController
{
void WhatToDoNext(IObject obj) {
/* Do player-ship-when-controlling-someone-else things */
}
}

class Ship : IObject
{
void Move() {}
void Shoot() {}

private IController c;

void SetController(IController c) { this.c = c; }
void Act() { this.c.WhatToDoNext(this); }
}

class Enemy : Ship {}
class Player : Ship {}



This way, you can add more AI behaviours if you need to.

Share this post


Link to post
Share on other sites
Thanks, both those help.

ToohrVyk, that seems pretty elegant, but what if my IObject doesnt have a shoot method, but say the ship does?

I've had a few situations like this and found that I'm forced to do some class casting or type checking which I know is "not good", but the WhatToDoNext imp would need to access atleast some of the specific methods of the ship.

Unless I guess if I just make the WhatToDoNext a little more generic.

This is in C#/Xna

Share this post


Link to post
Share on other sites
Quote:
Original post by dzeligman
Thanks, both those help.

ToohrVyk, that seems pretty elegant, but what if my IObject doesnt have a shoot method, but say the ship does?

I've had a few situations like this and found that I'm forced to do some class casting or type checking which I know is "not good", but the WhatToDoNext imp would need to access atleast some of the specific methods of the ship.

Unless I guess if I just make the WhatToDoNext a little more generic.

This is in C#/Xna


But IObject does have a shoot method. What's the problem? Ships are inherited from IObject.

You could even have the enemy ships and and the player ship be the same class, and just have different graphics and controllers for players and enemies. You might need sub-classes for ships with more guns or stuff, but that would be rather simple to take care of.

The other problem you mentioned in passing is actually getting a handle on the ship to be controlled. I think this is related to the question you asked in one of the beginner threads about seeking missiles. How does the missile know about the enemy ships?

The way I do it is for each object to have an integer id. It's actually the index in its storage array where it's stored, set by the function that adds it to the array. You could do it via a hash table, std::map or something like that. Then you have a funtion that returns a pointer to an object based on its ID.

Maybe you could just pass pointers around, I forgot why I don't do that.

If you click on a ship, you could use collision detection and handling code that is already in place to determine whether the click was on a ship, and either get a pointer to the ship to the missile or player, or tell it to start taking commands from the keyboard. I guess your using some other method for controlling a ship (try a mind-control bullet?), but you probably see what I'm getting at.

I suspect if you solve this issue of access, a lot of other issues will be helped. Tell me how you do it, I don't have it all figured out myself!

Share this post


Link to post
Share on other sites
Yeah I think I worded my last reply really poorly, my bad.

Quote:

The other problem you mentioned in passing is actually getting a handle on the ship to be controlled. I think this is related to the question you asked in one of the beginner threads about seeking missiles. How does the missile know about the enemy ships?


Yeah this is one issue that I will probably temporarly solve with more parameter passing (I'm doing this with XNA/C#, so no "pointers")

In terms of my need for typechecking let me explain furthur with code.
My actual code is more complex than this, but this is just for reference.

Say I have my top-level most generic Iobject

interface IObject
{
Move();
void Draw();
void Update();
}


My ship and and another object I want to be controlled such as an asteroid...


class Asteroid : IObject
{
void Move() {}
void Draw(){}
void Update(){}
void breakApart() {}

private IController c;


// has its own AIController,
void SetController(IController c) { this.c = c; }
void Act() { this.c.WhatToDoNext(this); }
}




class Ship : IObject
{
void Move() {}
void Shoot() {}
void Draw(){}
void Update(){}

private IController c;

void SetController(IController c) { this.c = c; }
void Act() { this.c.WhatToDoNext(this); }
}



So to be more specific than I was with my last post.
Quote:
but what if my IObject doesnt have a shoot method, but say the ship does?

I've had a few situations like this and found that I'm forced to do some class casting or type checking which I know is "not good", but the WhatToDoNext imp would need to access atleast some of the specific methods of the ship.


If my ship wants to use the tractor beam on the asteroid than when I change the controller interface implementation the whatToDONext of that implementation would need access to say the breakApart method since my IObject is really generic. But because IObject doesnt ahve a breakApart or "shoot" currently I would have to cast the object to a ship or to a Asteroid.

Not sure how to get around that.

Share this post


Link to post
Share on other sites
Quote:
Original post by theOcelot


But IObject does have a shoot method. What's the problem? Ships are inherited from IObject.



So every object that inherits from IObject would have a shoot method? Asteroids? Power ups? Doesn't that make your IObject class too much of a blob?

Share this post


Link to post
Share on other sites
Would you really want to control an asteroid? That would be weird. You could just make it part of the rules that you can't blow up an asteroid by tractor-beaming it. That takes care of it![grin] Then you just have an empty shoot method in the asteroid controller.

Gregrampage makes a point; you may want to move the shoot method into something like IMovingObject (that's an incredibly bad name, don't use it), which inherits from IObject, along with IPowerUp(?), and what have you. Or something like that.

come to think of it, might ships also have a function similar to breakApart, like BlowUp, called when the ship is destroyed. It might be worth adding to the interface (whatever level of interface that's right above Ship and Asteroid in the heirarchy).

Quote:
Yeah this is one issue that I will probably temporarly solve with more parameter passing (I'm doing this with XNA/C#, so no "pointers")


Oops!

Share this post


Link to post
Share on other sites
Quote:
Gregrampage makes a point; you may want to move the shoot method into something like IMovingObject (that's an incredibly bad name, don't use it), which inherits from IObject, along with IPowerUp(?), and what have you. Or something like that.


Yeah I was trying to get at the potential blobness of the IGameobject if shoot were included in it, I was really trying to get it on a more abstract level of the controller needing to know the specific objects -specific methods. (I.E. controller needs to know that what is is holding has a shoot method so it can use it, or that the object has a blowup, explode, doSpecialActionSpecificToThisObjectMethod() ---- the top level interface would not have these methods.

Another "possible" example, since an asteroid doesnt really make much sense I guess.

A projectile of any kind, it probably wouldn't shoot since it is what shot, but what if you wanted to turn it around back at who shot it?

It also needs to move and have its own controller thus it woudld be suitable to implement it as another iGameObject.

Share this post


Link to post
Share on other sites
I'm not sure what exactly you're trying to, now. Here are a couple ideas which may or may not help, or even make sense.

@ Have a game object class which has a subclass IMovingObject (projectiles, ships, there's that name again), which has a subclass IShootingObject, all abstract.

@ Have a class IController, which has a subclass IShootingController, and whatever other controllers you need.

Say that Asteroid.setController takes an argument of type IMovingObjectController, not an IShootingController. But a player can call Asteroid.setController with its own controller, since an IShootingController IS_A IMovingObjectController. Asteroid will only ever know about the parts that are relevant to itself. I still think, though, that blowing up should be something common to both interfaces anyway.

Wow, maybe that really will help.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!