yesterday I try to make my first pong.
By the way i found some problem and I think that the way I construct the game is completely wrong
![Laughing :lol:](./images/smilies/icon_lol.gif)
First of all I was not able to do it in 2D O_o
How is it possible to create a 2D node? Because I have seen a lot of 3d examples and tutorial and I have understood the way of managing 3d nodes, but what about 2d?
So I decided to make it using the 3D functions of the library. So first I create 2 bars, 1 ball, and other 2 supplementary bars that represent the upper limit and the down limit of the game
The ball can only move following some simple directions.
In the main loop I simply update the position of the ball by taking his position and updating it according to the current direction. I feel that it is very cpu consuming...
thank you for your comments
![Smile :)](./images/smilies/icon_smile.gif)
These are the functions needed to catch user input, detect a collision, to change the direction of the ball, to move the bars
Code: Select all
#include <irrlicht.h>
#include <iostream>
using namespace irr;
#pragma comment(lib, "Irrlicht.lib")
#define VELOCITA 0.01
#define UPLIMIT 30
#define DOWNLIMIT -30
//
class MyEventReceiver: public IEventReceiver {
public:
// This is the one method that we have to implement
virtual bool OnEvent(const SEvent& event) {
// Remember whether each key is down or up
if (event.EventType == irr::EET_KEY_INPUT_EVENT)
KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
return false;
}
// This is used to check whether a key is being held down
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:
// We use this array to store the current state of each key
bool KeyIsDown[KEY_KEY_CODES_COUNT];
};
//detect collision of two general nodes
bool collisiondetection(scene::ISceneNode * n1, scene::ISceneNode * n2) {
core::aabbox3d<f32> box1 = n1->getTransformedBoundingBox();
core::aabbox3d<f32> box2 = n2->getTransformedBoundingBox();
if (box1.intersectsWithBox(box2)) {
return true;
} else
return false;
}
//Move the bars on user input
void muovibarre(scene::ISceneNode * p1, scene::ISceneNode * p2,
MyEventReceiver receiver) {
core::vector3df poscorr = p1->getPosition();
if (receiver.IsKeyDown(irr::KEY_KEY_W) && poscorr.Y < UPLIMIT) {
//printf("key pressed W");
poscorr.Y = poscorr.Y + VELOCITA;
p1->setPosition(poscorr);
} else if (receiver.IsKeyDown(irr::KEY_KEY_S) && poscorr.Y > DOWNLIMIT) {
//printf("key pressed S");
poscorr.Y = poscorr.Y - VELOCITA;
p1->setPosition(poscorr);
}
core::vector3df poscorr2 = p2->getPosition();
if (receiver.IsKeyDown(irr::KEY_KEY_O) && poscorr2.Y < UPLIMIT) {
//printf("key pressed W");
poscorr2.Y = poscorr2.Y + VELOCITA;
p2->setPosition(poscorr2);
} else if (receiver.IsKeyDown(irr::KEY_KEY_L) && poscorr2.Y > DOWNLIMIT) {
//printf("key pressed S");
poscorr2.Y = poscorr2.Y - VELOCITA;
p2->setPosition(poscorr2);
}
}
//Move the ball according to the current direction
void muovipallino(scene::ISceneNode * node, float coeff, int dir) {
//1 vado verso destra
//2 vado verso sinistra
//remind: <-----x
// ^
// |
// |
// y
core::vector3df posizione;
if (dir == 1) {
posizione = node->getPosition();
posizione.X = posizione.X - VELOCITA;
if (coeff == 1)
posizione.Y = posizione.Y + VELOCITA;
else if (coeff == -1)
posizione.Y = posizione.Y - VELOCITA;
node->setPosition(posizione);
} else {
posizione = node->getPosition();
posizione.X = posizione.X + VELOCITA;
if (coeff == 1)
posizione.Y = posizione.Y + VELOCITA;
else if (coeff == -1)
posizione.Y = posizione.Y - VELOCITA;
node->setPosition(posizione);
}
}
//Update the direction of the ball after a collision
void collideandupdate(scene::ISceneNode * node, scene::ISceneNode * p1,
scene::ISceneNode * p2, scene::ISceneNode * uplimit,
scene::ISceneNode * downlimit, MyEventReceiver receiver, float* coeff,
int* dir) {
//Collisione con P1
if (collisiondetection(node, p1) && !(receiver.IsKeyDown(irr::KEY_KEY_W)
|| receiver.IsKeyDown(irr::KEY_KEY_S))) {
*dir = 1;
}
if (collisiondetection(node, p1) && receiver.IsKeyDown(irr::KEY_KEY_W)) {
*dir = 1;
*coeff = -1;
}
if (collisiondetection(node, p1) && receiver.IsKeyDown(irr::KEY_KEY_S)) {
*dir = 1;
*coeff = 1;
}
//Collisione con P2
if (collisiondetection(node, p2) && !(receiver.IsKeyDown(irr::KEY_KEY_O)
|| receiver.IsKeyDown(irr::KEY_KEY_L))) {
*dir = 0;
}
if (collisiondetection(node, p2) && receiver.IsKeyDown(irr::KEY_KEY_O)) {
*dir = 0;
*coeff = -1;
}
if (collisiondetection(node, p2) && receiver.IsKeyDown(irr::KEY_KEY_L)) {
*dir = 0;
*coeff = 1;
}
if (collisiondetection(node, uplimit)) {
*coeff = -1;
printf("collision uplimit");
}
if (collisiondetection(node, downlimit)) {
*coeff = 1;
printf("collision downlimit");
}
}
Code: Select all
int main() {
// let user select driver type
video::E_DRIVER_TYPE driverType = video::EDT_DIRECT3D9;
printf("Please select the driver you want for this example:\n"
" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"
" (d) Software Renderer\n (e) Burning's Software Renderer\n"
" (f) NullDevice\n (otherKey) exit\n\n");
char i;
std::cin >> i;
switch (i) {
case 'a':
driverType = video::EDT_DIRECT3D9;
break;
case 'b':
driverType = video::EDT_DIRECT3D8;
break;
case 'c':
driverType = video::EDT_OPENGL;
break;
case 'd':
driverType = video::EDT_SOFTWARE;
break;
case 'e':
driverType = video::EDT_BURNINGSVIDEO;
break;
case 'f':
driverType = video::EDT_NULL;
break;
default:
return 0;
}
// create device
MyEventReceiver receiver;
IrrlichtDevice* device = createDevice(driverType, core::dimension2d<s32>(
420, 300), 16, false, false, false, &receiver);
if (device == 0)
return 1; // could not create selected driver.
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
scene::ISceneNode * node = smgr->addSphereSceneNode();
if (node) {
node->setPosition(core::vector3df(0, 0, 1));
node->setScale(core::vector3df(0.3, 0.3, 0.3));
//node->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp"));
node->setMaterialFlag(video::EMF_LIGHTING, false);
}
scene::ISceneNode * p1 = smgr->addCubeSceneNode();
if (p1) {
p1->setPosition(core::vector3df(48, 0, 1));
p1->setScale(core::vector3df(0.1, 1, 0.1));
//p1->setMaterialTexture(0, driver->getTexture("../../media/t351sml.jpg"));
p1->setMaterialFlag(video::EMF_LIGHTING, false);
}
scene::ISceneNode * p2 = smgr->addCubeSceneNode();
if (p2) {
p2->setPosition(core::vector3df(-48, 0, 1));
p2->setScale(core::vector3df(0.1, 1, 0.1));
//p2->setMaterialTexture(0, driver->getTexture("../../media/t351sml.jpg"));
p2->setMaterialFlag(video::EMF_LIGHTING, false);
}
scene::ISceneNode * uplimit = smgr->addCubeSceneNode();
scene::ISceneNode * downlimit = smgr->addCubeSceneNode();
if (uplimit) {
uplimit->setPosition(core::vector3df(0, 35, 1));
uplimit->setScale(core::vector3df(10, 0.1, 0.1));
//uplimit->setMaterialTexture(0, driver->getTexture("../../media/t351sml.jpg"));
uplimit->setMaterialFlag(video::EMF_LIGHTING, false);
}
if (downlimit) {
downlimit->setPosition(core::vector3df(0, -35, 1));
downlimit->setScale(core::vector3df(10, 0.1, 0.1));
//downlimit->setMaterialTexture(0, driver->getTexture("../../media/t351sml.jpg"));
downlimit->setMaterialFlag(video::EMF_LIGHTING, false);
}
video::ITexture* images = driver->getTexture("../../media/pong.bmp");
scene::ICameraSceneNode * cam = smgr->addCameraSceneNode(0,
core::vector3df(0, 0, 50), core::vector3df(0, 0, 0), 1);
float coeff = 0;
int dir = 1;
while (device->run()) {
driver->beginScene(true, true, video::SColor(255, 113, 113, 133));
//draw background
driver->draw2DImage(images, core::position2d<s32>(0,0));
//Verify if there is a collision
collideandupdate(node, p1, p2, uplimit, downlimit, receiver, &coeff,
&dir);
//Move the ball
muovipallino(node, coeff, dir);
//Move the bars
muovibarre(p1, p2, receiver);
smgr->drawAll(); // draw the 3d scene
driver->endScene();
}
/*
In the end, delete the Irrlicht device.
*/
device->drop();
return 0;
}