Does Swing keep scanning for keyboard input (java)? - java

I am trying to move an image that I have drawn onto a Jpanel using g.drawImage(). I need to know why this code isn't working (I am trying to reposition the image using the w key to move it up)
int CharX = 1;
int CharY = 30;
public void keyPressed(KeyEvent w) {
CharY = CharY + 1;
repaint();
}
public void keyReleased(KeyEvent w) {
CharY = CharY + 1;
repaint();
}

You're not actually checking for the w key just by naming the KeyEvent w. You need to check if (w.getKeyCode() == KeyEvent.VK_W)
Y-coordinates in Java start with 0 at the top, so you might want to subtract from CharY to make it go up.
This will update twice, once when the key is pressed, and again when you let it go. Not sure if that's what you actually want.
Without knowing what's inside your paint function, or if you even implemented it, it's hard to say if the problem isn't actually in there, but it should look something like
public void paint(Graphics g) {
g.drawImage(yourImage, CharX, CharY, null);
}

You should not call repaint() inside the keyPressed() or keyReleased() method.
public void keyPressed(w.getKeyCode() == KeyEvent.VK_W) {
CharY = CharY + 1;
}
Call repaint() later.

Related

Processing Animation Troubles

I'm back with another Processing question. This time it's about animation. I'm trying to make a simple animation for my group's character sprite, but it's not working too well.
I tried to fix it by watching tutorials but they weren't helpful. Most of them were general animations that weren't for games (such as making circles float like bubbles or fall like balls) and the game-related tutorials were few and far in between. Most involved spritesheets, something we're not using, and the ones my friends and I watched and implemented didn't work either.
The animation is supposed to be a simple three-frame walk cycle. At the moment, the code is close to what we're trying to do, it's displaying the character, but the frames are overlapping instead of running an animation. Here is the code that is dedicated to the animation:
public void keyPressed() {
if (key == CODED) {
if (keyCode == LEFT) {
inMotion = true;
System.out.println("Left");
posX = posX - 5;
} else if (keyCode == RIGHT) {
inMotion = true;
posX = posX + 5;
System.out.println("Right");
} else {
inMotion = false;
}
}
}
public void draw() {
background(bg_game);
fill(50, 10, 10, 150);
if (inMotion) {
//System.out.println("CHar is in motion");
for (int i = 0; i < 3; i++) {
System.out.println(i);
image(playerImages[i], posX, posY, width, height);
if (!(i < 3)) {
i=0; //restarts for loop
}
}
} else {
image(playerImages[1], posX, posY, width, height);
}
}
If there's a better way for us to handle this, let us know!
In Processing, the draw() block is run between each frame. The computer does something like this:
run contents of the setup() block
display the result on the screen
run the draw() block
display the result on the screen
repeat steps 3 and 4
So when you put the for loop inside of draw(), it does this:
render the first walking frame
render the second walking frame (on top of the first)
render the third walking frame (on top of the others)
display the result on the screen
This clearly displays all three frames simultaneously, without cycling between them on different frames. You might do something like this:
int motionFrameStart = 0;
float walkSpeed = 20;//number of frames in a full cycle of walking
public void keyPressed() {
if (key == CODED) {
motionFrameStart = frameCount;
//... the rest of your keyPressed() code
}
}
public void draw() {
background(bg_game);
fill(50, 10, 10, 150);
if (inMotion) {
image(playerImages[(playerImages.length/walkSpeed)*((frameCount - motionFrameStart)%walkSpeed)], posX, posY, width, height);
} else {
image(playerImages[1], posX, posY, width, height);
}
}
In this version, when you press a key, the computer saves the frame when the walking started on, and then calculates which walking picture to use based on how many frames have been displayed since the button was pressed.

How to fix Java listening to more than 1 key at a time?

