Windows Azure Cloud Storage ermöglicht es Ihnen bereits ab 0,10€ pro GB/Monat die Vorteile der Cloud zu nutzen.
Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.de  
   
Advanced Developers Conference     
Bücher-Shop mit Amazon (Buchkategorien)C++ : Referenzen zu C++ : C++ Builder : Visual C++ : C# : Java : Spieleprogrammierung : Systemprogrammierung Linux : Software-Entwicklung : .NET : Compilertechnik : Algorithmen & Datenstrukturen : Objektorientierung : Entwurfsmuster : UML : eXtreme Programming : Scrum : Projektmanagement : Software-Testing : Datenbanken : Tom DeMarco : Dilbert : User Friendly
C/C++ Forum :: Spiele-/Grafikprogrammierung ::  Pong ist das ideale Starter-Projekt  
Gehen Sie zu Seite 1, 2  Weiter
  Zeige alle Beiträge auf einer Seite
Auf Beitrag antworten
Autor Nachricht
Erhard Henkes
Mitglied

Benutzerprofil
Anmeldungsdatum: 25.04.2000
Beiträge: 11885
Beitrag Erhard Henkes Mitglied 09:16:13 07.09.2008   Titel:   Pong ist das ideale Starter-Projekt            Zitieren

Tetris ist für den Anfang komplexer als das klassische "Pong". Daher sollte man mit einem "Pong" beginnen und dort das Auflegen von texturen, die Einbindung einer AI, das Optimieren des Codes bezüglich Performance, das Umwandeln in echte OOP (Klasse Ball, Bar, Game, ...) usw. üben. Pong ist hierfür ein Idealfall.

Hier ein Beispiel für den Code mit "irrlicht" (Grafik Engine), den man als Ausgangspunkt für diese Übungen verwenden könnte:
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
// Pong.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
//

Von mir optimiert auf Basis:
http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=30191

#include
"stdafx.h"
#include
<irrlicht.h>
#include
<iostream>

// irrlicht namespace
using namespace irr; using namespace core; using namespace scene;
using namespace video; using namespace io; using namespace gui;

#pragma
comment(lib, "Irrlicht.lib")

const f32 VELOCITY  =  0.5f;
const s32 UPLIMIT   =    30;
const s32 DOWNLIMIT =   -30;
f32 velocity  =  VELOCITY;
s32 hits1 = 0;
s32 hits2 = 0;

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];
};

//detect collision
bool isCollision(ISceneNode* n1, ISceneNode* n2)
{
   aabbox3d<f32> box1 = n1->getTransformedBoundingBox();
   aabbox3d<f32> box2 = n2->getTransformedBoundingBox();

   if (box1.intersectsWithBox(box2))
      return true;
     else
      return false
;
}

//move the bars according to user input
void moveBar(ISceneNode* bar1, ISceneNode* bar2, const MyEventReceiver& receiver)
{
   const f32 SPEEDFACTOR = 2.0f;
     vector3df poscorr = bar1->getPosition();
   if (receiver.IsKeyDown(KEY_KEY_W) && poscorr.Y < UPLIMIT)
     {
      poscorr.Y = poscorr.Y + SPEEDFACTOR*velocity;
      bar1->setPosition(poscorr);
   }
     else if (receiver.IsKeyDown(KEY_KEY_S) && poscorr.Y > DOWNLIMIT)
     {
      poscorr.Y = poscorr.Y - SPEEDFACTOR*velocity;
      bar1->setPosition(poscorr);
   }

   vector3df poscorr2 = bar2->getPosition();
   if (receiver.IsKeyDown(KEY_KEY_O) && poscorr2.Y < UPLIMIT)
     {
      poscorr2.Y = poscorr2.Y + SPEEDFACTOR*velocity;
      bar2->setPosition(poscorr2);
   }
     else if (receiver.IsKeyDown(KEY_KEY_L) && poscorr2.Y > DOWNLIMIT)
     {
      poscorr2.Y = poscorr2.Y - SPEEDFACTOR*velocity;
      bar2->setPosition(poscorr2);
   }
}

