ferreiradaselva

October 2017 GameDev Challenge: Arcade Battle Arena!

Recommended Posts

Arcade Battle Arena Challenge!

Make a game like the classics Bubble Bobble and Super Mario Bros 3 Battle Mode. Those games involve one or two players battling against waves of enemies on an arena.

Game Requirements

  • The game must have:
    • Start screen
    • Key to return to the start screen
    • Score system
    • Minimum of 2 enemies with different behavior (AI)
    • Graphics at least for the UI, player and enemies
    • Sound effects at least for when the player is hurt and when an enemy is killed
  • The actual gameplay must happen on a single screen (no camera translation)

Art Requirements

  • The game can be 2D or 3D
  • The art must use a maximum 16 colors palette
  • The art must be your own

Tips

  • An interesting game design approach of the two games is that they require the player to neutralize the enemy first, before killing it:
    • In the Super Mario Bros 3 Battle Mode, to kill an enemy, the player must first hit underneath the platform where the enemy is walking on
    • In Bubble Bobble, to kill an enemy, the player must first shot a bubble on the enemy
  • You can quickly make sound effects on Chiptone
  • You can decrease your color count by replacing two similar colors with a median between the two colors. This works nicely for similar dark colors or similar light colors
  • Enemy behavior can involve:
    • Response to the environment. What is the kind of tile that the enemy is currently at? What are the kind of tiles that are in front or behind the enemy?
    • Response to the player. Where is the player? Is it too far away? Is it close? In front or behind? How the enemy will respond to that?
    • Motion pattern. Does the enemy walk on the platform and stop for some time? Does it fly? Games like Super Mario World are good examples with a great variety of enemy patterns.
  • The tutorials on Youtube by Shaun Spalding teach some enemy programming. They are for Game Maker, but the logic can be translated to other game engine or framework:

Duration

4 weeks - October 6, 2017 to November 3, 2017

Submission

Post on this thread only your entries:

  • Link to the executable (specifying the platform)
  • Screenshots: if the screenshots are too big, post just a few, if they are small, you can post more, just don't take the entire space
  • A small post-mortem, in the same post of the entry, is encouraged, where you can share what went right, what went wrong, or just share a nifty trick
  • Source-code link is encouraged

Bubblebobble.png

SMB3_Battle_Mode_standard.png

Edited by ferreiradaselva

Share this post


Link to post
Share on other sites

So can we use this topic for any dumb question we may have related to the project? :/ 

If that's the case, then I have one: I would like to keep my #include "SDL.h" inside the source file rather than in the headers, is that the correct way? If so, I know how to forward declare struct SDL_Window; and struct SDL_Renderer; inside the header so that I can use pointers to those structs into it, but how do I forward declare a Uint32? 

I tried  "using Uint32 = uint32_t"  but for that to work I have to #include <cstdint> in the header... there is a smart way to use SDL Uint32 typedef without including SLD.h or <cstdint> in all my headers? Or should I just include SLD.h it in all my headers and it is not a big deal?

Edited by MarcusAseth

Share this post


Link to post
Share on other sites

Made some progress, got my timer up and running, is fairly similar to the last one I've made but because of that practice, writing it from scratch went considerably faster (...hope I have no mistakes in it) :P Unfortunately is templated so I have to keep the definitions in the same header... x_x

GameTimer.h:

Spoiler

#pragma once
#include <chrono>
using namespace std::chrono;

template<size_t T>
class GameTimer
{
	using TickDuration = duration < uint32_t, std::ratio<1, T>>;
	using TimePoint = time_point<steady_clock>;
	using FloatSeconds = duration<float>;

private://variables
	TimePoint AppStart;
	TimePoint Current;
	TimePoint NextUpdate;
	TickDuration UpdateRate;
	float DeltaT;

public://Methods
	GameTimer();
	GameTimer(const GameTimer&) = delete;
	GameTimer& operator=(const GameTimer&) = delete;
	GameTimer(GameTimer&&) = delete;
	GameTimer& operator=(GameTimer&&) = delete;

	void Tick();
	void Advance();
	float Interpolation();

	TimePoint CurrentTime()const { return Current; }
	TimePoint NextUpdateTime()const { return NextUpdate; }
	float DeltaTime()const { return DeltaT; };

};

template<size_t T>
GameTimer<T>::GameTimer() : 
	UpdateRate{ 1 }
{
	AppStart = Current = NextUpdate = steady_clock::now();
	DeltaT = duration_cast<FloatSeconds>(UpdateRate).count();
}

template<size_t T>
void GameTimer<T>::Tick()
{
	Current = steady_clock::now();
}

template<size_t T>
void GameTimer<T>::Advance()
{
	NextUpdate = Current + UpdateRate;
}

template<size_t T>
float  GameTimer<T>::Interpolation()
{
	auto Interpolation = duration_cast<FloatSeconds>(Current - (NextUpdate - UpdateRate)) / UpdateRate;
	return Interpolation*DeltaT;
}

 

Timer Usage:

Spoiler

void App::GameLoop()
{
	while (Running)
	{
		Timer->Tick();

		//Input
		SDL_Event Event;
		if (SDL_PollEvent(&Event))
		{
			switch (Event.type)
			{
				case SDL_QUIT:
				{
					Running = false;
				}
			}
		}

		//Update
		while(Timer->CurrentTime() > Timer->NextUpdateTime())
		{
			//Game->Update(Timer->DeltaTime());
			Timer->Advance();
		}

		//Draw
		//Game->Draw(Timer->Interpolation());
	}
}

 

 

Share this post


Link to post
Share on other sites
12 hours ago, MarcusAseth said:

So can we use this topic for any dumb question we may have related to the project? :/ 

If that's the case, then I have one: I would like to keep my #include "SDL.h" inside the source file rather than in the headers, is that the correct way? If so, I know how to forward declare struct SDL_Window; and struct SDL_Renderer; inside the header so that I can use pointers to those structs into it, but how do I forward declare a Uint32? 

I tried  "using Uint32 = uint32_t"  but for that to work I have to #include <cstdint> in the header... there is a smart way to use SDL Uint32 typedef without including SLD.h or <cstdint> in all my headers? Or should I just include SLD.h it in all my headers and it is not a big deal?

You should include sdl.h in the headers that need to see those functions.  One reason you might only include a header in a source file is to trigger rebuilding the source file only when that header is changed, but something like sdl your almost certainly not fiddling around with it's internal works, so there isn't much need to remove it from your headers.

 

I'm going to participate in this challenge as well, It's a good opportunity to flex the strengths of my framework and see how it holds up when assigned a random task.  thus far you can find my development progress here: https://github.com/slicer4ever/TriColor-Wars  I well be using a framework/engine i've built over the last couple years called Lightwave: https://github.com/slicer4ever/Lightwave

The goal is to support 1/2 player modes(possible over internet play well be included), i have an idea for 2 player mode of seperating keyboard/mouse controls to allow for local play.   I'm hoping to be mostly done within the next 48-72 hours, so let's see what happens.

I well likely try to push an update each night, and will include binarys after today's work as there should be something substancial to play by then.

Share this post


Link to post
Share on other sites
15 hours ago, MarcusAseth said:

If that's the case, then I have one: I would like to keep my #include "SDL.h" inside the source file rather than in the headers, is that the correct way?

It's not wrong. Place the #include where you need it. If you add an SDL type inside your header, you probably will need to add the #include in your header, too. But, if you are not using any SDL type in the header, then you don't need to add the #include in the header.

15 hours ago, MarcusAseth said:

I tried  "using Uint32 = uint32_t"  but for that to work I have to #include <cstdint> in the header... there is a smart way to use SDL Uint32 typedef without including SLD.h or <cstdint> in all my headers? Or should I just include SLD.h it in all my headers and it is not a big deal?

It's not a big deal. As for the use of `uint32_t`, I think if you include the <cstdint> in some central header (a header that is used everywhere in your project), you can use the `uint32_t` anywhere where that your header is included.

Your main loop is more "pro" than mine, btw. I just went with the crude SDL_Delay() approach to run at ~60 FPS. Maybe I will improve later.

3 hours ago, slicer4ever said:

I'm going to participate in this challenge as well, It's a good opportunity to flex the strengths of my framework and see how it holds up when assigned a random task.  thus far you can find my development progress here: https://github.com/slicer4ever/TriColor-Wars  I well be using a framework/engine i've built over the last couple years called Lightwave: https://github.com/slicer4ever/Lightwave

I wasn't so bold to use my own engine :p, I still need to make some cross-platform improvements on it. That's why I will stick with SDL2.

3 hours ago, slicer4ever said:

The goal is to support 1/2 player modes(possible over internet play well be included), i have an idea for 2 player mode of seperating keyboard/mouse controls to allow for local play.   I'm hoping to be mostly done within the next 48-72 hours, so let's see what happens.

I well likely try to push an update each night, and will include binarys after today's work as there should be something substancial to play by then.

That's hecking cool. I'm curious how the mouse controls will be.

I'm going to make updates every day, too. I'm uploading the progress here https://github.com/ferreiradaselva/very-small-games.

Share this post


Link to post
Share on other sites
6 hours ago, ferreiradaselva said:

Your main loop is more "pro" than mine, btw. I just went with the crude SDL_Delay() approach to run at ~60 FPS. Maybe I will improve later.

Thanks :) That's thanks to you guys which linked me the correct learning materials about game loop few weeks ago in my other topic about the breakout game,so... I can't stress enough the importance of adding good teaching materials related to the challenge requirements, I hope everyone will follow this format :D

Edited by MarcusAseth

Share this post


Link to post
Share on other sites
10 hours ago, ferreiradaselva said:

I wasn't so bold to use my own engine :p, I still need to make some cross-platform improvements on it. That's why I will stick with SDL2.

Like i said, this is another good opportunity to see how versatile it is for what my original goals were, what's the point of writing such things if you never make use of them? :)

 

As for today i got most of the main components done (https://github.com/slicer4ever/TriColor-Wars) and am now working on the gameplay, I still have my color switching element to work in mechanically, then i'll expand the enemys, toss in some sounds and try to prettify the background a bit.  at that point i'll decide if i want to try implementing mp or not at that stage. Creating my own art, and adhering to a 16 color pallete has been a bit challenging though, at the moment the game is basically a 1/2 player asteroid clone, tomorrow i hope to get some interesting enemy and mechanics in place :).

 

a quick video of gameplay:

 

Share this post


Link to post
Share on other sites

got a not so useful static piece of text on the screen:

vbGW0q9.png

Maybe I should do a button class next? Or I'll leave it for last and jump straight into the Play state.

Hey guys, I have a question,regarding this code:

void MenuState::Draw(float interpolation)
{
	SDL_Surface* TempText = TTF_RenderText_Blended(BubbleFont.GetFont(), "Play", SDL_Color{ 165,161,141,255 });
	SDL_Texture* TextTexture = SDL_CreateTextureFromSurface(WindowInfo.Renderer, TempText);
	
	//Draw
	SDL_SetRenderDrawColor(WindowInfo.Renderer, 40, 34, 50, 255);
	SDL_RenderClear(WindowInfo.Renderer);
	SDL_RenderCopy(WindowInfo.Renderer, TextTexture, NULL, &PlayPosition);
	SDL_RenderPresent(WindowInfo.Renderer);

	//cleanup
	SDL_FreeSurface(TempText);
	SDL_DestroyTexture(TextTexture);
}

Now I realize this text is static so I could set the texture once on the constructor,free the surfance once, and only destroy the texture once on the destructor, but for the sake of argument let's assume that my text change shade over time so now I need to do this FreeSurface() and DestroyTexture() on every Draw() iteration.   If that where the case, would this still be the right way of doing it? Or like drawing the surface directly would be preferred? :|

This question extends to pretty much all the game UI, since it will have score that need to be refreshed.

Edited by MarcusAseth

Share this post


Link to post
Share on other sites
20 hours ago, slicer4ever said:

As for today i got most of the main components done (https://github.com/slicer4ever/TriColor-Wars) and am now working on the gameplay, I still have my color switching element to work in mechanically, then i'll expand the enemys, toss in some sounds and try to prettify the background a bit.  at that point i'll decide if i want to try implementing mp or not at that stage. Creating my own art, and adhering to a 16 color pallete has been a bit challenging though, at the moment the game is basically a 1/2 player asteroid clone, tomorrow i hope to get some interesting enemy and mechanics in place :).

That was fast.

I added that 16 color limit because a lot of art beginners use too much colors without any meaning. Limiting the color usage helps to develop the art skills and a sense of adding colors only when necessary.

11 hours ago, MarcusAseth said:

Now I realize this text is static so I could set the texture once on the constructor,free the surfance once, and only destroy the texture once on the destructor, but for the sake of argument let's assume that my text change shade over time so now I need to do this FreeSurface() and DestroyTexture() on every Draw() iteration.   If that where the case, would this still be the right way of doing it? Or like drawing the surface directly would be preferred?

Creating the texture a single time would be a better option. Then draw that text surface on the texture. But, we are talking about a small game here. It's likely that creating and destroying those every frame won't be a performance problem. For bigger projects? You probably want to allocate some content and keep them allocated as long as you can.

 

Current status of my project:

image.png.0926555e4c702543d65b4b6f45143c5c.png

Content loading. I automated my build system to convert the PNG (texture atlas) to a c header containing the PNG in RGBA format. That way, I don't need to ship the executable with a *.dat or *.zip or even the PNG loose. I will do the same for sound effects.

Main loop. I fixed that main loop, and I have rendering working. I'm not using accelerated hardware (bwahahaha). Using SDL_Surface is easier to deal with. VERY limiting, but it's ok for this project.

The logic of the rendering is this:

  1. Get the window surface
  2. Create a "view" surface
  3. Create a "texture" surface for the texture (atlas)
    1. Loop start
    2. Clear "view" surface
    3. Draw portion of the "texture" surface on the "view" surface
    4. Draw "view" surface scaled on the window surface
    5. Loop end

The reason I'm drawing on a "view" surface is to keep the rendering "pixel-perfect".

Share this post


Link to post
Share on other sites
1 hour ago, ferreiradaselva said:

For bigger projects? You probably want to allocate some content and keep them allocated as long as you can.

So how would bigger projects handle the rendering of a text that change shade at every draw, in the specific? :P

Do you mean like allocating a sequence of pre-rendered images of all the shades for a given piece of text?

Edited by MarcusAseth

Share this post


Link to post
Share on other sites
10 minutes ago, MarcusAseth said:

So how would bigger projects handle the rendering of a text that change shade in the specific? :P

I'm not sure how flexible SDL is to do this, but I if I could access the OpenGL context via SDL, I would create a grayscale texture with every text I need, then a shader that do one of the two things:

  1. Take the vertex data + a uniform variable indicating the color, then the shader would use the grayscale as brightness value to plot the color
  2. Take the vertex data that includes the color for each vertex, then do the same as above (brightness + color) 

The fragment shader (responsible for selecting the output color) would be something simple like:

"gl_FragColor = vec4(grayscale * r, grayscale * g, grayscale * b, alpha);"

Share this post


Link to post
Share on other sites
9 minutes ago, ferreiradaselva said:

I'm not sure how flexible SDL is to do this, but I if I could access the OpenGL context via SDL, I would create a grayscale texture with every text I need, then a shader that do one of the two things:

  1. Take the vertex data + a uniform variable indicating the color, then the shader would use the grayscale as brightness value to plot the color
  2. Take the vertex data that includes the color for each vertex, then do the same as above (brightness + color) 

The fragment shader (responsible for selecting the output color) would be something simple like:

"gl_FragColor = vec4(grayscale * r, grayscale * g, grayscale * b, alpha);"

I see, thanks! :)

Edited by MarcusAseth

Share this post


Link to post
Share on other sites

Ok, i've deceided i've met my 48 hour deadline(+/- a bit, as i wasn't keeping exact track, but several hours were lost to playing games with friends, so i think it evens out).

I'm happy with my progress, it's not quite as much as i wanted, but it both meets the requirements of this challenge, and mechanically the idea's i wanted to play out.  overall i find it decently fun, I think if i dedicated more time to ai variety and wave tuning it could be more fun.  Ultimately i'm happy with what i was able to do in my self imposed limits.  Thank you @ferreiradaselva for creating the challenge, and I hope my work can be a learning experiance for others some day.

Link to github codebase:  https://github.com/slicer4ever/TriColor-Wars 

This is a video of gameplay:

 

 

1 hour ago, ferreiradaselva said:

Content loading. I automated my build system to convert the PNG (texture atlas) to a c header containing the PNG in RGBA format. That way, I don't need to ship the executable with a *.dat or *.zip or even the PNG loose. I will do the same for sound effects.

That's an interesting approach to data packaging, personally i'm not a fan of embedding content into the binarys when possible as it means a generally longer pipeline if some of your assets are in heavy modification.

 

35 minutes ago, MarcusAseth said:

So how would bigger projects handle the rendering of a text that change shade at every draw, in the specific?

Do you mean like allocating a sequence of pre-rendered images of all the shades for a given piece of text?

The way i handle it is through bitmap fonts.  basically you load a texture with all the characters you need, and a supplimentary file which tells you where in the texture each glyph is, and supplimentary information.  

then for dynamic text strings, each frame you reconstruct a mesh buffer of the glyphs for your text, and upload them for drawing.

for static text, you can use framebuffers or manually building of a texture that encompases the static text you want on screen, this is ideally more performant, but honestly all my text rendering is done as i described above, and i've yet to find a modern platform where their was any noticable performance impact due to it.

Share this post


Link to post
Share on other sites

what is a mesh buffer?! :S 

This by the way is where I am right now:

Font.cpp

Spoiler

 


#include "Utility.h"
#include "Font.h"


Font::Font(std::string path, uint8_t size) :
	Path{ path }, Size{ size }, TTFFont{ nullptr }
{
	if (TTF_WasInit()) {
		OpenFont(Path.c_str(), Size);
	}
}

Font::~Font()
{
	if (TTFFont) {
		if (!TTF_WasInit()){ Util::LogConsole("fuck!!"); }
		CloseFont();
	}
}

TTF_Font* Font::GetFont()const
{
	return TTFFont;
}

Font& Font::Resize(uint8_t size)
{
	Size = size;
	if (TTFFont) { 
		CloseFont(); 
	}
	OpenFont(Path.c_str(), Size);
	return *this;
}

void Font::OpenFont(std::string path, uint8_t size)
{
	TTFFont = TTF_OpenFont(Path.c_str(), Size);
	if (!TTFFont)
	{
		Util::LogConsole(TTF_GetError());
	}
}

void Font::CloseFont()
{
	TTF_CloseFont(TTFFont);
	TTFFont = nullptr;
}

 

Button.cpp

Spoiler

#include "Button.h"



Button::Button(SDL_Window* window, std::string text, int x, int y, Font& font, SDL_Color* buttonColor) :
	Window{ window }, Text{ text }, ButtonFont{ font }, ButtonColor{ buttonColor }, Shape{x,y,0,0}
{
	ReCalculateSize();
	CenterOnPosition();
}

Button::~Button()
{
}

void Button::ReCalculateSize() 
{
	TTF_SizeText(ButtonFont.GetFont(), Text.c_str(), &Shape.w, &Shape.h);
}

void Button::CenterOnPosition()
{
	Shape.x -= Shape.w / 2;
	Shape.y -= Shape.h / 2;
}

const char* Button::GetText() const
{
	return Text.c_str();
}

const SDL_Rect & Button::GetShape() const
{
	return Shape;
}

bool Button::IsHovered() const
{
	int MouseX{}, MouseY{};
	SDL_GetMouseState(&MouseX, &MouseY);

	if (MouseX < Shape.x + Shape.w &&
		MouseX > Shape.x &&
		MouseY < Shape.y + Shape.h &&
		MouseY > Shape.y)
	{
		return true;
	}
	return false;
}

bool Button::IsPressed() const
{
	if (SDL_GetMouseState(0, 0) & SDL_BUTTON(SDL_BUTTON_LEFT))
	{
		return true;
	}
	return false;
}

SDL_Color& Button::GetColor() const
{
	return *ButtonColor;
}

void Button::SetColor(SDL_Color & color)
{
	ButtonColor = &color;
}

 

MenuState.cpp

Spoiler

#include "MenuState.h"
#include "Paths.h"
#include "Button.h"
#include "GameMode.h"
#include "SDL2\SDL.h"

MenuState::MenuState(GameMode* game, Util::WindowInfo windowInfo) :
	GameState(game, windowInfo), BubbleFont(Paths::Fonts::BUBBLEBATH, 35),
	BaseTextColor{ 165,161,141,255 }, HighlightColor{ 222,210,181,255 }
{
	PlayButton = std::make_unique<Button>(WindowInfo.Window, "Play",
										  WindowInfo.Width / 2, WindowInfo.Height / 3,
										  BubbleFont, &BaseTextColor);
}

MenuState::~MenuState()
{
}

void MenuState::Update(float deltaTime)
{
	if (PlayButton->IsHovered()) {
		//pressed
		if (PlayButton->IsPressed())		{
			Game->SetCurrentState(GameMode::EGameState::PLAY);
		}

		//hovered
		if (&PlayButton->GetColor() != &HighlightColor) {
			PlayButton->SetColor(HighlightColor);
		}													  
	}
	else {//not hovered
		if (&PlayButton->GetColor() != &BaseTextColor) {
			PlayButton->SetColor(BaseTextColor);
		}
	}

}

void MenuState::Draw(float interpolation)
{

	SDL_Surface* TempText = TTF_RenderText_Blended(BubbleFont.GetFont(), PlayButton->GetText(), PlayButton->GetColor());
	SDL_Texture* TextTexture = SDL_CreateTextureFromSurface(WindowInfo.Renderer, TempText);

	//Draw
	SDL_SetRenderDrawColor(WindowInfo.Renderer, 40, 34, 50, 255);
	SDL_RenderClear(WindowInfo.Renderer);
	SDL_RenderCopy(WindowInfo.Renderer, TextTexture, NULL, &PlayButton->GetShape());
	SDL_RenderPresent(WindowInfo.Renderer);

	//cleanup
	SDL_FreeSurface(TempText);
	SDL_DestroyTexture(TextTexture);
}

 

Next I think I'll jump into the playState. What's the first logic task? Maybe an Entity class and then derive a Tile class from Entity?  (because tile have collision too, like other entities)

Though, Should I store tiles in a separate vector<Entity*>, since they don't require updates?

Edited by MarcusAseth

Share this post


Link to post
Share on other sites

Hi guys, I have my texture loading and entity mostly done, here in the image below my tiles entities neatly packed.

Now the next step should be to load a level, I guess. I am not yet sure how to handle that, never done. Should Level be a class object that I call with the path on disk of the level data? What is that data? a .txt? How do I parse the data to make it create the appropiate entity type inside the game?  

Can anyone link some good tutorials (possible C++) about the correct way to do this? I don't think I will proceed until I have it figure it out, I would only end up making a mess I'm sure.  Help! :P

6UwL8D1.png

Edited by MarcusAseth

Share this post


Link to post
Share on other sites
On 8.10.2017 at 4:49 AM, MarcusAseth said:

what is a mesh buffer?! :S 

This by the way is where I am right now:

Though, Should I store tiles in a separate vector<Entity*>, since they don't require updates?

The best tip i can give you or anybody else when you dont know what do to or dont know how get it working:

 

Write down your actual code for loading and rendering fonts into the main loop directly until it actually does something: Until your text is on the screen, or your mesh renders and rotates, or your player moves and kills enemies, whatever.... For any kind of problem.

Then start making a nice api / classes with no implementation and comment out your entire your code from before and put in your api/class and use it instead. If you satisfied with your api then move the actual working code you have written so far into the api/classes. Dont go any further than that. If you are advanced you can plan a little bit for the future, but only a little bit.

You can always abstract it away later! Do not abstract it right away, even when it looks obvious.

 

To give an real world example:

Spoiler

I have written a successful business application used by 100+ clients, which had the initial requirements:

- Copy some files in already defined xml file stored somewhere on the clients machine from a non-mapped windows share into a fixed installation path on the user clients machine

- The application must be able to do this without admin user privileges, so the operative code must be executed by a WCF service which has proper rights.

- The user can trigger this operation from a normal desktop application without needing any administrative privileges whatsoever.

- It must be rock solid and must be able to update itself

 

Thats the requriment, now to we get to the actual implementation:

I created a c# console application with one class and the main() entry point only - containing all code to satisfy the base requirements without any others methods or classes. When i run that application with admin rights it worked beutifully. Of course when i run it without admin rights it crashed at that point when it wanted to write/create something  in "C:\Program files" which was the targets base directory.

 

Now i moved out all actual file and directory operation code into its own static methods and made sure that it still works and does not depend on anything. Then i created a interface "IAdminFileOperations" containing all that method signatures. After that i created a class which implements the interface and containing all the code i had already. Of course i changed all the code to use the new interface and the implementation class instead and tested it by a unit-test class.

 

Now i had to get it working without admin privileges, called by that console application - which was a pain in the ass.

So i created two additional projects: One WCF windows service, one class library. I moved the interface into the class library and moved the implementation class into the windows service. A few days later i got it working doing exactly what i wanted. Why tooked it so long? Well... WCF (Windows Communication Framework) just sucks and is one of the worst network framework thingy i ever have worked with. But well it was a required, so i got it working and was happy...

Got it more features than i had before? No i just abstracted the IO operations to the service and thats it - with a few more required classes and interfaces... just because WCF... *sigh*

 

I personally had used a simple TCP network server/client approach, but it was a requirement from the management so i had no choice :-(

 

Long story short:

Now the console application is a full blown WPF GUI Application powered by DevExpress requiring millions of dll´s... with UI, progress bar, labels, buttons, whatsoever. Just doing the same thing as before: Copying files from A to B...

Of course the initial features was expanded in great detail and now its about 50 k lines of code with tons of classes. Now it supports FTP,  SFTP and Share´s as Source and Target as well - including impersonation if needed, but only abstracted with one interface and one class for each system. Just one layer more than i had before.

But the actual code which loops over the source files and triggers the actual operations is still the same as it was before: One gigantic method (>100 lines of code) - just because it worked beutifully and their was no need to change or abstract that. If there isn´t a need, dont abstract it.

 

And yes most of it is unit-tested, but the WCF part is not...

 

Could i have planned it? Partly yes, but the planning in this case would be useless just because the initial requirements was changed so much and often that it had never matched the planning at all... Also i had no idea about WCF and had to learn it. The documentation for that was pretty bad as well...

 

One major mistake i learned from that:

Dont put any code into a static constructor! When one single exception gets thrown you are screwed and the windows service wont startup.

 

Edited by Finalspace

Share this post


Link to post
Share on other sites
On 10/9/2017 at 7:31 AM, MarcusAseth said:

Now the next step should be to load a level, I guess. I am not yet sure how to handle that, never done. Should Level be a class object that I call with the path on disk of the level data? What is that data? a .txt? How do I parse the data to make it create the appropiate entity type inside the game?

There are many options possible here.

  • Make levels on Tiled, export to *.JSON and interpret using a JSON parser (which there are many online). Or export to *.CSV, which is very easy to parse without 3rd libraries.
  • Make the levels in the source code itself ¯\_(ツ)_/¯ that's what I'm doing, since the levels are small.
  • Procedural generation. 

 

Share this post


Link to post
Share on other sites
On 10.10.2017 at 11:57 PM, ferreiradaselva said:

There are many options possible here.

  • Make levels on Tiled, export to *.JSON and interpret using a JSON parser (which there are many online). Or export to *.CSV, which is very easy to parse without 3rd libraries.
  • Make the levels in the source code itself ¯\_(ツ)_/¯ that's what I'm doing, since the levels are small.
  • Procedural generation. 

 

Another option is to store the level in a uncompressed PNG/BMP image.

Making levels would just require a image creation programm, like paint.net, paint, photoshop, etc. Each pixel would represent a tile. Colors or components define the index into a tilesheet.

You can even have multiple layers - just make each pixel component a layer, for example: Red are solid tiles, Green are background tiles, Blue are entities etc.

 

I personally store my levels in binary files, so i can load it without doing any parsing at all.

Of course this requires you to make a plugin for an existing editor or write your own level editor - which is not that hard.

 

I recommend when you just want to define a simple level, just use a constant array in the code to get started.

Edited by Finalspace

Share this post


Link to post
Share on other sites

I'm probably in too. I'm using my home made Xtreme engine, which I've already used for WoA entries (and most other games on my home page).

I'm going for a second part of a Bubble Bobble clone I wrote back in DOS ages with Turbo Pascal. 

The levels are storied binary as well. If I ever see I'm going to do lots of stages I usually implement a simple editor in the game itself. A real editor helps a lot if you want to quickly test out different things.

 

Share this post


Link to post
Share on other sites
2 hours ago, povilaslt2 said:

Probably will try to do this challenge if I learn how to do that path finding. How you will do your path finding for this challenge?

Maybe you can try a line trace to a direction, so you can see where you can walk and where you cant. But making it jump is a lot harder i think. Also you can use a tilemap structure to see where you can walk and where you cant. I dont think you need a path finding for that.

But i never made any AI programming in my entirely 25 years of programming at all, so i just guess. Maybe it isn´t that hard?...Also there are plenty of resources out there.

 

Regarding if you can do this challenge: Just start and do it, you will see how far you can get. You can always hack something in :D

Edited by Finalspace

Share this post


Link to post
Share on other sites
3 hours ago, povilaslt2 said:

Probably will try to do this challenge if I learn how to do that path finding. How you will do your path finding for this challenge?

What @Finalspace said about checking the tiles to see where the enemy can walk and where it can't is a good and simple idea. (it is what I'm doing, too).

On 10/13/2017 at 3:10 PM, Finalspace said:

Making progress after a few evenings (Yeah i know it looks really devy, but it works great and has a stable system behind):

https://www.youtube.com/edit?o=U&video_id=iGGA1d_8dJY

Can't see the video. It's redirecting to my own channel url.

 

I'm slow on the development bc I'm studying for a test on 22nd :'(, after that I will be able to finish the game.

Share this post


Link to post
Share on other sites

I'm still somewhat new when it comes to game creation, considering I haven't ever finished or really even done anything, been doing some basic tutorials with Unity. I did some with Gamemaker, but I wasn't a huge fan of Gamemaker even after finishing a tutorial with that.

Regardless, maybe I'll atleast try and make something for this, just for the experience. 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now