Since I changed from the helper class CharacterControl to the new BetterCharacterControl I notice some improvements such as pushing other characters is working but my main character has started sliding over steps and can't climb higher steps.
I must jump the step above which is not the right way of playing, it should be just walking over. The old helper class CharacterControl had a default way of not sliding, just walking over steps and I think it can be corrected by altering the code where I create the main character.
private void createNinja() {
ninjaNode = (Node) assetManager
.loadModel("Models/Ninja/Ninja.mesh.xml");
ninjaNode.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
ninjaNode.setLocalScale(0.06f);
ninjaNode.setLocalTranslation(new Vector3f(55, 3.3f, -60));
ninjaControl = new BetterCharacterControl(2, 4, 0.5f);
ninjaControl.setJumpForce(new Vector3f(6, 6, 6));
ninjaNode.addControl(ninjaControl);
rootNode.attachChild(ninjaNode);
bulletAppState.getPhysicsSpace().add(ninjaControl);
getPhysicsSpace().add(ninjaControl);
animationControl = ninjaNode.getControl(AnimControl.class);
animationChannel = animationControl.createChannel();
}
The complete code is
package adventure;
import com.jme3.system.AppSettings;
import java.io.File;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.animation.AnimChannel;
import com.jme3.animation.AnimControl;
import com.jme3.animation.AnimEventListener;
import com.jme3.animation.LoopMode;
import com.jme3.app.SimpleApplication;
import com.jme3.asset.BlenderKey;
import com.jme3.asset.plugins.HttpZipLocator;
import com.jme3.asset.plugins.ZipLocator;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
import com.jme3.bullet.control.BetterCharacterControl;
import com.jme3.bullet.control.CharacterControl;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.input.ChaseCamera;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.AmbientLight;
import com.jme3.light.DirectionalLight;
import com.jme3.material.MaterialList;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.post.FilterPostProcessor;
import com.jme3.post.filters.BloomFilter;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.plugins.ogre.OgreMeshKey;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.input.MouseInput;
public class PyramidLevel extends SimpleApplication implements ActionListener,
AnimEventListener {
private Node gameLevel;
private static boolean useHttp = false;
private BulletAppState bulletAppState;
private AnimChannel channel;
private AnimControl control;
// character
private BetterCharacterControl goblinControl;
private BetterCharacterControl ninjaControl;
private Node ninjaNode;
boolean rotate = false;
private Vector3f walkDirection = new Vector3f(0, 0, 0);
private Vector3f viewDirection = new Vector3f(1, 0, 0);
private boolean leftStrafe = false, rightStrafe = false, forward = false,
backward = false, leftRotate = false, rightRotate = false;
private Node goblinNode;
Spatial goblin;
RigidBodyControl terrainPhysicsNode;
// animation
AnimChannel animationChannel;
AnimChannel shootingChannel;
AnimControl animationControl;
float airTime = 0;
// camera
private boolean left = false, right = false, up = false, down = false,
attack = false;
ChaseCamera chaseCam;
private boolean walkMode = true;
FilterPostProcessor fpp;
private Spatial sceneModel;
private RigidBodyControl landscape;
public static void main(String[] args) {
File file = new File("quake3level.zip");
if (!file.exists()) {
useHttp = true;
}
PyramidLevel app = new PyramidLevel();
AppSettings settings = new AppSettings(true);
settings.setTitle("Dungeon World");
settings.setSettingsDialogImage("Interface/splash.png");
app.setSettings(settings);
app.start();
}
#Override
public void simpleInitApp() {
this.setDisplayStatView(false);
bulletAppState = new BulletAppState();
bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL);
stateManager.attach(bulletAppState);
bulletAppState.setDebugEnabled(false);
setupKeys();
DirectionalLight dl = new DirectionalLight();
dl.setColor(ColorRGBA.White.clone().multLocal(2));
dl.setDirection(new Vector3f(-1, -1, -1).normalize());
rootNode.addLight(dl);
AmbientLight am = new AmbientLight();
am.setColor(ColorRGBA.White.mult(2));
rootNode.addLight(am);
if (useHttp) {
assetManager
.registerLocator(
"http://jmonkeyengine.googlecode.com/files/quake3level.zip",
HttpZipLocator.class);
} else {
assetManager.registerLocator("quake3level.zip", ZipLocator.class);
}
// create the geometry and attach it
MaterialList matList = (MaterialList) assetManager
.loadAsset("Scene.material");
OgreMeshKey key = new OgreMeshKey("main.meshxml", matList);
gameLevel = (Node) assetManager.loadAsset(key);
gameLevel.setLocalScale(0.1f);
gameLevel.addControl(new RigidBodyControl(0));
getPhysicsSpace().addAll(gameLevel);
rootNode.attachChild(gameLevel);
getPhysicsSpace().addAll(gameLevel);
createCharacters();
setupAnimationController();
setupChaseCamera();
setupFilter();
}
private void setupFilter() {
FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
BloomFilter bloom = new BloomFilter(BloomFilter.GlowMode.Objects);
fpp.addFilter(bloom);
viewPort.addProcessor(fpp);
}
private PhysicsSpace getPhysicsSpace() {
return bulletAppState.getPhysicsSpace();
}
private void setupKeys() {
inputManager.addMapping("wireframe", new KeyTrigger(KeyInput.KEY_T));
inputManager.addListener(this, "wireframe");
inputManager.addMapping("CharLeft", new KeyTrigger(KeyInput.KEY_A));
inputManager.addMapping("CharRight", new KeyTrigger(KeyInput.KEY_D));
inputManager.addMapping("CharUp", new KeyTrigger(KeyInput.KEY_W));
inputManager.addMapping("CharDown", new KeyTrigger(KeyInput.KEY_S));
inputManager
.addMapping("CharSpace", new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addMapping("CharShoot", new MouseButtonTrigger(
MouseInput.BUTTON_LEFT));
inputManager.addListener(this, "CharLeft");
inputManager.addListener(this, "CharRight");
inputManager.addListener(this, "CharUp");
inputManager.addListener(this, "CharDown");
inputManager.addListener(this, "CharSpace");
inputManager.addListener(this, "CharShoot");
}
private void createNinja() {
ninjaNode = (Node) assetManager
.loadModel("Models/Ninja/Ninja.mesh.xml");
ninjaNode.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
ninjaNode.setLocalScale(0.06f);
ninjaNode.setLocalTranslation(new Vector3f(55, 3.3f, -60));
ninjaControl = new BetterCharacterControl(2, 4, 0.5f);
ninjaControl.setJumpForce(new Vector3f(6, 6, 6));
ninjaNode.addControl(ninjaControl);
rootNode.attachChild(ninjaNode);
bulletAppState.getPhysicsSpace().add(ninjaControl);
getPhysicsSpace().add(ninjaControl);
animationControl = ninjaNode.getControl(AnimControl.class);
animationChannel = animationControl.createChannel();
}
private void createGoblin() {
goblinNode = (Node) assetManager
.loadModel("objects/goblin.j3o");
goblinNode.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
goblinNode.setLocalScale(4f);
goblinNode.setLocalTranslation(new Vector3f(51.5f, 3.3f, -60));
goblinControl = new BetterCharacterControl(2, 4, 0.5f);
goblinControl.setJumpForce(new Vector3f(6, 6, 6));
goblinNode.addControl(goblinControl);
rootNode.attachChild(goblinNode);
bulletAppState.getPhysicsSpace().add(goblinControl);
getPhysicsSpace().add(goblinControl);
animationControl = goblinNode.getControl(AnimControl.class);
animationChannel = animationControl.createChannel();
}
private void createCharacters() {
CapsuleCollisionShape capsule = new CapsuleCollisionShape(0.05f, 0.05f);
createNinja();
ninjaControl.setViewDirection(new Vector3f(0, 0, 1));
//getPhysicsSpace().add(ninjaControl);
createGoblin();
BlenderKey blenderKey = new BlenderKey("Models/Oto/Oto.mesh.xml");
Spatial man = (Spatial) assetManager.loadModel(blenderKey);
man.setLocalTranslation(new Vector3f(69, 15, -60));
man.setShadowMode(ShadowMode.CastAndReceive);
rootNode.attachChild(man);
//goblin = assetManager.loadModel("objects/goblin.j3o");
//goblin.scale(4f, 4f, 4f);
//goblinControl = new BetterCharacterControl(2,3,0.5f);
//goblin.addControl(goblinControl);
//goblinControl.setPhysicsLocation(new Vector3f(60, 3.5f, -60));
//goblin.setLocalTranslation(new Vector3f(150,70.5f, -5));
//control = goblin.getControl(AnimControl.class);
//control.addListener(this);
//channel = control.createChannel();
// for (String anim : control.getAnimationNames())
// System.out.println("goblin can:"+anim);
//channel.setAnim("walk");
//goblin.setLocalTranslation(new Vector3f(51.5f, 3, -55));
//rootNode.attachChild(goblin);
//getPhysicsSpace().add(goblinControl);
Spatial monster = assetManager
.loadModel("objects/creatures/monster/monster.packed.j3o");
Spatial monster2 = assetManager.loadModel("Models/Jaime/Jaime.j3o");
monster2.scale(5f, 5f, 5f);
monster.scale(2f, 2f, 2f);
monster.setLocalTranslation(new Vector3f(53, 3, -55));
monster2.setLocalTranslation(new Vector3f(48, 3, -55));
rootNode.attachChild(monster2);
rootNode.attachChild(monster);
}
private void setupChaseCamera() {
flyCam.setEnabled(false);
chaseCam = new ChaseCamera(cam, ninjaNode, inputManager);
chaseCam.setDefaultDistance(37);
}
private void setupAnimationController() {
animationControl = ninjaNode.getControl(AnimControl.class);
animationControl.addListener(this);
animationChannel = animationControl.createChannel();
}
#Override
public void simpleUpdate(float tpf) {
//goblinControl.setWalkDirection(goblin.getLocalRotation()
// .mult(Vector3f.UNIT_Z).multLocal(0.4f));
Vector3f camDir = cam.getDirection().clone().multLocal(8f);
Vector3f camLeft = cam.getLeft().clone().multLocal(8f);
camDir.y = 0;
camLeft.y = 0;
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());
}
// if (attack) {
// animationChannel.setAnim("Attack1");
// animationChannel.setLoopMode(LoopMode.DontLoop);
// }
if (!ninjaControl.isOnGround()) {
airTime = airTime + tpf;
} else {
airTime = 0;
}
if (walkDirection.length() == 0) {
if (!"Idle1".equals(animationChannel.getAnimationName())) {
animationChannel.setAnim("Idle1", 1f);
}
} else {
ninjaControl.setViewDirection(walkDirection.negate());
if (airTime > .3f) {
if (!"stand".equals(animationChannel.getAnimationName())) {
animationChannel.setAnim("Idle1");
}
} else if (!"Walk".equals(animationChannel.getAnimationName())) {
animationChannel.setAnim("Walk", 1f);
}
}
ninjaControl.setWalkDirection(walkDirection);
}
/*
* Ninja can: Walk Ninja can: Kick Ninja can: JumpNoHeight Ninja can: Jump
* Ninja can: Spin Ninja can: Attack1 Ninja can: Idle1 Ninja can: Attack3
* Ninja can: Idle2 Ninja can: Attack2 Ninja can: Idle3 Ninja can: Stealth
* Ninja can: Death2 Ninja can: Death1 Ninja can: HighJump Ninja can:
* SideKick Ninja can: Backflip Ninja can: Block Ninja can: Climb Ninja can:
* Crouch
*/
public void onAction(String binding, boolean value, float tpf) {
if (binding.equals("CharLeft")) {
if (value) {
left = true;
} else {
left = false;
}
} else if (binding.equals("CharRight")) {
if (value) {
right = true;
} else {
right = false;
}
} else if (binding.equals("CharUp")) {
if (value) {
up = true;
} else {
up = false;
}
} else if (binding.equals("CharDown")) {
if (value) {
down = true;
} else {
down = false;
}
} else if (binding.equals("CharSpace")) {
// character.jump();
ninjaControl.jump();
} else if (binding.equals("CharShoot") && value) {
// bulletControl();
Vector3f origin = cam.getWorldCoordinates(
inputManager.getCursorPosition(), 0.0f);
Vector3f direction = cam.getWorldCoordinates(
inputManager.getCursorPosition(), 0.0f);
// direction.subtractLocal(origin).normalizeLocal();
// character.setWalkDirection(location);
System.out.println("origin" + origin);
System.out.println("direction" + direction);
// character.setViewDirection(direction);
animationChannel.setAnim("Attack3");
animationChannel.setLoopMode(LoopMode.DontLoop);
}
}
public void onAnimCycleDone(AnimControl control, AnimChannel channel,
String animName) {
if (channel == shootingChannel) {
channel.setAnim("Idle1");
}
}
public void onAnimChange(AnimControl control, AnimChannel channel,
String animName) {
}
public Node getGameLevel() {
return gameLevel;
}
public void setGameLevel(Node gameLevel) {
this.gameLevel = gameLevel;
}
public static boolean isUseHttp() {
return useHttp;
}
public static void setUseHttp(boolean useHttp) {
PyramidLevel.useHttp = useHttp;
}
public BulletAppState getBulletAppState() {
return bulletAppState;
}
public void setBulletAppState(BulletAppState bulletAppState) {
this.bulletAppState = bulletAppState;
}
public AnimChannel getChannel() {
return channel;
}
public void setChannel(AnimChannel channel) {
this.channel = channel;
}
public AnimControl getControl() {
return control;
}
public void setControl(AnimControl control) {
this.control = control;
}
public BetterCharacterControl getGoblincharacter() {
return goblinControl;
}
public void setGoblincharacter(BetterCharacterControl goblincharacter) {
this.goblinControl = goblincharacter;
}
public BetterCharacterControl getCharacterControl() {
return ninjaControl;
}
public void setCharacterControl(BetterCharacterControl characterControl) {
this.ninjaControl = characterControl;
}
public Node getCharacterNode() {
return ninjaNode;
}
public void setCharacterNode(Node characterNode) {
this.ninjaNode = characterNode;
}
public boolean isRotate() {
return rotate;
}
public void setRotate(boolean rotate) {
this.rotate = rotate;
}
public Vector3f getWalkDirection() {
return walkDirection;
}
public void setWalkDirection(Vector3f walkDirection) {
this.walkDirection = walkDirection;
}
public Vector3f getViewDirection() {
return viewDirection;
}
public void setViewDirection(Vector3f viewDirection) {
this.viewDirection = viewDirection;
}
public boolean isLeftStrafe() {
return leftStrafe;
}
public void setLeftStrafe(boolean leftStrafe) {
this.leftStrafe = leftStrafe;
}
public boolean isRightStrafe() {
return rightStrafe;
}
public void setRightStrafe(boolean rightStrafe) {
this.rightStrafe = rightStrafe;
}
public boolean isForward() {
return forward;
}
public void setForward(boolean forward) {
this.forward = forward;
}
public boolean isBackward() {
return backward;
}
public void setBackward(boolean backward) {
this.backward = backward;
}
public boolean isLeftRotate() {
return leftRotate;
}
public void setLeftRotate(boolean leftRotate) {
this.leftRotate = leftRotate;
}
public boolean isRightRotate() {
return rightRotate;
}
public void setRightRotate(boolean rightRotate) {
this.rightRotate = rightRotate;
}
public Node getModel() {
return goblinNode;
}
public void setModel(Node model) {
this.goblinNode = model;
}
public Spatial getGoblin() {
return goblin;
}
public void setGoblin(Spatial goblin) {
this.goblin = goblin;
}
public RigidBodyControl getTerrainPhysicsNode() {
return terrainPhysicsNode;
}
public void setTerrainPhysicsNode(RigidBodyControl terrainPhysicsNode) {
this.terrainPhysicsNode = terrainPhysicsNode;
}
public AnimChannel getAnimationChannel() {
return animationChannel;
}
public void setAnimationChannel(AnimChannel animationChannel) {
this.animationChannel = animationChannel;
}
public AnimChannel getShootingChannel() {
return shootingChannel;
}
public void setShootingChannel(AnimChannel shootingChannel) {
this.shootingChannel = shootingChannel;
}
public AnimControl getAnimationControl() {
return animationControl;
}
public void setAnimationControl(AnimControl animationControl) {
this.animationControl = animationControl;
}
public float getAirTime() {
return airTime;
}
public void setAirTime(float airTime) {
this.airTime = airTime;
}
public boolean isLeft() {
return left;
}
public void setLeft(boolean left) {
this.left = left;
}
public boolean isRight() {
return right;
}
public void setRight(boolean right) {
this.right = right;
}
public boolean isUp() {
return up;
}
public void setUp(boolean up) {
this.up = up;
}
public boolean isDown() {
return down;
}
public void setDown(boolean down) {
this.down = down;
}
public boolean isAttack() {
return attack;
}
public void setAttack(boolean attack) {
this.attack = attack;
}
public ChaseCamera getChaseCam() {
return chaseCam;
}
public void setChaseCam(ChaseCamera chaseCam) {
this.chaseCam = chaseCam;
}
public boolean isWalkMode() {
return walkMode;
}
public void setWalkMode(boolean walkMode) {
this.walkMode = walkMode;
}
public FilterPostProcessor getFpp() {
return fpp;
}
public void setFpp(FilterPostProcessor fpp) {
this.fpp = fpp;
}
public Spatial getSceneModel() {
return sceneModel;
}
public void setSceneModel(Spatial sceneModel) {
this.sceneModel = sceneModel;
}
public RigidBodyControl getLandscape() {
return landscape;
}
public void setLandscape(RigidBodyControl landscape) {
this.landscape = landscape;
}
}
You can download a demo of my game but how do I improve the walking?
Update
My followup at the jmonkeyforum also had 0 replies.
To do this you change the value of the max slope:
setMaxSlope()
From the jmonkey site:
"How steep the slopes and steps are that the character can climb without considering them
an obstacle. Higher obstacles need to be jumped. Vertical height in world units."
Reading this I believe it works in a way similar to, when moving 1 unit in the world what is the maximum change in height a character can experience. If you set this to the size of the steps (or a larger by <1 for safety) you'r character should be able to walk up steps
Sources:
http://hub.jmonkeyengine.org/wiki/doku.php/jme3:advanced:walking_character#charactercontrol
Developing for Jmonkey before
Related
I can not solve the problem in question. I tried several solutions to this error but without any positive result. If i try to remove glCreateProgram() method the error move to glCreateShader() method.
Error
Exception in thread "main" java.lang.ExceptionInInitializerError
Caused by: java.lang.IllegalStateException: No GLCapabilities instance set for the current thread. Possible solutions:
a) Call GL.createCapabilities() after making a context current in the current thread.
b) Call GL.setCapabilities() if a GLCapabilities instance already exists for the current context.
at org.lwjgl.opengl.GL.getCapabilities(GL.java:238)
at org.lwjgl.opengl.GL20.glCreateProgram(GL20.java:209)
at ms.shaders.ShaderProgram.<init>(ShaderProgram.java:18)
at ms.shaders.Shaders.<init>(Shaders.java:8)
at ms.renderer.Renderer.<init>(Renderer.java:13)
at ms.main.MainGame.<clinit>(MainGame.java:16)
ShaderProgram
package ms.shaders;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL20.*;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public abstract class ShaderProgram {
private int programID;
private int vShaderID;
private int fShaderID;
public ShaderProgram(String vShader, String fShader) {
programID = glCreateProgram(); //Error line
String vertexShaderSource = loadShader(vShader);
vShaderID = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vShaderID, vertexShaderSource);
glCompileShader(vShaderID);
if (glGetShaderi(vShaderID, GL_COMPILE_STATUS) == GL_FALSE) {
throw new RuntimeException("Error creating vertex shader\n"
+ glGetShaderInfoLog(vShaderID, glGetShaderi(vShaderID, GL_INFO_LOG_LENGTH)));
}
glAttachShader(programID, vShaderID);
String fragmentShaderSource = loadShader(vShader);
fShaderID = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fShaderID, fragmentShaderSource);
glCompileShader(fShaderID);
if (glGetShaderi(fShaderID, GL_COMPILE_STATUS) == GL_FALSE) {
throw new RuntimeException("Error creating vertex shader\n"
+ glGetShaderInfoLog(fShaderID, glGetShaderi(fShaderID, GL_INFO_LOG_LENGTH)));
}
glAttachShader(programID, vShaderID);
}
protected abstract void bindAttribute();
protected void bindAttribute(int attribute, String name) {
glBindAttribLocation(programID, attribute, name);
}
public void link() {
glLinkProgram(programID);
if(glGetProgrami(programID, GL_LINK_STATUS) == GL_FALSE) {
throw new RuntimeException("Failed to link program: ");
}
}
public void validate() {
glValidateProgram(programID);
if(glGetShaderi(programID, GL_VALIDATE_STATUS) == GL_FALSE) {
throw new RuntimeException("Failed to validate program: ");
}
}
public void bind() {
glUseProgram(programID);
}
public void unbind() {
glUseProgram(0);
}
public void dispose() {
unbind();
glDetachShader(programID, vShaderID);
glDetachShader(programID, fShaderID);
glDeleteShader(vShaderID);
glDeleteShader(fShaderID);
glDeleteProgram(programID);
}
private static String loadShader(String file) {
StringBuilder shaderSource = new StringBuilder();
try {
BufferedReader reader = new BufferedReader(new FileReader(file));
String line;
while((line = reader.readLine()) != null) {
shaderSource.append(line).append("//\n");
}
reader.close();
} catch(IOException e){
e.printStackTrace();
System.exit(-1);
}
return shaderSource.toString();
}
}
Renderer
package ms.renderer;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL30.*;
import ms.renderer.VertexArrayObject.Vertex;
import ms.shaders.Shaders;
public class Renderer {
VertexArrayObject vertex = new VertexArrayObject();
Shaders shaders = new Shaders();
public void prepare() {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
}
public void render(Vertex vertex) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
shaders.bind();
glBindVertexArray(vertex.getVaoID());
glEnableVertexAttribArray(0);
glDrawElements(GL_TRIANGLES, vertex.getVertexCount(), GL_UNSIGNED_INT, 0);
glDisableVertexAttribArray(0);
glBindVertexArray(0);
shaders.unbind();
}
public void clear() {
shaders.dispose();
vertex.cleanUp();
}
}
MainGame
package ms.main;
import static org.lwjgl.glfw.GLFW.*;
import ms.input.KeyboardInput;
import ms.renderer.Renderer;
import ms.renderer.VertexArrayObject;
import ms.renderer.VertexArrayObject.Vertex;
import ms.utils.FinalVariables;
public class MainGame implements Runnable {
private Thread thread;
private static Display display = new Display();
private static Renderer renderer = new Renderer();
private static VertexArrayObject loader = new VertexArrayObject();
private static int WIDTH = FinalVariables.WIDTH;
private static int HEIGHT = FinalVariables.HEIGHT;
private static String TITLE = FinalVariables.TITLE;
private boolean isRunning = false;
public static void main(String[] args) {
MainGame game = new MainGame();
display = new Display(WIDTH, HEIGHT, TITLE);
game.start();
}
public void start() {
isRunning = true;
thread = new Thread(this, "MainThread");
thread.start();
}
public void run() {
display.init();
display.libVersion();
float[] positions = new float[]{
-0.5f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.5f, 0.5f, 0.0f,
};
int[] indices = new int[]{
0, 1, 3, 3, 1, 2
};
Vertex vertex = loader.loadToVAO(positions, indices);
while(isRunning) {
update();
renderer.prepare();
renderer.render(vertex);
if(glfwWindowShouldClose(display.window)) {
isRunning = false;
}
}
renderer.clear();
}
public void update() {
if(KeyboardInput.isKeyDown(GLFW_KEY_ESCAPE)) {
isRunning = false;
}
glfwSwapBuffers(display.window);
glfwPollEvents();
}
}
Display Where i call createCapabilities method
package ms.main;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryUtil.*;
import org.lwjgl.glfw.GLFWKeyCallback;
import org.lwjgl.glfw.GLFWVidMode;
import ms.input.KeyboardInput;
public class Display {
#SuppressWarnings("unused")
private GLFWKeyCallback keyCallback;
private int width;
private int height;
private String title;
public long window;
public Display() {
}
public Display(int width, int height, String title) {
this.width = width;
this.height = height;
this.title = title;
}
public void init() {
glfwInit();
if(!glfwInit()) {
System.err.println("Failed to initialize GLFW");
}
glfwDefaultWindowHints();
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
glfwWindowHint(GLFW_VISIBLE, GL_TRUE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
window = glfwCreateWindow(width, height, title, NULL, NULL);
if(window == NULL) {
System.err.println("Failed to create Window");
}
keyCallback = glfwSetKeyCallback(window, keyCallback = new KeyboardInput());
GLFWVidMode vidMode = glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwSetWindowPos(window,
(vidMode.width() - width) / 2,
(vidMode.height() - height) / 2);
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
glfwShowWindow(window);
createCapabilities();
}
public void libVersion() {
System.out.println("LWJGL Version: " + glfwGetVersionString());
System.out.println("OpenGL Version: " + glGetString(GL_VERSION));
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
The problem I think is in the createCapabilities() method position but I do not know how to solve.
State that I am a beginner and I'm getting closer now to the creation of video games.
Thanks in advance for any solutions.
I am unable to run my program. The app gets crashed. I am trying to make the image move on the screen by touchEvent.
java.lang.NullPointerException: Attempt to invoke virtual method 'int com.example.swapnil.new1.model.conmponents.Speed.getxDirection()' on a null object reference
at com.example.swapnil.new1.GamePanel.update(GamePanel.java:89)
at com.example.swapnil.new1.MainThread.run(MainThread.java:32)
I have added the Speed class which I think is responsible for this exception. Suggest any updates.
Speed class has the getxDirection method which is causing the exception.
package com.example.swapnil.new1.model.conmponents;
public class Speed {
public static final int DIRECTION_RIGHT = 1;
public static final int DIRECTION_LEFT = -1;
public static final int DIRECTION_UP = -1;
public static final int DIRECTION_DOWN = 1;
private float xv = 1; // speed in x
private float yv = 1; // speed in y
private int xDirection = DIRECTION_RIGHT;
private int yDirection = DIRECTION_DOWN;
public Speed() {
this.xv = 1;
this.yv = 1;
}
public Speed(float xv, float yv) {
this.xv = xv;
this.yv = yv;
}
public float getXv() {
return xv;
}
public void setXv(float xv) {
this.xv = xv;
}
public float getYv() {
return yv;
}
public void setYv(float yv) {
this.yv = yv;
}
public int getxDirection() {
return xDirection;
}
public void setxDirection(int xDirection) {
this.xDirection = xDirection;
}
public int getyDirection() {
return yDirection;
}
public void setyDirection(int yDirection) {
this.yDirection = yDirection;
}
public void toggleXDirection() {
xDirection = xDirection * -1;
}
public void toggleYDirection() {
yDirection = yDirection * -1;
}
}
The MainThread class:
package com.example.swapnil.new1;
import android.graphics.Canvas;
import android.util.Log;
import android.view.SurfaceHolder;
public class MainThread extends Thread {
private static final String TAG = MainThread.class.getSimpleName();
private boolean running;
private SurfaceHolder surfaceHolder;
private GamePanel gamePanel;
public MainThread(SurfaceHolder surfaceHolder , GamePanel gamePanel) {
super();
this.surfaceHolder = surfaceHolder;
this.gamePanel = gamePanel;
}
public void setRunning(boolean running) {
this.running = running;
}
#Override
public void run() {
Canvas canvas;
Log.d(TAG , "Starting game loop");
while(running) {
canvas = null;
try {
canvas = this.surfaceHolder.lockCanvas();
synchronized (surfaceHolder) {
this.gamePanel.render(canvas);
this.gamePanel.update();
}
} finally {
if(canvas != null) {
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
}
The GamePanel class:
import android.app.Activity;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import com.example.swapnil.new1.model.Droid;
import com.example.swapnil.new1.model.conmponents.Speed;
public class GamePanel extends SurfaceView implements
SurfaceHolder.Callback {
private static final String TAG = GamePanel.class.getSimpleName();
private MainThread thread;
private Droid droid;
public GamePanel(Context context) {
super(context);
getHolder().addCallback(this);
droid = new Droid(BitmapFactory.decodeResource(getResources(),R.drawable.droid_1),50,50);
thread = new MainThread(getHolder() , this);
setFocusable(true);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
thread.setRunning(true);
thread.start();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
while (retry) {
try {
thread.join();
retry = false;
}catch (InterruptedException e) {
}
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
droid.handleActionDown((int)event.getX(),(int)event.getY());
if (event.getY() > getHeight() - 50) {
thread.setRunning(false);
((Activity)getContext()).finish();
} else {
Log.d(TAG , "Coords : x = " + event.getX() + ",y = " + event.getY());
}
}
if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (droid.isTouched()) {
droid.setX((int)event.getX());
droid.setY((int) event.getY());
}
}
if (event.getAction() == MotionEvent.ACTION_UP) {
if (droid.isTouched()) {
droid.setTouched(false);
}
}
return true;
}
// changed protected to public
protected void render(Canvas canvas) {
canvas.drawColor(Color.BLACK);
droid.draw(canvas);
}
public void update() {
// collision with right
if (droid.getSpeed().getxDirection() == Speed.DIRECTION_RIGHT &&
droid.getX() + droid.getBitmap().getWidth()/2 >= getWidth()) {
droid.getSpeed().toggleXDirection();
}
//collision with left
if (droid.getSpeed().getxDirection() == Speed.DIRECTION_LEFT &&
droid.getX() - droid.getBitmap().getWidth()/2 <= 0) {
droid.getSpeed().toggleXDirection();
}
// collision with down
if (droid.getSpeed().getyDirection() == Speed.DIRECTION_DOWN &&
droid.getY() + droid.getBitmap().getHeight()/2 >= getHeight()) {
droid.getSpeed().toggleYDirection();
}
//collision with up
if (droid.getSpeed().getyDirection() == Speed.DIRECTION_UP &&
droid.getY() - droid.getBitmap().getHeight()/2 <= 0) {
droid.getSpeed().toggleYDirection();
}
droid.update();
}
}
Speed field in your Droid object is not set. In your GamePanel.update() method you are invoking getxDirection on this field and that cause NullPointerException.
can someone give me sample of code that will rotate my player please? I want achieve same control like in classical fps (w,a,s,d + mouse). Something with FlyByCamera but i don't know how to add it. Code is without errors. Thanks.
here are methods that are related to control
public class Main extends SimpleApplication
implements ActionListener {
private Spatial platforms[];
private Spatial trees[];
private Node sceneNode;
private Node playerNode;
private Node platformNode;
private Node treeNode;
private CameraNode camNode;
private BulletAppState bullet;
private RigidBodyControl scenePhysics;
private BetterCharacterControl player;
private Vector3f walkDir = new Vector3f(0, 0, 0);
private Vector3f viewDir = new Vector3f(0, 0, 1);
private boolean rotateLeft = false, rotateRight = false, forward = false,
backward = false, strafeLeft = false, strafeRight = false;
private float moveSpeed = 70;
public static void main(String[] args) {
Main app = new Main();
AppSettings settings = new AppSettings(true);
app.setSettings(settings);
settings.setTitle(“RUSHY”);
settings.setSettingsDialogImage(“Interface/intro.png”);
app.start();
}
public void simpleInitApp() {
bullet = new BulletAppState();
stateManager.attach(bullet);
setUpKeys();
scenePhysics = new RigidBodyControl(0f);
sceneNode.addControl(scenePhysics);
bullet.getPhysicsSpace().add(sceneNode);
rootNode.attachChild(sceneNode);
bullet.getPhysicsSpace().setGravity(new Vector3f(0, -50.0f, 0));
bullet.getPhysicsSpace().setAccuracy(0.016f);
playerNode = new Node(“player”);
playerNode.setLocalTranslation(new Vector3f(0, 10, 0)); //spawn position
rootNode.attachChild(playerNode);
player = new BetterCharacterControl(1.5f, 7f, 30f);
player.setJumpForce(new Vector3f(0, 1200f, 0));
player.setGravity(new Vector3f(0.0f, -10.0f, 0.0f));
playerNode.addControl(player);
bullet.getPhysicsSpace().add(player);
}
private void setUpKeys() {
inputManager.addMapping(“Forward”,
new KeyTrigger(KeyInput.KEY_W));
inputManager.addMapping(“Backward”,
new KeyTrigger(KeyInput.KEY_S));
inputManager.addMapping(“Rotate Left”,
new KeyTrigger(KeyInput.KEY_A));
inputManager.addMapping(“Rotate Right”,
new KeyTrigger(KeyInput.KEY_D));
inputManager.addMapping(“Strafe Right”,
new KeyTrigger(KeyInput.KEY_E));
inputManager.addMapping(“Strafe Left”,
new KeyTrigger(KeyInput.KEY_Q));
inputManager.addMapping(“Jump”,
new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addListener(this, “Rotate Left”, “Rotate Right”,
“Strafe Right”, “Strafe Left”, “Forward”, “Backward”, “Jump”);
}
public void onAction(String binding, boolean isPressed, float tpf) {
if (binding.equals(“Rotate Left”)) {
rotateLeft = isPressed;
} else if (binding.equals(“Rotate Right”)) {
rotateRight = isPressed;
} else if (binding.equals(“Strafe Left”)) {
strafeLeft = isPressed;
} else if (binding.equals(“Strafe Right”)) {
strafeRight = isPressed;
} else if (binding.equals(“Forward”)) {
forward = isPressed;
} else if (binding.equals(“Backward”)) {
backward = isPressed;
} else if (binding.equals(“Jump”)) {
player.jump();
}
}
#Override
public void simpleUpdate(float tpf) {
camNode = new CameraNode(“CamNode”, cam);
camNode.setControlDir(CameraControl.ControlDirection.SpatialToCamera);
camNode.setLocalTranslation(new Vector3f(0, 6, 0));
Quaternion quat = new Quaternion();
quat.lookAt(Vector3f.UNIT_Z, Vector3f.UNIT_Y);
camNode.setLocalRotation(quat);
playerNode.attachChild(camNode);
camNode.setEnabled(true);
Vector3f modelForwardDir = playerNode.getWorldRotation().mult(Vector3f.UNIT_Z);
Vector3f modelLeftDir = playerNode.getWorldRotation().mult(Vector3f.UNIT_X);
walkDir.set(0, 0, 0);
if (forward) {
walkDir.addLocal(modelForwardDir.mult(moveSpeed));
} else if (backward) {
walkDir.addLocal(modelForwardDir.mult(moveSpeed).
negate());
} else if (strafeLeft) {
walkDir.addLocal(modelLeftDir.mult(moveSpeed));
} else if (strafeRight) {
walkDir.addLocal(modelLeftDir.mult(moveSpeed).negate());
}
player.setWalkDirection(walkDir); // walk
if (rotateLeft) {
Quaternion rotateL = new Quaternion().
fromAngleAxis(FastMath.PI * tpf, Vector3f.UNIT_Y);
rotateL.multLocal(viewDir);
} else if (rotateRight) {
Quaternion rotateR = new Quaternion().
fromAngleAxis(-FastMath.PI * tpf, Vector3f.UNIT_Y);
rotateR.multLocal(viewDir);
}
player.setViewDirection(viewDir); // turn
}
}
Can you try something like the methods from an example:
private BulletAppState bulletAppState;
private Node gameLevel;
private PhysicsCharacter player;
private Vector3f walkDirection = new Vector3f();
private boolean left=false,right=false,up=false,down=false;
#Override
public void simpleUpdate(float tpf) {
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());
}
private void setupKeys() {
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("Space", new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addListener(this,"Lefts");
inputManager.addListener(this,"Rights");
inputManager.addListener(this,"Ups");
inputManager.addListener(this,"Downs");
inputManager.addListener(this,"Space");
}
public void onAction(String binding, boolean value, float tpf) {
if (binding.equals("Lefts")) {
if(value)
left=true;
else
left=false;
} else if (binding.equals("Rights")) {
if(value)
right=true;
else
right=false;
} else if (binding.equals("Ups")) {
if(value)
up=true;
else
up=false;
} else if (binding.equals("Downs")) {
if(value)
down=true;
else
down=false;
} else if (binding.equals("Space")) {
player.jump();
}
}
I'm making a game for a school project and have been stuck on this part for a few days. How would I go about restarting the following applet? I have tried to make a restart() method, but lack the necessary skills.
package main;
import game.framework.Animation;
import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.lang.Thread.State;
import java.net.URL;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JPanel;
//add speedboost
public class Main extends Applet implements Runnable, KeyListener{
enum GameState {
Running, Dead
}
static GameState state = GameState.Running;
private Background bg2, bg1;
private boolean restart = false;
private Player player;
private SpeedBoost sb1;
private Image image;
private Image backsprite1, backsprite2;
private Image player1, dad1, dad2, dad3;
private Image player2;
private Image player3;
private Image back1;
private Image back2, endscreen;
private Image back3, coin, bigcoin;
private Image back4, sbimg;
public Image tilebase, platform;
private Block block1, block2, block3, block4;
private Coin coin1, coin2, coin3, coin4, coin5;
private LargeCoin bc1;
//use for the base...
private Dad dad;
private Graphics second;
private Animation playwalk, dadwalk;
private URL base;
private Platform plat1, plat2, plat3, plat4, plat5, plat6, plat7;
public static int score = 1, coinsint = 1;
public static String score2, coins = "1";
public static int scorespeed = 1;
public int hs1, hs2, hs3, hs4, hs5, totcoins;
public String hs1s, hs2s, hs3s, hs4s, hs5s, totcoinss;
public Ends ends;
#Override
public void init() {
setSize(800, 480);
setBackground(Color.WHITE);
setFocusable(true);
addKeyListener(this);
Frame frame = (Frame) this.getParent().getParent();
frame.setTitle("Game v1.2.2");
try {
base = getDocumentBase();
} catch (Exception e) {
// TODO: handle exception
}
endscreen = getImage(base, "data/endscreen.png");
coin = getImage(base, "data/coin.png");
bigcoin = getImage(base, "data/bigcoin.png");
tilebase = getImage(base, "data/tilebase.png");
platform = getImage(base, "data/blocksmall.png");
back1 = getImage(base, "data/back1.png");
back2 = getImage(base, "data/back2.png");
back3 = getImage(base, "data/back3.png");
back4 = getImage(base, "data/back4.png");`enter code here`
sbimg = getImage(base, "data/speedboost.png");
player1 = getImage(base, "data/player1.png");
player2 = getImage(base, "data/player2.png");
player3 = getImage(base, "data/player3.png");
dad1 = getImage(base, "data/dad1.png");
dad2 = getImage(base, "data/dad2.png");
dad3 = getImage(base, "data/dad3.png");
backsprite1 = back1;
backsprite2 = back2;
playwalk = new Animation();
playwalk.addFrame(player1, 80);
playwalk.addFrame(player2, 80);
playwalk.addFrame(player3, 80);
dadwalk = new Animation();
dadwalk.addFrame(dad1, 80);
dadwalk.addFrame(dad2, 80);
dadwalk.addFrame(dad3, 80);
}
public void animate() {
playwalk.update(15);
dadwalk.update(15);
}
#Override
public void start() {
state = state.Running;
ends = new Ends(-3, 0);
//create objects at positions
coin1 = new Coin(-100, -10);
coin2 = new Coin(-10, -10);
coin3 = new Coin(-10, -10);
coin4 = new Coin(-10, -10);
coin5 = new Coin(-10, -10);
player = new Player();
dad = new Dad();
bg1 = new Background(1, 0);
bg2 = new Background(2099, 0);
plat1 = new Platform(0,0);
plat2 = new Platform(-100,0);
plat3 = new Platform(-200,0);
plat4 = new Platform(-300,0);
plat5 = new Platform(-400,0);
plat6 = new Platform(-500,0);
plat7 = new Platform(-600,0);
sb1 = new SpeedBoost(-100, 0);
bc1 = new LargeCoin(-99, 0);
block1 = new Block(0, 0);
block2 = new Block(0, 0);
block3 = new Block(0, 0);
block4 = new Block(0, 0);
Thread thread = new Thread(this);
thread.start();
}
#Override
public void stop() {
// TODO Auto-generated method stub
}
#Override
public void destroy() {
// TODO Auto-generated method stub
}
#Override
public void run() {
if (state == GameState.Running) {
while (true) {
//selecting sprites for the background
//updates go here
if(bg1.getBgX() < -2100){
bg1.setBgX(2100);
}
if(bg2.getBgX() < -2100){
bg2.setBgX(2100);
}
//backgrounds arent working
if(bg1.getBgX() > 2000){
Random rand = new Random();
int nel = rand.nextInt(4) + 1;
if(nel == 1){
backsprite1 = back1;
}if(nel == 2){
backsprite1 = back2;
}if(nel == 3){
backsprite1 = back3;
}if(nel == 4){
backsprite1 = back4;
}
}
if(bg2.getBgX() > 2000){
Random rand = new Random();
int n1 = rand.nextInt(4) + 1;
if(n1 == 1){
backsprite2 = back1;
}if(n1 == 2){
backsprite2 = back2;
}if(n1 == 3){
backsprite2 = back3;
}if(n1 == 4){
backsprite2 = back4;
}
}
block4.update();
block3.update();
block2.update();
block1.update();
sb1.update();
bc1.update();
player.update();
dad.update();
bg1.update();
bg2.update();
coin1.update();
coin2.update();
coin3.update();
coin4.update();
coin5.update();
plat1.update();
plat2.update();
plat3.update();
plat4.update();
plat5.update();
plat6.update();
plat7.update();
if(Block.lives < 0){
state = GameState.Dead;
}
animate();
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
#Override
public void update(Graphics g) {
if (image == null) {
image = createImage(this.getWidth(), this.getHeight());
second = image.getGraphics();
}
//other updates go here
block1.update();
block2.update();
block3.update();
block4.update();
sb1.update();
bc1.update();
coin1.update();
coin2.update();
coin3.update();
coin4.update();
coin5.update();
plat1.update();
plat2.update();
plat3.update();
plat4.update();
plat5.update();
plat6.update();
plat7.update();
bg1.update();
bg2.update();
player.update();
dad.update();
second.setColor(getBackground());
second.fillRect(0, 0, getWidth(), getHeight());
second.setColor(getForeground());
paint(second);
g.drawImage(image, 0, 0, this);
}
#Override
public void paint(Graphics g) {
if (state == GameState.Running) {
//main graphics identifyers here
// first are drawn below last
//need to make the platform lower down, see class for explanation
g.drawImage(backsprite1, bg1.getBgX(), bg1.getBgY(), this);
g.drawImage(backsprite2, bg2.getBgX(), bg2.getBgY(), this);
g.drawImage(playwalk.getImage(), player.getCenterX(), player.getCenterY(), this);
g.drawImage(platform, plat1.getCenterX(), plat1.getCenterY(), this);
g.drawImage(platform, plat2.getCenterX(), plat2.getCenterY(), this);
g.drawImage(platform, plat3.getCenterX(), plat3.getCenterY(), this);
g.drawImage(platform, plat4.getCenterX(), plat4.getCenterY(), this);
g.drawImage(platform, plat5.getCenterX(), plat5.getCenterY(), this);
g.drawImage(platform, plat6.getCenterX(), plat6.getCenterY(), this);
g.drawImage(platform, plat7.getCenterX(), plat7.getCenterY(), this);
g.drawImage(sbimg, sb1.getCenterX(), sb1.getCenterY(), this);
g.drawImage(bigcoin, bc1.centerX, bc1.centerY, this);
g.drawImage(dadwalk.getImage(), dad.centerX, dad.centerY, this);
g.drawImage(tilebase, block1.getCenterX(), block1.getCenterY(), this);
g.drawImage(tilebase, block2.getCenterX(), block2.getCenterY(), this);
g.drawImage(tilebase, block3.getCenterX(), block3.getCenterY(), this);
g.drawImage(tilebase, block4.getCenterX(), block4.getCenterY(), this);
g.drawImage(coin, coin1.getCenterX(), coin1.getCenterY(), this);
g.drawImage(coin, coin2.getCenterX(), coin2.getCenterY(), this);
g.drawImage(coin, coin3.getCenterX(), coin3.getCenterY(), this);
g.drawImage(coin, coin4.getCenterX(), coin4.getCenterY(), this);
g.drawImage(coin, coin5.getCenterX(), coin5.getCenterY(), this);
g.setColor(Color.MAGENTA);
g.drawString(score2, 700, 25);
Font font = new Font("Serif", Font.PLAIN, 36);
g.setFont(font);
g.drawString(coins, 20, 25);
}else if (state == GameState.Dead) {
totcoins += coinsint;
coinsint = 0;
hs1s = String.valueOf(hs1);
hs2s = String.valueOf(hs2);
hs3s = String.valueOf(hs3);
hs4s = String.valueOf(hs4);
hs5s = String.valueOf(hs5);
totcoinss = String.valueOf(totcoins);
if(score > hs1){
hs1 = score;
}else if(score > hs2){
hs2 = score;
}else if(score > hs3){
hs3 = score;
}else if(score > hs4){
hs4 = score;
}else if(score > hs5){
hs5 = score;
}
scorespeed = 0;
//format this shit up in here
//when restart is init, then this will be tested
g.setColor(Color.BLACK);
g.fillRect(0, 0, 800, 480);
g.setColor(Color.WHITE);
g.drawString(hs1s, 230, 220);
g.drawString(hs2s, 230, 250);
g.drawString(hs3s, 230, 280);
g.drawString(hs4s, 230, 310);
g.drawString(hs5s, 230, 340);
g.drawString(totcoinss, 700, 100);
g.drawImage(endscreen, ends.cornX, ends.cornY, this);
}
}
//fix the android stuff
#Override
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
player.jump();
Player.jumps += 1;
break;
}
switch (e.getKeyCode()) {
case KeyEvent.VK_SPACE:
if(state == state.Dead){
}
}
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
break;
}
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
public Background getBg1() {
return bg1;
}
public void setBg1(Background bg1) {
this.bg1 = bg1;
}
public Background getBg2() {
return bg2;
}
public void setBg2(Background bg2) {
this.bg2 = bg2;
}
public Player getPlayer() {
return player;
}
public void setPlayer(Player player) {
this.player = player;
}
public Image getImage() {
return image;
}
public void setImage(Image image) {
this.image = image;
}
public Image getBacksprite() {
return backsprite1;
}
public void setBacksprite(Image backsprite) {
this.backsprite1 = backsprite;
}
public Image getBacksprite1() {
return backsprite1;
}
public void setBacksprite1(Image backsprite1) {
this.backsprite1 = backsprite1;
}
public Image getBacksprite2() {
return backsprite2;
}
public void setBacksprite2(Image backsprite2) {
this.backsprite2 = backsprite2;
}
public Image getPlayer1() {
return player1;
}
public void setPlayer1(Image player1) {
this.player1 = player1;
}
public Image getPlayer2() {
return player2;
}
public void setPlayer2(Image player2) {
this.player2 = player2;
}
public Image getPlayer3() {
return player3;
}
public void setPlayer3(Image player3) {
this.player3 = player3;
}
public Image getBack1() {
return back1;
}
public void setBack1(Image back1) {
this.back1 = back1;
}
public Image getBack2() {
return back2;
}
public void setBack2(Image back2) {
this.back2 = back2;
}
public Image getBack3() {
return back3;
}
public void setBack3(Image back3) {
this.back3 = back3;
}
public Image getBack4() {
return back4;
}
public void setBack4(Image back4) {
this.back4 = back4;
}
public Graphics getSecond() {
return second;
}
public void setSecond(Graphics second) {
this.second = second;
}
public Animation getPlaywalk() {
return playwalk;
}
public void setPlaywalk(Animation playwalk) {
this.playwalk = playwalk;
}
public URL getBase() {
return base;
}
public void setBase(URL base) {
this.base = base;
}
public static Image getTilebase() {
// TODO Auto-generated method stub
return null;
}
public GameState getState() {
return state;
}
public void setState(GameState state) {
this.state = state;
}
public SpeedBoost getSb1() {
return sb1;
}
public void setSb1(SpeedBoost sb1) {
this.sb1 = sb1;
}
public Image getCoin() {
return coin;
}
public void setCoin(Image coin) {
this.coin = coin;
}
public Image getSbimg() {
return sbimg;
}
public void setSbimg(Image sbimg) {
this.sbimg = sbimg;
}
public Image getPlatform() {
return platform;
}
public void setPlatform(Image platform) {
this.platform = platform;
}
public Block getBlock1() {
return block1;
}
public void setBlock1(Block block1) {
this.block1 = block1;
}
public Block getBlock2() {
return block2;
}
public void setBlock2(Block block2) {
this.block2 = block2;
}
public Block getBlock3() {
return block3;
}
public void setBlock3(Block block3) {
this.block3 = block3;
}
public Block getBlock4() {
return block4;
}
public void setBlock4(Block block4) {
this.block4 = block4;
}
public Coin getCoin1() {
return coin1;
}
public void setCoin1(Coin coin1) {
this.coin1 = coin1;
}
public Coin getCoin2() {
return coin2;
}
public void setCoin2(Coin coin2) {
this.coin2 = coin2;
}
public Coin getCoin3() {
return coin3;
}
public void setCoin3(Coin coin3) {
this.coin3 = coin3;
}
public Coin getCoin4() {
return coin4;
}
public void setCoin4(Coin coin4) {
this.coin4 = coin4;
}
public Coin getCoin5() {
return coin5;
}
public void setCoin5(Coin coin5) {
this.coin5 = coin5;
}
public Platform getPlat1() {
return plat1;
}
public void setPlat1(Platform plat1) {
this.plat1 = plat1;
}
public Platform getPlat2() {
return plat2;
}
public void setPlat2(Platform plat2) {
this.plat2 = plat2;
}
public Platform getPlat3() {
return plat3;
}
public void setPlat3(Platform plat3) {
this.plat3 = plat3;
}
public Platform getPlat4() {
return plat4;
}
public void setPlat4(Platform plat4) {
this.plat4 = plat4;
}
public Platform getPlat5() {
return plat5;
}
public void setPlat5(Platform plat5) {
this.plat5 = plat5;
}
public Platform getPlat6() {
return plat6;
}
public void setPlat6(Platform plat6) {
this.plat6 = plat6;
}
public Platform getPlat7() {
return plat7;
}
public void setPlat7(Platform plat7) {
this.plat7 = plat7;
}
public static int getScore() {
return score;
}
public static void setScore(int score) {
Main.score = score;
}
public static int getCoinsint() {
return coinsint;
}
public static void setCoinsint(int coinsint) {
Main.coinsint = coinsint;
}
public static String getScore2() {
return score2;
}
public static void setScore2(String score2) {
Main.score2 = score2;
}
public static String getCoins() {
return coins;
}
public static void setCoins(String coins) {
Main.coins = coins;
}
public static int getScorespeed() {
return scorespeed;
}
public static void setScorespeed(int scorespeed) {
Main.scorespeed = scorespeed;
}
public void setTilebase(Image tilebase) {
this.tilebase = tilebase;
}
}
A good approach might be to use the methods like this:
init (should be called once, and by the browser only). Set up any common GUI elements and call the startNewGame() method.
start (called when the user restores the browser). Un-pause the action (paused in stop) and continue the game.
stop pause the current game.
startNewGame() set the initial lives, layout of pieces/characters, score etc.
When the user wants to start a new game, also call startNewGame().
I know this is an old question.
but the format of the applet above seems to be the issue. I would use something basic that would allow more control of the applet.
"Namely using a while(true) is never a good option in my opinion"
public class TestAppletCycle extends JApplet implements Runnable {
private Thread thread;
private boolean running;
#Override
public void init() {
// Init Game
}
#Override
public void start() {
if(!running) {
running = true;
thread = new Thread(this);
thread.start();
}
}
#Override
public void run() {
while(running) {
// Game Loop
}
}
#Override
public void stop() {
logger.log(Level.INFO, "TestAppletCycle.stop();");
if(running) {
running = false;
try {
thread.join();
} catch(Exception e) {
}
}
}
#Override
public void destroy() {
// Clean Up Game
}
}
Now to restart the applet you only need to stop and start the applet.
I'm trying to create a simple sideScroller in java, so far my game runs as expected but i have no idea on how to create a pause menu to go to the main menu and stuff (haven't got any idea on how to create a main manu for that mater) what do you think it's the best idea? this is the relevant code of my game, this panel is called inside a frame:
Game Code
package videojuegoalpha;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Background extends JPanel implements ActionListener, Runnable {
BufferedImage img, marco;
Character character;
Obstacle[] obstacleArray;
Timer time;
//CONSTANTS
final static int largoPantalla = 800;
final static int borderWidth=24;
final static int diferencialPantalla = 74;
final static int characterFlow=10;
final static int fontSize=18;
final static int flickerTime=150;
final static int invincibilityTime=2000;
int largonivel;
int controlPaso;
int actualHeight;
int standardHeight;
int maxHeightValue;
int deltaObstaculo;
Thread brinco;
static boolean debug=false;
boolean jumpCycleDone;
boolean runDone;
boolean maxHeight;
boolean shrinkHeart;
boolean pause;
static Font fontScore,fontMultiplier;
Lives lives;
static MultithreadSystem sounds = new MultithreadSystem();
static Thread MusicPlayer = new Thread(sounds);
static String BackgroundMusic;
String hitSound;
String score;
public Background(int actualHeight, int maxHeightValue,
String characterImage,String characterHitImage, int pasosPersonaje,int speed,
String imagenFondo,String imagenMarco,
String lowObstacleImage,String highObstacleImage,int obstacleDistance,
String musicFile,String jumpSound,String hitSound, String dashSound) {
controlPaso=0;
this.standardHeight = actualHeight;
this.actualHeight = this.standardHeight;
this.maxHeightValue = maxHeightValue;
jumpCycleDone = false;
runDone = false;
maxHeight = false;
shrinkHeart=false;
pause=false;
character = new Character(characterImage,characterHitImage,pasosPersonaje,
speed,jumpSound,dashSound);
lives=new Lives();
obstacleArray=Obstacle.getObstacleArray(5200,obstacleDistance,
standardHeight+deltaObstaculo+borderWidth, (standardHeight+deltaObstaculo)/,lowObstacleImage,highObstacleImage);
addKeyListener(new AL());
setFocusable(true);
try {
img = CompatibleImage.toCompatibleImage(ImageIO.read(new File(
"Images"+File.separator+"Background"+
File.separator+imagenFondo)));
marco = CompatibleImage.toCompatibleImage(ImageIO.read(new File(
"Images"+File.separator+imagenMarco)));
fontScore=(Font.createFont(Font.TRUETYPE_FONT,new FileInputStream(new File(
"Fonts"+File.separator+"score.ttf")))).deriveFont(Font.BOLD, 18);
fontMultiplier=(Font.createFont(Font.TRUETYPE_FONT,
new FileInputStream(new File("Fonts"+File.separator+"multi.ttf"))))
.deriveFont(Font.BOLD, fontSize+10);
} catch (IOException | FontFormatException e) {
System.out.println("Error al cargar" + ":" + e.toString());
}
deltaObstaculo=(character.getImage(character.pasoActual).
getHeight(null))- (obstacleArray[0].getImage().getHeight(null));
time = new Timer(5, this);
time.start();
BackgroundMusic = "Music/"+musicFile;
backMusic(BackgroundMusic);
this.hitSound=hitSound;
}
public static void backMusic(String MusisBck) {
sounds.newThread(BackgroundMusic);
MusicPlayer.start();
if (MusicPlayer.isAlive() != true) {
sounds.newThread(BackgroundMusic);
MusicPlayer.start();
}
}
#Override
public void actionPerformed(ActionEvent e) {
if(!pause){
character.move();
}
condWin(5200);
condLose();
avanzaPaso();
repaint();
}
public void avanzaPaso() {
if(!pause){
controlPaso++;
}
if (controlPaso % characterFlow == 0) {
character.pasoActual++;
if (character.pasoActual > character.pasos-3) {
character.pasoActual = 0;
}
debugMode("Paso: " + character.pasoActual);
}
if(controlPaso%(characterFlow*(character.pasos-2))==0){
shrinkHeart = !shrinkHeart;//oscilación para encojer/desencojer
}
}
public void condWin(int dist) {
if (character.getPositionX() == dist) {
MultithreadSystem sounds = new MultithreadSystem();
sounds.newThread("Music/FF3Victory.wav");
Thread sounds_player = new Thread(sounds);
MusicPlayer.stop();
sounds_player.start();
JOptionPane.showMessageDialog(null, "YOU WIN!");
System.exit(0);
}
}
public void condLose() {
if (character.lives == 0) {
character.isAlive = false;
if (!character.isAlive) {
MultithreadSystem sounds = new MultithreadSystem();
sounds.newThread("Music/gameOver01.wav");
Thread sounds_player = new Thread(sounds);
MusicPlayer.stop();
sounds_player.start();
JOptionPane.showMessageDialog(null, "YOU SUCK");
System.exit(0);
}
}
}
#Override
public void paint(Graphics g) {
debugMode("Altura: " + actualHeight);
if (character.deltaY == 1 && runDone == false) {
runDone = true;
brinco = new Thread(this);
brinco.start();
}
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(img, largoPantalla - character.getnX2(), 0, null);
if (character.getPositionX() > diferencialPantalla) {
g2d.drawImage(img, largoPantalla - character.getnX(), 0, null);
}
for (int i = 0; i < obstacleArray.length; i++) {
if (obstacleArray[i] != null) {
if (obstacleArray[i].getPositionX() == -character.posicionFija) {
obstacleArray[i] = null;
}
if (obstacleArray[i] != null) {
if(!pause){
obstacleArray[i].move(character.pixPerStep);
}
if (obstacleArray[i].getPositionX() ==
largoPantalla + character.posicionFija) {
obstacleArray[i].setVisible(true);
}
if (obstacleArray[i].isVisible()) {
g2d.drawImage(obstacleArray[i].getImage(),
obstacleArray[i].getPositionX(),
obstacleArray[i].getPositionY(), null);
}
checkCollisions(obstacleArray[i]);
}
}
}
if (character.paintCharacter) {
g2d.drawImage(character.getImage(character.pasoActual),
character.posicionFija, actualHeight, null);
}
character.hit(flickerTime);
if (shrinkHeart) {
g2d.drawImage(lives.getImage(character.getLives()),
borderWidth + 5,
borderWidth + 5,
(int) (lives.getImage(character.getLives()).getWidth() * .95),
(int) (lives.getImage(character.getLives()).getHeight() * .95),
null);
} else {
g2d.drawImage(lives.getImage(character.getLives()),
borderWidth + 5,
borderWidth + 5,
null);
}
g2d.drawImage(marco, 0, 0, null);
g2d.setFont(fontScore);
g2d.setColor(Color.BLACK);
score = String.format("%08d", character.score);
g2d.drawString("score:" + score, 500, borderWidth * 2);
g2d.setFont(fontMultiplier);
g2d.drawString(character.multiplier + "",
(largoPantalla / 2) - 75, (borderWidth * 2) + 10);
}
private class AL extends KeyAdapter {
#Override
public void keyReleased(KeyEvent e) {
character.keyReleased(e);
}
#Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if(!pause){
character.keyPressed(e);
}
if (key == KeyEvent.VK_D) {
debug=(!debug);
}
if(key==KeyEvent.VK_P){
pause=(!pause);
}
if (key == KeyEvent.VK_ESCAPE) {
System.exit(0);
}
}
}
public void checkCollisions(Obstacle obstacle) {
if (character.posicionFija == obstacle.getPositionX()) {
if (obstacle instanceof LowObstacle) {
debugMode("Obstaculo Bajo, Altura: "+obstacle.getPositionY());
if (actualHeight <= (standardHeight - obstacle.getImage().getHeight(null))){
if (character.multiplier < 4) {
character.multiplier++;
}
} else {
if (character.hitAllowed) {
sounds = new MultithreadSystem();
sounds.newThread("SFX/" + hitSound);
Thread sounds_player = new Thread(sounds);
sounds_player.start();
character.multiplier = 1;
character.lives--;
character.hitAllowed = false;
}
}
}
else{
debugMode("Obstaculo Alto, Altura: "+obstacle.getPositionY());
if (character.dashPressed) {
if (character.multiplier < 4) {
character.multiplier++;
}
} else {
if (character.hitAllowed) {
sounds = new MultithreadSystem();
sounds.newThread("SFX/" + hitSound);
Thread sounds_player = new Thread(sounds);
sounds_player.start();
character.multiplier = 1;
character.lives--;
character.hitAllowed = false;
}
}
}
}
}
public void cycle() {
if(!pause){
if (maxHeight == false) {
actualHeight--;
}
if (actualHeight == maxHeightValue) {
maxHeight = true;
}
if (maxHeight == true && actualHeight <= standardHeight) {
actualHeight++;
if (actualHeight == standardHeight) {
jumpCycleDone = true;
}
}
}
}
#Override
public void run() {
character.isJumping = true;
character.keyAllowed = false;
long beforeTime, timeDiff, sleep;
beforeTime = System.currentTimeMillis();
while (jumpCycleDone == false) {
cycle();
timeDiff = System.currentTimeMillis() - beforeTime;
sleep = 8 - timeDiff;
if (sleep < 0) {
sleep = 2;
}
try {
Thread.sleep(sleep);
} catch (InterruptedException e) {
}
beforeTime = System.currentTimeMillis();
}
jumpCycleDone = false;
maxHeight = false;
runDone = false;
character.keyAllowed = true;
character.isJumping = false;
}
public static void debugMode(String string){
if(debug){
System.out.println(string);
}
}
// Getters y Setters //
public Character getCharacter() {
return character;
}
public void setCharacter(Character character) {
this.character = character;
}
}
As you can see I already have a pause variable which pauses everything, but I would like to have a little window popup in the middle while pause its true
The problem is that your class Background is directly where you draw.
Normally your game handles all the frames and stuff, but then you have some kind of GameState object which your main game calls, like this:
public void update() {
if (pause) {
gameState = pauseState;
} else {
gameState = playState;
}
gameState.update();
}
#Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
gameState.paint(g2d)
}
The idea is that you can have as many gameStates as you want. Simply make an interface GameState that provides methods for Update, Paint, Initialize and Dispose (or something like this).
Then you can have all kinds of GameStates, for example Play, Pause, MainMenu, SaveGameMenu, etc., each one in charge of updating and drawing itself.
It's the main class (where your game loop is) where you handle the logic to swap the GameStates.