Initialize an Image - java

I'm trying to make top and bottom walls for my Pong game. I think I have everything right but it will not run because it says "The local variable wall may not have been initialized". How do I initialize an Image?
import java.awt.Graphics;
import java.awt.Image;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Wall extends Block
{
/**
* Constructs a Wall with position and dimensions
* #param x the x position
* #param y the y position
* #param wdt the width
* #param hgt the height
*/
public Wall(int x, int y, int wdt, int hgt)
{super(x, y, wdt, hgt);}
/**
* Draws the wall
* #param window the graphics object
*/
public void draw(Graphics window)
{
Image wall;
try
{wall = ImageIO.read(new File("C:/eclipse/projects/Pong/wall.png"));}
catch (IOException e)
{e.printStackTrace();}
window.drawImage(wall, getX(), getY(), getWidth(), getHeight(), null);
}
}
Thanks to everyone who answered I've figured it out. I didn't realize I just needed to set wall = null.

Your image is indeed initialised with the statement
wall = ImageIO.read(new File("C:/eclipse/projects/Pong/wall.png"));
However, the compiler is complaining because that statement could possibly fail, as it is in a try/catch block. A possible way to just "satisfy" the compiler is to set the Image variable to null:
Image wall = null;

You are initializing the Image correctly. The reason Java is complaining is you have it in a try block. Try blocks are not guaranteed to run and you don't compensate for the possibility of the code failing in the catch block, so it you (and more importantly, Java) can't be sure that wall will exist when you call window.drawImage(). A possible fix would be (cutting out the imports but with a bit of code for reference):
public class Wall extends Block
{
/**
* Constructs a Wall with position and dimensions
* #param x the x position
* #param y the y position
* #param wdt the width
* #param hgt the height
*/
public Wall(int x, int y, int wdt, int hgt)
{super(x, y, wdt, hgt);}
/**
* Draws the wall
* #param window the graphics object
*/
public void draw(Graphics window)
{
Image wall;
try
{wall = ImageIO.read(new File("C:/eclipse/projects/Pong/wall.png"));}
catch (IOException e)
{
e.printStackTrace();
wall = new BufferedWindow(getWidth(), getHeight(), <Correct Image Type>);
}
window.drawImage(wall, getX(), getY(), getWidth(), getHeight(), null);
}
}

Always initialization of the variable declared to class is important
Image wall = null;

Related

In GLFW Open Gl, its created frame buffer does not change size when the screen is stretched