//move the ball according to the current direction
void moveBall(ISceneNode* ball, float coeff, int dir)
{
   vector3df pos = ball->getPosition();
     if (dir == 1)
     {
      pos.X -= velocity;
      pos.Y += coeff*velocity;
     }
     else
     {
      pos.X += velocity;
      pos.Y += coeff*velocity;
     }
     
     if ( (pos.X < -50) || (pos.X > 50) )
   {
         if (pos.X < -50) ++hits1;
         if (pos.X >  50) ++hits2;
       pos.X = 0;
         dir   = -dir;
     }
     ball->setPosition(pos);
}

void updateDirectionAfterCollison(ISceneNode* ball, ISceneNode* bar1, ISceneNode* bar2, ISceneNode* uplimit,
  ISceneNode* downlimit, const MyEventReceiver& receiver, float* coeff, int* dir)
{
   //Collision with bar1
   if (isCollision(ball, bar1) && !(receiver.IsKeyDown(KEY_KEY_W) || receiver.IsKeyDown(KEY_KEY_S)))
     {
      *dir = 1;
   }
   if (isCollision(ball, bar1) && receiver.IsKeyDown(KEY_KEY_W))
     {
      *dir = 1;
      *coeff = -1;
   }
   if (isCollision(ball, bar1) && receiver.IsKeyDown(KEY_KEY_S))
     {
      *dir = 1;
      *coeff = 1;
   }

   //Collision with bar2
   if (isCollision(ball, bar2) && !(receiver.IsKeyDown(KEY_KEY_O)
         || receiver.IsKeyDown(KEY_KEY_L)))
     {
      *dir = 0;
   }
   if (isCollision(ball, bar2) && receiver.IsKeyDown(KEY_KEY_O))
     {
      *dir = 0;
      *coeff = -1;
   }
   if (isCollision(ball, bar2) && receiver.IsKeyDown(KEY_KEY_L))
     {
      *dir = 0;
      *coeff = 1;
   }

   if (isCollision(ball, uplimit))
     {
       *coeff = -1;
             std::cout << "collision uplimit"   << std::endl;
   }
   if (isCollision(ball, downlimit))
     {
       *coeff = 1;
       std::cout << "collision downlimit" << std::endl;
   }
}

int main()
{
   E_DRIVER_TYPE driverType = EDT_DIRECT3D9;

     std::cout << "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" << std::endl;

   char i;
   std::cin >> i;

   switch (i)
     {
         case 'a': driverType = EDT_DIRECT3D9;            break;
         case 'b': driverType = EDT_DIRECT3D8;            break;
         case 'c': driverType = EDT_OPENGL;                 break;
         case 'd': driverType = EDT_SOFTWARE;                break;
         case 'e': driverType = EDT_BURNINGSVIDEO;    break;
         case 'f': driverType = EDT_NULL;                   break;
         default:     return 0;
   }

   // create device
   MyEventReceiver receiver;

   IrrlichtDevice* device = createDevice(driverType, dimension2d<s32>(420, 300),
         16, false, false, true, &receiver);
   if (device == 0) return 1; // could not create selected driver.
   IVideoDriver* driver = device->getVideoDriver();
   ISceneManager* smgr  = device->getSceneManager();

   ISceneNode* ball = smgr->addSphereSceneNode();
   if (ball)
     {
      ball->setPosition(vector3df(0.0f, 0.0f, 1.0f));
      ball->setScale(vector3df(0.3f, 0.3f, 0.3f));
      ball->setMaterialFlag(EMF_LIGHTING, false);
   }

   ISceneNode* bar1 = smgr->addCubeSceneNode();
   if (bar1)
     {
      bar1->setPosition(vector3df(48.0f, 0.0f, 1.0f));
      bar1->setScale(vector3df(0.1f, 1.0f, 0.1f));
      bar1->setMaterialFlag(EMF_LIGHTING, false);
   }

   ISceneNode* bar2 = smgr->addCubeSceneNode();
   if (bar2)
     {
      bar2->setPosition(vector3df(-48.0f, 0.0f, 1.0f));
      bar2->setScale(vector3df(0.1f, 1.0f, 0.1f));
      bar2->setMaterialFlag(EMF_LIGHTING, false);
   }

   ISceneNode* uplimit   = smgr->addCubeSceneNode();
   ISceneNode* downlimit = smgr->addCubeSceneNode();

   if (uplimit)
     {
      uplimit->setPosition(vector3df(0.0f, 35.0f, 1.0f));
      uplimit->setScale(vector3df(10.0f, 0.1f, 0.1f));
      uplimit->setMaterialFlag(EMF_LIGHTING, false);
   }
   if (downlimit)
     {
      downlimit->setPosition(vector3df(0.0f, -35.0f, 1.0f));
      downlimit->setScale(vector3df(10.0f, 0.1f, 0.1f));
      downlimit->setMaterialFlag(EMF_LIGHTING, false);
   }

   ICameraSceneNode* cam = smgr->addCameraSceneNode(0, vector3df(0,0,50), vector3df(0,0,0), 1);

   float coeff = 0;
   int dir = 1;
   while (device->run())
     {
     driver->beginScene(true, true, SColor(255, 113, 113, 133));
                updateDirectionAfterCollison(ball, bar1, bar2, uplimit, downlimit, receiver, &coeff, &dir);
                moveBall(ball, coeff, dir);
                moveBar(bar1, bar2, receiver);
                smgr->drawAll(); // draw the 3d scene
     driver->endScene();

         s32 fps = driver->getFPS();
         stringw str = L"PONG   FPS: ";
         str += fps;
         str += L"   Left:  ";
         str += hits1;
         str += L"   Right: ";
         str += hits2;
         device->setWindowCaption(str.c_str());
   }
   device->drop();

   return 0;
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
// Pong.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
//

Von mir optimiert auf Basis:
http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=30191

#include
"stdafx.h"
#include
<irrlicht.h>
#include
<iostream>

// irrlicht namespace
using namespace irr; using namespace core; using namespace scene;
using namespace video; using namespace io; using namespace gui;

#pragma
comment(lib, "Irrlicht.lib")

const f32 VELOCITY = 0.5f;
const s32 UPLIMIT = 30;
const s32 DOWNLIMIT = -30;
f32 velocity = VELOCITY;
s32 hits1 = 0;
s32 hits2 = 0;

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];
};