Me and my partner are attempting to create the game Pong for our computer science final project. We created a reference code where 2 cubes can be controlled upwards and downwards and it works fine. The problem occurs when attempting to control both cubes at the same time (only 1 cube will move at a time). We want to make both cubes move at the same time.
WE want to say that:
yPos - is the y position of the black cube
xPos - is the x position of the black cube
xPos2 - is the x position of the blue cube
YPos2 - is the y position of the blue cube
Keys:
A - Go up for black cube
Z - Go down for black cube
K - Go up for blue cube
M - go down for blue cube
We have tried using a more complicated version which used j-label animation. How ever we want to make our pong game through the graphics function. But we do not understand:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class PongHelpNeed extends JFrame implements KeyListener
{
// booleans to tell which key is pressed
boolean upKey;
boolean downKey;
boolean upKey2;
boolean downKey2;
// the position variables
int yPos;
int xPos;
int xPos2;
int yPos2;
public PongHelpNeed ()
{
//create window
super ("Controller");
setSize (660, 700);
// set keys to false and original positions
upKey = false;
downKey = false;
upKey2 = false;
downKey2 = false;
xPos = 100;
yPos = 350;
xPos2 = 500;
yPos2 = 350;
// add the frame as a listener to your keys
addKeyListener (this);
// Show the frame
setVisible(true);
}
//needs to be here because the class implements KeyListener
public void keyTyped (KeyEvent e)
{
System.out.println (e.getKeyCode () + " Typed");
}
//needs to be here because the class implements KeyListener
public void keyPressed (KeyEvent e) {
//check if keys a,z or k,m are pressed
if (e.getKeyCode () == KeyEvent.VK_A)
{
upKey = true;
}
else if (e.getKeyCode () == KeyEvent.VK_Z)
{
downKey = true;
}
else if (e.getKeyCode () == KeyEvent.VK_K)
{
upKey2 = true;
}
else if (e.getKeyCode () == KeyEvent.VK_M)
{
downKey2 = true;
}
//repaint the window everytime you press a key
repaint ();
}
//needs to be here because the class implements KeyListener
public void keyReleased (KeyEvent e)
{
System.out.println (e.getKeyCode () + " Released");
}
//paints the pictures
public void paint (Graphics g)
{
//set background
g.setColor(Color.WHITE);
g.fillRect(0, 0, 660, 700);
//cube 1
g.setColor(Color.BLACK);
g.fillRect(xPos,yPos,50, 50);
//draw cube 2
g.setColor(Color.BLUE);
g.fillRect(xPos2,yPos2, 50, 50);
//if keys are pressed move the cubes accordingly up or down
if (upKey == true)
{
yPos = yPos - 15;
upKey = false;
}
else if (downKey == true)
{
yPos = yPos + 15;
downKey = false;
}
else if (downKey2 == true){
yPos2 = yPos2 + 15;
downKey2 = false;
}
else if (upKey2 == true) {
yPos2 = yPos2 - 15;
upKey2 = false;
}
}
public static void main (String[] args)
{
new PongHelpNeed ();
}
}
Our expected results are we are trying to move both cube at the same time. So when we press the A key and the K key the black square should move and the blue cube should move.
Calling repaint() does not trigger a call to the paint immediately, so it's possible that the keyPressed is triggered twice (or more) before paint.
In your paint method you are checking the keys in if-else, which means that if one of the flags is true, the rest are not checked. You also have a race condition where the keyPressed is fighting with paint over the flags. Also, if you press a key quickly multiple times, you'll lose all the extra key presses between the first handled event and the next repaint.
Instead of doing the move within paint, you should do it within the keyPressed handler. Don't set a flag to e.g. upKey = true;, but instead do the action directly: yPos = yPos - 15;. The paint method will then just refresh the view to reflect the current (updated) state.

keyPressed() event carries on firing even after i stop pressing the key

So the object that I've drawn starts moving either up or down depending on what arrow key I've pressed but once i let go it carries on moving in the same direction not stopping unless i press a random key. If i press up it starts moving up and carries on moving up even after letting go of up. If i then press down it starts moving down and carries on moving down even after i am no longer pressing it. If any key other than up arrow key or down arrow key is pressed whilst it is moving it stops moving.
MAIN SKETCH:
Defender defender1;
PImage background;
int x=0; //global variable background location
void setup() {
size(800,400);
background = loadImage("spaceBackground.jpg");
background.resize(width,height);
defender1 = new Defender(200,200);
}
void draw () {
image(background, x, 0); //draw background twice adjacent
image(background, x+background.width, 0);
x -=4;
if(x == -background.width)
x=0; //wrap background
defender1.render();
defender1.keyPressed();
}
Defender Class:
class Defender {
int x;
int y;
Defender(int x, int y) {
this.x = x;
this.y = y;
}
void render() {
fill(255,0,0);
rect(x,y,50,20);
triangle(x+50,y,x+50,y+20,x+60,y+10);
fill(0,0,100);
rect(x,y-10,20,10);
}
void keyPressed() {
if (key == CODED) {
if (keyCode == UP) {
defender1.y = y-1;
} else if (keyCode == DOWN) {
defender1.y = y+1;
}
}
}
}
You're calling your defender1.keyPressed() function every time draw() is called.
The key and keyCode variables hold the most recently pressed key, regardless of whether that key is currently being held down.
To check whether any key is currently being pressed, you could use the keyPressed variable.
Or you could change your code to only call defender1.keyPressed() from the sketch-level keyPressed() function.
You can find more info in the reference.
Shameless self-promotion: here is a tutorial on user input in Processing.

Rocket move through class. Processing

