Newyears challenge 2006/2007
Newyears challenge 2006/2007
Ladies(?) and gentlemen!
Please consider participating in the newyears challenge 2006/2007, details below:
Materials mandatory:
*Irrlicht (or any version or fork of irrlicht, including irr-spintz and such)
Materials optional:
*Anything you can get your hands on (and redistribute) without violating copyrights or licences
Concept:
an implementation of the classic Space-Invaders
For those of us(like kornerr) who dont know what space-invaders is:
http://en.wikipedia.org/wiki/Space_invaders
Participation in this challenge is mandatory for some people(like kornerr)
Prizes to be announced later
Deadline: end of January
good luck!
Please consider participating in the newyears challenge 2006/2007, details below:
Materials mandatory:
*Irrlicht (or any version or fork of irrlicht, including irr-spintz and such)
Materials optional:
*Anything you can get your hands on (and redistribute) without violating copyrights or licences
Concept:
an implementation of the classic Space-Invaders
For those of us(like kornerr) who dont know what space-invaders is:
http://en.wikipedia.org/wiki/Space_invaders
Participation in this challenge is mandatory for some people(like kornerr)
Prizes to be announced later
Deadline: end of January
good luck!
if you're looking for me, start looking on irc, i'm probably there.
I just couldn't resist, SpaceInvaders is too much fun ;-)
Just copy the code in a main.cpp and use one of the example makefiles, that should work (i hope so). This implementation ain't great - but it's playable. You're also free to enter the challenge with a modified (and hopfully improved) version of that code (it's quite unlikely that i'd find another evening to spend on this). I'd like to see that and hope your implementations will rock mine away :-)
Just copy the code in a main.cpp and use one of the example makefiles, that should work (i hope so). This implementation ain't great - but it's playable. You're also free to enter the challenge with a modified (and hopfully improved) version of that code (it's quite unlikely that i'd find another evening to spend on this). I'd like to see that and hope your implementations will rock mine away :-)
Code: Select all
// Written by Michael Zeilfelder (aka CuteAlien)
// This software is using the zlib license
#include <irrlicht.h>
#include <iostream>
#ifdef __GNUWIN32__
#undef swprintf
#define swprintf _snwprintf
#endif // __GNUWIN32__
using namespace irr;
const s32 INVADER_ROWS = 16;
const s32 INVADER_LINES = 5;
const s32 MAX_SHOTS_INVADERS = 3;
const s32 MAX_SHOTS_PLAYER = 3;
const float ROOM_RADIUS = 1200.f;
const float ROOM_BOTTOM = -800.f;
const float UPPER_LINE = 300.f;
const float LINE_OFFSET = 120.f;
const float LEFT_ROW = -900.f;
const float ROW_OFFSET = 120.f;
video::IVideoDriver* driver = 0;
scene::ISceneManager* sceneManager = 0;
gui::IGUIEnvironment* env = 0;
// The floor is drawn by a number of vertices. Those are extruded in direction of extrude_.
// Will work *only* for convex base areas
scene::SMeshBuffer* CreateExtrudedPolyLineMeshBuffer(s32 numVertices_, const core::vector3df * vertices_, const core::vector3df &extrude_)
{
if ( numVertices_ < 3 || !vertices_ )
return NULL;
video::SMaterial material;
material.DiffuseColor = video::SColor(200, 255, 200, 255);
material.AmbientColor = video::SColor(255, 255, 255, 255);
material.EmissiveColor = video::SColor(255, 255, 255, 255);
material.MaterialType = video::EMT_SOLID;
material.Lighting = true;
material.BackfaceCulling = false;
// material.Wireframe = true; // hm, can't decide if it's nicer with or without wireframe :)
scene::SMeshBuffer * buffer = new scene::SMeshBuffer();
buffer->Material = material;
// sides
for ( s32 i=0; i<numVertices_; ++i)
{
video::S3DVertex v;
v.Pos = vertices_[i];
buffer->Vertices.push_back(v);
v.Pos = vertices_[i] + extrude_;
buffer->Vertices.push_back(v);
buffer->Indices.push_back( ((i+1)*2+1) % (numVertices_*2) );
buffer->Indices.push_back( ((i+1)*2) % (numVertices_*2) );
buffer->Indices.push_back(i*2);
buffer->Indices.push_back(i*2);
buffer->Indices.push_back(i*2+1);
buffer->Indices.push_back( ((i+1)*2+1) % (numVertices_*2) );
}
for ( s32 i=1; i<numVertices_-1; ++i)
{
buffer->Indices.push_back(0);
buffer->Indices.push_back(i*2);
buffer->Indices.push_back(i*2+2);
buffer->Indices.push_back(i*2+3);
buffer->Indices.push_back(i*2+1);
buffer->Indices.push_back(1);
}
// scene::IMeshManipulator * mm = mSceneManager->getMeshManipulator();
// mm->recalculateNormals(buffer);
buffer->recalculateBoundingBox();
return buffer;
}
scene::SMeshBuffer* CreateShipMeshBuffer()
{
float depth = 30;
core::vector3df vertices[8];
vertices[0].set(-50, 0.f, -depth);
vertices[1].set(50, 0.f, -depth);
vertices[2].set(50, 15, -depth);
vertices[3].set(20, 20, -depth);
vertices[4].set(5, 30, -depth);
vertices[5].set(-5, 30, -depth);
vertices[6].set(-20, 20, -depth);
vertices[7].set(-50, 15, -depth);
return CreateExtrudedPolyLineMeshBuffer(8, vertices, core::vector3df(0, 0, depth));
}
scene::SMeshBuffer* CreateAlienMeshBuffer()
{
float depth = 30;
core::vector3df vertices[5];
vertices[0].set(0, 0.f, -depth);
vertices[1].set(-50, 30.f, -depth);
vertices[2].set(-30, 50, -depth);
vertices[3].set(30, 50, -depth);
vertices[4].set(50, 30, -depth);
return CreateExtrudedPolyLineMeshBuffer(5, vertices, core::vector3df(0, 0, depth));
}
scene::SMeshBuffer* CreateShotMeshBuffer()
{
float depth = 10;
core::vector3df vertices[4];
vertices[0].set(-10, 0.f, -depth);
vertices[1].set(10, 0, -depth);
vertices[2].set(10, 10, -depth);
vertices[3].set(-10, 10, -depth);
return CreateExtrudedPolyLineMeshBuffer(4, vertices, core::vector3df(0, 0, depth));
}
struct Invaders
{
Invaders();
scene::ISceneNode * mModel;
};
Invaders::Invaders()
{
mModel = NULL;
}
struct Controller
{
Controller();
void Reset();
s32 mMove;
s32 mShoot;
};
Controller::Controller()
{
Reset();
}
void Controller::Reset()
{
mMove = 0;
mShoot = 0;
}
struct Player
{
Player();
s32 mLives;
s32 mScore;
scene::ISceneNode * mModel;
};
Player::Player()
{
mLives = 0;
mScore = 0;
mModel = 0;
}
struct Shot
{
Shot();
scene::ISceneNode *mModel;
};
Shot::Shot()
{
mModel = 0;
}
enum GameMode
{
GM_MAINSCREEN,
GM_RUNNING,
};
struct Game
{
Game();
void CreateMeshes();
void CreateModels();
void UpdateRunning(u32 time_);
void StartGame();
void SpawnInvaders();
bool ShootPlayer( const core::vector3df &pos_ );
bool ShootInvader( const core::vector3df &pos_ );
bool mQuitGame;
GameMode mGameMode;
s32 mLevel;
s32 mInvaderMoveDir;
s32 mInvadersLiving;
s32 mCountPlayerShots;
Invaders mInvaders[INVADER_ROWS*INVADER_LINES];
Controller mController;
s32 mPain;
s32 mNoStartTime;
Player mPlayer;
Shot mShotsInvaders[MAX_SHOTS_INVADERS];
Shot mShotsPlayer[MAX_SHOTS_PLAYER];
scene::SMesh * mMeshShip;
scene::SMesh * mMeshAlien;
scene::SMesh * mMeshShot;
};
Game::Game()
{
mQuitGame = false;
mGameMode = GM_MAINSCREEN;
mMeshShip = NULL;
mMeshAlien = NULL;
mCountPlayerShots = 0;
mPain = 0;
mNoStartTime = 0;
}
void Game::CreateMeshes()
{
scene::SMeshBuffer * meshBuffer = CreateShipMeshBuffer();
mMeshShip = new scene::SMesh();
mMeshShip->addMeshBuffer(meshBuffer);
meshBuffer = CreateAlienMeshBuffer();
mMeshAlien = new scene::SMesh();
mMeshAlien->addMeshBuffer(meshBuffer);
meshBuffer = CreateShotMeshBuffer();
mMeshShot = new scene::SMesh();
mMeshShot->addMeshBuffer(meshBuffer);
}
void Game::CreateModels()
{
mPlayer.mModel = sceneManager->addMeshSceneNode( mMeshShip );
mPlayer.mModel->setPosition( core::vector3df( 0, ROOM_BOTTOM, 0 ) );
mPlayer.mModel->setVisible(true);
for ( s32 y = 0; y < INVADER_LINES; ++y )
{
for ( s32 x = 0; x < INVADER_ROWS; ++ x)
{
mInvaders[y*INVADER_ROWS+x].mModel = sceneManager->addMeshSceneNode( mMeshAlien);
mInvaders[y*INVADER_ROWS+x].mModel->setVisible(false);
}
}
for ( s32 i=0; i<MAX_SHOTS_INVADERS; ++i )
{
mShotsInvaders[i].mModel = sceneManager->addMeshSceneNode( mMeshShot );
mShotsInvaders[i].mModel->setVisible(false);
}
for ( s32 i=0; i<MAX_SHOTS_PLAYER; ++i )
{
mShotsPlayer[i].mModel = sceneManager->addMeshSceneNode( mMeshShot );
mShotsPlayer[i].mModel->setVisible(false);
}
}
void Game::StartGame()
{
mLevel = 0;
mInvaderMoveDir = 1;
mGameMode = GM_RUNNING;
mPlayer.mScore = 0;
mPlayer.mLives = 3;
SpawnInvaders();
}
void Game::SpawnInvaders()
{
mInvadersLiving = INVADER_LINES*INVADER_ROWS;
for ( s32 y = 0; y < INVADER_LINES; ++y )
{
for ( s32 x = 0; x < INVADER_ROWS; ++ x)
{
mInvaders[y*INVADER_ROWS+x].mModel->setPosition( core::vector3df( LEFT_ROW + x*ROW_OFFSET, UPPER_LINE+y*LINE_OFFSET, 0 ) );
mInvaders[y*INVADER_ROWS+x].mModel->setVisible(true);
}
}
}
bool Game::ShootPlayer( const core::vector3df &pos_ )
{
for ( s32 i=0; i < MAX_SHOTS_PLAYER; ++i )
{
if ( !mShotsPlayer[i].mModel->isVisible() )
{
mShotsPlayer[i].mModel->setPosition( pos_ + core::vector3df(0, 10, 0) );
mShotsPlayer[i].mModel->setVisible(true);
return true;
}
}
return false;
}
bool Game::ShootInvader( const core::vector3df &pos_ )
{
for ( s32 i=0; i < MAX_SHOTS_INVADERS; ++i )
{
if ( !mShotsInvaders[i].mModel->isVisible() )
{
mShotsInvaders[i].mModel->setPosition( pos_ + core::vector3df(0, -10, 0) );
mShotsInvaders[i].mModel->setVisible(true);
return true;
}
}
return false;
}
void Game::UpdateRunning(u32 time_)
{
float movePlayer = (float)time_* 1.f;
if ( mController.mMove > 0 )
{
if ( mPlayer.mModel->getPosition().X <= ROOM_RADIUS )
mPlayer.mModel->setPosition( mPlayer.mModel->getPosition() + core::vector3df(movePlayer, 0, 0) );
}
else if ( mController.mMove < 0 )
{
if ( mPlayer.mModel->getPosition().X >= -ROOM_RADIUS )
mPlayer.mModel->setPosition( mPlayer.mModel->getPosition() + core::vector3df(-movePlayer, 0, 0) );
}
if ( mController.mShoot )
{
++mCountPlayerShots;
ShootPlayer( mPlayer.mModel->getPosition() );
for ( s32 i=0; i < MAX_SHOTS_PLAYER; ++i )
{
if ( !mShotsPlayer[i].mModel->isVisible() )
{
mShotsPlayer[i].mModel->setPosition( mPlayer.mModel->getPosition() + core::vector3df(0, 10, 0) );
mShotsPlayer[i].mModel->setVisible(true);
break;
}
}
mController.mShoot = 0;
}
bool invadersHitFloor = false;
float speedInvader = 0.1f + (float)(INVADER_ROWS*INVADER_LINES-mInvadersLiving)*0.005 + (float)mLevel*0.01;
float moveInvader = (float)time_* speedInvader;
moveInvader *= mInvaderMoveDir;
bool flipDir = false;
for ( s32 i=0; i < INVADER_ROWS*INVADER_LINES; ++i )
{
if ( mInvaders[i].mModel->isVisible() )
{
mInvaders[i].mModel->setPosition( mInvaders[i].mModel->getPosition() + core::vector3df(moveInvader, 0, 0) );
if ( mInvaders[i].mModel->getPosition().X < -ROOM_RADIUS
|| mInvaders[i].mModel->getPosition().X > ROOM_RADIUS )
{
flipDir = true;
}
}
}
if ( flipDir )
{
mInvaderMoveDir *= -1;
moveInvader *= -1;
float moveDown = 50.f;
for ( s32 i=0; i < INVADER_ROWS*INVADER_LINES; ++i )
{
if ( mInvaders[i].mModel->isVisible() )
{
mInvaders[i].mModel->setPosition( mInvaders[i].mModel->getPosition() + core::vector3df(moveInvader, -moveDown, 0) );
if ( mInvaders[i].mModel->getPosition().Y < ROOM_BOTTOM )
{
invadersHitFloor = true;
}
}
}
}
static u32 urgeToShoot = 0;
urgeToShoot += time_;
if ( urgeToShoot > 3000 )
{
s32 row = mCountPlayerShots % INVADER_ROWS; // nearly random ;-)
for ( s32 y = INVADER_LINES-1; y >= 0; --y )
{
if ( mInvaders[y*INVADER_ROWS+row].mModel->isVisible() )
{
if ( ShootInvader( mInvaders[y*INVADER_ROWS+row].mModel->getPosition() ) )
{
urgeToShoot = 0;
break;
}
}
}
}
float moveShotPlayer = (float)time_ * 1.f;
for ( s32 i=0; i < MAX_SHOTS_PLAYER; ++i )
{
if ( mShotsPlayer[i].mModel->isVisible() )
{
mShotsPlayer[i].mModel->setPosition( mShotsPlayer[i].mModel->getPosition() + core::vector3df(0, moveShotPlayer, 0) );
if ( mShotsPlayer[i].mModel->getPosition().Y > ROOM_RADIUS )
{
mShotsPlayer[i].mModel->setVisible(false);
}
}
}
float moveShotInvader = (float)time_ * 1.f;
for ( s32 i=0; i < MAX_SHOTS_INVADERS; ++i )
{
if ( mShotsInvaders[i].mModel->isVisible() )
{
mShotsInvaders[i].mModel->setPosition( mShotsInvaders[i].mModel->getPosition() + core::vector3df(0, -moveShotInvader, 0) );
if ( mShotsInvaders[i].mModel->getPosition().Y < -ROOM_RADIUS )
{
mShotsInvaders[i].mModel->setVisible(false);
}
}
}
const float HIT_DIST = 3000.f;
// check collisions
for ( s32 i=0; i < MAX_SHOTS_PLAYER; ++i )
{
if ( mShotsPlayer[i].mModel->isVisible() )
{
for ( s32 a=0; a < INVADER_ROWS*INVADER_LINES; ++a )
{
if ( mInvaders[a].mModel->isVisible() )
{
if ( (mShotsPlayer[i].mModel->getPosition()-mInvaders[a].mModel->getPosition()).getLengthSQ() < HIT_DIST )
{
mShotsPlayer[i].mModel->setVisible(false);
mInvaders[a].mModel->setVisible(false);
--mInvadersLiving;
++mPlayer.mScore;
}
}
}
}
}
for ( s32 i=0; i < MAX_SHOTS_INVADERS; ++i )
{
if ( mShotsInvaders[i].mModel->isVisible() )
{
if ( (mShotsInvaders[i].mModel->getPosition()-mPlayer.mModel->getPosition()).getLengthSQ() < HIT_DIST )
{
--mPlayer.mLives;
mShotsInvaders[i].mModel->setVisible(false);
mPain = 500;
}
}
}
if ( mPlayer.mLives <= 0 || invadersHitFloor )
{
mGameMode = GM_MAINSCREEN;
mNoStartTime = 3000;
}
if ( !mInvadersLiving )
{
++mLevel;
SpawnInvaders();
}
}
// another global...
Game GAME;
class MyEventReceiver : public IEventReceiver
{
public:
virtual bool OnEvent(SEvent event)
{
// allow leaving program with ESC (otherwise fullscreentests suck)
if ( event.EventType == irr::EET_KEY_INPUT_EVENT
&& !event.KeyInput.PressedDown
&& event.KeyInput.Key == KEY_ESCAPE )
GAME.mQuitGame = true;
if ( event.EventType == irr::EET_KEY_INPUT_EVENT )
{
switch ( event.KeyInput.Key )
{
case KEY_SPACE:
if ( event.KeyInput.PressedDown )
{
if ( GAME.mGameMode == GM_MAINSCREEN )
{
if ( GAME.mNoStartTime <= 0 ) // prevent accidential restart (shoot and restart use same keys)
{
GAME.StartGame();
}
}
else
GAME.mController.mShoot = 1;
}
break;
case KEY_LEFT:
if ( event.KeyInput.PressedDown )
GAME.mController.mMove = -1;
else
GAME.mController.mMove = 0;
break;
case KEY_RIGHT:
if ( event.KeyInput.PressedDown )
GAME.mController.mMove = 1;
else
GAME.mController.mMove = 0;
break;
}
}
return false;
}
};
int main()
{
MyEventReceiver receiver;
IrrlichtDevice *device = createDevice(video::EDT_OPENGL,
core::dimension2d<s32>(800, 600), 16, true, false, false, &receiver);
if (device == 0)
return 1; // could not create selected driver.
driver = device->getVideoDriver();
sceneManager = device->getSceneManager();
env = device->getGUIEnvironment();
driver->setAmbientLight(video::SColor(255,255,255,255));
GAME.CreateMeshes();
GAME.CreateModels();
scene::ICameraSceneNode* cam = sceneManager->addCameraSceneNode();
cam->setPosition( core::vector3df( 0, 0, -1500 ) );
cam->setTarget( core::vector3df( 0, 0, 0 ) );
sceneManager->setActiveCamera(cam);
gui::IGUIStaticText * staticScore = env->addStaticText(L"SCORE: ", core::rect<s32>(35,35,240,50) );
gui::IGUIStaticText * staticLives = env->addStaticText(L"LIVES: ", core::rect<s32>(35,65,240,80) );
gui::IGUIStaticText * staticStart = env->addStaticText(L"PRESS SPACE TO START", core::rect<s32>(135,165,340,180) );
while(device->run() && driver && !GAME.mQuitGame)
{
if (device->isWindowActive())
{
static u32 oldTime = device->getTimer()->getRealTime();
u32 newTime = device->getTimer()->getRealTime();
u32 timeDiff = newTime - oldTime;
oldTime = newTime;
if ( GAME.mNoStartTime > 0 )
{
GAME.mNoStartTime -= timeDiff;
}
if ( GAME.mPain > 0 )
{
driver->beginScene(true, true, video::SColor(100,255,0,0));
GAME.mPain -= timeDiff;
}
else
{
driver->beginScene(true, true, video::SColor(100,100,100,100));
}
if ( GAME.mGameMode == GM_MAINSCREEN )
{
staticStart->setVisible(true); // bad: shouldn't be done each frame
}
else if ( GAME.mGameMode == GM_RUNNING )
{
staticStart->setVisible(false); // bad: shouldn't be done each frame
GAME.UpdateRunning(timeDiff);
}
sceneManager->drawAll();
wchar_t str[200];
swprintf( str, 200, L" SCORE: %d", GAME.mPlayer.mScore );
staticScore->setText( str );
swprintf( str, 200, L" LIVES: %d", GAME.mPlayer.mLives );
staticLives->setText( str );
env->drawAll();
driver->endScene();
}
}
device->drop();
return 0;
}
I will be participating. Prior to the release of my entry, I'm going to be releasing some really helpful classes for the other competitors- including a proper high score class.
Also, if anyone is interesting in joining me on my entry... I really don't have time to do proper billboard sprites / background models for the game; so if you are a artist interested in being part of this remake contest send me an email: webmaster A:T g0dsoft.com
@CuteAlien - Good work!
Also, if anyone is interesting in joining me on my entry... I really don't have time to do proper billboard sprites / background models for the game; so if you are a artist interested in being part of this remake contest send me an email: webmaster A:T g0dsoft.com
@CuteAlien - Good work!
Thats the first alpha of my entry.
Right now u can only move your ship around but i'm working on enemies and goodies right now
http://gdlib.net/index.php?name=Downloa ... ails&id=88
Right now u can only move your ship around but i'm working on enemies and goodies right now
http://gdlib.net/index.php?name=Downloa ... ails&id=88
We're programmers. Programmers are, in their hearts, architects, and the first thing they want to do when they get to a site is to bulldoze the place flat and build something grand. We're not excited by renovation:tinkering,improving,planting flower beds.
made a little update to it
http://gdlib.net/index.php?name=Downloa ... ails&id=88
http://gdlib.net/index.php?name=Downloa ... ails&id=88
We're programmers. Programmers are, in their hearts, architects, and the first thing they want to do when they get to a site is to bulldoze the place flat and build something grand. We're not excited by renovation:tinkering,improving,planting flower beds.
Well, was at work today and figured I'd throw something together. It's using IrrSpintz engine, so here's Windows exe with precompiled DLL.
( It's compiled using DX Dec 2004, so make sure you have at least that installed ).
http://irrlicht.spintz.com/spaceinvader ... vaders.zip
Some screenshots -
{EDIT} Im still doing more work on it, I whipped this together today in about 4 hours at work.
( It's compiled using DX Dec 2004, so make sure you have at least that installed ).
http://irrlicht.spintz.com/spaceinvader ... vaders.zip
Some screenshots -
{EDIT} Im still doing more work on it, I whipped this together today in about 4 hours at work.
Uploaded new version ::: http://irrlicht.spintz.com/spaceinvader ... vaders.zip
- It actually progresses through levels, and invaders move faster with each passing level.
- Shows high scores, saves high scores
- New SpaceShip graphic
- keeps tracks of hits/misses per round
- if you dont miss, its a perfect round and you get bonus points of 2000 * level
- if you miss less than 5 times, its a good round and get get bonus points of 500 * level
- if you miss, you lost 1 point
- invaders are worth more points as each level passes
- LeftArrow/Numpad4 - Move Left
- RightArrow/NumPad6 - Move Right
- Spacebar/NumPad0 - Fire
Heres a new version, as an installer, so just run installer and it will create icon on your desktop.
http://irrlicht.spintz.com/spaceinvader ... taller.msi
The aliens should be in the correct direction now. And I have my high score on their of 495,020. Best so far in my household!
http://irrlicht.spintz.com/spaceinvader ... taller.msi
The aliens should be in the correct direction now. And I have my high score on their of 495,020. Best so far in my household!