Be a Supporter!

Programming Regs Lounge

  • 422,061 Views
  • 17,911 Replies
New Topic Respond to this Topic
Dean
Dean
  • Member since: Feb. 16, 2008
  • Offline.
Forum Stats
Moderator
Level 47
Gamer
Response to Programming Regs Lounge 2013-02-21 14:33:17 Reply

I thought a congratulations was in order, seeing as Diki is now a forum moderator! Congrats Diki. Hopefully now this forum will get the moderation attention it deserves. No longer will you have to put up with awful threads that belong in the Flash forum. If you do see one, spam Diki's inbox until it has been dealt with :P

In other news, my uni bought in some Nexus 7 Android tablets so I snagged one for the next 7 weeks. Now I finally have a device that can make use of the Android API features I need. Apparently my HTC WildfireS is too old to use Android's RTP classes. My friend Simon was also trusting enough to offer me a loan of his Motorola tablet. I think it's a "Xoom"? Anyway, now I have no excuse to delay working on my dissertation project because I have all the hardware I need. I'll probably still end up not working on it as much as I need to though, because I've become lazy.

In other other news, still trying to get to grips with C++. It's taking me longer than I thought it would. Bloody pointers. I understand them as a concept but having been raised on Java I'm still not quite grasping how/when to use them. Defining a class, creating an instance of that class and then trying to call one of that instance's functions was driving me loopy last night. That shouldn't even be such a hard thing to do but for some reason I just couldn't work it out. I'm planning on working a lot more than usual over this weekend. I feel like I'm starting to fall behind so I need to correct that.


BBS + Chat Moderator - Feel free to send me a PM if you have a problem!
Want to instant message me? [ Skype - DeanNewgrounds ]

BBS Signature
Diki
Diki
  • Member since: Jan. 31, 2004
  • Online!
Forum Stats
Moderator
Level 13
Programmer
Response to Programming Regs Lounge 2013-02-21 15:30:16 Reply

At 2/21/13 02:33 PM, Dean wrote: Congrats Diki.

:)

At 2/21/13 02:33 PM, Dean wrote: Bloody pointers. I understand them as a concept but having been raised on Java I'm still not quite grasping how/when to use them.

They're definitely a wily beast.
A common use for pointers is to store the address of memory that is dynamically allocated at run time, or to pass large amounts of stack-data to a function without having to reallocate it. Here's an example of that second point:

struct Thing {
    int64_t data[32];
}

struct ComplexThing {
    Thing stuff[128];
}

void doSomething(ComplexThing *ptr) {
    // Do stuff here
}

int main() {
    ComplexThing foo;
    doSomething(&foo);
}

Pretend you had a good reason for those arrays.

Since the passed ComplexThing is a pointer it will only push a single pointer onto the stack (which will be either 32 or 64 bits, depending on compiler settings) and then assign the memory address to it which is just a simple integer assignment.
If you were to instead just pass a copy it would, at runtime, push 256KB onto the stack, and then have to assign 256KB worth of data. Imagine that's something you need to do in an update loop for an application; you would be wasting a lot of resources.

