Win32 and SFML noodling

I ran into a problem that I thought would be best solved by combining a prior UI framework and SFML. There are a zillion reasons you’d want to do this – if you need any kind of UI element (button, menu, text entry, etc) with an SFML project you quickly run into this crossroad.

GTK+, the only UI framework I’m familiar with, has a C API with its own wacky OOP implementation. There is a C++ binding called GTKMM, but some of the tutorials and code samples I’ve seen are bit off-putting.

I researched Qt and didn’t find a lot of hope there. Any framework that seems to insist on using its own development environment sounds like a bad time. There are Visual Studio plugins, but I didn’t see any clear indication that they would work with Visual Studio Express 2013.

Visual Studio Express 2013 obviously has Win32 support and project wizards built in, so what about that?

win32SFML

This seems to work. I referenced the Win32 sample on the SFML creator’s Github repository, as well as this outdated tutorial on the SFML site itself.

A few years back I ran through a few Win32 tutorials in order to understand some demo code at work, but the stuff that gets generated with VSE2013 looks nothing like it. I’m going to have to do a lot of research if I want to keep going forward with this.

There are lots of big questions, like how do I intercept SFML events? Does the Win32-generated window get them first, and I have to intercept/interpret those and then pass them to SFML? What about timing loops (a big deal in some of the game programming I’ve been doing)? Why does the window go white when I resize it?

Posted in Programming | 1 Comment

Initializing a C++ class with a reference to another class

I’ve been working on a small game that has a Player class and a Render class. The Render class needs to know about the Player class so that it can draw the player in the right spot. My first pass at this had a method in the Render class called UpdatePlayerLocation where I passed it the Player’s location.

This seemed a bit inefficient. I figured it would be better if my Render class was initialized with a reference to my (existing) Player class, so that any time the Player location was updated my Render class would already know about it.

All of my attempts to get this to work resulted in a compiler error, or the Render class only creating a local copy of the Player class, meaning my updates to the Player outside of Render were ignored by Render.

I decided to create a small program to test my methods and figured it out. It’s extremely troubling how I got it to work. Let me demonstrate the wrong way (only a local copy created), the error way, and the right way.

The general idea is that I have a class called SomeNumber that is initialized with a number, and has methods for getting and setting this number after initialization. I have another class called NumberPrinter that is initialized with knowledge of an instance of the SomeNumber class. NumberPrinter prints the number stored in the instance of SomeNumber class that it’s passed. The program(s) below show the definitions of the SomeNumber and NumberPrinter classes, and the main() function initializes the classes, lets them print their number values, changes the SomeNumber number, and prints again. Ideally the number change in SomeNumber will propagate to NumberPrinter (propagate is the wrong word since it’s just a reference, but you know what I mean).

The Wrong Way

#include "stdafx.h"

class SomeNumber
{
public:
	SomeNumber(){};
	SomeNumber(int number)
	{
		mNumber = number;
	}

	void SetNumber(int number)
	{
		mNumber = number;
	}

	int GetNumber()
	{
		return mNumber;
	}
	void PrintNumber()
	{
		printf("In SomeNumber: %i\n", mNumber);
	}

private:
	int mNumber;
};

class NumberPrinter
{
public:
	NumberPrinter(SomeNumber& somenumber)
	{
		mSomeNumber = somenumber;
	}

	void PrintNumber()
	{
		printf("In NumberPrinter: %i\n", mSomeNumber.GetNumber());
	}

private:
	SomeNumber mSomeNumber;
};

int _tmain(int argc, _TCHAR* argv[])
{
	SomeNumber somenumber(42);
	NumberPrinter numberprinter(somenumber);

	somenumber.PrintNumber();
	numberprinter.PrintNumber();

	printf("\nSetting SomeNumber to 27\n\n");
	somenumber.SetNumber(27);

	somenumber.PrintNumber();
	numberprinter.PrintNumber();

	getchar();
	return 0;
}

This was the wrong way. The output is:

wrongway

The second printout of SomeNumber and NumberPrinter doesn’t match. This is because the class definition of NumberPrinter is wrong. It looks like it’s being initialized with a reference to a SomeNumber class instance, but it seems that setting a local (non-reference type) instance of SomeNumber to this passed reference only creates a class-local copy. mSomeNumber becomes a brand new instance (copy?), and isn’t affected by anything done outside of NumberPrinter. This seems obvious in hindsight.

