Thanks for sarcasm/irony. Here is complete code:
Code: Select all
/*
This code is based off of the Movement tutorial, with stuff from the Quake3Map tutorial
and Boogle's 3rd Person Camera code thrown in.
*/
#include <stdio.h>
#include <wchar.h>
#include <irrlicht.h>
using namespace irr;
#pragma comment(lib, "Irrlicht.lib")
/*
I like to define controls as powers of 2, so I can squash them all bitwise onto a single
int. This makes it really easy to deal with and probably also makes it nice and fast. :)X
*/
#define C_UP 1
#define C_DOWN 2
#define C_LEFT 4
#define C_RIGHT 8
#define C_CAML 16
#define C_CAMR 32
#define MOVESPEED 5.0f // how fast p1 and the camera move
#define ROTSPEED 2.0f // how fast p1 rotates
#define HEIGHT 0.0f // how high camera hovers over center of target
scene::ICameraSceneNode* camera;
scene::IAnimatedMeshSceneNode* p1;
IrrlichtDevice* device = 0;
float cam_rotate=0;
float p1_rotate=0;
float moving=0;
bool start=false;
unsigned int controls=0;
/*
Read the keys, and use them to set the bits of (controls).
*/
class MyEventReceiver : public IEventReceiver
{
public:
virtual bool OnEvent(SEvent event)
{
if (event.EventType == irr::EET_KEY_INPUT_EVENT)
{
unsigned int k=0;
switch(event.KeyInput.Key) {
case(KEY_UP):
k=C_UP;
break;
// case(KEY_DOWN):
// k=C_DOWN;
// break;
case(KEY_LEFT):
k=C_LEFT;
break;
case(KEY_RIGHT):
k=C_RIGHT;
break;
case(KEY_KEY_A):
k=C_CAML;
break;
case(KEY_KEY_S):
k=C_CAMR;
break;
}
if(k) {
if(event.KeyInput.PressedDown)
controls |= k;
else
controls ^= k;
return true;
}
}
return false;
}
};
/*
Parse the controls to move p1.
*/
void resolve_controls_RE() {
/*
Resident Evil -style controls; up=forward, down=back, left & right = rotate
Nice and simple. :)X
*/
if(controls & C_UP)
{
start=true;
moving = controls && C_UP ? MOVESPEED : -MOVESPEED;
if(controls & C_LEFT + C_RIGHT) {
p1_rotate += controls & C_RIGHT ? ROTSPEED : (360.0f-ROTSPEED);
if(p1_rotate>=360.0f)
p1_rotate -= 360.0f;
p1->setRotation(core::vector3df(0,p1_rotate,0));
}
}
else
start=false;
if(controls & C_CAML + C_CAMR)
cam_rotate = controls & C_CAMR ? ROTSPEED : -ROTSPEED;
}
void resolve_controls_WW() {
/*
Wind Waker -style controls; direction pressed makes you go in that direction relative
to the camera. Not so nice and simple, and also not quite working right. :(X
*/
p1_rotate=0;
switch(controls & C_UP+C_DOWN+C_LEFT+C_RIGHT) {
case(C_UP+C_LEFT):
p1_rotate+=45.0f;
case(C_LEFT):
p1_rotate+=45.0f;
case(C_DOWN+C_LEFT):
p1_rotate+=45.0f;
case(C_DOWN):
p1_rotate+=45.0f;
case(C_DOWN+C_RIGHT):
p1_rotate+=45.0f;
case(C_RIGHT):
p1_rotate+=45.0f;
case(C_UP+C_RIGHT):
p1_rotate+=45.0f;
case(C_UP):
core::matrix4 matty;
matty.buildCameraLookAtMatrixLH(camera->getPosition(),camera->getTarget(),camera->getUpVector());
p1_rotate+=matty.getRotationDegrees().Z+270.0f;
while(p1_rotate>=360.0f) {
p1_rotate-=360.0f;
}
float foo = p1->getRotation().Y-p1_rotate;
if(foo<0)
foo=-foo;
if(foo<45.0f || foo>360.0f-45.0f)
moving = MOVESPEED;
if(foo>ROTSPEED || foo>360.0f-ROTSPEED) {
if(foo<180.0f)
if(p1->getRotation().Y>p1_rotate)
p1->setRotation(p1->getRotation() + core::vector3df(0,360.0f-ROTSPEED*2,0));
else
p1->setRotation(p1->getRotation() + core::vector3df(0,ROTSPEED*2,0));
else
if(p1->getRotation().Y<p1_rotate)
p1->setRotation(p1->getRotation() + core::vector3df(0,360.0f-ROTSPEED*2,0));
else
p1->setRotation(p1->getRotation() + core::vector3df(0,ROTSPEED*2,0));
if(p1->getRotation().Y>=360.0f)
p1->setRotation(p1->getRotation() - core::vector3df(0,360.0f,0));
}
}
if(controls & C_CAML + C_CAMR)
cam_rotate = controls & C_CAMR ? ROTSPEED : -ROTSPEED;
}
int main()
{
MyEventReceiver receiver;
device = createDevice(video::EDT_DIRECTX8, core::dimension2d<s32>(800, 600),
16, true, false, false ,&receiver);
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
/*
Make the background go!
*/
//device->getFileSystem()->addZipFileArchive("map-20kdm2.pk3");
scene::IAnimatedMesh* mesh = smgr->getMesh("town5.3ds");
scene::ISceneNode* bg = smgr->addOctTreeSceneNode(mesh->getMesh(0));
bg->setPosition(core::vector3df(-1000,-100,-100));
/*
Triangle Selecty-ness on the background
*/
scene::ITriangleSelector* selector = 0;
selector = smgr->createOctTreeTriangleSelector(mesh->getMesh(0), bg, 128);
bg->setTriangleSelector(selector);
selector->drop();
/*
Make the player character
*/
mesh = smgr->getMesh("sydney.md2");
p1 = smgr->addAnimatedMeshSceneNode(mesh);
p1->setPosition(core::vector3df(0,0,0));
scene::ISceneNode* p1_target = smgr->addEmptySceneNode(p1);
p1_target->setPosition(core::vector3df(1,0,0));
p1->setMaterialFlag(video::EMF_LIGHTING, false);
p1->setFrameLoop(320, 360);
p1->setAnimationSpeed(30);
p1->setMaterialTexture(0, driver->getTexture("sydney.bmp"));
/*
Set collision for player character
*/
core::vector3df dimensions = mesh->getBoundingBox().MaxEdge - mesh->getBoundingBox().MinEdge;
scene::ISceneNodeAnimator* collision = smgr->createCollisionResponseAnimator(selector,p1,dimensions/2.0f);
p1->addAnimator(collision);
/*
Make the camera go!
*/
camera = smgr->addCameraSceneNode(0, core::vector3df(-10,HEIGHT,0), core::vector3df(0,0,100));
/*
Set collision for camera
*/
collision = smgr->createCollisionResponseAnimator(
selector,camera,core::vector3df(20,20,20),
core::vector3df(0,0,0), 0.0f,
core::vector3df(0,0,0));
camera->addAnimator(collision);
collision->drop();
irr::video::ITexture *crosshairTexture = driver->getTexture("gui2.bmp");
driver->makeColorKeyTexture(crosshairTexture,irr::core::position2d<irr::s32>(0,0));
device->getCursorControl()->setVisible(false);
/*
Main game loop
*/
while(device->run())
{
driver->beginScene(true, true, video::SColor(255,90,90,156));
smgr->drawAll();
//core::position2d<s32> m = device->getCursorControl()->getPosition();
// irr::core::position2d<irr::s32> crosshairLocation = device->getCursorControl()->getPosition();
//crosshairLocation.X = 500;
//crosshairLocation.Y = 0;
// draw the crosshair
driver->draw2DImage(crosshairTexture,core::position2d<s32>(673,0),
irr::core::rect<irr::s32>(0,0,127,350),0,
irr::video::SColor(255,255,255,255),true);
driver->endScene();
if (start)//this is problematic part!!
{
p1->setFrameLoop(320, 360);
}
else
{
p1->setFrameLoop(0, 320);
}
int fps = driver->getFPS();
wchar_t tmp[1024];
swprintf(tmp, 1024, L"Following Camera Example - Irrlicht Engine (%s)(fps:%d)(%2.2f)(%2.2f)(%2.2f)",
driver->getName(), fps,p1_rotate,p1->getRotation().Y,p1_rotate-p1->getRotation().Y);
device->setWindowCaption(tmp);
/*
Set control scheme here;
RE = Resident Evil -style
WW = Wind Waker -style
*/
resolve_controls_RE();
/*
p1_target is an empty node that floats 1.0f in front of p1. It's used just like a
camera's target to determine which way p1 is facing, and since it's already 1.0f away,
it doesn't have to be normalized. Is there a better way to do this?
Set p1_movedir to the direction p1 is facing, then move in that direction!
*/
core::vector3df p1_movedir = p1_target->getAbsolutePosition() - p1->getPosition();
if(moving) {
p1->setPosition(p1->getPosition()+(p1_movedir*moving));
moving=0;
}
/*
That's it for moving the player. Now here's the stuff for moving the camera.
While we want to camera to look directly at p1, we want its movement to be based on
a point HEIGHT above p1.
*/
camera->setTarget(p1->getPosition());
f64 distance = camera->getPosition().getDistanceFrom(camera->getTarget()+core::vector3df(0,HEIGHT,0));
core::vector3df cam_movedir = (camera->getTarget()+core::vector3df(0,HEIGHT,0))-camera->getPosition();
cam_movedir.normalize();
/*
The camera tries to stay between 50.0f and 50.0f+MOVESPEED from HEIGHT above p1;
if it tried to stay at exactly 50.0f, it would freak out and jiggle too much.
*/
if(distance>(90.0f+MOVESPEED))
camera->setPosition(camera->getPosition()+(cam_movedir*MOVESPEED));
else if(distance<90.0f)
camera->setPosition(camera->getPosition()-(cam_movedir*MOVESPEED));
/*
The camera rotation stuff cheats a little, because instead of rotating it perfectly
around p1, it just moves the camera left or right relatively, and lets the camera
automatically adjust to the right distance.
*/
if(cam_rotate) {
core::vector3df crossy = (camera->getTarget()-camera->getPosition()).crossProduct(camera->getUpVector());
crossy.normalize();
camera->setPosition(camera->getPosition()-crossy*cam_rotate);
cam_rotate=0;
}
}
/*
In the end, delete the Irrlicht device.
*/
device->drop();
return 0;
}
You know what I need.
Thanks again.