There is also a limit to how much data can be put onto the stack (the heap as well, but it's much larger). If you attempt to push too much data onto the stack it will overflow, which is why large data allocations should be done on the heap which will give you a pointer in return.

And here's one more thing you can do with pointers:

struct Color {
    unsigned char r, g, b;
};

int main() {
    Color color;

    color.r = 128;
    color.g = 64;
    color.b = 256;

    unsigned char *colorPtr= &color; // This will cast the Color pointer to a unsigned char pointer automatically

    unsigned char r = colorPtr[0]; // 128
    unsigned char g = colorPtr[1]; // 64
    unsigned char b = colorPtr[2]; // 256
}

Casting the Color pointer to an unsigned char pointer will give you a pointer to the same data, but in "char sized" chunks. Pointers in C/C++ can be used in a similar manner to arrays, so the [] operator will return the "elements" that the pointer points to (I put that in quotations since they're not really elements).
When you use the [] operator with a pointer it's the same thing as incrementing the pointer by the passed value multiplied by the size of the pointer type in bytes, and then dereferncing the result.

For the sake of argument assume that colorPtr is at the memory address 0x00A0.
And for the sake of clarity remember that a char in C/C++ is always 1 byte. That means that 0x00A0 is the address of the "r" member variable, 0x00A1 is the address of the "g" member variable, and 0x00A2 is the address of the "b" member variable.
So when you access element [0] you are incrementing 0x00A0 by 0 times the size of a char, which is 1, so you have 0x00A0 + (0*1) which is of course 0x00A0 which gives you the "r" member. Each operation is broken down like this:

[0] -> 0x00A0 + (0*1) = 0x00A0
[1] -> 0x00A0 + (1*1) = 0x00A1
[2] -> 0x00A0 + (2*1) = 0x00A2

Using the [] operator will also dereference the memory address for you, which gives you the value at that location, which in this example of the red/green/blue colour values.

Hopefully I explained that well.
If you don't understand something just say, and I'll do my best to explain it better.

Dean
Dean
  • Member since: Feb. 16, 2008
  • Offline.
Forum Stats
Moderator
Level 47
Gamer
Response to Programming Regs Lounge 2013-02-21 16:50:55 Reply

At 2/21/13 03:30 PM, Diki wrote: Hopefully I explained that well.

I appreciate the time you took to do that. It definitely gave me a better understanding of why they're useful. It's just when it comes to writing C/C++ code for myself, I always have to stop and think "wait, should I be using a pointer to an object here?" I'm still not at the stage where it comes naturally to me. It's like an additional level of thinking is required and I'm still not used to it.

I expected to be doing some C++ stuff tonight but it doesn't look like I will be at this rate. Too caught up watching YouTube videos and I'll probably stick some Star Trek on in a bit. If I'm still having bother with it tomorrow I'll make a post about it and I'd appreciate if you could point out what I'm doing wrong. It was just meant to be a really simple introduction to C++ type task. Create a class called Person with attributes for a name and id number. There's also be a function called "print" that would print out the name. Initialise a few instances of that class in the main program and we were to take a person's id number as user input and then return the name of the person who had that id. It sounded like really really simple stuff and I'm pretty certain it is really simple stuff, but I just couldn't get it working and it frustrated me. Something that simple shouldn't have taken me so long and then fail to get working.


BBS + Chat Moderator - Feel free to send me a PM if you have a problem!
Want to instant message me? [ Skype - DeanNewgrounds ]

BBS Signature
Diki
Diki
  • Member since: Jan. 31, 2004
  • Online!
Forum Stats
Moderator
Level 13
Programmer
Response to Programming Regs Lounge 2013-02-21 17:34:28 Reply

At 2/21/13 04:50 PM, Dean wrote: I'm still not at the stage where it comes naturally to me. It's like an additional level of thinking is required and I'm still not used to it.

Unfortunately that's one of the things you can really only learn through experience. Though a good rule of thumb is for any non-scalar type that is larger than 32 bytes, and is being passed to a function, should be passed as a pointer or reference.
Discerning between pointers and references isn't too big of a deal; they're pretty much the same thing (you can think of a reference as a pointer that is always dereferenced and cannot be incremented or decremented). Personally I only use a reference when I want a guarantee that the value passed isn't NULL.

At 2/21/13 04:50 PM, Dean wrote: If I'm still having bother with it tomorrow I'll make a post about it and I'd appreciate if you could point out what I'm doing wrong.

I'm more than happy to offer what advice I can. :)

At 2/21/13 04:50 PM, Dean wrote:

:Something that simple shouldn't have taken me so long and then fail to get working.

C++ is good at making something that you would think is simple be rather difficult.
It will make you its bitch, and have you come back asking for more.

Dean
Dean
  • Member since: Feb. 16, 2008
  • Offline.
Forum Stats
Moderator
Level 47
Gamer
Response to Programming Regs Lounge 2013-02-21 18:08:06 Reply

So I decided to hold back on watching Star Trek and get this simple little program working. It's working, but I thought I'd just dump it here and see if you had anything to point out. I get the impression that I might be misusing header files or something, so if you see anything that looks wrong or out of place, let me know. I'd rather get my misunderstandings resolved ASAP because believe it or not, I'm expected to have developed a simple arcade game in a few weeks time!

People.cpp (entry point of application)

#include "stdafx.h"
#include "Person.h"
#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	Person *dean = new Person(1, "Dean");
	Person *john = new Person(2, "John");
	Person *sam = new Person(3, "Sam");
	Person *paul = new Person(4, "Paul");
	Person people[4] = {*dean, *john, *sam, *paul};
	
	cout << "Enter the id of an employee: ";
	int input;
	cin >> input;

	for(int i=0; i < 3; i++)
	{
		if(people[i].get_id() == input)
		{
			people[i].print();
			cin >> input; // Used to halt execution
			return 0;
		}
	}
	cout << "Nobody with that name exists" << endl;
	cin >> input; // Used to halt execution
	return 0;
}

Person.h

#pragma once
#include <string>

class Person
{
private:
	int id;
	std::string name;
	
public:
	Person(int id=-1, std::string name="null");
	int get_id();
	void print();
	~Person(void);
};

Person.cpp

#include "stdafx.h"
#include "Person.h"
#include <iostream>

Person::Person(int id, std::string name)
{
	this->id = id;
	this->name = name;
}

int Person::get_id()
{
	return this->id;
}

void Person::print()
{
	std::cout << this->name << std::endl;
}

Person::~Person(void)
{
}

BBS + Chat Moderator - Feel free to send me a PM if you have a problem!
Want to instant message me? [ Skype - DeanNewgrounds ]

BBS Signature
Diki
Diki
  • Member since: Jan. 31, 2004
  • Online!
Forum Stats
Moderator
Level 13
Programmer
Response to Programming Regs Lounge 2013-02-21 19:02:56 Reply

At 2/21/13 06:08 PM, Dean wrote: I get the impression that I might be misusing header files or something

Nope. You're using them correctly.
Though it's worth noting that #pragma once is not a standard, so it might not be supported on some compilers (I can't think of any off-hand though). The standard way of doing it, and the way I do it just out of habit, is a bit more verbose but is guaranteed to work anywhere:

#ifndef _MYHEADER_H_
#define _MYHEADER_H_

class Foo {
};

#endif

Note: I'm assuming you know what those C-processor commands do. If not I can explain them; it's really simple.