So I figured that I should simply not declare my private mSomeNumber variable to be a SomeNumber class, but a reference to a SomeNumber class. This leads me to the error way.

The Error Way

I won’t copy/paste the entire program. Only the NumberPrinter class changed.

class NumberPrinter
{
public:
	NumberPrinter(SomeNumber& somenumber)
	{
		mSomeNumber = somenumber;
	}

	void PrintNumber()
	{
		printf("In NumberPrinter: %i\n", mSomeNumber.GetNumber());
	}

private:
	SomeNumber& mSomeNumber;
};

This results in a compiler error. “a member of reference type must be initialized”. I Googled the error, then refined my search to be more about how to pass a class a class reference in the constructor and came across this StackOverflow post: http://stackoverflow.com/questions/11117347/passing-references-to-a-c-constructor-and-saving-them-to-reference-or-non-refe

The guy in the post wasn’t getting the same error (he was asking a different question entirely) but I noticed his code worked and he was doing pretty much the same thing I was doing. The only difference was how he was doing the initializing. This leads me to the right way.

The Right Way

class NumberPrinter
{
public:
	NumberPrinter(SomeNumber& somenumber)
		:mSomeNumber(somenumber)
	{

	}

	void PrintNumber()
	{
		printf("In NumberPrinter: %i\n", mSomeNumber.GetNumber());
	}

private:
	SomeNumber& mSomeNumber;
};

Instead of putting mSomeNumber = somenumber in the constructor function body, I used the other way if initializing class variables with :mSomeNumber(somenumber). Here’s the results:

therightway

 

Yes, this is what I wanted!

I sincerely thought that initializing class variables like that was a style choice, but it seems to be a rule for some cases.

I’m pretty new to C++, and stuff like this eats up entire evenings. Thankfully I live in a time when StackOverflow exists. I’d have been super stuck not realizing that the word “initialized” can have different contextual meanings! I think that the colon marks the start of an “initializer list”.

I read a few more posts on the subject. I can kind of see why this is. You don’t want to pass a reference that could potentially get freed outside of the class it’s passed to. I wonder if there is a graceful “smart pointer” way of handling it, or maybe I could just use raw pointers. More experimenting is needed. Here is another SO post that I found interesting: http://stackoverflow.com/questions/17992121/must-a-reference-type-be-initialized-in-constructor-initialization-list

 

 

Posted in Programming | 1 Comment

Rotation!

I was so surprised that this worked that I actually jumped out of my chair. When I hold down the “A” key the line rotates counter-clockwise around the blue circle (like a clock hand).

rotation

I spent ages working this out on graph paper. I’ve been working on the next iteration of Chocolate Quest. It’s going to be a top-down game controlled by the arrow keys. I’ve been trying to implement as much of the movement code on my own, instead of using SFML functions. Rotation is weird, and I didn’t feel right implementing it before I really understood it. I think I have it all worked out, but it’s going to take time to clean up my notes and make a coherent post out of it.

Next is making the little circle move in the direction the line is pointing. After I know I understand how to do movement, I’ll feel comfortable using the built-in SFML functions. It would feel like cheating otherwise.

Posted in Programming | Leave a comment

Moving Around

I was thinking about Command & Conquer this morning, and realized that there’s a very simple feature in that game that I couldn’t work out in my head how to do myself: click on a location on the screen and have an object move towards that location.

There are lots of wrong ways to do this. I started trying to work out on paper how to move a coordinate along a diagonal line, but really that’s the wrong way to think about it. You’re have to add a value to the X and Y coordinate of your object such that it steadily goes towards the new location.

If you take the X and Y distances between the object and the new location, divide those distances by some constant (which is what we’ll just call the “speed” in this example), you have a value to increment X and Y by bit by bit until it reaches the destination (or close enough to the destination).

Completely on accident I implemented this idea such that the object slows down as it approaches the target – this is because I re-calculate the distance after every move of my object. The X and Y distances gets smaller, but the “speed” I divide by stays the same, so the incremental value I add to the X and Y position gets smaller and smaller (so it appears to be approaching slower and slower).

Anyways, here’s a small example using SFML to do the drawing.

