TigerJython xx
für Gymnasien

Figuren verfolgen

Verfolgung bzw. Spielfiguren zueinander bewegen lassen, wird bei der Spielprogrammierung ofr verwendet. Dabei können siche die Figuren im Gitter bewegen, d.h. von Zelle zur Zelle (Beispiel 1) oder auf dem direkten Weg zum verfolgen Objekt (Beispiel 2).

Beispiel 1: Ein Hai verfolgt Nemo

Nemo schwimmt horizontal hin und her und wird vom Hai verfolgt. Der Hai bewegt sich von Zelle zur Zelle jeweils in Richtung der aktuellen Position von Nemo.

  Dabei kann er bei jedem Schritt eine der 8 möglichen benachbar- ten Zellen wählen. Die für die Verfolgung optimale Richtung wird mit der Methode
getCompassDirectionTo() bestimmt.

Als Parameter erhält diese Methode die Position des verfolgten Objekts.
Damit der Hai den Nemo nicht sofort packt, lassen wir den Hai nur jeden fünften Simulationszyklus bewegen.

 

 
# Gg7.py

from gamegrid import *


# --------------------- class Fish ---------------------
class Fish(Actor):
    def __init__(self):
        Actor.__init__(self, "sprites/snemo.gif")
 
    def act(self):
        self.move()
        if self.getX() == 9:
            self.turn(180)
            self.setHorzMirror(True)
        if self.getX() == 0:
            self.turn(180)
            self.setHorzMirror(False)


# --------------------- class Shark ---------------------
class Shark(Actor):
    def __init__(self):
        Actor.__init__(self, True, "sprites/shark.gif")
 
    def act(self):
        if self.nbCycles % 5 == 0 and not nemo.isRemoved():
            self.setDirection(self.getLocation().
                  getCompassDirectionTo(nemo.getLocation()))
            self.move()
        aNemo = getOneActorAt(self.getLocation(), Fish)
        if aNemo != None:
            aNemo.removeSelf()


makeGameGrid(10, 10, 60, Color.red, "sprites/reef.gif")
nemo = Fish()
addActor(nemo, Location(0, 1))
shark = Shark()
addActor(shark, Location(7, 9))
show()
Programmcode markieren (Ctrl+C kopieren, Ctrl+V einfügen)

 

Erklärungen zum Programmcode:

if self.nbCykles % 5 == 0 : Der Hai bewegt sich nur jeden 5. Simulationszyklus
setDirection(self.getLocation().getCompassDirectionTo(nemo.getLocation())) Hai bewegt sich in die nächste Zelle und wählt dabei diejenige die in der Richtung zum Nemo liegt

 

Beispiel 2: Direkte Verfolgung. Der weisse Ball folgt dem roten Ball

Im Unterschied zum vorhergehenden Beispiel bewegt sich der weisse Ball (Ball) auf dem direkten Weg zum roten Ball (Target); d.h. nicht von Zelle zu Zelle, sondern kontinuierlich. Nachdem der Ball die Position des Targets erreicht hat, verschwindet der rote Ball und erscheint auf einer neuen, zufällig gewählten Position. Die beginnt die Verfolgung erneut.

Die Position des weissen Balls wird punktweise wie folgt berechnet: Zu Beginn jeder Verfolgung wird die Differenz der x-Koordinaten dx und die Differenz der y-Koordinaten dy berechnet. Damit sich der Ball bei grossen Distanzen gleich schnell wie bei kleinen Distanzen bewegt, "normieren" wir die Speed-Komponenten, in dem wir dx und dy durch die Entfernung der beiden Bälle dividieren. Der Speedfaktor kann beliebig angepasst werden. Die neue Koordinaten x und y erhalten wir, in dem wir jeweils zu der aktuellen x bzw. y- Koordinate vx bzw. vy addieren.

 

 
# Gg7a.py

from ch.aplu.jgamegrid import GameGrid, Actor, Location
import random

# ---------------- class Alien ----------------
class Alien(Actor):
    def __init__(self):
        Actor.__init__(self, "_sprites/alien.gif", 2);
     
    def act(self):
        self.setDirection(90)
        if self.getY() < 19:
            self.move()
        else:
            self.show(1)
            
# ---------------- main ----------------------
def mousePressed(e):
    global nbHits 
    location = gg.toLocationInGrid(e.getX(), e.getY())
    actor = gg.getOneActorAt(location)
    if actor != None:
        actor.removeSelf()
        nbHits += 1 
        gg.setTitle("Hits: " + str(nbHits))      

gg = GameGrid(20, 20, 30, False, mousePressed = mousePressed)
gg.setSimulationPeriod(400) 
nbHits = 0    
for i in range(10):
     if gg.nbCycles % 10 == 0: 
         x = random.randint(1, 19)
         y = random.randint(0, 2)
         gg.addActor(Alien(), Location(x, y))  
gg.setTitle("Hits: " + str(nbHits))            
gg.show()
gg.doRun()
Programmcode markieren (Ctrl+C kopieren, Ctrl+V einfügen)

 


Erklärungen zum Programmcode:

int dx = targetPos.x - getPixelLocation().x
int dy = targetPos.y - getPixelLocation().y   
Berechnung der Differenz der x-Koordinaten der beiden Bälle
Berechnung der Differenz der y-Koordinaten der beiden Bälle
norm = Math.sqrt(dx * dx + dy *dy); Die Entfernung der beiden Bälle zu Beginn der Verfolgung
vx = speedFactor * dx / norm;
vy = speedFactor * dy / norm;
Berechnet die speed Komponenten
x += vx;
y += vy;
Berechnet die neuen Koordinaten
setPixelLocation(new Point((int)x, (int)y)) Setzt den weissen Ball an die genaue Position, die durch die beiden berechneten Pixelkoordinaten gegeben ist
if (ball.getLocation().equals(getLocation())) Gibt true zurück, wenn sich die beiden Bälle in der gleichen Zelle befinden