Setup Item Drop rendering/physics. Handle items landing on the ground. Config file options related to item drops added. Added a spawning item function.

pull/28/head
sigonasr2 1 year ago
parent a29df8b954
commit 403690747d
  1. 41
      Crawler/Crawler.cpp
  2. 1
      Crawler/Crawler.h
  3. 5
      Crawler/Crawler.vcxproj
  4. 6
      Crawler/Crawler.vcxproj.filters
  5. 123
      Crawler/ItemDrop.cpp
  6. 59
      Crawler/ItemDrop.h
  7. 2
      Crawler/State_GameRun.cpp
  8. 2
      Crawler/Version.h
  9. 20
      Crawler/assets/config/items/items.txt
  10. 7
      Crawler/olcPixelGameEngine.h

@ -57,6 +57,7 @@ SUCH DAMAGE.
#include "Unlock.h" #include "Unlock.h"
#include "State_OverworldMap.h" #include "State_OverworldMap.h"
#include "Test.h" #include "Test.h"
#include "ItemDrop.h"
INCLUDE_EMITTER_LIST INCLUDE_EMITTER_LIST
@ -181,6 +182,7 @@ bool Crawler::OnUserCreate(){
GameState::Initialize(); GameState::Initialize();
Unlock::Initialize(); Unlock::Initialize();
ItemDrop::Initialize();
ValidateGameStatus(); //Checks to make sure everything has been initialized properly. ValidateGameStatus(); //Checks to make sure everything has been initialized properly.
@ -417,6 +419,9 @@ void Crawler::HandleUserInput(float fElapsedTime){
if(GetKey(I).bPressed){ if(GetKey(I).bPressed){
Menu::OpenMenu(INVENTORY); Menu::OpenMenu(INVENTORY);
} }
if(GetKey(O).bPressed){
ItemDrop::SpawnItem(&ITEM_DATA.at("Green Slime Remains"),player->GetPos());
}
} }
void Crawler::UpdateCamera(float fElapsedTime){ void Crawler::UpdateCamera(float fElapsedTime){
@ -554,6 +559,10 @@ void Crawler::PopulateRenderLists(){
foregroundEffectsUpper.clear(); foregroundEffectsUpper.clear();
endZones.clear(); endZones.clear();
upperEndZones.clear(); upperEndZones.clear();
dropsBeforeLower.clear();
dropsAfterLower.clear();
dropsBeforeUpper.clear();
dropsAfterUpper.clear();
tilePreparationList.clear(); tilePreparationList.clear();
tileForegroundList.clear(); tileForegroundList.clear();
@ -575,6 +584,22 @@ void Crawler::PopulateRenderLists(){
} }
} }
} }
for(int i=0;i<ItemDrop::drops.size();i++){
ItemDrop&drop=ItemDrop::drops[i];
if(drop.GetPos().y<pl->GetPos().y){//This item drop renders before the player does (behind the player)
if(drop.OnUpperLevel()){
dropsBeforeUpper.push_back(i);
}else{
dropsBeforeLower.push_back(i);
}
} else {//This item drop renders after the player does (in front of the player)
if(drop.OnUpperLevel()){
dropsAfterUpper.push_back(i);
}else{
dropsAfterLower.push_back(i);
}
}
}
for(auto it=BULLET_LIST.begin();it!=BULLET_LIST.end();++it){ for(auto it=BULLET_LIST.begin();it!=BULLET_LIST.end();++it){
Bullet*b=(*it).get(); Bullet*b=(*it).get();
if(b->OnUpperLevel()){ if(b->OnUpperLevel()){
@ -660,6 +685,7 @@ void Crawler::RenderWorld(float fElapsedTime){
pos=player->teleportStartPosition.lerp(player->teleportTarget,(0.35-player->teleportAnimationTimer)/0.35); pos=player->teleportStartPosition.lerp(player->teleportTarget,(0.35-player->teleportAnimationTimer)/0.35);
} }
view.DrawPartialRotatedDecal(pos+vf2d{0,-player->GetZ()*(std::signbit(scale.y)?-1:1)},player->GetFrame().GetSourceImage()->Decal(),player->GetSpinAngle(),{12,12},player->GetFrame().GetSourceRect().pos,player->GetFrame().GetSourceRect().size,playerScale*scale,player->GetBuffs(BuffType::ATTACK_UP).size()>0?Pixel{255,uint8_t(255*abs(sin(1.4*player->GetBuffs(BuffType::ATTACK_UP)[0].duration))),uint8_t(255*abs(sin(1.4*player->GetBuffs(BuffType::ATTACK_UP)[0].duration)))}:WHITE); view.DrawPartialRotatedDecal(pos+vf2d{0,-player->GetZ()*(std::signbit(scale.y)?-1:1)},player->GetFrame().GetSourceImage()->Decal(),player->GetSpinAngle(),{12,12},player->GetFrame().GetSourceRect().pos,player->GetFrame().GetSourceRect().size,playerScale*scale,player->GetBuffs(BuffType::ATTACK_UP).size()>0?Pixel{255,uint8_t(255*abs(sin(1.4*player->GetBuffs(BuffType::ATTACK_UP)[0].duration))),uint8_t(255*abs(sin(1.4*player->GetBuffs(BuffType::ATTACK_UP)[0].duration)))}:WHITE);
SetDecalMode(DecalMode::NORMAL);
if(player->GetState()==State::BLOCK){ if(player->GetState()==State::BLOCK){
view.DrawDecal(player->GetPos()-vf2d{12,12},GFX["block.png"].Decal()); view.DrawDecal(player->GetPos()-vf2d{12,12},GFX["block.png"].Decal());
} }
@ -814,12 +840,18 @@ void Crawler::RenderWorld(float fElapsedTime){
for(ZoneData&zone:endZones){ for(ZoneData&zone:endZones){
RenderZone(zone.zone); RenderZone(zone.zone);
} }
for(int index:dropsBeforeLower){
ItemDrop::drops[index].Draw();
}
for(Monster*m:monstersBeforeLower){ for(Monster*m:monstersBeforeLower){
m->Draw(); m->Draw();
} }
if(!player->upperLevel){ if(!player->upperLevel){
RenderPlayer(player->GetPos(),{1,1}); RenderPlayer(player->GetPos(),{1,1});
} }
for(int index:dropsAfterLower){
ItemDrop::drops[index].Draw();
}
for(Monster*m:monstersAfterLower){ for(Monster*m:monstersAfterLower){
m->Draw(); m->Draw();
} }
@ -965,12 +997,18 @@ void Crawler::RenderWorld(float fElapsedTime){
for(ZoneData&zone:upperEndZones){ for(ZoneData&zone:upperEndZones){
RenderZone(zone.zone); RenderZone(zone.zone);
} }
for(int index:dropsBeforeUpper){
ItemDrop::drops[index].Draw();
}
for(Monster*m:monstersBeforeUpper){ for(Monster*m:monstersBeforeUpper){
m->Draw(); m->Draw();
} }
if(player->upperLevel){ if(player->upperLevel){
RenderPlayer(player->GetPos(),{1,1}); RenderPlayer(player->GetPos(),{1,1});
} }
for(int index:dropsAfterUpper){
ItemDrop::drops[index].Draw();
}
for(Monster*m:monstersAfterUpper){ for(Monster*m:monstersAfterUpper){
m->Draw(); m->Draw();
} }
@ -1962,6 +2000,9 @@ void Crawler::ValidateGameStatus(){
if(!Unlock::IsUnlocked(State_OverworldMap::GetCurrentConnectionPoint())){ if(!Unlock::IsUnlocked(State_OverworldMap::GetCurrentConnectionPoint())){
ERR("WARNING! The current connection point is not unlocked! This is not supposed to be happening.") ERR("WARNING! The current connection point is not unlocked! This is not supposed to be happening.")
} }
if(ItemDrop::gravity!="ItemDrop.Item Drop Gravity"_F){
ERR("WARNING! Gravity constant for item drops was not initialized to "<<"Item Drop Gravity"_F<<". Actual value: "<<ItemDrop::gravity);
}
} }
void Crawler::RenderVersionInfo(){ void Crawler::RenderVersionInfo(){

@ -65,6 +65,7 @@ public:
private: private:
std::vector<std::unique_ptr<Effect>>foregroundEffects,backgroundEffects,foregroundEffectsToBeInserted,backgroundEffectsToBeInserted; std::vector<std::unique_ptr<Effect>>foregroundEffects,backgroundEffects,foregroundEffectsToBeInserted,backgroundEffectsToBeInserted;
std::vector<TileRenderData*>tilePreparationList,tileForegroundList; std::vector<TileRenderData*>tilePreparationList,tileForegroundList;
std::vector<int>dropsBeforeLower,dropsAfterLower,dropsBeforeUpper,dropsAfterUpper;
std::vector<ZoneData>endZones,upperEndZones; std::vector<ZoneData>endZones,upperEndZones;
std::vector<vf2d>circleCooldownPoints; std::vector<vf2d>circleCooldownPoints;
std::map<std::string,TilesetData>MAP_TILESETS; std::map<std::string,TilesetData>MAP_TILESETS;

@ -286,6 +286,10 @@
<ClInclude Include="Error.h" /> <ClInclude Include="Error.h" />
<ClInclude Include="GameState.h" /> <ClInclude Include="GameState.h" />
<ClInclude Include="Item.h" /> <ClInclude Include="Item.h" />
<ClInclude Include="ItemDrop.h">
<SubType>
</SubType>
</ClInclude>
<ClInclude Include="MenuAnimatedIconToggleButton.h" /> <ClInclude Include="MenuAnimatedIconToggleButton.h" />
<ClInclude Include="MenuComponent.h" /> <ClInclude Include="MenuComponent.h" />
<ClInclude Include="MenuIconButton.h" /> <ClInclude Include="MenuIconButton.h" />
@ -354,6 +358,7 @@
<ClCompile Include="GameState.cpp" /> <ClCompile Include="GameState.cpp" />
<ClCompile Include="InventoryConsumableWindow.cpp" /> <ClCompile Include="InventoryConsumableWindow.cpp" />
<ClCompile Include="Item.cpp" /> <ClCompile Include="Item.cpp" />
<ClCompile Include="ItemDrop.cpp" />
<ClCompile Include="ItemLoadoutWindow.cpp" /> <ClCompile Include="ItemLoadoutWindow.cpp" />
<ClCompile Include="Key.cpp" /> <ClCompile Include="Key.cpp" />
<ClCompile Include="LevelCompleteWindow.cpp" /> <ClCompile Include="LevelCompleteWindow.cpp" />

@ -258,6 +258,9 @@
<ClInclude Include="Item.h"> <ClInclude Include="Item.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="ItemDrop.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="Player.cpp"> <ClCompile Include="Player.cpp">
@ -434,6 +437,9 @@
<ClCompile Include="State_LevelComplete.cpp"> <ClCompile Include="State_LevelComplete.cpp">
<Filter>Source Files\Game States</Filter> <Filter>Source Files\Game States</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="ItemDrop.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="cpp.hint" /> <None Include="cpp.hint" />

@ -0,0 +1,123 @@
#pragma region License
/*
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions or derivations of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions or derivative works in binary form must reproduce the above
copyright notice. This list of conditions and the following disclaimer must be
reproduced in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may
be used to endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
#pragma endregion
#include "ItemDrop.h"
#include "olcUTIL_Geometry2D.h"
#include "Crawler.h"
INCLUDE_game
INCLUDE_GFX
float ItemDrop::gravity;
std::vector<ItemDrop>ItemDrop::drops;
void ItemDrop::Initialize(){
gravity="ItemDrop.Item Drop Gravity"_F;
}
ItemDrop::ItemDrop(ItemInfo*item,vf2d pos)
:item(item),pos(pos){
speed.x=util::random("ItemDrop.Item Drop Horizontal Speed"_f[1]-"ItemDrop.Item Drop Horizontal Speed"_f[0])+"ItemDrop.Item Drop Horizontal Speed"_f[0];
speed.y=util::random("ItemDrop.Item Drop Vertical Speed"_f[1]-"ItemDrop.Item Drop Vertical Speed"_f[0])+"ItemDrop.Item Drop Vertical Speed"_f[0];
zSpeed="ItemDrop.Item Drop Initial Rise Speed"_F;
}
vf2d ItemDrop::GetPos(){
return pos;
}
bool ItemDrop::OnUpperLevel(){
return upperLevel;
}
void ItemDrop::Draw(){
#pragma region Item Drop Shadow Rendering
if(GetZ()>0){
vf2d shadowScale=vf2d{8*"ItemDrop.Item Drop Scale"_F/3.f,1}/std::max(1.f,GetZ()/24);
game->view.DrawDecal(GetPos()-vf2d{3,3}*shadowScale/2+vf2d{0,6*"ItemDrop.Item Drop Scale"_F},GFX["circle.png"].Decal(),shadowScale,BLACK);
}
#pragma endregion
game->view.DrawRotatedDecal(pos-vf2d{0,GetZ()},item->Decal(),0,item->Decal()->sprite->Size()/2,{"ItemDrop.Item Drop Scale"_F,"ItemDrop.Item Drop Scale"_F});
game->SetDecalMode(DecalMode::ADDITIVE);
game->view.DrawRotatedDecal(pos-vf2d{0,GetZ()},item->Decal(),0,item->Decal()->sprite->Size()/2,{"ItemDrop.Item Drop Scale"_F,"ItemDrop.Item Drop Scale"_F},{uint8_t(abs(sin(game->levelTime*1.5)*255.f)),uint8_t(abs(sin(game->levelTime*1.5)*255.f)),uint8_t(abs(sin(game->levelTime*1.5)*255.f)),255});
game->SetDecalMode(DecalMode::NORMAL);
}
void ItemDrop::UpdateDrops(float fElapsedTime){
for(ItemDrop&drop:drops){
#pragma region Handle Z Speed
drop.z+=drop.zSpeed*fElapsedTime;
if(drop.z<0)drop.zSpeed=0;
else{
drop.zSpeed+=gravity*fElapsedTime;
drop.pos+=drop.speed*fElapsedTime;
}
#pragma endregion
#pragma region Check for Suction / Player pull-in
if(drop.zSpeed==0&&drop.OnUpperLevel()==game->GetPlayer()->OnUpperLevel()){
geom2d::line<float>lineTo=geom2d::line<float>(drop.pos,game->GetPlayer()->GetPos());
float dist=lineTo.length();
if(dist<="ItemDrop.Item Drop Suction Range"_F){
vf2d pointVel=lineTo.vector();
drop.pos+=pointVel*(1/dist*fElapsedTime);
}
}
#pragma endregion
#pragma region Handle Upper/Lower Level Zone Intersecting
if(drop.speed.mag()>0){
std::map<std::string,std::vector<ZoneData>>&zoneData=game->GetZoneData(game->GetCurrentLevel());
for(ZoneData&upperLevelZone:zoneData["UpperZone"]){
if(geom2d::overlaps(upperLevelZone.zone,drop.pos)){
drop.upperLevel=true;
}
}
for(ZoneData&lowerLevelZone:zoneData["LowerZone"]){
if(geom2d::overlaps(lowerLevelZone.zone,drop.pos)){
drop.upperLevel=false;
}
}
}
#pragma endregion
}
}
float ItemDrop::GetZ(){
return z;
}
void ItemDrop::SpawnItem(ItemInfo*item,vf2d pos){
drops.push_back(ItemDrop{item,pos});
}

@ -0,0 +1,59 @@
#pragma region License
/*
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2023 OneLoneCoder.com
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions or derivations of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions or derivative works in binary form must reproduce the above
copyright notice. This list of conditions and the following disclaimer must be
reproduced in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may
be used to endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
#pragma endregion
#include "olcPixelGameEngine.h"
#include "Item.h"
#include "util.h"
#include "Crawler.h"
class ItemDrop{
friend class Crawler;
vf2d pos;
vf2d speed{};
float zSpeed=0;
float z=0;
float randomSpinOffset=0;
ItemInfo*item=nullptr;
bool upperLevel=false;
static float gravity;
static std::vector<ItemDrop>drops;
ItemDrop(ItemInfo*item,vf2d pos);
public:
static void Initialize();
vf2d GetPos();
bool OnUpperLevel();
void Draw();
static void UpdateDrops(float fElapsedTime);
float GetZ();
static void SpawnItem(ItemInfo*item,vf2d pos);
};

@ -35,6 +35,7 @@ SUCH DAMAGE.
#include "Crawler.h" #include "Crawler.h"
#include "DEFINES.h" #include "DEFINES.h"
#include "Menu.h" #include "Menu.h"
#include "ItemDrop.h"
INCLUDE_MONSTER_LIST INCLUDE_MONSTER_LIST
INCLUDE_game INCLUDE_game
@ -63,6 +64,7 @@ void State_GameRun::OnUserUpdate(Crawler*game){
} }
game->monstersToBeSpawned.clear(); game->monstersToBeSpawned.clear();
ItemDrop::UpdateDrops(game->GetElapsedTime());
game->UpdateBullets(game->GetElapsedTime()); game->UpdateBullets(game->GetElapsedTime());
game->UpdateCamera(game->GetElapsedTime()); game->UpdateCamera(game->GetElapsedTime());
}; };

@ -35,7 +35,7 @@ SUCH DAMAGE.
#define VERSION_MAJOR 0 #define VERSION_MAJOR 0
#define VERSION_MINOR 2 #define VERSION_MINOR 2
#define VERSION_PATCH 1 #define VERSION_PATCH 1
#define VERSION_BUILD 2998 #define VERSION_BUILD 3052
#define stringify(a) stringify_(a) #define stringify(a) stringify_(a)
#define stringify_(a) #a #define stringify_(a) #a

@ -3,4 +3,24 @@ ItemConfiguration
Item Database = "ItemDatabase.txt" Item Database = "ItemDatabase.txt"
Item Scripts = "ItemScript.txt" Item Scripts = "ItemScript.txt"
Item Categories = "ItemCategory.txt Item Categories = "ItemCategory.txt
}
ItemDrop
{
# Item drops horizontal random speed range
Item Drop Horizontal Speed = -30,30
# Item drops vertical random speed range
Item Drop Vertical Speed = -15,15
# Item drop suction range
Item Drop Suction Range = 48
# Item drop initial rise speed
Item Drop Initial Rise Speed = 10
# Item drop gravity
Item Drop Gravity = -9.8
# Item drop scale
Item Drop Scale = 0.4
} }

@ -851,6 +851,8 @@ namespace olc
STENCIL, STENCIL,
ILLUMINATE, ILLUMINATE,
WIREFRAME, WIREFRAME,
BLENDWHITE,
SCREEN,
MODEL3D, MODEL3D,
}; };
@ -4505,6 +4507,11 @@ namespace olc
case olc::DecalMode::WIREFRAME: case olc::DecalMode::WIREFRAME:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
break; break;
case olc::DecalMode::BLENDWHITE:
break;
case olc::DecalMode::SCREEN:
glBlendFunc(GL_ONE, GL_ONE);
break;
} }
nDecalMode = mode; nDecalMode = mode;

Loading…
Cancel
Save