Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (538)
Games in Android Showcase (132)
games submitted by our members
Games in WIP (601)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Different scales or ZOOM effect, how ?!  (Read 4046 times)
0 Members and 1 Guest are viewing this topic.
Offline fermixx

Senior Newbie





« Posted 2009-09-09 06:38:29 »

Hi dudes, this is a question i had for a long time, and now that i had to face it (by "force"), i decided to post it here

I have a canvas big 800x640 (its just a piece of the whole frame) and i need to support different "scales"

My coordinate system is +-400 x, +- 320 y.
Instead of having a lot of zoom capabilities (thus a lot of different scales) i decided to make just 4 scales : x1, x2, x3, x4.
So for x2 for example, my canvas should represent a 1600x1280 space (+- 800x, ..)

I think this should be way easier than zooming with the mousewheel.

So what i was thinking is to divide everything on my shapes (what is drawn into the canvas) by the scale.

For example if my rectangle is at 120, 100, has a width of 100 and a height of 50, i should draw it as follows (considering x2 scale):

x: 60
y: 50
width: 50
height: 25

So dividing is the way to go? is that hard to make the zoom with the mousewheel and having multiple scales?


Thanks in advance for your time and patience


EDITED: im using standard j2se, im using java2D (i guess), not open gl nor any stuff like that
EDITED2: im a big noob (just if you didnt notice that)

RTS game or a big rock-paper-sissors ?
Offline Nate

« JGO Bitwise Duke »


Medals: 158
Projects: 4
Exp: 14 years


Esoteric Software


« Reply #1 - Posted 2009-09-09 09:04:24 »

glScale

Offline Bonbon-Chan

JGO Coder


Medals: 12



« Reply #2 - Posted 2009-09-09 09:57:24 »

Well, fermixx are you using an OpenGL binding or Java2D ?
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline fermixx

Senior Newbie





« Reply #3 - Posted 2009-09-09 18:42:32 »

sorry for not pointing that out, im using plain j2se. So its java2D what im using.

I have no idea about openGL.


first post edited

thanks for the replies

RTS game or a big rock-paper-sissors ?
Offline Bonbon-Chan

JGO Coder


Medals: 12



« Reply #4 - Posted 2009-09-10 12:18:13 »

I will reply without really knowing the performance.

With Java2D, I avoid antialiasing (for performance) so I should stick to x1,x2,x3 or it will be "ugly" (when zoom out, it seems that you want to zoom in).
An easy way to do it is to :
- keeper the same size buffer and resize everything at the end when passing to the display (just with the Gaphics.drawImage)
- or resize the buffer and using "Graphics2D.scale(double sx, double sy)"
Offline fermixx

Senior Newbie





« Reply #5 - Posted 2009-09-10 19:58:03 »


An easy way to do it is to :
- keeper the same size buffer and resize everything at the end when passing to the display (just with the Gaphics.drawImage)
- or resize the buffer and using "Graphics2D.scale(double sx, double sy)"


1 should be something like i said on my post right? (dividing)
2 does this work with passive rendering? im doing everything at drawComponent (graphics g) inside my panel.

then i do the classic Graphics2D g2d = (Graphics2D) g;

So should i use g2d.scale() with half the sizes?

(when zoom out, it seems that you want to zoom in)

i want to zoom out actually. It sounds confusing because it sounds like the zoom in a microscope. What i meant is that i need to represent twice the width (-+800 instead of +-400), not that i want to see things two times bigger.

X2 should be in this case, increase the coordinate system by two, and since the canvas is still the same, everything should decrease its size

Sorry for not being clear.

RTS game or a big rock-paper-sissors ?
Offline zoto

Senior Devvie


Medals: 4



« Reply #6 - Posted 2009-09-11 12:10:12 »

Here's an example of using Java2D to scale an image with the mouse wheel.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.imageio.ImageIO;
import javax.swing.JFrame;