//detect collision
bool isCollision(ISceneNode* n1, ISceneNode* n2)
{
aabbox3d<f32> box1 = n1->getTransformedBoundingBox();
aabbox3d<f32> box2 = n2->getTransformedBoundingBox();

if (box1.intersectsWithBox(box2))
return true;
else
return false
;
}

//move the bars according to user input
void moveBar(ISceneNode* bar1, ISceneNode* bar2, const MyEventReceiver& receiver)
{
const f32 SPEEDFACTOR = 2.0f;
vector3df poscorr = bar1->getPosition();
if (receiver.IsKeyDown(KEY_KEY_W) && poscorr.Y < UPLIMIT)
{
poscorr.Y = poscorr.Y + SPEEDFACTOR*velocity;
bar1->setPosition(poscorr);
}
else if (receiver.IsKeyDown(KEY_KEY_S) && poscorr.Y > DOWNLIMIT)
{
poscorr.Y = poscorr.Y - SPEEDFACTOR*velocity;
bar1->setPosition(poscorr);
}

vector3df poscorr2 = bar2->getPosition();
if (receiver.IsKeyDown(KEY_KEY_O) && poscorr2.Y < UPLIMIT)
{
poscorr2.Y = poscorr2.Y + SPEEDFACTOR*velocity;
bar2->setPosition(poscorr2);
}
else if (receiver.IsKeyDown(KEY_KEY_L) && poscorr2.Y > DOWNLIMIT)
{
poscorr2.Y = poscorr2.Y - SPEEDFACTOR*velocity;
bar2->setPosition(poscorr2);
}
}

//move the ball according to the current direction
void moveBall(ISceneNode* ball, float coeff, int dir)
{
vector3df pos = ball->getPosition();
if (dir == 1)
{
pos.X -= velocity;
pos.Y += coeff*velocity;
}
else
{
pos.X += velocity;
pos.Y += coeff*velocity;
}

if ( (pos.X < -50) || (pos.X > 50) )
{
if (pos.X < -50) ++hits1;
if (pos.X > 50) ++hits2;
pos.X = 0;
dir = -dir;
}
ball->setPosition(pos);
}

