[quote] Slightly OT, but how does your player AI actually behave? I’d like to do something similar, but have no idea where to start…
[/quote]
Just some simple rules. For steering the ai uses keyPresses, so each maneuver is possible for a human player. Instead of explaining the rules I post the code.
!BEWARE OF BAD CODING STYLE AND UGLY FORMATING!
(sorry, I’m just too lazy to make it nicer now)
Because you opened this thread and asked for it, everybody else should shut both eyes and scroll down ;D
public class AutoPilot
extends KClass {
private Ship ship;
private GameEngine g;
public AutoPilot(Ship ship) {
this.ship = ship;
this.g = ship.g;
}
public void steer() {
Key.setPressed(Key.LEFT, false);
Key.setPressed(Key.RIGHT, false);
Key.setPressed(Key.UP, false);
Key.setPressed(Key.DOWN, false);
if (foes()) {
ship.fire();
}
headFor(new V2(ship.startx, g.now.y + .25));
FoeFire ff = (FoeFire) g.ym.foeFire.getClosestYop(ship);
if (ff != null) {
float dist = ff.dist(ship);
//if(dist<.03f)ship.pod.fireByName(Lang.SmartSuperCluster);
if (dist < .04f && ship.shield < 2) { //@todo: richtung berücksichtigen
if (ship.hp / ship.hpMax < .1 && ship.hasShieldLeft()) {
ship.fireShield();
}
else {
headAwayFrom(ff);
}
return;
}
}
if (ship.foesInNegTractorbeamRange > 10) {
fireSpecial();
}
Foe nf = (Foe) g.ym.foes.getClosestYop(ship);
if (nf != null) {
float dist = nf.dist(ship);
if (dist < .08f && ship.shield < 2) {
headAwayFrom(nf);
if (dist < .04f) {
fireSpecial();
}
return;
}
}
Yop p = nearestPow();
if (p != null) {
//Foe f=Yop.closestFoe(p);if(f!=null && p.pos.dist(f.pos)<.13f) return;
if (p.name.equalsIgnoreCase(Lang.YSHOP) && ship.money < 800) {
return;
}
headFor(p);
return;
}
if (foes()) {
Foe f = Yop.closestFoe(ship);
if (f != null) {
float dist = f.pos.y - g.now.y - f.getRadius();
if (dist > .3f && ship.pos.y < f.pos.y) {
headFor(f.pos.addN(0, -.3f));
}
}
//if(Ma.wave(4f)>0){Key.setPressed(Key.LEFT,true);Key.setPressed(Key.RIGHT,false);}else {Key.setPressed(Key.RIGHT,true);Key.setPressed(Key.LEFT,false);}
}
}
boolean foes() {
return g.ym.foes.size() > 0 || g.ym.foesGround.size() > 0;
}
Yop nearestPow() {
return g.ym.powerUps.getClosestYop(ship);
}
void headFor(V2 v) {
ship.headFor(v);
}
void headFor(Yop o) {
V2 v = new V2(o.pos);
headFor(v);
}
void headAwayFrom(Yop o) {
headAwayFrom(o.pos);
}
void headAwayFrom(V2 v) {
V2 pos = ship.pos;
//Yop.getAngle()
Key.setPressed(ship.bright(), v.x < pos.x);
Key.setPressed(ship.bleft(), v.x > pos.x);
Key.setPressed(ship.bup(), v.y < pos.y);
Key.setPressed(ship.bdown(), v.y > pos.y);
}
float lastspecial;
void fireSpecial() {
if (ship.pod.getSpecials().size() == 0) {
return;
}
float n = g.ym.foes.size() + g.ym.foesGround.size();
n /= ship.pod.getFirepower() * 15f;
n /= (float) ship.hp / ship.hpMax;
M.log.warning(this, "prob=" + n);
if (!Ma.prob(n)) {
return;
}
if (g.time() - lastspecial < 1f) {
return;
}
ship.fireSpecial();
lastspecial = g.time();
}
}
the logger for the stats runs in an extra thread and makes a snapshot every second…