How do I retain proper background on a character-based graphics system? - graphics

I got feeling retro and decided to write my favorite 8-bit computer game (Williams' Defender) on my first computer (Commodore PET 4032). All the code is being done in 6502 Assembly language. For those not familiar with the PET, all the graphics are character-based and to build games you move different characters around a 40 column x 25-row screen. This is very old tech - there are no sprites, no graphics layers, no ability to AND at the screen level, etc that we would be used to today.
I want the game to have multiple "laser beams" to be fired at the same time, and those laser beams might go on top of one another as they traverse the screen. Right now, as the beams move along the screen they store in memory what was underneath themselves and then replace what was underneath themselves as they move along to restore the background to its original state. The problem comes when a second laser goes on top of the first .. the first moves along and replaces the original background rather than leaving the second laser on top, then that second laser moves along and leaves artifacts of the first behind.
Is there a classic "light" algorithm or rule-set that allows multiple objects to move across one another such that the original proper things underneath are retained? I've tried different approaches (swapping backgrounds as things traverse, etc) but nothing seems to give me the correct result that I want.

It's certain an option to have each sprite keep a copy of whatever it overwrote, and have them erase themselves in the opposite order to that in which you drew them. That can't fail, but it assumes you have time for a full sprite draw and erase each frame.
You can also use a screen-sized buffer of 'is background' and 'is sprite' flags. Each time a sprite is drawn, mark its character locations as 'is sprite'. To erase all sprites iterate through the screen-sized buffer repainting the background anywhere that isn't marked 'is background'. You can keep upper and lower bounds of updated positions if iterating the whole 2000 potential slots is too great a cost.
You can also compare the differences between two such buffers to reduce flicker substantially supposing you have only one video buffer: paint the new sprites first, wherever they should go, noting them in the new buffer. Once all sprites are drawn, fill in background anywhere that the new buffer isn't marked 'is sprite' but the old is.

I would suggest:
Maintain a model of the game state that would allow you to redraw the entire screen at any time. This would include the positions and other state of all movable elements
As you update the game state between frames, accumulate a mask of all the cells that will need to be redrawn, because something in them changed or moved.
Iterate through the game elements in depth order from top to bottom, redrawing the parts of each element that are in the changed-cell mask
Remove any cell you draw from the changed-cell mask so it won't be rewritten by deeper elements.
The background will be last, and will redraw all remaining cells, leaving you with an empty mask ready for the next frame.
This procedure avoids any flicker that would be caused by undrawing anything you draw in a single frame.
Various indexing structures can be added to the changed cell mask to avoid unnecessary drawing work. What kinds of optimizations are appropriate here depend on your game. If the background is mostly static, for example, then it would be useful to add the coordinates of each changed cell to a list during the update, and then only check those cells during the background redraw. Or you could do this based on the previous positions of all movable elements... up 2 you.
If the majority of the scene changes in every frame, then you can skip the mask accumulation and just start with a full screen mask... although I think a PET might not be fast enough for such games.

Having never programmed for the Pet, I can't offer any specific advice about what you might try, but I can recommend keeping a copy of the current on-screen background in about 1k of RAM. That way, you can use that data to restore your background when removing the last "sprite" written to that tile. Unfortunately, that also requires you to keep your code and object data combined under 31k, unless you are programming this as a cartridge. Just a few thoughts, for what they're worth.

Related

Check if any body overlaps with Area2D

I am trying to check if a KinematicBody2D enters an Area2D. There is a signal for that(on_body_entered), but it only emits when the body is completely inside the area. Is there a way to constantly get if a body is just overlaping?
but it only emits when the body is completely inside the area
This is not correct. A more accurate description of the "body_entered" would be that it triggers on contact. The body could be partially or totally overlapping.
I suggest you enable "Visible Collision Shapes" from the debug menu. Perhaps your collider are not set the way you expect them to be.
We do not have a signal for when the body is completely inside.
What you can do is set up a smaller area (or a larger one depending on your need)…
The idea is to have two areas that are one larger than the other, in such way that there is a margin for just the size of the player character, then when the outer one triggers, it means the character is only overlapping the larger one, and when the inner one triggers the character is fully inside the larger one.
For example, if you have a 500 by 500 area, and your player is 100 by 100, then set an area with the size 300 by 300 centered at the larger area… When the player enters in contact with the smaller area, it will trigger the "body_entered" signal, which will also mean it is entirely inside the larger one. If you only got "body_entered" from the outer area but the inner area, then the player character is overlapping the outer area, but not fully inside it.

Godot - Game freezes when Area2D Monitoring turned on

So when my player falls off the map, I want the level to reload. I have used an area2d with a collisionshape2d to create an area that will call a function when the player collides with this area. However, when the game is run with this code included, the player will animate through a few frames then the game completely freezes before I can even move the player.
func _on_Area2D_body_entered(body):
get_tree().reload_current_scene()
If I delete this code, or set monitoring to off, and re-run the game it will not freeze.
Below is a screenshot of my level design.
Level design
Any help would be greatly appreciated :) - Is this a bug or am I doing something stupid?
When I set a breakpoint on the get_tree().reload_current_scene() line the following report shows
debugger
does this mean the player is colliding with a tile - If this is the case I don't see how as the program freezes before the player touches the ground.
As I said in the comments, this line:
get_tree().reload_current_scene()
Returns a value.
Now, you have said that 0 is "continuously outputted". In this context 0 means OK, in other words: it was able to reload the scene. The problem is the "continuously" part. It means that the scene reloads and then this code is triggered, and then it reloads again, and then this code is triggered again, and so on.
Now, apparently the Area2D is colliding with the TileMap. That makes sense. If it is a collision between the Area2D and a tile upon loading the scene, you would get the observed behavior. And the way the Area2D and TileMap are positioned in the scene supports the idea.
And about fixing it. I'll give you three solutions, either of these will work, with their drawbacks and caveats:
Don't have the Area2D positioned in a way that intersects non-passable tiles. This is easy to do by moving the Area2D further down, or by removing any tiles that overlap it.
The drawback with this approach is that it is fragile. You may forget in the future and move the Area2D or add tiles or something else that make the problem return. Also, it might not work well with your intended scenario design.
Change the collision_mask and collision_layer in such way that the tiles and the Area2D do not collide. As long as the bits from the mask do not overlap the bits from the layer of the other and viceversa, Godot will not even check for a collision between them.
The main drawback with this approach is that you have limited number of layers.
There is also the fact that it is less intuitive that simply placing things in such a way they don't collide.
To make it easier to work with, assign layers to different kinds of things… Go to your Project Settings, on the General Tab, under Layer Names, and 2D Physics, and give them names (e.g. "environment", "enemies", "enemy bullets", "player", "player bullets", "items", "others").
Then you can assign to each object on collision_layer what they are, and on collision_mask set every thing they MUST collide with. With the caveat that Godot will check both ways.
In this case you would set the collision_layer of the player character physics object (the KinematicBody2D) to "player" (or similar), and put the collision_mask of the Area2D to the same, so they collide. Have the collision_layer of the TileMap set to something else (e.g. "environment") that is not in the collision_mask of the Area2D, so the Area2D and the TileMap do not collide. And set the collision_mask of the player character to something that include the layer you set to the TileMap, so the player character also collides with it. I hope that makes sense.
And, of course, you can filter on the Area2D, with a little of code. It can be checking the class, or node group, or the name of the physics body. For example you can insert at the start of the method something like this: if body.name != "player": return. So that it exits the method before it reaches reload_current_scene unless it is the correct physics body.
The drawback with this approach is that it is still checking and registering the collision, so it has worse performance that using collision_mask and collision_layer. But it will work, and it will perform OK for a small to mid sized game.
For more complex situations, you may employ a combination of these approaches (because, as I said, there is a limited number of layers, so you need to add filtering on top of it). I have a more detailed explanation of how to setup physics objects, including the techniques mentioned here, in another answer.

Flip horizontally and vertically single frames of an animated sprite

I have 4 (0-3 animation frames) different images of a coin animation with differet states of it spinning. I would like to make it look like its spinning by adding another 2 frames (4-5) to make it look like it spins. In current situation it looks like the coin spins 180 degrees and goes back to it's original position. I would like to flip vertically ONLY the 4th and 5th frame. How can i achieve that without making new redundant pngs?
I know making 2 new pngs is not a big deal in this case, but if i had more frames, and/or bigger sprites it could make a significant difference in future projects.
I was thinking you could make the animation flip horizontally when it reaches the last fame, however that would mean you would have to omit #4 and #5 to avoid duplicates, but it still would look odd because frame #3 would skip directly back to frame #0. I tried thinking of different orders the sprite frames could be placed in to clean this up, but all my solutions either result in duplicate frames, or ugly skips. Maybe you might be able to solve what I couldn't.
Unfortunately, it seems that though Godot supports play_backwards functionality for the animation_player node, there is no such feature when it comes to animated_sprite. Too bad, because this would likely solve your problem.
For now, I think your best bet is to do what you were trying to avoid.. flip the sprite images yourself and add them as animation frames, or make a separate animation containing the flipped sprites and have them switch back and forth after their last frames, respectively. It might be a lot of work for super large projects, but without some kind of play_backwards functionality for animated sprites, I don't think it's worth breaking your back trying to find a workaround this time.
Of course, if I am wrong, I would welcome any correction from the community.
Good luck.
this is one way to accomplish the task.
Inside the ready function of godot write
#used to store frame value
var frame = 0
Inside the function that your using that runs every frame write:
frame += 1
#resets the value representing the current frame
if frame > 5:
frame = 0
if frame == 4 || frame == 5:
#this should be whatever function you use to flip the sprite vetically
flip_h = true
else:
#this should be whatever function you se to flip the sprite horizontally
flip_h = false
You probably already know this because I recognize the udemy course this screenshot is from, as I am doing it right now, and this is explained later in the course (when adding spikeman enemy). But for those who don't know it can be solved by adding an AnimationPlayer and adding new animation track that deals with animation flip_h property of AnimatedSprite. Then you have to set flip_h on those last 2 duplicated frames.
You could use the signals to detect when the animation has finished

How Might I organize vertex data in WebGL for a frame-by-frame (very specific) animated program?

I have been working on an animated graphics project with very specific requirements, and after quite a bit of searching and test coding, I have figured that I could take several approaches, but the Khronos and MDN documentation I have been reading coupled with other posts I have seen here don't answer all of my questions regarding my particular project. In the meantime, I have written short test programs (setting infrastructure for testing).
Firstly, I should describe the project:
The main object drawn to the screen is a simple quad surrounded by a black outline (LINE_LOOP or LINES will do, probably, though I have had issues with z-fighting...that will be left for another question). When the user interacts with the program, exactly one new quad is created and immediately drawn, but for a set amount of time its vertices move around until the quad moves to its final destination. (Note that translations won't do.) Random black lines are also drawn, and sometimes those lines also move around.
Once one of the quads reaches its final spot, it never moves again.
A new quad is always atop old quads (closer to the screen). That means that I need to layer the quads and lines from oldest to newest.
*this also means that it would probably be best to assign z-values to each quad and line, even if the graphics are in pixel coordinates and use an orthographic matrix. Would everyone agree with this?
Given these parameters, I have a few options with varying levels of complexity:
1> Take the object-oriented approach and just assign a buffer to each quad, and the same goes for the random lines. --creation and destruction of buffers every frame for the one shape that is moving. I truthfully think that this is a terrible idea that might only work in a higher level library that does heavy optimization underneath. This approach also doesn't take advantage of the fact that almost every quad will stay the same.
[vertices0] ... , [verticesN]
Draw x N (many draws for many small-size buffers)
2> Assign a z-value to each quad, outline, and line (as mentioned above). Allocate a huge vertex buffer and element buffer to store all permanently-in-their-final-positions quads. Resize only in the very unlikely case someone interacts for long enough. Create a second tiny buffer to store the one temporary moving quad and use bufferSubData every frame. When the quad reaches its destination, bufferSubData it into the large buffer and overwrite the small buffer upon creation of the next quad...all on the same frame. The main questions I have here are: is it possible (safe?) to use bufferSubData and draw it on the same frame? Also, would I use DYNAMIC_DRAW on both buffers even though the larger one would see fewer updates?
[permanent vertices ... | uninitialized (keep a count)]
bufferSubData -> [tempVerticesForOneQuad]
Draw 2x
3> Still create the large and small buffers, but instead of using bufferSubData every frame, create a second shader program and add an attribute for the new/moving quad that explicitly sets the vertex positions for the animation (I would pass vertex index attributes). Only draw with the small buffer when the quad is moving. For the frame when the quad reaches its destination, draw both large and small buffer, but then bufferSubData the final coordinates into the large permanent buffer to be used in the next frame.
switchToShaderProgramA();
[permanent vertices...| uninitialized (keep a count)]
switchToShaderProgramB();
[temp vertices] <- shader B accepts indices for each vertex so we can do all animation in the vertex shader
---last frame of movement arrives : bufferSubData into the permanent vertices buffer for when the the next quad is created
I get the sense that the third option might be the best, but I would like to learn whether there are some other factors that I did not consider. For example, my assumption that a program switch, additional attributes, and vertex shader manipulation would be faster than just substituting the buffer values as in 2>. The advantage of approach 3> (I think) is that I can defer the buffer substitution to a time when nothing needs to be drawn.
Still, I am still not sure of how to work with the randomly-appearing lines. I can't take the "single quad vertex buffer" approach since the number of lines cannot be predicted. Might I also allocate a large buffer for the moving lines? Those also stay after the quad is finished moving, though I don't think that I could use the vertex shader trick because there would be too many attributes to set (as opposed to the 4 for the one quad). I suppose that I could create a large "permanent line data" buffer first, but what to do during the animation is tricky because the lines move. Maybe bufferSubData() + draw on the same frame is not terrible? Or it could be. This is where I need advise.
I understand that this question might not be too specific code-wise, but I don't believe that I would be allowed to show the core of the program. All I have is the typical WebGL boilerplate ready.
I am looking forward to hearing people's thoughts on how I might proceed and whether there are any trade-offs I might have missed when considering the three options above.
Thank you in advance, and please feel free to ask any additional questions if clarification is necessary.
Honestly, for what you're describing, it doesn't sound to me like it matters which you choose. On modern hardware, drawing a few hundred quads and a few thousand lines each frame would not really tax the hardware much.
Having said that, I agree that approach 1 seems very inefficient. Approach 2 sounds perfectly fine. You can safely draw a buffer on the same frame that you uploaded the data. I don't think it matters much whether you use DYNAMIC_DRAW or STATIC_DRAW for the buffer. I tend to think of dynamic buffers as being something you're updating every frame. If you only update it every few seconds or less, then static is fine. Approach 3 is also fine. Between 2 and 3, I'd say do whichever is easier for you to understand and program.
Likewise, for the lines, I would use a separate buffer. It sounds like that one changes per frame, so I would use DYNAMIC_DRAW for that. Allocating a single large buffer for it and performing a glBufferSubData() per frame is probably a fine strategy. As always, trying it and profiling it will tell you for sure.

NES Programming - Nametables?

I'm wondering about how the NES displays its graphical muscle. I've researched stuff online and read through it, but I'm wondering about one last thing: Nametables.
Basically, from what I've read, each 8x8 block in a NES nametable points to a location in the pattern table, which holds graphic memory. In addition, the nametable also has an attribute table which sets a certain color palette for each 16x16 block. They're linked up together like this:
(assuming 16 8x8 blocks)
Nametable, with A B C D = pointers to sprite data:
ABBB
CDCC
DDDD
DDDD
Attribute table, with 1 2 3 = pointers to color palette data, with < referencing value to the left, ^ above, and ' to the left and above:
1<2<
^'^'
3<3<
^'^'
So, in the example above, the blocks would be colored as so
1A 1B 2B 2B
1C 1D 2C 2C
3D 3D 3D 3D
3D 3D 3D 3D
Now, if I have this on a fixed screen - it works great! Because the NES resolution is 256x240 pixels. Now, how do these tables get adjusted for scrolling?
Because Nametable 0 can scroll into Nametable 1, and if you keep scrolling Nametable 0 will wrap around again. That I get. But what I don't get is how to scroll the attribute table wraps around as well. From what I've read online, the 16x16 blocks it assigns attributes for will cause color distortions on the edge tiles of the screen (as seen when you scroll left to right and vice-versa in SMB3).
The concern I have is that I understand how to scroll the nametables, but how do you scroll the attribute table? For intsance, if I have a green block on the left side of the screen, moving the screen to right should in theory cause the tiles to the right to be green as well until they move more into frame, to which they'll revert to their normal colors.
~~~~EDIT:
I do want to point out that I know about the scanlines, X and Y. This thought just ran through my mind.
Let's say I'm at scanline Y of 10. That means I'm reading 10 values into my nametables, horizontally. That would mean my first column is off of the screen, as it only has pixel width of 8. However, the color attribute stays, since it has width of 16.
Assuming the color attribute for the entire column is green, would I be correct in assuming that to the user, the first 6 pixels on the left of the screen would be colored green, and the rightmost 10 on the screen should be green as well?
So, would I be correct in my assumption that according to the screen, the left?
This site I'm sure you are already very, very familiar with. I will preface this by saying I never got to program for the NES, but I am very experienced with all the Gameboy hardware that was ever released and the NES shares many, ahh quirks with the GB/DMG. I going to bet that you either need to do one of a few things:
Don't scroll the attribute table. Make sure that your levels all have similiar color blocks along the direction you are moving. I'd guess that many first generation games did this.
Go ahead and allow limited attribute scrolling - just make sure that the areas where the changes are occuring are either partially color shared or sparce enough that the change isn't going to be noticable.
Get out your old skool atari 2600 timer and time a write to register $2006 in the end of HBlank update to get the color swap you need done, wait a few tics, then revert during the HBlank return period so that the left edge of the next line isn't affected. I have a feeling this is the solution used most often, but without a really good emulator and patience, it will be a pain in the butt. It will also eat a bit into your overall CPU usage as you have to wait around in interrupts on multiple scan lines to get your effect done.
I wish I had a more concrete answer for you, but this hopefully helps a bit. Thanks goodness the GB/DMG had a slightly more advanced scrolling system. :)
Both Super Mario Bros. 3 and Kirby's Adventure display coloring artifacts on the edge of the screen when you scroll. I believe both games set the bit that blanks the left 8 pixels of the screen, so 0-8 pixels will be affected on any one frame.
If I remember correctly, Kirby's Adventure always tries to put the color-glitched columns on the side of the screen that is scrolling off to make it less noticeable. I don't think these artifacts are preventable without switching to vertical mirroring, which introduces difficulties of its own.
Disclaimer: it's been like five years since I wrote any NES code.
Each nametable has its own attribute table, so there should be no graphical artifacts when scrolling from one nametable to another. The type of color glitching you are referring to is really only an issue if your game scrolls both vertically and horizontally. You only have two nametables, so scrolling both ways requires you to cannibalize the visible screen. There are various solutions to this problem, a great summary of which can be found in this nesdev post:
http://nesdev.parodius.com/bbs/viewtopic.php?p=58509#58509
This site may be of some help.
http://www.games4nintendo.com/nes/faq.php#4
(Search for "What's up with $2005/2006?" and begin reading around that area.)
It basically looks like its impossible to get it pixel perfect, however those are going to be the bits you're probably going to need to look into.
Wish I could be more help.
Each nametable has its own attribute table. If you limit your game world to just two screens, you'll only need to write the nametables and attribute tables once. The hard part comes when you try to make worlds larger than two screens. Super Mario Bros. 1 did this by scrolling to the right, wrapping around as necessary, and rendering the level one column of blocks at a time (16 pixels) just before that column came into view. I don't know how one would code this efficiently (keep in mind you only have a millisecond of vblank time).

Resources