📄 playfield.cpp
字号:
/*
* Copyright (C) 2002 Robert Ernst <robert.ernst@linux-solutions.at>
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free Software
* Foundation and appearing in the file LICENSE.GPL included in the
* packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* See COPYING for GPL licensing information.
*
*/
#include <bitdev.h>
#include <icebloxx.rsg>
#include <stdlib.h>
#include <stdio.h> // for dump()
#include <string.h>
#include <eikenv.h>
#include <eikapp.h>
#include <eikappui.h>
#include "IceBloxxView.h"
#include "spritecollection.h"
#include "PlayField.h"
#include "icehidlg.h"
#ifdef UIQ3
const TInt KTextOffset = 66;
#else
const TInt KTextOffset = 60;
#endif
const TInt KLeftOffset = 5;
PlayField::PlayField(CIceBloxxView * aParent, const char * /*name*/, TInt /*f*/)
{
SetMainView(aParent);
m_sprites = new SpriteCollection();
m_timer = CPeriodic::NewL(CActive::EPriorityStandard);
m_pixmap = 0;
m_pixmap= new (ELeave) QPixmap(CEikonEnv::Static()->WsSession());
m_pixmap->Create(iView->Size(),EColor256);
m_pixdevice = CFbsBitmapDevice::NewL(m_pixmap);
m_pixdevice->CreateContext(m_pixgc);
m_speed = -1;
m_strength = -1;
m_coins = -1;
m_state = Intro_1;
m_counter = 0;
m_score = 0;
m_lives = 0;
m_levels_completed = 0;
m_blocks_broken = 0;
m_coins_collected = 0;
m_flames_killed = 0;
m_actors = 0;
m_coins_in_level = 0;
m_click_x = -1;
m_click_y = -1;
#ifdef CAN_TELEPORT
m_teleport = false;
#endif
for(TInt loop=0;loop<10;loop++)
{
m_Hiscores[loop] = (10-loop)*1000;
if(loop&1)
{
m_HiscoreNames[loop] = _L("Karl Hoernell");
}
else
{
m_HiscoreNames[loop] = _L("Robert Ernst");
}
}
m_soundHandler = CSoundHandler::NewL();
LoadSoundsL();
}
PlayField::~PlayField()
{
delete m_sprites;
if(m_timer)
{
m_timer->Cancel();
delete m_timer;
}
delete m_pixdevice;
delete m_pixgc;
delete m_pixmap;
delete m_soundHandler;
}
void PlayField::paintEvent(QPaintEvent * /*event*/)
{
switch (m_state) {
case Intro_1:
drawIntro_1();
break;
case Intro_2:
drawIntro_2();
break;
case Intro_3:
drawIntro_3();
break;
case HiScore:
drawHiScore();
break;
case Playing:
case Dying:
case HappyPenguin:
drawField();
break;
case GameOver:
drawGameOver();
break;
}
}
void PlayField::showEvent()
{
TCallBack callback(StaticTimerTick,this);
m_timer->Start(75000,75000,callback);
m_soundHandler->StartSound();
}
void PlayField::hideEvent()
{
m_timer->Cancel();
m_soundHandler->SuspendSound();
}
/*void PlayField::resizeEvent(QResizeEvent *event)
{
QWidget::resizeEvent(event);
if (!m_pixmap || event->size() != event->oldSize()) {
if (m_pixmap) {
delete m_pixmap;
}
m_pixmap = new QPixmap(event->size().width(), event->size().height());
}
}*/
void PlayField::keyPressEvent(QKeyEvent *event)
{
switch (event->key()) {
case Key_Up:
if (m_state == Playing) {
m_actor[0].m_req_dir = Up;
m_click_x = -1;
m_click_y = -1;
#ifdef CAN_TELEPORT
m_teleport = false;
#endif
}
break;
case Key_Down:
if (m_state == Playing) {
m_actor[0].m_req_dir = Down;
m_click_x = -1;
m_click_y = -1;
#ifdef CAN_TELEPORT
m_teleport = false;
#endif
}
break;
case Key_Left:
if (m_state == Playing) {
m_actor[0].m_req_dir = Left;
m_click_x = -1;
m_click_y = -1;
#ifdef CAN_TELEPORT
m_teleport = false;
#endif
}
break;
case Key_Right:
if (m_state == Playing) {
m_actor[0].m_req_dir = Right;
m_click_x = -1;
m_click_y = -1;
#ifdef CAN_TELEPORT
m_teleport = false;
#endif
}
break;
case Key_Space:
case Key_Enter:
if (m_state != Playing && m_state != Dying && m_state != HappyPenguin) {
start();
#ifdef CAN_TELEPORT
} else if (m_state == Playing) {
m_teleport = true;
#endif
}
break;
case Key_Escape:
if (m_state == Playing || m_state == Dying || m_state == HappyPenguin) {
stop();
}
break;
}
}
void PlayField::keyReleaseEvent(QKeyEvent *event)
{
switch (event->key()) {
case Key_Up:
case Key_Down:
case Key_Left:
case Key_Right:
if (m_state == Playing) {
m_actor[0].m_req_dir = Stop;
m_click_x = -1;
m_click_y = -1;
#ifdef CAN_TELEPORT
m_teleport = false;
#endif
}
break;
}
}
void PlayField::mousePressEvent(QMouseEvent *event)
{
if (m_state == Playing) {
int max_y = m_pixmap->height();
int offs_y = (max_y - 240);
#ifdef CAN_TELEPORT
if (event->y() < offs_y) {
m_teleport = true;
return;
} else {
m_teleport = false;
}
#endif
int xdiff = event->x() - 15 - m_actor[0].m_x;
int ydiff = event->y() - offs_y - 15 - m_actor[0].m_y;
if (abs(xdiff) > abs(ydiff)) {
ydiff = 0;
} else {
xdiff = 0;
}
if (ydiff > 15) {
m_actor[0].m_req_dir = Down;
m_click_x = (m_actor[0].m_x / 30) * 30;
m_click_y = ((event->y() - offs_y) / 30) * 30;
} else if (ydiff < -15) {
m_actor[0].m_req_dir = Up;
m_click_x = (m_actor[0].m_x / 30) * 30;
m_click_y = ((event->y() - offs_y) / 30) * 30;
} else if (xdiff > 15) {
m_actor[0].m_req_dir = Right;
m_click_x = (event->x() / 30) * 30;
m_click_y = (m_actor[0].m_y / 30) * 30;
} else if (xdiff < -15) {
m_actor[0].m_req_dir = Left;
m_click_x = (event->x() / 30) * 30;
m_click_y = (m_actor[0].m_y / 30) * 30;
} else {
m_actor[0].m_req_dir = Stop;
m_click_x = -1;
m_click_y = -1;
}
} else if (m_state != Dying && m_state != HappyPenguin) {
start();
}
}
void PlayField::start(void)
{
m_state = Playing;
m_counter = 0;
m_score = 0;
m_lives = 3;
m_levels_completed = 0;
m_blocks_broken = 0;
m_coins_collected = 0;
m_flames_killed = 0;
m_actors = 0;
m_coins_in_level = 0;
m_click_x = -1;
m_click_y = -1;
#ifdef CAN_TELEPORT
m_teleport = false;
#endif
int nloops = 0;
do {
makeField();
} while (!isFieldOk() && ++nloops < 10);
repaint(false);
}
void PlayField::stop(void)
{
if (m_state != Intro_1) {
m_state = Intro_1;
m_counter = 0;
repaint(false);
}
}
TInt PlayField::StaticTimerTick(TAny* aPlayField)
{
static_cast<PlayField*>(aPlayField)->timerTick();
return 0;
}
void PlayField::timerTick(void)
{
m_counter++;
switch (m_state) {
case Intro_1:
if (m_counter >= 100) {
m_state = Intro_2;
m_counter = 0;
}
break;
case Intro_2:
if (m_counter >= 100) {
m_state = Intro_3;
m_counter = 0;
}
break;
case Intro_3:
if (m_counter >= 100) {
m_state = HiScore;
m_counter = 0;
}
break;
case HiScore:
if (m_counter >= 100) {
m_state = Intro_1;
m_counter = 0;
}
break;
case Playing:
/* clear the actors that can move from the drawing buffer */
clearField();
/* update the counters for actors that have an animated pixmap */
animateActors();
/* update the actors positions */
moveActors();
/* re-create flames from points after a few seconds */
recreateFlames();
break;
case Dying:
/* clear the actors that can move from the drawing buffer */
clearField();
/* update the counters for actors that have an animated pixmap */
animateActors();
/* update the actors positions */
recreateFlames();
/* leave this state after a while */
if (m_actor[0].m_counter >= 32) {
if (m_lives>0) {
m_state = Playing;
recreatePlayer();
} else {
m_state = GameOver;
m_counter = 0;
CheckForHiscoreL();
}
}
break;
case HappyPenguin:
/* clear the actors that can move from the drawing buffer */
clearField();
/* update the counters for actors that have an animated pixmap */
animateActors();
/* re-create flames from points after a few seconds */
recreateFlames();
/* leave this state after a while */
if (m_actor[0].m_counter >= 40) {
m_actors = 0;
m_coins_in_level = 0;
int nloops = 0;
do {
makeField();
} while (!isFieldOk() && ++nloops < 10);
m_state = Playing;
m_actor[0].m_counter = 0;
m_actor[0].m_req_dir = Stop;
m_actor[0].m_act_dir = Stop;
m_click_x = -1;
m_click_y = -1;
#ifdef CAN_TELEPORT
m_teleport = false;
#endif
}
break;
case GameOver:
if (m_counter >= 300) {
m_state = Intro_1;
m_counter = 0;
}
break;
}
repaint(false);
}
void PlayField::updateSpeed(int speed)
{
if (speed != m_speed) {
m_speed = speed;
if (m_state == Playing || m_state == Dying || m_state == HappyPenguin) {
start();
}
}
#ifdef UIQ3
iView->UpdateCommandsL(m_coins, m_speed, m_strength);
#endif
}
void PlayField::updateStrength(int strength)
{
if (strength != m_strength) {
m_strength = strength;
if (m_state == Playing || m_state == Dying || m_state == HappyPenguin) {
start();
}
}
#ifdef UIQ3
iView->UpdateCommandsL(m_coins, m_speed, m_strength);
#endif
}
void PlayField::updateCoins(int coins)
{
if (coins != m_coins) {
m_coins = coins;
if (m_state == Playing || m_state == Dying || m_state == HappyPenguin) {
start();
}
}
#ifdef UIQ3
iView->UpdateCommandsL(m_coins, m_speed, m_strength);
#endif
}
void PlayField::drawIntro_1(void)
{
QPainter painter_pixmap(m_pixgc);
QColor black(0, 0, 0);
QColor white(255, 255, 255);
int max_x = iView->Size().iWidth;
int max_y = iView->Size().iHeight;
painter_pixmap.fillRect(0, 0, max_x, max_y, black);
painter_pixmap.setPen(white);
m_sprites->drawIntro(painter_pixmap, (max_x - 208) / 2, 7);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -