Add hit reset flag for monsters that charge at players such that they must reset it to damage the player with contact damage again. Player spawn location now reads from the level file. Collision tile data loaded.

This commit is contained in:
sigonasr2 2023-06-23 20:42:55 -07:00
parent d9e8c6ddbd
commit cdab15d8d3
13 changed files with 78 additions and 45 deletions

View File

@ -8,6 +8,7 @@
#include "Version.h"
#include "TMXParser.h"
#include "TSXParser.h"
#include "Map.h"
#include "DEFINES.h"
//192x192
@ -342,11 +343,7 @@ void Crawler::HandleUserInput(float fElapsedTime){
}
if(player.GetVelocity()==vf2d{0,0}){
if(RightHeld()){
if(player.GetPos().x+12*player.GetSizeMult()+fElapsedTime*100*player.GetMoveSpdMult()<WORLD_SIZE.x*24){
player.SetX(player.GetX()+fElapsedTime*100*player.GetMoveSpdMult());
} else {
player.SetX(WORLD_SIZE.x*24-12);
}
player.SetX(player.GetX()+fElapsedTime*100*player.GetMoveSpdMult());
player.SetFacingDirection(RIGHT);
if(player.GetState()==State::NORMAL){
player.UpdateWalkingAnimation(RIGHT);
@ -354,11 +351,7 @@ void Crawler::HandleUserInput(float fElapsedTime){
setIdleAnimation=false;
}
if(LeftHeld()){
if(player.GetPos().x-12*player.GetSizeMult()+fElapsedTime*100*player.GetMoveSpdMult()>0){
player.SetX(player.GetX()-fElapsedTime*100*player.GetMoveSpdMult());
} else {
player.SetX(12);
}
player.SetX(player.GetX()-fElapsedTime*100*player.GetMoveSpdMult());
if(setIdleAnimation){
player.SetFacingDirection(LEFT);
if(player.GetState()==State::NORMAL){
@ -368,11 +361,7 @@ void Crawler::HandleUserInput(float fElapsedTime){
setIdleAnimation=false;
}
if(UpHeld()){
if(player.GetPos().y-12*player.GetSizeMult()+fElapsedTime*100*player.GetMoveSpdMult()>0){
player.SetY(player.GetY()-fElapsedTime*100*player.GetMoveSpdMult());
} else {
player.SetY(12);
}
player.SetY(player.GetY()-fElapsedTime*100*player.GetMoveSpdMult());
if(setIdleAnimation){
player.SetFacingDirection(UP);
if(player.GetState()==State::NORMAL){
@ -382,11 +371,7 @@ void Crawler::HandleUserInput(float fElapsedTime){
setIdleAnimation=false;
}
if(DownHeld()){
if(player.GetPos().y+12*player.GetSizeMult()+fElapsedTime*100*player.GetMoveSpdMult()<WORLD_SIZE.y*24){
player.SetY(player.GetY()+fElapsedTime*100*player.GetMoveSpdMult());
} else {
player.SetY(WORLD_SIZE.y*24-12);
}
player.SetY(player.GetY()+fElapsedTime*100*player.GetMoveSpdMult());
if(setIdleAnimation){
player.SetFacingDirection(DOWN);
if(player.GetState()==State::NORMAL){
@ -624,6 +609,11 @@ void Crawler::RenderWorld(float fElapsedTime){
if(!IsForegroundTile(tileSheet,tileSheetIndex)){
view.DrawPartialDecal(vi2d{x,y}*24,{24,24},tileSheet.tileset.tileset->Decal(),vi2d{tileSheetX,tileSheetY}*24,{24,24});
}
if(tileSheet.tileset.collision.find(tileSheetIndex)!=tileSheet.tileset.collision.end()){
geom2d::rect<int>collision=tileSheet.tileset.collision[tileSheetIndex].collision;
view.FillRectDecal(vi2d{x,y}*24+collision.pos,collision.size,{0,0,0,128});
view.DrawRectDecal(vi2d{x,y}*24+collision.pos,collision.size,GREY);
}
}
}
}
@ -797,6 +787,7 @@ void Crawler::InitializeLevel(std::string mapFile,MapName map){
Renderable*r=new Renderable();
MAP_TILESETS["assets/maps/"+baseSourceDir].tileset=r;
MAP_TILESETS["assets/maps/"+baseSourceDir].foregroundTiles=tileset.GetData().ForegroundTileData;
MAP_TILESETS["assets/maps/"+baseSourceDir].collision=tileset.GetData().CollisionData;
r->Load("assets/maps/"+tileset.GetData().ImageData.data["source"]);
}
}
@ -806,6 +797,7 @@ void Crawler::LoadLevel(MapName map){
SPAWNER_LIST.clear();
foregroundTileGroups.clear();
currentLevel=map;
player.SetPos(MAP_DATA[map].MapData.playerSpawnLocation);
WORLD_SIZE={MAP_DATA[map].MapData.width,MAP_DATA[map].MapData.height};
for(SpawnerTag&spawner:MAP_DATA[map].SpawnerData){
std::vector<std::pair<MonsterName,vf2d>>monster_list;

View File

@ -32,13 +32,13 @@ class Crawler : public olc::PixelGameEngine
vf2d worldShakeVel={};
const float WORLD_SHAKE_ADJUST_MAX_TIME=0.4;
MapName currentLevel=MapName::CAMPAIGN_1_1;
vi2d WORLD_SIZE={120,8};
std::vector<TileGroup>foregroundTileGroups;
public:
Crawler();
public:
vi2d WORLD_SIZE={120,8};
TileTransformedView view;
bool OnUserCreate() override;
bool OnUserUpdate(float fElapsedTime) override;

View File

@ -164,7 +164,7 @@
"id": 4,
"members": [
],
"name": "SpawnLocation",
"name": "PlayerSpawnLocation",
"type": "class",
"useAs": [
"property",

View File

@ -1,16 +1,22 @@
#pragma once
#include "TSXParser.h"
#include "olcUTIL_Geometry2D.h"
struct XMLTag;
enum MapName{
LEVEL1,
LEVEL2,
CAMPAIGN_1_1,
};
struct TileCollisionData{
geom2d::rect<int>collision;
};
struct TilesetData{
Renderable*tileset;
std::map<int,XMLTag>foregroundTiles;
std::map<int,TileCollisionData>collision;
};
struct TileRenderData{

View File

@ -167,6 +167,7 @@ bool Monster::Update(float fElapsedTime){
targetAcquireTimer=3;
target=geom2d::line(pos,game->GetPlayer().GetPos()).upoint(1.2);
state=MOVE_TOWARDS;
hasHitPlayer=false;
}
if(state==MOVE_TOWARDS&&geom2d::line(pos,target).length()>100*fElapsedTime*GetMoveSpdMult()){
SetPosition(pos+geom2d::line(pos,target).vector().norm()*100*fElapsedTime*GetMoveSpdMult());
@ -295,7 +296,8 @@ void Monster::Draw(){
}
}
void Monster::Collision(Player&p){
if(MONSTER_DATA[type].GetCollisionDmg()>0){
if(MONSTER_DATA[type].GetCollisionDmg()>0&&!hasHitPlayer){
hasHitPlayer=true;
p.Hurt(MONSTER_DATA[type].GetCollisionDmg());
}
Collision();

View File

@ -71,6 +71,7 @@ struct Monster{
MonsterName type;
std::vector<Buff>buffList;
AnimationState GetDeathAnimationName();
bool hasHitPlayer=false;
public:
Monster();
Monster(vf2d pos,MonsterData data);

View File

@ -29,11 +29,11 @@ void Player::SetClass(Class cl){
}
void Player::SetX(float x){
pos.x=x;
pos.x=std::clamp(x,12.f,float(game->WORLD_SIZE.x*24-12));
};
void Player::SetY(float y){
pos.y=y;
pos.y=std::clamp(y,12.f,float(game->WORLD_SIZE.y*24-12));
}
void Player::SetZ(float z){
@ -221,13 +221,9 @@ void Player::Update(float fElapsedTime){
vel.y=std::min(0.f,vel.y+friction*fElapsedTime);
}
float newX=pos.x+vel.x*fElapsedTime;
if(newX-12*size>0&&newX+12*size<game->GetWorldSize().x*24){
pos.x=newX;
}
float newY=pos.y+vel.y*fElapsedTime;
if(newY-12*size>0&&newY+12*size<game->GetWorldSize().y*24){
pos.y=newY;
}
SetX(newX);
SetY(newY);
if(attack_cooldown_timer==0&&game->GetMouse(0).bHeld){
switch (cl) {
case WARRIOR:{

View File

@ -18,6 +18,7 @@ struct XMLTag{
struct MapTag{
int width,height;
vi2d playerSpawnLocation;
friend std::ostream& operator << (std::ostream& os, MapTag& rhs);
};
@ -74,7 +75,7 @@ class TMXParser{
}
std::ostream& operator << (std::ostream& os, MapTag& rhs){
os <<
"(width:"<<rhs.width<<", height:"<<rhs.height<<")\n";
"(width:"<<rhs.width<<", height:"<<rhs.height<<",playerSpawnLocation:"<<rhs.playerSpawnLocation<<")\n";
return os;
}
int XMLTag::GetInteger(std::string dataTag) {
@ -209,14 +210,17 @@ class TMXParser{
obj={newTag};
goto spawnerResetSkip;
} else
if (newTag.tag=="property"&&buildingSpawner) {
if(newTag.data["propertytype"]=="MonsterName"){
obj.properties.push_back(newTag);
}
goto spawnerResetSkip;
} else {
std::cout<<"Unsupported tag format! Ignoring."<<"\n";
if (newTag.tag=="object"&&newTag.data["type"]=="PlayerSpawnLocation") {
parsedMapInfo.MapData.playerSpawnLocation={newTag.GetInteger("x")-newTag.GetInteger("width")/2,newTag.GetInteger("y")-newTag.GetInteger("height")/2};
} else
if (newTag.tag=="property"&&buildingSpawner) {
if(newTag.data["propertytype"]=="MonsterName"){
obj.properties.push_back(newTag);
}
goto spawnerResetSkip;
} else {
std::cout<<"Unsupported tag format! Ignoring."<<"\n";
}
if(buildingSpawner){
parsedMapInfo.SpawnerData.push_back(obj);
}

View File

@ -2,12 +2,15 @@
#include "olcPixelGameEngine.h"
#include <strstream>
#include "TMXParser.h"
#include "Map.h"
#include "olcUTIL_Geometry2D.h"
using namespace olc;
struct Tileset{
XMLTag ImageData;
std::map<int,XMLTag> ForegroundTileData;
std::map<int,TileCollisionData> CollisionData;
friend std::ostream& operator << (std::ostream& os, Tileset& rhs);
};
@ -17,6 +20,8 @@ class TSXParser{
private:
Tileset parsedTilesetInfo;
void ParseTag(std::string tag);
std::string previousTag;
int previousTagID;
public:
TSXParser(std::string file);
};
@ -81,7 +86,16 @@ class TSXParser{
parsedTilesetInfo.ImageData=newTag;
} else
if (newTag.tag=="tile"&&newTag.data["type"]=="ForegroundTile"){
parsedTilesetInfo.ForegroundTileData[stoi(newTag.data["id"])]=newTag;
parsedTilesetInfo.ForegroundTileData[newTag.GetInteger("id")]=newTag;
} else
if (newTag.tag=="tile"){
previousTag=newTag.tag;
previousTagID=newTag.GetInteger("id");
} else
if (newTag.tag=="object"&&previousTag=="tile"){
TileCollisionData data;
data.collision=geom2d::rect<int>{{newTag.GetInteger("x"),newTag.GetInteger("y")},{newTag.GetInteger("width"),newTag.GetInteger("height")}};
parsedTilesetInfo.CollisionData[previousTagID]=data;
}
std::cout<<"\n"<<"=============\n";
}

View File

@ -2,7 +2,7 @@
#define VERSION_MAJOR 0
#define VERSION_MINOR 2
#define VERSION_PATCH 0
#define VERSION_BUILD 231
#define VERSION_BUILD 245
#define stringify(a) stringify_(a)
#define stringify_(a) #a

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.10" tiledversion="1.10.1" orientation="orthogonal" renderorder="right-down" width="186" height="159" tilewidth="24" tileheight="24" infinite="0" nextlayerid="4" nextobjectid="1">
<map version="1.10" tiledversion="1.10.1" orientation="orthogonal" renderorder="right-down" width="186" height="159" tilewidth="24" tileheight="24" infinite="0" nextlayerid="5" nextobjectid="4">
<tileset firstgid="1" source="../maps/grass_tiles_24x24.tsx"/>
<layer id="1" name="Kachelebene 1" width="186" height="159">
<data encoding="csv">
@ -490,4 +490,22 @@
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
</data>
</layer>
<objectgroup id="4" name="Object Layer 1">
<object id="1" name="Player Spawn" type="PlayerSpawnLocation" x="288" y="2160" width="24" height="24"/>
<object id="2" name="2x Green Slime" type="SpawnGroup" x="480" y="2064" width="384" height="408">
<properties>
<property name="Monster1" type="class" propertytype="Monster">
<properties>
<property name="Type" type="int" propertytype="MonsterName" value="1"/>
</properties>
</property>
<property name="Monster2" type="class" propertytype="Monster">
<properties>
<property name="Type" type="int" propertytype="MonsterName" value="1"/>
</properties>
</property>
</properties>
<ellipse/>
</object>
</objectgroup>
</map>

View File

@ -142,7 +142,7 @@
</properties>
<ellipse/>
</object>
<object id="7" name="Player Spawn Point" type="SpawnLocation" x="120" y="984" width="24" height="24"/>
<object id="7" name="Player Spawn Point" type="PlayerSpawnLocation" x="120" y="984" width="24" height="24"/>
<object id="10" name="To Caverns" type="Door" x="792" y="912" width="120" height="72">
<properties>
<property name="connection" value="./maps/Level2.tmx"/>

View File

@ -258,7 +258,7 @@
</properties>
<ellipse/>
</object>
<object id="5" name="Player Spawn Point" type="SpawnLocation" x="408" y="96" width="24" height="24"/>
<object id="5" name="Player Spawn Point" type="PlayerSpawnLocation" x="408" y="96" width="24" height="24"/>
<object id="7" name="To Overworld" type="Door" x="384" y="48" width="72" height="48">
<properties>
<property name="connection" value="./maps/Level1.tmx"/>