Jump to content
  • Advertisement

Recommended Posts

Posted (edited)

 

You know Pacman, the game with the pellet eating monster; I'm trying to recreate that (Mrs Pacman actually). Because the game is arranged in a series of 28 x 31 tiles, smooth collision for this is difficult to recreate. Here's the tilemap:

nodemap = {
    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
    {1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1},
    {1,1,0,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,0,1,1},
    {1,1,0,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,0,1,1},
    {1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
    {1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1},
    {1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1},
    {1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1},
    {1,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,1},
    {1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1},
    {1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1},
    {1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1},
    {1,1,1,1,0,1,1,1,1,1,0,1,1,1,0,0,1,1,1,0,1,1,1,1,1,0,1,1,1,1},
    {1,1,1,1,0,1,1,1,1,1,0,1,0,0,0,0,0,0,1,0,1,1,1,1,1,0,1,1,1,1},
    {1,1,1,1,0,1,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,1,1,0,1,1,1,1},
    {1,1,1,1,0,1,1,0,1,1,0,1,0,0,0,0,0,0,1,0,1,1,0,1,1,0,1,1,1,1},
    {1,1,1,1,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,0,1,1,1,1},
    {1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1},
    {1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1},
    {1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1},
    {1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1},
    {1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1},
    {1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1},
    {1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
    {1,1,0,1,1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,1,1,0,1,1},
    {1,1,0,1,1,1,1,0,1,1,1,1,1,0,1,1,0,1,1,1,1,1,0,1,1,1,1,0,1,1},
    {1,1,0,1,1,1,1,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,1,1,1,1,0,1,1},
    {1,1,0,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,0,1,1},
    {1,1,0,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,0,1,1},
    {1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
    {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
}

This is my collision code (And explanations for each segment):

-- Make Pacmans position consist of a single decimal (because over time a number of 1.899999994 will occur and that's ugly)
mrspacman.x = math.floor(mrspacman.x*10)/10
mrspacman.y = math.floor(mrspacman.y*10)/10

--If an arrowkey was pressed (Think of this as "A new direction was queued")
if (mrspacman.nextDirection) then

    -- If Pacman is in the center of a tile, then
    if (mrspacman.x == math.floor(mrspacman.x)) and (mrspacman.y == math.floor(mrspacman.y)) then

        -- If the tile in front of Pacman is empty, set direction to that
        if (nodemap[mrspacman.y-math2.sin(mrspacman.dir)][mrspacman.x+math2.cos(mrspacman.dir)]~=1) then
            mrspacman.dz = mrspacman.dir

            -- Disable this queue
            mrspacman.nextDirection = false
        end
    end
end

-- If Pacman is NOT in the center of a tile
if (mrspacman.x ~= math.floor(mrspacman.x)) or (mrspacman.y ~= math.floor(mrspacman.y)) then

    -- Constantly move forwards
    mrspacman.x = mrspacman.x + (math2.cos(mrspacman.dz)*mrspacman.speed)
    mrspacman.y = mrspacman.y - (math2.sin(mrspacman.dz)*mrspacman.speed)
else

    -- If the tile in front of Pacman is empty, move to that tile
    if (nodemap[mrspacman.y-math2.sin(mrspacman.dz)][mrspacman.x+math2.cos(mrspacman.dz)] ~= 1) then
        mrspacman.x = mrspacman.x + (math2.cos(mrspacman.dz)*mrspacman.speed)
        mrspacman.y = mrspacman.y - (math2.sin(mrspacman.dz)*mrspacman.speed)
    end
end

The above results in this (sometimes unable to go backwards, movement is sometimes faster towards a vector compared to the opposite vector, will stop when going back, and freeze...) How can I implement this smooth movement?

math2.cos / math2.sin is just a custom table I created with those 2 trig functions (makes code cleaner looking, and I don't have to mess with accuracy of converting deg-->rad.)

mrspacman.speed has a value of .1

Edited by Rico Solana

Share this post


Link to post
Share on other sites
Advertisement

In my opinion your math looks too complex for what you are trying to do.

To fix the problem I wouldn't move in vector space but instead have the collisions move in tile space, while only the art moves in vector space.

PackMan.jpg.ba217b7e6bcc7e525cee0744a7e210d1.jpg

This way your collision check is as simple as checking if the next grid block is empty. Moving is a illusion that just waits for PackMan to catch up.

When I think of the controls of the original game I would say it was done like this or very similar.

Share this post


Link to post
Share on other sites
8 minutes ago, Scouting Ninja said:

In my opinion your math looks too complex for what you are trying to do.

To fix the problem I wouldn't move in vector space but instead have the collisions move in tile space, while only the art moves in vector space.

PackMan.jpg.ba217b7e6bcc7e525cee0744a7e210d1.jpg

This way your collision check is as simple as checking if the next grid block is empty. Moving is a illusion that just waits for PackMan to catch up.

When I think of the controls of the original game I would say it was done like this or very similar.

I agree with you that I could check for the next tile and wait a time for the animation to finish, but I suppose that the reason I had complex math was because objects are capable of colliding with other objects without being in the center of each tile.

If I were to use the method you had, moving from tile to tile and in-between each tile movement waiting for the animation of movement to finish, Pacman would have to wait the entire frametime of the animation until a command can be entered; then can move (This mainly applies to moving backwards -- doesn't apply to turning towards a side because Pacman can only turn towards an empty space when in the center of a tile -- the animation would be canceled by then). Do you have an idea/suggestion for that? (I've been working on this since December; so anxious to get it over with; to call it a day; to close the book...)

pic.png

Share this post


Link to post
Share on other sites

A simple solution would be to move each entity as if it were affixed on a grid and check for collisions during the animation.

Share this post


Link to post
Share on other sites
Posted (edited)
20 hours ago, Rico Solana said:

Pacman would have to wait the entire frametime of the animation until a command can be entered

Sorry that wasn't what I meant. What I meant was when you press the Right_Key the collision box moves to the next block and Left_Key it moves back. This is instant.

The problem you are talking about won't exist when moving backwards, it will exist when moving forwards. That is PacMans collision can't move forward without PackMan reaching the middle of the tile:

PacManMove.jpg.df18e058bb3c82936a90b3ed6877d827.jpg

The green shows what direction it can move. If it is in the middle of a tile it can move in any direction. When a new direction is selected it can still move back to a previous tile, turn around, but moving forward needs it to reach.

The reason I think PacMan worked like this is how it kept moving in one direction till it collided. Doing that will hide this effect.

 

To be clear, the pack man image decides what boxes can be selected, only the ones next to it.

 

Edited by Scouting Ninja

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!