I am developing a Java 2D Game, in which I have used a KeyListener, but as you probably can guess, it has focusing issues, mainly when the Player is running and you keep the same key pressed for long, for example pressing "W" to run forward, but after some seconds of keep pressing W, the KeyListener dies and no key works, I want to use KeyBindings, as most people suggest it for game development, but I cannot find any usefull tutorials, most of them use some form of Buttons, and other useless features for my game, so how can i avoid the KeyListener from losing focus, or how can I write a simple KeyBinding code, that only moves the player, and other simple stuff used in a game.
This is the kind of Key Binding that I want, I KNOW IT DOES NOT WORK, it is an example:
component.getInputMap().put(KeyStroke.getKeyStroke(VK_W),
"move forward")
component.getActionMap().put("released",
releasedAction);
if(releasedAction == true){
Player.playerSpeedY = 7;
} else{
Player.playerSpeedY = 0;
}
FWI: this is the current KeyListener code:
if(HUD.PlayerHealth > 0){
if(key == KeyEvent.VK_W) {Player.playerSpeedY = -5; keyDown[0]= true;}
if(key == KeyEvent.VK_S) {Player.playerSpeedY = 5; keyDown [1]= true;}
if(key == KeyEvent.VK_A) {Player.playerSpeedX = -5; keyDown [2]= true;}
if(key == KeyEvent.VK_D) {Player.playerSpeedX = 5; keyDown [3]= true;}
}
I keep looking for Actions and Input maps tutorials, or KeyBinding ones, and I just don't find anything useful, another dough, the component in action and input map, what is it for?, should my entire code be based on that, and is there any way to only make the action map move the player, and only that?
Try something like this:
this.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0, false), "right");
this.getActionMap().put("right", new AbstractAction() {
public void actionPerformed(ActionEvent e) {
//Do Something Here
Player.playerSpeedX = 5;
}
});
How to use KeyBindings
Related
I'm quite new to Processing.
I'm trying to make Processing randomly play a video after I clear the screen by mouseclick, so I create an array that contain 3 videos and play one at a time.
Holding 'Spacebar' will play a video and release it will stop the video. Mouseclick will clear the screen to an image. The question is how can it randomize to another video if I press spacebar again after clear the screen.
I've been searching all over the internet but couldn't find any solution for my coding or if my logic is wrong, please help me.
Here's my code.
int value = 0;
PImage photo;
import processing.video.*;
int n = 3; //number of videos
float vidN = random(0, n+1);
int x = int (vidN);
Movie[] video = new Movie[3];
//int rand = 0;
int index = 0;
void setup() {
size(800, 500);
frameRate(30);
video = new Movie[3];
video[0] = new Movie (this, "01.mp4");
video[1] = new Movie (this, "02.mp4");
video[2] = new Movie (this, "03.mp4");
photo = loadImage("1.jpg");
}
void draw() {
}
void movieEvent(Movie video) {
video.read();
}
void keyPressed() {
if (key == ' ') {
image(video[x], 0, 0);
video[x].play();
}
}
void mouseClicked() {
if (value == 0) {
video[x].jump(0);
video[x].stop();
background(0);
image(photo, 0, 0);
}
}
You have this bit of logic in your code which picks a random integer:
float vidN = random(0, n+1);
int x = int (vidN);
In theory, if you want to randomise to another video when the spacebar is pressed again you can re-use this bit of logic:
void keyPressed() {
if (key == ' ') {
x = int(random(n+1));
image(video[x], 0, 0);
video[x].play();
}
}
(Above I've used shorthand of the two lines declaring vidN and x, but the logic is the same. If the logic is harder to follow since two operations on the same line (picking a random float between 0,n+1 and rounding down to an integer value), feel free to expand back to two lines: readability is more important).
As side notes, these bit of logic look a bit off:
the if (value == 0) condition will always be true since value never changes, making both value and the condition redundant. (Perhaps you plan to use for something else later ? If so, you could save separate sketches, but start with the simplest version and exclude anything you don't need, otherwise, in general, remove any bit of code you don't need. It will be easier to read, follow and change.)
Currently your logic says that whenever you click current video resets to the start and stops playing and when you hit the spacebar. Once you add the logic to randomise the video that the most recent frame of the current video (just randomised) will display (image(video[x], 0, 0);), then that video will play. Unless you click to stop the current video, previously started videos (via play()) will play in the background (e.g. if they have audio you'll hear them in the background even if you only see one static frame from the last time space was pressed).
Maybe this is the behaviour you want ? You've explained a localised section of what you want to achieve, but not overall what the whole of the program you posted should do. That would help others provide suggestions regarding logic.
In general, try to break the problem down to simple steps that you can test in isolation. Once you've found a solid solution for each part, you can add each part into a main sketch one at a time, testing each time you add something. (This way if something goes wrong it's easy to isolate/fix).
Kevin Workman's How To Program is a great article on this.
As a mental excercise it will help to read through the code line by line and imagine what it might do. Then run it and see if the code behaves as you predicted/intended. Slowly and surely this will get better and better. Have fun learning!
I am quite new to programming and decided to make a little game, so far I have only made a small block that is able to move in all 4 directions (left, right, up and down). Pretty simple and nothing extra-ordinary. However, when I run my program, sometimes it will stop working, not as in crashing causing Processing itself to crash, but my program will just end.
As far as my testing goes, I think this happens when I press two keys at the same time (like W and S). Does anyone happen to know what causes it to stop, and perhaps how to fix it as well?
void setup(){
size(1080,720);
frameRate(30);
}
int shipLR = 0; //Variable for the ship to go left/right
int shipUD = 0; //Variable for the ship to go up / down
void draw(){
background(0);
shipLR = constrain(shipLR, 0, 1040); //Constrain the ship in the window
shipUD = constrain(shipUD,0,680); // Constrain the ship in the window
move();
Shuttle();
}
void Shuttle(){
rect(shipLR, shipUD, 40,40); //Draw the ship
}
void move(){
if (keyPressed) {
if (key == 'a') {
shipLR = shipLR - 20; // Go left
return;}
if (key == 'd') {
shipLR = shipLR + 20; // Go right
return;}
if (key == 'w'){
shipUD = shipUD - 20; // Go up
return;}
if (key == 's') {
shipUD = shipUD + 20; // Go down
return;}
}
}
Any help will be greatly appreciated.
Edit: I found something that causes this problem to occur more frequent; If I implement a frameRate of a value lower than 60 (currently trying with 30) this happens more often.
Edit 2: With the suggestions below of making my move function in a single if block had a lot of good impact. The program no longer stops when I move the ship in the middle of the window it no longer stops, it now only does it at rare occasions when I bump too often against the borders of the window. Perhaps it has something to do with constrain?
in move() (java naming conventions specify that method names start with lower case) you should exit on the first key pressed found. the code can be re-organized to reduce multiple identical conditions:
void move(){
if (keyPressed) {
if (key == 'a') {
shipLR = shipLR - 20; // Go left
return;
}
if (key == 'd') { // still inside if keyPressed
shipLR = shipLR + 20; // Go right
return;
}
if (key == 'w') {
...
}
} // end of if keyPressed
}
My guess it that the program doesn't "stop working" or end- it's just that your rectangle stops moving. If you let go of all the keys, then push just one key, I'd bet that the rectangle starts moving again. (In the future, please try to be more specific- saying "it stops working" isn't very helpful.)
Anyway, that's because of the way you're handling the key presses. What happens if you press a key other than the ones you're checking for?
You'll enter the move() function, and you'll enter the if(keyPressed) block, but you won't enter any if the other if statements inside that block. The key variable only holds the most recently pressed key.
Depending on what you want to do, you should either refactor those if statements to only change the direction if the key was valid, and to ignore all other key presses. Or you might want to use a set of boolean variables to track multiple keys being pressed at the same time. More info on that approach can be found here.
If you still can't get it working, then please try to be more specific about exactly what happens.
I'm creating a game where the player will use Drag gestures to "slash" an enemy, swiping their finger across the screen to kill them.
I have a feeling this should be easier than it is, but currently the code I have to detect this is:
while (TouchPanel.IsGestureAvailable)
{
GestureSample gs = TouchPanel.ReadGesture();
if (gs.GestureType == GestureType.FreeDrag ||
gs.GestureType == GestureType.HorizontalDrag ||
gs.GestureType == GestureType.VerticalDrag)
{
Current_Start = gs.Position;
Current_End = Current_Start + gs.Delta;
}
if (gs.GestureType == GestureType.DragComplete)
{
DragEnded = true;
}
}
This isn't quite working, though. I need the two vectors of:
Where the drag started
Where the drag ended
What is wrong, and how would I get this to work?
I would try using the onmousedown and onmouseup events to get the start and end points and go from there.
Trying to make an xna game, where the user needs to tap to stop a bar going down. The simulation is like what we see in a WWE PS3/xbox game, the give up bar.
Anyway, the way i have done it, serves the purpose. However, if the user holds the touch, touch values keep incrementing.
What I want is, if the user taps it, only 1 point will be scored. And when he taps again, he will get 1 point more. At the moment what is happening is, if the user holds it, it keeps incrementing, kind of like in a keyboard (if u hold a button, keypresses keeps going on).
foreach (TouchLocation location in TouchPanel.GetState())
{
if (location.State == TouchLocationState.Moved)
{
touchPoints++;
break;
}
}
Change from TouchLocationState.Moved to TouchLocationState.Pressed. That should only occur with each new touch.
foreach (TouchLocation location in TouchPanel.GetState())
{
TouchLocation prevLocation;
bool prevLocationAvailable = location.TryGetPreviousLocation(out prevLocation);
if (location.State == TouchLocationState.Pressed && prevLocation.State != TouchLocationState.Pressed)
{
touchPoints++;
break;
}
}
And for the future, if you're doing Keyboard input and want each press of the keyboard to increment the value but to be ignored if the player is holding down the space, you just have to store the previous state of the keyboard. Then you compare if the current keyboard state the key is being pressed and the previous keyboard state the key wasn't pressed.
(didn't actually code in compiler so there could be some code issues with the below)
KeyboardState currentKeyboardState = Keyboard.GetState();
if (currentKeyboardState.IsKeyDown(Keys.Space) && !previousKeyboardState.IsKeyDown(Keys.Space) {
//Do whatever it is you want to do with the press of the space key
}
previousKeyboardState = currentKeyboardState;
This is a snippet of my code of how i got each touch to be a individual value.
The system.diagnostics line is the test that will show you in your output box.
TouchCollection touch = TouchPanel.GetState();
foreach (TouchLocation touchLocation in touch)
{
if (touchLocation.State == TouchLocationState.Pressed)
{
base.InputPointX = touchLocation.Position.X;
base.InputPointY = touchLocation.Position.Y;
System.Diagnostics.Debug.WriteLine("X: " + base.InputPointX + \
", Y: " + base.InputPointY);
base.Update();
return true;
}
}
I am trying to write some code that will allow the user to draw on the touch screen.
When using either GestureService or ManipulationStarted/Delta, there's a "pause" that occurs when the user starts moving their finger - only when the finger is far enough from the point in which it started, only then do you start getting ManipulationDelta events (and like I said, same deal is true for GestureService).
What can I do to avoid this threshold? It really does not work well with drawing code.
Just blogged about it as I have come across similar questions on AppHub Forum.
https://invokeit.wordpress.com/2012/04/27/high-performance-touch-interface-wpdev-wp7dev/
Manipulation Delta and Gesture services are high level touch interfaces. If you want performance, consider using low level interfaces: Touch and an event called TouchReported. I tend to use them mostly (for drawing / position detection) in many of my projects
The event you want to plug in to detech touch is
Touch.FrameReported += Touch_FrameReported;
You can do this in Loaded event. Here's the implementation of the Touch_FrameReported handler. WorkArea is Canvas in this. I have also used this in conjugation with WritableBitmap
private void Touch_FrameReported(object sender, TouchFrameEventArgs e)
{
try
{
// Determine if finger / mouse is down
point = e.GetPrimaryTouchPoint(this.workArea);
if (point.Position.X < 0 || point.Position.Y < 0)
return;
if (point.Position.X > this.workArea.Width || point.Position.Y > this.workArea.Height)
return;
if (this.lbLetter.SelectedIndex == -1)
return;
switch (point.Action)
{
case TouchAction.Down:
draw = true;
old_point = point;
goto default;
case TouchAction.Up:
draw = false;
break;
default:
Draw();
break;
}
}
catch
{
MessageBox.Show("Application encountered error processing last request.");
}
}
This works lot better than high level interfaces.