button class, angle

This commit is contained in:
2019-01-21 14:47:22 +01:00
parent 0fb81584b6
commit a02490512d
4 changed files with 276 additions and 148 deletions

View File

@@ -3,6 +3,22 @@ int i_citizenAmount = 10;
int i_selectedCitizen;
int i_femaleCount;
//je nachdem wie hoch der derzeitige fokus ist wird es schwerer, ihn abzulenken.
//intrinsischer fokus korreliert mit joy/motivation/positive erinnerung an etwas
//zur welt:
//
//0-100:
//motivation (bei arbeiter montag ~40, freitag ~80 - 100)
//7 emotionen?
// berufsfeld: webdesigner, pädagoge, schmuckdesigner, schmied
// berufsstatus: beamter, selbstständiger, unternehmer, angestellter, grundschüler, gymnasiast, hauptschüler, realschüler, azubi, student, rentner
// identität: gelbhemd, lokal, regional, national, international, fremd,
Citizen[] citizen = new Citizen[i_citizenAmount];
void initCitizen() {
@@ -25,13 +41,13 @@ void initCitizen() {
int age = int(random(0, 100));
citizen[i] = new Citizen(int(random(0, houses.size())), S_citizenNames[gender][int(random(0, S_citizenNames[gender].length))], gender, age);
}
for (int i = 0; i < citizen.length; i++) {
for (int i = 0; i < citizen.length; i++) {
if (i != i_selectedCitizen)
citizen[i].spawn(citizen[i].i_home);
else citizen[i].spawn(100,100);
else citizen[i].spawn(100, 100);
if (citizen[i].b_randomRun) citizen[i].goTo(int(random(0, pg_map.width)), int(random(0, pg_map.height))); //bad
if (citizen[i].b_randomRun) citizen[i].goTo(int(random(0, pg_map.width)), int(random(0, pg_map.height)), 10); //bad
}
selectCitizen(0);
}
@@ -54,12 +70,14 @@ class Citizen extends Entity {
int i_age;
int i_home;
float f_movementSpeed;
float f_FOV = PI / 4.0;
int i_visionDistance = 60;
boolean b_randomRun;
GraphNode startNode, endNode;
int startNodeID, endNodeID;
GraphNode[] rNodes;
// ArrayList<GraphNode> rNodesList = new ArrayList<GraphNode>();
// ArrayList<GraphNode> rNodesList = new ArrayList<GraphNode>();
int nextNode;
IGraphSearch pathFinder;
@@ -81,28 +99,11 @@ class Citizen extends Entity {
c_stroke = color(255, 255, 255);
}
//citizen kann "lookat" mit 180° winkel mit bullseye förmigen gradient welches die chance etwas zu bemerken darstellt
void lookAt (Entity entity) {
}
//setFocus(entity) durch geräusche auch von objekten ausserhalb des sichtfeldes aufrufbar
//citizen kann "focus", guckt mit den augen in die richtung. 2. augen-vektor! kopf wird mitgedreht je nach "openness"
//citizen kann "take", nimmt gegenstand in die hand. arraylist "holds" - gegenstände in der hand
//entitiy-subklassen: papier
//setFocus(entity) durch geräusche auch von objekten ausserhalb des sichtfeldes aufrufbar
//je nachdem wie hoch der derzeitige fokus ist wird es schwerer, ihn abzulenken.
//intrinsischer fokus korreliert mit joy/motivation/positive erinnerung an etwas
//zur welt:
//
//0-100:
//motivation (bei arbeiter montag ~40, freitag ~80 - 100)
//7 emotionen?
// berufsfeld: webdesigner, pädagoge, schmuckdesigner, schmied
// berufsstatus: beamter, selbstständiger, unternehmer, angestellter, grundschüler, gymnasiast, hauptschüler, realschüler, azubi, student, rentner
// identität: gelbhemd, lokal, regional, national, international, fremd,
int i_direction(float f, float v) {
@@ -110,61 +111,34 @@ class Citizen extends Entity {
else if (f >= 0+v) return 1;
else return 0;
}
void update() {
f_angle = v2_direction.heading();
if (b_moving) { //if rNodes.length > 0
if (rNodes.length > nextNode) {
float f_xPosNext = rNodes[nextNode].xf();
float f_yPosNext = rNodes[nextNode].yf();
float f_movementVelo = f_movementSpeed;
//slow down movement velocity if moving diagnoally
if (int(rNodes[nextNode].xf()) != int(f_xPos) && int(rNodes[nextNode].yf()) != int(f_yPos)) f_movementVelo = f_movementVelo / 1.41;
f_xPos += i_direction(f_xPosNext-f_xPos, f_movementVelo) * f_movementVelo;
f_yPos += i_direction(f_yPosNext-f_yPos, f_movementVelo) * f_movementVelo;
if (abs(f_yPos - f_yPosNext) < f_movementVelo && abs(f_xPos - f_xPosNext) < f_movementVelo) {
f_yPos = f_yPosNext;
f_xPos = f_xPosNext;
nextNode++;
}
} else {
b_moving = false;
nextNode = 0;
if (!b_randomRun) {
//check if standing on an other citizens position
} else {
goTo(int(random(0, pg_map.width)), int(random(0, pg_map.height)));
}
}
move();
}
watch();
//look collision detection
}
void debug() {
//draw Route
if (rNodes.length >= 2 && (b_drawPathLine || b_drawPathDestination)) {
pg_map.pushStyle();
if (b_drawPathLine) {
pg_map.stroke(color(100, 100, 100));
pg_map.strokeWeight(1);
pg_map.noFill();
for (int i = 1; i < rNodes.length; i++)
pg_map.line(rNodes[i-1].xf(), rNodes[i-1].yf(), rNodes[i].xf(), rNodes[i].yf());
} //draw destination
if (b_drawPathDestination) {
pg_map.stroke(160, 0, 0);
if (b_selected) pg_map.fill(255, 0, 0);
else pg_map.fill(0);
pg_map.ellipse(rNodes[rNodes.length-1].xf(), rNodes[rNodes.length-1].yf(), nodeSize, nodeSize);
}
pg_map.popStyle();
void lookAt (int x, int y, int prio) {
}
void watch() {
if (b_moving) {
}
}
void goTo(int x, int y) {
void goTo(int x, int y, int prio) {
//add: go to node? go to house?
int i_goToX = x;
int i_goToY = y;
int spread = 0;
boolean findingWay = false;
while (!findingWay) {
float nodeDistance = 1.0f;
findingWay = true;
@@ -185,12 +159,8 @@ class Citizen extends Entity {
i_goToY+= spread;
}
}
pathFinder.search(startNodeID, endNodeID, true); //returns null if no route is found
rNodes = pathFinder.getRoute();
if (rNodes.length > 0) {
nextNode = 0;
b_moving = true;
@@ -198,13 +168,70 @@ class Citizen extends Entity {
// rNodesList.add(rNodes[i]);
//}
} else { //implement more intelligent design which calls goTo not in this frame (this can cause infinite loops), but in the next 120 frames or so
//also at this point i can move recalculating the nodes into the next frames if no route is found (not only random)..
if (b_randomRun) goTo(int(random(0, pg_map.width)), int(random(0, pg_map.height)));
//also at this point i can move recalculating the nodes into the next frames if no route is found (not only random)..
if (b_randomRun) goTo(int(random(0, pg_map.width)), int(random(0, pg_map.height)), 10);
}
}
void move() {
if (rNodes.length > nextNode) {
float f_xPosNext = rNodes[nextNode].xf();
float f_yPosNext = rNodes[nextNode].yf();
float f_movementVelo = f_movementSpeed;
//slow down movement velocity if moving diagnoally
if (int(rNodes[nextNode].xf()) != int(f_xPos) && int(rNodes[nextNode].yf()) != int(f_yPos)) f_movementVelo = f_movementVelo / 1.41;
f_xPos += i_direction(f_xPosNext-f_xPos, f_movementVelo) * f_movementVelo;
f_yPos += i_direction(f_yPosNext-f_yPos, f_movementVelo) * f_movementVelo;
v2_direction.x = f_xPos - f_xPosNext;
v2_direction.y = f_yPos - f_yPosNext;
if (abs(f_yPos - f_yPosNext) < f_movementVelo && abs(f_xPos - f_xPosNext) < f_movementVelo) {
f_yPos = f_yPosNext;
f_xPos = f_xPosNext;
nextNode++;
}
} else {
b_moving = false;
//v2_direction =
nextNode = 0;
if (!b_randomRun) {
//check if standing on an other citizens position
} else {
goTo(int(random(0, pg_map.width)), int(random(0, pg_map.height)), 10);
}
}
}
void debug() {
//draw Route
if (rNodes.length >= 2) {
pg_map.pushStyle();
pg_map.stroke(color(100, 100, 200));
pg_map.strokeWeight(1);
pg_map.noFill();
for (int i = 1; i < rNodes.length; i++)
pg_map.line(rNodes[i-1].xf(), rNodes[i-1].yf(), rNodes[i].xf(), rNodes[i].yf());
//draw destination
pg_map.stroke(160, 0, 0);
if (b_selected) pg_map.fill(255, 0, 0);
else pg_map.fill(0);
pg_map.ellipse(rNodes[rNodes.length-1].xf(), rNodes[rNodes.length-1].yf(), nodeSize, nodeSize);
pg_map.popStyle();
}
pg_map.stroke(color(100, 50, 50));
for (int i = -5; i < 6; i++) { //16 rays
float fRayAngle = (f_angle) + i/TWO_PI;
pg_map.line(f_xPos, f_yPos, f_xPos-cos(fRayAngle)*i_visionDistance, f_yPos-sin(fRayAngle)*i_visionDistance);
}
pg_map.stroke(color(255, 255, 255));
pg_map.line(f_xPos, f_yPos, f_xPos-cos(f_angle)*i_visionDistance, f_yPos-sin(f_angle)*i_visionDistance);
}
}
String[][] S_citizenNames = { { "Marie", "Mari", "Sophie", "Maria", "Sophia", "Sofia", "Emilia", "Emma", "Hannah", "Hanna", "Anna", "Luisa", "Louisa", "Mia", "Emma", "Sophia", "Sofia", "Hanna", "Hannah", "Emilia",
"Mia", "Anna", "Lina", "Mila", "Klara", "Clara", "Marie", "Lea", "Leah", "Lena", "Henri", "Luisa", "Ella", "Leni", "Sophie", "Sofie", "Marie", "Maria", "Luise", "Louise", "Sophia", "Sofia",
"Elisabeth", "Katharina", "Catharina", "Charlotte", "Johanna", "Emilia", "Anna", "Luisa", "Louisa", "Victoria", "Viktoria", "Josefine", "Josephine", "Mathilda", "Matilda", "Layla", "Leyla", "Elif", "Nur", "Amira", "Aliyah", "Amina" },

View File

@@ -1,5 +1,6 @@
int i_interactableAmount = 10;
//entitiy-subklassen: papier .. computer .. mobiles ... books ... lamps ... tables ...
Interactable[] interactables = new Interactable[10];
@@ -16,28 +17,42 @@ void initInteractables() {
class Entity {
String S_name;
boolean b_linked;
int i(int x) {
return (x);
};
boolean b_selected;
boolean b_moving;
float f_xPos, f_yPos, f_xSpawn, f_ySpawn;
int i_diameter = 10; //ellipse representation on map
float f_angle;
int i_diameter = 10;
int i_nameSize = 12;
color c_selected = color(128, 50, 50);
color c_color = color(50, 200, 80);
color c_stroke = color(255, 255, 255);
//PVector v2_direction(int x, int y){
// PVector pv = new PVector(f_xPos+x,f_yPos+y);
// return (pv);
//};
PVector v2_direction = new PVector(0,0);
void spawn(int house) {
void spawn(int house) { //generic spawn
PVector v2_spawnPoint = houses.get(house).v2_randomSpawnPoint();
f_xSpawn = v2_spawnPoint.x;
f_ySpawn = v2_spawnPoint.y;
f_xPos = f_xSpawn;
f_yPos = f_ySpawn;
v2_direction.x = f_xPos;
v2_direction.y = f_yPos + 10;
f_angle = 0;
b_linked = true;
}
void spawn(int x, int y) {
void spawn(int x, int y) { //specific spawn
f_xSpawn = x;
f_ySpawn = y;
f_xPos = f_xSpawn;
f_yPos = f_ySpawn;
v2_direction.x = f_xPos;
v2_direction.y = f_yPos + 10;
b_linked = true;
}
void despawn() {

213
UI.pde
View File

@@ -1,25 +1,23 @@
Button buttons[] = new Button[3];
int i_uiTransparency = 200;
void initUI() {
i_uiX = 0;
i_uiY = 518;
i_uiW = width;
i_uiH = height - i_uiY;
buttons[0] = new Button(15, 50, 100, i_debugTextSize, 5, "Autoplay", 0);
buttons[1] = new Button(15, 70, 100, i_debugTextSize, 5, "Lock Camera", 1);
buttons[2] = new Button(15, 90, 100, i_debugTextSize, 5, "Debug", 2);
}
int i_uiX, i_uiY, i_uiW, i_uiH;
int i_uiOffsetX, i_uiOffsetY, i_uiOffsetStartX, i_uiOffsetStartY, i_initUiY;
void drawUI() {
strokeWeight(1);
line(i_uiX, i_uiY, i_uiX+i_uiW, i_uiY);
strokeWeight(0);
fill(255, i_uiTransparency);
rect(i_uiX, i_uiY, i_uiW, i_uiH);
rect(6, 4, 140, 31, 6);
fill(0);
textSize(30);
textAlign(LEFT);
text(String.format("%02d", hour()) + ":" + String.format("%02d", minute()) + ":" + String.format("%02d", second()), 10, 30);
//camera tracking
if (b_cameraFollow) {
@@ -32,78 +30,154 @@ void drawUI() {
}
}
//draw
//buttons
strokeWeight(0);
textSize(i_debugTextSize);
for (int i = 0; i < buttons.length; i++) {
buttons[i].display();
}
//clock
fill(255, i_uiTransparency);
rect(6, 4, 140, 31, 6);
textSize(30);
textAlign(LEFT);
fill(0);
text(String.format("%02d", hour()) + ":" + String.format("%02d", minute()) + ":" + String.format("%02d", second()), 10, 30);
//debug
String[] debug = {
"FPS: " + int(frameRate),
"Amount citizen: " + i_citizenAmount,
"Females: " + i_femaleCount + " Males: " + str(i_citizenAmount-i_femaleCount),
" ",
"Selected Citizen ID: " + i_selectedCitizen,
"Name: " + citizen[i_selectedCitizen].S_name,
"Gender: " + citizen[i_selectedCitizen].S_gender,
"Age: " + citizen[i_selectedCitizen].i_age,
"x: " + int(citizen[i_selectedCitizen].f_xPos),
"y: " + int(citizen[i_selectedCitizen].f_yPos),
"Movement speed: " + round(citizen[i_selectedCitizen].f_movementSpeed*100),
"Random Run: " + citizen[i_selectedCitizen].b_randomRun,
" ",
"Sunrise: " + S_sunrise,
"Sunset: " + S_sunset,
"Autoplay: " + b_autoPlayAfterSelect,
"Locked Camera: " + b_cameraFollow,
//"Velocity: ",
//"Outside",
//"Mood: "
};
int ts = i_debugTextSize;
textSize(ts);
int line = 0;
int maxLinesPerColumn = i_uiH/ts;
int columnWidth = 130;
if (maxLinesPerColumn > 0) {
int requiredColumns = (debug.length/maxLinesPerColumn)+1;
for (int i = 0; i < requiredColumns; i++) {
while (((line-(maxLinesPerColumn*i)) * ts + ts-1)+i_uiY<height && line < debug.length) {
text(debug[line], 10+(columnWidth*i), i_uiY+(ts*((line-(maxLinesPerColumn*i))+1)));
line++;
if (b_debug) {
//bottom
fill(255, i_uiTransparency);
strokeWeight(1);
line(i_uiX, i_uiY, i_uiX+i_uiW, i_uiY);
strokeWeight(0);
rect(i_uiX, i_uiY, i_uiW, i_uiH);
fill(0);
String[] debug = {
"FPS: " + int(frameRate),
"Amount citizen: " + i_citizenAmount,
"Females: " + i_femaleCount + " Males: " + str(i_citizenAmount-i_femaleCount),
" ",
"Selected Citizen ID: " + i_selectedCitizen,
"Name: " + citizen[i_selectedCitizen].S_name,
"Gender: " + citizen[i_selectedCitizen].S_gender,
"Age: " + citizen[i_selectedCitizen].i_age,
"x: " + int(citizen[i_selectedCitizen].f_xPos),
"y: " + int(citizen[i_selectedCitizen].f_yPos),
"Angle: " + citizen[i_selectedCitizen].f_angle,
"Movement speed: " + round(citizen[i_selectedCitizen].f_movementSpeed*100),
"Random Run: " + citizen[i_selectedCitizen].b_randomRun,
" ",
"Sunrise: " + S_sunrise,
"Sunset: " + S_sunset,
"Autoplay: " + b_autoPlayAfterSelect,
"Locked Camera: " + b_cameraFollow,
"Debug Mode: " + b_debug,
//"Velocity: ",
//"Outside",
//"Mood: "
};
textSize(i_debugTextSize);
int line = 0;
int maxLinesPerColumn = i_uiH/i_debugTextSize;
int columnWidth = 130;
if (maxLinesPerColumn > 0) {
int requiredColumns = (debug.length/maxLinesPerColumn)+1;
for (int i = 0; i < requiredColumns; i++) {
while (((line-(maxLinesPerColumn*i)) * i_debugTextSize + i_debugTextSize -1)+i_uiY<height && line < debug.length) {
text(debug[line], 10+(columnWidth*i), i_uiY+(i_debugTextSize*((line-(maxLinesPerColumn*i))+1)));
line++;
}
}
}
//text("FPS: " + int(frameRate), 10, i_uiY + 15);
//text("Selected Citizen: " + i_selectedCitizen, 10, i_uiY + 30);
}
//buttons
fill(150, 170, 250, 80);
rect(i_uiX+i_uiW-135, i_uiY+ts/2, 120, ts, 5);
fill(0);
text("Autoplay", i_uiX+i_uiW-135, i_uiY+ts/2+ts);
fill(150, 170, 250, 80);
rect(i_uiX+i_uiW-135, i_uiY+ts/2+1.41*ts+ts/2, 120, ts, 5);
fill(0);
text("Lock Camera", i_uiX+i_uiW-135, i_uiY+ts/2+1.41*ts+ts+ts/2);
}
void buttonFunctions(int s) {
switch (s) {
case(0):
citizen[i_selectedCitizen].b_moving = !citizen[i_selectedCitizen].b_moving;
citizen[i_selectedCitizen].b_randomRun = !citizen[i_selectedCitizen].b_randomRun;
b_autoPlayAfterSelect = !b_autoPlayAfterSelect;
break;
case(1):
b_cameraFollow = !b_cameraFollow;
break;
case(2):
b_debug = !b_debug;
//dirty
for(int i = 0; i < citizen.length; i++){
citizen[i].c_stroke = color(int(!b_debug)*255);
}
for(int i = 0; i < interactables.length; i++){
interactables[i].c_stroke = color(int(!b_debug)*255);
}
break;
case(3):
break;
default:
break;
}
}
class Button {
int i_x, i_y, i_w, i_h, i_c, i_f, i_tx;
int i_margin = 5;
String s_t;
Button(int x, int y, int w, int h, int corner, String text, int function) {
i_x = x;
i_y = y;
i_w = w;
i_h = h;
i_c = corner;
i_f = function;
s_t = text;
i_tx = i_x + (i_w/2) - (int(textWidth(s_t) /2));
}
boolean hover() {
if (mouseX > i_x - i_margin && mouseX < i_x+i_w + i_margin && mouseY > i_y - i_margin && mouseY < i_y+i_h + i_margin) return true;
else return false;
}
void click() {
buttonFunctions(i_f);
}
void display() {
fill(150, 170, 250, 150);
rect(i_x, i_y, i_w, i_h, i_c);
fill(0);
text(s_t, i_tx, i_y + i_debugTextSize);
}
}
boolean b_mouseChangeMapOffset, b_mouseChangeUiHeight;
boolean b_hoverUI;
void mousePressed() {
if (mouseButton == LEFT) {
boolean clickUI = false;
if (mouseX >= i_uiX && mouseX <= i_uiX+i_uiW && mouseY >= i_uiY-10 && mouseY <= i_uiY+10) { //drag and drop debug window size
b_mouseChangeUiHeight = true;
i_uiOffsetStartY = mouseY;
i_initUiY = i_uiY;
} else if (mouseX >= i_uiX+i_uiW-135 && mouseX <= i_uiX+i_uiW-135+120 //autoplay button
&& mouseY >= i_uiY+i_debugTextSize/2-5 && mouseY <= i_uiY+i_debugTextSize/2+i_debugTextSize+5) {
//if (b_autoPlayAfterSelect) {
// citizen[i_selectedCitizen].b_moving = false;
// citizen[i_selectedCitizen].b_randomRun = false;
//}
citizen[i_selectedCitizen].b_moving = !citizen[i_selectedCitizen].b_moving;
citizen[i_selectedCitizen].b_randomRun = !citizen[i_selectedCitizen].b_randomRun;
b_autoPlayAfterSelect = !b_autoPlayAfterSelect;
} else if (mouseX >= i_uiX+i_uiW-135 && mouseX <= i_uiX+i_uiW-135+120 //autoplay button
&& mouseY >= i_uiY+i_debugTextSize/2+1.41*i_debugTextSize+i_debugTextSize/2-5 && mouseY <= i_uiY+i_debugTextSize/2+1.41*i_debugTextSize+i_debugTextSize/2+i_debugTextSize+5) {
b_cameraFollow = !b_cameraFollow;
} else {
clickUI = true;
}
for (int i = 0; i < buttons.length; i++) {
if (buttons[i].hover()) {
buttons[i].click();
clickUI = true;
}
}
if (!clickUI) {
int selectedCitizen = i_selectedCitizen; //leftclick select citizen
for (int i = 0; i < citizen.length; i++) {
if (selectedCitizen != i) {
@@ -127,7 +201,7 @@ void mousePressed() {
citizen[i_selectedCitizen].b_randomRun = false;
citizen[i_selectedCitizen].b_moving = false;
}
citizen[i_selectedCitizen].goTo(constrain(i_mapViewToMap(mouseX, i_mapOffsetX), 0, pg_map.width), constrain(i_mapViewToMap(mouseY, i_mapOffsetY), 0, pg_map.height));
citizen[i_selectedCitizen].goTo(constrain(i_mapViewToMap(mouseX, i_mapOffsetX), 0, pg_map.width), constrain(i_mapViewToMap(mouseY, i_mapOffsetY), 0, pg_map.height), 10);
}
}
int i_mapViewToMap(int mouse, int offset) {
@@ -144,6 +218,9 @@ void mouseDragged() {
i_uiY = mouseY - i_uiOffsetStartY + i_initUiY;
if (i_uiY > height) i_uiY = height;
i_uiH = height - i_uiY;
//hook buttons to ui panel
}
}
void mouseReleased() {

View File

@@ -1,11 +1,14 @@
//settings
boolean b_smallerImage = false; //use a cropped, smaller version of the 1920x1080 image for faster development
boolean b_loadSun = false; //load sun from web-api instead of local json file (local file is adressed to january 4th 2019. might implement a check that downloads today's information only once...
boolean b_drawNodes = false;
boolean b_drawPathLine = true;
boolean b_drawPathDestination = true;
boolean b_cameraFollow = true;
boolean b_autoPlayAfterSelect = false;
boolean b_debug = true;
boolean b_drawNodes = false;
float f_nodeResolution = 0.2; //defines density of path-finding nodes, multiplied with resolution
int i_pathAlgorithm = 3;
int i_debugTextSize = 10;
@@ -69,7 +72,8 @@ void draw() {
pg_map.beginDraw();
pg_map.background(127);
pg_map.image(img_map, 0, 0, img_houses.width, img_houses.height);
if(b_debug) pg_map.image(img_houses, 0, 0, img_houses.width, img_houses.height);
else pg_map.image(img_map, 0, 0, img_houses.width, img_houses.height);
//pg_map.image(img_houses, 0, 0, img_houses.width, img_houses.height);
//image(img_streets, 0, 0, img_houses.width, img_houses.height);
@@ -92,9 +96,14 @@ void draw() {
citizen[i].update();
if (i != i_selectedCitizen)
citizen[i].display();
//citizen[i].debug();
if(b_debug)
citizen[i].debug();
}
}
citizen[i_selectedCitizen].v2_direction.x = citizen[i_selectedCitizen].f_xPos - (float)constrain(i_mapViewToMap(mouseX, i_mapOffsetX), 0, pg_map.width);
citizen[i_selectedCitizen].v2_direction.y = citizen[i_selectedCitizen].f_yPos - (float)constrain(i_mapViewToMap(mouseY, i_mapOffsetY), 0, pg_map.height);
citizen[i_selectedCitizen].display();
pg_map.endDraw();