1 module cactus;
2 
3 import dsfml.graphics;
4 import resourcemanager;
5 import collidable;
6 import collider;
7 import std.conv;
8 import helpers;
9 
10 /// Size of a small cactus
11 static immutable small_cactus_size = Vector2f(17, 33);
12 /// Size of a medium cactus
13 static immutable medium_cactus_size = Vector2f(25, 45);
14 /// Size of a big cactus
15 static immutable big_cactus_size = Vector2f(24, 46);
16 
17 private static immutable cactus_count = 11;
18 
19 private string path(const uint i) {
20   return "assets/cactuses/" ~ i.to!string ~ ".png";
21 }
22 private string name(const uint i) {
23   return "cactus" ~ i.to!string;
24 }
25 
26 static this() {
27   foreach(i; 1..cactus_count + 1) {
28     assert(resource_manager.register!Texture(path(i), name(i), make_collider));
29   }
30 }
31 
32 private const(Collider) get_collider(const uint cactus_id) {
33   return resource_manager.get!Collider(cactus_id.name);
34 }
35 
36 private Vector2f cactus_size(const uint cactus_id) {
37   return resource_manager.get!Texture(cactus_id.name).getSize.changeType!float;
38 }
39 
40 /// Cactus class
41 class Cactus : Drawable, Collidable {
42 	private const(Collider) collider_not_translated;
43 
44   private uint cactus_id;
45 
46   /// Distance from the left side of the window
47   float horizontal_offset;
48 
49   /// Height of the game window
50   float window_height;
51 
52   /// Constructs a cactus with given type and position
53   this(uint _cactus_id, float _horizontal_offset) {
54     cactus_id = _cactus_id;
55     horizontal_offset = _horizontal_offset;
56 
57 		collider_not_translated = get_collider(cactus_id);
58 	}
59 
60   /// Texture of the cactus
61   const(Texture) texture() const {
62     return resource_manager.get!Texture(cactus_id.name);
63   }
64 
65   /// Position of the cactus
66   Vector2f position() const {
67     return Vector2f(horizontal_offset, window_height - cactus_id.cactus_size.y);
68   }
69 
70   /// Moves a cactus by a given distance
71   void move(float distance) {
72     horizontal_offset -= distance;
73   }
74 
75   /* Override methods from Drawable and Collidable */
76   override void draw(RenderTarget window, RenderStates states) const {
77     RectangleShape s = new RectangleShape;
78     s.position(position);
79     s.size(cactus_size(cactus_id));
80     s.setTexture(texture);
81     s.fillColor(Color(255, 255, 255));
82 
83     window.draw(s);
84 		window.draw(collider_not_translated.translate(position));
85   }
86 
87   override Collider collider() const {
88 		return collider_not_translated.translate(position);
89   }
90 }
91 
92 /// Creates a randomly prepared cactus
93 Cactus random_cactus_at(float horizontal_offset, uint window_height) {
94   import std.random : uniform;
95 
96   auto res = new Cactus(uniform!uint % cactus_count + 1, horizontal_offset);
97   res.window_height = window_height;
98   return res;
99 }