public class ZoomFrame extends JFrame implements KeyListener, MouseWheelListener{
   BufferedImage image;
   int zoom = 1;

   public ZoomFrame() {
      try{
         image = ImageIO.read(new File("USA_Map_With_States_Names.png"));
      } catch (Exception e) {
         e.printStackTrace();
         System.exit(-1);
      }
      setDefaultCloseOperation(EXIT_ON_CLOSE);
      setVisible(true);
      setFocusable(true);
      addKeyListener(this);
      addMouseWheelListener(this);
      pack();
   }
   public static void main(String[] args) {
      new ZoomFrame();
   }
   @Override
   public Dimension getPreferredSize() {
      return new Dimension(800, 600);
   }
   public void keyReleased(KeyEvent e) {
      int key = e.getKeyCode();
      if(key == KeyEvent.VK_1)
         zoom = 1;
      if(key == KeyEvent.VK_2)
         zoom = 2;
      if(key == KeyEvent.VK_3)
         zoom = 3;
      if(key == KeyEvent.VK_4)
         zoom = 4;
      repaint();
   }

   public void mouseWheelMoved(MouseWheelEvent e) {
      zoom += e.getWheelRotation();
      repaint();
   }

   @Override
   public void paint(Graphics g) {
      Graphics2D g2 = (Graphics2D)g;
      g2.setColor(Color.BLACK);
      g2.fill(getBounds());
      if(zoom == 0)
         g2.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), 0, 0, image.getWidth(), image.getHeight(), null);
      else if(zoom < 0)
         g2.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), 0, 0, image.getWidth()/-zoom, image.getHeight()/-zoom, null);
      else
         g2.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), 0, 0, image.getWidth()*zoom, image.getHeight()*zoom, null);
   }
   public void keyPressed(KeyEvent e) {}
   public void keyTyped(KeyEvent e) {}
}
Offline fermixx

Senior Newbie





« Reply #7 - Posted 2009-09-11 22:48:00 »

Here's an example of using Java2D to scale an image with the mouse wheel.

Thanks for that, i'll try it out later.

In my case i have something like this:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
//this is my custom panel which extends JPanel

@Override
public void paintComponent (Graphics g){
        super.paintComponent(g);  //did it just in case
        Graphics2D g2d = (Graphics2D) g;
        g2d.setColor(skyBlue);   //background colour
        g2d.fillRect(0, 0, 800, 640);     //erasing screen

        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); //adding AA

        GoalArea goalArea = main.getGoalArea(); //an unique tipe of rectangle
        if (goalArea != null) goalArea.draw(g2d);
       
        for (int i = 0; i < main.shapesList.size(); i++){ //this is an arrayList with all my shapes (rects and circles)
            Shape figure = main.shapesList.get(i);
            figure.draw(g2d);
        }

        g2d.dispose();
}


So all the shapes have their own drawing method, which consists in:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
@Override
    public void draw(Graphics2D g2d){
       
        AffineTransform oldAT = g2d.getTransform(); //backupping the affine transform
               
        trans.rotate(Math.toRadians(angle), x + width/2, y - height/2); //trans is a pre-constructed affine transform
        g2d.setTransform(trans);

        Point oldCoords = new Point (x,y);
        Point newCoords = new Point();

        trans.inverseTransform(oldCoords, newCoords);
               
        int newX = (int) newCoords.getX(); int newY = (int) newCoords.getY();
        g2d.setColor (myRectangleColour);
        g2d.fillRect(newX-width/2, newY-height/2, width, height); //coordinates are the shape's center
        g2d.setTransform(oldAT);
        trans = oldAT;
       
    }


(both codes were simplified a bit to be clearer)

So, in my paintComponent, how should i do that?

is the g2d a graphics context of a back buffer image (since, i guess, swing uses double buffering) which i can retrieve and then scale?

RTS game or a big rock-paper-sissors ?
Offline zoto

Senior Devvie


Medals: 4



« Reply #8 - Posted 2009-09-13 00:35:00 »

You can just draw them scaled rather than scaling the final drawing. I see your using an AffineTransform to draw already, you can add
trans.scale(scale, scale);
to have it handle scaling for you.
Offline Bonbon-Chan

JGO Coder


Medals: 12



« Reply #9 - Posted 2009-09-14 07:54:03 »

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
//this is my custom panel which extends JPanel

@Override
public void paintComponent (Graphics g){
        super.paintComponent(g);  //did it just in case
        Graphics2D g2d = (Graphics2D) g;
        g2d.setColor(skyBlue);   //background colour
        g2d.fillRect(0, 0, 800, 640);     //erasing screen

        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); //adding AA

        AffineTransform oldAT = g2d.getTransform(); //backupping the affine transform
        g2d.scale(zoom,zoom);

        GoalArea goalArea = main.getGoalArea(); //an unique tipe of rectangle
        if (goalArea != null) goalArea.draw(g2d);
       
        for (int i = 0; i < main.shapesList.size(); i++){ //this is an arrayList with all my shapes (rects and circles)
            Shape figure = main.shapesList.get(i);
            figure.draw(g2d);
        }

        g2d.setTransform(oldAT);
        g2d.dispose();
}


Grin

You can simplify the object drawing method :

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
@Override
    public void draw(Graphics2D g2d)
{
        AffineTransform oldAT = g2d.getTransform(); //backupping the affine transform
               
        g2d.translate(x,y);
        g2d.rotate(Math.toRadians(angle));
        g2d.setColor (myRectangleColour);
        g2d.fillRect(-width/2, -height/2, width, height);

        g2d.setTransform(oldAT);        
    }

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline fermixx

Senior Newbie





« Reply #10 - Posted 2009-09-15 00:01:43 »

You can simplify the object drawing method :

Thanks for that. Thats really simplified ! and it worked really well.
Had no idea i could apply rotations and stuff straight into the g2d, thought i had to use an affine transform as my only choice.


Tryed the paintcomponent code with the g2d.scale. It worked really well, but the problem is that everything stays at the same position (coordinates). Their size is reduced but they are not repositioned with what should be a new (bigger) coordinate system.

What i mean is that the point (800,640) is still (800,640) instead of (1600,1080). I think im going to need to do the width/zoom, x/zoom, etc thing

For example, something that was on the top left corner, after zooming out, the object should appear closer to the center, but its still on the top left corner

RTS game or a big rock-paper-sissors ?
Offline Bonbon-Chan

JGO Coder


Medals: 12



« Reply #11 - Posted 2009-09-15 06:57:39 »

What i mean is that the point (800,640) is still (800,640) instead of (1600,1080). I think im going to need to do the width/zoom, x/zoom, etc thing

Hmmm, I don't see what you mean... may be you speech about mouse coordinate on the screen ? If so, yes you will need to transform the screen coordinate to the drawing coordinate.

For example, something that was on the top left corner, after zooming out, the object should appear closer to the center, but its still on the top left corner
Yes, the zoom is a scaling from the (0,0) point. You will have to add a translation to zoom from another point.
For you example, your (0,0) point can be at the center of the screen and you start by doing a translation of (width/2,height/2).


1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
   Point2D.Float mouseScreen = new Point2D.Float();
   Point2D.Float mouseDrawing = new Point2D.Float();
   AffineTransform drawingTransform = null;
 
    ...
 
   AffineTransform oldAT = g2d.getTransform(); //backupping the affine transform
   g2d.translate(width/2,height/2);
   g2d.scale(zoom,zoom);
   drawingTransform = g2d.getTransform();
   g2d.invert();
   
   ...

   g2d.setTransform(oldAT);
   g2d.dispose();

   ...

  mouseScreen.x = mouse_x;
  mouseScreen.y = mouse_y;
  drawingTransform.transform(mouseScreen ,mouseDrawing );
   

Offline ishailin

Junior Newbie





« Reply #12 - Posted 2010-03-16 15:18:07 »

