Blackberry Touch event detecting object at touch up position - java

This is my first blackberry app and I am attempting to make a simple game for a touch screen device.
Its the typical image split into tiles and you have to unscramble them so the tiles are in the correct order and show the picture.
The intention is that the user will be able to "drag" a tile anywhere they want on the screen and they will swap places with the tile they drop it over.
I am using bitmapbuttons for my tiles
HorizontalFieldManager hfm = new HorizontalFieldManager();
add(hfm);
hfm.add(button1);
hfm.add(button2);
etc...
I have a class called Puzzle screen as follows:
class PuzzleScreen extends MainScreen implements FieldChangeListener {
I have added the following to try and detect the movement of the persons touch on the screen
protected boolean touchEvent(TouchEvent event) {
case TouchEvent.MOVE:
PuzzleTile fieldMove = (PuzzleTile) this.getLeafFieldWithFocus();
// Dialog.alert("MOVE");
int[] x_points;
int[] y_points;
int[] time_points;
int size = event.getMovePointsSize();
x_points = new int[size];
y_points = new int[size];
time_points = new int[size];
event.getMovePoints(1, x_points, y_points, time_points);
return true;
}
return false;
}
I need to find which image tile (bitmapbutton) is at the position of the upevent.
I have the coordinates (I think) above but not sure how to find which tile that relates to.
Bex

Something like this.
static class TestScreen extends MainScreen {
private static String down;
public TestScreen () {
HorizontalFieldManager hfm = new HorizontalFieldManager();
add(hfm);
hfm.add(new TestButton("bt1"));
hfm.add(new TestButton("bt2"));
hfm.add(new TestButton("bt3"));
hfm.add(new TestButton("bt4"));
hfm.add(new TestButton("bt5"));
hfm.add(new TestButton("bt6"));
}
public static void touchDown(TestButton tb) {
down = tb.getText();
System.out.println("DOWN in " + tb.getText());
}
public static void touchUp(TestButton tb) {
System.out.println("UP in " + tb.getText());
if(!down.equals(tb.getText()))
System.out.println("swap " + down + " and " + tb.getText());
down = "";
}
class TestButton extends LabelField {
public TestButton (String label) {
super(label);
}
protected boolean touchEvent(TouchEvent event) {
if(event.getEvent() == TouchEvent.UP)
TestScreen.touchUp(this);
else if(event.getEvent() == TouchEvent.DOWN)
TestScreen.touchDown(this);
return super.touchEvent(event);
}
}
}

Related

libGDX: How to read and display text from a .txt file line by line after pressing a key?

I'm new to Java and I'm trying to make a Visual Novel type of game.
What I'm trying to do is display text from a text file line by line by pressing a space button, like in a usual novel.
I've overlooked different methods but nothing works out for me. I know there are Scanner and BufferedReader, but are they suitable for what I'm doing?
Right now all that happens is when I press "space" the whole text appears on the screen, and when I let go, it dissapears.
This is my game class:
public class NovelGame extends Game {
public static final int WIDTH = 1366;
public static final int HEIGHT = 768;
public SpriteBatch batch;
public String txtFileString;
public String lines[];
public BitmapFont bitmapFont;
#Override
public void create () {
batch = new SpriteBatch();
bitmapFont = new BitmapFont();
this.setScreen(new MainMenuScreen(this));
txtFileString = Gdx.files.internal("script.txt").readString();
String[] anArray = txtFileString.split("\\r?\\n");}
#Override
public void render () {
super.render();
}}
This is my game screen class:
public class MainGameScreen implements Screen{
private Texture img;
NovelGame game;
public MainGameScreen (NovelGame game) {
this.game = game;
}
#Override
public void show() {
img = new Texture("bck.jpg");
}
#Override
public void render(float delta) {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); // This cryptic line clears the screen.
game.batch.begin();
game.batch.draw(img, 0, 0);
if(Gdx.input.isKeyPressed(Input.Keys.SPACE)){
game.bitmapFont.draw(game.batch, game.txtFileString,Gdx.graphics.getWidth()/2,Gdx.graphics.getHeight()/2);
}
game.batch.end();
}
I had an idea to display it using while and if, but can't exactly figure out how to do it.
EDIT: I found a way to display text, but now, once I run my game, it starts piling one on another endlessly after I press space.
Code:
public class MainGameScreen implements Screen{
private Texture img;
NovelGame game;
public MainGameScreen (NovelGame game) {
this.game = game;
}
#Override
public void show() {
img = new Texture("bck.jpg");
}
#Override
public void render(float delta) {
try {
BufferedReader br = new BufferedReader (new FileReader("C:\\Users\\hydra\\Documents\\JAVA_PROJECTS\\gamespace\\core\\assets\\startd.txt"));
while((game.strLine = br.readLine()) != null){
game.list.add(game.strLine);
}
br.close();
} catch (IOException e) {
System.err.println("Unable to read the file.");
}
if(Gdx.input.isKeyJustPressed(Input.Keys.SPACE)){
game.showText = true;
}
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); // This cryptic line clears the screen.
game.batch.begin();
game.batch.draw(img, 0, 0);
if(game.showText) {
for(int i = 0; i < game.list.size(); i++) {
System.out.println(game.list.get(i));
game.bitmapFont.draw(game.batch, game.list.get(i), 100, 50);
}
}
game.batch.end();
}
Problem is here. Gdx.input.isKeyPressed returns true if only key is pressing currently.
if(Gdx.input.isKeyPressed(Input.Keys.SPACE)){
game.bitmapFont.draw(game.batch, game.txtFileString,Gdx.graphics.getWidth()/2,Gdx.graphics.getHeight()/2);
}
To fix this add a boolean flag activate it after key is only just pressed:
if(Gdx.input.isKeyJustPressed(Input.Keys.SPACE)){
showText = true;
}
And in render method:
if (showText) {
game.bitmapFont.draw(game.batch, game.txtFileString,Gdx.graphics.getWidth()/2,Gdx.graphics.getHeight()/2);
}
I found out what I was doing wrong in the end. I put everything in render method, and that's why file was being read endlessly. I need to do it only once in the constructor class and then put it in the render method.

