Gameboy Development Forum

Discussion about software development for the old-school Gameboys, ranging from the "Gray brick" to Gameboy Color
(Launched in 2008)

You are not logged in.

Ads

#1 2021-06-30 15:34:15

shiblivs
New member
Registered: 2021-06-10
Posts: 7

Collision on gameboy

Hey! I'm trying to make a platformer, but don't know how to handle collisions etc.

I have a basic understanding of collisions, and don't need raw code. I just need a quick explanation on how I would
do it on the Gameboy.

Offline

 

#2 2021-06-30 20:57:40

Tauwasser
Member
Registered: 2010-10-23
Posts: 160

Re: Collision on gameboy

Most games simply use primitive shapes (points, circles, squares, rectangles,...) and quickly calculate if one such shape intersects another such shape using common math formulas (for exact intersection) or inequalities (for true/false):

Here's a simple Python 3 example for rectangles:

Code:

shapes = [
    {'x':  5, 'y':  6, 'w':  8, 'h':  8},
    {'x':  6, 'y':  7, 'w':  8, 'h':  8},
    {'x':  2, 'y':  5, 'w':  5, 'h':  6},
    {'x': 20, 'y': 15, 'w': 10, 'h': 10},
    {'x': 18, 'y': 13, 'w': 13, 'h': 13},
    {'x': 10, 'y': 12, 'w':  3, 'h':  4},
    {'x':  8, 'y': 18, 'w':  1, 'h':  1},
    {'x':  8, 'y': 14, 'w':  2, 'h':  2},
    ]

def findIntersections():
    
    intersections = []
    
    for i in range(0, len(shapes)):
        
        shape = shapes[i]
        
        for j in range(i + 1, len(shapes)):
            
            other_shape = shapes[j]
            
            # other shape does not overlap shape in x dimension
            if ((other_shape['x'] + other_shape['w']) <= shape['x']):
                continue
            # shape does not overlap other shape in x dimension
            if ((shape['x'] + shape['w']) <= other_shape['x']):
                continue
            
            # other shape does not overlap shape in y dimension
            if ((other_shape['y'] + other_shape['h']) <= shape['y']):
                continue
            # shape does not overlap other shape in y dimension
            if ((shape['y'] + shape['h']) <= other_shape['y']):
                continue
            
            intersections.append((i, j))
    
    return intersections

# 35x30 field
width = 35
height = 30
field = [[' '] * width for _ in range(height)]

