I'm trying to make a game i want to be able to press down on my gamePadUI to keep my character walking. Far as I can tell the TouchEvents only get called 1st time I push down on the screen
I have 2 methods called constantly update() which keeps track of my game states and in each state has TouchEvents, so in my Running state it will call updateRunning() and checks for TouchedEvent then map the the x and y points to my gamepadUI
The other is Present() which handles the drawing of each states.
so here is my updateRunning() method that tells the character to walk
public void updateRunning(float deltaTime) {
List<TouchEvent> touchEvents = game.getInput().getTouchEvents();
int len = touchEvents.size();
for (int i = 0; i < len; i++) {
Input.TouchEvent event = touchEvents.get(i);
touchPoint.set(event.x, event.y);
guiCam.touchToWorld(touchPoint);
switch(event.type){
case TouchEvent.TOUCH_DOWN:
gamePad(deltaTime);
case TouchEvent.TOUCH_DRAGGED:
gamePad(deltaTime);
case TouchEvent.TOUCH_UP:
}
}
}
I have tried looping the event but my present then will not get called for there the drawing will not get updated.
what can I do to make it keep TOUCH_DOWN going to call my gamepad method.
Related
So, for a school project, I've been trying to get a jumping mechanism down. However, the problem I've been having is that the player is able to just float around, rather than having to fall down after reaching a certain jump height.
I have tried many things, including the normal idea of when the up key is pressed, setting jumping equal to true, and then in the actionPerformed method, setting the yVelocity to -4. But, when the jump key is clicked, I record the yPosition at the time, and when the current yPosition is less than the original position - 50, I set the yVelocity equal to 0, and the fallVelocity to 1.
This is the code in my actionPerformed method:
if (jumping) {
if (yPos <= homeY - 50) {
yVel = 0;
fallVel = 1;
falling = true;
jumping = false;
System.out.println("bye");
} else {
yVel = -JUMP_SPEED;
}
}
yPos += yVel + fallVel;
'''
This is the code in the keyPressed method:
if (!jumping && !falling) {
jumping = true;
homeY = yPos;
count = 0;
}
So, I expect the result to be a player that goes up 50 pixels, and then starts falling down. But in the program, the player just sort of keeps on floating, as long as the up key is pressed.
Jumping does not really work properly as an up/down switch imo. The best approach is to use gravity (which is very easy to add).
To add gravity just modify the player velocity each tick. This should be run on a fixed time update loop to make consistent gravity at different frame rates:
// Play with this number for rate of gravity
player.ySpeed -= 4.9; // Gravity = 9.8m/s^2
Then for your jumping just add to the player ySpeed. This will create a natural parabolic jump.
if (jumpWasPressed) {
player.ySpeed += 50; // play with this number for jump height
}
This approach does assume you have a hotbox for your "ground" object to stop the player from falling through the ground
I have a program where the user is traveling in a grid and has to kill an enemy. When they do so, a message comes up stating that the user has heard a scream.
This message is only supposed to display once when the user fires their weapon. I made the message display if the following method was true:
public boolean deadWumpus()
{
for(int x=0;x<10;x++)
{
for(int y=0;y<10;y++)
{
if(map.grid[x][y].getDeadWumpus()==true)
return true;
}
}
return false;
}
I then have a line in my paint() method which states that if this method is true then display the message. However, this keeps on displaying as there is no regulator to tell it to run only once when the user fires.
I attempted to create an int to ensure it only runs once:
// at beginning of program
int once=0;
//in paint()
if(once==0){
if(deadWumpus()==true)
{
g.drawString("You hear a scream.",300,675);
}
}
once++;
Using this it never displays the message. Is there a way I can get the message to only display once when the user shoots and then disappear once the user makes their next move?
Thanks.
The paint() method is called every time a frame of your game is drawn on the screen. When you make it drawn "only once," you made it literally draw "only once," as in, for only one frame, since frames are being update really fast, the text flashes and then never shows up again. I recommend having something like this:
long userFired;
// when the user fires -> userFired = System.currentTimeMillis();
paint() { /*the "2000" means that the text will display for 2 seconds*/
if(System.currentTimeMillis()-userFired < 2000 && deadWumpus()==true) {
g.drawString("You hear a scream.",300,675);
}
}
I'm having trouble with event driven input detection for moving my actors.
I'm currently using a GestureDetector and detecting a Tap (this all works)`
#Override
public void show() {
GestureDetector GD = new GestureDetector(this);
InputMultiplexer inputMulti = new InputMultiplexer();
inputMulti.addProcessor(hudStage);
inputMulti.addProcessor(GD);
Gdx.input.setInputProcessor(inputMulti);
}
#Override
public boolean tap(float x, float y, int count, int button) {
System.out.println("YOU HAVE PERFORMED A TAP");
this.playStage.act(Gdx.graphics.getDeltaTime());
return true;
}`
Currently tap just prints out something along the lines of you have performed a tap(see above) it also calls the stage act method which works partly (It moves the actor a frames worth of movement instead of the entire distance). I've used polling to get the actor to perform how I want as i can call the method in the render loop which then allows it to continue updating movements frame by frame. Using Event driven I've not currently found a of updating it frame by frame so instead it does as much as it can in one frame and then stops.
I've looked around, a lot, looked into threading but it seems libgdx is not thread safe. My main problem with going back to polling is that i need to separate out my stages and I'm not entirely sure how to do that.
For polling i didn't use an action but used this code
if(!fStarted){
if (Gdx.input.isTouched()) {
fStarted = true;
touchX = Gdx.input.getX();
spriteX = cSprite.x;
}
}
final float dv = delta * speed;
if (Math.abs(touchX - spriteX) > 45) {
playStage.getBatch().draw(flameImage, spriteX, fSprite.y);
if (spriteX < touchX) {
spriteX += dv;
//fSprite.x = spriteX;
}
if (spriteX > touchX) {
spriteX -= dv;
//fSprite.x = spriteX;
}
}
else{
spriteX = 9000;
fStarted=false;
}
fStarted just determines whether or not the actor is currently moving to a position. As the actor is a projectile I didn't want more than one at one point (game choices you know).
If there is any other information you need just comment and I'll provide it.
Clarity
How can I use event driven gesture detection to move an actor to a position that is tapped by the user?
I'm developing an application that needs to get all fingers on the screen of the Android. That's not complex, and I could make it in a few lines of code.
However, the way android sends callbacks is not what I need. I have done many tests, and here is what I could find out:
Once he sent the fingers positions, if no "big" movement has been made, he will not send a onTouch event.
Also, when a finger is REMOVED from the screen (for example: there are 3 fingers, and one is removed), it seems that it ONLY sends the next event, if at least one of the remaining fingers move on the screen.
I'm doing some tracking on fingers, and matching with objects, and to do this properly, I need to know all the fingers positions all the time. If there is not a way to "request" finger's touch event even when it didn't moved, how can I access the current finger positions without an callback event? Is there any other solution?
Here is my code:
ArrayList<Vector3> fingerTips = new ArrayList<Vector3>();
#Override
public boolean onTouchEvent(MotionEvent event) {
final int points = event.getPointerCount();
String out = "==========\n";
fingerTips.clear();
for(int i = 0; i < points; i++){
out += "\tPoint "+i+"\t("+event.getX(i)+", "+event.getY(i) + ")\n";
fingerTips.add( new Vector3(event.getX(i), event.getY(i)) );
}
Log.i(TAG, out);
// Send touches to SurfaceView
chwaziViewGL.onUpdateFingerTips(fingerTips);
return true;
}
My problem was that I didn't received one event with all the finger positions AFTER removing a finger...
After lot's of tests and logging, I discovered that it's true (in part).
Whenever you REMOVE a finger on the SCREEN, the NEXT event sent is an ACTION_POINTER_UP or ACTION_UP, meaning that the finger x is no longer touching the screen.
Since there was NO motion after removing the finger, the last MotionEvent sent was the UP, containg the removed finger also.
So, to fix that, I check if the action is UP, and on the loop that get's all the fingers, I created an if checking if that was the finger removed from the screen. If so, I just didn't add it to the array.
Here is my final code:
ArrayList<Vector3> fingerTips = new ArrayList<Vector3>();
#Override
public boolean onTouchEvent(MotionEvent event) {
final int points = event.getPointerCount();
// Check if it's an event that a finger
// was removed, if so, set removedPoint
int removedPoint = -1;
final int action = event.getAction() & MotionEvent.ACTION_MASK;
if(action == MotionEvent.ACTION_POINTER_UP || action == MotionEvent.ACTION_UP)
removedPoint = (action & MotionEvent.ACTION_POINTER_INDEX_MASK)
>> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
String out = "==========\n";
fingerTips.clear();
for(int i = 0; i < points; i++){
// Find out pointer ID
int pointerID = event.getPointerId(i);
if(pointerID == MotionEvent.INVALID_POINTER_ID){
out += "\tPoint "+pointerID+" INVALID\n";
continue;
}
// Check if it's the removed finger
if(removedPoint == i){
out += "\tPoint "+pointerID+" REMOVED\n";
continue;
}
out += "\tPoint "+pointerID+"\t("+event.getX(i)+", "+event.getY(i) + ")\n";
fingerTips.add( new Vector3(event.getX(i), event.getY(i), pointerID) );
}
Log.i(TAG, out);
// Send touches to SurfaceView
chwaziViewGL.onUpdateFingerTips(fingerTips);
return true;
}
Sorry, but your code cost me a lot of hairs;-(( After days I found the problem finally before I got insane. This code
final int action = event.getAction() & MotionEvent.ACTION_MASK;
if(action == MotionEvent.ACTION_POINTER_UP || action == MotionEvent.ACTION_UP)
removedPoint = (action & MotionEvent.ACTION_POINTER_INDEX_MASK)
>> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
could have never been worked!!!
Why? Because if you mask the value that is coming from getAction() it is simply a plain integer value of the action. And when you try to use this plain value and masking it again with something, it has no meaning at all!
The correction is to use again event.getAction() in the seconds masking:
removedPoint = (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)
>> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
It was really a nightmare to find this. But anyway, I think you just wanted the best and help others:-))) Its ok.
I am developing an Android game in java where I will have a sprite that follows the user's finger and is supposed to fire a bullet every second. In other words, I am trying to attach a bitmap that moves up every second. The bitmap starts at the x and y coordinates of the main character sprite. I can't get it to draw more than one missile at a time, and I have run out of ideas of how to do so. I have tried so many things, and I really could use some help.
By the way, my Main Game Panel class extends a surfaceView and implements a SurfaceHolder.Callback:
public class MainGamePanel extends SurfaceView implements SurfaceHolder.Callback{
Thanks!
As far as I understand you want to have the ability to shoot more than 1 bullet at a time? You can use a Vector or Array to do this. With an Array you can set a default amount of visible bullets and in a Vector you could have as mant bullets that your finger is capable of producing.
Here's my code that I use to generate lasers (I store the values in an Array).
public void updatePlayerLaser(boolean shootLaser) {
// Check if a new Laser should be created
if(shootLaser == true) {
if(timeLastCreatedLaser + 100 < System.currentTimeMillis()) {
timeLastCreatedLaser = System.currentTimeMillis();
boolean createdNewLaser = false;
for(int i = 0; i < this.amountOfVisibleLasers; i++) {
if(createdNewLaser == false) {
if(holderLaser[i].isDisposed()) {
this.generateNewLaser(i);
createdNewLaser = true;
}
}
}
}
}
// Update all the other Lasers
for(int i = 0; i < this.amountOfVisibleLasers; i++) {
if(holderLaser[i].isDisposed() == false) {
holderLaser[i].update();
}
}
}
Disposed in this contexts means that the laser is dead, thus making space for a new laser to take the old lasers spot.