소스 검색

Merge pull request #16 from CrystalPointA4/feature/portal_logic

Feature/portal logic
Kenneth van Ewijk 9 년 전
부모
커밋
31c11f3e1f
18개의 변경된 파일234개의 추가작업 그리고 48개의 파일을 삭제
  1. 14 4
      Crystal.cpp
  2. 2 1
      Crystal.h
  3. 2 0
      CrystalPoint.vcxproj
  4. 9 3
      CrystalPoint.vcxproj.filters
  5. 9 1
      Enemy.cpp
  6. 1 0
      Enemy.h
  7. 21 7
      Interface.cpp
  8. 2 0
      Interface.h
  9. 2 1
      Main.cpp
  10. 34 0
      Portal.cpp
  11. 19 0
      Portal.h
  12. 16 0
      Skybox.cpp
  13. 3 0
      Skybox.h
  14. 51 5
      World.cpp
  15. 3 1
      World.h
  16. 2 0
      WorldHandler.cpp
  17. 34 24
      worlds/ice.json
  18. 10 1
      worlds/small.json

+ 14 - 4
Crystal.cpp

@@ -5,10 +5,11 @@
 
 Crystal::Crystal(const std::string & filled, const std::string & empty, const Vec3f & position, Vec3f & rotation, const float & scale)
 {
-	this->filled = filled;
-	this->empty = empty;
+	this->filled = Model::load(filled);
+	this->empty = Model::load(empty);
+	model = this->filled;
+	
 
-	model = Model::load(this->filled);
 	this->position = position;
 	this->rotation = rotation;
 	this->scale = scale;
@@ -20,6 +21,15 @@ Crystal::~Crystal()
 {
 	if (model)
 		Model::unload(model);
+
+	//if isfilled, means model is model filled, so model empty has to been deleted.
+	//if is not filled, means model is model empty, so model filled has to been deleted.
+	if (isFilled)
+		if(empty)
+			Model::unload(empty);
+	else
+		if(filled)
+			Model::unload(filled);
 }
 
 void Crystal::draw()
@@ -33,6 +43,6 @@ void Crystal::collide()
 	{
 		Player::getInstance()->crystals++;
 		isFilled = false;
-		model = Model::load(empty);
+		model = empty;
 	}	
 }

+ 2 - 1
Crystal.h

@@ -14,6 +14,7 @@ public:
 	void draw();
 	void collide();
 private:
-	std::string filled, empty;
+	Model* filled;
+	Model* empty;
 };
 

+ 2 - 0
CrystalPoint.vcxproj

@@ -165,6 +165,7 @@
     <ClCompile Include="LevelObject.cpp" />
     <ClCompile Include="Main.cpp" />
     <ClCompile Include="Model.cpp" />
+    <ClCompile Include="Portal.cpp" />
     <ClCompile Include="Sound.cpp" />
     <ClCompile Include="SoundSystem.cpp" />
     <ClCompile Include="Player.cpp" />
@@ -186,6 +187,7 @@
     <ClInclude Include="LevelObject.h" />
     <ClInclude Include="Main.h" />
     <ClInclude Include="Model.h" />
+    <ClInclude Include="Portal.h" />
     <ClInclude Include="Sound.h" />
     <ClInclude Include="SoundSystem.h" />
     <ClInclude Include="Player.h" />

+ 9 - 3
CrystalPoint.vcxproj.filters

@@ -79,10 +79,13 @@
       <Filter>Source Files</Filter>
     </ClCompile>
     <ClCompile Include="Sound.cpp">
-		<Filter>Source Files</Filter>
+      <Filter>Source Files</Filter>
     </ClCompile>
     <ClCompile Include="Crystal.cpp">
-		<Filter>Source Files</Filter>
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Portal.cpp">
+      <Filter>Source Files</Filter>
     </ClCompile>
   </ItemGroup>
   <ItemGroup>