for i, shape in enumerate(shapes):
    
    x = shape['x']
    y = shape['y']
    w = shape['w']
    h = shape['h']
    
    # draw corners
    field[y+0][x+0] = '┌'
    field[y+0][x+w] = '┐'
    field[y+h][x+0] = '└'
    field[y+h][x+w] = '┘'
    
    # draw horizontal lines
    for x_ in range(x + 1, x + w):
        field[y+0][x_] = '─'
        field[y+h][x_] = '─'
    
    # draw vertical lines
    for y_ in range(y + 1, y + h):
        field[y_][x+0] = '│'
        field[y_][x+w] = '│'
    
    # draw ID
    field[y+h//2][x+w//2] = str(i)

for line in field:
    print("".join(line))

for i, j in findIntersections():
    print(f'Shape {i} intersects shape {j}.')

Example output:

Code:

  ┌────┐
  │  ┌─│─────┐
  │  │┌│──────┐
  │ 2│││     ││
  │  │││     ││
  │  │││ 0   ││
  └────┘  1  ││
     ││   ┌──┐│
     ││   │  ││   ┌────────────┐
     └│─┌─┐5─││   │            │
      └─│7│──│┘   │ ┌─────────┐│
        └─┘──┘    │ │         ││
                  │ │         ││
        6┐        │ │         ││
        └┘        │ │   4     ││
                  │ │    3    ││
                  │ │         ││
                  │ │         ││
                  │ │         ││
                  │ │         ││
                  │ └─────────┘│
                  └────────────┘



Shape 0 intersects shape 1.
Shape 0 intersects shape 2.
Shape 0 intersects shape 5.
Shape 1 intersects shape 2.
Shape 1 intersects shape 5.
Shape 1 intersects shape 7.
Shape 3 intersects shape 4.

Notice that this code does not compute the actual intersection just whether or not the shapes intersect based on inequalities. Depending on your platformer's needs you might need to actually calculate the intersection point(s). (Notice that my codes does not consider the right-most edge as being part of the rectangle, so a shape starting at x=0 with width 2 does not intersect another shape starting at x=2.)

You might need different types of objects, e.g. a player might be a rectangle, a platform, too, but a bullet might just be a single point or a circle/ellipse etc. There are well-known formulas for quickly determining intersections between all these primitive shape types e.g. point inside rectangle, point on line, line intersection etc.
If you order your shapes by y and then x coordinate you can optimize the run-time of the comparisons. You can stop at the first negative comparison when you know all other shapes are organized further down and/or further to the right. Let's sort the list from the example above first by y followed by x coordinate:

Code:

shapes = [                                           shapes = [
    {'x':  5, 'y':  6, 'w':  8, 'h':  8},                {'x':  2, 'y':  5, 'w':  5, 'h':  6},
    {'x':  6, 'y':  7, 'w':  8, 'h':  8},                {'x':  5, 'y':  6, 'w':  8, 'h':  8},
    {'x':  2, 'y':  5, 'w':  5, 'h':  6},                {'x':  6, 'y':  7, 'w':  8, 'h':  8},
    {'x': 20, 'y': 15, 'w': 10, 'h': 10},     =>         {'x':  8, 'y': 14, 'w':  2, 'h':  2},
    {'x': 18, 'y': 13, 'w': 13, 'h': 13},                {'x':  8, 'y': 18, 'w':  1, 'h':  1},
    {'x': 10, 'y': 12, 'w':  3, 'h':  4},                {'x': 10, 'y': 12, 'w':  3, 'h':  4},
    {'x':  8, 'y': 18, 'w':  1, 'h':  1},                {'x': 18, 'y': 13, 'w': 13, 'h': 13},
    {'x':  8, 'y': 14, 'w':  2, 'h':  2},                {'x': 20, 'y': 15, 'w': 10, 'h': 10},
    ]                                                    ]

Taking the re-ordered example above, a collision comparison for shape 0 (x=2,y=5) can stop after having checked for collision with shape 3 (x=8,y=14), because all other shapes are going to be a) further down or b) further to the right as the list is sorted by x and then by y value.

Good luck with your platformer development smile

Last edited by Tauwasser (2021-06-30 21:02:09)

Offline

 

#3 2021-07-01 03:46:37

toxa
Member
Registered: 2020-02-13
Posts: 305

Re: Collision on gameboy

for checking collisions with scenery, simply make square collision map array.

Offline

 

#4 2021-07-12 10:36:43

shiblivs
New member
Registered: 2021-06-10
Posts: 7

Re: Collision on gameboy

Sorry for late response but thank you!

Tauwasser wrote:

Most games simply use primitive shapes (points, circles, squares, rectangles,...) and quickly calculate if one such shape intersects another such shape using common math formulas (for exact intersection) or inequalities (for true/false):

Here's a simple Python 3 example for rectangles:

Code:

shapes = [
    {'x':  5, 'y':  6, 'w':  8, 'h':  8},
    {'x':  6, 'y':  7, 'w':  8, 'h':  8},
    {'x':  2, 'y':  5, 'w':  5, 'h':  6},
    {'x': 20, 'y': 15, 'w': 10, 'h': 10},
    {'x': 18, 'y': 13, 'w': 13, 'h': 13},
    {'x': 10, 'y': 12, 'w':  3, 'h':  4},
    {'x':  8, 'y': 18, 'w':  1, 'h':  1},
    {'x':  8, 'y': 14, 'w':  2, 'h':  2},
    ]

def findIntersections():
    
    intersections = []
    
    for i in range(0, len(shapes)):
        
        shape = shapes[i]
        
        for j in range(i + 1, len(shapes)):
            
            other_shape = shapes[j]
            
            # other shape does not overlap shape in x dimension
            if ((other_shape['x'] + other_shape['w']) <= shape['x']):
                continue
            # shape does not overlap other shape in x dimension
            if ((shape['x'] + shape['w']) <= other_shape['x']):
                continue
            
            # other shape does not overlap shape in y dimension
            if ((other_shape['y'] + other_shape['h']) <= shape['y']):
                continue
            # shape does not overlap other shape in y dimension
            if ((shape['y'] + shape['h']) <= other_shape['y']):
                continue
            
            intersections.append((i, j))
    
    return intersections

