Added support for scrolling backgrounds
[supertux.git] / src / object / background.cpp
1 //  SuperTux
2 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
3 //
4 //  This program is free software: you can redistribute it and/or modify
5 //  it under the terms of the GNU General Public License as published by
6 //  the Free Software Foundation, either version 3 of the License, or
7 //  (at your option) any later version.
8 //
9 //  This program is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //  GNU General Public License for more details.
13 //
14 //  You should have received a copy of the GNU General Public License
15 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17 #include "object/background.hpp"
18 #include "supertux/globals.hpp"
19 #include "supertux/object_factory.hpp"
20 #include "util/reader.hpp"
21
22 Background::Background() :
23   layer(LAYER_BACKGROUND0),
24   imagefile_top(),
25   imagefile(),
26   imagefile_bottom(),
27   pos(),
28   speed(),
29   speed_y(),
30   scroll_speed(),
31   scroll_offset(),
32   image_top(),
33   image(),
34   image_bottom()
35 {
36 }
37
38 Background::Background(const Reader& reader) :
39   layer(LAYER_BACKGROUND0),
40   imagefile_top(),
41   imagefile(),
42   imagefile_bottom(),
43   pos(),
44   speed(),
45   speed_y(),
46   scroll_speed(),
47   scroll_offset(),
48   image_top(),
49   image(),
50   image_bottom()
51 {
52   // read position, defaults to (0,0)
53   float px = 0;
54   float py = 0;
55   reader.get("x", px);
56   reader.get("y", py);
57   this->pos = Vector(px,py);
58
59   speed = 1.0;
60   speed_y = 1.0;
61
62   reader.get("scroll-offset-x", scroll_offset.x);
63   reader.get("scroll-offset-y", scroll_offset.y);
64
65   reader.get("scroll-speed-x", scroll_speed.x);
66   reader.get("scroll-speed-y", scroll_speed.y);
67
68   reader.get("layer", layer);
69   if(!reader.get("image", imagefile) || !reader.get("speed", speed))
70     throw std::runtime_error("Must specify image and speed for background");
71
72   set_image(imagefile, speed);
73   if (!reader.get("speed-y", speed_y))
74   {
75     speed_y = speed;
76   }
77
78   if (reader.get("image-top", imagefile_top)) {
79     image_top = Surface::create(imagefile_top);
80   }
81   if (reader.get("image-bottom", imagefile_bottom)) {
82     image_bottom = Surface::create(imagefile_bottom);
83   }
84 }
85
86 Background::~Background()
87 {
88 }
89
90 void
91 Background::update(float delta)
92 {
93   scroll_offset += scroll_speed * delta;
94 }
95
96 void
97 Background::set_image(const std::string& name, float speed)
98 {
99   this->imagefile = name;
100   this->speed = speed;
101
102   image = Surface::create(name);
103 }
104
105 void
106 Background::draw(DrawingContext& context)
107 {
108   if(image.get() == NULL)
109     return;
110
111   int w = (int) image->get_width();
112   int h = (int) image->get_height();
113   int sx = int(scroll_offset.x + pos.x-context.get_translation().x * speed) % w - w;
114   int sy = int(scroll_offset.y + pos.y-context.get_translation().y * speed_y) % h - h;
115   int center_image_py = int(pos.y-context.get_translation().y * speed_y);
116   int bottom_image_py = int(pos.y-context.get_translation().y * speed_y) + h;
117   context.push_transform();
118   context.set_translation(Vector(0, 0));
119   for(int x = sx; x < SCREEN_WIDTH; x += w) {
120     for(int y = sy; y < SCREEN_HEIGHT; y += h) {
121       if (image_top.get() != NULL && (y < center_image_py)) {
122         context.draw_surface(image_top.get(), Vector(x, y), layer);
123         continue;
124       }
125       if (image_bottom.get() != NULL && (y >= bottom_image_py)) {
126         context.draw_surface(image_bottom.get(), Vector(x, y), layer);
127         continue;
128       }
129       context.draw_surface(image.get(), Vector(x, y), layer);
130     }
131   }
132   context.pop_transform();
133 }
134
135 /* EOF */