You don't need to use the naming convention I do in that example; that's just what I use when I write code. It really doesn't matter what you use so long as it's consistent throughout your project.

At 2/21/13 06:08 PM, Dean wrote: Person *dean = new Person(1, "Dean");
Person *john = new Person(2, "John");
Person *sam = new Person(3, "Sam");
Person *paul = new Person(4, "Paul");

Using dynamically allocated memory here isn't really necessary. Your class is pretty tiny (it only uses 36 bytes in 32-bit mode), so there's nothing wrong with just throwing that data onto the stack.
Also don't forget that for every single piece of memory that you allocate with new you need to delete. C++ isn't garbage collected and it's easy to leak memory with it. Your small application won't leak memory since once it terminates the memory will be returned to the OS, but it's still a good habit to get into: one delete for every new.

At 2/21/13 06:08 PM, Dean wrote: Person(int id=-1, std::string name="null");

Two things I should mention here:

1) Your giving the variables default values, but in your constructor you don't check if the variables have those values, so ultimately it's not really doing anything. If you want to guarantee that values are given you just not give the constructor any default values. Your program will fail to compile if values are not given.

2) It's a better convention to use const char* for passing strings than std::string because it has less overhead. The STL string class is 32 bytes by itself (in 32-bit mode; I'm not certain if that's also true for 64-bit mode) before even allocating the string you pass to it, which requires data on the heap to be allocated and the given c-string to be copied into it. The std::string class has an overloaded assignment operator for c-strings, so you can just change that type to const char* and it will still work just fine (unless a NULL value is given which will cause your program to crash, so if that's a possibility you should check for that).

At 2/21/13 06:08 PM, Dean wrote: Person::Person(int id, std::string name)
{
this->id = id;
this->name = name;
}

There's nothing really wrong with this, but the C++ convention of assigning values in the constructor is to use an initialiser list:

Person::Person(int id, std::string name)
    : id(id), name(name)
{}

The benefits of this are:

- You don't need to use the this keyword to prevent naming collisions.
- It's completely required if you are assigning a value to a const member because of how C++ works; it requires classes "be ready" before the constructor is called, so a const member needs a value before that.

It also allows you to call the constructor of a child class before that constructor:

Person::Person(int id, std::string name)
    : ChildClass(id, name)
{}

Unless you have a compelling reason not to, of which I cannot think of one, you should use an initialiser list.

At 2/21/13 06:08 PM, Dean wrote: int Person::get_id()
{
return this->id;
}

Nothing wrong here, but using the this keyword here isn't necessary. You could just write return id.

At 2/21/13 06:08 PM, Dean wrote: Person::~Person(void)
{
}

This is also not necessary.
If your destructor doesn't do anything you can just exclude it and the compiler will make an empty one for you. The same goes for constructors (although you need your constructor here).

Dean
Dean
  • Member since: Feb. 16, 2008
  • Offline.
Forum Stats
Moderator
Level 47
Gamer
Response to Programming Regs Lounge 2013-02-22 09:35:40 Reply

At 2/21/13 07:02 PM, Diki wrote: Though it's worth noting that #pragma once is not a standard

Yea, that was just Visual Studio putting that in there so I just left it as it was. Same with the deconstructor.

Note: I'm assuming you know what those C-processor commands do. If not I can explain them; it's really simple.

I can't say I'm terribly familiar with the C Preprocessor. The only times I can think of using it are for the basic stuff like #include or #define. I assume those commands that you mentioned are just there to make sure that the header file hasn't already been defined elsewhere?

Using dynamically allocated memory here isn't really necessary.

So better to just do something like this? I was mainly just doing it that previous way to try and familiarise myself with pointers.

Person joe = Person(5, "Joe");
1) Your giving the variables default values, but in your constructor you don't check if the variables have those values

Yea the compiler was moaning that there was no default constructor or something, so that was the first thing I tried to resolve the issue and it worked. I could maybe do with some clarification on how you set up a default constructor properly.

There's nothing really wrong with this, but the C++ convention of assigning values in the constructor is to use an initialiser list

I'll keep that in mind. Don't think I've ever been shown that way of doing it.

Nothing wrong here, but using the this keyword here isn't necessary. You could just write return id.

Ah, right. I think I've always used the this keyword when I've been writing classes. Bad habit I guess.


BBS + Chat Moderator - Feel free to send me a PM if you have a problem!
Want to instant message me? [ Skype - DeanNewgrounds ]

BBS Signature
Diki
Diki
  • Member since: Jan. 31, 2004
  • Online!
Forum Stats
Moderator
Level 13
Programmer
Response to Programming Regs Lounge 2013-02-22 10:54:46 Reply

At 2/22/13 09:35 AM, Dean wrote: I can't say I'm terribly familiar with the C Preprocessor. The only times I can think of using it are for the basic stuff like #include or #define. I assume those commands that you mentioned are just there to make sure that the header file hasn't already been defined elsewhere?

Yep. That's all they do.
#ifndef is short for if not defined which just checks if the macro has been defined; if it hasn't been that means the file hasn't been included before, so it doesn't touch the code between the #ifndef and #endif statements.

Just remember that all the C-Preprocessor does is manipulate your source code; nothing else. It just goes through the text you wrote, and makes changes to it depending on the commands/macros you wrote. One of the most common uses is "NULL". In C++ NULL is literally just a zero:

#define NULL 0

That means anywhere you type "NULL" (with some exceptions, such as inside a string) it will replace that with a 0, and then the result of all those changes gets sent off to the compiler.
Note: you shouldn't start using 0 in place of NULL just because it will work though; using NULL makes it clear to the reader that your assigning the value to a pointer.

At 2/22/13 09:35 AM, Dean wrote: So better to just do something like this? I was mainly just doing it that previous way to try and familiarise myself with pointers.

Person joe = Person(5, "Joe");

Yeah. That will allocate on the stack, which will be popped off the stack for you once the variable joe falls out of scope (which in this example would be the end of your main function, so the end of the application).
If you'd like to play with your Person class and use pointers you could try making functions that take a pointer to a Person object and changes its values.

Something that helped me learn pointers back when I was new to C++ was to make a linked list that dynamically allocates memory on the heap and therefore uses pointers for everything. If you're looking for a bit of an extra challenge you could even make it a doubly-linked list.
Another good exercise for familiarising yourself with pointers is to reimplement some of the standard library functions, such as memset, strlen, and strcat.

You should never actually do either of those in production code, but it's perfectly fine for the purposes of learning.

At 2/22/13 09:35 AM, Dean wrote: Yea the compiler was moaning that there was no default constructor or something, so that was the first thing I tried to resolve the issue and it worked. I could maybe do with some clarification on how you set up a default constructor properly.

A default constructor is just a constructor that takes no arguments whatsoever, so in your class it would look like this:

Person.h

class Person {
public:
    Person();
};

Person.cpp

#include "Person.h"

Person::Person() {
    // Do something here
}

I forgot to mention in my previous post that this is only generated for you if you do not supply any other constructor. Since you gave a constructor that takes arguments there was no default constructor generated for you.
You do not always need a default constructor though, and in your code I cannot see where the compiler was tripping up on you not having one. Did you change something in People.cpp after getting the "no default constructor" error?

At 2/22/13 09:35 AM, Dean wrote: Ah, right. I think I've always used the this keyword when I've been writing classes. Bad habit I guess.

It does have its uses, and one good thing to remember is that this is just a pointer to the object, so if you are ever writing a method of an object and what to pass a pointer to that object from inside that method you can just pass this.
In my experience I find it to be comparable to the this keyword in AS3: generally you only use it to prevent naming collisions, and sometimes, albeit rarely, to pass around the instance of the object.

Diki
Diki
  • Member since: Jan. 31, 2004
  • Online!
Forum Stats
Moderator
Level 13
Programmer
Response to Programming Regs Lounge 2013-02-23 15:34:49 Reply

Finally got off my ass and got some more work done on my C++ XInput framework EasyXInput.
Other than needing to fix a few style and spacing issues the Readme is now complete (more or less) and shows everything the framework can do with examples. I also cleaned up some parts of the code and added a bunch of missing comments.

There are a few glitches that I need to fix, the two big ones are:
- The ANALOG event never fires.
- The button combo detection is being a bit screwy; I think I introduced this while cleaning up the code (whoops).

Overall I'd say the framework is about 90% complete, and I might be able to get that up to 100% by the end of the day.

kiwi-kiwi
kiwi-kiwi
  • Member since: Mar. 6, 2009
  • Offline.
Forum Stats
Member
Level 09
Programmer
Response to Programming Regs Lounge 2013-02-23 15:46:43 Reply

At 2/23/13 03:34 PM, Diki wrote: - The button combo detection is being a bit screwy; I think I introduced this while cleaning up the code (whoops).

I think this is what's causing problems.