# 35x30 field
width = 35
height = 30
field = [[' '] * width for _ in range(height)]

for i, shape in enumerate(shapes):
    
    x = shape['x']
    y = shape['y']
    w = shape['w']
    h = shape['h']
    
    # draw corners
    field[y+0][x+0] = '┌'
    field[y+0][x+w] = '┐'
    field[y+h][x+0] = '└'
    field[y+h][x+w] = '┘'
    
    # draw horizontal lines
    for x_ in range(x + 1, x + w):
        field[y+0][x_] = '─'
        field[y+h][x_] = '─'
    
    # draw vertical lines
    for y_ in range(y + 1, y + h):
        field[y_][x+0] = '│'
        field[y_][x+w] = '│'
    
    # draw ID
    field[y+h//2][x+w//2] = str(i)

for line in field:
    print("".join(line))

for i, j in findIntersections():
    print(f'Shape {i} intersects shape {j}.')

Example output:

Code:

  ┌────┐
  │  ┌─│─────┐
  │  │┌│──────┐
  │ 2│││     ││
  │  │││     ││
  │  │││ 0   ││
  └────┘  1  ││
     ││   ┌──┐│
     ││   │  ││   ┌────────────┐
     └│─┌─┐5─││   │            │
      └─│7│──│┘   │ ┌─────────┐│
        └─┘──┘    │ │         ││
                  │ │         ││
        6┐        │ │         ││
        └┘        │ │   4     ││
                  │ │    3    ││
                  │ │         ││
                  │ │         ││
                  │ │         ││
                  │ │         ││
                  │ └─────────┘│
                  └────────────┘



Shape 0 intersects shape 1.
Shape 0 intersects shape 2.
Shape 0 intersects shape 5.
Shape 1 intersects shape 2.
Shape 1 intersects shape 5.
Shape 1 intersects shape 7.
Shape 3 intersects shape 4.

Notice that this code does not compute the actual intersection just whether or not the shapes intersect based on inequalities. Depending on your platformer's needs you might need to actually calculate the intersection point(s). (Notice that my codes does not consider the right-most edge as being part of the rectangle, so a shape starting at x=0 with width 2 does not intersect another shape starting at x=2.)

You might need different types of objects, e.g. a player might be a rectangle, a platform, too, but a bullet might just be a single point or a circle/ellipse etc. There are well-known formulas for quickly determining intersections between all these primitive shape types e.g. point inside rectangle, point on line, line intersection etc.
If you order your shapes by y and then x coordinate you can optimize the run-time of the comparisons. You can stop at the first negative comparison when you know all other shapes are organized further down and/or further to the right. Let's sort the list from the example above first by y followed by x coordinate:

Code:

shapes = [                                           shapes = [
    {'x':  5, 'y':  6, 'w':  8, 'h':  8},                {'x':  2, 'y':  5, 'w':  5, 'h':  6},
    {'x':  6, 'y':  7, 'w':  8, 'h':  8},                {'x':  5, 'y':  6, 'w':  8, 'h':  8},
    {'x':  2, 'y':  5, 'w':  5, 'h':  6},                {'x':  6, 'y':  7, 'w':  8, 'h':  8},
    {'x': 20, 'y': 15, 'w': 10, 'h': 10},     =>         {'x':  8, 'y': 14, 'w':  2, 'h':  2},
    {'x': 18, 'y': 13, 'w': 13, 'h': 13},                {'x':  8, 'y': 18, 'w':  1, 'h':  1},
    {'x': 10, 'y': 12, 'w':  3, 'h':  4},                {'x': 10, 'y': 12, 'w':  3, 'h':  4},
    {'x':  8, 'y': 18, 'w':  1, 'h':  1},                {'x': 18, 'y': 13, 'w': 13, 'h': 13},
    {'x':  8, 'y': 14, 'w':  2, 'h':  2},                {'x': 20, 'y': 15, 'w': 10, 'h': 10},
    ]                                                    ]

Taking the re-ordered example above, a collision comparison for shape 0 (x=2,y=5) can stop after having checked for collision with shape 3 (x=8,y=14), because all other shapes are going to be a) further down or b) further to the right as the list is sorted by x and then by y value.

Good luck with your platformer development smile

Offline

 

Board footer

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson