/** * Triangles * Copyright (C) 2016 POSITIVE MENTAL ATTITUDE * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "Bullet.hpp" #include "Utility.hpp" #include "cmath" Bullet::Bullet(float rotation, sf::Vector2f initialPosition, sf::SoundBuffer& buffer1, sf::SoundBuffer& buffer2, Foreground* foreground): _texture(nullptr), _foreground(foreground), _hit(false), _dead(false) { setRotation(rotation); setPosition(initialPosition); _vertex[0].position = sf::Vector2f(-3.f, 40.f); _vertex[1].position = sf::Vector2f(3.f, 40.f); _vertex[2].position = sf::Vector2f(3.f, -40.f); _vertex[3].position = sf::Vector2f(-3.f, -40.f); _sound.setBuffer(buffer1); _explosion.setBuffer(buffer2); _sound.play(); genCollisionBox("data/hitbox/Bullet.png", sf::Vector2f(3.f, 40.f)); } void Bullet::setTexture(sf::Texture& texture) { _texture = &texture; sf::Vector2u size = texture.getSize(); _vertex[0].texCoords = sf::Vector2f(0, size.y); _vertex[1].texCoords = sf::Vector2f(size.x, size.y); _vertex[2].texCoords = sf::Vector2f(size.x / 2.f, 0); _vertex[3].texCoords = sf::Vector2f(size.x / 2.f, size.y / 2.f); } void Bullet::draw(sf::RenderTarget& target, sf::RenderStates states) const { if(_hit) return; states.transform *= getTransform(); if(_texture != nullptr) states.texture = (_texture); target.draw(_vertex, 4, sf::Quads, states); } #include "iostream" void Bullet::destroyPixels(int& k, int x, int y) { int plus = 1; int dir = 0; int curr = 0; bool q[4] = {false, false, false, false}; while(k <= 6400) { if(_foreground->destroy(x, y)) { q[dir] = true; ++k; } switch(dir) { case 0: ++x; break; case 1: ++y; break; case 2: --x; break; case 3: --y; break; default: break; } ++curr; if(curr >= plus) { curr = 0; ++dir; if(dir == 4) { dir = 0; /* * This prevents destroying remote islands of foreground. */ bool exit = true; for(int i = 0; i < 4; ++i) { if(q[i]) exit = false; q[i] = false; } if(exit) break; } if(dir == 0 or dir == 2) ++plus; } } } void Bullet::update(sf::Time delta) { float seconds = delta.asSeconds(); const double degree = 3.14159265358 / 180.; sf::Vector2f movement; movement.x = std::sin(getRotation() * degree) * 1080.f * seconds; movement.y = -std::cos(getRotation() * degree) * 1080.f * seconds; move(movement); Collidable::updateTransform(getTransform()); if(!_hit) { int k = pixelPerfect(*_foreground); if(k != -1) { sf::Vector2i vec = (sf::Vector2i)getTransform().transformPoint(_cmap[k]); int n = vec.x, m = vec.y; int k = 0; destroyPixels(k, n, m); _foreground->reloadFromPixel(vec.x, vec.y, true); _explosion.play(); _hit = true; } } if(_hit and _sound.getStatus() == sf::Sound::Status::Stopped and _explosion.getStatus() == sf::Sound::Status::Stopped) { _dead = true; } } const bool Bullet::isDead() const { return _dead; }