@@ -138,7 +141,7 @@
       <Filter>Header Files</Filter>
     </ClInclude>
     <ClInclude Include="Sound.h">
-	  <Filter>Header Files</Filter>
+      <Filter>Header Files</Filter>
     </ClInclude>
     <ClInclude Include="Crystal.h">
       <Filter>Header Files</Filter>
@@ -146,6 +149,9 @@
     <ClInclude Include="Skybox.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="Portal.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="worlds\worlds.json">

+ 9 - 1
Enemy.cpp

@@ -20,6 +20,7 @@ Enemy::Enemy(const std::string &fileName,
 	radius = 10;
 	hasTarget = false;
 	hit_sound_id = CrystalPoint::GetSoundSystem().LoadSound("WAVE/Sound.wav", false);
+	attack = false;
 }
 
 
@@ -83,6 +84,8 @@ void Enemy::update(float delta)
 		length = sqrt(dx*dx + dz*dz);
 		if (length > 1)
 		{
+			attack = false;
+
 			dx /= length;
 			dz /= length;
 
@@ -92,6 +95,11 @@ void Enemy::update(float delta)
 			position.x += dx;
 			position.z += dz;
 		}
+		else
+		{	
+			attack = true;
+		}
+
 		rotation.y = atan2f(dx, dz) * 180 / M_PI;		
 	}
 
@@ -101,4 +109,4 @@ void Enemy::update(float delta)
 		sound->SetPos(position, Vec3f());
 		sound->Play();
 	}
-}
+}

+ 1 - 0
Enemy.h

@@ -13,6 +13,7 @@ public:
 	bool hasTarget;
 	Vec3f target;
 	float speed,radius;
+	bool attack;
 
 	void update(float);
 	void draw();

+ 21 - 7
Interface.cpp

@@ -14,6 +14,15 @@ Interface::Interface()
 	crystalWidth = 20;
 	crystalHeight = 50;
 	crystalOffset = 5;
+	maxCrystals = 0;
+}
+
+Interface::Interface(int maxCrystal)
+{
+	crystalWidth = 20;
+	crystalHeight = 50;
+	crystalOffset = 5;
+	maxCrystals = maxCrystal;
 }
 
 
@@ -80,18 +89,23 @@ void Interface::draw()
 	glColor4f(1.0f, 1.0f, 0.1f, 1.0);
 	glutBitmapString("Level: " + std::to_string(player->level), 490, 900);
 
