Decreasing a Filled Rectangle's height from top - java

I am using a paintComponent Class in a project of mine, and I am currently wondering how I can decrease the size of the rectangle from the top making it's way downwards.
This is the part of the code:
public Battery(){
super();
firstTime = true;
f = new Font("Helvetica", Font.BOLD, 14);
m = Toolkit.getDefaultToolkit().getFontMetrics(f);
}
public void paintComponent(Graphics g){
if(firstTime){
firstTime = false;
batteryLevel = 1 + this.getHeight();
decr = batteryLevel / 20;
}else{
g.setColor(Color.RED);
g.fillRect(1, 0, this.getWidth(), this.getHeight());
g.setColor(Color.GREEN);
g.fillRect(1, 0, this.getWidth(), batteryLevel);
g.setColor(Color.BLACK);
g.setFont(f);
g.drawString("TEST", (getWidth() - m.stringWidth("TEST")) / 2 , this.getHeight() / 2);
}
}
public void decreaseBatteryLevel(){
batteryLevel -= decr;
this.repaint();
}
PS. Sorry if I did something wrong, I'm new to this forum.

As you want the visible battery level to descend you will want to increase your Y co-ordinate in relation to the value of batteryLevel. You could use:
g.fillRect(1, getHeight() - batteryLevel, getWidth(), batteryLevel);

Instead
g.fillRect(1, 0, this.getWidth(), batteryLevel);
Do
g.fillRect(1, batteryLevel, this.getWidth(), getHeight() - batteryLevel);
Also maybe repaint(50L) instead of repaint().
If your question meant: how to animate a change in the battery level.
Use a javax.swing.Timer:
int toPaintBatteryLevel = batteryLevel;
// In the paintComponent paint upto toPaintBatteryLevel.
Timer timer = new Timer(100, new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (toPaintBatteryLevl == batteryLevel) {
return;
}
if (toPaintBatteryLevl > batteryLevel) {
--toPaintBatteryLevel; // Animate slowly
} else {
toPaintBatteryLevel = batteryLevel; // Change immediately
}
repaint(50L);
};
});
timer.start();
For ease of coding, there is a permanent timer. And externally one changes the batteryLevel,
and the time determines the toPaintBatteryLevel, which paintComponent uses to paint.

Related

JAVA How can I update an already drawn string?

I am trying to repaint a string used to keep score in a small java game I'm making but I am not sure how to have the string change on the screen. As you can see it is initially drawn, and I am trying to update it inside of the ingame if statement.
public void paint(Graphics g)
{
super.paint(g);
g.setColor(Color.white);
g.fillRect(0, 0, d.width, d.height);
//g.fillOval(x,y,r,r);
//Draw Player
g.setColor(Color.red);
g.fillRect(p.x, p.y, 20, 20);
if(p.moveUp == true) {
p.y -= p.speed;
}
moveObstacles();
for (int i = 0; i < o.length; i++ ) {
g.fillRect(o[i].x, o[i].y, 10, 5);
}
Font small = new Font("Helvetica", Font.BOLD, 14);
FontMetrics metr = this.getFontMetrics(small);
g.setColor(Color.black);
g.setFont(small);
g.drawString(message, 10, d.height-60);
g.drawString(message2, 10, d.height-80);
if (ingame) {
for (int i = 0; i < o.length; i++ ) {
if ((o[i].x < p.x + 20 && o[i].x > p.x) && (o[i].y < p.y + 20 && o[i].y > p.y)) {
p.x = BOARD_WIDTH/2;
p.y = BOARD_HEIGHT - 60;
lives = lives - 1;
g.drawString(message, 10, d.height-60);
}
}
// g.drawImage(img,0,0,200,200 ,null);
}
Toolkit.getDefaultToolkit().sync();
g.dispose();
}
You create a method like setMessage(…). This method with then save the "message" as a property in your class.
The method will then invoke repaint(), which will cause the component to repaint itself.
This is how all Swing components work. Think about a JLabel and the setText(…) method.
Also:
Custom painting is done by overriding the paintComponent() method, not the paint() method.
There is no need for the Toolkit sync() method.
You should NOT dispose of the Graphics object.

How to hide JToolTip background when exceeding borders?

I've created this custom JToolTip for my application. When the tooltip is entirely diplayed inside a JFrame, no background is visible (expected), but when the tooltip is displayed outside the JFrame, the background will be visible. How can I have it removed either way?
I've tried setBackground(new Color(255, 255, 255, 0)); with the '0' alpha value to make sure the background is transparent, but that didn't do the trick.
The tooltip inside the frame, as expected:
The tooltip exceeding the JFrame, with the unwanted background:
The custom JTooltip:
public class DefaultToolTip extends JToolTip {
public DefaultToolTip() {
setOpaque(false);
setPreferredSize(new Dimension(275, 30));
setBackground(new Color(255, 255, 255, 0));
}
#Override
public void addNotify() {
super.addNotify();
setOpaque(false);
Component parent = this.getParent();
if (parent != null) {
if (parent instanceof JComponent) {
JComponent jparent = (JComponent) parent;
jparent.setOpaque(false);
}
}
}
#Override
public void paint(Graphics g) {
String text = getComponent().getToolTipText();
addNotify();
Graphics2D g2d = drawComponent(g);
drawText(text, g2d);
g2d.dispose();
}
private void drawText(String text, Graphics2D g2d) {
//Draw the text
int cHeight = getComponent().getHeight();
FontMetrics fm = g2d.getFontMetrics();
g2d.setColor(Color.WHITE);
if (cHeight > getHeight())
g2d.drawString(text, (getWidth() - fm.stringWidth(text)) / 2, (getHeight() + fm.getAscent()) / 2 + 2);
else
g2d.drawString(text, (getWidth() - fm.stringWidth(text)) / 2, (cHeight + fm.getAscent()) / 2 + 2);
}
private Graphics2D drawComponent(Graphics g) {
//Create a round rectangle
Shape round = new RoundRectangle2D.Float(0, 8, getWidth(), getHeight(), 8, 8);
//Draw the background
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.GRAY);
g2d.fill(round);
//Draw the left triangle
Point p1 = new Point(getWidth() / 2, getHeight() - 30);
Point p2 = new Point(getWidth() / 2 + 8, getHeight() - 20);
Point p3 = new Point(getWidth() / 2 - 8, getHeight() - 20);
int[] xs = {p1.x, p2.x, p3.x};
int[] ys = {p1.y, p2.y, p3.y};
Polygon triangle = new Polygon(xs, ys, xs.length);
g2d.fillPolygon(triangle);
return g2d;
}
}
Solution
A few things have changed to have the tooltip behave as expected. the paint method has been replaced by the paintComponent method, the addNotify call was removed, the method updated to fetch the window of the component and to give it a transparent background. setBorder(BorderFactory.createEmptyBorder()); was also needed to remove the components default border.
public class DefaultToolTip extends JToolTip {
public DefaultToolTip() {
setOpaque(false);
setPreferredSize(new Dimension(275, 30));
setBackground(new Color(255, 255, 255, 0));
setBorder(BorderFactory.createEmptyBorder());
}
#Override
public void addNotify() {
super.addNotify();
setOpaque(false);
Component parent = this.getParent();
if (parent != null) {
if (parent instanceof JComponent) {
JComponent jparent = (JComponent) parent;
jparent.setOpaque(false);
}
}
Window window = SwingUtilities.windowForComponent(this);
try {
window.setBackground(new Color(255, 255, 255, 0));
} catch (IllegalComponentStateException e) {
//Do nothing
}
}
#Override
public void paintComponent(Graphics g) {
//super.paintComponent(g);
String text = getComponent().getToolTipText();
Graphics2D g2d = drawComponent(g);
drawText(text, g2d);
g2d.dispose();
}
private void drawText(String text, Graphics2D g2d) {
//Draw the text
int cHeight = getComponent().getHeight();
FontMetrics fm = g2d.getFontMetrics();
g2d.setColor(Color.WHITE);
if (cHeight > getHeight())
g2d.drawString(text, (getWidth() - fm.stringWidth(text)) / 2, (getHeight() + fm.getAscent()) / 2 + 2);
else
g2d.drawString(text, (getWidth() - fm.stringWidth(text)) / 2, (cHeight + fm.getAscent()) / 2 + 2);
}
private Graphics2D drawComponent(Graphics g) {
//Create a round rectangle
Shape round = new RoundRectangle2D.Float(0, 8, getWidth(), getHeight(), 8, 8);
//Draw the background
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.GRAY);
g2d.fill(round);
//Draw the left triangle
Point p1 = new Point(getWidth() / 2, getHeight() - 30);
Point p2 = new Point(getWidth() / 2 + 8, getHeight() - 20);
Point p3 = new Point(getWidth() / 2 - 8, getHeight() - 20);
int[] xs = {p1.x, p2.x, p3.x};
int[] ys = {p1.y, p2.y, p3.y};
Polygon triangle = new Polygon(xs, ys, xs.length);
g2d.fillPolygon(triangle);
return g2d;
}
}
A note however, super.paintComponent(g) was commented out, since it would draw text another time.
Don't know if any of these will help but:
Don't override paint(...). Custom painting is done by overriding paintComponent(...).
Invoke super.paintComponent(...) as the first statement
Don't invoke addNotify() in a painting method. A painting method is for painting only.
with the '0' alpha value to make sure the background is transparent,
Swing components don't know how to handle transparent backgrounds. Just make the component non-opaque.
When the tooltip overlaps the component. The tooltip is actually added to a JWindow before it is displayed. So in your addNotify() logic, you can search for the window and make it transparent.
Check out:
Window window = SwingUtilities.windowForComponent(...);

