image image


Kollisionserkennung mit Processing.py und P5.js (Teil 1: Kreise)

Bei der Spieleprogrammierung, aber auch bei der Programmierung von Simulationen werden mit ziemlicher Sicherheit Kollisionserkennungen benötigt. Im Prinzip weiß man ja, wie man diese programmiert, aber wie so oft steckt der Teufel im Detail und man wühlt in seinen alten Programmen herum, wie man dies den damals erfolgreich implementiert hat. In dieser kleinen Reihe möchte ich nun an ein paar Beispielen aufzeigen, wie man Kollisionserkennungen programmieren kann. Ich habe die Programme jeweils zuerst in Processing.py, dem Python-Mode von Processing implementiert und dann, um die Funktion auch im Web darstellen zu können, nach P5.js, Processings JavaScript-Ableger, portiert.

Da es zwar nicht unmöglich, aber nicht ganz durchschaubar ist, mehr als einen Canvas mit P5.js auf einer Webseite darzustellen, stelle ich jede Lösung in einem separaten Beitrag vor. Heute die Implementierung der Kollisionserkennung zweier Kreise (es kann ein wenig dauern, bis der Sketch geladen ist, aber nach wenigen Sekunden sollte er unter diesem Absatz erscheinen – ansonsten schaut nach, ob Ihr JavaScript in Eurem Browser enabled habt 🤓):

In diesem Sketch gibt es zwei Kreise. Der kleinere wird mit der Maus bewegt, während der größere unbeweglich ist. Den Python-Code habe ich wegen der besseren Übersichtlichkeit in einzelne Tabs untergebracht, hier zuerst das Hauptprogramm:

from enemies import Enemy
from player import Player

def setup():
    global enemy, player
    size(420, 420)
    this.surface.setTitle("Circle Collision Detection")
    enemy = Enemy(width/2, height/2)
    player = Player(20, 20)

def draw():
    global enemy, player
    background("#95e0f5")
    if circle_collision(enemy, player):
        background("#817ac6")
    else:
        background("#95e0f5")
    enemy.show()
    player.update()
    player.show()

def circle_collision(c1, c2):
    distance = dist(c1.x, c1.y, c2.x, c2.y)
    if distance < c1.r + c2.r:
        return True
    else:
        return False

Die Klasse Enemy (der größere, unbewegliche Kreis) und die Klasse Player werden importiert:

class Enemy(object):

    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.r = 64
    
    def show(self):
        strokeWeight(1)
        fill("#c666e6")
        ellipse(self.x, self.y, self.r*2, self.r*2)
class Player(object):

    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.r = 32
    
    def update(self):
        self.x = mouseX
        self.y = mouseY
    
    def show(self):
        strokeWeight(1)
        fill("#9757a5")
        ellipse(self.x, self.y, self.r*2, self.r*2)

Wenn Ihr den Sketch laufen laßt, sieht er ungefähr so aus:

image

Die Implementierung dieser Kollisionserkennung ist recht einfach. Wenn der Abstand zweier Kreiser größer oder gleich ist, als die Summe der beiden Radii, dann kollidieren sie nicht, wenn er kleiner ist, dann liegt eine Kollision vor. Im Sketch wird das dadurch visualisiert, daß im Falle einer Kollision sich die Hintergrundfarbe ändert.

Nun noch die JavaScript-Version, die durch die neuen Klassen von ES6 nahezu eine 1:1-Kopie der Python-Variante ist:

let enemy;
let player;

function setup() {
  let myCanvas = createCanvas(640, 320);
  myCanvas.parent("myCanvas");
  enemy = new Enemy(width/2, height/2);
  player = new Player(20, 20);
}

function draw() {
  background("#95e0f5");
  if (circleCollision(enemy, player)) {
    background("#817ac6");
  } else {
    background("#95e0f5");
  }
  enemy.show();
  player.update();
  player.show();
}

function circleCollision(c1, c2) {
  distance = dist(c1.x, c1.y, c2.x, c2.y);
  if (distance < c1.r + c2.r) {
    return true;
  } else {
    return false;
  }
}

class Enemy {
  
  constructor(x, y) {
    this.x = x;
    this.y = y;
    this.r = 64;
  }
  
  show() {
    strokeWeight(1);
    fill("#c666e6");
    ellipse(this.x, this.y, this.r*2, this.r*2);
  }
}

class Player {
  
  constructor(x, y) {
    this.x = x;
    this.y = y;
    this.r = 32;
  }
  
  update() {
    this.x = mouseX;
    this.y = mouseY;
  }
  
  show() {
    strokeWeight(1);
    fill("#9757a5");
    ellipse(this.x, this.y, this.r*2, this.r*2);
  }
}

JavaScript benötigt ein paar Sicherheitsklammern mehr, aber nun könnt Ihr in beiden Sprachen Kreiskollisionen programmieren und ein wenig damit herumspielen. Habt Spaß!


(Kommentieren) 

image image



Über …

Der Schockwellenreiter ist seit dem 24. April 2000 das Weblog digitale Kritzelheft von Jörg Kantel (Neuköllner, EDV-Leiter Rentner, Autor, Netzaktivist und Hundesportler — Reihenfolge rein zufällig). Hier steht, was mir gefällt. Wem es nicht gefällt, der braucht ja nicht mitzulesen. Wer aber mitliest, ist herzlich willkommen und eingeladen, mitzudiskutieren!

Alle eigenen Inhalte des Schockwellenreiters stehen unter einer Creative-Commons-Lizenz, jedoch können fremde Inhalte (speziell Videos, Photos und sonstige Bilder) unter einer anderen Lizenz stehen.

Der Besuch dieser Webseite wird aktuell von der Piwik Webanalyse erfaßt. Hier können Sie der Erfassung widersprechen.

Diese Seite verwendet keine Cookies. Warum auch? Was allerdings die iframes von Amazon, YouTube und Co. machen, entzieht sich meiner Kenntnis.


Werbung

Diese Spalte wurde absichtlich leergelassen!


Werbung


image  image  image
image  image  image


image