This repository has been archived by the owner on Jan 5, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
physicstank.cpp
164 lines (151 loc) · 4.3 KB
/
physicstank.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/**
* Authors - William Erginac, Kenzie Evans, Alex Richins, Gavin Pease
*
* The aquarium used in all levels. Keeps track of or detect:
* - Water level
* - Food
* - Fish
*/
#include "physicstank.h"
#include "physicsfish.h"
#include "physicsfood.h"
#include <QPainter>
#include <QDebug>
#include <utility>
// Tank
Tank::Tank(std::string name, QPointF position, double rotation, QPointF scale) :
PhysicsGameObject(std::move(name), position, rotation, scale, PhysicsGameObject::createBodyDef(b2_staticBody), QImage(":/res/simpleTank.png"), 3)
{
waterLevel = 0;
emptyTank = graphic;
}
/**
* @brief Sets the body of the tank game object
* @param newBody - the body to be set to
*/
void Tank::setBody(b2Body* newBody)
{
// Make the sensor...
b2PolygonShape sensorShape;
sensorShape.SetAsBox(4, 2);
b2FixtureDef hitBoxDefinition;
hitBoxDefinition.shape = &sensorShape;
hitBoxDefinition.isSensor = true;
hitBoxDefinition.density = 1;
hitBoxDefinition.friction = 1;
newBody->CreateFixture(&hitBoxDefinition);
//Make the bottom...
b2PolygonShape bottomShape;
bottomShape.SetAsBox(5, 0.25, b2Vec2(0, -2), 0);
b2FixtureDef bottomFixture;
bottomFixture.shape = &bottomShape;
bottomFixture.isSensor = false;
bottomFixture.density = 1;
bottomFixture.friction = 1;
bottomFixture.restitution = 0.25;
newBody->CreateFixture(&bottomFixture);
//Make the left wall...
{
b2PolygonShape wall;
wall.SetAsBox(0.5, 2.5, b2Vec2(-4.5, 0), 0);
b2FixtureDef wallFixture;
wallFixture.shape = &wall;
wallFixture.isSensor = false;
wallFixture.density = 1;
wallFixture.friction = 1;
wallFixture.restitution = 0.25;
newBody->CreateFixture(&wallFixture);
}
//Make the right wall...
{
b2PolygonShape wall;
wall.SetAsBox(0.5, 2.5, b2Vec2(4.5, 0), 0);
b2FixtureDef wallFixture;
wallFixture.shape = &wall;
wallFixture.isSensor = false;
wallFixture.density = 1;
wallFixture.friction = 1;
wallFixture.restitution = 0.25;
newBody->CreateFixture(&wallFixture);
}
newBody->SetAngularDamping(0);
//THIS MUST ALWAYS BE CALLED AT THE END OF A SETBODY FOR ANY PHYSICSGAMEOBJECT.
PhysicsGameObject::setBody(newBody);
}
/**
* @brief Gets the current water level.
* @return A percentage of how full the water in the tank is.
*/
int Tank::getWaterLevel() const
{
return waterLevel;
}
/**
* @brief Sets the water level of the tank to a given percentage.
* @param newWaterLevel - The new percentage of water in the tank, capped to values between 0 and 100.
*/
void Tank::setWaterLevel(int newWaterLevel)
{
if(waterLevel > 100)
waterLevel = 100;
if (waterLevel < 0)
waterLevel = 0;
waterLevel = newWaterLevel;
drawWater();
}
/**
* @brief Draws the current level of water in the tank.
*/
void Tank::drawWater()
{
//Start with an empty canvas.
QImage water(emptyTank.width(), emptyTank.height(), QImage::Format::Format_RGBA64);
water.fill(Qt::transparent);
QPainter painter(&water);
//Draw the water as a rectangle behind the tank.
painter.setBrush(QColor(0, 75, 225, 225));
painter.drawRect(0, emptyTank.height() - waterLevel*emptyTank.height()/100, emptyTank.width()-2, waterLevel*emptyTank.height()/100);
//Draw the tank.
painter.drawImage(QPointF(0, 0), emptyTank);
painter.end();
graphic = water;
}
/**
* @brief Detects when an object enters the tank
*/
void Tank::onSensorEnter(b2Contact *collision, bool isA, PhysicsGameObject *other)
{
//Apply drag to submerged objects
other->getBody()->SetLinearDamping(other->getBody()->GetLinearDamping()*5);
other->getBody()->SetAngularDamping(other->getBody()->GetAngularDamping()*5);
//Check for important objects that have entered the tank.
auto fish = dynamic_cast<Fish*>(other);
auto food = dynamic_cast<Food*>(other);
if(fish != nullptr)
fish->setInTank(true);
else if (food)
incrementFoodInTank();
}
/**
* @brief Detects when an object leaves the tank
*/
void Tank::onSensorExit(PhysicsGameObject *other)
{
//Get rid of the drag caused by being in water.
other->getBody()->SetLinearDamping(other->getBody()->GetLinearDamping()/5);
other->getBody()->SetAngularDamping(other->getBody()->GetAngularDamping()/5);
}
/**
* @brief Gets how much food is in the tank.
*/
int Tank::getFoodInTank() const
{
return foodInTank;
}
/**
* @brief Increments the amount of food that has been disperesed into the tank by one.
*/
void Tank::incrementFoodInTank()
{
foodInTank++;
}