How to move this eye applet or to make it blink?

Please help me how to make this eye move or to make it blink using repaint, thread and implements runnable. I don't know where to place the right codes to make it work. Please help me guys! Thank you!
Here is the code:
import java.awt.*;
import java.applet.*;
public class Pucca extends Applet {
public Pucca(){
setSize(700, 700); }
//paint method
public void paint(Graphics g){
Color white = new Color(255,255,255);
g.setColor(white);
g.fillOval(600, 100, 125, 125); //left white fill eye
g.setColor(Color.BLA­CK);
g.drawOval(600, 100, 125, 125); // left big black line eye
g.setColor(white);
g.fillOval(700, 100, 125, 125); //right white fill eye
g.setColor(Color.BLA­CK);
g.drawOval(700, 100, 125, 125); //right big black line eye
Color blue = new Color(0, 160, 198);
g.setColor(blue);
g.fillOval(635, 130, 51, 51); // left blue fill eye
g.setColor(Color.BLA­CK);
g.drawOval(635, 130, 50, 50); // left black small line eye
g.setColor(blue);
g.fillOval(735, 130, 51, 51); // right blue fill eye
g.setColor(Color.BLA­CK);
g.drawOval(735, 130, 50, 50); // right black small line eye
g.setColor(Color.BLA­CK);
g.fillOval(650, 145, 20, 20); // left black iris
g.setColor(Color.BLA­CK);
g.fillOval(750, 145, 20, 20); // right black iris
}
}
When it comes to animation, everything becomes variable. You also have a lot of repeated code (seriously, if you can paint one eye, you can paint lots).
The first thing you need to is make all the values of the eye as variable as possible.
The follow makes the eye size and position variable and the iris and pupil a scaled value of the eye size, which makes the whole process simpler to animate.
Next, you need an updated loop, which can update the state of the values you want to change. To keep it simple, I've set it up so that the pupil has a variable offset, which is changed over time.
import java.applet.Applet;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
public class Pucca extends Applet {
public Pucca() {
setSize(700, 700);
Thread t = new Thread(new Runnable() {
private int xDelta = -1;
private int yDelta = 0;
private int blinkCount = 0;
#Override
public void run() {
while (true) {
try {
Thread.sleep(40);
} catch (InterruptedException ex) {
}
xOffset += xDelta;
double irisSize = eyeSize.width * irisScale;
double range = ((eyeSize.width - irisSize) / 2);
if (xOffset <= -range) {
xOffset = -(int) range;
xDelta *= -1;
} else if (xOffset >= range) {
xOffset = (int) range;
xDelta *= -1;
}
blinkCount++;
if (blink && blinkCount > 10) {
blink = false;
blinkCount = 0;
} else if (blinkCount > 25) {
blink = true;
blinkCount = 0;
}
repaint();
}
}
});
t.setDaemon(true);
t.start();
}
private boolean blink = false;
private int xOffset, yOffset = 0;
private Dimension eyeSize = new Dimension(125, 125);
private Point left = new Point(20, 20);
private Point right = new Point(left.x + 100, left.y);
private double irisScale = 0.4;
private double pupilScale = 0.16;
//paint method
#Override
public void paint(Graphics g) {
super.paint(g);
paintEye(g, new Rectangle(left, eyeSize));
paintEye(g, new Rectangle(right, eyeSize));
}
protected void paintEye(Graphics g, Rectangle bounds) {
Color white = new Color(255, 255, 255);
if (blink) {
g.setColor(Color.YELLOW);
} else {
g.setColor(white);
}
g.fillOval(bounds.x, bounds.y, bounds.width, bounds.height); //left white fill eye
g.setColor(Color.BLACK);
g.drawOval(bounds.x, bounds.y, bounds.width, bounds.height); // left big black line eye
if (!blink) {
Color blue = new Color(0, 160, 198);
paintEyePartAt(g, bounds, irisScale, blue);
paintEyePartAt(g, bounds, pupilScale, Color.BLACK);
}
}
private void paintEyePartAt(Graphics g, Rectangle bounds, double delta, Color color) {
int width = (int) (bounds.width * delta);
int height = (int) (bounds.height * delta);
g.setColor(color);
g.fillOval(
xOffset + bounds.x + ((bounds.width - width) / 2),
yOffset + bounds.y + ((bounds.height - height) / 2),
width, height); // left blue fill eye
g.setColor(Color.BLACK);
g.drawOval(
xOffset + bounds.x + ((bounds.width - width) / 2),
yOffset + bounds.y + ((bounds.height - height) / 2),
width,
height); // left blue fill eye
}
}
This complicates things, as painting can occur for any number of reasons, many of which you don't have control over or will be notified about, so you should be very careful about where and when you change values.
You should also have a look at Java Plugin support deprecated and Moving to a Plugin-Free Web and Why CS teachers should stop teaching Java applets.
Applets are simply a dead technology and given the inherent complexities involved in using them, you should instead focus you should probably attention towards window based programs.
Personally, I'd start with having a look at Painting in AWT and Swing and Performing Custom Painting