#include <SFML/Graphics.hpp>

int main()
{
	sf::RenderWindow window(sf::VideoMode(640, 480), "Click to move");

	//Variables to store the position of the chaser, the
	//target, and the mouse click
	sf::Vector2i clickPosition;
	sf::Vector2f targetPosition;
	sf::Vector2f chaserPosition;

	//variables to store distances between the
	//chaser and target
	float distanceX;
	float distanceY;
	float distance;

	//Speed of the chaser
	float chaserSpeed = 2000;

	//tracking is 1 when I click the mouse, and
	//0 when the chaser hits the target.
	bool tracking = 0;

	//target circle size, color, and initial
	//position
	sf::CircleShape targetCircle;
	targetCircle.setFillColor(sf::Color::Red);
	targetCircle.setRadius(10.f);
	targetCircle.setPosition(0.f, 0.f);

	//chaser circle size, color, and initial
	//position
	sf::CircleShape chaserCircle;
	chaserCircle.setFillColor(sf::Color::Blue);
	chaserCircle.setRadius(10.f);
	chaserCircle.setPosition(100.f, 100.f);

	while (window.isOpen())
	{
		sf::Event event;
		while (window.pollEvent(event))
		{
			if (event.type == sf::Event::Closed)
				window.close();

			if (event.type == sf::Event::MouseButtonPressed)
			{
				//If the mouse is clicked, get the position
				clickPosition = sf::Mouse::getPosition(window);

				//Set the target circle to that mouse click position
				targetCircle.setPosition((float)clickPosition.x, (float)clickPosition.y);

				//set tracking to 1 to enable tracking
				tracking = 1;

				//print useful debug info
				printf("Tracking...\n");

				//print useful debug info
				printf("click X: %i, click Y: %i\n", clickPosition.x, clickPosition.y);

			}
		}

		if (tracking)
		{
			//We'll need the target and chaser positions
			targetPosition = targetCircle.getPosition();
			chaserPosition = chaserCircle.getPosition();

			//get the X and Y distance between the chaser
			//and target
			distanceX = targetPosition.x - chaserPosition.x;
			distanceY = targetPosition.y - chaserPosition.y;

			//calculate the distance between the chaser
			//and target
			distance = sqrt(distanceX * distanceX + distanceY * distanceY);

			//update the position of the chaser by adding incremental
			//values to its current X and Y position.
			chaserCircle.setPosition(chaserPosition.x + (distanceX / chaserSpeed), chaserPosition.y + (distanceY / chaserSpeed));

			//if the distance is close, stop tracking
			if (distance < 10)
			{
				tracking = 0;
				printf("End tracking, distance %f\n", distance);
			}

		}

		window.clear();
		window.draw(chaserCircle);
		window.draw(targetCircle);
		window.display();
	}

	return 0;
}

Neat, huh? I found this site that has some examples of all kinds of movement, but it’s in Javascript: http://www.somethinghitme.com/2013/11/13/snippets-i-always-forget-movement/

I’m itching to make another small game so that I can put some of the ideas in this fantastic SFML game development book, SFML Game Development, into use. The only thing holding me back right now is solidifying my understanding of some of the more advanced C++ the book uses (templates, woof).

Posted in Programming | Leave a comment

Windows 8 beat my Mac

I encountered a very interesting usability issue this evening. A coworkers son completed a school video project in Premier on his Mac, but had to turn in the video in .wmv format. Premier doesn’t appear to be able to do this. That’s interesting (and I have my doubts) but I don’t have Premier to try it myself.

I felt confident I could take his .mov and use some program to convert it on my end. So problem #1 was how to get a 300 MB file to me that didn’t involve driving for an hour. Dropbox? No, he doesn’t use it. Google Drive? Same problem.

I was faced with walking him through setting up a Dropbox account (which is a bit invasive if you choose to use the client) or a Google account (to use a Google service I don’t have any experience with myself).

Ok, what about good old FTP? Well, he hadn’t done that before, but I was optimistic that OS X had some built-in FTP capabilities. It does (hit Command-K in a Finder window) but you can’t upload like that – only browse and download! Woof, big OS X fail there. Furthermore, the FTP server I was trying to use (the one at my day job) was not having a good time.