for (std::vector<int>::const_iterator itr = buttonIds.begin(); itr != buttonIds.end(); itr++)
        {
            if (std::find(buttonIds.begin(), buttonIds.end(), *itr) != buttonIds.end()) {
                result = true;
            }
kiwi-kiwi
kiwi-kiwi
  • Member since: Mar. 6, 2009
  • Offline.
Forum Stats
Member
Level 09
Programmer
Response to Programming Regs Lounge 2013-02-23 15:53:47 Reply

Btw, if you expect some users other than yourself, you might also want to remove these from the input.h because they're usually included in precompiled headers to speed up builds

#include <windows.h>
#include <XInput.h>

Otherwise very nice and readable code, nice job

Diki
Diki
  • Member since: Jan. 31, 2004
  • Online!
Forum Stats
Moderator
Level 13
Programmer
Response to Programming Regs Lounge 2013-02-23 16:12:41 Reply

At 2/23/13 03:46 PM, kiwi-kiwi wrote: I think this is what's causing problems.

for (std::vector<int>::const_iterator itr = buttonIds.begin(); itr != buttonIds.end(); itr++)
{
if (std::find(buttonIds.begin(), buttonIds.end(), *itr) != buttonIds.end()) {
result = true;
}

It most definitely was. :)
While making some slight changes to that I fucked it up without noticing; that was supposed to be this:

for (std::vector<int>::const_iterator itr = comboIds.begin(); itr != comboIds.end(); itr++)
{
    if (std::find(buttonIds.begin(), buttonIds.end(), *itr) != buttonIds.end()) {
        result = true;
    }

And now it works just fine.
I've been staring at this code for long I didn't even notice I was comparing a vector to itself. Thanks!

At 2/23/13 03:53 PM, kiwi-kiwi wrote: Btw, if you expect some users other than yourself, you might also want to remove these from the input.h because they're usually included in precompiled headers to speed up builds

#include <windows.h>
#include <XInput.h>

And that's a good point; I definitely am developing this for myself and others to use, so I should probably do that.
Not like it's hard to type out those two lines if someone isn't using precompiled headers anyway.

Diki
Diki
  • Member since: Jan. 31, 2004
  • Online!
Forum Stats
Moderator
Level 13
Programmer
Response to Programming Regs Lounge 2013-02-23 16:49:23 Reply

Actually, I thought about it a little more thoroughly, and talked to some other programmers on IRC, and I've decided to keep the includes in my headers. Keeping them there won't have any significant affect on build speed, and will lower the amount of "setup code" users of my framework will need to write.

NinoGrounds
NinoGrounds
  • Member since: Nov. 28, 2005
  • Offline.
Forum Stats
Member
Level 19
Programmer
Response to Programming Regs Lounge 2013-02-23 20:09:38 Reply

At 2/23/13 04:49 PM, Diki wrote: Actually, I thought about it a little more thoroughly, and talked to some other programmers on IRC, and I've decided to keep the includes in my headers. Keeping them there won't have any significant affect on build speed, and will lower the amount of "setup code" users of my framework will need to write.

w00t w00t congratz Diki. May the Force guide you

Dean
Dean
  • Member since: Feb. 16, 2008
  • Offline.
Forum Stats
Moderator
Level 47
Gamer
Response to Programming Regs Lounge 2013-03-04 16:23:42 Reply

Well, I think I'm starting to get the hang of C++ now. Probably still not using it all that efficiently but I definitely feel like I have a better understanding of the language.

Something I was having trouble with was deleting Bullets from a List whilst iterating through it. I finally have it working. Wouldn't be surprised if one of you were to point out a better way of doing this but as it currently stands the Bullet class has a function to test whether or not the Bullet is off screen. If it is, I'm doing a "delete this;" which is what I wasn't sure about, as it's being done in member function. Is this okay or is there a more correct way of doing this?

Bullet class:

bool off_screen()
{
	if(Bullet::pos.y < 0)
	{
		delete this;
		return true;
	}
	return false;
}

Then in part of the game's main loop, I run through all the Bullets and update their positions. When it runs the "off_screen()" function, the Bullet object will be deleted (if it is off screen) and then the pointer to that Bullet will be erased from the list.

Main program loop:

std::list<Bullet*>::iterator bullet_it = bullets.begin();
	while(bullet_it != bullets.end())
	{
		(*bullet_it)->update();
		
		// Delete bullets if they are off screen
		if((*bullet_it)->off_screen())
			bullets.erase(bullet_it++);
		else
			++bullet_it;
	}

So yea, any comments on how I'm doing this? Like I say, it seems to work as expected although I'm not sure how to check whether or not the Bullets are being deleted from memory, but they're definitely being erased from the list. I guess I'm mainly just curious as to whether or not having a "delete this;" in a member function is okay.

But yea, the whole idea of pointers are starting to make sense to me now. I hope.


BBS + Chat Moderator - Feel free to send me a PM if you have a problem!
Want to instant message me? [ Skype - DeanNewgrounds ]

BBS Signature
Diki
Diki
  • Member since: Jan. 31, 2004
  • Online!
Forum Stats
Moderator
Level 13
Programmer
Response to Programming Regs Lounge 2013-03-05 02:50:01 Reply

At 3/4/13 04:23 PM, Dean wrote: If it is, I'm doing a "delete this;" which is what I wasn't sure about

It's perfectly legal code and won't cause any problems if you do it correctly.
In your example there's nothing really wrong with it since you're not doing anything with your object after deleting it.

Personally I would do the deleting in your main loop, or in a separate function, though, but it's really just a matter of taste.

At 3/4/13 04:23 PM, Dean wrote: Main program loop:

std::list<Bullet*>::iterator bullet_it = bullets.begin();
while(bullet_it != bullets.end())
{
(*bullet_it)->update();

// Delete bullets if they are off screen
if((*bullet_it)->off_screen())
bullets.erase(bullet_it++);
else
++bullet_it;
}

This is also perfectly legal and there's nothing wrong with it.
Though it's worth noting that this only works because you are incrementing the iterator before removing the value, and you're using the post-fix increment operator so it passes the previous position, which is precisely the way you remove from a list while iterating over it, so hopefully you didn't do it the correct way accidentally and it's what you wanted to be doing. :)

At 3/4/13 04:23 PM, Dean wrote: So yea, any comments on how I'm doing this? Like I say, it seems to work as expected although I'm not sure how to check whether or not the Bullets are being deleted from memory

Add a destructor to the Bullet class, and then create a global variable that will act as a counter; make it a signed int and initialise it to 0, and also make sure that the Bullet class has access to that global variable.
In the constructor of Bullet increment the counter by one, and in the destructor decrement it by one. Since the delete operator will always call the destructor of the passed argument the counter variable will be be equal to 0 if everything you allocated was also deleted; anything greater than 0 means you're leaking memory.

That's one way to unit test quickly which is pretty sufficient, though the absolute best way to detect memory leaks is to use something like Dr. Memory if you're on Windows or Valgrind if you're on Linux or OSX. These programs will "watch" what memory you allocate and how much you deallocate, and will tell you if those values are not equal. They're very handy programs.

Dean
Dean
  • Member since: Feb. 16, 2008
  • Offline.
Forum Stats
Moderator
Level 47
Gamer
Response to Programming Regs Lounge 2013-03-05 16:27:14 Reply

Apologies for all these technical questions in the lounge but it seems better for me to ask here rather than make new threads for this stuff.

Basically I'm trying to implement the collision detection in my Space Invaders clone and it's giving me grief. Here's my current collision detection strategy:

enemy_it = enemies.begin(); // Enemy iterator
bullet_it = bullets.begin(); // Bullet iterator

while(bullet_it != bullets.end()) // Loop over all bullets
{
	Vector2D bullet_pos = *(*bullet_it)->get_pos(); // Get current bullets position

	while(enemy_it != enemies.end()) // Compare this bullet with all the enemies
	{
		Vector2D enemy_pos = *(*enemy_it)->get_pos(); // Get current enemys position
		if( /* Collision test */ ) 
		{
			(*enemy_it)->kill(); // Collision, so delete enemy
			(*bullet_it)->kill(); // Delete bullet
			enemies.erase(enemy_it); // Erase enemy from list of enemies
			bullets.erase(bullet_it); // Erase bullet from list of bullets
			break; // Bullet destroyed so no need to compare it with remaining enemies
		}
		else
			++enemy_it; // No collision with current enemy so check next enemy
	}
	++bullet_it; // Check the next bullet
}

It's detecting the collisions but I'm getting a "List iterator not incrementable " error on the bullet list iterator, I think. My guess is that the "break;" is the cause of the problem somehow. The break should exit the inner while loop and run the "++bullet_it;" line, right?

Any help would be appreciated. I thought this would have been straight forward but somehow I've managed to muck it up. I'm half expecting this to be a really straight forward fix but right now I'm failing to see it. I'm tempted to blame it on tiredness but I'll spare you the excuses haha.


BBS + Chat Moderator - Feel free to send me a PM if you have a problem!
Want to instant message me? [ Skype - DeanNewgrounds ]

BBS Signature
Diki
Diki
  • Member since: Jan. 31, 2004
  • Online!
Forum Stats
Moderator
Level 13
Programmer
Response to Programming Regs Lounge 2013-03-05 16:46:50 Reply

You're removing the iterator from the list, and then attempting to increment it, which is a no-no. If you increment it, and then remove the iterator that it was previously, it should work.
From the looks of it you'll want to do something like this:

enemies.erase(enemy_it++); // Erase enemy from list of enemies
bullets.erase(bullet_it++); // Erase bullet from list of bullets

And then make sure you don't increment "bullet_it" twice with this line:

++bullet_it;
Dean
Dean
  • Member since: Feb. 16, 2008
  • Offline.
Forum Stats
Moderator
Level 47
Gamer
Response to Programming Regs Lounge 2013-03-05 17:54:26 Reply

At 3/5/13 04:46 PM, Diki wrote: You're removing the iterator from the list, and then attempting to increment it, which is a no-no.

Once again, I appreciate your help Diki!

Seems to be a flaw somewhere in my game though. If I just spam bullets they go through the enemies and then after a short while, they both die. If I fire bullets with an longer interval between each, it behaves as intended. Ah well, too tired to look into it right now. Probably going to end up re-writing this at some point anyway or making a totally new game. Still have like 3 weeks before this is due. It's meant to be a "serious" game that teaches about some issue of our choice. Might be better if I came up with a new concept. I dunno, we'll see.


BBS + Chat Moderator - Feel free to send me a PM if you have a problem!
Want to instant message me? [ Skype - DeanNewgrounds ]

BBS Signature
helloNeighbour
helloNeighbour
  • Member since: Mar. 7, 2013
  • Offline.
Forum Stats
Member
Level 01
Blank Slate
Response to Programming Regs Lounge 2013-03-07 22:55:05 Reply

can anyone write a program for this question pls..

Write a program that displays a graphical seating chart for a dinner party. Create a class called Diner (as in one who dines) that stores the person's name, gender, and location at the dinner table. A diner is graphically represented as a circle, color-coded by gender, with the person's name printed in the circle.

:/

Diki
Diki
  • Member since: Jan. 31, 2004
  • Online!
Forum Stats
Moderator
Level 13
Programmer
Response to Programming Regs Lounge 2013-03-08 09:21:34 Reply

At 3/7/13 10:55 PM, helloNeighbour wrote: can anyone write a program for this question pls..

Are you asking people to do your homework for you?

Dean
Dean
  • Member since: Feb. 16, 2008
  • Offline.
Forum Stats
Moderator
Level 47
Gamer
Response to Programming Regs Lounge 2013-03-10 20:06:14 Reply

Productive afternoon using C++.

Since I was finding it hard to add a serious twist to my Space Invaders clone (the game has to have some serious aspect to it) I decided to make a new game called "Cost of War". The 'serious' aspect being to highlight the cost of war. Both financial cost and the cost of life.

Basically it's a side scrolling shoot 'em up where you play as a crudely drawn grey aircraft who's job is to shoot the green enemy aircraft and bomb the even more crudely drawn brown buildings. It records how many bullets are fired, bombs dropped, enemy aircraft destroyed, buildings blown up and then upon a game over, you're presented with the damaged you caused and the number of lives you took.

Still needs some features implemented. Currently the enemies don't fire at you and there's no collision detection for enemies flying into you. There are a few other things I'll fix or make better eventually. Wish I could do something to make the graphics nicer but the drawing functions we're provided with suck. You can basically draw lines, rectangles, circles and "closed shapes" which I've not been able to figure out how to implement. If I could work out how to use them then the wings of the aircraft would be thicker than just a standard line. Should probably do something to make the buildings look nicer too.

Also, right now it's insanely easy but I'm hoping that once I give the enemies the ability to shoot it should make things a bit trickier.

Anyway, not too bad for an afternoons work. By my standards anyway. Try not to laugh too much at the graphics :(

Programming Regs Lounge


BBS + Chat Moderator - Feel free to send me a PM if you have a problem!
Want to instant message me? [ Skype - DeanNewgrounds ]

BBS Signature
smulse
smulse
  • Member since: Mar. 24, 2005
  • Offline.
Forum Stats
Member
Level 31
Blank Slate
Response to Programming Regs Lounge 2013-03-13 09:10:18 Reply

At 3/10/13 08:06 PM, Dean wrote: Anyway, not too bad for an afternoons work. By my standards anyway. Try not to laugh too much at the graphics :(

Reminds me of one of the first games I made years and years ago while I was still in school

  • Flight Unlimited
    Flight Unlimited by smulse

    Flight Unlimited, pwn the skies.

    Score
    3.84 / 5.00
    Type
    Game
    Popularity
    3,625 Views
    Rated
    Ages 13+


BBS Signature
Dean
Dean
  • Member since: Feb. 16, 2008
  • Offline.
Forum Stats
Moderator
Level 47
Gamer
Response to Programming Regs Lounge 2013-03-13 09:50:43 Reply

At 3/13/13 09:10 AM, smulse wrote: Reminds me of one of the first games I made years and years ago while I was still in school
http://www.newgrounds.com/portal/view/290057

I suppose it'd be a lot easier to make this kind of game in with Flash but I don't really have much interest in Flash of AcionScript. Plus, this was for a C++ based course anyway. But yea, your game does play kind similar. Although in the game I've been making the aircraft are restricted to "lanes" where as in your game you're free to move anywhere on the Y-axis, which I'd like to have implemented but I was having problems with the movement controls. Like if the user held the UP key to fly up, it'd register the KEY_DOWN then wait for a short period of time and then register the next KEY_DOWNs. The delay prevented the controls from feeling smooth so I just decided to make it so that pressing up or down would take you either a lane up, or a lane down.

Anyway, my game is pretty much in a near finished state. It could obviously use a lot more polish and if I have time over the next couple weeks I'll add some stuff to it. Wanted to add an explosion effect when a bomb hits the ground or if an enemy is shot down. It'd literally just be an orange circle with a gradually increasing radius though. Like I said before, the drawing functions we have are crap. There's literally something like dot(), line(), circle(), rect(), closedShape(). The way rectangles work is like this:

void Rect(int left, int top, int right, int bot) { }

Which basically means your rectangles have to be parallel to the axis because it's not taking coordinates of the corners but instead it takes the Y value of the top side and bottom side along with the X value of the left side and right side.

When I was trying to make the graphics look a little nicer by adding some basic 3D effect, I had to make use of the closedShape() function which literally just takes a vector of coordinates and puts lines between them. The crappy thing about this is that the shapes made with closedShape() don't seem to get filled with colour, so my aircraft wings and the sides/roofs of buildings are transparent :(

Here's how it's currently looking. You can see what I mean about the wings and walls of buildings being transparent.


BBS + Chat Moderator - Feel free to send me a PM if you have a problem!
Want to instant message me? [ Skype - DeanNewgrounds ]

BBS Signature
Dean
Dean
  • Member since: Feb. 16, 2008
  • Offline.
Forum Stats
Moderator
Level 47
Gamer
Response to Programming Regs Lounge 2013-03-17 19:40:42 Reply

Back to working on my Android audio chat application after a weekend of doing nothing. Trying to implement a better method of choosing which device you want to start an audio call with because currently you're required to manually enter the IP address of the device you want to call which is impractical for a few reasons. I suppose the three most annoying reasons are: it requires user effort, IP addresses aren't all that memorable and a device isn't always assigned the same address each time it connects to the network, I don't believe.

So my current plan, which is partially implemented, is to have the user enter their name when they launch the app. Their name will be put in a UDP packet and broadcast across the network. Devices running the app will listen out for the packets, store the name from the packets and associate that name with the packet's address. This way I could just present the user with a list of all the received names, they can pick one and it'll send the audio packets to the associated IP address.

One downside to my plan right now is that I'm storing the names and addresses in a HashMap, which doesn't allow a key to be used multiple times, in this case the name. So if two devices were to be broadcasting the same name, it's going to cause some problems. Even if I was storing them in some other data structure, name conflicts are still a problem right now.

Ah well, currently I'm able to receive and store the names and addresses in the HashMap. Although it appears that one of my three Android devices (the HTC Wildfire S) doesn't like receiving broadcast packets for some reason. It'll broadcast packets itself, but it wont receive any that are sent from other devices.


BBS + Chat Moderator - Feel free to send me a PM if you have a problem!
Want to instant message me? [ Skype - DeanNewgrounds ]

BBS Signature
smulse
smulse
  • Member since: Mar. 24, 2005
  • Offline.
Forum Stats
Member
Level 31
Blank Slate
Response to Programming Regs Lounge 2013-03-18 11:48:57 Reply

At 3/17/13 07:40 PM, Dean wrote: One downside to my plan right now is that I'm storing the names and addresses in a HashMap, which doesn't allow a key to be used multiple times, in this case the name. So if two devices were to be broadcasting the same name, it's going to cause some problems. Even if I was storing them in some other data structure, name conflicts are still a problem right now.

I guess you could always do some sort of blackberry pin idea, where everyone has a unique id that they use for reference and then they can give themselves a screen name too (that doesn't have to be unique).


BBS Signature
Dean
Dean
  • Member since: Feb. 16, 2008
  • Offline.
Forum Stats
Moderator
Level 47
Gamer
Response to Programming Regs Lounge 2013-03-18 12:20:28 Reply

At 3/18/13 11:48 AM, smulse wrote: I guess you could always do some sort of blackberry pin idea, where everyone has a unique id that they use for reference and then they can give themselves a screen name too (that doesn't have to be unique).

Although I assume that's going to require some kind of central server or something to deal with the unique pin allocation and to store info on which pin belongs to which device? The original idea behind this project was that it was to be audio communication over ad-hoc WiFi, but due to Android's lack of support for ad-hoc WiFi, I've sort of abandoned that idea and given the time constraint of this project (I only have a few weeks left to work on it) I don't want to make it any more complex than I have to.

I don't want the devices interacting with a server or anything. I'd still like it in a sort of ad-hoc fashion where the devices just sort of talk amongst themselves. At present, I think I'm just going to ignore the name conflict issue and work out a fix if I have enough time. While I've already achieved audio streaming, I still need to implement some kind of call request system, where one device can request to call another and the user on the other device can choose whether or not to start the audio conversation. Once I get that sorted, my app should have the basic functionality. If I have time left over to work on it, I'll try and polish it up a little.

This is my final year university project by the way. It's a little less exciting than I thought it would be and honestly, I don't think it's a particularly impressive project. Mostly just because when I think about what I'm working on, it's a phone call system. Most non-technically minded people who don't understand what's involved in making a system like this probably wont be impressed by it at all. Hell, I'm sure there will even be technically minded people who don't think it's a particularly impressive project. If it were to be operating over ad-hoc WiFi, that'd probably be more impressive but I think it would also have required a lot more work. Still, it'll probably be the most impressive piece of software I've produced if I actually get it working.


BBS + Chat Moderator - Feel free to send me a PM if you have a problem!
Want to instant message me? [ Skype - DeanNewgrounds ]

BBS Signature
FlyingColours
FlyingColours
  • Member since: Jul. 3, 2011
  • Offline.
Forum Stats
Member
Level 06
Programmer
Response to Programming Regs Lounge 2013-03-23 21:59:01 Reply

Since HTML5 games are here, I think there should be a :main for HTML5, CSS3 and JS. I know Afro-Ninja has locked previous attempts at (X)HTML, CSS and JS mains, but you can't just go to w3schools to learn how to make HTML5 games. (I am aware that HTML5 and CSS3 are not programming languages, but how the DOM interacts with JS is a programming topic.)

I apologise if I'm not the first to suggest this...

Diki
Diki
  • Member since: Jan. 31, 2004
  • Online!
Forum Stats
Moderator
Level 13
Programmer
Response to Programming Regs Lounge 2013-03-25 15:07:02 Reply

I started a new Python project which uses non-blocking sockets. Since I'm mostly making this project for my portfolio I'm not using Twisted; under any other circumstances I absolutely wouldn't be rolling out my own framework for this.

Either way I found a handy use for function decorators specifically for handling non-blocking operations. Normally to do this you need to wrap everything you do with the sockets in a try/catch that looks for the blocking exception:

def handle_conn():
  try:
    return mysocket.accept()
  catch socket.error as err:
    if err.errno != errno.EWOULDBLOCK:
      raise Exception(err)

def handle_recv():
  try:
    return mysocket.recv(1024)
  catch socket.error as err:
    if err.errno != errno.EWOULDBLOCK:
      raise Exception(err)

As you can imagine this gets ugly pretty damn fast, and is pretty damn repetitive.
Function decorators to the rescue:

def no_block(function):
  def wrapper():
    try:
      return function()
    except socket.error as err:
      if err.errno != errno.EWOULDBLOCK:
        raise Exception(err)
  return wrapper

@no_block
def handle_conn():
  return mysocket.accept()

@no_block
def handle_recv():
  return mysocket.recv(1024)

Now isn't that much prettier?
This is why I love Python so very, very much.

mandog
mandog
  • Member since: Jul. 13, 2010
  • Offline.
Forum Stats
Member
Level 22
Musician
Response to Programming Regs Lounge 2013-03-30 13:50:49 Reply

At 3/25/13 03:07 PM, Diki wrote: Python

I wish I remembered how to code in python...

print "hello"

right?


original I am.

BBS Signature