Skip to content

Instantly share code, notes, and snippets.

@Orpheon
Created August 29, 2011 11:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Orpheon/1178251 to your computer and use it in GitHub Desktop.
Save Orpheon/1178251 to your computer and use it in GitHub Desktop.
import functions
import pygame
def characterCheckCollision(character, wallmask):
# Check if a the Character has hit the wall:
hasCollided = False
for index in range(len(wallmask)):
if abs(wallmask[index].centerx-character.rect.centerx) < 50:
if abs(wallmask[index].centery-character.rect.centery) < 50:
if character.rect.colliderect(wallmask[index]):
# Hit detected Flag as hit and break out.
hasCollided = True
break
if hasCollided:
return True
else:
return False
def characterHitObstacle(character, mapMask):
# The Character has collided; Push him back out:
oldx=character.x
oldy=character.y
oldhspeed=character.hspeed
oldvspeed=character.vspeed
# slide left and right to get outside of any walls
move_outside_solid(0, 8)
move_outside_solid(180, 16)
hleft = character.hspeed
vleft = character.vspeed
loopCounter = 0
stuck = 0
while((abs(hleft) >= 1 or abs(vleft) >= 1) and stuck == 0): # while we still have distance to travel
loopCounter += 1
if(loopCounter > 10):
# debugging stuff.
#show_message("x = " + string(x) + "#y = " + string(y) + "#oldx = " + string(oldx) + "#oldy = " + string(oldy) + "#hspeed = " + string(hspeed) + "#vspeed = " + string(vspeed) + "#hleft = " + string(hleft) + "#vleft = " + string(vleft) + "#hdirection = " + string(hdirection) + "#vdirection = " + string(vdirection))
#game_end()
# After 10 loops, it's assumed we're stuck. Will eliminating vertical movement fix the problem?
#vspeed = 0
#vleft = 0
# note that we should instead be checking the collisionRectified variable instead of waiting
# some arbitrary number of iterations
stuck = 1
collisionRectified = False # set this to true when we fix a collision problem
# (eg. detect hitting the ceiling and setting vspeed = 0)
# if, after checking for all our possible collisions, we realize that we haven't
# been able to fix a collision problem, then we probably hit a corner or something,
# and we should try to fix that
prevX = character.x
prevY = character.y
# move as far as we can without hitting something
# In GMK, this was "move_contact_solid(point_direction(x, y, x + hleft, y + vleft), point_distance(x, y, x + hleft, y + vleft))"
length = functions.lengthdir(hleft, vleft)
hoffset = hleft/length
voffset = vleft/length
for distance in range(0, length):
x = character.x
y = character.y
character.x = x+hleft*distance
character.y = y+vleft*distance
if not (characterCheckCollision):
character.x = x
character.y = y
# deduct that movement from our remaining movement
hleft -= character.x - prevX
vleft -= character.y - prevY
# determine what we hit, and act accordingly
if(vleft != 0 and not place_free(character.x, character.y + sign(vleft))): # we hit a ceiling or floor
if(vleft>0):
moveStatus = 0 # floors, not ceilings, reset moveStatus
vleft = 0 # don't go up or down anymore
character.vspeed = 0 # don't try it next frame, either
collisionRectified = True
if(hleft != 0 and not place_free(character.x + sign(hleft), character.y)): # we hit a wall on the left or right
moveStatus = 0
if(place_free(character.x + sign(hleft), character.y - 6)): # if we could just walk up the step
character.y -= 6 # hop up the step.
collisionRectified = True
elif(place_free(character.x + sign(hleft), character.y + 6) and abs(character.hspeed) >= abs(character.vspeed)): # ceiling sloping
character.y += 6
collisionRectified = True
else: # it's not just a step, we've actually gotta stop
hleft = 0 # don't go left or right anymore
hspeed = 0 # don't try it next frame, either
collisionRectified = true
if(not collisionRectified and (abs(hleft) >= 1 or abs(vleft) >= 1)):
# uh-oh, no collisions fixed, try stopping all vertical movement and see what happens
vspeed = 0
vleft = 0
character.x -= character.hspeed # the game will += these in a moment, so we compensate for that
character.y -= character.vspeed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment