#include <iostream>
#include <cmath>
-#include "particlesystem_interactive.h"
-#include "video/drawing_context.h"
-#include "lisp/parser.h"
-#include "lisp/lisp.h"
-#include "lisp/writer.h"
-#include "resources.h"
-#include "main.h"
+#include "particlesystem_interactive.hpp"
+#include "video/drawing_context.hpp"
+#include "lisp/parser.hpp"
+#include "lisp/lisp.hpp"
+#include "lisp/writer.hpp"
+#include "resources.hpp"
+#include "main.hpp"
-#include "tile.h"
-#include "tilemap.h"
-#include "math/aatriangle.h"
-#include "collision.h"
-#include "collision_hit.h"
-#include "object/camera.h"
-#include "object/rainsplash.h"
-#include "badguy/bomb.h"
+#include "tile.hpp"
+#include "tilemap.hpp"
+#include "math/aatriangle.hpp"
+#include "collision.hpp"
+#include "collision_hit.hpp"
+#include "object/camera.hpp"
+#include "object/rainsplash.hpp"
+#include "badguy/bomb.hpp"
-//TODO: Dynamically create splashes at collision spots
-// Find a way to make rain collide with objects like bonus blocks
+//TODO: Find a way to make rain collide with objects like bonus blocks
// Add an option to set rain strength
+// Fix rain being "respawned" over solid tiles
ParticleSystem_Interactive::ParticleSystem_Interactive()
{
virtual_width = SCREEN_WIDTH;
context.pop_transform();
}
-bool
+int
ParticleSystem_Interactive::collision(Particle* object, Vector movement)
{
TileMap* solids = Sector::current()->solids;
x2 = x1 + 32 + movement.x;
y1 = object->pos.y;
y2 = y1 + 32 + movement.y;
+ bool water = false;
// test with all tiles in this rectangle
int starttilex = int(x1-1) / 32;
const Tile* tile = solids->get_tile(x, y);
if(!tile)
continue;
- // skip non-solid tiles
- if(!(tile->getAttributes() & Tile::SOLID))
+ // skip non-solid tiles, except water
+ if (tile->getAttributes() & Tile::WATER)
+ water = true;
+ if(!water && !(tile->getAttributes() & Tile::SOLID))
continue;
if(tile->getAttributes() & Tile::SLOPE) { // slope tile
}
// did we collide at all?
- if(hit.time < 0)
- return false; else return true;
+ if(hit.time < 0) {
+ return -1; //no collision
+ }
+ else {
+ if (water)
+ return 0; //collision with water tile - don't draw splash
+ else {
+ if ((hit.normal.x == 1) && (hit.normal.y == 0))
+ return 2; //collision from right
+ else return 1; //collision from above
+ }
+ }
}
RainParticleSystem::RainParticleSystem()
{
- rainimages[0] = new Surface("images/objects/particles/rain0.png", true);
- rainimages[1] = new Surface("images/objects/particles/rain1.png", true);
+ rainimages[0] = new Surface("images/objects/particles/rain0.png");
+ rainimages[1] = new Surface("images/objects/particles/rain1.png");
virtual_width = SCREEN_WIDTH * 2;
float abs_y = Sector::current()->camera->get_translation().y;
particle->pos.y += movement;
particle->pos.x -= movement;
- if ((particle->pos.y > SCREEN_HEIGHT + abs_y) || (collision(particle, Vector(-movement, movement)))) {
+ int col = collision(particle, Vector(-movement, movement));
+ if ((particle->pos.y > SCREEN_HEIGHT + abs_y) || (col >= 0)) {
//Create rainsplash
- if (particle->pos.y <= SCREEN_HEIGHT + abs_y){
- //TODO: Find out at which side of the tile the collision happens
- bool vertical = false;
+ if ((particle->pos.y <= SCREEN_HEIGHT + abs_y) && (col >= 1)){
+ bool vertical = (col == 2);
int splash_x, splash_y;
- if (vertical) {
- splash_x = int(particle->pos.x) - (int(particle->pos.x) % 32) + 32;
- splash_y = int(particle->pos.y);
- }
- else {
+ if (!vertical) { //check if collision happened from above
splash_x = int(particle->pos.x);
splash_y = int(particle->pos.y) - (int(particle->pos.y) % 32) + 32;
+ Sector::current()->add_object(new RainSplash(Vector(splash_x, splash_y),vertical));
}
- Sector::current()->add_object(new RainSplash(Vector(splash_x, splash_y),vertical));
+ // Uncomment the following to display vertical splashes, too
+ /* else {
+ splash_x = int(particle->pos.x) - (int(particle->pos.x) % 32) + 32;
+ splash_y = int(particle->pos.y);
+ Sector::current()->add_object(new RainSplash(Vector(splash_x, splash_y),vertical));
+ } */
}
int new_x = (rand() % int(virtual_width)) + int(abs_x);
int new_y = 0;
CometParticleSystem::CometParticleSystem()
{
- cometimages[0] = new Surface("images/creatures/mr_bomb/exploding-left-0.png", true);
- cometimages[1] = new Surface("images/creatures/mr_bomb/exploding-left-0.png", true);
+ cometimages[0] = new Surface("images/creatures/mr_bomb/exploding-left-0.png");
+ cometimages[1] = new Surface("images/creatures/mr_bomb/exploding-left-0.png");
virtual_width = SCREEN_WIDTH * 2;
float abs_y = Sector::current()->camera->get_translation().y;
particle->pos.y += movement;
particle->pos.x -= movement;
- if ((particle->pos.y > SCREEN_HEIGHT + abs_y) || (collision(particle, Vector(-movement, movement)))) {
- if (particle->pos.y <= SCREEN_HEIGHT + abs_y) {
+ int col = collision(particle, Vector(-movement, movement));
+ if ((particle->pos.y > SCREEN_HEIGHT + abs_y) || (col >= 0)) {
+ if ((particle->pos.y <= SCREEN_HEIGHT + abs_y) && (col >= 1)) {
Sector::current()->add_object(new Bomb(particle->pos, LEFT));
}
int new_x = (rand() % int(virtual_width)) + int(abs_x);