-	int cw, ch, offset;
-	cw = 20;
-	ch = 50;
-	offset = 5;
-	for (int i = 0; i < player->crystals; i++)
+	for (int i = 0; i < maxCrystals; i++)
 	{
 		glBegin(GL_QUADS);
-		glColor4f(0, 1.0f, 1.0f, 1.0f);
+
+		if(i < player->crystals)
+			glColor4f(0, 1.0f, 1.0f, 1.0f);
+		else
+			glColor4f(0, 0.4f, 0.4f, 1.0f);
+
 		glVertex2f(975 - crystalWidth / 2	, crystalOffset*i + crystalHeight*i);
 		glVertex2f(975 - crystalWidth		, crystalHeight / 2 + crystalOffset*i + crystalHeight*i);
 
-		glColor4f(0, 0.8f, 0.8f, 1.0f);
+		if (i < player->crystals)
+			glColor4f(0, 0.7f, 0.7f, 1.0f);
+		else
+			glColor4f(0, 0.2f, 0.2f, 1.0f);
+
 		glVertex2f(975 - crystalWidth / 2	, crystalHeight + crystalOffset*i + crystalHeight*i);
 		glVertex2f(975						, crystalHeight / 2 + crystalOffset*i + crystalHeight*i);
 		glEnd();

+ 2 - 0
Interface.h

@@ -3,11 +3,13 @@ class Interface
 {
 public:
 	Interface();
+	Interface(int);
 	~Interface();
 
 	void draw(void);
 	void update(float deltaTime);
 
 	int crystalWidth, crystalHeight, crystalOffset;
+	int maxCrystals;
 };
 

+ 2 - 1
Main.cpp

@@ -64,7 +64,8 @@ void configureOpenGL()
 	//Init window and glut display mode
 	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
 	glutInitWindowSize(800, 600);
-	glutCreateWindow("Crystal Point");
+	//glutInitWindowPosition(glutGet(GLUT_WINDOW_WIDTH) / 2 - 800/2, glutGet(GLUT_WINDOW_HEIGHT) / 2 - 600/2);
+	glutCreateWindow("Crystal Point");	
 	glutFullScreen();
 
 	//Depth testing

+ 34 - 0
Portal.cpp

@@ -0,0 +1,34 @@
+#include "Portal.h"
+#include "Model.h"
+#include <iostream>
+#include "Player.h"
+#include "WorldHandler.h"
+
+Portal::Portal(const std::string &fileName,
+	const Vec3f &position,
+	Vec3f &rotation,
+	const float &scale)
+{
+	model = Model::load(fileName);
+	this->position = position;
+	this->rotation = rotation;
+	this->scale = scale;
+	this->canCollide = true;
+
+	mayEnter = false;
+	maxCrystals = 0;
+}
+
+
+Portal::~Portal()
+{
+}
+
+void Portal::collide()
+{		
+	if (maxCrystals == (Player::getInstance()->crystals) && !mayEnter)
+	{
+		canCollide = false;
+		mayEnter = true;
+	}
+}

+ 19 - 0
Portal.h

@@ -0,0 +1,19 @@
+#pragma once
+#include "Entity.h"
+#include <string>
+
+class Portal :
+	public Entity
+{
+public:
+	Portal(const std::string &fileName,
+		const Vec3f &position,
+		Vec3f &rotation,
+		const float &scale);
+	~Portal();
+
+	void collide();
+	int maxCrystals;
+	bool mayEnter;
+};
+

+ 16 - 0
Skybox.cpp

@@ -4,6 +4,7 @@
 #include "stb_image.h"
 #include "Skybox.h"
 #include <string>
+#include <iostream>
 
 enum{SKY_LEFT=0,SKY_BACK,SKY_RIGHT,SKY_FRONT,SKY_TOP,SKY_BOTTOM};
 GLuint skybox[6];
@@ -12,6 +13,9 @@ Skybox::Skybox(const float &size, const std::string &folder)
 {
 	this->size = size;
 	this->folder = folder;
+
+	brightness = 80;
+	targetBrightness = 80;
 }
 
 Skybox::~Skybox()
@@ -31,6 +35,8 @@ void Skybox::init()
 
 void Skybox::draw()
 {
+	glColor4f(brightness/255, brightness/255, brightness/255, 1);
+
 	bool b1 = glIsEnabled(GL_TEXTURE_2D);
 	glDisable(GL_LIGHTING);
 	glDisable(GL_DEPTH_TEST);
@@ -114,6 +120,16 @@ void Skybox::draw()
 		glDisable(GL_TEXTURE_2D);
 }
 
+void Skybox::update(float deltaTime, int curr, int max)
+{
+	targetBrightness = 80 + ((255 - 80) / max) * curr;
+
+	if (targetBrightness > brightness)
+	{
+		brightness += 20 * deltaTime;
+	}
+}
+
 GLuint Skybox::loadTexture(const std::string & fileName)  //load the filename named texture
 {
 	int width, height, bpp;

+ 3 - 0
Skybox.h

@@ -6,11 +6,14 @@ class Skybox
 private:
 	float size;
 	std::string folder;
+	float brightness;
+	float targetBrightness;
 public:
 	Skybox(const float &size, const std::string &folder);
 	~Skybox();
 
 	void init();
 	void draw();
+	void update(float deltaTime, int, int);
 	GLuint loadTexture(const std::string &fileName);
 };

+ 51 - 5
World.cpp

@@ -6,6 +6,7 @@
 #include "CrystalPoint.h"
 #include <fstream>
 #include <iostream>
+#include <algorithm>
 #include "WorldHandler.h"
 
 World::World(const std::string &fileName):
@@ -94,11 +95,12 @@ World::World(const std::string &fileName):
 
 		//Create
 		Vec3f position(object["pos"][0].asFloat(), object["pos"][1].asFloat(), object["pos"][2].asFloat());		
-		position.y = getHeight(position.x, position.z) + 2.0f;
+		position.y = getHeight(position.x, position.z);
 
 		entities.push_back(new LevelObject(object["file"].asString(), position, rotation, scale, hasCollision));
 	}
 
