Pacman Mechanics

Here I come with another question!

How does one learn an enemy AI: (the ghosts of pacman)

That they can move from point A to B by hitting the wall at a specific point.

Or is this overly complicated and should I drop it for a first BGE project?

Or only support it for the player? (This kinda feels like cheating to me)

I came up with a thought whilst typing this, but I still would like to get a second opinion :smiley:

Are you talking about the tunnels that teleport you from once side of the stage to another?

Or are you talking about the ghosts making a path to the player?

Attachments


If you want to know about old fashioned tile based movement I can write a tutorial about it…

You can read various analysis of the ghost AI:


http://gameai.com/wiki/index.php?title=Pac-Man
etc.

@Lordofthechings : Both actually since i’m not satisfied by how the navmesh and steering works!

@Smoking_mirror : That would be very nice. Take Your time and let me know when it’s finished.

@sdfgeoff : A little homework xD I’ll be reading that right now!

Also I’ve made a navmesh from a pacman-like map I made.
Totally not satisfied by how the object navigates the mesh! (I think it’s limited in every way)
Are ther any means of manipulating the way this works, Except from the turning and moving speed (Steering actuator)

If you’re making a game like pacman your best way forward would be to code it in a similar way.
That means using python quite a lot though. Are you comfortable with using python for most of the movement?
pros: total control of movement, doesn’t need any collision or other things, hit detection is as easy as measuring a vector.
cons: no physics, difficult to do 3d movement(up/down), no so easy to use logic bricks…

No I have almost no experience in coding (very little Java)
And I have not looked into python either!

This is on my agenda though

nevermind that each ghost has its different AI :smiley:

that is a possible ghost AI (semplified)
as usual i prefer AI with “alzaymer” (no memory)


import random
import bge
from mathutils import Vector, Matrix




"""pac-man ghost AI (iper - semplificated)


the face forward of the ghost object is +Y (green arrow)(to semplificate face_to())
the ghost obj is not a object physic (not influeced from collisions)


"""


TILE_SIZE = 2.0  # 2 meters




def face_to(own, pos): # align to position without interpolations
    own.worldOrientation = (pos - own.worldPosition).to_track_quat("Y","Z")


def get_target(own):
    # these are sort of -> north south owest east
    FOUR_DIRECTIONS = [vec * verse for verse in [-1,1] for vec in Matrix().to_3x3()[:2]]
    start = own.worldPosition
    directions = []
    for direction in FOUR_DIRECTIONS:
        end = start + direction * TILE_SIZE * 1.5
        if not own.rayCast(end, start)[0]: 
            directions.append(direction) # the ray has not found obstacle, so free way, add
            
    # is assumed that at least one direction free exist (otherwise give error) 
    direction = random.choice(directions) # pick one random
    target_position = start + (direction * TILE_SIZE)
    return target_position








def main():
    cont = bge.logic.getCurrentController()
    own = cont.owner


    if not "init" in own:
        own["target_xyz"] = None
        own["init"] = True
        own["speed"] = 0.05
        
    if not own["target_xyz"]:
        xyz = own["target_xyz"] = get_target(own)
        face_to(own, xyz)
   
    
    #debug
    bge.render.drawLine(own.worldPosition, own["target_xyz"], [1,0,0])
    
    ## move
    speed = own["speed"]
    dist = own.getDistanceTo(own["target_xyz"])
    if dist > speed:
        own.applyMovement((0,speed,0),1)
    else:
        own.worldPosition = own["target_xyz"]
        own["target_xyz"] = None
    


try:
    main()
except:
    bge.logic.endGame()
    raise
    
    

EDIT: bugfix (copy paste wrong)

@MarcoIT really cool, I changed the the speed to .1 and tile size to 2. Is there anyway to tweek the randon direction? You programmers are awesome.

That’s a really cool article. Thanks.

you mean a bit less random?

can be added more chances to the forward direction
and removed the “back” direction.(as is in pacman original)

ok, now is a bit better :slight_smile:


import random
import bge
from mathutils import Vector, Matrix








"""pac-man ghost AI (iper - semplificated)




the face forward of the ghost object is +Y (green arrow)(to semplificate face_to())
the ghost obj is not a object physic (not influeced from collisions)


added patch for "no direction founded"
"""




TILE_SIZE = 2.0  # 2 meters








def face_to(own, pos): # align to position without interpolations
    own.worldOrientation = (pos - own.worldPosition).to_track_quat("Y","Z")




def get_target(own):
    vx, vy = own.worldOrientation.col[:2]
    local_directions = [-vx, vx, vy, vy, vy] # more forward direction
    start = own.worldPosition
    targets_candidate = [start+vec*TILE_SIZE for vec in local_directions]
    targets_free = []
    for target in targets_candidate:
        if not own.rayCast(target, start)[0]: 
            targets_free.append(target)
    
    if not targets_free:
        return None
    target = random.choice(targets_free)
    # chunkifyze.. should be already , but to be more sure ...
    return Vector([round(v/TILE_SIZE)*TILE_SIZE for v in target])










def main():
    cont = bge.logic.getCurrentController()
    own = cont.owner




    if not "init" in own:
        own["target_xyz"] = None
        own["init"] = True
        own["speed"] = 0.1
        
    if not own["target_xyz"]:
        target = own["target_xyz"] = get_target(own)
        if not target:
            return
        face_to(own, target)
        
    
    #debug
    bge.render.drawLine(own.worldPosition, own["target_xyz"], [1,0,0])
    
    ## move
    speed = own["speed"]
    dist = own.getDistanceTo(own["target_xyz"])
    if dist > speed:
        own.applyMovement((0,speed,0),1)
    else:
        own.worldPosition = own["target_xyz"]
        own["target_xyz"] = None
    




try:
    main()
except:
    bge.logic.endGame()
    raise
    
    
    

Thank you Marco. Very cool. I’ll play with it later, been really busy these past few days. :slight_smile: