Why do I need in row 189 this "break"? EDIT: problem solved, device->run() was lacking in the while loop.
Code: Select all
// IrrSpiel.cpp from www.HenkesSoft.de
// First 3D-Game "Muhaha Code1"
//
// Irrlicht types cf. irrTypes.h, e.g.
// s32: __int32, u32: unsigned __int32,
// f32: float, f64: double
#include "stdafx.h" // MS VisualC++
#include <ctime> // clock, time
#include <cstdlib> // srand, rand
#include <iostream> // cout, cin, endl
#include <limits> // wait()
#include <irrlicht.h> // grafic engine (free)
#include <irrklang.h> // sound system (free for private use)
// irrlicht namespace
using namespace irr; using namespace core; using namespace scene;
using namespace video; using namespace io; using namespace gui; using namespace std;
// linker commands
#pragma comment(lib, "irrlicht.lib")
#pragma comment(lib, "irrklang.lib")
void wait() // prohibits "unexpected shutdown" of console
{
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cin.get();
}
void drawScene(IVideoDriver* driver, ISceneManager* smgr, IGUIEnvironment* guienv)
{
driver->beginScene(true, true, SColor(0,200,200,200));
smgr->drawAll();
guienv->drawAll();
driver->endScene();
}
// Event Handler
class MyEventReceiver : public IEventReceiver
{
public:
virtual bool OnEvent(const SEvent& event)
{
if (event.EventType == EET_KEY_INPUT_EVENT)
KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
return false;
}
virtual bool IsKeyDown(EKEY_CODE keyCode) const {return KeyIsDown[keyCode];}
MyEventReceiver(){for(u32 i=0; i<KEY_KEY_CODES_COUNT; ++i) KeyIsDown[i] = false;}
private:
bool KeyIsDown[KEY_KEY_CODES_COUNT];
};
struct MyBullet
{
IAnimatedMeshSceneNode* nodeBullet;
bool hasHit;
bool isValid;
};
// Simple collision functions
bool isCollisionA(ISceneNode* one, ISceneNode* two, int size)
{
return( one->getAbsolutePosition().getDistanceFrom(two->getAbsolutePosition()) < size );
}
bool isCollisionB(ISceneNode* one, ISceneNode* two)
{
return ( one->getTransformedBoundingBox().intersectsWithBox( two->getTransformedBoundingBox() ) );
}
// entry point of program
s32 main()
{
// init randomizer
srand(unsigned(time(0)));
// start Irrlicht
MyEventReceiver receiver;
IrrlichtDevice* device = createDevice(
EDT_DIRECT3D9, dimension2d<s32>(800,600),32,0,0,0,&receiver);
IVideoDriver* driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();
IGUIEnvironment* guienv = device->getGUIEnvironment();
device->getCursorControl()->setVisible(false); // no mouse cursor
// "Skybox" six times "black sky with some stars" (512*512 pixel)
ISceneNode* SkyBox = smgr->addSkyBoxSceneNode (
driver->getTexture("../skybox/top.jpg" ),
driver->getTexture("../skybox/bottom.jpg" ),
driver->getTexture("../skybox/front.jpg" ),
driver->getTexture("../skybox/back.jpg" ),
driver->getTexture("../skybox/right.jpg" ),
driver->getTexture("../skybox/left.jpg" ));
// Intro - Background Music - Camera
IGUIImage* img =
guienv->addImage( driver->getTexture("../media/uglyface_starterImage.jpg"), position2d<int>(30,30));
irrklang::ISound* snd = (irrklang::createIrrKlangDevice())->play2D(
"../media/IrrlichtTheme.ogg", true, false, true);
//IrrlichtTheme.ogg comes with Irrlicht Engine
if(snd) { snd->setVolume(0.2f); snd->drop(); }
ICameraSceneNode* cam = smgr->addCameraSceneNode(0, vector3df(0,1000,0), vector3df(0,0,0));
// SpaceShip //http://www.turbosquid.com/FullPreview/Index.cfm/ID/261430 (free)
const vector3df STARTPOSSPACESHIP = vector3df(-200,0,0);
const vector3df RESETPOSSPACESHIP = vector3df(-600,0,0);
const s32 MAXSHOOTS_PER_SEC = 10;
f32 velocitySpaceship = 2250.0;
// Texture
SMaterial matSpaceShip;
matSpaceShip.setTexture(0, driver->getTexture("../media/orange.jpg"));
matSpaceShip.Lighting = false;
// Mesh
IAnimatedMeshSceneNode* nodeSpaceShip;
IAnimatedMesh* meshSpaceShip = smgr->getMesh("../media/spaceship.3ds");
if (meshSpaceShip){
nodeSpaceShip = smgr->addAnimatedMeshSceneNode(meshSpaceShip);
nodeSpaceShip->setPosition(STARTPOSSPACESHIP);
nodeSpaceShip->getMaterial(0) = matSpaceShip;
nodeSpaceShip->setMaterialFlag(EMF_LIGHTING, false);
}
// Enemies
const vector3df STARTPOSENEMY = vector3df( 700,0, 800);
const vector3df ENDPOSENEMY = vector3df(-600,0,-800);
// Texture
SMaterial matEnemy;
matEnemy.setTexture(0, driver->getTexture("../media/orange.jpg"));// 512*512 pixel (orange color)
matEnemy.Lighting = false;
// Mesh
IAnimatedMeshSceneNode* nodeEnemy;
IAnimatedMesh* meshEnemy = smgr->getMesh("../media/vm21.3ds"); // really nice ;-)
//http://www.turbosquid.com/FullPreview/Index.cfm/ID/222232 (free)
if (meshEnemy){
nodeEnemy = smgr->addAnimatedMeshSceneNode(meshEnemy);
nodeEnemy->setPosition(STARTPOSENEMY);
nodeEnemy->getMaterial(0) = matEnemy;
nodeEnemy->setMaterialFlag(EMF_LIGHTING, false);
nodeEnemy->setScale(vector3df(20,20,20)); // x-,y-,z-scaling factors
nodeEnemy->setRotation(vector3df(0,90,30)); // rotate by ... degrees (x,y,z)
}
ISceneNodeAnimator* animFS = smgr->createFlyStraightAnimator(STARTPOSENEMY, ENDPOSENEMY, 2000, true);
if(animFS){
nodeEnemy->addAnimator(animFS); // move enemy
animFS->drop();
}
// Bullet
const s32 MAXSHOOTS = 2000;
MyBullet bullets[MAXSHOOTS];
for(int i=0; i<MAXSHOOTS; ++i)
{
bullets[i].hasHit = false;
bullets[i].nodeBullet = 0;
bullets[i].isValid=false;
}
// Game data
u32 t = 0; // time
s32 life = 10; // life of SpaceShip
s32 echelon = 1; // attack waves
s32 shoots = 0; // shoots of SpaceShip
s32 hits = 0; // enemies hit
s32 fps = 1500; // first value before exact measurement
s32 level = 0; // start image
/********************* "device->run()" with FPS and Info ********************/
while(device->run())
{
if( (life <= 0) || (shoots > MAXSHOOTS) ) break;
if(device->isWindowActive())
{
f32 delta = velocitySpaceship/fps; // target 1.50
while(!level)
{
if( receiver.IsKeyDown(KEY_RETURN) )
{
level = 1; // first game level
img->setVisible(false);
}
drawScene(driver, smgr, guienv);
break; // It works, but why is it necessary???
}
// keys W A S D pressed?
vector3df v = nodeSpaceShip->getAbsolutePosition();
if (receiver.IsKeyDown(KEY_UP)) {v.X += delta; }
if (receiver.IsKeyDown(KEY_DOWN)) {v.X -= delta; }
if (receiver.IsKeyDown(KEY_LEFT)) {v.Z += delta; }
if (receiver.IsKeyDown(KEY_RIGHT)){v.Z -= delta; }
if (receiver.IsKeyDown(KEY_KEY_T)){velocitySpaceship = 5000.0f; }
if (receiver.IsKeyDown(KEY_KEY_M)){velocitySpaceship = 2250.0f; }
if (receiver.IsKeyDown(KEY_KEY_B)){velocitySpaceship = 1500.0f; }
// check collision between bullets and enemies
for(int i=0; i<MAXSHOOTS; ++i)
{
if(bullets[i].nodeBullet && bullets[i].isValid && nodeEnemy)
{
if((bullets[i].nodeBullet->getAbsolutePosition().X) > 700) // upper border of window
{
ISceneNodeAnimator* animDel = smgr->createDeleteAnimator(1);
if(animDel)
{
bullets[i].nodeBullet->addAnimator(animDel); // delete bullet
bullets[i].isValid = false;
animDel->drop();
}
}
if(isCollisionB(bullets[i].nodeBullet,nodeEnemy) && (!bullets[i].hasHit))
{
bullets[i].hasHit = true;
bullets[i].nodeBullet->setVisible(false);
ISceneNodeAnimator* animDel = smgr->createDeleteAnimator(1);
if(animDel)
{
bullets[i].nodeBullet->addAnimator(animDel); // delete bullet
bullets[i].isValid = false;
animDel->drop();
}
++hits;
// Irrklang not free for comercial purpose!
snd = (irrklang::createIrrKlangDevice())->play3D("../media/muhaha.wav", v, false, false, true);
// http://download.dual-players.eu/cs/cstrike/sound/dualplayers/ (free?)
if(snd){ snd->setMinDistance(1000.0f); snd->setVolume(1.0f); snd->drop(); }
// fireball
IParticleSystemSceneNode* fireball;
fireball = smgr->addParticleSystemSceneNode(false);
fireball->setPosition( nodeEnemy->getAbsolutePosition() );
fireball->setScale(vector3df(20.0f,20.0f,20.0f));
fireball->setParticleSize(dimension2d<f32>(20.0f, 10.0f));
IParticleEmitter* em = fireball->createBoxEmitter(
aabbox3d<f32>(-70,0,-70,70,10,70),
vector3df(0.0f,0.6f,0.0f), 80, 100,
SColor(0,255,255,255),SColor(0,255,255,255), 800,2000);
fireball->setEmitter(em);
em->drop();
IParticleAffector* paf = fireball->createFadeOutParticleAffector();
fireball->addAffector(paf);
paf->drop();
fireball->setMaterialFlag(video::EMF_LIGHTING, false);
fireball->setMaterialTexture(0, driver->getTexture("../media/fireball.bmp"));
fireball->setMaterialType(video::EMT_TRANSPARENT_VERTEX_ALPHA);
}
}
}
// check collision between spaceship and enemies
if(isCollisionB(nodeSpaceShip,nodeEnemy))
{
v = RESETPOSSPACESHIP;
--life;
}
// SPACE pressed? SHOOT!
if (receiver.IsKeyDown(KEY_SPACE))
{
if (shoots > MAXSHOOTS)
break;
static clock_t last_t;
if( clock() > (last_t + CLOCKS_PER_SEC / MAXSHOOTS_PER_SEC) )
{
// Shoot sound
irrklang::ISound* snd = (irrklang::createIrrKlangDevice())->play3D(
"../media/impact.wav", v, false, false, true);
// impact.wav comes with Irrlicht Engine
if (snd)
{
snd->setMinDistance(1000.0f);
snd->setVolume(1.0f);
snd->drop();
}
last_t = clock();
// bullet
IAnimatedMeshSceneNode* bullet = 0;
IAnimatedMesh* meshBullet = smgr->getMesh("../media/sphere.3ds");
if (meshBullet)
{
bullet = smgr->addAnimatedMeshSceneNode(meshBullet);
bullet->setPosition(v);
bullet->getMaterial(0) = matSpaceShip;
bullet->setMaterialFlag(EMF_LIGHTING, false);
}
bullet->setScale(vector3df( 1.0f, 0.3f, 0.3f ));
ISceneNodeAnimator* animFS = smgr->createFlyStraightAnimator(
v,vector3df(1000,v.Y,v.Z), 500, false);
if(animFS)
{
bullet->addAnimator(animFS); // move bullet
animFS->drop();
}
bullets[shoots].nodeBullet = bullet;
bullets[shoots].isValid = true;
++shoots;
}//if
}//if
// borders for moving SpaceShip
if(v.X> 100)v.X= 100;
if(v.X< -600)v.X= -600;
if(v.Z> 900)v.Z= 900;
if(v.Z< -900)v.Z= -900;
// define position
nodeSpaceShip->setPosition(v);
// draw scene
drawScene(driver, smgr, guienv);
// deliver information in window caption
fps = driver->getFPS();
stringw str = L"HenkesSoft \"MUHAHA Code1\" FPS: ";
str += fps;
str += L" Wave: ";
str += echelon;
str += L" Shoots: ";
str += shoots;
str += L" Hits: ";
str += hits;
str += L" Life: ";
str += life;
device->setWindowCaption(str.c_str());
if( (life <= 0) || (shoots > MAXSHOOTS) )
break;
}//if
}//while
device->drop(); // delete object
cout << "GAME OVER - Press ENTER (twice), please. Thank you for playing this game." << endl;
wait(); // windows console specialty ;-)
}//main