Fortunately I had installed and configured VSFTPD on my Digital Ocean server a while back, so I started that up and made him an account. I had him download FileZilla, which was fairly painless except for some very scammy click-bait ads on the SourceForge site. No, SourceForge, nobody wants to use your download manager. Ever.

Alight, so he’s all set uploading that file and I have 30 minutes until it’s done to find a conversion solution.

I’ve thrown out the possibility of using any of the scammy looking free converters. What about VLC? Well, it looked like it could do it, but the closest I could pull off was a .asf file. What about iMovie? Nope, no .wmv export option that I can see (which was a bit optimistic of me). I do have a very old copy of Sony Vegas on a Windows 7 boot drive in my closet, but it’s so old that I don’t think it supported wide aspect ratios (and I recall exporting to .wmv producing insanely large files unless you spent a long time noodling with the settings).

So I did the usual pace around and stare off into space muttering to myself thing that typically produces results (and gets me worried glances from coworkers) and thought of something.

I installed Windows 8 a few months ago, just to see what all the fuss is about. I remembered that the ads had some kind of video making program, so I did a Bing search (I’m playing ball today Microsoft) and managed to install the Windows 8 Movie Maker.

The Windows 8 Movie Maker opened the .mov, and saved right out to .wmv. No fussing, no noodling with settings, no nothing but good results.

Windows 8 beat my Mac in built-in functionality. How about that.

 

Posted in Uncategorized | Leave a comment

Project Euler 14 Complete

Project Euler Problem 14 was quick to bang out: https://github.com/cheydrick/Project-Euler/blob/master/ProjectEuler14.c

Problem 15 is intimidating.

Posted in Programming | Leave a comment

Project Euler 13 Complete

I finished up my solution to Project Euler 13https://github.com/cheydrick/Project-Euler

This one was easy to work out on paper, but irritating to implement. It’s pretty brute force, and I read a few solutions in the problem’s forum (which you get access to after you solve the problem) that are much more elegant.

It would have been faster to start from scratch. My half-done program from 2012 had two subtle problems that I (hopefully!) wouldn’t have re-created. The first was screwing up how to index an array, and the second was that I mistakenly thought it was 50 numbers instead of 100.

On to #14!

Posted in Programming | Leave a comment

Books in 2014

I’m going to try to keep track of the books I read in 2014.

So far in the first 16 days of 2014 I’ve read The Twelve by Justin Cronin, and Island in the Sea of Time by S.M. Stirling.

The Twelve is the sequel to The Passage. Both were fairly enjoyable post-apocalyptic reads. I’m looking forward to the third book that should come out this year.

Island in the Sea of Time is an alternative history novel that has a few sequels and I think several other books were written in the same universe. I might pick up the sequel if I stumble across it, but I’m hesitant to get sucked into reading a large collection from one author (again).

Posted in Uncategorized | Leave a comment

Project Euler 12 complete

With the exception of one cosmetic change, I didn’t make any progress in the Project Euler problem set at all in 2013.

I solved Problem 12 a while ago, but never brought it into the project as a whole, so this morning I did just that: https://github.com/cheydrick/Project-Euler

I’m about half-way through solving Problem 13 (and I think I can quickly do Problem 14).

Posted in Programming | Leave a comment

VGA Mandelbrot Set

I read Masters of Doom a few weeks ago, and it inspired me to do some old-school DOS VGA graphics programming.

VGAMandelbrot

https://github.com/cheydrick/VGA-Mandelbrot

When I was a kid I played around with some sample programs that came with DJGPP or Borland C or Turbo Pascal that did various interesting things with VGA graphics, but beyond modifying the routines slightly to see the effects I never truly understood what exactly was happening.

There’s a fantastic VGA programming tutorial here: http://www.brackeen.com/vga/. Big thanks to David Brackeen for writing that.

I managed to get Borland C installed in DOSBox using this tutorial: http://borlandc.org/how-to-install-borland-c-on-windows-8-avoiding-application-cant-run-on-your-pc-contact-with-your-software-publisher/

Unfortunately there are not a lot of good DOS programming resources that are easily searchable. I’d really like to figure out how to read keypresses. David’s tutorial covers registering mouse activity, but I can’t find anything for the keyboard.

Posted in Programming | Leave a comment