⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 playfield.cpp

📁 Source code (C++) of the Icebloxx game for Symbian OS UIQ3.x
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	for (j = 0; j < max_cols; j++) {
	    visited[i][j] = false;
	    map[i][j] = Empty;
	}
    }
    for (i = 0; i < m_actors; i++) {
	int x = m_actor[i].m_x / 30;
	int y = m_actor[i].m_y / 30;
	if (x < 0 || x >= max_cols || y < 0 || y >= max_rows) {
	    return false;
	}
	map[y][x] = m_actor[i].m_type;
    }

    /* second, set all field to "visited" that can be reached from x=0/y=0 */
    check_field(map, visited, 0, 0);

    /* third, check if all coins are on a visited field */
    for (i = 0; i < max_rows; i++) {
	for (j = 0; j < max_cols; j++) {
	    if (map[i][j] == BlockCoin && visited[i][j] == false) {
		return false;
	    }
	}
    }
    return true;
}

void PlayField::clearField(void)
{
#pragma message("Clear bitmap field")
    QPainter painter_pixmap(m_pixgc);
    QColor black(0, 0, 0);
    int max_y = m_pixmap->height();
    int offs_y = (max_y - 240);
    int i;

    for (i = 0; i < m_actors; i++) {
	if (m_actor[i].m_type != Wall) {
	    painter_pixmap.fillRect((KMajorPart*m_actor[i].m_x)/KDividor, m_actor[i].m_y + offs_y,
		KBlockWidth, 30, black);
	}
    }
}

void PlayField::animateActors(void)
{
    int i;

    for (i = 0; i < m_actors; i++) {
	if (m_actor[i].m_type == Player || m_actor[i].m_type == Flame
	    || m_actor[i].m_type == Points) {
	    m_actor[i].m_counter++;
	}
    }
}

void PlayField::moveActors(void)
{
    int x;
    int y;
    int i;
    int j;

    /* first, move the blocks - they just move until they crash
     * into another object, but they kill all flames on their way...
     */
    for (i = 1; i < m_actors; i++) {
	if (m_actor[i].m_type == Block || m_actor[i].m_type == BlockCoin) {
	    switch (m_actor[i].m_act_dir) {
	    case Up:
		x = m_actor[i].m_x;
		y = m_actor[i].m_y - m_actor[i].m_speed;
		while ((j = detectCollisionFlame(i, x, y)) >= 0) {
		    killFlame(j);
		}
		if ((j = detectCollisionBlockOrWall(i, x, y)) >= 0) {
		    y = (m_actor[i].m_y / 30) * 30;
		    m_actor[i].m_act_dir = Stop;
		    m_actor[i].m_req_dir = Stop;
		}
		m_actor[i].m_x = x;
		m_actor[i].m_y = y;
		break;
	    case Down:
		x = m_actor[i].m_x;
		y = m_actor[i].m_y + m_actor[i].m_speed;
		while ((j = detectCollisionFlame(i, x, y)) >= 0) {
		    killFlame(j);
		}
		if ((j = detectCollisionBlockOrWall(i, x, y)) >= 0) {
		    y = ((m_actor[i].m_y + 29) / 30) * 30;
		    m_actor[i].m_act_dir = Stop;
		    m_actor[i].m_req_dir = Stop;
		}
		m_actor[i].m_x = x;
		m_actor[i].m_y = y;
		break;
	    case Left:
		x = m_actor[i].m_x - m_actor[i].m_speed;
		y = m_actor[i].m_y;
		while ((j = detectCollisionFlame(i, x, y)) >= 0) {
		    killFlame(j);
		}
		if ((j = detectCollisionBlockOrWall(i, x, y)) >= 0) {
		    x = (m_actor[i].m_x / 30) * 30;
		    m_actor[i].m_act_dir = Stop;
		    m_actor[i].m_req_dir = Stop;
		}
		m_actor[i].m_x = x;
		m_actor[i].m_y = y;
		break;
	    case Right:
		x = m_actor[i].m_x + m_actor[i].m_speed;
		y = m_actor[i].m_y;
		while ((j = detectCollisionFlame(i, x, y)) >= 0) {
		    killFlame(j);
		}
		if ((j = detectCollisionBlockOrWall(i, x, y)) >= 0) {
		    x = ((m_actor[i].m_x + 29) / 30) * 30;
		    m_actor[i].m_act_dir = Stop;
		    m_actor[i].m_req_dir = Stop;
		}
		m_actor[i].m_x = x;
		m_actor[i].m_y = y;
		break;
	    default:
		break;
	    }
	}
    }

    /* then, calculate the directions of the flames (always towards the player) */
    for (i = 1; i < m_actors; i++) {
	if (m_actor[i].m_type == Flame) {
	    /* default: move in a random direction */
	    int xdiff = m_actor[i].m_x - m_actor[0].m_x;
	    int ydiff = m_actor[i].m_y - m_actor[0].m_y;
	    switch (rand() % 5) {
	    case 0:
		m_actor[i].m_req_dir = Stop;
		break;
	    case 1:
		m_actor[i].m_req_dir = Up;
		break;
	    case 2:
		m_actor[i].m_req_dir = Down;
		break;
	    case 3:
		m_actor[i].m_req_dir = Left;
		break;
	    case 4:
		m_actor[i].m_req_dir = Right;
		break;
	    }

	    /* if the player is too far away, the flame doesn't see him */
	    if (abs(xdiff) > 150 || abs(ydiff) > 150) {
		continue;
	    }

	    /* if the flame is in line of sight, it chases the player */
	    if (abs(xdiff) < 15) {
		if (lineOfSight(i, 0, (ydiff > 0) ? Up : Down)) {
		    m_actor[i].m_req_dir = (ydiff > 0) ? Up : Down;
		    continue;
		}
	    } else if (abs(ydiff) < 15) {
		if (lineOfSight(i, 0, (xdiff > 0) ? Left : Right)) {
		    m_actor[i].m_req_dir = (xdiff > 0) ? Left : Right;
		    continue;
		}
	    }

	    /* if the player is too far away, the flame doesn't see him */
	    if (abs(xdiff) > 90 || abs(ydiff) > 90) {
		continue;
	    }

	    /* move in the direction with the smaller difference if we have
	     * to go both horizontal or vertical
	     */
	    if (xdiff != 0 && ydiff != 0) {
		if (abs(xdiff) > abs(ydiff)) {
		    xdiff = 0;
		} else {
		    ydiff = 0;
		}
	    }
	    if (xdiff != 0) {
		m_actor[i].m_req_dir = (xdiff > 0) ? Left : Right;
	    } else if (ydiff != 0) {
		m_actor[i].m_req_dir = (ydiff > 0) ? Up : Down;
	    }
	}
    }

    /* at last, move the player and the flames. note: if the requested direction
     * differs from the actual one, the player or flame is moved to the next tile
     * position before actually changing the direction (or stopping).
     */
    for (i = 0; i < m_actors; i++) {
	if (m_actor[i].m_type != Player && m_actor[i].m_type != Flame) {
	    continue;
	}
#ifdef CAN_TELEPORT
	if (i == 0 && m_teleport) {
	    /* if teleport() works, the act/req_dir members will be reset! */
	    teleport();
	    m_teleport = false;
	}
#endif
	if (m_actor[i].m_act_dir == Stop) {
	    m_actor[i].m_act_dir = m_actor[i].m_req_dir;
	}
	switch (m_actor[i].m_act_dir) {
	case Up:
	    x = m_actor[i].m_x;
	    y = m_actor[i].m_y - m_actor[i].m_speed;
	    if (m_actor[i].m_req_dir != Up) {
		if ((m_actor[i].m_y % 30) < m_actor[i].m_speed) {
		    m_actor[i].m_act_dir = m_actor[i].m_req_dir;
		    y = (m_actor[i].m_y / 30) * 30;
		}
	    } else if (i == 0) {
		if ((j = detectCollisionFlame(i, x, y)) >= 0) {
		    killPlayer();
		} else if ((j = detectCollisionBlockOrWall(i, x, y)) >= 0) {
		    if (m_actor[j].m_type == Block || m_actor[j].m_type == BlockCoin) {
			moveOrCrushBlock(j, m_actor[i].m_act_dir);
		    } else {
			m_actor[i].m_req_dir = Stop;
			m_actor[i].m_act_dir = Stop;
		    }
		    y = (m_actor[i].m_y / 30) * 30;
		}
	    } else {
		if (( j = detectCollisionPlayer(x, y)) >= 0) {
		    killPlayer();
		} else if ((j = detectCollisionMovingBlock(i, x, y)) >= 0) {
		    killFlame(i);
		    y = (m_actor[i].m_y / 30) * 30;
		    m_actor[i].m_req_dir = Stop;
		    m_actor[i].m_act_dir = Stop;
		} else if ((j = detectCollisionBlockOrWall(i, x, y)) >= 0) {
		    y = (m_actor[i].m_y / 30) * 30;
		    m_actor[i].m_req_dir = Stop;
		    m_actor[i].m_act_dir = Stop;
		}
	    }
	    if (i == 0 && hasReachedClickPosition(x, y)) {
		m_actor[i].m_req_dir = Stop;
	    }
	    m_actor[i].m_x = x;
	    m_actor[i].m_y = y;
	    break;
	case Down:
	    x = m_actor[i].m_x;
	    y = m_actor[i].m_y + m_actor[i].m_speed;
	    if (i == 0 && hasReachedClickPosition(x, y)) {
		m_actor[i].m_req_dir = Stop;
	    }
	    if (m_actor[i].m_req_dir != Down) {
		if ((y % 30) <= m_actor[i].m_speed) {
		    m_actor[i].m_act_dir = m_actor[i].m_req_dir;
		    y = (y / 30) * 30;
		}
	    } else if (i == 0) {
		if ((j = detectCollisionFlame(i, x, y)) >= 0) {
		    killPlayer();
		} else if ((j = detectCollisionBlockOrWall(i, x, y)) >= 0) {
		    if (m_actor[j].m_type == Block || m_actor[j].m_type == BlockCoin) {
			moveOrCrushBlock(j, m_actor[i].m_act_dir);
		    } else {
			m_actor[i].m_req_dir = Stop;
			m_actor[i].m_act_dir = Stop;
		    }
		    y = ((m_actor[i].m_y + 29) / 30) * 30;
		}
	    } else {
		if (( j = detectCollisionPlayer(x, y)) >= 0) {
		    killPlayer();
		} else if ((j = detectCollisionMovingBlock(i, x, y)) >= 0) {
		    killFlame(i);
		    y = ((m_actor[i].m_y + 29) / 30) * 30;
		    m_actor[i].m_req_dir = Stop;
		    m_actor[i].m_act_dir = Stop;
		} else if ((j = detectCollisionBlockOrWall(i, x, y)) >= 0) {
		    y = ((m_actor[i].m_y + 29) / 30) * 30;
		    m_actor[i].m_req_dir = Stop;
		    m_actor[i].m_act_dir = Stop;
		}
	    }
	    m_actor[i].m_x = x;
	    m_actor[i].m_y = y;
	    break;
	case Left:
	    x = m_actor[i].m_x - m_actor[i].m_speed;
	    y = m_actor[i].m_y;
	    if (m_actor[i].m_req_dir != Left) {
		if ((m_actor[i].m_x % 30) < m_actor[i].m_speed) {
		    m_actor[i].m_act_dir = m_actor[i].m_req_dir;
		    x = (m_actor[i].m_x / 30) * 30;
		}
	    } else if (i == 0) {
		if ((j = detectCollisionFlame(i, x, y)) >= 0) {
		    killPlayer();
		} else if ((j = detectCollisionBlockOrWall(i, x, y)) >= 0) {
		    if (m_actor[j].m_type == Block || m_actor[j].m_type == BlockCoin) {
			moveOrCrushBlock(j, m_actor[i].m_act_dir);
		    } else {
			m_actor[i].m_req_dir = Stop;
			m_actor[i].m_act_dir = Stop;
		    }
		    x = (m_actor[i].m_x / 30) * 30;
		}
	    } else {
		if (( j = detectCollisionPlayer(x, y)) >= 0) {
		    killPlayer();
		} else if ((j = detectCollisionMovingBlock(i, x, y)) >= 0) {
		    killFlame(i);
		    x = (m_actor[i].m_x / 30) * 30;
		    m_actor[i].m_req_dir = Stop;
		    m_actor[i].m_act_dir = Stop;
		} else if ((j = detectCollisionBlockOrWall(i, x, y)) >= 0) {
		    x = (m_actor[i].m_x / 30) * 30;
		    m_actor[i].m_req_dir = Stop;
		    m_actor[i].m_act_dir = Stop;
		}
	    }
	    if (i == 0 && hasReachedClickPosition(x, y)) {
		m_actor[i].m_req_dir = Stop;
	    }
	    m_actor[i].m_x = x;
	    m_actor[i].m_y = y;
	    break;
	case Right:
	    x = m_actor[i].m_x + m_actor[i].m_speed;
	    y = m_actor[i].m_y;
	    if (i == 0 && hasReachedClickPosition(x, y)) {
		m_actor[i].m_req_dir = Stop;
	    }
	    if (m_actor[i].m_req_dir != Right) {
		if ((x % 30) <= m_actor[i].m_speed) {
		    m_actor[i].m_act_dir = m_actor[i].m_req_dir;
		    x = (x / 30) * 30;
		}
	    } else if (i == 0) {
		if ((j = detectCollisionFlame(i, x, y)) >= 0) {
		    killPlayer();
		} else if ((j = detectCollisionBlockOrWall(i, x, y)) >= 0) {
		    if (m_actor[j].m_type == Block || m_actor[j].m_type == BlockCoin) {
			moveOrCrushBlock(j, m_actor[i].m_act_dir);
		    } else {
			m_actor[i].m_req_dir = Stop;
			m_actor[i].m_act_dir = Stop;
		    }
		    x = ((m_actor[i].m_x + 29) / 30) * 30;
		}
	    } else {
		if (( j = detectCollisionPlayer(x, y)) >= 0) {
		    killPlayer();
		} else if ((j = detectCollisionMovingBlock(i, x, y)) >= 0) {
		    killFlame(i);
		    x = ((m_actor[i].m_x + 29) / 30) * 30;
		    m_actor[i].m_req_dir = Stop;
		    m_actor[i].m_act_dir = Stop;
		} else if ((j = detectCollisionBlockOrWall(i, x, y)) >= 0) {
		    x = ((m_actor[i].m_x + 29) / 30) * 30;
		    m_actor[i].m_req_dir = Stop;
		    m_actor[i].m_act_dir = Stop;
		}
	    }
	    m_actor[i].m_x = x;
	    m_actor[i].m_y = y;
	    break;
	case Stop:
	    break;
	}
    }
}

