Skip to content

Commit

Permalink
apps: add TestBrickTower and TestBrickWall (adapted from jme3-examples)
Browse files Browse the repository at this point in the history
  • Loading branch information
stephengold committed Jun 20, 2024
1 parent 33cea11 commit 7b8baf7
Show file tree
Hide file tree
Showing 2 changed files with 455 additions and 0 deletions.
251 changes: 251 additions & 0 deletions apps/src/main/java/jme3test/bullet/TestBrickTower.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
/*
* Copyright (c) 2009-2021 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package jme3test.bullet;

/*
* Copyright (c) 2009-2012 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

import com.jme3.app.SimpleApplication;
import com.jme3.asset.TextureKey;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.collision.shapes.SphereCollisionShape;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.font.BitmapText;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.material.Material;
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.shape.Box;
import com.jme3.scene.shape.Sphere;
import com.jme3.scene.shape.Sphere.TextureMode;
import com.jme3.texture.Texture;
import com.jme3.texture.Texture.WrapMode;

/**
*
* @author double1984 (tower mod by atom)
*/
public class TestBrickTower extends SimpleApplication {

final private int bricksPerLayer = 8;
final private int brickLayers = 30;

final private static float brickWidth = .75f, brickHeight = .25f, brickDepth = .25f;
final private float radius = 3f;
private float angle = 0;


private Material mat;
private Material mat2;
private Material mat3;
private Sphere bullet;
private Box brick;
private SphereCollisionShape bulletCollisionShape;

private BulletAppState bulletAppState;

public static void main(String args[]) {
TestBrickTower f = new TestBrickTower();
f.start();
}

@Override
public void simpleInitApp() {
bulletAppState = new BulletAppState();
// bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL);
// bulletAppState.setEnabled(false);
stateManager.attach(bulletAppState);
bullet = new Sphere(32, 32, 0.4f, true, false);
bullet.setTextureMode(TextureMode.Projected);
bulletCollisionShape = new SphereCollisionShape(0.4f);

brick = new Box(brickWidth, brickHeight, brickDepth);
brick.scaleTextureCoordinates(new Vector2f(1f, .5f));
initMaterial();
initTower();
initFloor();
initCrossHairs();
this.cam.setLocation(new Vector3f(0, 25f, 8f));
cam.lookAt(Vector3f.ZERO, new Vector3f(0, 1, 0));
cam.setFrustumFar(80);
inputManager.addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
inputManager.addListener(actionListener, "shoot");
rootNode.setShadowMode(ShadowMode.Off);
}

private PhysicsSpace getPhysicsSpace() {
return bulletAppState.getPhysicsSpace();
}
final private ActionListener actionListener = new ActionListener() {

@Override
public void onAction(String name, boolean keyPressed, float tpf) {
if (name.equals("shoot") && !keyPressed) {
Geometry bulletGeometry = new Geometry("bullet", bullet);
bulletGeometry.setMaterial(mat2);
bulletGeometry.setShadowMode(ShadowMode.CastAndReceive);
bulletGeometry.setLocalTranslation(cam.getLocation());
// RigidBodyControl bulletNode = new BombControl(assetManager, bulletCollisionShape, 1);
RigidBodyControl bulletNode = new RigidBodyControl(bulletCollisionShape, 1);
bulletNode.setLinearVelocity(cam.getDirection().mult(25));
bulletGeometry.addControl(bulletNode);
rootNode.attachChild(bulletGeometry);
getPhysicsSpace().add(bulletNode);
}
}
};

public void initTower() {
double tempX = 0;
double tempY = 0;
double tempZ = 0;
angle = 0f;
for (int i = 0; i < brickLayers; i++){
// Increment rows
if(i!=0)
tempY+=brickHeight*2;
else
tempY=brickHeight;
// Alternate brick seams
angle = 360.0f / bricksPerLayer * i/2f;
for (int j = 0; j < bricksPerLayer; j++){
tempZ = Math.cos(Math.toRadians(angle))*radius;
tempX = Math.sin(Math.toRadians(angle))*radius;
System.out.println("x="+((float)(tempX))+" y="+((float)(tempY))+" z="+(float)(tempZ));
Vector3f vt = new Vector3f((float)(tempX), (float)(tempY), (float)(tempZ));
// Add crenelation
if (i==brickLayers-1){
if (j%2 == 0){
addBrick(vt);
}
}
// Create main tower
else {
addBrick(vt);
}
angle += 360.0/bricksPerLayer;
}
}

}

public void initFloor() {
Box floorBox = new Box(10f, 0.1f, 5f);
floorBox.scaleTextureCoordinates(new Vector2f(3, 6));

Geometry floor = new Geometry("floor", floorBox);
floor.setMaterial(mat3);
floor.setShadowMode(ShadowMode.Receive);
floor.setLocalTranslation(0, 0, 0);
floor.addControl(new RigidBodyControl(0));
this.rootNode.attachChild(floor);
this.getPhysicsSpace().add(floor);
}

public void initMaterial() {
mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
TextureKey key = new TextureKey("Textures/Terrain/BrickWall/BrickWall.jpg");
key.setGenerateMips(true);
Texture tex = assetManager.loadTexture(key);
mat.setTexture("ColorMap", tex);

mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
TextureKey key2 = new TextureKey("Textures/Terrain/Rock/Rock.PNG");
key2.setGenerateMips(true);
Texture tex2 = assetManager.loadTexture(key2);
mat2.setTexture("ColorMap", tex2);

mat3 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
TextureKey key3 = new TextureKey("Textures/Terrain/Pond/Pond.jpg");
key3.setGenerateMips(true);
Texture tex3 = assetManager.loadTexture(key3);
tex3.setWrap(WrapMode.Repeat);
mat3.setTexture("ColorMap", tex3);
}

public void addBrick(Vector3f ori) {
Geometry brickGeometry = new Geometry("brick", brick);
brickGeometry.setMaterial(mat);
brickGeometry.setLocalTranslation(ori);
brickGeometry.rotate(0f, (float)Math.toRadians(angle) , 0f );
brickGeometry.addControl(new RigidBodyControl(1.5f));
brickGeometry.setShadowMode(ShadowMode.CastAndReceive);
brickGeometry.getControl(RigidBodyControl.class).setFriction(1.6f);
this.rootNode.attachChild(brickGeometry);
this.getPhysicsSpace().add(brickGeometry);
}

protected void initCrossHairs() {
guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
BitmapText ch = new BitmapText(guiFont);
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);
}
}
Loading

0 comments on commit 7b8baf7

Please sign in to comment.