void updateDirectionAfterCollison(ISceneNode* ball, ISceneNode* bar1, ISceneNode* bar2, ISceneNode* uplimit,
ISceneNode* downlimit, const MyEventReceiver& receiver, float* coeff, int* dir)
{
//Collision with bar1
if (isCollision(ball, bar1) && !(receiver.IsKeyDown(KEY_KEY_W) || receiver.IsKeyDown(KEY_KEY_S)))
{
*dir = 1;
}
if (isCollision(ball, bar1) && receiver.IsKeyDown(KEY_KEY_W))
{
*dir = 1;
*coeff = -1;
}
if (isCollision(ball, bar1) && receiver.IsKeyDown(KEY_KEY_S))
{
*dir = 1;
*coeff = 1;
}

//Collision with bar2
if (isCollision(ball, bar2) && !(receiver.IsKeyDown(KEY_KEY_O)
|| receiver.IsKeyDown(KEY_KEY_L)))
{
*dir = 0;
}
if (isCollision(ball, bar2) && receiver.IsKeyDown(KEY_KEY_O))
{
*dir = 0;
*coeff = -1;
}
if (isCollision(ball, bar2) && receiver.IsKeyDown(KEY_KEY_L))
{
*dir = 0;
*coeff = 1;
}

if (isCollision(ball, uplimit))
{
*coeff = -1;
std::cout << "collision uplimit" << std::endl;
}
if (isCollision(ball, downlimit))
{
*coeff = 1;
std::cout << "collision downlimit" << std::endl;
}
}

int main()
{
E_DRIVER_TYPE driverType = EDT_DIRECT3D9;

std::cout << "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" << std::endl;

char i;
std::cin >> i;

switch (i)
{
case 'a': driverType = EDT_DIRECT3D9; break;
case 'b': driverType = EDT_DIRECT3D8; break;
case 'c': driverType = EDT_OPENGL; break;
case 'd': driverType = EDT_SOFTWARE; break;
case 'e': driverType = EDT_BURNINGSVIDEO; break;
case 'f': driverType = EDT_NULL; break;
default: return 0;
}

// create device
MyEventReceiver receiver;

IrrlichtDevice* device = createDevice(driverType, dimension2d<s32>(420, 300),
16, false, false, true, &receiver);
if (device == 0) return 1; // could not create selected driver.
IVideoDriver* driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();

ISceneNode* ball = smgr->addSphereSceneNode();
if (ball)
{
ball->setPosition(vector3df(0.0f, 0.0f, 1.0f));
ball->setScale(vector3df(0.3f, 0.3f, 0.3f));
ball->setMaterialFlag(EMF_LIGHTING, false);
}

ISceneNode* bar1 = smgr->addCubeSceneNode();
if (bar1)
{
bar1->setPosition(vector3df(48.0f, 0.0f, 1.0f));
bar1->setScale(vector3df(0.1f, 1.0f, 0.1f));
bar1->setMaterialFlag(EMF_LIGHTING, false);
}

ISceneNode* bar2 = smgr->addCubeSceneNode();
if (bar2)
{
bar2->setPosition(vector3df(-48.0f, 0.0f, 1.0f));
bar2->setScale(vector3df(0.1f, 1.0f, 0.1f));
bar2->setMaterialFlag(EMF_LIGHTING, false);
}

ISceneNode* uplimit = smgr->addCubeSceneNode();
ISceneNode* downlimit = smgr->addCubeSceneNode();

if (uplimit)
{
uplimit->setPosition(vector3df(0.0f, 35.0f, 1.0f));
uplimit->setScale(vector3df(10.0f, 0.1f, 0.1f));
uplimit->setMaterialFlag(EMF_LIGHTING, false);
}
if (downlimit)
{
downlimit->setPosition(vector3df(0.0f, -35.0f, 1.0f));
downlimit->setScale(vector3df(10.0f, 0.1f, 0.1f));
downlimit->setMaterialFlag(EMF_LIGHTING, false);
}

ICameraSceneNode* cam = smgr->addCameraSceneNode(0, vector3df(0,0,50), vector3df(0,0,0), 1);

float coeff = 0;
int dir = 1;
while (device->run())
{
driver->beginScene(true, true, SColor(255, 113, 113, 133));
updateDirectionAfterCollison(ball, bar1, bar2, uplimit, downlimit, receiver, &coeff, &dir);
moveBall(ball, coeff, dir);
moveBar(bar1, bar2, receiver);
smgr->drawAll(); // draw the 3d scene
driver->endScene();

s32 fps = driver->getFPS();
stringw str = L"PONG FPS: ";
str += fps;
str += L" Left: ";
str += hits1;
str += L" Right: ";
str += hits2;
device->setWindowCaption(str.c_str());
}
device->drop();

return 0;
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
// Pong.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
//

Von mir optimiert auf Basis:
http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=30191

#include
"stdafx.h"
#include
<irrlicht.h>
#include
<iostream>

// irrlicht namespace
using namespace irr; using namespace core; using namespace scene;
using namespace video; using namespace io; using namespace gui;

#pragma
comment(lib, "Irrlicht.lib")

const f32 VELOCITY  =  0.5f;
const s32 UPLIMIT   =    30;
const s32 DOWNLIMIT =   -30;
f32 velocity  =  VELOCITY;
s32 hits1 = 0;
s32 hits2 = 0;

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];
};

