hey leute,
ich hab mir ein kleines jme3 programm geschrieben in dem man mit ego-perspektive rumlaufen kann und kannonenkugeln abfeuern kann. ich weiß das ist nichts großes, es dient ja nur zur übung^^
jetzt hab ich vor die farbe der kannonenkugel zu ändern, wenn die die scene trifft, aber ich habe keinen plan wie ich das anstellen soll.
dies ist mein programm:
ich hatte mich etwas schlau gemacht und es heißt ich muss PhysicsCollisionListener implementieren. was ich damit dann mache weiß ich aber nicht
implementieren:
die methode:
so hab ich es dann gemacht. ich bekomme aber einfach keine nachricht wenn ich mit der kannonenkugel etwas treffe.
hat einer von euch vielleicht eine ahnung was ich in meinem code noch einfügen/ändern muss, damit ich festhalten kann wann die kannonenkugel kollidiert?
(hoffe das ist verständlich xD)
ich hab mir ein kleines jme3 programm geschrieben in dem man mit ego-perspektive rumlaufen kann und kannonenkugeln abfeuern kann. ich weiß das ist nichts großes, es dient ja nur zur übung^^
jetzt hab ich vor die farbe der kannonenkugel zu ändern, wenn die die scene trifft, aber ich habe keinen plan wie ich das anstellen soll.
dies ist mein programm:
Java:
package mygame;
import com.jme3.app.SimpleApplication;
import com.jme3.asset.TextureKey;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.control.CharacterControl;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.util.CollisionShapeFactory;
import com.jme3.collision.CollisionResult;
import com.jme3.collision.CollisionResults;
import com.jme3.font.BitmapText;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.light.AmbientLight;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Ray;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Sphere;
import com.jme3.scene.shape.Sphere.TextureMode;
import com.jme3.system.AppSettings;
import com.jme3.texture.Texture;
public class Main extends SimpleApplication {
BulletAppState bulletAppState;
CharacterControl player;
Vector3f walkDirection = new Vector3f();
boolean left = false, right = false, up = false, down = false;
Node shootables;
Geometry mark;
// materials vorbereiten
Material wall_mat;
Material stone_mat;
// dimensionen für ziegel und mauer
static final float brickLength = 0.48f;
static final float brickWidth = 0.24f;
static final float brickHeight = 0.12f;
public static void main(String[] args) {
// eigenes dialogbild und titel einfügen
AppSettings settings = new AppSettings(true);
settings.setSettingsDialogImage("/Interface/Logo/bild.png");
settings.setTitle("My Game");
Main app = new Main();
app.setSettings(settings);
app.start();
}
@Override
public void simpleInitApp() {
// physik einrichten
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
// flyby camera einrichten
viewPort.setBackgroundColor(new ColorRGBA(0.7f,0.8f,1f,1f));
flyCam.setMoveSpeed(100);
// die scene laden
Spatial sceneModel = assetManager.loadModel("Scenes/town/main.j3o");
sceneModel.setLocalScale(2f);
sceneModel.setName("Scene");
// collision für die scene einrichten
CollisionShape sceneShape =
CollisionShapeFactory.createMeshShape((Node) sceneModel);
RigidBodyControl landscape = new RigidBodyControl(sceneShape, 0);
sceneModel.addControl(landscape);
landscape.addCollideWithGroup(02);
// collision für den spieler einrichten
CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(1.5f, 6f, 1);
player = new CharacterControl(capsuleShape, 0.05f);
player.setJumpSpeed(20);
player.setFallSpeed(30);
player.setGravity(30);
player.setPhysicsLocation(new Vector3f(0, 10, 15));
// scene und spieler dem rootNode und physics space hinzufügen
rootNode.attachChild(sceneModel);
bulletAppState.getPhysicsSpace().add(landscape);
bulletAppState.getPhysicsSpace().add(player);
//vier boxen der scene hinzufügen
shootables = new Node("Shootables");
rootNode.attachChild(shootables);
shootables.attachChild(makeCube("a Dragon", -2f, 4f, -19f));
shootables.attachChild(makeCube("a tin can", 1f, 6f, -20f));
shootables.attachChild(makeCube("the Sheriff", 0f, 2f, -22f));
shootables.attachChild(makeCube("the Deputy", 1f, 8f, -24f));
shootables.attachChild(sceneModel);
initCrossHairs(); // ein "+" in der bildschirmmitte
initMark(); // roter punkt zum markieren der "auswahl"
setUpKeys(); // tasten einrichten
setUpLight(); // licht
initMaterials();
initWall();
}
private void setUpLight() {
// licht einrichten
AmbientLight al = new AmbientLight();
al.setColor(ColorRGBA.White.mult(1.3f));
rootNode.addLight(al);
DirectionalLight dl = new DirectionalLight();
dl.setColor(ColorRGBA.White);
dl.setDirection(new Vector3f(2.8f, -2.8f, -2.8f).normalizeLocal());
rootNode.addLight(dl);
}
private void setUpKeys() {
// tasten einrichten
inputManager.addMapping("Lefts", new KeyTrigger(KeyInput.KEY_A));
inputManager.addMapping("Rights", new KeyTrigger(KeyInput.KEY_D));
inputManager.addMapping("Ups", new KeyTrigger(KeyInput.KEY_W));
inputManager.addMapping("Downs", new KeyTrigger(KeyInput.KEY_S));
inputManager.addMapping("Jumps", new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addListener(actionListener, "Lefts");
inputManager.addListener(actionListener, "Rights");
inputManager.addListener(actionListener, "Ups");
inputManager.addListener(actionListener, "Downs");
inputManager.addListener(actionListener, "Jumps");
//"Select" aktion einrichten
inputManager.addMapping("Select", new KeyTrigger(KeyInput.KEY_E));
inputManager.addListener(actionListener, "Select");
//"Shoot" aktion einrichten
inputManager.addMapping("Shoot", new MouseButtonTrigger(0)); // left-button click
inputManager.addListener(actionListener, "Shoot");
}
private ActionListener actionListener = new ActionListener() {
@Override
public void onAction(String name, boolean keyPressed, float tpf) {
//aktionen für die tasten einrichten
if (name.equals("Lefts")) {
left = keyPressed;
} else if (name.equals("Rights")) {
right = keyPressed;
} else if (name.equals("Ups")) {
up = keyPressed;
} else if (name.equals("Downs")) {
down = keyPressed;
} else if (name.equals("Jumps")) {
player.jump();
}
if (name.equals("Shoot") && !keyPressed) {
makeCannonBall();
}
//"Select" aktion definieren
if (name.equals("Select") && !keyPressed) {
CollisionResults results = new CollisionResults();
Ray ray = new Ray(cam.getLocation(), cam.getDirection());
shootables.collideWith(ray, results);
System.out.println("----- Collisions? " + results.size() + "-----");
for (int i = 0; i < results.size(); i++) {
float dist = results.getCollision(i).getDistance();
Vector3f pt = results.getCollision(i).getContactPoint();
String hit = results.getCollision(i).getGeometry().getName();
System.out.println("* Collision #" + i);
System.out.println(" You shot " + hit + " at " + pt + ", " + dist + " wu away.");
}
if (results.size() > 0){
CollisionResult closest = results.getClosestCollision();
mark.setLocalTranslation(closest.getContactPoint());
rootNode.attachChild(mark);
} else {
rootNode.detachChild(mark);
}
}
}
};
protected Geometry makeCube(String name, float x, float y, float z) {
// eine box als ziel für "select aktion" einrichten
Box box = new Box(new Vector3f(x, y, z), 1, 1, 1);
Geometry cube = new Geometry(name, box);
Material mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat1.setColor("Color", ColorRGBA.randomColor());
cube.setMaterial(mat1);
return cube;
}
public void initMaterials() {
wall_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
TextureKey key = new TextureKey("Textures/Brick/Brick.jpg");
key.setGenerateMips(true);
Texture tex = assetManager.loadTexture(key);
wall_mat.setTexture("ColorMap", tex);
stone_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
TextureKey key2 = new TextureKey("Textures/Rock/Rock.jpg");
key2.setGenerateMips(true);
Texture tex2 = assetManager.loadTexture(key2);
stone_mat.setTexture("ColorMap", tex2);
}
//einen physikalischen zigelstein erstellen
public void makeBrick(Vector3f loc) {
Box box = new Box(Vector3f.ZERO, brickLength, brickHeight, brickWidth);
box.scaleTextureCoordinates(new Vector2f(1f, .5f));
Geometry brick_geo = new Geometry("brick", box);
brick_geo.setMaterial(wall_mat);
rootNode.attachChild(brick_geo);
brick_geo.setLocalTranslation(loc);
RigidBodyControl brick_phy = new RigidBodyControl(2f);
brick_phy.addCollideWithGroup(02);
brick_geo.addControl(brick_phy);
bulletAppState.getPhysicsSpace().add(brick_phy);
}
//wand aus ziegelsteinen erstellen
public void initWall() {
float startpt = brickLength / 4;
float height = 0;
for (int j = 0; j < 15; j++) {
for (int i = 0; i < 4; i++) {
Vector3f vt =
new Vector3f(i * brickLength * 2 + startpt, brickHeight + height, 0);
makeBrick(vt);
}
startpt = -startpt;
height += 2 * brickHeight;
}
}
// physikalische kannonenkugel erstellen
public void makeCannonBall() {
Sphere sphere = new Sphere(32, 32, 0.4f, true, false);
sphere.setTextureMode(TextureMode.Projected);
Geometry ball_geo = new Geometry("cannon ball", sphere);
ball_geo.setMaterial(stone_mat);
rootNode.attachChild(ball_geo);
ball_geo.setLocalTranslation(cam.getLocation());
RigidBodyControl ball_phy = new RigidBodyControl(1f);
ball_phy.setCollisionGroup(02);
ball_phy.addCollideWithGroup(02);
ball_phy.removeCollideWithGroup(01);
ball_geo.addControl(ball_phy);
bulletAppState.getPhysicsSpace().add(ball_phy);
ball_phy.setGravity(new Vector3f(0,0,0));
ball_phy.setLinearVelocity(cam.getDirection().mult(50));
}
//roten punkt erstellen zum markieren der auswahl ("select" aktion)
protected void initMark() {
Sphere sphere = new Sphere(30, 30, 0.2f);
mark = new Geometry("BOOM!", sphere);
Material mark_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mark_mat.setColor("Color", ColorRGBA.Red);
mark.setMaterial(mark_mat);
}
//fadenkreuz
protected void initCrossHairs() {
guiNode.detachAllChildren();
guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
BitmapText ch = new BitmapText(guiFont, false);
ch.setSize(guiFont.getCharSet().getRenderedSize() * 2);
ch.setText("+"); // crosshairs
ch.setLocalTranslation( // center
settings.getWidth()/2 - guiFont.getCharSet().getRenderedSize()/3*2,
settings.getHeight()/2 + ch.getLineHeight()/2, 0);
guiNode.attachChild(ch);
}
@Override
public void simpleUpdate(float tpf) {
// laufen-aktion
Vector3f camDir = cam.getDirection().clone().multLocal(0.6f);
Vector3f camLeft = cam.getLeft().clone().multLocal(0.4f);
walkDirection.set(0, 0, 0);
if (left) { walkDirection.addLocal(camLeft); }
if (right) { walkDirection.addLocal(camLeft.negate()); }
if (up) { walkDirection.addLocal(camDir); }
if (down) { walkDirection.addLocal(camDir.negate()); }
player.setWalkDirection(walkDirection);
cam.setLocation(player.getPhysicsLocation());
}
}
ich hatte mich etwas schlau gemacht und es heißt ich muss PhysicsCollisionListener implementieren. was ich damit dann mache weiß ich aber nicht
implementieren:
Java:
public class Main extends SimpleApplication implements PhysicsCollisionListener{...}
Java:
public void collision(PhysicsCollisionEvent event) {
if ("Scene".equals(event.getNodeA().getName()) || "Scene".equals(event.getNodeB().getName())) {
if ("cannon ball".equals(event.getNodeA().getName()) || "cannon ball".equals(event.getNodeB().getName())) {
System.out.println("HIT!");
}
}
}
hat einer von euch vielleicht eine ahnung was ich in meinem code noch einfügen/ändern muss, damit ich festhalten kann wann die kannonenkugel kollidiert?
(hoffe das ist verständlich xD)