Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (487)
Games in Android Showcase (110)
games submitted by our members
Games in WIP (553)
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  
  Zoom in at mouse (SLICK2D)  (Read 849 times)
0 Members and 1 Guest are viewing this topic.
Offline zacpier

Junior Newbie





« Posted 2013-05-04 20:58:47 »

I've been working on a RTS game and I wanted to be able to zoom in with the mouse wheel toward the mouse.
In a lot of RTS games, you can hover over a unit, scroll upwards, and end up with the unit in the middle of your screen very zoomed.
That's what I'm trying to accomplish.

Here's my World.java:

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  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
package net.space.render;

import java.util.ArrayList;

import net.space.entity.Entity;
import net.space.main.ReducedSpace;

import org.lwjgl.input.Mouse;
import org.newdawn.slick.Graphics;

public class World {

   public float zX=0, zY=0;

   private float zoomLevel;
   private static final float zoomStep=0.0625f;
   
   private ArrayList<Entity> entities = new ArrayList<Entity>();
   
   
   
   public void draw(Graphics g) {
      g.scale(getZoomLevel(), getZoomLevel());
      g.translate(zX, zY);
     
      for(Entity e:entities) {
         if(e!=null) {
            e.draw(g);
         }
      }
   }
   
   
   
   public float getZoomLevel() {
      return zoomLevel;
   }
   
   public void setZoomLevel(float z) {
      zoomLevel = z;
   }
   
   
   
   public void mouseWheelZoom() {
     
        int mouseWheel = Mouse.getDWheel();
       
        if(mouseWheel==0) {
           
           return;
        }
       
        boolean positive = mouseWheel>0;
       
       
        if (positive) {
           
           addZoomLevel(zoomStep);
        }
       
        else {

           addZoomLevel(-zoomStep);
        }
       
        if(mouseWheel != 0) {
           
           zX+=(Mouse.getX()*(mouseWheel/240f))/zoomLevel;
           zY-=((ReducedSpace.h-Mouse.getY())*(mouseWheel/240f))/zoomLevel;
        }
       
        System.out.println("RAWX: "+Mouse.getX()+"\nRAWY: "+Mouse.getY()+"\nEXP: "+mouseWheel+"|"+(mouseWheel/240f)+"\nWHEEL: "+mouseWheel);
        System.out.println("X: "+zX+"\nY: "+zY);
   }
   
   public void addZoomLevel(float a) {
     
      zoomLevel+=a;
     
      if(zoomLevel>1.2375f) {
         zoomLevel=1.2375f;
      }
     
      if(zoomLevel<.1f) {
         
         zoomLevel=.1f;
      }
   }
   
   public int addEntity(Entity e) {
      entities.add(e);
      return entities.size();
   }
   public void removeEntity(int index) {
      entities.set(index, null);
   }
   public void removeEntity(String name) {
      for(int i=0;i<entities.size();i++) {
         if(entities.get(i).name.matches(name)) {
            removeEntity(i);
            return;
         }
      }
   }
   public Entity getEntity(int index) {
      return entities.get(index);
   }
   public Entity getEntity(String name) {
      for(int i=0;i<entities.size();i++) {
         if(entities.get(i).name.matches(name)) {
            return getEntity(i);
         }
      }
      return null;
   }
}


Thanks for any help!
Offline Mike

JGO Wizard


Medals: 73
Projects: 1
Exp: 6 years


Java guru wanabee


« Reply #1 - Posted 2013-05-04 22:22:04 »

This forum has a very nice search function... Wink

http://www.java-gaming.org/topics/camera-zooming-on-specific-point/28713/view.html

Mike

My current game, Minecraft meets Farmville and goes online Smiley
State of Fortune | Discussion thread @ JGO
Offline zacpier

Junior Newbie





« Reply #2 - Posted 2013-05-04 23:43:36 »

I guess my keywords weren't sufficient.  I'll check that out. Thanks!
I don't know what LibGDX is, but I would really like to do this without ANOTHER library. I already have Slick2D and LWJGL. Another seems like it shouldn't be necessary...
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline HeroesGraveDev

JGO Kernel


Medals: 246
Projects: 11
Exp: 2 years


┬─┬ノ(ಠ_ಠノ)(╯°□°)╯︵ ┻━┻


« Reply #3 - Posted 2013-05-05 00:30:27 »

You can do it with a simple translate and scale (or is it scale and translate?)

You should be able to get it by changing order of transformations.

Offline zacpier

Junior Newbie





« Reply #4 - Posted 2013-05-05 00:32:04 »

I understood that you could do it that way, but I'm having trouble getting the transformations just right.  Could you give me any pointers?
Offline HeroesGraveDev

JGO Kernel


Medals: 246
Projects: 11
Exp: 2 years


┬─┬ノ(ಠ_ಠノ)(╯°□°)╯︵ ┻━┻


« Reply #5 - Posted 2013-05-05 00:40:19 »

You have translation working right?

If you don't, go and fix it.

If/Once you have translation working, add in a scale before or after the translation. Whatever one works.

Offline zacpier

Junior Newbie





« Reply #6 - Posted 2013-05-05 00:41:42 »

Wait, translate BEFORE the scale?
Offline HeroesGraveDev

JGO Kernel


Medals: 246
Projects: 11
Exp: 2 years


┬─┬ノ(ಠ_ಠノ)(╯°□°)╯︵ ┻━┻


« Reply #7 - Posted 2013-05-05 00:43:51 »

Wait, translate BEFORE the scale?

Or after.

I can't test it now so I'm not sure.

It also depends on when the transformation is performed.

You need to experiment

Offline zacpier

Junior Newbie





« Reply #8 - Posted 2013-05-05 00:46:42 »

The results are always weird and unpredictable.  I don't know how to code this :X
Offline Mike

JGO Wizard


Medals: 73
Projects: 1
Exp: 6 years


Java guru wanabee


« Reply #9 - Posted 2013-05-06 09:10:23 »

No matter if you use lwjgl or slick or java2d or something else it will always be the same idea, just with a little bit different code.

From the thread I posted:
In general, check where the mouse was (in the game, not in the applet), do the zoom, check where it is after and move the camera the difference.

It shouldn't be too hard to implement the above in any engine of your choice. Smiley

Mike

My current game, Minecraft meets Farmville and goes online Smiley
State of Fortune | Discussion thread @ JGO
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline DrZoidberg

Senior Member


Medals: 15



« Reply #10 - Posted 2013-05-06 19:12:05 »

First you need to have a camera position in your game. The virtual "camera" in a 2D game is simply a rectangle that's positioned somewhere in your 2D world.
An example - your world is 10,000 * 10,000 pixels big and your drawing surface (the window you paint in or the entire screen in full screen mode) is 1000 * 1000. Then you might define your camera to have a position of (200, 300) and a size of (1000, 1000). Everything inside that rectangle is displayed on the screen.
Most of the time it's sufficient to just remember the camera position and forget about it's size because the Graphics object doesn't need to know if an object is inside the visible area. Drawing stuff outside the screen is not causing any problems. So you can simply always draw all objects.
Additionally to the position you also need to store the zoom level of the camera.

The draw method will then look like this.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
public void draw(Graphics g) {
  g.scale(getZoomLevel(), getZoomLevel());
  g.translate(-cameraPos.getX(), -cameraPos.getY());
 
  for(Entity e:entities) {
     if(e!=null) {
        e.draw(g);
     }
  }
}

It's convinient to use vectors for positions.
So cameraPos should be of type org.newdawn.slick.geom.Vector2f.
So replace
1  
public float zX=0, zY=0;

with
1  
public cameraPos = new Vector2f(0,0);

Also it's important to remember that a game always has two coordinate systems. So you need to know which vectors are relative to the screen (absolute screen coordinates) and which vectors are relative to the coordinate system of your game.
cameraPos is always relative to the game.
Furthermore org.newdawn.slick.Graphics uses a coordinate system where (0, 0) is the upper left corner of the screen/window.
org.lwjgl.input.Mouse however puts (0, 0) at the lower left corner.
This video here demonstrates that. http://thenewboston.org/watch.php?cat=54&number=10
So you need to convert your coordinates so (0, 0) is always at the upper left corner.
You could do that like this.
1  
2  
3  
static Vector2f getMousePos() {
    return new Vector2f(Mouse.getX(), gameContainer.getHeight()-1-Mouse.getY());
}

Now for the mouseWheelZoom method. I assume you call that every frame?
Try this
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
public void mouseWheelZoom() {
    int mouseWheel = Mouse.getDWheel();
    if(mouseWheel==0) {
       return;
    }
    if(mouseWheel != 0) {
        Vector2f mousePosAbs = getMousePos();
        Vector2f mousePosRel = mousePosAbs.copy().scale(1/zoomLevel).add(cameraPos);
        if (mouseWheel>0) {
           addZoomLevel(zoomStep);
        } else {
           addZoomLevel(-zoomStep);
        }
        cameraPos = mousePosRel.sub(mousePosAbs.scale(1/zoomLevel));
    }
}

I wasn't able to test those modifications since I don't have all of your code but I hope it works.
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.

CopyableCougar4 (23 views)
2014-08-22 19:31:30

atombrot (34 views)
2014-08-19 09:29:53

Tekkerue (30 views)
2014-08-16 06:45:27

Tekkerue (28 views)
2014-08-16 06:22:17

Tekkerue (18 views)
2014-08-16 06:20:21

Tekkerue (27 views)
2014-08-16 06:12:11

Rayexar (65 views)
2014-08-11 02:49:23

BurntPizza (41 views)
2014-08-09 21:09:32

BurntPizza (33 views)
2014-08-08 02:01:56

Norakomi (42 views)
2014-08-06 19:49:38
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

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
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!