//detect collision
bool isCollision(ISceneNode* n1, ISceneNode* n2)
{
   aabbox3d<f32> box1 = n1->getTransformedBoundingBox();
   aabbox3d<f32> box2 = n2->getTransformedBoundingBox();

   if (box1.intersectsWithBox(box2))
      return true;
     else
      return false
;
}

//move the bars according to user input
void moveBar(ISceneNode* bar1, ISceneNode* bar2, const MyEventReceiver& receiver)
{
   const f32 SPEEDFACTOR = 2.0f;
     vector3df poscorr = bar1->getPosition();
   if (receiver.IsKeyDown(KEY_KEY_W) && poscorr.Y < UPLIMIT)
     {
      poscorr.Y = poscorr.Y + SPEEDFACTOR*velocity;
      bar1->setPosition(poscorr);
   }
     else if (receiver.IsKeyDown(KEY_KEY_S) && poscorr.Y > DOWNLIMIT)
     {
      poscorr.Y = poscorr.Y - SPEEDFACTOR*velocity;
      bar1->setPosition(poscorr);
   }

   vector3df poscorr2 = bar2->getPosition();
   if (receiver.IsKeyDown(KEY_KEY_O) && poscorr2.Y < UPLIMIT)
     {
      poscorr2.Y = poscorr2.Y + SPEEDFACTOR*velocity;
      bar2->setPosition(poscorr2);
   }
     else if (receiver.IsKeyDown(KEY_KEY_L) && poscorr2.Y > DOWNLIMIT)
     {
      poscorr2.Y = poscorr2.Y - SPEEDFACTOR*velocity;
      bar2->setPosition(poscorr2);
   }
}

//move the ball according to the current direction
void moveBall(ISceneNode* ball, float coeff, int dir)
{
   vector3df pos = ball->getPosition();
     if (dir == 1)
     {
      pos.X -= velocity;
      pos.Y += coeff*velocity;
     }
     else
     {
      pos.X += velocity;
      pos.Y += coeff*velocity;
     }
     
     if ( (pos.X < -50) || (pos.X > 50) )
   {
         if (pos.X < -50) ++hits1;
         if (pos.X >  50) ++hits2;
       pos.X = 0;
         dir   = -dir;
     }
     ball->setPosition(pos);
}

void updateDirectionAfterCollison(ISceneNode* ball, ISceneNode* bar1, ISceneNode* bar2, ISceneNode* uplimit,
  ISceneNode* downlimit, const MyEventReceiver& receiver, float* coeff, int* dir)
{
   //Collision with bar1
   if (isCollision(ball, bar1) && !(receiver.IsKeyDown(KEY_KEY_W) || receiver.IsKeyDown(KEY_KEY_S)))
     {
      *dir = 1;
   }
   if (isCollision(ball, bar1) && receiver.IsKeyDown(KEY_KEY_W))
     {
      *dir = 1;
      *coeff = -1;
   }
   if (isCollision(ball, bar1) && receiver.IsKeyDown(KEY_KEY_S))
     {
      *dir = 1;
      *coeff = 1;
   }

   //Collision with bar2
   if (isCollision(ball, bar2) && !(receiver.IsKeyDown(KEY_KEY_O)
         || receiver.IsKeyDown(KEY_KEY_L)))
     {
      *dir = 0;
   }
   if (isCollision(ball, bar2) && receiver.IsKeyDown(KEY_KEY_O))
     {
      *dir = 0;
      *coeff = -1;
   }
   if (isCollision(ball, bar2) && receiver.IsKeyDown(KEY_KEY_L))
     {
      *dir = 0;
      *coeff = 1;
   }

   if (isCollision(ball, uplimit))
     {
       *coeff = -1;
             std::cout << "collision uplimit"   << std::endl;
   }
   if (isCollision(ball, downlimit))
     {
       *coeff = 1;
       std::cout << "collision downlimit" << std::endl;
   }
}

