Created
January 1, 2016 13:21
-
-
Save darkwave/04a7a70b60997bad1ecf to your computer and use it in GitHub Desktop.
Sprite collision using boundaries intersection and (then) bitmask with Processing 3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Element player, enemy; | |
void setup() { | |
fullScreen(); | |
player = new Element("animal.gif", 50, 50); | |
enemy = new Element("animal.gif", 40, 40, -175, -309); | |
stroke(#ff00ff); | |
} | |
void draw() { | |
background(0); | |
if (player.getBitmaskCollision(enemy)) | |
tint(255, 0, 0); | |
else | |
tint(255, 255); | |
player.display(); | |
enemy.display(); | |
player.getBitmaskCollision(enemy); | |
PVector[] intersection = player.getBoundaries(); | |
stroke(#ffcc00); | |
if (intersection != null) { | |
line(intersection[0].x, intersection[0].y, intersection[1].x, intersection[1].y); | |
line(intersection[1].x, intersection[1].y, intersection[2].x, intersection[2].y); | |
line(intersection[2].x, intersection[2].y, intersection[3].x, intersection[3].y); | |
line(intersection[3].x, intersection[3].y, intersection[0].x, intersection[0].y); | |
} | |
intersection = enemy.getBoundaries(); | |
stroke(#ff0000); | |
if (intersection != null) { | |
line(intersection[0].x, intersection[0].y, intersection[1].x, intersection[1].y); | |
line(intersection[1].x, intersection[1].y, intersection[2].x, intersection[2].y); | |
line(intersection[2].x, intersection[2].y, intersection[3].x, intersection[3].y); | |
line(intersection[3].x, intersection[3].y, intersection[0].x, intersection[0].y); | |
} | |
intersection = player.getIntersection(enemy); | |
stroke(#ff00ff); | |
if (intersection != null) { | |
line(intersection[0].x, intersection[0].y, intersection[1].x, intersection[1].y); | |
line(intersection[1].x, intersection[1].y, intersection[2].x, intersection[2].y); | |
line(intersection[2].x, intersection[2].y, intersection[3].x, intersection[3].y); | |
line(intersection[3].x, intersection[3].y, intersection[0].x, intersection[0].y); | |
} | |
} | |
void mouseDragged() { | |
enemy.setPosition(new PVector(mouseX, mouseY)); | |
} | |
class Element { | |
PImage sprite; | |
PImage currentFrame; | |
int w, h; | |
PVector position = null; | |
PVector offset = null; | |
int[] bitmask; | |
Element(PImage sprite, float x, float y) { | |
this.sprite = sprite; | |
w = sprite.width; | |
h = sprite.height; | |
position = new PVector(x, y); | |
bitmask = getBitmask(); | |
} | |
Element(PImage sprite, float x, float y, float offsetX, float offsetY) { | |
this(sprite, x, y); | |
offset = new PVector(offsetX, offsetY); | |
} | |
Element(String spriteFilename, float x, float y) { | |
this(loadImage(spriteFilename), x, y); | |
} | |
Element(String spriteFilename, float x, float y, float offsetX, float offsetY) { | |
this(loadImage(spriteFilename), x, y); | |
offset = new PVector(offsetX, offsetY); | |
} | |
Element(String spriteFilename) { | |
this(loadImage(spriteFilename), 0, 0); | |
} | |
void display() { | |
PVector currentPosition = getPosition(); | |
image(sprite, currentPosition.x, currentPosition.y); | |
} | |
PVector getPosition() { | |
if (offset != null) { | |
return PVector.add(position, offset); | |
} else { | |
return position; | |
} | |
} | |
void setPosition(PVector newPosition) { | |
position = newPosition.get(); | |
} | |
PVector[] getBoundaries() { | |
PVector currentPosition = getPosition(); | |
return new PVector[] { | |
new PVector(currentPosition.x, currentPosition.y), | |
new PVector(currentPosition.x + w, currentPosition.y), | |
new PVector(currentPosition.x + w, currentPosition.y + h), | |
new PVector(currentPosition.x, currentPosition.y + h), | |
}; | |
} | |
PVector[] getIntersection(Element other) { | |
PVector[] boundaries = getBoundaries(); | |
PVector[] otherBoundaries = other.getBoundaries(); | |
float xL = max(boundaries[0].x, otherBoundaries[0].x); | |
float xR = min(boundaries[1].x, otherBoundaries[1].x); | |
if (xR <= xL) | |
return null; | |
float yT = max(boundaries[0].y, otherBoundaries[0].y); | |
float yB = min(boundaries[3].y, otherBoundaries[3].y); | |
if (yB <= yT) | |
return null; | |
return new PVector[] { | |
new PVector(xL, yT), | |
new PVector(xR, yT), | |
new PVector(xR, yB), | |
new PVector(xL, yB), | |
}; | |
} | |
boolean getBitmaskCollision(Element other) { | |
PVector[] intersection = getIntersection(other); | |
PVector[] boundaries = getBoundaries(); | |
PVector[] otherBoundaries = other.getBoundaries(); | |
if (intersection == null) | |
return false; | |
int iw = int(intersection[1].x - intersection[0].x); | |
int ih = int(intersection[2].y - intersection[0].y); | |
for (int x = int(intersection[0].x); x < int(intersection[1].x); x++) { | |
for (int y = int(intersection[0].y); y < int(intersection[2].y); y++) { | |
if (other.bitmask[int(x - otherBoundaries[0].x) + int(y - otherBoundaries[0].y) * other.w] > 20 && | |
bitmask[int(x - boundaries[0].x) + int(y - boundaries[0].y) * other.w] > 20 | |
) { | |
//set(x, y, color(#ffff00)); | |
return true; | |
} | |
} | |
} | |
return false; | |
} | |
int[] getBitmask() { | |
int[] result = new int[w * h]; | |
for (int x = 0; x < w; x++) | |
for (int y = 0; y < h; y++) { | |
result[y * w + x] = int(alpha(sprite.get(x, y))); | |
} | |
return result; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment