-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathImgScroll.java
executable file
·152 lines (142 loc) · 6.51 KB
/
ImgScroll.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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import greenfoot.Actor;
import greenfoot.Color;
import greenfoot.GreenfootImage;
import greenfoot.World;
/**
* CLASS: ImgScroll (subclass of Object)<br>
* AUTHOR: danpost (greenfoot.org username)<br>
* VERSION DATE: April 1, 2015<br>
* <br>
* DESCRIPTION: a scrolling engine that scrolls the world given to the limits of the scrolling
* background image given or to the dimensions given where the given background image is tiled,
* if needed, to fill the scrolling area; keep in mind that the smaller the world window is, the
* less lag you are likely to get (increasing the world size will cause an exponential increase
* in possible lag); this class is designed to keep lag at a minimum by breaking the scrolling
* background image into smaller parts so that the entire scrolling background image is not drawn
* every time scrolling occurs;<br>
* <br>
* There are two ways to create a scroller with this class:<br>
* (1) Use the two-parameter constructor to limit scrolling to the given background image dimensions;<br>
* (2) Use the four-parameter one to give the dimensions of the scrolling area and have the given
* image tiled, if needed, to fill that area;
*/
public class ImgScroll {
private final World scrollWorld; // the world the background image scrolls in
private final GreenfootImage[][] scrollImages; // the drawing panels (background image broken down)
private final int scrollWidth;
private final int scrollHeight; // the dimensions of the scrolling area
private final int worldWidth;
private final int worldHeight; // the dimensions of the world window
private int xScrAmt, yScrAmt; // the overall horizontal and vertical scrolled amounts
/**
* calls the main constructor of the class using the dimensions of the given image for
* the dimensions of the scrolling area
*
* @param scrWorld the world the given background image is to scroll in
* @param scrImage the scrolling background image to be used in the given world
*/
public ImgScroll(World scrWorld, GreenfootImage scrImage) {
this(scrWorld, scrImage, scrImage.getWidth(), scrImage.getHeight());
}
/**
* this main constructor sets field values and initial world background image
*
* @param scrWorld the world the given background image is to scroll in
* @param repImage the image that is tiled to create the scrolling background image of the given world
* @param wide the horizontal dimension of the scrolling area
* @param high the vertical dimension of the scrolling area
*/
public ImgScroll(World scrWorld, GreenfootImage repImage, int wide, int high) {
// the field values
scrollWorld = scrWorld;
worldWidth = scrWorld.getWidth();
worldHeight = scrWorld.getHeight();
scrollWidth = wide;
scrollHeight = high;
// the scrolling image
if (repImage == null) repImage = scrWorld.getBackground();
GreenfootImage scrImage = new GreenfootImage(wide, high);
scrImage.setColor(Color.WHITE);
scrImage.fill(); // ensures no transparent pixels in background
for (int i = 0; i < wide; i += repImage.getWidth())
for (int j = 0; j < high; j += repImage.getHeight())
scrImage.drawImage(repImage, i, j);
// the drawing panels (to help reduce lag by reducing the number of pixels drawn when scrolling)
int x = 1 + scrollWidth / worldWidth; // number of panels across
int y = 1 + scrollHeight / worldHeight; // number of panels down
scrollImages = new GreenfootImage[y][x]; // creates the array
for (int j = 0; j < y; j++)
for (int i = 0; i < x; i++) // fills the array
{
scrollImages[j][i] = new GreenfootImage(worldWidth, worldHeight);
scrollImages[j][i].drawImage(scrImage, -i * worldWidth, -j * worldHeight);
}
scrollBackground(); // sets initial world background image
}
/**
* sets the world background image determined by the current scroll values
*/
private void scrollBackground() {
int x = (-xScrAmt) / worldWidth; // panel x index
int y = (-yScrAmt) / worldHeight; // panel y index
int dx = -((-xScrAmt) % worldWidth); // drawing x offset
int dy = -((-yScrAmt) % worldHeight); // drawing y offset
GreenfootImage bg = scrollWorld.getBackground(); // gets local reference to world background
bg.drawImage(scrollImages[y][x], dx, dy); // draw top-left image
if (dx != 0) // draw top-right image if needed
bg.drawImage(scrollImages[y][x + 1], dx + worldWidth, dy);
if (dy != 0) // draw bottom-left image if needed
bg.drawImage(scrollImages[y + 1][x], dx, dy + worldHeight);
if (dx != 0 && dy != 0) // draw bottom-right image if needed
bg.drawImage(scrollImages[y + 1][x + 1], dx + worldWidth, dy + worldHeight);
}
/**
* performs limited scrolling using the given changes in scroll values
*
* @param dx the amount to scroll horizontally (positive values scroll left moving view toward the right)
* @param dy the amount to scroll vertically (positive values scroll up moving view toward the bottom)
*/
public void scroll(int dx, int dy) {
// limit change values
if (dx > 0 && xScrAmt + dx > 0) dx = -xScrAmt;
if (dx < 0 && xScrAmt + dx <= worldWidth - scrollWidth)
dx = (worldWidth - scrollWidth) - xScrAmt;
if (dy > 0 && yScrAmt + dy > 0) dy = -yScrAmt;
if (dy < 0 && yScrAmt + dy <= worldHeight - scrollHeight)
dy = (worldHeight - scrollHeight) - yScrAmt;
// change scrolling values
xScrAmt += dx;
yScrAmt += dy;
// update world background
scrollBackground();
// keep actors in place with relation to background image
for (Object obj : scrollWorld.getObjects(null)) {
Actor actor = (Actor) obj;
actor.setLocation(actor.getX() + dx, actor.getY() + dy);
}
}
/**
* returns the overall amount scrolled horizontally
*/
public int getScrolledX() {
return xScrAmt;
}
/**
* returns the overall amount scrolled vertically
*/
public int getScrolledY() {
return yScrAmt;
}
/**
* returns the width of the scrolling area
*/
public int getScrollWidth() {
return scrollWidth;
}
/**
* returns the height of the scrolling area
*/
public int getScrollHeight() {
return scrollHeight;
}
}