About Store Forum Documentation Contact



Post Reply 
moving the player to a new position
Author Message
yvanvds Offline
Member

Post: #1
moving the player to a new position
Hey.

I know about the technique to move a character to another world, but this time i'd like to change a characters position to another location in the same world. And I don't want to save/load games, because that would alter the world items too.

So as a button function, I implemented this:
Code:
    if (Players.elms()) {
        Vec pos(-272.014, 1, -53.298);
        Players[0].newPos(pos);
        Vec from(pos);
        from.x--;
        from.z++;
        from.z--;
        Cam.setFromAt(from, pos);
    }

newPos being a function i implemented in my custom player class:
Code:
void Player::newPos(C Vec &pos) {
    __super::pos(pos);
    ctrl_pos = pos;
}

Thing is, the camera changes to the new position, but the player is nowhere to be found. I just like to know if there is a standard practise to do this. I guess i cannot be the first one who wants to have his character moved at once to a new position?

Thanks,

yvan
11-24-2010 09:40 PM
Find all posts by this user Quote this message in a reply
Dynad Offline
Member

Post: #2
RE: moving the player to a new position
Why are you creating a new function for setting a position? does e.g player[0].pos(Vec(0,10,0)); or player[0].ctrl.actor.pos(Vec(0,10,0)); not work directly? and you need to make sure that you don't place the character under the world in the new position cause the player will fall down to nothing.

There is always evil somewhere, you just have to look for it properly.
(This post was last modified: 11-24-2010 09:56 PM by Dynad.)
11-24-2010 09:50 PM
Visit this user's website Find all posts by this user Quote this message in a reply
yvanvds Offline
Member

Post: #3
RE: moving the player to a new position
Because player::pos gets overwritten with this function:

Code:
void Player::pos(C Vec &pos) {
   Vec delta=pos-T.pos();
   __super::pos(pos);

   ctrl_pos+=delta;
}

This is taken from the tutorial section. It is needed for the third person camera. But since it takes the current position into account when calculating the new ctrl_pos, i cannot use it when suddenly changing places.

That is why i set the camera by hand with newPos. And no, ctrl.actor.pos doesn't do it either. I'm very sure the player is not under the world, since i took my positions from looking at the terrain under the cursor in the world editor, and added +2 to Y-axis. (tried with +20 also, but still no character :-)
11-24-2010 11:04 PM
Find all posts by this user Quote this message in a reply
Driklyn Offline
Member

Post: #4
RE: moving the player to a new position
Draw the character's position to the screen to see where he's at.

And, btw, your newPos function does the exact same thing as the pos function.
11-24-2010 11:37 PM
Find all posts by this user Quote this message in a reply
Rofar Offline
Member

Post: #5
RE: moving the player to a new position
I know the problem you are seeing because I had this same issue when trying to do this myself and spent quite a bit of time getting it to work properly. I would have to go back and look at my code and try to give you some tips on how to make this work. I'll check back when I get time and see if you solved it and if not, I will see what I did to make it work.
(This post was last modified: 11-25-2010 12:08 AM by Rofar.)
11-25-2010 12:05 AM
Find all posts by this user Quote this message in a reply
yvanvds Offline
Member

Post: #6
RE: moving the player to a new position
I guess you might be right. If i choose a nearby position, i can just use this code:
Code:
    if (Players.elms()) {
        Vec pos(-272.014, 1, -50.298);
        Players[0].pos(pos);
    }

The camera just follows. But i'd like to have some portals around to move very fast from one part of the world to another. So this implies the positions i want to go to are by definition not nearby :-)
(This post was last modified: 11-25-2010 12:32 AM by yvanvds.)
11-25-2010 12:10 AM
Find all posts by this user Quote this message in a reply
Rofar Offline
Member

Post: #7
RE: moving the player to a new position
Ok, after looking at my code for this, I think this is the general sequence of events that I am doing when teleporting a player to a new location within the same world.

- Save Player data to a memory FILE.
- Remove Player from the world.
- call World update with the character destination location as the location for the update.
- Move camera to the destination location.
- Call World objInject, where playerChache is the memory FILE for the player.
Game::World.objInject(OBJ_PLAYER, playerCache, &destLoc);

I do not do all of those steps within the same update. I think I do the save player and remove player in one update, then the next update I do the world update, move the camera and objInject the player. It looks like the very next update I also do an explicit World update with the destination location supplied as the location for the update again.

I hope this helps.
(This post was last modified: 11-26-2010 04:03 PM by Rofar.)
11-26-2010 03:49 PM
Find all posts by this user Quote this message in a reply
yvanvds Offline
Member

Post: #8
RE: moving the player to a new position
Ok, thanks! Got it all working now. For future reference, here's my code for it. Hopefully someone else can use it.

This gets called when a location is selected:

Code:
void cTravelWindow::museumPressed(Ptr) {
    travelWindow.hide();
    travelWindow.movePlayer(-272.014, 20, -53.298);
}

void cTravelWindow::beachPressed(Ptr) {
    travelWindow.hide();
    travelWindow.movePlayer(-265.747, 20, 752.708);
}

These functions are placed inside a gui struct, and might better be someplace else, but I use this gui window to select a location.

Code:
void cTravelWindow::movePlayer(Flt x, Flt y, Flt z) {
    if (Players.elms()) {
        tempSave.writeMem();
        Players[0].save(tempSave);
        Players.removeValid(0);
        newPos.x = x;
        newPos.y = y;
        newPos.z = z;
        updateStep = 1;
    }
}

void cTravelWindow::injectPlayer() {
    tempSave.pos(0);
    Game::World.objInject(OBJ_PLAYER, tempSave, &newPos);
    tempSave.reset();
}

And here's the way I update the world. This is placed inside the main GameUpdate function:
Code:
// parse input
input.update();
Gui.update();
// the next lines are added to move a player to a new position
// in a proper way
switch (travelWindow.updateStep) {    
    // First step is to save and remove the player. This is done elsewhere.
    // we just skip the world update for now
    case 1:    travelWindow.updateStep = 2;
                break;
    // Second step is updating the world and camera to a new position
    // also inject the player at this position
    case 2:    Game::World.update(travelWindow.newPos);
                Cam.setFromAt(travelWindow.newPos, travelWindow.newPos);
                travelWindow.injectPlayer();
                travelWindow.updateStep = 3;
                break;
    // now do an explicit world update to this position again
    case 3:    Game::World.update(travelWindow.newPos);
                travelWindow.updateStep = 0;
                break;
    // this is a normal world update
    default:    Game::World.update(Cam.matrix.pos);
}
camera.update();
11-27-2010 07:19 PM
Find all posts by this user Quote this message in a reply
Post Reply