+	maxEnemies = 0;
 	//Load and place enemies into world
 	for (auto e : v["enemies"])
 	{		
@@ -124,9 +126,10 @@ World::World(const std::string &fileName):
 		Vec3f position(e["pos"][0].asFloat(), e["pos"][1].asFloat(), e["pos"][2].asFloat());
 		position.y = getHeight(position.x, position.z) + 2.0f;
 
+		maxEnemies++;
 		enemies.push_back(new Enemy(e["file"].asString(), position, rotation, scale));
 	}
-
+	maxCrystals = 0;
 	if (!v["crystal"].isNull())
 	{
 		std::string filled = "unknown";
@@ -164,11 +167,12 @@ World::World(const std::string &fileName):
 					scale = instance["scale"].asFloat();
 
 				position.y = getHeight(position.x, position.z);
-
+				maxCrystals++;
 				Crystal *c = new Crystal(filled, empty, position, rotation, scale);
 								
 				entities.push_back(c);
 			}
+			interface->maxCrystals = maxCrystals;
 		}
 	}
 
@@ -180,6 +184,30 @@ World::World(const std::string &fileName):
 		music->Play();
 	}
 
+	if (!v["portal"].isNull())
+	{
+		Vec3f pos(0, 0, 0);
+		if (!v["portal"]["pos"].isNull())
+			pos = Vec3f(v["portal"]["pos"][0].asFloat(),
+				v["portal"]["pos"][1].asFloat(),
+				v["portal"]["pos"][0].asFloat());
+
+		pos.y = getHeight(pos.x, pos.z);
+
+		Vec3f rot(0, 0, 0);
+		if (!v["portal"]["rot"].isNull())
+			pos = Vec3f(v["portal"]["rot"][0].asFloat(),
+				v["portal"]["rot"][1].asFloat(),
+				v["portal"]["rot"][0].asFloat());
+
+		float scale = 1.0f;
+		if (!v["portal"]["scale"].isNull())
+			scale = !v["portal"]["scale"].asFloat();
+
+		portal = new Portal(v["portal"]["file"], pos, rot, scale);
+		entities.push_back(portal);
+		portal->maxCrystals = maxCrystals;
+	}
 }
 
 
@@ -214,8 +242,6 @@ void World::draw()
 	float lightAmbient[4] = { 0.2, 0.2, 0.2, 1 };
 	glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient);
 
-	glColor4f(1, 1, 1, 1);
-
 	skybox->draw();
 
 	heightmap->Draw();
@@ -234,6 +260,9 @@ void World::update(float elapsedTime)
 	for (auto &entity : entities)
 		entity->update(elapsedTime);
 
+	int count = 0;
+	int remove = false;
+
 	for (auto &enemy : enemies)
 	{
 
@@ -252,9 +281,26 @@ void World::update(float elapsedTime)
 					break;
 				}
 			}
+
+			if (enemy->attack)
+			{
+				remove = true;
+				continue;
+			}
 		}
 		enemy->position.y = getHeight(enemy->position.x, enemy->position.z) + 2.0f;
+		
+		if(!remove)
+			count++;
 	}
+
+	if(remove)
+		enemies.erase(enemies.begin() + count);
+
+	skybox->update(elapsedTime, maxEnemies - enemies.size(), maxEnemies);
+
+	if (portal->mayEnter)
+		WorldHandler::getInstance()->NextWorld();
 }
 
 void World::addLevelObject(LevelObject* obj)

+ 3 - 1
World.h

@@ -8,6 +8,7 @@
 #include "Interface.h"
 #include "Crystal.h"
 #include "Skybox.h"
+#include "Portal.h"
 
 class Entity;
 
@@ -20,8 +21,9 @@ private:
 	HeightMap* heightmap;
 	Interface* interface;
 	Skybox* skybox;
+	Portal* portal;
 	
-	int music_id;
+	int music_id,maxCrystals,maxEnemies;
 
 	std::vector<Entity*> entities;
 	std::vector<Enemy*> enemies;

+ 2 - 0
WorldHandler.cpp

@@ -126,6 +126,7 @@ void WorldHandler::NextWorld()
 	if (!loadingWorld)
 	{
 		ChangeWorld(worldIndex + 1);
+		Player::getInstance()->crystals = 0;
 	}
 }
 
@@ -134,5 +135,6 @@ void WorldHandler::PreviousWorld()
 	if (!loadingWorld)
 	{
 		ChangeWorld(worldIndex - 1);
+		Player::getInstance()->crystals = 0;
 	}
 }

+ 34 - 24
worlds/ice.json

@@ -1,33 +1,43 @@
 {
-   "world": {
+  "world": {
     "heightmap": "worlds/hmcs.png",
-    "texture": "worlds/hmcstexture.png",
+    "texture":  "hmcstexture.png",
+    "skybox": "skyboxes/peaceful/",
     "object-templates": [
-		{
-			"color":100,
-			"file": "models/boom/Boom.obj",
-			"collision": false
-		}
-	]
-   },
+      {
+        "color": 100,
+        "file": "models/boom/Boom.obj",
+        "collision": true
+      }
+    ],
+	"music": "WAVE/bond.wav"
+  },
   "player": {
-    "startposition": [ 0, 1.7, 0]
+    "startposition": [ 1, 5, 20 ]
+  },
+  "objects": [ ],
+  "portal": {     
+    "file": "models/Teleporter/Teleporter.obj",
+    "pos": [ 10, 5, 10 ]    
   },
-  "objects": [
-    {
-      "file": "models/boom/Boom.obj",
-      "pos": [ 10, 0, -4 ]
-    },
-    {
-      "file": "models/Teleporter/Teleporter.obj",
-      "pos": [ 0, 0, -4 ]
-    }
-  ],
   "enemies": [
-    {
+  {
       "file": "models/squid/Blooper.obj",
-      "pos": [ 10, 2, -10 ],
+      "pos": [ 20, 5, 10 ],
       "scale": 0.01
-    }
-  ]
+  }],
+  "crystal": {
+    "full texture": "models/crystal/Crystal.obj",
+    "empty texture": "models/crystal/PickedUpCrystal.obj",
+    "instances": [
+      {
+        "pos": [ 31, 5, 33 ],
+        "rot": [ 0, 0, 0 ]
+      },
+      {
+        "pos": [ 40, 5, 40 ],
+        "rot": [ 0, 0, 0 ]
+      }
+    ]
+  }
 }

+ 10 - 1
worlds/small.json

@@ -15,11 +15,20 @@
     "startposition": [ 20, 5, 20 ]
   },
   "objects": [ ],
+  "portal": {     
+    "file": "models/Teleporter/Teleporter.obj",
+    "pos": [ 10, 5, 10 ]    
+  },
   "enemies": [
-  {
+    {
       "file": "models/squid/Blooper.obj",
       "pos": [ 20, 5, 10 ],
       "scale": 0.01
+    },
+    {
+      "file": "models/squid/Blooper.obj",
+      "pos": [ 30, 10, 10 ],
+      "scale": 0.01
   }],
   "crystal": {
     "full texture": "models/crystal/Crystal.obj",