int main()
{
   E_DRIVER_TYPE driverType = EDT_DIRECT3D9;

     std::cout << "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" << std::endl;

   char i;
   std::cin >> i;

   switch (i)
     {
         case 'a': driverType = EDT_DIRECT3D9;            break;
         case 'b': driverType = EDT_DIRECT3D8;            break;
         case 'c': driverType = EDT_OPENGL;                 break;
         case 'd': driverType = EDT_SOFTWARE;                break;
         case 'e': driverType = EDT_BURNINGSVIDEO;    break;
         case 'f': driverType = EDT_NULL;                   break;
         default:     return 0;
   }

   // create device
   MyEventReceiver receiver;

   IrrlichtDevice* device = createDevice(driverType, dimension2d<s32>(420, 300),
         16, false, false, true, &receiver);
   if (device == 0) return 1; // could not create selected driver.
   IVideoDriver* driver = device->getVideoDriver();
   ISceneManager* smgr  = device->getSceneManager();

   ISceneNode* ball = smgr->addSphereSceneNode();
   if (ball)
     {
      ball->setPosition(vector3df(0.0f, 0.0f, 1.0f));
      ball->setScale(vector3df(0.3f, 0.3f, 0.3f));
      ball->setMaterialFlag(EMF_LIGHTING, false);
   }

   ISceneNode* bar1 = smgr->addCubeSceneNode();
   if (bar1)
     {
      bar1->setPosition(vector3df(48.0f, 0.0f, 1.0f));
      bar1->setScale(vector3df(0.1f, 1.0f, 0.1f));
      bar1->setMaterialFlag(EMF_LIGHTING, false);
   }

   ISceneNode* bar2 = smgr->addCubeSceneNode();
   if (bar2)
     {
      bar2->setPosition(vector3df(-48.0f, 0.0f, 1.0f));
      bar2->setScale(vector3df(0.1f, 1.0f, 0.1f));
      bar2->setMaterialFlag(EMF_LIGHTING, false);
   }

   ISceneNode* uplimit   = smgr->addCubeSceneNode();
   ISceneNode* downlimit = smgr->addCubeSceneNode();

   if (uplimit)
     {
      uplimit->setPosition(vector3df(0.0f, 35.0f, 1.0f));
      uplimit->setScale(vector3df(10.0f, 0.1f, 0.1f));
      uplimit->setMaterialFlag(EMF_LIGHTING, false);
   }
   if (downlimit)
     {
      downlimit->setPosition(vector3df(0.0f, -35.0f, 1.0f));
      downlimit->setScale(vector3df(10.0f, 0.1f, 0.1f));
      downlimit->setMaterialFlag(EMF_LIGHTING, false);
   }

   ICameraSceneNode* cam = smgr->addCameraSceneNode(0, vector3df(0,0,50), vector3df(0,0,0), 1);

   float coeff = 0;
   int dir = 1;
   while (device->run())
     {
     driver->beginScene(true, true, SColor(255, 113, 113, 133));
                updateDirectionAfterCollison(ball, bar1, bar2, uplimit, downlimit, receiver, &coeff, &dir);
                moveBall(ball, coeff, dir);
                moveBar(bar1, bar2, receiver);
                smgr->drawAll(); // draw the 3d scene
     driver->endScene();

         s32 fps = driver->getFPS();
         stringw str = L"PONG   FPS: ";
         str += fps;
         str += L"   Left:  ";
         str += hits1;
         str += L"   Right: ";
         str += hits2;
         device->setWindowCaption(str.c_str());
   }
   device->drop();

   return 0;
}

_________________
OS-Development-, C++, Win32-API-, MFC-, Chemie-, Robotik- und Flugsimulator-Tutorials
http://www.henkessoft.de/index.htm


Zuletzt bearbeitet von Erhard Henkes am 09:28:51 07.09.2008, insgesamt 2-mal bearbeitet
hustbaer
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.10.2006
Beiträge: 12748
Beitrag hustbaer Mitglied 19:21:08 08.09.2008   Titel:              Zitieren

@Erhard Henkes:
Ich weiss nicht wieso du auf die Idee kommst man sollte Tetris als Anfängerspiel in 3D programmieren?!?
In 2D ist Tetris relativ einfach hinzubekommen.

Klar ist Pong noch einfacher, ob nun in 2D oder 3D, bloss ... Pong alleine spielen macht genau garkeinen Spass (mit oder ohne Computer-Gegner, ganz egal).

Deswegen: Tetris ist IMO immer noch besser geeignet als Pong. Allerdings eben nicht notwändigerweise mit einer 3D Engine.

_________________
"Let there be Licht..." http://lichttools.sourceforge.net/
Sehr cooles ASCII Spiel (leider nicht von mir): ASCII-Scramble - http://www.roskakori.at/ascii/
Krux
Mitglied

Benutzerprofil
Anmeldungsdatum: 03.01.2006
Beiträge: 772
Beitrag Krux Mitglied 19:23:31 08.09.2008   Titel:              Zitieren

ne ich bin für Space Invaders :p

_________________
versuch mal Scala
Kuldren
Mitglied

Benutzerprofil
Anmeldungsdatum: 18.07.2005
Beiträge: 764
Beitrag Kuldren Mitglied 20:38:39 08.09.2008   Titel:              Zitieren

hustbaer schrieb:
@Erhard Henkes:
Ich weiss nicht wieso du auf die Idee kommst man sollte Tetris als Anfängerspiel in 3D programmieren?!?
In 2D ist Tetris relativ einfach hinzubekommen.

Klar ist Pong noch einfacher, ob nun in 2D oder 3D, bloss ... Pong alleine spielen macht genau garkeinen Spass (mit oder ohne Computer-Gegner, ganz egal).

Deswegen: Tetris ist IMO immer noch besser geeignet als Pong. Allerdings eben nicht notwändigerweise mit einer 3D Engine.


Ich denke es ging ihm eher um den Lernfaktor beim Programmieren.
Erhard Henkes
Mitglied

Benutzerprofil
Anmeldungsdatum: 25.04.2000
Beiträge: 11885
Beitrag Erhard Henkes Mitglied 22:47:12 08.09.2008   Titel:              Zitieren

Zitat:
Ich denke es ging ihm eher um den Lernfaktor beim Programmieren.
Ja, mir geht es momentan nur um die Didaktik, denn viele Einstieger haben massive Probleme mit der Spieleprogrammierung, obwohl sie dort gerne mitmischen würden.

_________________
OS-Development-, C++, Win32-API-, MFC-, Chemie-, Robotik- und Flugsimulator-Tutorials
http://www.henkessoft.de/index.htm
hustbaer
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.10.2006
Beiträge: 12748
Beitrag hustbaer Mitglied 10:55:57 09.09.2008   Titel:              Zitieren

Gerade dann verstehe ich nicht wie man auf die Idee kommt mit einer full-blown 3D Engine ala Irrlicht anfangen zu wollen?!?

_________________
"Let there be Licht..." http://lichttools.sourceforge.net/
Sehr cooles ASCII Spiel (leider nicht von mir): ASCII-Scramble - http://www.roskakori.at/ascii/
rapso
Moderator

Benutzerprofil
Anmeldungsdatum: 17.06.2002
Beiträge: 7213
Beitrag rapso Moderator 13:08:47 09.09.2008   Titel:              Zitieren

hustbaer schrieb:
Gerade dann verstehe ich nicht wie man auf die Idee kommt mit einer full-blown 3D Engine ala Irrlicht anfangen zu wollen?!?
genau das frage ich mich auch, didaktisch echt zweifelhaft IMO. jemand der gerade lernt wie man ein winziges spiel macht soll gleich ne riesen engine nutzen.
ich denke die beispiele sind eher um fuer leute denen pong/tetris an sich 08/15 ist, zu zeigen wie man anhand dieser beispiele mit der engine umgeht. nicht andersrum.

