Yes, that's true. My desc wasn't quite right.
You need to also know which side you collide.
In case if you fall, you can't touch ceil by bottom of box. So, you should push up only if you collide with bottom.
Same regarding ceils, you should push down only if you collide by top.
Usually in games you don't see collision boxes, so you have no evidence did you stoped before, or not. But logic with pushes posted above, it's actually how popular genesis platformers works.
Even more, they use 3 points. bottom, top, and front. Instead of collision box.
Front one changes when you "flip" horizontaly. Bottom checks for falling, top checks for ceils. And you can't zip because collision cells is quite big (16 pixels for example), so if you zip into it 15 pixels, it will still push back. Same vertically.
Main example: Earthworm Jim.
If you think its physics is not enough for you, then... Alright.
I'm getting 50 FPS average now, and could get 5 or so FPS more if I didn't draw any map placeholder tiles. The ~20 times it calls gui.drawImage per frame is straining the performance. I think it won't get better if I want to draw more detailed map tiles and additionally draw other characters and split up map tiles between foreground and background elements (even more gui.drawImages).
I could render one big map image and therefore do just one gui.drawImage but I don't really want to do that (can't edit map without having to edit the image, people can cheat by looking at the .PNG before playing the game, and other drawbacks).
I wish I knew a way to do the "pre-rendering". But I don't think the Bizhawk lua implementation can do that, and I don't know how to use anything outside of lua.
Perhaps I will just not bother about performance for now and end up with a 40 FPS game, which is decent enough?
Still not sure how far I'm going to continue this project. Knowing myself, I will probably drop it halfway through but I hope not.. :P
This is fascinating.
I don't know anything about CPU architecture or computer/information security, but I found those remarkably simple to understand (or if not understand, at least get the gist of), it's pretty surprising such inherent flaws went un-detected for so long, and also a little scary.
The unfinished html5 game (that I made in 2013 or so and presented here in 2016 or so) has been unavailable on Altervista for a long time, so I decided to make it available again. It's not really anything big but I'm happy to show it again.
MUGG wrote:
There is also very early v1 available here.
I have recently attempted to make a platforming game like this in Bizhawk Lua with good results, but I lost motivation again and while the attempt was much more clean and solid, I made the same mistake: Working on too much stuff at once and trying to add too much. I'm not happy with those things I added, such as ledge climbing, sliding on slopes, etc. (not shown in the video)
So If I come back to this project, I would remove some of the features and try to simplify the code as much as possible before going on.
I think each time I attempt game programming like this, the results will get better and better. I can definitely see myself coming back to this project someday.
I'm considering to get into C++ now. I followed this page and installed CodeBlocks with C++ compiler.
I have some knowledge on Java, on Javascript/HTML5 and scripted in Lua a lot. Do you think it would be wise to get straight into trying to create a window and drawing stuff? Or should I learn some basics first? Am I being naive if I were to say I want to see some results fast?
Joined: 4/17/2010
Posts: 11486
Location: Lake Chargoggagoggmanchauggagoggchaubunagungamaugg
I'd rather suggest creating a minimal application implementing some logic with just command line. It's clean and helps to learn actual language rather than whatever fluff IDE adds to it (like when you create a "simple" app that shows a window in Visual Studio).
Here's my simple tool:
https://github.com/vadosnaprimer/avifps/blob/master/avifps.cpp
And it can get even simpler:
Download div.cpp
Language: cpp
// usage: div <arg1>/<arg2>
#include <stdio>
#include <stdlib>
#include <string>
int main(int argc, const char *const *const argv)
{
if (argc == 2)
{
const char *p = strchr(argv[1], '/');
if (p)
{
int num = atoi(argv[1]), denom = atoi(p+1);
if (denom)
{
printf("%f\n", (double)num/(double)denom);
}
}
}
return(0);
}
MUGG wrote:
Am I being naive if I were to say I want to see some results fast?
If you want to be going fast, C++ is not your choice at all. Use C#. It's way closer to Java mindset.
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Those header files should be either <cstdio> and <cstdlib>, or <stdio.h> and <stdlib.h> (the former is recommended in C++). I'm surprised that even compiles. Could be a non-standard behavior from the compiler, if it indeed does.
int main(int argc, const char *const *const argv)
Technically speaking the standard defines only two signatures for main():
int main()
or
int main(int argc, char** argv)
The main() function (both in C and C++) is a bit special in that, rather unusually, it doesn't really matter what kind of parameters you declare it to take. It will still usually compile (and possibly misbehave if you specify the wrong type of parameters and try to read them), and technically speaking const char*const*const will work. It's just that the standard doesn't define it as one of the valid signatures.
(It's actually not wrong to change argv, either the variable itself, or what it points to. So it's not like it's horribly wrong to not make it const. I suppose you can make an argument that it's still a good idea to do so.)
Whether those names are available in the global namespace depends on whether you included <cstdio> and <cstdlib>, or <stdio.h> and <stdlib.h>. While it might feel convenient at first to do the latter and avoid the std:: prefix, a very good argument can be made to use the former, and use the prefix:
Joined: 2/28/2006
Posts: 2275
Location: Milky Way -> Earth -> Brazil
yeah, C# also opens the possibility of using the mono runtime and potentially making your executable cross-platform, like java
"Genuine self-esteem, however, consists not of causeless feelings, but of certain knowledge about yourself.
It rests on the conviction that you — by your choices, effort and actions — have made yourself into the
kind of person able to deal with reality. It is the conviction — based on the evidence of your own volitional
functioning — that you are fundamentally able to succeed in life and, therefore, are deserving of that success."
- Onkar Ghate
Bisqwit wrote:
Still trying with C++, I've been trying to copy-paste various "simple game example codes" into CodeBlocks (the program I'm using), but it keeps showing various errors when compiling. Stuff is not declared or there is no reference etc. it says.
I'd like to show a window and draw graphics in it.
Joined: 3/2/2010
Posts: 2178
Location: A little to the left of nowhere (Sweden)
It's not trivial showing a window with graphics with C++. Follow feos advice and start small.
Inclusion in C/C++ works entirely different from what you are most likely used to from Java and Javascript.
Unlike the previous languages you have been exploring, C/C++ does not perform memory management for you, so you are going to encounter many new concepts, but once you understand them, they are not that difficult to handle.
So, start small, really small, like "Hello World" in various forms. This will allow you to ease into the concepts and how inclusions work. Once you have the basics, you're free to try again with a small game.
EDIT: mugg, feel free to ping me on IRC if you want more hands on help. If I am at the computer, I will respond.
Unlike the previous languages you have been exploring, C/C++ does not perform memory management for you
Well, yes and no. If you use standard containers like std::vector and std::map, they are going to manage their memory without you having to do anything about it. You can also create similar classes yourself (although this requires a bit advanced knowledge of the language.)
In general, if you can avoid new and delete you ought to be mostly fine in terms of memory management. The main problem becomes things like accessing arrays out of bounds and other such errors.
Joined: 3/2/2010
Posts: 2178
Location: A little to the left of nowhere (Sweden)
Warp wrote:
Warepire wrote:
Unlike the previous languages you have been exploring, C/C++ does not perform memory management for you
Well, yes and no. If you use standard containers like std::vector and std::map, they are going to manage their memory without you having to do anything about it. You can also create similar classes yourself (although this requires a bit advanced knowledge of the language.)
In general, if you can avoid new and delete you ought to be mostly fine in terms of memory management. The main problem becomes things like accessing arrays out of bounds and other such errors.
In many/most cases you would instantiate such point and rectangle objects by value, rather than with new. (In fact, creating them by value is more efficient.) If you needed to store lots of eg. point objects, you usually would use eg. a std::vector to do so, instead of allocating every individual object dynamically (once again also gaining a performance benefit as a positive side effect).
Suppose you were, for example, to handle an image, and every pixel is an object. Rather than allocate width*height individual pixel objects (which would be horrendously inefficient), you instead create a std::vector of width*height objects (very efficient).
Of course there are situations where you just can't get around it, and you simply have to allocate individual objects dynamically with new. In that case you do need to decide on how to manage those objects, because the language will indeed not automatically do it for you. But the language standard library does offer a few tools that could possibly be used, such as std::unique_ptr or std::shared_ptr which, if feasible to use in your use case, can remove the burden of manual memory management.
If those simply cannot be used, or would be too much overhead, or for some other reason, then yes, you would need to manage it yourself. In most cases you could write your own class that does the memory managing, but writing such a class does require experience, knowledge and a bit of work.
Joined: 3/2/2010
Posts: 2178
Location: A little to the left of nowhere (Sweden)
You need to be aware of how it works internally anyway, otherwise you'll be really surprised later on, and possibly really confused.
That the standard library and language itself has a lot of tools that help you manage memory in many ways is great, but it does not relieve you of being aware of how the language works.
I think going for C/C++ was a bit overwhelming after all.
I tried to find ways to make Lua work, and I found Love2d.
It allows for lots of things that Bizhawk couldn't do (like image manipulation and sound) and allows to convert the program into an executable later.
I'm in the process of porting my Bizhawk script to it. It has been difficult but I'm getting results:
Unfortunately I had to throw some things out for now (fading, 3-sec countdown, input config). My code is a mess and I want to simplify it a lot before I add to it anything new.
Love2d uses 3 functions
love.load() which is called once at the start, used for declaring everything
love.update(), called once per frame, used for logic etc.
love.draw(), called once per frame, used for drawing stuff
My script was structured in such a way that logic and drawing was mixed (this is an example):
Language: Lua
game = { -- game[mode]
[0]= function()
-- stuff
end
[1]= function()
-- other stuff
end
[2]=function()
-- the actual game
playerMove()
wallCollision()
drawMap()
drawPlayer()
[3]=function()
-- ...
So I had to split game into two: game and draw.
I call game[mode]() in love.update()
and draw[mode]() in love.draw()
I'm not happy with this structure, but because of the complication of this 3 function system, it's the only way to make it work. Maybe I will find a better way soon.
I'm also a bit worried about the thing I read in one tutorial, about delta times.
Ideally the game runs at the same constant FPS for everyone and I can do logic based on frames. But in practice, it seems you need to account for FPS differences and include delta time in most calculations. Maybe I will not worry about it for now...
Ideally the game runs at the same constant FPS for everyone and I can do logic based on frames. But in practice, it seems you need to account for FPS differences and include delta time in most calculations. Maybe I will not worry about it for now...
It depends on how exactly you are doing the timing of your code.
If the framework/game engine you are using is calling your update function eg. 60 times per second, always, regardless of hardware, and your game is light enough, you could bypass checking for passed time and always assume your game runs at exactly that speed. If the game is light enough, it will probably run at that speed even on a potato, and even if some lag frames are introduced (eg. something else on the OS becomes suddenly so heavy that it causes your game to lag), you'll just get an individual stutter or two.
The problem is that most game frameworks/engines won't call your update function at a given interval, but rather at the screen's refresh rate (because if they don't, you'll get tearing), and this refresh rate may be different for different computers. Heck, someone might be running your game on a 144Hz display, and there's no way the game engine can scale that evenly to 60Hz. Either your update function will now be called 144 times per second, making your game run over twice as fast (if you don't account for the time difference between updates), or there will be some odd constant stuttering if the engine really tries to call it at exactly 60Hz but also vsync at the same time.
Of course in case your game does become too heavy to run on a potato PC, and the framerate drops to eg. 30Hz, your game will start running at half the speed.
I don't know if the library you are using offers timing functionality that automatically provides you with the time delta since the last frame, but most game engines do, and it should be used. (If the library you are using doesn't, then you have to figure it out somehow.)
But, I suppose, for a simple small project, you could just as well ignore it for now.
@Warp
I guess I shouldn't worry.
Because the FPS in love2d for me is 450 FPS unrestricted.
I'm using the "more sophisticated way to cap at 30 fps" shown on this page, only difference is that I cap at 60 fps.
So my only concern actually is with what happens when it becomes lower than 60 fps consistently.
"Genuine self-esteem, however, consists not of causeless feelings, but of certain knowledge about yourself.
It rests on the conviction that you — by your choices, effort and actions — have made yourself into the
kind of person able to deal with reality. It is the conviction — based on the evidence of your own volitional
functioning — that you are fundamentally able to succeed in life and, therefore, are deserving of that success."
- Onkar Ghate
Bisqwit wrote:
@pirate_sephiroth, thanks.
In Lua, is it possible to split a hexadecimal number in two? (without string conversion, preferably)
0x1234 -> 0x12 and 0x34
0x123456 -> 0x1234 and 0x56
Joined: 3/2/2010
Posts: 2178
Location: A little to the left of nowhere (Sweden)
For splitting hexadecimal values in Lua, you need to apply some bit math, such as this library: http://bitop.luajit.org/
(Which is already part of BizHawk, so you may have used it already).
Decimal, hexadecimal, binary, the values are all the same internally, so if you know the conversion operations you can split them with bit math. Here's a good introduction if you need it: https://playground.arduino.cc/Code/BitMath
(C++ oriented, but it should be very easy adapt it to the above suggested Lua library)
The variant of bit math you're looking for in this case is called "bit masking".
However, these bitwise operation were only introduced to Lua in version 5.3.
It's useful to know that this can also be done by using division and splitting up the integer part (integer division) and the remainder part (modulo operation):
Think how dividing 5678 by 100 will give you 56.78 - the integer part 56 and remainder part 78.
This is the same in base 16: 0x1234 dividing by 0x100 will give you an integer part 0x12 and a remainder part 0x34.
Getting the integer part is done by using math.floor and the remainder part uses %:
I'm having fun with my project and making slow progress.
But I'm running into a lot of bugs, some of which are beyond my power to fix, and my code is very messy.
So maybe I will start over and try to implement things differently and in a more clean way. Perhaps I will even try something entirely different from the grid-based system I was using.