Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 20 Aug 2009
Offline Last Active Jul 27 2016 05:42 AM

#5294621 Code vs. drag and drop in Game Maker

Posted by on 02 June 2016 - 05:04 AM

Firstly, how experienced are you with Game Maker?

The tutorials hopefully tell you what each piece of code is doing, so you can recreate it with dnd. After googling around a bit, I've found an excellent reference. Unfortunately, this converts dnd to code, not the other way around, that would be a tremendous amount of work. However, if you skim the pdf, it should be manageable.

My search query was "game maker drag and drop to gml", in case you'd like to find more.
As for functionality, most 2D games without too much logic going on can be done with dnd. Think of platformers, schmups, racing games, top-down shooters, etc. In theory, even more advanced games can be done, like RTSes, but the dnd would be too verbose for that I think. Try to stay away from complex AI and algorithms, and you should be fine.

#5278359 "check before flight" list - for OpenGL

Posted by on 26 February 2016 - 03:44 PM

-Are your matrices correctly set? ( world, view, and most importantly, projection)


Edit: Also, if I'm unsure if things are working, I usually change the clear color from frame to frame. That way I know that the window and the context is working, and the draw calls are actually happening. This can also show that buffers are swapped if necessary.

#5269179 Criticism of C++

Posted by on 04 January 2016 - 06:50 AM


"You cannot print enum values": by writing the enum with clever macros and templates you can (any particularly good example to recommend?)

Here's one.

#5268490 [GMS] Need help with overlapping sprites

Posted by on 30 December 2015 - 10:54 AM

If those sprites are two different objects, just set their depths. The lower the value, the "higher up" the sprite will be. 

#5254375 Glut & opengl only for 2D [Question]

Posted by on 28 September 2015 - 08:11 AM


To use OpenGL, you need a window to draw to. This means you'll always need some kind of window manager. Either use the OS's native one, or a cross-platform one, like SDL. The benefit of the latter is that it abstracts away a lot of platform-specific details you won't have to bother with, and a lot of work is already done for you.

If simply not using SDL or any other "library", you could do fine with using a native window handler ( WinAPI for example ). Technically that's another library, but I think that's okay, you can't really go lower-level from there.


Now, I'm not entirely sure about this one, but technically you could do "without a window" on some Linux distros when no GUI is present. Then again, you still need to request a surface, which is pretty close to using a window manager. I could be wrong on this one, and I don't advise going this route.


On the other hand, if SDL seems like an overkill, try GLFW. It handles windows and input to some limited extent. You'll have to do anything else by yourself.

#5251111 How can I save/flush the offline data to disk and start it from there next ti...

Posted by on 08 September 2015 - 12:19 AM

Yes, the quickest and dirty-ish solution would be to use a conditional branch. Something like this: 

