Hi guys!
So, I'm trying to get my head around doing a Dig Dug type game. I decided to try with drawing rectangles. I've got something that looks promising but doesn't behave very well.
--local tunnelHalfHeight = PLAYER.tunnel:getHeight()/2
local tunnelY = PLAYER.tunnel:getY()
--local playerHalfHeight = PLAYER:getHeight()/2
local playerY = PLAYER:getY()
local distance = playerY - tunnelY
print("Tunnel distance is: "..distance)
if distance > 1 then
--PLAYER.tunnel:setY(PLAYER:getY())
PLAYER.tunnel:setSize(PLAYER.tunnel:getWidth(), distance)
end |
The rectangle expands but the Y stays static. If I uncomment setY(), it never resizes as it moves with the player. (I'm using
http://giderosmobile.com/forum/discussion/100/any-chance-of-a-setwidth-and-setheight-for-bitmaps/p1)
I thought of just creating a new rectangle with every +1 playerY but that sounds like it could turn into a performance nightmare.
Perhaps this is entirely the wrong approach though and I would be better off drawing straight onto canvas somehow. Assuming I can then limit monster movement to stay inside what is drawn, i.e. the tunnels (I was originally going to do rectangle collision checks)...
I'm guessing the way they used to do it was to calculate every line with every frame (or something?).
Comments
Likes: Astirian
But seriously, I saw the example here: http://docs.giderosmobile.com/reference/gideros/RenderTarget
Which is great, looks like we can basically manipulate render targets directly (had to Google render targets ))
I guess I would add a transparent texture over diggable ground as a mask (this would be my target), then apply color transforms to certain areas of this mask depending on player direction, let's say make them black. Then I suppose I use getPixel like: if the color data is black I know it's a tunnel?
Likes: Astirian
But I'm struggling a little bit with renderTarget (I'm still a baby programmer )).
I can't get a hold of the individual pixels in my buffer and I hope I don't have to write a shader because that's still way too advanced for me.
Basically, I'm trying something like this on my RT (background):
But maybe there's an easier way to paint on a render target..
I haven;t played with RenderTarget and its methods of getting pixels. I think that needs better documentation (ie; there is no documentation to my knowledge).
In theory you could use a Rendertarget and at the start of the level fill it with a color (0xffffff for this example). Whenever the player moves further in the map just clear the immediate area of the RenderTarget (clear(x, y, w, h) and then for collision you can check if the pixels in the direction of travel are not 0xffffff. If they are not then you should be able to move in that direction.
I think I need to find a Dig Dug emulator and play it to see how the controls actually work.
To modify the rendertarget's pixels, just draw some sprite on it. There is no setPixel() method. For getPixels(), you were nearly there: the object returned is a string containing the R,G,B and A components of all pixels of the selected region (left to right, top to bottom), each char of the string being a component. I hope this make sense...
You could still maintain the "digging" feel with a grid, you would just use more grids, so one grid for the actual collision data and another for storing the digging information.
Does that make sense?
So I guess I'm drawing the shape onto the render target each frame, seems to work, dunno if I'll have to add a line to remove the shape for performance. Actually, I know! I'll just create the shape outside onEnterFrame and just update the coordinates on onEnterFrame.
As for the grid system I'm sure that would work as well, it never occurred to me to just use pixel sized grids! I had 32x32 stuck in my head for some reason.
Collisions are up next.
8-X
One of the cool things about Dig Dug is that there are thin walls between rows and columns which not many other games have. Usually those other games have walls that are one tile wide and high.
I got to thinking that you could just use a grid of cells and each cell would store connectivity data to specify if any direction (Left, Right, Up, Down ) was blocked or open. So a cell in the grid would be like so..
Just a side note that this type of grid is commonly used to generate mazes
So I made a little example to show how it all works. Sorry it's a bit messy and there are a bunch of hardcoded things in there but you should be able to decipher it without too much problem.
You will see in the example that the walls of the tunnels are very thin (like Dig Dug) and the simple collision checking implemented makes the agent only able to move in the tunnels.
On a side note, would adding enemies and doing collisions against them be object based? At the moment I'd probably do something like add each enemy on creation to an enemies array then iterate through the array in onEnterFrame to check for collisions using bump.lua, dunno if that's silly or not.
I'm gonna have a fun time with AI and pathing too, I can tell. :P Great fun though. Especially when it all comes together on the screen!
Likes: antix
With a cell based system like the one in my example I would probably also run a 2d grid array alongside it. This grid would be used for path finding using one of the many a* libraries out there. Dig Dug does also have the whole "ghosty drifting" thing but that shouldn't be too hard to get working.
Sometimes it's easier to look in the direction of the move for a map cell that is empty or not - then set it as being occupied and move in that direction (over x frames), at the same time as setting the current cell to empty.
https://deluxepixel.com
Bump.lua is working well so far, I've added rocks and it all seems to work (well, anchor points seem to need some tweaking, hopefully that doesn't bite me in the bum later!)
So I'm working on procedural generation of elements when the level loads up. The idea is that I'll move the rock if it collides against an enemy, only problem is, I'm stuck in an infinite loop (unless I remove that last IF on the collisionsResolved boolean):
Note that also even though it might not get caught forever.. it might get caught up for many seconds.
Likes: Astirian
So I made this little example which populates the game world with game objects using a grid system. There is more code and maybe it is a bit messier but it will always work and never get caught in any strange loops.
Looking at the screen dump you can see the world is divided up into 4 quadrants and each quadrant is inhabited by 4 enemies and 2 rocks.
This example can be used for any game where you have quadrants that need objects inserted into them without those objects overlapping any other objects in the quadrant.
Just ask if you have any questions about it
Likes: Astirian
1 Upper left quadrant
2 Upper right quadrant
3 Lower left quadrant
4 Lower right quadrant
Create a plane with each quadrant having these dimensions.
Likes: pie, Astirian
You are a gentleman and a scholar! Thank you very much.
Likes: antix
Another idea I had for a bump based solution would be to just move objects slowly away from each other until they didn't collide. This would work pretty well and the only case where you would need to choose a new random location would be when one of the moving objects overlapped with two or more other objects.
I do feel however that the grid based system is far superior. I have been thinking about how to make the class better too so you could have sectors (name change of quad) and you could have a 3x3 matrix, or whatever sized matrix you liked, as opposed to the 2x2 matrix it currently has. This would be beneficial in games with big maps I think.
Likes: Astirian
I'm sure it'd be great for stuff like; "this sector is water" etc... Then you could just move the world/stage around when the player got close to the sides of the screen to mimic a camera moving with the player I guess.
Of course I wouldn't be surprised if there was already a Lua library for this as platformers are so ubiquitous. I had read briefly about the Tiled editor a while back and was going to circle around back to it.
For zones I found it was quite easy to just use the characters midpoint for that. in your tilemap you can decide which blocks are which types of zone for example blocks 1 might be water and 2 might be lava, etc. I used an extra layer in my tiled map to edit them.
Check which tile in the map the player is on. If it's in the water zone and the player is not set to be in water then set them in water, and do enterNewZone effects. If it's no zone (0 - 109) and they are not in no zone then set them in no zone and do exitLastZone effects.
I chose this method because in a platformer you are always checking the players midpoint so it was natural to use it for zone entry/exit as well.
Likes: Astirian
I tried replacing drawing brushes onto the RT with self:addChild and they're always just the last two in the last two quads for some reason.
I'm probably missing something obvious though?
The brush is a SINGLE object but bump expects every object you add to its world to be UNIQUE (so you are getting the error because you are trying to add the same object repeatedly).
The solution is to create a new collision rectangle for each tile that is solid and then add that to the bump world..
Likes: Astirian
So I've been away for a while (getting married and honeymooning hurrah!)...
I've come back to this and it's looking pretty good. Although I've done a weird mix of both your approaches:
The player may move at any point in any of the 4 directions, so he/she is not limited to a grid. The placement of the enemies and rocks is grid based, and my enemies check for a path to the player every 2 seconds or so (using a smaller grid)...
The player draws a black rectangle onto the rt canvas on every frame to draw the tunnel. This works pretty well. Only...
I've kind of designed myself into a corner. Basically because of the players freedom of movement, there's a chance that some slivers of dirt are left, and because the enemies check a grid for pathing (the smaller grid, not the one I use for the procgen placement), there's a chance that they'll 'glide' through the dirt (because I mark the grid as an obstacle using getPixel(), which gets the center pixel's info for that grid square).
I've thought of three solutions to this but they're very expensive. The easiest one I've implemented is that I give the enemies black rectangles that they draw onto the rt canvas when they move on every frame (so they can essentially dig through small portions of dirt), but when you have 12 enemies, the game slows down too much because of the performance hit.
Second thing I've thought about is a finer pathchecking grid but the path check for every enemy every 2 seconds is already quite expensive (due to getPixel()) so that's going to be a performance hit too.
Third solution is even more use of getPixel(), which isn't an option.
Man, and I thought a Dig Dug game was going to be easy! Hahaha!
Likes: Atavismus, MoKaLux
Secondly, commiserations on your Dig Dug issues
Does having collision enabled vs having collision disabled make a difference with many monsters? I'm not 100% sure but I would say that the issue would be the GetPixel() calls. Do you make only one GetPixel() call per monster or many?
You might still be able to use Bump collision for this as well, I don't see the need for any GetPixel calls at all. I'll think up an example.
Bump is now also included as a plugin in Gideros and is vastly faster than the lua based one (which should still be fine for your case).
Anyway I'll try to think of an example using Bump.
Would you be able to paste any code here that roughly shows how your current getPixel() collision works, or is that sharing too much secret sauce?
I don't know if bump is really having that much of an impact. Everything runs relatively smoothly, even the A* pathing calls that use getPixel (more or less, as getPixel seems fairly pricey anyway). It really looks like it's the enemies' drawing of the black rectangles onto the render target on every frame that's causing the slowness.
Basically the slowdown isn't there when 12 enemies are moving without their black "clearing" rectangles but when they have them; the more enemies that move, the more everything slows down. 1-2 are fine then it gets a bit choppy with 3-4, by the time all 12 are moving, it definitely gets very er... slideshowy.
P.S: My workaround with getPixel is to only have the enemies check for a path every 2 seconds as opposed to every frame.
I'm happy to post up some code but there's a lot here haha! I can always send you the full monty if you like. Or write up an abridged version maybe?
Whenever a monster is created they are assigned a unique number (1 - 12 for 12 monsters).
Each frame we update and reset a global frame counter (1- 12 for 12 monsters).
When updating each monster only draw a black thing if the global frame counter matches their unique number.
Using this method you will only have one monster drawing a black thing each frame. Here is some quick code to demonstrate roughly how it would go..
Likes: Astirian