it's easy to do with this tools i made
my skype is  ishailin and msn is ailin8@163.com
i can send the tools to you

public class gCanvas extends Canvas{
   Image img;
   Zoom zoom = new Zoom();
   gCanvas()
   {
      try {
         img = Image.createImage("/menu160.png");
         zoom.setImage(img, W, H);
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
   
   int W=50,H=70;
   protected void paint(Graphics g) {
      zoom.draw(g,this.getWidth()>>1, this.getHeight()>>1, 3);
      g.drawImage(img, this.getWidth()>>1, this.getHeight()>>1, 3);
   }
   protected void keyPressed(int key)
   {
      zoom.setSize(W+=5,H+=5);
      repaint();
   }
}

//-------------------------------------------------------------------------------------------------------------



public class Zoom {

            private AbstractImage globe;
            private AbstractImage lastRenderedImage;
            private ImageTransformationResize resizer;
            private int oldW;
            private int oldH;


            public void setImage(Image img, int w, int h) {
/*  19*/        try {
/*  19*/            Dispose();
/*  20*/            globe = new SmartImage(img);
/*  21*/            resizer = new ImageTransformationResize();
/*  22*/            setSize(w, h);
                }
/*  24*/        catch (Exception ex) {
/*  26*/            ex.printStackTrace();
                }
            }

            public void Dispose() {
/*  32*/        globe = null;
/*  33*/        lastRenderedImage = null;
/*  34*/        resizer = null;
            }

            public void setSize(int w, int h) {
/*  39*/        if (w <= 0 || h <= 0) {
/*  41*/            return;
                }
/*  43*/        if (w == oldW && h == oldH) {
/*  45*/            return;
                } else {
/*  49*/            oldW = w;
/*  50*/            oldH = h;
/*  52*/            lastRenderedImage = null;
/*  53*/            lastRenderedImage = new SmartImage(w, h);
/*  54*/            resizer.setTargetDimensions(w, h);
/*  55*/            resizer.process(globe, lastRenderedImage);
/*  56*/            return;
                }
            }

            public void draw(Graphics g, int x, int y, int anchor) {
/*  60*/        lastRenderedImage.drawOnGraphics(g, x, y, anchor);
            }
}
Offline Eli Delventhal

JGO Kernel


Medals: 42
Projects: 11
Exp: 10 years


Game Engineer


« Reply #13 - Posted 2010-03-16 15:42:04 »

glScale
This made me laugh because it was so short, succinct, and exactly right. Smiley

See my work:
OTC Software
Offline DzzD
« Reply #14 - Posted 2010-03-16 19:06:02 »

Here's an example of using Java2D to scale an image with the mouse wheel.
NB:
when zooming it is better to do zoom*=1.1 or zoom*=0.9  (rather than zoom+=something and zoom-=something), it give a more linear result

also for mousewhell you should handle multiple ticks something like :

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
public void mouseWheelMoved(MouseWheelEvent e) 
{  
       int wheel=e.getWheelRotation();
       if(wheel<0)
       {
          this.zoom*=Math.pow(1.2,-wheel);  
       }
       else
       {
       
          this.zoom*=Math.pow(0.8,wheel);      
       }
}

Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

rwatson462 (30 views)
2014-12-15 09:26:44

Mr.CodeIt (20 views)
2014-12-14 19:50:38

BurntPizza (42 views)
2014-12-09 22:41:13

BurntPizza (76 views)
2014-12-08 04:46:31

JscottyBieshaar (37 views)
2014-12-05 12:39:02

SHC (51 views)
2014-12-03 16:27:13

CopyableCougar4 (48 views)
2014-11-29 21:32:03

toopeicgaming1999 (115 views)
2014-11-26 15:22:04

toopeicgaming1999 (103 views)
2014-11-26 15:20:36

toopeicgaming1999 (30 views)
2014-11-26 15:20:08
Resources for WIP games
by kpars
2014-12-18 10:26:14

Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!