Antidote Posted August 2, 2013 Share Posted August 2, 2013 It's still VERY much WIP (considering i started writing it last night) but the basics are in place, all that's needed is a widget system, bitmap font class, and all the Zelda trappings Currently the Octorok just chases Link around and cause 1 damage so obviously his AI needs work. GITHUB REPO: https://github.com/Antidote/2dzeldaengine Don't mind the Derpy code, the stuff in Octorok is just hacky stuff to test delta timing and me learning AI programming as i go. 9 Link to comment Share on other sites More sharing options...
Conker Posted August 2, 2013 Share Posted August 2, 2013 Looks pretty cool so far. keep it up bbz Link to comment Share on other sites More sharing options...
Antidote Posted August 2, 2013 Author Share Posted August 2, 2013 Thanks, right now I'm working on the Widget system, and tomorrow I'll work on maps. As it is, I'm having to add entities manually in Engine::initialize (Yes it's a singleton, but it's the only one) 1 Link to comment Share on other sites More sharing options...
Kargaroc Posted August 2, 2013 Share Posted August 2, 2013 This is really impressive! Link to comment Share on other sites More sharing options...
Antidote Posted August 3, 2013 Author Share Posted August 3, 2013 I can't seem to think of a name, if you have any suggestions please post them. Also this is the official logo Credit goes to KevinB834 Link to comment Share on other sites More sharing options...
HeavyZ Posted August 3, 2013 Share Posted August 3, 2013 For the Zelda game? Depends what the story is going to be. I'd throw some at you if I had more details Link to comment Share on other sites More sharing options...
Antidote Posted August 3, 2013 Author Share Posted August 3, 2013 For the engine, not really planning a game yet, I want to get all the important backend stuff fleshed out before i do any real plans to make a game. Link to comment Share on other sites More sharing options...
xdaniel Posted August 3, 2013 Share Posted August 3, 2013 Yep, it's looking quite nice and (from that glimpse into the project's files on the screenshot) well-organized. Wouldn't mind hearing more about the design, too, like... how your entities interact, ex. how the Octorok "knows" Link and chases him or somesuch? I don't really know about a lot of what goes into making a game or game engine, from AI to collision detection to who knows what Also, if I may say this: You're indirectly at fault that I stayed up through the night, as you kinda inspired me to try and create a game engine of sorts (yet) again. Which'll probably go nowhere as can be guess from the above. Got as far as an animated ALttP Link running around, tho via C# + MonoGame, but for now I'm too tired to keep going... Link to comment Share on other sites More sharing options...
Antidote Posted August 3, 2013 Author Share Posted August 3, 2013 XD Sorry about that, and as for the Octorok chasing Link, it's just a basic circle algorithm without the radius. On top of that EntityManager keeps track of the Player Object, and only allows 1 instance of an entity of type "Player" void Octorok::think(sf::Time dt){ sf::Vector2f playerVec = Engine::instance().entityManager().player()->position(); move((playerVec - m_pos) * (2.f*dt.asSeconds()));}If you want to know how i'm doing depth sorting, it's pretty simple: std::sort :3 BUMP As promised last night during ShadowFire's stream, i've uploaded the source to github, if you want to help out in anyway just ask and I'll see about adding you to the repo. I'd love for this engine to go somewhere EDIT: To mods, I only double posted to inform people following this of the status update, please merge this post with my previous one. Link to comment Share on other sites More sharing options...
SanguinettiMods Posted August 3, 2013 Share Posted August 3, 2013 I'd be happy to make graphics for any sort of Interface you may have planned. Link to comment Share on other sites More sharing options...
Antidote Posted August 3, 2013 Author Share Posted August 3, 2013 That would be great, right now i'm sticking with ALTTP Style, but I may go with MC style later on. EDIT:Been ripping sprites from ALTTP using zcompress and yy-chr (via wine) so here is an example of what i'm able to do using yy-chr's unique "palette set" feature which makes ripping a breeze Before: After: The NPC sprite and blue bird use different palettes from the red bird and the bunny (which is demonic if you ask me lol) Later on I'll right a tutorial on how to rip them this way. 1 Link to comment Share on other sites More sharing options...
Crownjo Posted August 5, 2013 Share Posted August 5, 2013 I like ALTTP style. I am curious if it's possible to have any sort of co-op. Would be rad to have an engine to include it. Link to comment Share on other sites More sharing options...
Antidote Posted August 5, 2013 Author Share Posted August 5, 2013 It's definitely possible, but I'd have to make some changes and add a NetworkManager class, fortunately SFML provides a pretty good library for networking. Local coop is doable as well. 1 Link to comment Share on other sites More sharing options...
Crownjo Posted August 5, 2013 Share Posted August 5, 2013 Good thing I gave you my co-op concept. ALTTP co-op would be the best thing ever. Link to comment Share on other sites More sharing options...
Antidote Posted August 5, 2013 Author Share Posted August 5, 2013 When creating the input manager i noticed something pretty bad: it had a very negative affect on the whole program. I have a 9800GTX+ (pretty high end 6 years ago) and i was averaging about 300 FPS with the input manager being updated every frame, which is poor design to begin with, but bear with me. So I decided to make put it on a separate thread, which is normal practice for modern games anyway, and boy was I surprised by the difference Before: EDIT: Added it back AFTER (screw you xfce4-screenshooter) Link to comment Share on other sites More sharing options...
DarthDub Posted August 7, 2013 Share Posted August 7, 2013 This is looking really neat. Link to comment Share on other sites More sharing options...
Antidote Posted August 7, 2013 Author Share Posted August 7, 2013 I just did a test to see how many entities i can have on screen at once, NO view culling used. I was able to render about 900 entities at once, each doing about 400 cycles of a simple AI routine, before things started slowing down really bad. I don't know of a case where I'll EVER need to do that, so i think that's a success :3 2 Link to comment Share on other sites More sharing options...
Conker Posted August 7, 2013 Share Posted August 7, 2013 Great job, bruv! Link to comment Share on other sites More sharing options...
Crownjo Posted August 8, 2013 Share Posted August 8, 2013 I hope this becomes the best ALTTP engine because I like the progress you made so far. Link to comment Share on other sites More sharing options...
Antidote Posted August 8, 2013 Author Share Posted August 8, 2013 Working on my map compiler right now, once it's finished I'll start writing the read class (which forces me to right the Map -> Layer -> Tile classes) Right now the only collision types that are supported are Solid = 0x00, and non-Solid =0xFF Since I've decided to make Tiled-Qt the official map editor of this engine, A dedicated "Collision" layer will be used to calculate this using tile properties, (basically meaning you can use any image you damn well please for each collision type minus Non Solid, which is defined by a lack of tile) Once I've decided on the naming convention I'll let you know so people can make tests maps if they desire. Anyway here is the map compiler as it sits right now: MapFileWriter.cpp: http://pastebin.com/TYreGFYT MapFileWriter.hpp: http://pastebin.com/hbn5h5sX Here is an example of what i mean, you guys should recognize it despite it's ugliness: 2 Link to comment Share on other sites More sharing options...
Antidote Posted August 8, 2013 Author Share Posted August 8, 2013 (edited) Ran out of room in that post So double posting due to an update. Here is an updated collision map: I personally think it looks pretty professional. EDIT:After 2 hours of head scratching, compiler WTFs and 1D10T errors, the map format is complete, Now to write the reader and the classes. Here is the completed source (header is the same) #include "MapFileWriter.hpp"#include <Exception.hpp>#include <TmxParser/Tmx.h>#include <sstream>#include <algorithm>#include <Map.hpp>#include <iostream>#include <iomanip> namespace zelda{namespace utility{inline void tolower(std::string& str){ std::transform(str.begin(), str.end(), str.begin(), ::tolower);} }namespace io{ MapFileWriter::MapFileWriter(const Uint8* data, const Uint64 length) : base(data, length){} MapFileWriter::MapFileWriter(const std::string &filepath) : base(filepath){} struct TileFlags{ bool Horizontal:1; bool Vertical:1; bool Diagonal:1;}; void MapFileWriter::fromTMX(const std::string &filepath){ Tmx::Map map; map.ParseFile(filepath); if (map.HasError()) { std::stringstream err; err << "error in Tmx::Parser : " << (int)map.GetErrorCode() << ": " << map.GetErrorText() << std::endl; throw zelda::error::Exception(err.str()); } base::writeUInt32(Map::MAGIC_NUMBER); base::writeUInt32(Map::VERSION); base::writeUInt16(0xFEFF); base::writeUInt32(map.GetWidth()*map.GetTileWidth()); base::writeUInt32(map.GetHeight()*map.GetTileHeight()); base::writeUInt32(map.GetTileWidth()); base::writeUInt32(map.GetTileHeight()); base::writeUByte(map.GetOrientation()); // will probably go unused but you never know base::writeUInt32(map.GetTilesets().size()); Uint64 layerCountOffset = base::position(); base::writeUInt32(map.GetLayers().size() - 1); // Align to 32bytes for Wii/GCN support base::seek((m_position + 0x1F) & ~0x1F, base::Beginning); for (Tmx::Tileset* tileset : map.GetTilesets()) { std::string path = tileset->GetImage()->GetSource(); path = path.substr(path.find_last_of("/") + 1, (path.size() - path.find_last_of("/")) - 1); base::writeString(path); } // Align to 32bytes for Wii/GCN support base::seek((base::position() + 0x1F) & ~0x1F, base::Beginning); Tmx::Layer* colLayer = NULL; Uint32 layerCount = 0; for (Tmx::Layer* layer : map.GetLayers()) { std::string name = (std::string)layer->GetName(); utility::tolower(name); if (!name.compare("collision")) { if (!colLayer) colLayer = layer; else throw "Too many collision layers, The map can have at most 1 Collision layer, please remove the extraneous layers"; continue; } int tileCount = 0; for (int y = 0; y < layer->GetHeight(); y++) { for (int x = 0; x < layer->GetWidth(); x++) { if (layer->GetTileTilesetIndex(x, y) == -1) continue; tileCount++; } } if (tileCount == 0) continue; layerCount++; base::writeBool(layer->IsVisible()); base::writeUInt32(layer->GetZOrder()); //base::writeUInt32(layer->GetProperties().GetSize()); base::writeUInt32(tileCount); // Align to 32bytes for Wii/GCN support base::seek((base::position() + 0x1F) & ~0x1F, base::Beginning); for (int y = 0; y < layer->GetHeight(); y++) { for (int x = 0; x < layer->GetWidth(); x++) { if (layer->GetTileTilesetIndex(x, y) == -1) continue; Tmx::MapTile& tile = (Tmx::MapTile&)layer->GetTile(x, y); base::writeInt32(tile.id); base::writeUInt32(layer->GetTileTilesetIndex(x, y)); TileFlags flags; flags.Horizontal = tile.flippedHorizontally; flags.Vertical = tile.flippedVertically; flags.Diagonal = tile.flippedDiagonally; base::writeUBytes((Uint8*)&flags, 1); base::writeUInt16(x*map.GetTileWidth()); base::writeUInt16(y*map.GetTileHeight()); } } base::seek((base::position() + 0x1F) & ~0x1F, base::Beginning); } // Write the collision data for (int y = 0; y < map.GetHeight(); y++) { for (int x = 0; x < map.GetWidth(); x++) { if (colLayer) { if (colLayer->GetTileTilesetIndex(x, y) != -1) { Tmx::MapTile& mapTile = (Tmx::MapTile&)colLayer->GetTile(x, y); const Tmx::Tile* tile = map.GetTileset(mapTile.tilesetId)->GetTile(mapTile.id); Uint8 flags = 0; if (tile) { Uint8 flippedDamage = 0; flippedDamage |= (colLayer->IsTileFlippedHorizontally(x, y) ? 0x01 : 0x00); flippedDamage |= (colLayer->IsTileFlippedVertically(x, y) ? 0x02 : 0x00); if (tile->GetProperties().HasProperty("Type")) { // Clear this flag for the ones that don't need it flags |= 0x01; std::string type = tile->GetProperties().GetLiteralProperty("Type"); if (!type.compare("Angle45")) { flags |= 0x02; std::cout << "Angle45 " << std::hex << (int)flags << std::endl; } else if (!type.compare("Angle25")) { flags |= 0x04; std::cout << "Angle25 " << std::hex << (int)flags << std::endl; } else if (!type.compare("Jump")) { flags &= ~0x01; flags |= 0x08; std::cout << "Jump " << std::hex << (int)flags << std::endl; } else if (!type.compare("WaterShallow")) { flags &= 0x01; flags |= 0x10; } else if (!type.compare("WaterDeep")) { flags &= 0x01; flags |= 0x20; } else if (!type.compare("Damage")) { flags &= ~0x01; flags |= 0x40; if (tile->GetProperties().HasProperty("Value")) { // Damage tiles ignore flipping flippedDamage = (Uint8)(tile->GetProperties().GetNumericProperty("Value") & 0xFF); } else { flippedDamage = 0; } std::cout << "Damage " << std::hex << (int)flags << std::endl; } } else { std::cout << "WARNING: Collision tile with no type at " << x << "," << y << " assuming complete solid" << std::endl; flags |= 0x01; } std::cout << "Final value: " << std::setw(2) << std::setfill('0') << (int)flags << std::dec << std::endl; base::writeByte(flags); base::writeByte(flippedDamage); } else base::writeUInt16(0); } else base::writeUInt16(0); } } } base::seek(layerCountOffset, base::Beginning); base::writeUInt32(layerCount); std::cout << layerCount << std::endl; // Finally save the map base::save();} void MapFileWriter::setFilepath(const std::string& filepath){ base::m_filepath = filepath;}}} Edited August 8, 2013 by Antidote 4 Link to comment Share on other sites More sharing options...
Crownjo Posted August 8, 2013 Share Posted August 8, 2013 Amazing work! Link to comment Share on other sites More sharing options...
Antidote Posted August 8, 2013 Author Share Posted August 8, 2013 Good thing i always go back and read my posts, or i probably wouldn't have noticed that i wasn't properly clearing those bits XD flags &= 0x01; instead of flags &= ~0x01; that would have caused a TON of headaches down the line if i didn't catch it. @Crownjo: Thanks, once I'm done with the map reader i'll be able to really get started. 1 Link to comment Share on other sites More sharing options...
Antidote Posted August 9, 2013 Author Share Posted August 9, 2013 I found a bug in the TMX Parser i'm using, and trying to track it down. I'm pretty sure i know where it is so once i fix it and send a patch upstream I'll start implementing maps in Sakura, (yes that's the name of the engine now) 1 Link to comment Share on other sites More sharing options...
Crownjo Posted August 9, 2013 Share Posted August 9, 2013 Hmm name of the engine should be Zelda related lol. But I hope you find that blasted bug. Spray it with raid! Hope this becomes a big thing in the future. Ya know like SMBX. 1 Link to comment Share on other sites More sharing options...
Recommended Posts