Java getCanvasImage and paintComponent draws out of sync

Objective:
I'm trying to draw bounding boxes around NPCs from a game client. I need to save the screenshot to a folder and save the box coordinates to a text file.
Problem:
When I rotate the camera, the boxes drawn on the canvas no longer align with the NPCs. It looks like the NPC coordinates lag behind the screenshot that is being draw on. Some of the screenshots also appear to be half previous frame and half new frame. I assume this may be related to multiple images being sent to save before the first one completes. Another thing to note is that the boxes don't finish drawing before the next frame appears on the canvas.
How can I force the screenshots to sync with the box coordinates? Is there some way I can get the game data and screenshot at the same time and then force the client to stop drawing until the task is complete?
This is the first time I've ever worked with Java (The data this script collects is intended for use with a Python project I'm working on) so please simplify answers as much as possible.
Update:
After messing around with things, it appears that the screen tearing may be the main issue. The delay looks like it's caused by the screen tear. The boxes are being drawn at the correct position on the parts of the screen that didn't get updated before they were saved.
https://media.giphy.com/media/39yEawmLBT4zKpPoz3/giphy.gif
Performing at its worst:
Tearing:
public class Pair {
public String key;
public Rectangle value;
public Pair(String key, Rectangle value) {
this.key = key;
this.value = value;
}
}
public class MyPaint extends JPanel{
private static final long serialVersionUID = 9091790544960515120L;
private BufferedImage paintImage = getClient().getCanvasImage();
#Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(paintImage, 0, 0, null);
}
public void updatePaint(){
synchronized (this) {
Graphics g = paintImage.createGraphics();
List<NPC> rsNpcs = new NPCs(getClient()).all()
.stream()
.filter(i -> i.getName().equals(npcName)
&& i.isOnScreen() == true
&& inTile(i.getTile()) == false)
.collect(Collectors.toList());
//Classifying the NPC in the box for the text file.
for (NPC rsNpc : rsNpcs) {
Rectangle bbox = rsNpc.getBoundingBox();
g.drawRect(bbox.x, bbox.y, bbox.width, bbox.height);
if (rsNpc.isInCombat() == true) {
Pair rsNpcPair = new Pair("CombatChicken", bbox);
onScreenRsNpcs.add(rsNpcPair);
} else {
Pair rsNpcPair = new Pair("RegularChicken", bbox);
onScreenRsNpcs.add(rsNpcPair);
}
}
//This bit is to save the boxes to a text file:
for (Pair rsNpc : onScreenRsNpcs) {
String data = (String.valueOf(rsNpc.value) + "Class Name: " + rsNpc.key + " Image Name: " + String.valueOf(count));
globalData.add(data);
}
g.dispose();
repaint();
}
}
public void save() throws IOException{
ImageIO.write(paintImage, "PNG", new File(String.format("%s/%s.jpg", getManifest().name(), count)));
count = count + 1;
}
public void load() throws IOException {
paintImage = ImageIO.read(new File(String.format("%s/%s.jpg", getManifest().name(), count)));
repaint();
}
}
//...
private MyPaint paint;
public void onStart() {
paint = new MyPaint();
}
//...
#Override
public int onLoop() {
try {
paint.updatePaint();
paint.save();
paint.load();
} catch (Exception e) {
e.printStackTrace();
}
return 1;
}