I have one problem with frame buffers. I'm writing a project in java using the library LWJGL 2. There the display is created in Display.class. Just there when you create your own frame buffer on which I render the shadow map the screen changes the size of the buffer frame when you stretch the window. And also all works with a buffer of frames for reflection and refraction of water. But when I switched to LWJGL 3 I have a display created using the GLFW library. And there default frame buffer changes the size of the normally, and here is when I running an own frame buffer for water or shadows the I have the entire scene not changes the size of the from for this frame buffer.
As I understand the new frame buffer at the unbind the screen size of the original resolution. Supposedly the original screen resolution is 960x540 and I at the unbind of this permission, he puts.
No matter what I add a frame buffer for, it always does not measure the size when stretched.
Im tried use the GLFW getFramebufferSize:
public void resizeFramebuffer(int width, int height)
{
IntBuffer framebufferSize = BufferUtils.createIntBuffer(2);
GLFW.nglfwGetFramebufferSize(this.window, MemoryUtil.memAddress(framebufferSize),MemoryUtil.memAddress(framebufferSize + 4);
width = framebufferSize.get(0);
height = framebufferSize.get(1);
GlHelper.glViewport(0, 0, width, height);
}
But it works on the default frame buffer.
If anyone wants it here is my frame buffer object for shadows:
public class ShadowFrameBuffer extends FrameBuffer
{
private final int WIDTH;
private final int HEIGHT;
private int fbo;
private int shadowMap;
/**
* Initialises the frame buffer and shadow map of a certain size.
*/
public ShadowFrameBuffer(long windowId, int width, int height)
{
super(windowId, width, height);
this.WIDTH = width;
this.HEIGHT = height;
this.initialiseFrameBuffer();
}
/**
* Deletes the frame buffer and shadow map texture when the game closes.
*/
#Override
public void cleanUp()
{
GlHelper.glDeleteFramebuffers(fbo);
GlHelper.glDeleteTextures(shadowMap);
}
/**
* #return The ID of the shadow map texture.
*/
public int getShadowMap()
{
return shadowMap;
}
/**
* Binds the frame buffer, setting it as the current render target. Anything
* rendered after this will be rendered to this FBO, and not to the screen.
*/
public void bindDrawFrameBuffer()
{
if(GlHelperError.isFramebufferSupported())
{
TextureManager.bindTexture2d(0);
GlHelper.glBindFramebuffers(Framebuffer.FRAMEBUFFER, fbo);
GlHelper.glViewport(0, 0, WIDTH, HEIGHT);
}
}
/**
* Creates the frame buffer and adds its depth attachment texture.
*/
public void initialiseFrameBuffer()
{
this.fbo = createFrameBuffer();
this.shadowMap = createDepthBufferAttachment(WIDTH, HEIGHT);
this.unbindFrameBuffer();
}
/**
* Creates a frame buffer and binds it so that attachments can be added to
* it. The draw buffer is set to none, indicating that there's no colour
* buffer to be rendered to.
*
* #return The newly created frame buffer's ID.
*/
public static int createFrameBuffer()
{
int frameBuffer = GlHelper.glGenFramebuffers();
GlHelper.glBindFramebuffers(Framebuffer.FRAMEBUFFER, frameBuffer);
GlHelper.glDrawBuffers(Framebuffer.NONE);
GlHelper.glReadBuffer(Framebuffer.NONE);
return frameBuffer;
}
/**
* Creates a depth buffer texture attachment.
*
* #param width - the width of the texture.
* #param height - the height of the texture.
* #return The ID of the depth texture.
*/
private static int createDepthBufferAttachment(int width, int height)
{
int texture = GlHelper.glGenTextures();
TextureManager.bindTexture2d(texture);
GlHelper.glTexImage2D(0, Depth.DEPTH_COMPONENT16, width, height, 0,
Depth.DEPTH_COMPONENT, Texture.FLOAT, (ByteBuffer) null);
GlHelper.glTexParameteri(Texture.TEXTURE_MAG_FILTER, Texture.NEAREST);
GlHelper.glTexParameteri(Texture.TEXTURE_MIN_FILTER, Texture.NEAREST);
GlHelper.glTexParameteri(Texture.TEXTURE_WRAP_S, Texture.CLAMP_TO_EDGE);
GlHelper.glTexParameteri(Texture.TEXTURE_WRAP_T, Texture.CLAMP_TO_EDGE);
GlHelper.glFramebufferTexture(Framebuffer.FRAMEBUFFER, Depth.DEPTH_ATTACHMENT, texture, 0);
return texture;
}
}
If someone does not know what GlHelper is, then this is a class in which almost all Open Gl methods are connected to one class, so as not to write GL11, 12, 30, etc. Well, there are still some utilities.
Please help who than can. I would be very grateful. I myself am not new to Open Gl but I have faced this problem.
I figured out what my mistake was. I used GLFW.nglfwGetFramebufferSize() which got the size of the buffer frame on not the screen itself. I should have used GLFW.glfwGetWindowSize(), that's how it works. If anyone has the same problem here is the full code:
public void resize()
{
IntBuffer bufferedWidth = BufferUtils.createIntBuffer(1);
IntBuffer bufferedHeight = BufferUtils.createIntBuffer(1);
GLFW.glfwGetWindowSize(this.windowId, bufferedWidth, bufferedHeight);
}
And then in the decoupling of the buffer frame on which the scene is displayed, you need to add parameters from the saved buffer width and height:
public void unbindFrameBuffer()
{
Gl30.glBindFramebuffers(Framebuffer.FRAMEBUFFER, 0);
Gl11.glViewport(0, 0, bufferedWidth.get(0), bufferedHeight.get(0));
}
And we need to make sure that all these operations occur in a while loop.

How do you work with packages? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
Okay, I'm just a greenhorn here and I'm trying some various codes. Now this game GUI src I found have some image files inside a folder and its a necessity for the whole game to work.
I tried some methods, but I just can't understand how can I make the src connected to the folder. The program runs now but it only displays black screen because it can't connect to the images. Please, I need help.
What I just wanted is how can I make the program recognize the files I'm using as background images and such. The code line is there, but it displays an exception...
Am I still unclear? ._.
Well it goes like this:
package moon_lander;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
/**
* Actual game.
*
* #author www.gametutorial.net
*/
public class Game {
/**
* The space rocket with which player will have to land.
*/
private PlayerRocket playerRocket;
/**
* Landing area on which rocket will have to land.
*/
private LandingArea landingArea;
/**
* Game background image.
*/
private BufferedImage backgroundImg;
/**
* Red border of the frame. It is used when player crash the rocket.
*/
private BufferedImage redBorderImg;
public Game()
{
Framework.gameState = Framework.GameState.GAME_CONTENT_LOADING;
Thread threadForInitGame = new Thread() {
#Override
public void run(){
// Sets variables and objects for the game.
Initialize();
// Load game files (images, sounds, ...)
LoadContent();
Framework.gameState = Framework.GameState.PLAYING;
}
};
threadForInitGame.start();
}
/**
* Set variables and objects for the game.
*/
private void Initialize()
{
playerRocket = new PlayerRocket();
landingArea = new LandingArea();
}
/**
* Load game files - images, sounds, ...
*/
private void LoadContent()
{
try
{
URL backgroundImgUrl = this.getClass().getResource("/moon_lander/resources/images/background.jpg");
backgroundImg = ImageIO.read(backgroundImgUrl);
URL redBorderImgUrl = this.getClass().getResource("/moon_lander/resources/images/red_border.png");
redBorderImg = ImageIO.read(redBorderImgUrl);
}
catch (IOException ex) {
Logger.getLogger(Game.class.getName()).log(Level.SEVERE, null, ex);
}
}
/**
* Restart game - reset some variables.
*/
public void RestartGame()
{
playerRocket.ResetPlayer();
}
/**
* Update game logic.
*
* #param gameTime gameTime of the game.
* #param mousePosition current mouse position.
*/
public void UpdateGame(long gameTime, Point mousePosition)
{
// Move the rocket
playerRocket.Update();
// Checks where the player rocket is. Is it still in the space or is it landed or crashed?
// First we check bottom y coordinate of the rocket if is it near the landing area.
if(playerRocket.y + playerRocket.rocketImgHeight - 10 > landingArea.y)
{
// Here we check if the rocket is over landing area.
if((playerRocket.x > landingArea.x) && (playerRocket.x < landingArea.x + landingArea.landingAreaImgWidth - playerRocket.rocketImgWidth))
{
// Here we check if the rocket speed isn't too high.
if(playerRocket.speedY <= playerRocket.topLandingSpeed)
playerRocket.landed = true;
else
playerRocket.crashed = true;
}
else
playerRocket.crashed = true;
Framework.gameState = Framework.GameState.GAMEOVER;
}
}
/**
* Draw the game to the screen.
*
* #param g2d Graphics2D
* #param mousePosition current mouse position.
*/
public void Draw(Graphics2D g2d, Point mousePosition)
{
g2d.drawImage(backgroundImg, 0, 0, Framework.frameWidth, Framework.frameHeight, null);
landingArea.Draw(g2d);
playerRocket.Draw(g2d);
}
/**
* Draw the game over screen.
*
* #param g2d Graphics2D
* #param mousePosition Current mouse position.
* #param gameTime Game time in nanoseconds.
*/
public void DrawGameOver(Graphics2D g2d, Point mousePosition, long gameTime)
{
Draw(g2d, mousePosition);
g2d.drawString("Press space or enter to restart.", Framework.frameWidth / 2 - 100, Framework.frameHeight / 3 + 70);
if(playerRocket.landed)
{
g2d.drawString("You have successfully landed!", Framework.frameWidth / 2 - 100, Framework.frameHeight / 3);
g2d.drawString("You have landed in " + gameTime / Framework.secInNanosec + " seconds.", Framework.frameWidth / 2 - 100, Framework.frameHeight / 3 + 20);
}
else
{
g2d.setColor(Color.red);
g2d.drawString("You have crashed the rocket!", Framework.frameWidth / 2 - 95, Framework.frameHeight / 3);
g2d.drawImage(redBorderImg, 0, 0, Framework.frameWidth, Framework.frameHeight, null);
}
}
}
And this is the Exception:
Exception in thread "Thread-2" java.lang.IllegalArgumentException: input == null!
at javax.imageio.ImageIO.read(ImageIO.java:1362)
at moon_lander.Framework.LoadContent(Framework.java:115)
at moon_lander.Framework.GameLoop(Framework.java:162)
at moon_lander.Framework.access$000(Framework.java:21)
at moon_lander.Framework$1.run(Framework.java:90)
Process completed.
How you load imagines doesn't have anything to do with packages.
Normally you find an image as a resource via class path. This can be arranged any way you wish.
I tried some methods, but I just can't understand how can I make the src connected to the folder.
Usually you build an application. When you run it, you use the build, not the src. i.e. you don't use the source when you run the program. Usually the images are copied with the same relative path you used in your source and this relative path is what you use to find and load your images.
I can't be more specific, as there is not enough detail in the questions such as what you directory structure is and which IDE or build system you are using.

Moving a Pacman

This is a program I wrote for creating a pacman. I now want the Pacman to move in a straight line from a random start point to a random goal point.
Could you please suggest how to do it.
import javax.swing.JFrame;
/**
* Main class for pacman example. All it does is create a frame and put
* the pacman panel in it.
*/
public class PacmanGUI extends JFrame{
private Pacman pc;
public PacmanGUI(){
super("Pacman");
pc = new Pacman();
this.getContentPane().add(pc);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.pack();
this.setVisible(true);
}
public static void main(String[] args) {
new PacmanGUI();
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
/**
* Pacman class that extends JPanel and paints a pacman animation.
* It uses Timers and Actionlistener to do the Animation.
*
*/
public class Pacman extends JPanel implements ActionListener{
private int figureSize = 50;
private static final int DELAY = 200;
private double mouthOpenPercentages[] = {.1,.5};
private Timer animationTimer;
private int mouthState = 0;
private Point pacManPosition;
/**
* No args constructor that starts the animation.
*/
public Pacman(){
startAnimation();
}
/**
* Overriden paintComponent method that paints pacman.
*/
public void paintComponent(Graphics g) {
super.paintComponent(g);
pacManPosition = new Point(this.getWidth()/2 - figureSize/2,
this.getHeight()/2 - figureSize/2);
g.fillRect(0,0,this.getWidth(), this.getHeight());
drawPacMan(g);
mouthState = (++mouthState) % mouthOpenPercentages.length;
}
/**
* Stops the animation by stopping the animation timer.
*/
public void stopAnimation(){ animationTimer.stop(); }
/**
* Method do deal with actionevents that are triggered. In this
* case we only have actionevents being triggered from our timer
* and by the more usual case of a button click.
*/
public void actionPerformed(ActionEvent e){ repaint(); }
/**
* Gets the size that this component would like to be.
*/
public Dimension getPreferredSize(){ return new Dimension(400,400); }
/**
* Gets the minimum size for this component.
*/
public Dimension getMinimumSize(){ return new Dimension(200,200); }
/**
* Starts the animation by setting a timer. When this timer goes
* off the actionPerformed method will be triggered, which in
* turn triggers the painting.
*/
private void startAnimation(){
if (animationTimer == null){
mouthState = 0;
animationTimer = new Timer(DELAY, this);
animationTimer.start();
} else { //continue animating..
if (!animationTimer.isRunning())
animationTimer.restart();
}
}
/**
* Draws our little pacman on the given graphics canvas.
* #param g
*/
private void drawPacMan(Graphics g){
Color c = g.getColor();
g.setColor(Color.yellow);
g.fillOval(pacManPosition.x, pacManPosition.y, figureSize, figureSize);
//Change color back to original and draw pacman's mouth
g.setColor(c);
//calculate mouth offsets
int yOffset = (int)((figureSize/2)*mouthOpenPercentages[mouthState]);
//draw the mouth cutout.
int x[] = {pacManPosition.x + figureSize/2, pacManPosition.x + figureSize, pacManPosition.x + figureSize};
int y[] = {pacManPosition.y + figureSize/2,
pacManPosition.y + figureSize/2 + yOffset,
pacManPosition.y + figureSize/2 - yOffset};
g.fillPolygon(x, y, x.length);
}
}
Inside the Pacman class you would need to create 2 more values to store the start and end points. You already have private Point pacManPosition; declared so I would also declare these as Points. You'll want to set pacManPosition initially to the start point.
Point start = // random start point
Point end = // random end point
Point pacManPoint = new Point(start);
Now you'll want to determine the speed you want your Pacman to move at, let's say 2 pixels per frame.
int speed = 2;
To determine how much to move the Pacman each frame, we'll need to do some calculations. First, get the distance of the line -
double distance = Math.sqrt(Math.pow(end.x - start.x, 2) +
Math.pow(end.y - start.y, 2));
Then we calculate how many frames it will take to go that distance at the speed we want.
int totalFrames= (int)Math.round(distance / speed);
And add a frame counter -
int frame = 0;
Now, look inside your paintComponent method. Right now you're setting pacManPosition to the same point (the center of the panel) each time it paints. What you want to do here instead is to update pacManPosition each frame until it gets to the end position. You're doing something similar lower in paintComponent where you're updating mouthState each time to get the mouth to animate. For animating position it will look like -
if (frame < totalFrames) {
pacManPosition.x = start.x + frame * (end.x - start.x) / totalFrames;
pacManPosition.y = start.y + frame * (end.y - start.y) / totalFrames;
frame++;
}
This is only one way to do movement animation, and it assumes several things - constant speed, no need to avoid obstacles, no player control. The calculation in totalFrames isn't exact - it moves pacMan close to the end point, but there's no guarantee it will end exactly there. It is also tied to the frame rate, which has drawbacks. There are many, many other ways to do this depending on the situation.
Problem
You have to manage two animations at the same time.
The first, which you've already coded, opens and closes the Pacman's mouth.
The second animation is responsible for moving the Pacman from one location to another.
Solution - Sprite class
I suggest you create a Sprite class. The Sprite class would be responsible for holding the current position of the sprite, the next position of the sprite, and the speed at which the sprite moves.
You would extend Sprite to get one Pacman class, and a Chaser class with 4 instances.
Pacman class
The Pacman class would be responsible for the mouth animation.
Chaser class
The Chaser class would be responsible for determining whether to chase the Pacman, or run away from the Pacman.
Swing Tips
You should not extend Java Swing components, unless you are overriding one or more of the component classes. You should use Swing components.
You should always start your Swing GUI on the Event Dispatch Thread (EDT). You do this by executing the invokeLater method of SwingUtilities.
You should have a GUI model, separate from your GUI components. The three classes I defined would be part of your GUI model. You also need to lay out a maze.

Moving mouse cursor when station is locked (java)

I have the need at my workstation to disable a long idle.
I've been using a piece of code that moves the mouse on the screen once a while, which worked pretty well.
Lately, our security department applied a smart-card&biometric login policy,
which requires my card to be present inside the keyboard (special slot).
Since then the troubles began.
The process works fine as long as I'm logged in, meaning my card is present, but not working if my card is removed.
(I've been logging the process activity, and everything works fine, but the mouse cursor doesn't move.)
Can someone suggest me a way (or link) so I can solve this matter?
Edit
OS: Windows XP
Here's the code that is resposible for moving the mouse.
Notice that I have logged its operation, and tested it: The results outcome logged entries (as if the code was ran) but the mouse cursor wasn't moved on the locked session.
Thanks again
package AntiIdle;
import java.awt.*;
import java.util.Calendar;
import java.text.SimpleDateFormat;
class SimulateMouseAction implements Runnable {
/**
* Robot object used to move the mouse.
*/
private Robot iRobot;
/**
* Bed object, so thread could notify sleeping objects.
*/
private Bed bed;
/**
* Default constructor is neutralized.
*/
#SuppressWarnings("unused")
private SimulateMouseAction () { }
/**
* Constructs class with bed object.
*
* #param bed Bed object to notify the sleepers.
* #throws AWTException if Robot creation fails.
*/
public SimulateMouseAction (Bed bed) throws AWTException {
this.bed = bed;
iRobot = new Robot();
}
/**
* Activates tread.
*/
public void run() {
System.out.println(new SimpleDateFormat("d/M/yy hh:mm").format(Calendar.getInstance().getTime()) +
"Mouse start");
Dimension scrSize = Toolkit.getDefaultToolkit().getScreenSize();
int x, y;
for (int prcnt=0; prcnt<100; prcnt++) {
x = (int) scrSize.getWidth() * prcnt / 100;
y = (int) scrSize.getHeight() * prcnt / 100;
moveMouse(x, y);
}
y = (int) scrSize.getHeight() - 20;
for (int prcnt=100; prcnt>0; prcnt--) {
x = (int) scrSize.getWidth() * prcnt / 100;
moveMouse(x, y);
}
for (int prcnt=0; prcnt<100; prcnt++) {
x = (int) scrSize.getWidth() * prcnt / 100;
y = (int) scrSize.getHeight() * (100-prcnt) / 100;
moveMouse(x, y);
}
iRobot.mouseMove((int) scrSize.getWidth()/2, (int) scrSize.getHeight()/2);
System.out.println(new SimpleDateFormat("d/M/yy hh:mm").format(Calendar.getInstance().getTime()) +
"Mouse end");
bed.awakeTheSleepers();
}
/**
* Moves mouse cursor to given coordinates.
*
* #param x X coordinate.
* #param y Y coordinate.
*/
private void moveMouse(int x, int y) {
iRobot.mouseMove(x, y);
try {
Thread.sleep(10);
} catch(InterruptedException ie) {
ie.printStackTrace();
}
}
}
Edit
#Mark Peters: Thanks for repling. As funny as it seems, they gave me this solution... I've built a java application which launches some vb script that loads Excel and performs some tasks and create reports. The problem is that it stops launching Excel after a day of idle on my station. Everything else seem to be working (The java application keeps working-I've been logging its activity as well as the mouse mover activity in the attached code above). So as you can see, the security problem you suggested isn't solved either way. As a rule at my country, I'm forced to have 1 week of vacation in a row at least once a year. Ironically, this what's preventing me from fulfilling this duty.
Any suggestion?

Difficulty understanding Java MouseEvent

I'm doing these iTunes Stanford classes, and I've been learning beginning Java. Things are going great, but they recently introduced events-and specifically MouseEvents. I've been reading the chapters in the book, and pouring through the example code, and something is just not clicking right for me...it's always that asynchronous stuff that gives me trouble :-D
Earlier, some people mentioned it was important that I mention that the "addMouseListener" is a class in the Graphics import. As far as I can tell, that just adds a blanket mouse listener to the canvas.
I'm still real new to this, so I may not be describing things as well as I should.
This is a piece of code that I have been trying to simplify in order to better understand it. Currently, it will build a red rectangle, and I can click on it and drag it along the x axis. Great!!!
import java.awt.*;
import java.awt.event.*;
import acm.graphics.*;
import acm.program.*;
/** This class displays a mouse-draggable rectangle and oval */
public class DragObject extends GraphicsProgram {
/* Build a rectangle */
public void run() {
GRect rect = new GRect(100, 100, 150, 100);
rect.setFilled(true);
rect.setColor(Color.RED);
add(rect);
addMouseListeners();
}
/** Called on mouse press to record the coordinates of the click */
public void mousePressed(MouseEvent e) {
lastX = e.getX();
lastY = e.getY();
gobj = getElementAt(lastX, lastY);
}
/** Called on mouse drag to reposition the object */
public void mouseDragged(MouseEvent e) {
if((lastX) > 100){
gobj.move(e.getX() - lastX, 0);
lastX = e.getX();
lastY = e.getY();
}
}
/** Called on mouse click to move this object to the front */
public void mouseClicked(MouseEvent e) {
if (gobj != null) gobj.sendToFront();
}
/* Instance variables */
private GObject gobj; /* The object being dragged */
private double lastX; /* The last mouse X position */
private double lastY; /* The last mouse Y position */
}
If I drag the mouse off the canvas, I want the rectangle to stay within the canvas, and not move off it (the same behavior that a horizontal scroll bar would do if you moved beyond the scroll area with the mouse button still clicked). How can I do that?
I've been trying something along these lines, but it's not working right:
if ( ( lastX > (getWidth() - PADDLE_WIDTH) ) || ( lastX < PADDLE_WIDTH ) ) {
gobj.move(0, 0);
} else {
gobj.move(e.getX() - lastX, 0);
}
Your code is moving the rectangle relative to the last position of the mouse. This works fine when you are simply moving things, but for your needs when you want it to stop at the borders, you need to use absolute positioning.
// When the mouse is pressed, calculate the offset between the mouse and the rectangle
public void mousePressed(MouseEvent e) {
lastX = e.getX();
lastY = e.getY();
gobj = getElementAt(lastX, lastY);
}
public void mouseDragged(MouseEvent e) {
double newX;
// Assuming you can get the absolute X position of the object.
newX = gobj.getX() + e.getX() - lastX;
// Limit the range to fall within your canvas. Adjust for your paddle width as necessary.
newX = Math.max( 0, Math.min( newX, getWidth() ) );
// Set the new position of the paddle, assuming you can set the absolute position.
gobj.setX( newX );
lastX = e.getX();
lastY = e.getY();
}
}
This may not be quite what you want because as soon as you go off the edge, the object will stop moving, but then once you move back toward the canvas, your paddle will move immediately instead of waiting for the mouse to reach the same relative position to the paddle at which it started.
You can probably experiment to get it to do what you want.
In order to do this you will need to know the width of the Canvas object, i'm sure there will be a method that will provide this value. You can then check the current x location of the MouseEvent against the width of the canvas, and not increment the x coordinates of the shape object once you are past the width of the canvas. Depending on how much of the shape you want to remain in the canvas, you may need to take into account the width of the shape object as well.
One thing that helps me when dealing w/ animation and moving objects in a gui is drawing out a few scenarios on paper, and noting how the coordinates change.

Categories

Resources