Way to repaint this JPanel after given count

Hello I would like to prevent graphics drawing and drawing again but I don't know how to do, I just want my panel delete all painted graphics and restart with same code. I tried some methods posted here but no one does the job.
public class Main extends JPanel implements ActionListener {
Timer timer;
private double angle = 444;
private double scale = 1;
private double delta = 0.0001;
RoundRectangle2D.Float r = new RoundRectangle2D.Float();
int counter = 0;
public Main() {
timer = new Timer(55, this);
timer.start();
}
public void paint(Graphics g) {
counter++;
int h = getHeight();
int w = getWidth();
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(new Color(randomNumber(0, 155), randomNumber(0, 255),randomNumber(0, 155), randomNumber(0, 255)));
drawCircles(g2d, getWidth()/2, getHeight()/2, 250);
if(counter > 200){
g2d.clearRect (0, 0, getWidth(), getHeight());
super.paintComponent(g2d);
counter = 0;
}
}
public int randomNumber(int min, int max) {
int c = new Random().nextInt((max - min) + 1);
return c;
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setUndecorated(true);
Dimension dim = new Dimension(Toolkit.getDefaultToolkit()
.getScreenSize().width, Toolkit.getDefaultToolkit()
.getScreenSize().height);
frame.setSize(dim);
frame.setLocation(0, 0);
frame.setBackground(new Color(0, 0, 0, 255));
frame.add(new Main());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
void drawCircles(Graphics graphics, int xMid, int yMid, int radius) {
// end recursion
if(radius < 5)
return;
// Draw circle
// start recursion
//left
drawCircles(graphics, xMid-radius, yMid, radius / 2);
((Graphics2D) graphics).rotate(angle);
graphics.drawOval(xMid - radius, yMid - radius, radius * 2, radius * 2);
//right
drawCircles(graphics, xMid+radius, yMid, radius / 2);
graphics.drawOval(xMid - radius, yMid - radius, radius * 2, radius * 2);
((Graphics2D) graphics).rotate(angle);
((Graphics2D) graphics).rotate(angle);
((Graphics2D) graphics).setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
((Graphics2D) graphics).setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);
}
public void actionPerformed(ActionEvent e) {
if (scale < 0.01)
delta = -delta;
else if (scale > 0.99)
delta = -delta;
scale += delta;
angle += 0.001;
repaint();
}
}
I am not sure I understand you fully, but you can use a JToggleButton (for example) where is the toggle button is down it prevents drawing. I can see something like this inside your drawCircles() method:
void drawCircles(Graphics graphics, int xMid, int yMid, int radius)
{
if(!toggleBtn.isSelected() // the toggle button is pressed
{
// draw something
}
}
In your example, you are drawing two circles and two ovals. If I understood you correctly, you want to be able to pause in the middle of the method, for example, and only draw the first circle. Then, at some point, you want to continue drawing the two ovals and the remaining circle. Unfortunately, you cannot do that. You cannot stop (or pause) a method in the middle of it.
Methods have to execute to completion (whether to the end, or an exception is thrown). However, you can create some kind of task to draw ONE shape (for example, a circle). If you create multiple tasks, you can draw many circles. To accomplish this, you will need to learn about Concurrency and probably about Java Tasks. You can have these tasks execute in some kind of order and because of concurrency, you could pause and resume these drawing tasks the way I think you would want.

Swing: moving two graphics at the same time

I am working on Air Hockey Game for my midterm project.
I have problem with handling two graphics, in this case two handles each of them consists of 3 circles.
I can move only one handle because of keyPressed method.
Another problem is that I can't limit the moving domain, for example when you pressed → the red handle can go beyond the frame width.
I know first problem is related to thread, but I've studied this subject from last week.
My problems are in this class:
public class StartGamePanel extends JPanel implements KeyListener, ActionListener {
double xCircle1 = 200;
double yCircle1 = 100;
double xCircle2 = 200;
double yCircle2 = 700;
double velX = 0, velY = 0;
public StartGamePanel() {
Timer t = new Timer(5, this);
t.start();
addKeyListener(this);
setFocusable(true);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g.setColor(new Color(51, 153, 255));
g.fillRoundRect(5, 5, 485, 790, 10, 10);
addKeyListener(this);
Graphics2D southArc = (Graphics2D) g;
southArc.setColor(Color.WHITE);
southArc.setStroke(new BasicStroke(3));
southArc.drawArc(98, 640, 300, 300, 0, 180);
//
Graphics2D northArc = (Graphics2D) g;
northArc.setColor(Color.WHITE);
northArc.setStroke(new BasicStroke(3));
northArc.drawArc(98, -143, 300, 300, 180, 180);
Graphics2D line = (Graphics2D) g;
line.setStroke(new BasicStroke(3));
line.setColor(Color.white);
line.drawLine(6, 395, 488, 395);
Graphics2D dot = (Graphics2D) g;
dot.setColor(Color.black);
for (int j = 10; j < 800; j += 20) {
for (int i = 6; i < 502; i += 20) {
dot.drawLine(i, j, i, j);
}
}
Graphics2D circle1 = (Graphics2D) g;
circle1.setColor(new Color(255, 51, 51));
Shape theCircle = new Ellipse2D.Double(xCircle1 - 40, yCircle1 - 40, 2.0 * 40, 2.0 * 40);
circle1.fill(theCircle);
Graphics2D circle2 = (Graphics2D) g;
circle2.setColor(new Color(255, 102, 102));
Shape theCircle2 = new Ellipse2D.Double(xCircle1 - 35, yCircle1 - 35, 2.0 * 35, 2.0 * 35);
circle2.fill(theCircle2);
Graphics2D circle3 = (Graphics2D) g;
circle3.setColor(new Color(255, 51, 51));
Shape theCircle3 = new Ellipse2D.Double(xCircle1 - 20, yCircle1 - 20, 2.0 * 20, 2.0 * 20);
circle3.fill(theCircle3);
Graphics2D circleprim = (Graphics2D) g;
circleprim.setColor(new Color(0, 51, 102));
Shape theCircleprim = new Ellipse2D.Double(xCircle2 - 40, yCircle2 - 40, 2.0 * 40, 2.0 * 40);
circleprim.fill(theCircleprim);
Graphics2D circle2prim = (Graphics2D) g;
circle2prim.setColor(new Color(0, 102, 204));
Shape theCircle2prim = new Ellipse2D.Double(xCircle2 - 35, yCircle2 - 35, 2.0 * 35, 2.0 * 35);
circle2prim.fill(theCircle2prim);
Graphics2D circle3prim = (Graphics2D) g;
circle3prim.setColor(new Color(0, 51, 102));
Shape theCircle3prim = new Ellipse2D.Double(xCircle2 - 20, yCircle2 - 20, 2.0 * 20, 2.0 * 20);
circle3prim.fill(theCircle3prim);
Graphics2D ball = (Graphics2D) g;
ball.setColor(new Color(224, 224, 224));
Shape theball = new Ellipse2D.Double(200 - 20, 400 - 20, 2.0 * 20, 2.0 * 20);
ball.fill(theball);
Graphics2D ball2 = (Graphics2D) g;
ball2.setColor(new Color(160, 160, 160));
Shape theball2 = new Ellipse2D.Double(200 - 15, 400 - 15, 2.0 * 15, 2.0 * 15);
ball2.fill(theball2);
Graphics2D goal = (Graphics2D) g;
goal.setColor(Color.BLACK);
goal.fill3DRect(100, 0, 300, 10, true);
Graphics2D goal2 = (Graphics2D) g;
goal2.setColor(Color.BLACK);
goal2.fill3DRect(100, 790, 300, 10, true);
}
#Override
public void actionPerformed(ActionEvent e) {
repaint();
xCircle1 += velX;
yCircle1 += velY;
}
#Override
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
if (code == KeyEvent.VK_UP) {
velY = -2;
velX = 0;
}
if (code == KeyEvent.VK_DOWN) {
velY = 2;
velX = 0;
}
if (code == KeyEvent.VK_LEFT) {
if (xCircle1 < 0) {
velY = 0;
velX = 0;
} else {
velY = 0;
velX = -2;
}
}
if (code == KeyEvent.VK_RIGHT) {
if (xCircle1 > 200) {
velY = 0;
velX = 0;
}
velY = 0;
velX = 2;
}
}
#Override
public void keyReleased(KeyEvent e) {
int code = e.getKeyCode();
if (code == KeyEvent.VK_UP) {
velY = 0;
velX = 0;
}
if (code == KeyEvent.VK_DOWN) {
velY = 0;
velX = 0;
}
if (code == KeyEvent.VK_LEFT) {
velY = 0;
velX = 0;
}
if (code == KeyEvent.VK_RIGHT) {
velY = 0;
velX = 0;
}
}
#Override
public void keyTyped(KeyEvent e) { }
}
Thanks!
Your key listener should be as quick as possible so it does not block following key events. Since several people press keys almost at the same time, this situation is common in games.
So the advice would be to use separate thread to listen for key presses which will quickly add events to a queue. This queue then will be processed on EDT(Swing main thread) and paint the results.
You can check out the KeyboardAnimation.java example found in Motion Using The Keyboard. It attempts to explain why Key Bindings are preferred over using a KeyListener.
The example code will animate two images. The left image controlled by W, A, S, D and the right image by Up, Down, Left and Right arrow keys. It also keeps the images within the window bounds. The code is not an actual game, it was just designed to show one way to use configurable Key Bindings.
You might want to also want to change the way the keypress's are handled. At the moment (I think) your only detecting one key down at a time.
You probably need to have an array for "heldkeys" and every time a key is down, add to that array. When a key is released, subtract that key from it.
Then, at a interval, check what keys are in the "heldkeys" array and act on them all.
At least, you will probably need something like this if you plan to have two players. (who both should be able to press keys at the same time).
I don't know Swing well enough to give you exact code, but it will be something like;
//an array of numbers to hold the key-codes of the keys currently held down
HashSet<Integer> HeldKeys = new HashSet<Integer>();
#Override
public void keyDown(KeyEvent e) {
// add key to keys currently held down
HeldKeys.add(e.getKeyCode());
}
#Override
public void keyUp(KeyEvent e) {
//remove key from list of things currently held
HeldKeys.remove(e.getKeyCode());
}
#Override
public void keyPress(KeyEvent e) {
Iterator<Integer> kit = HeldKeys.iterator();
//we loop over every key currently held down, running actions for them if
//there is any assigned.
//For example, one button might move a sprite on the left down
//Another might move a sprite on the right. One, the other, or both should be
//able to all move without waiting for the other.
while (kit.hasNext()) {
int keycode = kit.next();
if (keycode==48){
//do stuff if key with code 48 is held
//(move one of the circles, etc)
}
if (keycode==46){
//do stuff if key with code 46 is held
}
//...etc, for any number of keys you want to do different things for.
}
}
Note; With this method you are not detecting a keypress as one thing, but rather detecting both the key being held down, and then the key being released as separate events.
As people wont hit the keys at the exact same time, this lets you detect lots of keys at once.
This code is off the top of my head, Java, but I have a gwt background, so the names for "keydown" and "keyup" etc might be different.
The "keypress" event in gwt will repeat automatically, if that's not the case in Swing you might need to use a Timer instead, running at an interval. (you might prefer this anyway as its a bit more controllable).

Categories

Resources