LibGDX - How to spawn objects at a certain distance from each other?

So I'm trying to create a game and it's my first time. My game is a 2D side scroller and is about the player in space avoiding the incoming meteors. I have successfully managed to get the meteors spawning randomly on the x and y axis off screen and re position once it has gone pass the screen.
But the problem I face now is sometimes the spawn of the meteors will clump together which I don't want. How do I get the meteors to spawn at a certain distance from each other so they don't clump together. I couldn't find any good tutorials or if anyone can point me to the right direction. Below are my codes so far.
Meteor Class
public class Meteors {
private Texture bigMeteor;
private Vector2 posBigMeteor;
private Random yrand;
//Constructor
public Meteors(float x){
bigMeteor = new Texture("meteor.png");
yrand = new Random();
//Spawn location of meteor
posBigMeteor = new Vector2(x, yrand.nextInt(AstroDemo.HEIGHT/2 - bigMeteor.getHeight()));
}
public Texture getBigMeteor() {
return bigMeteor;
}
public Vector2 getPosBigMeteor() {
return posBigMeteor;
}
//Reposition the meteors
public void reposition(float x){
posBigMeteor.set(x, yrand.nextInt(AstroDemo.HEIGHT/2 - bigMeteor.getHeight()));
}
}
PlayState Class
public class PlayState extends State {
//Total meteor count on screen
private static final int METEOR_COUNT = 8;
private Naught naught;
private Texture bg;
private Random xrand;
private Array <Meteors> meteors;
public PlayState(GameStateManager gsm) {
super(gsm);
//Starting co-ordinates of main character (Naught)
naught = new Naught(50, 100);
//Setting viewport of the camera
cam.setToOrtho(false, AstroDemo.WIDTH/2, AstroDemo.HEIGHT/2);
bg = new Texture("bg.png");
xrand = new Random();
meteors = new Array <Meteors>();
//Spawn meteors randomly off screen
for (int i = 1; i <= METEOR_COUNT; i++){
meteors.add(new Meteors(AstroDemo.WIDTH/2 + (xrand.nextInt(300))));
}
}
#Override
protected void handleInput() {
//If screen/mouse is held
if(Gdx.input.isTouched()){
//Main Character jumps/flys
naught.jump();
}
}
#Override
public void update(float dt) {
handleInput();
naught.update(dt);
//If meteors are left side of the screen, re-position to the right side of the screen
for(Meteors meteor : meteors){
if (cam.position.x - (cam.viewportWidth/2) > meteor.getPosBigMeteor().x + meteor.getBigMeteor().getWidth()){
meteor.reposition(meteor.getPosBigMeteor().x + (AstroDemo.WIDTH/2 + 20 + (xrand.nextInt(300))));
}
}
cam.position.x = naught.getPosition().x + 80;
cam.update();
}
#Override
public void render(SpriteBatch sb) {
//Adjust the spritebatch for co-ordinate system in relation to camera
sb.setProjectionMatrix(cam.combined);
sb.begin();
//Draw background where the camera is
sb.draw(bg, cam.position.x - (cam.viewportWidth/2), 0);
sb.draw(naught.getTexture(), naught.getPosition().x, naught.getPosition().y);
for (Meteors meteor : meteors) {
sb.draw(meteor.getBigMeteor(), meteor.getPosBigMeteor().x, meteor.getPosBigMeteor().y);
}
sb.end();
}
#Override
public void dispose() {
}
}
create a array of predefined value for your y position and then get value randomly from that array.
or
Divide height into sub portion then get random value from that portion so that each random value not collide with other value.

Reuse code when using screens in Libgdx

From what I understand when reading other peoples code on how to make different screens. You do a main handler class sort of... And then create a new class for each screen.
The thing that confuses me is that whenever you create a new screen, you have to redefine everything that's going to be rendered, like SpriteBatch, sprites, fonts, etc. Is there any way to reuse these kind of things in all screens? I mean, if I have 10 screens, and want to be able to draw text on every screen. Is it really good programming practice to make a new BitmapFont for all 10 screen classes?
I've created an Abstract Screen class that contains all the common objects for a screen, every one of my screens extend this abstract class. And that looks like this:
public abstract class AbstractScreen implements Screen {
protected final Game game;
protected InputMultiplexer multiInputProcessor;
protected ScreenInputHandler screenInputHandler;
protected Stage uiStage;
protected Skin uiSkin;
public AbstractScreen(Game game) {
this.game = game;
this.uiStage = new Stage();
this.uiSkin = new Skin();
this.screenInputHandler = new ScreenInputHandler(game);
this.multiInputProcessor = new InputMultiplexer();
multiInputProcessor.addProcessor(uiStage);
multiInputProcessor.addProcessor(screenInputHandler);
Gdx.input.setInputProcessor(multiInputProcessor);
}
private static NinePatch processNinePatchFile(String fname) {
final Texture t = new Texture(Gdx.files.internal(fname));
final int width = t.getWidth() - 2;
final int height = t.getHeight() - 2;
return new NinePatch(new TextureRegion(t, 1, 1, width, height), 3, 3, 3, 3);
}
#Override
public void render (float delta) {
Gdx.gl.glClearColor(0.2f, 0.2f, 0.2f, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
uiStage.act(Math.min(Gdx.graphics.getDeltaTime(), 1 / 30f));
uiStage.draw();
Table.drawDebug(uiStage);
}
#Override
public void resize (int width, int height) {
}
#Override
public void show() {
}
#Override
public void hide() {
dispose();
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void dispose() {
uiStage.dispose();
uiSkin.dispose();
}
}
When I want to create a new class I just extend the abstract screen and add what I need. For example I have a basic credits screen, I just need to create the components but the abstract screen draws it:
public class CreditsScreen extends AbstractScreen {
public CreditsScreen(final Game game) {
super(game);
// Generate a 1x1 white texture and store it in the skin named "white".
Pixmap pixmap = new Pixmap(1, 1, Format.RGBA8888);
pixmap.setColor(Color.WHITE);
pixmap.fill();
uiSkin.add("white", new Texture(pixmap));
// Store the default libgdx font under the name "default".
BitmapFont buttonFont = new BitmapFont();
buttonFont.scale(scale);
uiSkin.add("default", buttonFont);
// Configure a TextButtonStyle and name it "default". Skin resources are stored by type, so this doesn't overwrite the font.
TextButtonStyle textButtonStyle = new TextButtonStyle();
textButtonStyle.up = uiSkin.newDrawable("white", Color.DARK_GRAY);
textButtonStyle.down = uiSkin.newDrawable("white", Color.DARK_GRAY);
textButtonStyle.checked = uiSkin.newDrawable("white", Color.BLUE);
textButtonStyle.over = uiSkin.newDrawable("white", Color.LIGHT_GRAY);
textButtonStyle.font = uiSkin.getFont("default");
uiSkin.add("default", textButtonStyle);
// Create a table that fills the screen. Everything else will go inside this table.
Table table = new Table();
table.setFillParent(true);
uiStage.addActor(table);
table.debug(); // turn on all debug lines (table, cell, and widget)
table.debugTable(); // turn on only table lines
// Label
BitmapFont labelFont = new BitmapFont();
labelFont.scale(scale);
LabelStyle labelStyle = new LabelStyle(labelFont, Color.BLUE);
uiSkin.add("presents", labelStyle);
final Label myName = new Label("Credits and all that stuff", uiSkin, "presents");
table.add(myName).expand().center();
}
}
I also have a single class that handles the input for all the screens, the specific purpose for this is to handle how the back button works around the different screens. And this input handler class is created in the abstract class.
public class ScreenInputHandler implements InputProcessor {
private final Game game;
public ScreenInputHandler(Game game) {
this.game = game;
}
#Override
public boolean keyDown(int keycode) {
if(keycode == Keys.BACK || keycode == Keys.BACKSPACE){
if (game.getScreen() instanceof MainMenuScreen) {
Gdx.app.exit();
}
if (game.getScreen() instanceof GameScreen) {
World.getInstance().togglePause(false);
}
if (game.getScreen() instanceof CreditsScreen) {
game.setScreen(new MainMenuScreen(game));
}
}
return false;
}
}

JMonkey - Shooting in Direction of Crosshairs

How can I shoot in the direction that a cross-hair is pointing at?
Using the JMonkey engine, I am creating a game where I need a ship to shoot other ships.
So, I created cross-hairs that can move on the screen (up, down, left, right) according to user input, so the user can aim on a certain place.
Now I need I to shoot a cannon from my ship, in the direction that the cross-hair is standing at.
How can I shoot at the place that the cross-hair is pointing at?
You can get camera direction with:
directionXYZ=cam.getDirection(); //Vector3f form
and can get position from:
positionXYZ=cam.getLocation(); //Vector3f
You can have a ray casting:
Ray ray = new Ray(directionXYZ, positionXYZ);
then can collect data for collisions:
shootables.collideWith(ray, results)
where shootable is a "Node".
Finally, check for what you want:
for (int i = 0; i < results.size(); i++) {
// For each hit, we know distance, impact point, name of geometry.
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.");
}
Taken from jmonkey wiki
My reading of this question is that the aim is not to shoot where the camera is facing but where a cursor (not in the centre of the screen) is pointing.
This can be achieved using the cam.getWorldCoordinates(screenPosition, zDepth); command, this returns the 3D point in space that would end up at the point screenPosition on the screen. So if we create a point at zDepth of zero and a point at zDepth of one we can create a ray coming from the cursor position travelling outwards so anything that the curser is "over" is selected. screenPosition is in pixels from the bottom left of the window
An example program that uses this technique is as follows and is based upon the second part of hello picking.
In my example the cursor is moved using the keyboard (H,J,K,U) but a mouse click could also be used (but I'm using the mouse for looking around)
import com.jme3.app.SimpleApplication;
import com.jme3.collision.CollisionResults;
import com.jme3.font.BitmapText;
import com.jme3.input.KeyInput;
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.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Box;
public class Main extends SimpleApplication {
public static KeyBindings keyBindings;
public Vector2f cursorPosition=new Vector2f(100,100);
public Node shootables=new Node();
public Node crossHairNode=new Node();
public static void main(String[] args) {
Main app = new Main();
app.start();
}
#Override
public void simpleInitApp() {
//bind keys to move cursor
keyBindings=new KeyBindings(inputManager); //for managing keystrokes
keyBindings.registerKeyBinding(KeyInput.KEY_SPACE, "fire");
keyBindings.registerKeyBinding(KeyInput.KEY_U, "up");
keyBindings.registerKeyBinding(KeyInput.KEY_J, "down");
keyBindings.registerKeyBinding(KeyInput.KEY_H, "left");
keyBindings.registerKeyBinding(KeyInput.KEY_K, "right");
initGui();
Box b = new Box(Vector3f.ZERO, 2, 2, 2);
Geometry geom = new Geometry("BigBox", b);
Box b2 = new Box(Vector3f.ZERO, 1, 1, 1);
Geometry geom2 = new Geometry("SmallBox", b2);
geom2.setLocalTranslation(3, 0, 3);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setColor("Color", ColorRGBA.Blue);
geom.setMaterial(mat);
geom2.setMaterial(mat);
rootNode.attachChild(shootables);
shootables.attachChild(geom);
shootables.attachChild(geom2);
}
#Override
public void simpleUpdate(float tpf) {
updateCrossHairs();
if (keyBindings.getBinding("fire").hasBecomeTrueSinceLastAccess()){
CollisionResults results = new CollisionResults();
Vector3f cursor3dLocation = cam.getWorldCoordinates(
new Vector2f(cursorPosition.x, cursorPosition.y), 0f).clone();
Vector3f dir = cam.getWorldCoordinates(
new Vector2f(cursorPosition.x, cursorPosition.y), 1f).subtractLocal(cursor3dLocation).normalizeLocal();
Ray ray = new Ray(cursor3dLocation, dir);
shootables.collideWith(ray, results);
if (results.size()>0){
resultsText.setText("Hit: " + results.getClosestCollision().getGeometry().getName());
resultsText.setLocalTranslation(settings.getWidth()-resultsText.getLineWidth(),resultsText.getLineHeight(), 0);
}else{
resultsText.setText("Missed");
resultsText.setLocalTranslation(settings.getWidth()-resultsText.getLineWidth(),resultsText.getLineHeight(), 0);
}
}
}
private void updateCrossHairs(){
if (keyBindings.getBinding("up").getValue()==true){
cursorPosition.y+=1;
}
if (keyBindings.getBinding("down").getValue()==true){
cursorPosition.y+=-1;
}
if (keyBindings.getBinding("left").getValue()==true){
cursorPosition.x+=-1;
}
if (keyBindings.getBinding("right").getValue()==true){
cursorPosition.x+=+1;
}
crossHairNode.setLocalTranslation(cursorPosition.x - crossHair.getLineWidth()/2,cursorPosition.y + crossHair.getLineHeight()/2, 0);
}
BitmapText crossHair;
BitmapText instructions;
BitmapText resultsText;
private void initGui() {
setDisplayStatView(false);
guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
crossHair = new BitmapText(guiFont, false);
crossHair.setSize(guiFont.getCharSet().getRenderedSize() * 2);
crossHair.setText("+"); // crosshairs
crossHairNode.setLocalTranslation(cursorPosition.x - crossHair.getLineWidth()/2,cursorPosition.y + crossHair.getLineHeight()/2, 0);
guiNode.attachChild(crossHairNode);
crossHairNode.attachChild(crossHair);
instructions= new BitmapText(guiFont, false);
instructions.setSize(guiFont.getCharSet().getRenderedSize());
instructions.setText("Move cross hairs with U,H,J,K keys, fire with space \n (WSAD moves camera position and look with mouse)");
instructions.setLocalTranslation(0, settings.getHeight(), 0);
guiNode.attachChild(instructions);
resultsText= new BitmapText(guiFont, false);
resultsText.setSize(guiFont.getCharSet().getRenderedSize());
resultsText.setText("Press Space to fire");
resultsText.setLocalTranslation(settings.getWidth()-resultsText.getLineWidth(),resultsText.getLineHeight(), 0);
guiNode.attachChild(resultsText);
}
#Override
public void simpleRender(RenderManager rm) {
//TODO: add render code
}
}
Keybindings, used only to control cursor movement:
import com.jme3.input.InputManager;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.input.controls.MouseButtonTrigger;
import java.util.ArrayList;
import java.util.Locale;
public class KeyBindings implements ActionListener{
private InputManager inputManager;
private ArrayList<String> bindingString=new ArrayList<String>(100);
private ArrayList<KeyBinding> binding=new ArrayList<KeyBinding>(100);
public KeyBindings(InputManager inputManager){
this.inputManager=inputManager;
}
public void registerKeyBinding(int key,String bindingName){
bindingName=preprocess(bindingName);
inputManager.addMapping( bindingName, new KeyTrigger(key));
inputManager.addListener(this, bindingName);
binding.add(new KeyBinding());
bindingString.add(bindingName);
}
public void registerMouseBinding(int button,String bindingName){
bindingName=preprocess(bindingName);
inputManager.addMapping( bindingName, new MouseButtonTrigger(button));
inputManager.addListener(this, bindingName);
binding.add(new KeyBinding());
bindingString.add(bindingName);
}
public KeyBinding getBinding(String bindingName){
//get which binding we're after
bindingName=preprocess(bindingName);
int index=bindingString.indexOf(bindingName);
if (index!=-1){
return binding.get(index);
}else{
return null;
}
}
public void onAction(String bindingName, boolean isPressed, float tpf) {
bindingName=preprocess(bindingName);
//get which binding we're after
int index=bindingString.indexOf(bindingName);
if (index!=-1){
binding.get(index).setValue(isPressed);
}
}
private String preprocess(String string){
return string.toUpperCase();
}
}
public class KeyBinding {
private boolean value;
private boolean changedSinceLastAccess; //to avoid multiclicks etc
private boolean valueTrueSinceLastAccess;
public void setValue(boolean value){
this.value=value;
changedSinceLastAccess=true;
if (value==true){
valueTrueSinceLastAccess=true;
}
}
public boolean hasChangedSinceLastAccess(){
return changedSinceLastAccess;
}
public boolean hasBecomeTrueSinceLastAccess(){
//this collects any trues since the last access, is good for things like mouse clicks,
//which are instantaneous and you want then recorded on the next tick
if (valueTrueSinceLastAccess==true){
valueTrueSinceLastAccess=false;
return true;
}else{
return false;
}
}
public boolean getValue(){
changedSinceLastAccess=false;
valueTrueSinceLastAccess=false;
return value;
}
public boolean getValue_withoutNotifying(){
return value;
}
}

Categories