_________________
Kilo Byte=1000,Kilobyte=1024 ANSI/IEEE Standard 1084-1986
rapso
-Mod im Spiele-/Grafikprogrammierung| rapsoo@hotmail.com | #dionysos irc.quakenet.org | amazon stole my PS3 :(
Xebov
Mitglied

Benutzerprofil
Anmeldungsdatum: 26.07.2008
Beiträge: 681
Beitrag Xebov Mitglied 16:24:12 09.09.2008   Titel:              Zitieren

Ich denke er will eher zeigen wie man sowa smacht wenn man ne Engine nimmt, nicht jedem liegt es ja selbst ne Engine zu bauen, wobei ich für so einfache Sachen lieber ne recht simple Engine bauen würde als ne fertige zu benutzen weil es einem sehr viel Grundlagen wissen beibringt.
Erhard Henkes
Mitglied

Benutzerprofil
Anmeldungsdatum: 25.04.2000
Beiträge: 11885
Beitrag Erhard Henkes Mitglied 17:49:25 11.09.2008   Titel:              Zitieren

Zitat:
zu zeigen wie man anhand dieser beispiele mit der engine umgeht
Genau, ich halte es für richtig, sofort mit einer Engine zu beginnen, und um den Leuten zu zeigen, dass es mehr gibt als Ego-Shooter, Terrains, FPS-Cameras und Quake-Maps zeige ich diese Beispiele. Man steht auf einem Riesen und experimentiert an einem kleinen Modell. Das vermittelt Sicherheit durch Einfachheit und man lernt den Rahmenaufbau des neuen Werkzeuges dabei spielerisch kennen. So stelle ich mir den Beginn der Lernkurve vor.

_________________
OS-Development-, C++, Win32-API-, MFC-, Chemie-, Robotik- und Flugsimulator-Tutorials
http://www.henkessoft.de/index.htm
Erhard Henkes
Mitglied

Benutzerprofil
Anmeldungsdatum: 25.04.2000
Beiträge: 11885
Beitrag Erhard Henkes Mitglied 23:16:08 13.09.2008   Titel:              Zitieren

Warum favorisiere ich den Start mit einer Engine so überzeugt? Es sind eigene Erfahrungen und posts wie diese:
Zitat:
In irrlicht everything is simple. Just only a few lines code, you can create everything in 3D space. Along time ago, I have ideal about a simple game 3D. At that time, I didn't have irrlicht engine, I just only use DirectX SDK. As you see, DirectX SDK really complicated. I was painful with it because it has many complicated functions with much formulary mathematics. I think if you aren’t good at mathematics, you can not use DirectX SDK professionally. I had spent for three months but my game hadn't finish yet. And now with irrlicht, I was easily finish it. The irrlicht engine has only one weakness that is speed. If your 3D application has many 3D objects then the speed of frame per second is very slow. So I think the irrlicht doesn't correspond for commercial games or tactical RST games. But if you are amateur programmer then irrlicht is the best engine for you. I really like irrlicht very much. This is my first 3D game. It's name "Dragon killer", this is very simple game. This is the link to download this game: http://www.mediafire.com/?dgedptm9z43
Have fun!

Quelle: http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=29325

Die mathematischen Anforderungen und die nutzlose Komplexität, die durch das DirectX SDK oder OpenGL verursacht werden, kann man sich einfach schenken, indem man eine Ebene höher programmiert. Das Argument bezüglich Performance kann ich noch nicht ausreichend beurteilen, ist mir aber auch schon aufgefallen bei irrlicht. Es gibt ja auch noch OGRE.

_________________
OS-Development-, C++, Win32-API-, MFC-, Chemie-, Robotik- und Flugsimulator-Tutorials
http://www.henkessoft.de/index.htm
C/C++ Forum :: Spiele-/Grafikprogrammierung ::  Pong ist das ideale Starter-Projekt  
Gehen Sie zu Seite 1, 2  Weiter
Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info, www.c-sar.de, www.c-plusplus.net und www.baeckmann.de enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.