void Grid::calculateActualCosts() {
	unsigned last_i = 0;
	unsigned last_j = 0;
		last_i = getLastI();
		last_j = getLastJ();
	unsigned i = 0;
	unsigned j = 0;
	for (auto& walkable : m_walkables) {
		j = 0;
		if(i++ < last_i)
		for (auto& walkables : m_walkables) {
			if(j++ < last_j)
			AStarNode* fromNode = acquireNode(...);
			AStarNode* toNode = acquireNode(...);
			AStarNodePair pair(fromNode, toNode);
			astar(fromNode, toNode, totalCost);
			actualCosts.insert(std::make_pair(pair, totalCost));	 

Or, you could keep an std::set<std::pair<walkable, walkable>>. If a pair of any two walkables is in the set, it has been processed already and you can just do a continue, like this: 

for (auto& walkables : m_walkables) {
	if(progressSet.count({walkable, walkables}))
	AStarNode* fromNode = acquireNode(...);
	AStarNode* toNode = acquireNode(...);
	AStarNodePair pair(fromNode, toNode);
	astar(fromNode, toNode, totalCost);
	actualCosts.insert(std::make_pair(pair, totalCost));	

        progressSet.insert({walkable, walkables});

At the beginning of the function you'd start with an empty set, and if you are continuing, read the set from a file. 


Your update2 also sounds valid, if it is practical to sort your data. 

At first, a VM sounds like an overkill, but if it's something you only run on your dev computer ( I assume so ), it is the fastest way to having a solution. 

#5250215 Code generation and entropy coder

Posted by on 01 September 2015 - 11:41 PM

Your code generation article is really interesting, although got me wondering. 

The last time I did code generation, I used PHP. The syntax is generally really easy, it is a general-purpose language, so you can do mostly whatever you want, and it is high-level and productive. Also, it is really easy to use it for generating text because you can freely mix raw text and code ( instead of long print("..."); lines ). 

The example you show ( index the template xml itself ) could also be done, although would need some preprocessing. 

So, I'm curious as to why implement template-specific languages, instead of get download a php and type away. What are the pros and cons? 

#5249778 lame question how to delete something from vector

Posted by on 30 August 2015 - 03:25 PM

Do you mean deleting by value instead of index? So, something like

std::vector<float> values = {1.41f, 3.14f, 42.0f}; //Initialize vector with some values

for(float v : values)
    std::cout << v << std::endl; 

And it would say 3.14f and 42.0f?


For that, you could just run through the vector and delete the value:

for(auto it = values.begin(); it != values.end(); it++)
    if(*it == 1.41f) { 

Or, include <algorithm> and do this:

values.erase(std::find(values.begin(), values.end(), 1.41f);

std::find returns the iterator to the first item in the range ( values.begin(), values.end() ) that compares equal to the value (1.41f) that you provide.


Please note that in the example, I use floats, so it is hard to confuse the value with an index. However, comparing floats simply with the == operator is usually not optimal. That is an entirely different topic, I advise you to look it up.

#5244610 Curved and sloped 3D tiles

Posted by on 05 August 2015 - 03:57 AM

You could even apply some kind of transformation afterwards. Look at Warcraft3's system, for example. The terrain is certainly composed of tiles ( mostly flat tiles, cliffs at certain places ). However, you can also apply height to them. Basically, you have a mesh composed of tiles, and then offset the vertices' z values by a heightmap. 

Sorry, I can't provide an image right now, but if you search a bit, you will definitely find some. 


Also, it's worth noting that you can do any sort of transformation you wish. Just provide the editor with some way to control that transform, and preview it. ( Assuming you have some kind of level editor ) 

#5236211 Default Keyboard Controls

Posted by on 22 June 2015 - 02:17 PM

G is really awkward to reach when your fingers are on WASD. I'd suggest moving it to F, or using Q and E for your frequent actions ( like reload and grenades )

#5131585 Std vector, sorting and/or filling

Posted by on 15 February 2014 - 12:32 PM

Are you sure you certainly need a vector?

If your elements are unique, you could use an std::set or std::map, which both offer sorting, you'd only have to roll your own compare-function.

#5129049 will mingw optymize ...

Posted by on 05 February 2014 - 10:20 AM

passing with & * is dirtier to read test etc
I don't see how using references would be dirtier.
struct float3 { float x,y,z; };
float3 cross(const float3& a, const float3& b)
   float3 out;
   out.x = a.y * b.z - a.z * b.y;
   out.y = a.z * b.x - a.x * b.z;
   out.z = a.x * b.y - a.y * b.x;
   return out;

This will eliminate two ( unnecessary ) copies, and the function definition also tells you that the two input parameters are read-only, so you can depend on their values staying the same after the function call. Notice how the function body didn't change at all. You'd use the function the same way you did before, too.

#5124006 I'm having doubt about my map loading method and its performance.

Posted by on 15 January 2014 - 05:13 PM

For starters, switch from text to binary :) It will be much faster, since you don't have to go through hundreds of characters, you just read a piece of data and there you are.

I remember seeing people just directly reading into the variables ( ie. foo.read(&mapWidth, sizeof(int)); ) and writing them as they are. This is certainly fast, but I'm not sure if this is good practice - issues could emerge when you copy a map from your computer to another and they happen to use different endianness. Still, I don't know how relevant this problem is, I hope somebody more experienced will answer :)

If it is of concern, you could use some fixed endianness in your files, and swap your byte order if while reading/writing if the running machine uses a different one.


In case it's of any help, I've written a simple library which does what I've described in my previous sentence. At start it checks what endianness the machine uses. Then you can create buffers, fill them with ( endian-correct ) data and flush those buffers to some file stream or whereever you wish. At reading you can load the whole file into a buffer and read from it, endianness will be handled. Although you have to tell each buffer what endianness they should use. ( i.e. if the buffer's endianness differs from the system's, it will flip the byte order ). Feel free to use it or just check the code :)

#5123194 Programming experiments/surveys (games)?

Posted by on 12 January 2014 - 09:32 PM

I'd second HTML, it has a really simple syntax, easy to learn. You can make it interactive with JavaScript. With some programming knowledge ( judging by your post, I think you have it ) it's not hard to learn its syntax. jQuery ditto.
Still, I'd like to add that to store any kind of data, at least you would need PHP*. You can get away with simply learning a few file functions ( fopen, fwrite, fread, fclose, maybe flock ) and basic syntax ( you don't declare variables just use them, and they start with $, eg. $foo=2;). To be able to run PHP, you need hosting. Lots of free hosts are available.

To show videos you'd get a free flash solution ( flowplayer? didn't do this kind of stuff in a while ), which is basically copying a few files over and pasting a piece of code. Flashing images for really short whiles can be done with JavaScript.


* - Well, technically you can indeed get away with pure HTML+JS by setting up a node.js server. But I don't think you'd want to do that as a beginner tongue.png

#5120252 Math?

Posted by on 31 December 2013 - 02:12 AM

Apart from that, a useful skill is being able to create formulas for various stuff. I use it to determine how does a light fade with distance, but the same thing can be used to determine splash damage, or you can create a formula to determine how much XP does each character level need to proceed, how much gold do you get given the monster's strength, etc. etc. If you can visualise a few formulas, it'll be fine ( power(x,n) - particularly square root and square, sin, cos, 1/x, I think you will be mostly fine with these ).


Also, linear interpolation, aka. lerp. Nothing fancy ( y=a+(b-a)*x ), but it can be incredibly useful if you know what it does. You can even play around with x and apply additional functions to it. For example, if you want to make it interpolate more smoothly, you can use (1-cos(x*pi))/2, if you want to make it interpolate "suddenly", you can use x^n. Some more complicated methods exist for interpolation, but I personally haven't used them that much.


Edit: The most basic vector math you might want to know is get a vector's length ( sqrt(v1^2 + v2^2 + ... + vn^n), where v's are the vector's coords ), direction ( see atan2 ), pitch ( atan2, but instead of atan2(y,x), you use atan2(z, veclen(x,y)), where z is up/down and y is front/back ), and do all of these backwards: to create a vector from direction, pitch and length:

//dir and pitch must be in radians ( 1 deg = pi/180 rad )
//If you are working in 2D, you might want to negate y to make y+ point downwards on the screen

To normalize a vector, you divide all of its components by it its length, and now you can easily represent a direction with it. You can for example add them up and normalize the result to get an average of the directions ( which could be more straightforward than using angles and mapping them, checking for overflows, etc. although I believe this is debatable ). Or you can check if one direction looks away from the other by taking their dot product and checking if it's negative ( when using normalized vectors, their dot product is the cosine of the angle between them ).

A lot of these tricks can be found with a proper understanding of the topics posted above.