85 ticker.start(25, this); |
81 ticker.start(25, this); |
86 setAttribute(Qt::WA_OpaquePaintEvent, true); |
82 setAttribute(Qt::WA_OpaquePaintEvent, true); |
87 setMouseTracking(false); |
83 setMouseTracking(false); |
88 } |
84 } |
89 |
85 |
90 void updatePlayer() { |
86 void Raycasting::updatePlayer() { |
91 int interval = qBound(20, watch.elapsed(), 250); |
87 int interval = qBound(20, watch.elapsed(), 250); |
92 watch.start(); |
88 watch.start(); |
93 angle += angleDelta * interval / 1000; |
89 angle += angleDelta * interval / 1000; |
94 qreal step = moveDelta * interval / 1000; |
90 qreal step = moveDelta * interval / 1000; |
95 qreal dx = cos(angle) * step; |
91 qreal dx = cos(angle) * step; |
99 int yi = static_cast<int>(pos.y()); |
95 int yi = static_cast<int>(pos.y()); |
100 if (world_map[yi][xi] == 0) |
96 if (world_map[yi][xi] == 0) |
101 playerPos = playerPos + QPointF(dx, dy); |
97 playerPos = playerPos + QPointF(dx, dy); |
102 } |
98 } |
103 |
99 |
104 void showFps() { |
100 void Raycasting::showFps() { |
105 static QTime frameTick; |
101 static QTime frameTick; |
106 static int totalFrame = 0; |
102 static int totalFrame = 0; |
107 if (!(totalFrame & 31)) { |
103 if (!(totalFrame & 31)) { |
108 int elapsed = frameTick.elapsed(); |
104 int elapsed = frameTick.elapsed(); |
109 frameTick.start(); |
105 frameTick.start(); |
111 setWindowTitle(QString("Raycasting (%1 FPS)").arg(fps)); |
107 setWindowTitle(QString("Raycasting (%1 FPS)").arg(fps)); |
112 } |
108 } |
113 totalFrame++; |
109 totalFrame++; |
114 } |
110 } |
115 |
111 |
116 void render() { |
112 void Raycasting::render() { |
117 |
113 |
118 // setup the screen surface |
114 // setup the screen surface |
119 if (buffer.size() != bufferSize) |
115 if (buffer.size() != bufferSize) |
120 buffer = QImage(bufferSize, QImage::Format_ARGB32); |
116 buffer = QImage(bufferSize, QImage::Format_ARGB32); |
121 int bufw = buffer.width(); |
117 int bufw = buffer.width(); |
246 } |
242 } |
247 |
243 |
248 update(QRect(QPoint(0, 0), bufferSize)); |
244 update(QRect(QPoint(0, 0), bufferSize)); |
249 } |
245 } |
250 |
246 |
251 protected: |
247 void Raycasting::resizeEvent(QResizeEvent*) { |
252 |
|
253 void resizeEvent(QResizeEvent*) { |
|
254 #if defined(Q_OS_WINCE_WM) |
248 #if defined(Q_OS_WINCE_WM) |
255 touchDevice = true; |
249 touchDevice = true; |
256 #elif defined(Q_OS_SYMBIAN) |
250 #elif defined(Q_OS_SYMBIAN) |
257 // FIXME: use HAL |
251 // FIXME: use HAL |
258 if (width() > 480 || height() > 480) |
252 if (width() > 480 || height() > 480) |
275 bufferSize = size(); |
269 bufferSize = size(); |
276 } |
270 } |
277 update(); |
271 update(); |
278 } |
272 } |
279 |
273 |
280 void timerEvent(QTimerEvent*) { |
274 void Raycasting::timerEvent(QTimerEvent*) { |
281 updatePlayer(); |
275 updatePlayer(); |
282 render(); |
276 render(); |
283 showFps(); |
277 showFps(); |
284 } |
278 } |
285 |
279 |
286 void paintEvent(QPaintEvent *event) { |
280 void Raycasting::paintEvent(QPaintEvent *event) { |
287 QPainter p(this); |
281 QPainter p(this); |
288 p.setCompositionMode(QPainter::CompositionMode_Source); |
282 p.setCompositionMode(QPainter::CompositionMode_Source); |
289 |
283 |
290 p.drawImage(event->rect(), buffer, event->rect()); |
284 p.drawImage(event->rect(), buffer, event->rect()); |
291 |
285 |
313 } |
307 } |
314 |
308 |
315 p.end(); |
309 p.end(); |
316 } |
310 } |
317 |
311 |
318 void keyPressEvent(QKeyEvent *event) { |
312 void Raycasting::keyPressEvent(QKeyEvent *event) { |
319 event->accept(); |
313 event->accept(); |
320 if (event->key() == Qt::Key_Left) |
314 if (event->key() == Qt::Key_Left) |
321 angleDelta = 1.3 * M_PI; |
315 angleDelta = 1.3 * M_PI; |
322 if (event->key() == Qt::Key_Right) |
316 if (event->key() == Qt::Key_Right) |
323 angleDelta = -1.3 * M_PI; |
317 angleDelta = -1.3 * M_PI; |
325 moveDelta = 2.5; |
319 moveDelta = 2.5; |
326 if (event->key() == Qt::Key_Down) |
320 if (event->key() == Qt::Key_Down) |
327 moveDelta = -2.5; |
321 moveDelta = -2.5; |
328 } |
322 } |
329 |
323 |
330 void keyReleaseEvent(QKeyEvent *event) { |
324 void Raycasting::keyReleaseEvent(QKeyEvent *event) { |
331 event->accept(); |
325 event->accept(); |
332 if (event->key() == Qt::Key_Left) |
326 if (event->key() == Qt::Key_Left) |
333 angleDelta = (angleDelta > 0) ? 0 : angleDelta; |
327 angleDelta = (angleDelta > 0) ? 0 : angleDelta; |
334 if (event->key() == Qt::Key_Right) |
328 if (event->key() == Qt::Key_Right) |
335 angleDelta = (angleDelta < 0) ? 0 : angleDelta; |
329 angleDelta = (angleDelta < 0) ? 0 : angleDelta; |
337 moveDelta = (moveDelta > 0) ? 0 : moveDelta; |
331 moveDelta = (moveDelta > 0) ? 0 : moveDelta; |
338 if (event->key() == Qt::Key_Down) |
332 if (event->key() == Qt::Key_Down) |
339 moveDelta = (moveDelta < 0) ? 0 : moveDelta; |
333 moveDelta = (moveDelta < 0) ? 0 : moveDelta; |
340 } |
334 } |
341 |
335 |
342 void mousePressEvent(QMouseEvent *event) { |
336 void Raycasting::mousePressEvent(QMouseEvent *event) { |
343 qreal dx = centerPad.x() - event->pos().x(); |
337 qreal dx = centerPad.x() - event->pos().x(); |
344 qreal dy = centerPad.y() - event->pos().y(); |
338 qreal dy = centerPad.y() - event->pos().y(); |
345 angleDelta = dx * 2 * M_PI / width(); |
339 angleDelta = dx * 2 * M_PI / width(); |
346 moveDelta = dy * 10 / height(); |
340 moveDelta = dy * 10 / height(); |
347 } |
341 } |
348 |
342 |
349 void mouseMoveEvent(QMouseEvent *event) { |
343 void Raycasting::mouseMoveEvent(QMouseEvent *event) { |
350 qreal dx = centerPad.x() - event->pos().x(); |
344 qreal dx = centerPad.x() - event->pos().x(); |
351 qreal dy = centerPad.y() - event->pos().y(); |
345 qreal dy = centerPad.y() - event->pos().y(); |
352 angleDelta = dx * 2 * M_PI / width(); |
346 angleDelta = dx * 2 * M_PI / width(); |
353 moveDelta = dy * 10 / height(); |
347 moveDelta = dy * 10 / height(); |
354 } |
348 } |
355 |
349 |
356 void mouseReleaseEvent(QMouseEvent*) { |
350 void Raycasting::mouseReleaseEvent(QMouseEvent*) { |
357 angleDelta = 0; |
351 angleDelta = 0; |
358 moveDelta = 0; |
352 moveDelta = 0; |
359 } |
353 } |
360 |
354 |
361 private: |
|
362 QTime watch; |
|
363 QBasicTimer ticker; |
|
364 QImage buffer; |
|
365 qreal angle; |
|
366 QPointF playerPos; |
|
367 qreal angleDelta; |
|
368 qreal moveDelta; |
|
369 QImage textureImg; |
|
370 int textureCount; |
|
371 bool touchDevice; |
|
372 QRect trackPad; |
|
373 QPoint centerPad; |
|
374 QSize bufferSize; |
|
375 }; |
|
376 |
|
377 int main(int argc, char **argv) |
|
378 { |
|
379 QApplication app(argc, argv); |
|
380 |
|
381 Raycasting w; |
|
382 w.setWindowTitle("Raycasting"); |
|
383 #if defined(Q_OS_SYMBIAN) || defined(Q_OS_WINCE_WM) |
|
384 w.showMaximized(); |
|
385 #else |
|
386 w.resize(640, 480); |
|
387 w.show(); |
|
388 #endif |
|
389 |
|
390 return app.exec(); |
|
391 } |
|