I have a moving image as a background
PImage background;
int x=0; //global variable background location
rocket Rocket;
void setup(){
size(800,400);
background = loadImage("spaceBackground.jpg");
background.resize(width,height);
Rocket = new rocket();
}
void draw ()
{
image(background, x, 0); //draw background twice adjacent
image(background, x+background.width, 0);
x -=4;
if(x == -background.width)
x=0; //wrap background
Rocket.defender();
Rocket.move();
}
In a different class i'm trying to make a rocket move up and down
class rocket {
float x;
float y;
float speedy;
boolean up;
boolean down;
rocket(){
x = 50;
y = 200;
speedy = 3;
}
void move() {
if(up)
{
y = y - speedy;
}
if(down)
{
y = y + speedy;
}
}
void defender(){
fill(255,0,0);
rect(x,y,50,20);
triangle(x+50,y,x+50,y+20,x+60,y+10);
fill(0,0,100);
rect(x,y-10,20,10);
}
void keyPressed(){
if(keyCode == UP)
{
up = true;
}
if(keyCode == DOWN)
{
down = true;
}
}
void keyReleased(){
if(keyCode == UP)
{
up = false;
}
if(keyCode == DOWN)
{
down = false;
}
}
}
The rocket will display but won't move. I tried everything I know but nothing works. I also tried the rocket class just as a project by itself and the rocket moves, so it has to be something with the class. i'm quite new to coding so please keep that in mind, thank you in advance.
The keyPressed() and keyReleased() functions (and any other event function) need to be at the sketch level, not inside another class. If they're inside another class, Processing doesn't know how to find them.
So, what you need to do is move the keyPressed() and keyReleased() functions to the sketch, and then call functions on your Rocket class (class names should start with an upper-case letter, btw), similar to how you're calling rocket.defender() and rocket.move() (variable names should start with a lower-case letter) from the sketch-level draw() function.

override the rate settings of the mouse. Creating my own mouse rate algorithm

I am working with disabled children, who have cerebral palsy. One child has limited fine motor control, so she currently uses a joystick to control the mouse, and it's traverse rate is set very low. This works well for her, as she can click all buttons on the screen, but I think we could do better - when she wants to traverse the whole screen it takes an age to do so (about 10 seconds).
My hypothesis is that her brain is fine, and only her motor control is poor. If that's true, I believe that a mouse that started at a low speed, but experienced a constant acceleration, would be better for her, as it would pick up speed and become quick when traversing the whole screen.
If this works, then we could be tweaking PID control, and velocity/acceleration setting for a great number of disabled people, speeding up their access and hence their learning and development.
But I do not know the best way to build this - all suggestions, thoughts, links and tips welcome.
To begin with I have tried using Processing and Java, and using a mouseListener, and a Robot to control the cursor. I'm not convinced that this is the best way though, as I'm reading the cursor position and then writing to it, so my best attempts still make the cursor jump around, and there is not smooth movement. Is it achievable in Java? Do I need to read the mouse input from the USB using some kind of driver, and then replace the plotting of the cursor on screen with my own?
I've made a couple of videos to illustrate the effect I am trying to bring about.
The Status quo (my illustration is driving the cursor off the arrow keys)
http://www.youtube.com/watch?v=3ZhQCg5DJt8
The new behaviour I want (mouse accelerates)
http://www.youtube.com/watch?v=JcBK_ZCFGPs
if it's any use, the Processing code I used to make those demos is copied in below:
Status quo demo:
import java.awt.AWTException;
import jav
a.awt.Robot;
Robot robot;
int i = 0;
int j = 0;
void setup() {
setupDotgame();
try {
robot = new Robot();
}
catch (AWTException e) {
e.printStackTrace();
}
robot.mouseMove(screenWidth/2, screenHeight/2);
}
void draw() {
//println(frameCount);
robot.mouseMove(screenWidth/2+8*i, screenHeight/2+8*j);
drawDotgame();
}
void keyPressed() {
if (keyCode == UP) {
j--;
}
else if (keyCode == DOWN) {
j++;
}
else if (keyCode == RIGHT) {
i++;
}
else if (keyCode == LEFT) {
i--;
}
}
Desired behaviour:
import java.awt.AWTException;
import java.awt.Robot;
Robot robot;
int i = 0;
int j = 0;
int delta = 8;
int time = 0;
void setup() {
setupDotgame();
try {
robot = new Robot();
}
catch (AWTException e) {
e.printStackTrace();
}
robot.mouseMove(screenWidth/2, screenHeight/2);
}
void draw() {
//println(frameCount);
robot.mouseMove(screenWidth/2+i, screenHeight/2+j);
drawDotgame();
}
void keyPressed() {
if (millis() - time < 90) {
delta += 8;
}
else { delta = 8; }
time = millis();
if (keyCode == UP) {
j-=delta;
}
else if (keyCode == DOWN) {
j+=delta;
}
else if (keyCode == RIGHT) {
i+=delta;
}
else if (keyCode == LEFT) {
i-=delta;
}
}
And the DotGame code they both reference:
void setupDotgame() {
size(1000, 600);
background(255);
fill(255, 0, 0);
noStroke();
smooth();
drawCircle();
}
void drawDotgame() {
if (get(mouseX, mouseY) != color(255)) {
background(255);
drawCircle();
}
}
void drawCircle() {
int x = round(random(50, width-50));
int y = round(random(50, height-50));
int rad = round(random(20, 80));
ellipse(x, y, rad, rad);
}
Thanks in advance
as Carl suggested, I believe the best answer short of making the mouse actually have this behavior, is some sort of jumping behavior that will get the mouse fairly close to where you need to go, then use the joystick from there.
I happen to know that a program called AutoItv3 can do this sort of thing. You could set it up to recognize special hotkeys, then have that hotkey move the mouse to whatever region you wish.
Commands useful for this are HotKeySet, MouseMove, and Func/EndFunc.

Categories