void PlayField::recreateFlames(void)
{
    int i;

    for (i = 1; i < m_actors; i++) {
	if (m_actor[i].m_type == Points && m_actor[i].m_counter >= 36) {
	    /* first, set the position of the flame to the tile position */
	    m_actor[i].m_x = ((m_actor[i].m_x + 15) / 30) * 30;
	    m_actor[i].m_y = ((m_actor[i].m_y + 15) / 30) * 30;
	    m_actor[i].m_counter = 0;
	    m_actor[i].m_type = Flame;

	    /* then, move the flame if it is too near to the player */
	    int nloops = 0;
	    while (++nloops < 1000) {
		int xdiff = abs(m_actor[i].m_x - m_actor[0].m_x);
		int ydiff = abs(m_actor[i].m_y - m_actor[0].m_y);
		if (xdiff >= 90 && ydiff >= 90
		    && detectCollision(i, m_actor[i].m_x, m_actor[i].m_y) < 0) {
		    break;
		}
		m_actor[i].m_x = (rand() % max_cols) * 30;
		m_actor[i].m_y = (rand() % max_rows) * 30;
	    }
	}
    }
}

void PlayField::recreatePlayer(void)
{
    int i;

    /* first, set the position of the player to the tile position */
    m_actor[0].m_x = ((m_actor[0].m_x + 15) / 30) * 30;
    m_actor[0].m_y = ((m_actor[0].m_y + 15) / 30) * 30;
    m_actor[0].m_counter = 0;

    /* actually, we don't recreate or move the player, but we move all flames
     * that are too near to an other position.
     */
    for (i = 1; i < m_actors; i++) {
	if (m_actor[i].m_type == Flame) {
	    int nloops = 0;
	    while (++nloops < 1000) {
		int xdiff = abs(m_actor[i].m_x - m_actor[0].m_x);
		int ydiff = abs(m_actor[i].m_y - m_actor[0].m_y);
		if (xdiff >= 90 && ydiff >= 90
		    && detectCollision(i, m_actor[i].m_x, m_actor[i].m_y) < 0) {
		    break;
		}
		m_actor[i].m_x = (rand() % max_cols) * 30;
		m_actor[i].m_y = (rand() % max_rows) * 30;
		m_actor[i].m_counter = 0;
	    }
	}
    }
}

void PlayField::killFlame(int actor)
{
    if (actor < 0 || actor >= m_actors || m_actor[actor].m_type != Flame) {
    }
    m_flames_killed++;
    m_score = m_score + 50;
	m_soundHandler->PlaySampleL(m_SoundEffects[EKillFireFx]);
    if (m_flames_killed % 10 == 0 && m_lives < max_lives) {
	m_lives++;
    }
    m_actor[actor].m_type = Points;
    m_actor[actor].m_counter = 0;
    m_actor[actor].m_req_dir = Stop;
    m_actor[actor].m_act_dir = Stop;
}

void PlayField::killPlayer(void)
{
	m_soundHandler->PlaySampleL(m_SoundEffects[EGameOverFx]);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -