Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  
Pages: 1 ... 73 74 [75] 76 77 ... 796

Author Topic: if self.isCoder(): post() #Programming Thread  (Read 886266 times)

nenjin

  • Bay Watcher
  • Inscrubtable Exhortations of the Soul
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #1110 on: February 01, 2012, 07:00:14 pm »

So, you still write a pointer into the class definition, then set the pointer equal to an object at run time? Or not?

And what would a member access statement look like?

Quote
And if the object was defined at run-time (i.e. no use of the 'new' operator) it doesn't have to be deleted either.

And that's because of what memory section it's set up in (the stack vs. the heap), yeah?
« Last Edit: February 01, 2012, 07:04:26 pm by nenjin »
Logged
Cautivo del Milagro seamos, Penitente.
Quote from: Viktor Frankl
When we are no longer able to change a situation, we are challenged to change ourselves.
Quote from: Sindain
Its kinda silly to complain that a friendly NPC isn't a well designed boss fight.
Quote from: Eric Blank
How will I cheese now assholes?
Quote from: MrRoboto75
Always spaghetti, never forghetti

Aqizzar

  • Bay Watcher
  • There is no 'U'.
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #1111 on: February 01, 2012, 07:05:05 pm »

I'm stumped on where to go in teaching myself game development.

The next logical step for my roguelike (which I haven't touched in a week) is to implement line of sight calculation, if simply by copying a tutorial.  The problem is, I can already see that my hunt-and-peck tile drawing method, used to save the processing and waiting time of redrawing the whole Console each turn, will be a painful development bottleneck that I shouldn't try to account for.

What I should be doing is learning how to use a "graphic" library, in the manner of Curses (or libtcod), however the Hell that works.  I keep waiting for some nebulous person to hold my hand through it, but I don't even know what it means.

And then as soon as I thought of that, I remembered that I keep itching to jump into another idea, a turn-based strategy game where I would be perfectly forgiven for redrawing the Console all the time.  Which is basically a way of avoiding the issue when I should be teaching myself a new element.

Indecision is crippling.  Anyone have anything to say about libraries I should know, before jumping in blind?
Logged
And here is where my beef pops up like a looming awkward boner.
Please amplify your relaxed states.
Quote from: PTTG??
The ancients built these quote pyramids to forever store vast quantities of rage.

nenjin

  • Bay Watcher
  • Inscrubtable Exhortations of the Soul
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #1112 on: February 01, 2012, 07:08:35 pm »

Library use is something I find kind of daunting too. I've had arguments with other coders who are like "You don't need to understand the library, you just need to believe it does what is says it will do!"

And that seems pretty hard to swallow. But as they tell it, go Google libraries, read the documentation on them....and go to work. I've seen Libtcod mentioned so often it seems the place to start.
Logged
Cautivo del Milagro seamos, Penitente.
Quote from: Viktor Frankl
When we are no longer able to change a situation, we are challenged to change ourselves.
Quote from: Sindain
Its kinda silly to complain that a friendly NPC isn't a well designed boss fight.
Quote from: Eric Blank
How will I cheese now assholes?
Quote from: MrRoboto75
Always spaghetti, never forghetti

Aqizzar

  • Bay Watcher
  • There is no 'U'.
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #1113 on: February 01, 2012, 07:13:26 pm »

I guess my real question is, after downloading Libtcod C# (last build, August 2010), what do the heck do I do with this thing?  The test-example program runs fine, but how do I actually use it?  The home site doesn't seem to have C# documentation, and it sure doesn't come with any.
Logged
And here is where my beef pops up like a looming awkward boner.
Please amplify your relaxed states.
Quote from: PTTG??
The ancients built these quote pyramids to forever store vast quantities of rage.

Levi

  • Bay Watcher
  • Is a fish.
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #1114 on: February 01, 2012, 07:14:28 pm »

I guess my real question is, after downloading Libtcod C# (last build, August 2010), what do the heck do I do with this thing?  The test-example program runs fine, but how do I actually use it?  The home site doesn't seem to have C# documentation, and it sure doesn't come with any.

Here are the docs:
http://doryen.eptalys.net/data/libtcod/doc/1.5.1/index2.html?c=false&cpp=false&cs=true&py=false&lua=false

And although its not in C#, you can probably follow along a bit with this great tutorial:

http://roguebasin.roguelikedevelopment.org/index.php/Complete_Roguelike_Tutorial,_using_python%2Blibtcod
« Last Edit: February 01, 2012, 07:16:02 pm by Levi »
Logged
Avid Gamer | Goldfish Enthusiast | Canadian | Professional Layabout

Aqizzar

  • Bay Watcher
  • There is no 'U'.
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #1115 on: February 01, 2012, 07:31:44 pm »

I guess my real question is, after downloading Libtcod C# (last build, August 2010), what do the heck do I do with this thing?  The test-example program runs fine, but how do I actually use it?  The home site doesn't seem to have C# documentation, and it sure doesn't come with any.

Here are the docs:
http://doryen.eptalys.net/data/libtcod/doc/1.5.1/index2.html?c=false&cpp=false&cs=true&py=false&lua=false

Well, that sure looks helpful, but how do I actually put the library in the program?  Is it a using thing?  Where do I put the files?

I know these probably sound like retarded questions to anyone who knows what they're doing, but I was in over my head as soon as I downloaded this thing.
Logged
And here is where my beef pops up like a looming awkward boner.
Please amplify your relaxed states.
Quote from: PTTG??
The ancients built these quote pyramids to forever store vast quantities of rage.

Max White

  • Bay Watcher
  • Still not hollowed!
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #1116 on: February 01, 2012, 07:40:22 pm »

Alright! We are onto libtcod? I can throw up a hello world if you give me a second, just logged onto the intertubes, so gotta do some chores, but otherwise I can help out here.

Levi

  • Bay Watcher
  • Is a fish.
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #1117 on: February 01, 2012, 07:44:36 pm »

Well, that sure looks helpful, but how do I actually put the library in the program?  Is it a using thing?  Where do I put the files?

I honestly have no idea.   :P Is there a dll?  Maybe just drop it and whatever font files are there right into the directory you compile too.  Maybe...
Logged
Avid Gamer | Goldfish Enthusiast | Canadian | Professional Layabout

Max White

  • Bay Watcher
  • Still not hollowed!
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #1118 on: February 01, 2012, 08:01:31 pm »

Ok, libtcod for c#!
First I want you to make sure you have all of these files.
  • libtcod-net.dll
  • libtcod-net-unmanaged.dll
  • libtcod-VS.dll
  • SDL.dll
  • zlib1.dll
  • terminal.png
Now make a new folder in the same file inside your program in windows, and add a copy of all those files. Name the file Libtcod, or support or services if you want, but libtcod is probably best.
The first one, libtcod-net.dll, is what we will be using. It is a dynamically linked library, and provides access to everything we need. To use this, you need a reference to it. To do this, find references on the right side of your screen, right click, add reference, browse, find and select libtcod-net.dll
Now that that is added, you might be wondering what those other files are for. While our program is dependant on only libtcod-net, it is dependant on other dlls. If it can't find these, the program crashes. So that it knows where to find them, you need to add them to the project.
Right click on the name of your project, and select 'Add existing item' and change file type to executable file. Now find those four and add them to the project.
The last item is your sprite sheet. You can use any sheet, but by defult it is configured to curses. To save having to configure it before we can make a hello world, you should be using something like this.

It is the exact same graphic that dwarf fortress, and many other roguelikes use.
This time go to add existing item, but change file type to image file, and throw it in.

Now even though they are part of our solution, that doesn't mean libtcod will have access to them. They need to be in the same file location   as the exe when we try to run it. So, select the four extra dlls and one image file you added, and in the properties box below the solution explorer, you should hopefully be able to find a tag labelled 'Copy to output', change this to 'Copy if newer'

There, you can now start using libtcod! Continues in part 2, when we start to program.

Mego

  • Bay Watcher
  • [PREFSTRING:MADNESS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #1119 on: February 01, 2012, 08:27:44 pm »

So, you still write a pointer into the class definition, then set the pointer equal to an object at run time? Or not?

And what would a member access statement look like?

Quote
And if the object was defined at run-time (i.e. no use of the 'new' operator) it doesn't have to be deleted either.

And that's because of what memory section it's set up in (the stack vs. the heap), yeah?

Code: (C++ Classes and Pointers) [Select]
#include <string>
#include <iostream>

using namespace std;

class Stuff {
int number;
double decimal;
string name;
public:
void setNumber(int n) {
number = n;
}
void setDecimal(double d) {
decimal = d;
}
void setName(string s) {
name = s;
}
int getNumber() {
return number;
}
double getDecimal() {
return decimal;
}
string getName() {
return name;
}
};

int main() {
Stuff junk;
Stuff *p = &junk;
junk.setNumber(42);
cout << (*p).getNumber() << endl; // The first method of accessing member stuff with a pointer, by dereferencing the pointer and then using the dot operator for member access
p->setDecimal(3.14); // The second (and preferred) method of accessing member stuff with a pointer, with the arrow operator
cout << junk.getDecimal() << endl;
Stuff *q = new Stuff(); // Dynamic allocation
q->setName("Mego");
junk.setName(q->getName());
cout << boolalpha << (q->getName() == p->getName()) << endl; // boolalpha makes the program print "true" and "false" instead of "1" and "0"
delete q; // q was dynamically allocated, so we have to delete it, or else we get memory leaks
return 0; // We do not delete junk or p, because they were both statically allocated, and will be destroyed at the end of the function. Plus, junk wasn't a pointer, so we can't delete it anyway.
}

Code: (Output) [Select]
42
3.14
true

nenjin

  • Bay Watcher
  • Inscrubtable Exhortations of the Soul
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #1120 on: February 01, 2012, 08:31:04 pm »

Thanks Mego, that was exceptionally helpful.
Logged
Cautivo del Milagro seamos, Penitente.
Quote from: Viktor Frankl
When we are no longer able to change a situation, we are challenged to change ourselves.
Quote from: Sindain
Its kinda silly to complain that a friendly NPC isn't a well designed boss fight.
Quote from: Eric Blank
How will I cheese now assholes?
Quote from: MrRoboto75
Always spaghetti, never forghetti

Max White

  • Bay Watcher
  • Still not hollowed!
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #1121 on: February 01, 2012, 09:03:25 pm »

Ok, now over to your main! First thing we need to do before we can start drawing onto a console is to tell libtcod that is is needed, and the specifics for the console to make. We do this by initializing the root console, like so!
Spoiler (click to show/hide)
Are red lines showing up? I'm betting they are. This is because even though we have a reference to libtcod in our project, we don't have the using statement for this block of code. Because we are using visual studio, there is a really easy fix for this. Right click the offending code (In this case TCODConsole) and select "Resolve" and then "Using libtcod;" and this will add the using statement for you. This can be mighty handy when you know what class you need, but no idea where to find it.
Anyway, black magic? Not really. TCODConsole is the class for consoles in libtcod, so instead of Console.DoShit(), you will need to call TCODConsole.DoShit(). This can get annoying at first, but there is a great little work around that will come later.
initRoot is just the name of the static method we are calling.
Now 80 is the width, in tiles, of your console, and 40 is the height. "Name of your game" is the string that will appear in the title of the window. The past parameter, a bool, is for if you want your game to be full screen or not. If this were true, your game would be stretched to fullscreen and the tiles would appear much larger, but you would still have a 80 * 40 aspect.

Now we want our game to exist in a loop, so that we don't go through once and it ends. We can add the following for that.
Spoiler (click to show/hide)
A bit of a jump in the amount of code, but hopefully it is all stuff you have seen before. The only new thing here is TCODConsole.isWindowClosed()
If the window is still open, that will return false, otherwise once the player clicks the X in the top right hand side to close, it will become true. We also made a public method to quit, and that will become some what handy later on.

Now let's make it print something!
Spoiler (click to show/hide)
Try running that, and tell me how it works out for you.
Not exactly what you were hoping for, is it? The screen is just white! This is because even though you updated the root console, you never told it that it needs to print itself onto the main screen. With the standard c# console, it updates every time you draw something, but that would be a little slow for our needs, so instead we tell it what to draw, then tell it to draw later. So let's add that code now!
Spoiler (click to show/hide)
Run that. A big improvement! We have graphics in their simplest form, a hello world. But something is still wrong. We can't interact with the screen in any way. It is totally unresponsive to our input. That is because we haven't told the console that we want any input!
Libtcod handles input in what can only be described as the dumbest of ways. Seriously, this shit is retarded, and you may grow to hate it, but we will do what we can. To make the console responsive again, we add this line of code.
Spoiler (click to show/hide)
That will check for not only a key press, but any and all input, mouse included. It gets significantly worse, trust me. Still, that is the basis of the hello world!
Coming soon: Part 3; Something that people really should fucking do when making games, but often don't, and shoot themselves in the foot because of it.

Aqizzar

  • Bay Watcher
  • There is no 'U'.
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #1122 on: February 01, 2012, 09:16:42 pm »

That sounds pretty important, whatever is in Part 3.

This raises a critical question though.  Does this mean I'll have to go back through my code and rewrite every instance of Console to use libtcod's methods?  Or is there some way to set it up so that I can use standard C# Console commands, and libtcod will catch them and use them for itself?
Logged
And here is where my beef pops up like a looming awkward boner.
Please amplify your relaxed states.
Quote from: PTTG??
The ancients built these quote pyramids to forever store vast quantities of rage.

Virex

  • Bay Watcher
  • Subjects interest attracted. Annalyses pending...
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #1123 on: February 01, 2012, 09:32:07 pm »

This may be more of an algorithm question than a programming question, but eff it, it's too late to program anything and you guys are probably my best bet.


I've been working on a new FoV algorithm for grid-based games. The idea is as following:


Step 1:
Start at the center of the player's tile (0.5, 0.5) and cast rays in the directions [1, 0], [1,1], [0, 1] [0, 0], [-1 0] et cetera, using Bresenham's Line algorithm. Terminate the rays when they reach the edge of the FoV or pass through an obstacle.


Step 2: Take every tile surrounded by 3 visible tiles that are not obstacles, and cast a ray from the player through it. We do not need to consider the tiles between the player and the starting tile because they have been visited already.
Spoiler (click to show/hide)


Step 3: Repeat until there are no more tiles surrounded by 3 visible empty tiles.
Spoiler (click to show/hide)


Now, the algorithm has the advantage that it is guaranteed to visit each tile exactly once. However, as you can see from the last image, it introduces some artifacts, as it only considers tile centers and not corners. This is especially jarring in case of the horizontal wall as only the front end is visible, while it feels like the whole wall should be visible. Now, I could solve this problem by casting rays from corner to corner instead of from center to center, but then we run into the problem that a lot of tiles are visited twice. So I was wondering if anyone knows some other trick that can be employed here?
« Last Edit: February 01, 2012, 09:34:11 pm by Virex »
Logged

Max White

  • Bay Watcher
  • Still not hollowed!
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #1124 on: February 01, 2012, 09:59:27 pm »

At this point, I would say archive your game, start fresh using the things you have learnt, develop significantly faster than you were before.
Now, part 3 is all about structure, and making sure your game stays neat, instead of becoming a mess of code. To start with, this is an object oriented language, so let's move this code over to a new class called 'Game', and take out some of that static!
Spoiler (click to show/hide)
We can refine this a little more through use of constructors.
Spoiler (click to show/hide)
Back in our main, and we can change it to this.
Spoiler (click to show/hide)
There is a good chance that is all our main will ever be... Kind of sad, to think that the entry point to the entire program is nothing more than making a new game, a lonely gate keeper, so to speak. Until you realise it is just code and doesn't have the capacity to feel lonely.

Anyhoo! There will come a point when you want different states for your game, such as when you are in the main menu, when you are in character creation and when you are playing a level. To make the switch between states, it may seem tempting to do something like this.
Spoiler (click to show/hide)
And then have a massive switch statement to handle the flow of the program. Trust me, I have a much better way that isn't going to do your head in later on.
To start with, add a new class, and call it 'GameState', now make it abstract, make a protected constructor, and give it a protected variable for a Game. You should hopefully end up with this.
Spoiler (click to show/hide)
Now for a little bit of separation of logic. Updating a game, and drawing a game and different things, so let's have different methods for them.
Spoiler (click to show/hide)
Now you might have noticed we are taking a console as a parameter. I might have forgotten to mention, but in libtcod consoles are not static. You can make new ones, and pass them around. The point of this is so that you can 'blit' one on top of another, and have a console for each screen currently being shown.
Anyway, the point of having two separate methods is that later on, when we have a few more tricks under our belt, we can upgrade our game so that if the FPS is running low we can skip drawing a few frames to catch up, making the game move a lot less lagy.

Back in our game class, it needs a bit of up upgrade to handle states. Firstly it will need a reference to it's state, and a method to set a new state. Also removing the line to take keyboard input. This is because in some instances you might want the game to run in real time, but otherwise you might want it to wait for input, so this depends on the state. Hell, you might even want an opening cut scene where they get no input! Up to you. But here is what you should be looking to achieve.

Spoiler (click to show/hide)

That is pretty much it for structure. You can now swap between states without the need for big, bulky switch statements. I'll give you a little example of a test state to get you started. Feel free to ask any questions.

Spoiler (click to show/hide)
And don't forget to update that line in the constructor of the Game class.

Edit: Sorry, forgot something, updated it.
Pages: 1 ... 73 74 [75] 76 77 ... 796