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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
| _W = display.contentWidth;
_H = display.contentHeight;
m = {}
m.random = math.random;
local state = display.newGroup();
-- Imports
local movieclip = require("movieclip");
local physics = require("physics");
physics.start();
-- Import projectile classes
local projectile = require("projectile");
-- Variables setup
local projectiles_container = nil;
local force_multiplier = 10;
local velocity = m.random(50,100);
-- Visible groups setup
local background = display.newGroup();
local slingshot_container = display.newGroup();
-- Build the catapult
-- Slingshot
local sling = display.newImage("images/sling.png",true);
sling:setReferencePoint(display.CenterReferencePoint);
sling.x = 159; sling.y = 743;
-- Move catapult up
slingshot_container.y = 50;
local state_value = nil;
-- Transfer variables to the projectile classes
projectile.shot = shot;
projectile.band_stretch = band_stretch;
-- Background image
local bg_image = display.newImage("lavel1base.png",true);
background:insert(bg_image);
local slingshot = display.newImage("slingshot.png",350,380)
--[[
projectile TOUCH FUNCTION
]]--
local function projectileTouchListener(e)
-- The current projectile on screen
local t = e.target;
-- If the projectile is 'ready' to be used
if(t.ready) then
-- if the touch event has started...
if(e.phase == "began") then
-- Play the band stretch
audio.play(band_stretch);
-- Set the stage focus to the touched projectile
display.getCurrentStage():setFocus( t );
t.isFocus = true;
t.bodyType = "kinematic";
-- Stop current physics motion, if any
t:setLinearVelocity(0,0);
t.angularVelocity = 0;
-- Init the elastic band.
local myLine = nil;
local myLineBack = nil;
-- Bunny eyes animation
-- If the target of the touch event is the focus...
elseif(t.isFocus) then
-- If the target of the touch event moves...
if(e.phase == "moved") then
-- If the band exists... refresh the drawing of the line on the stage.
if(myLine) then
myLine.parent:remove(myLine); -- erase previous line
myLineBack.parent:remove(myLineBack); -- erase previous line
myLine = nil;
myLineBack = nil;
end
-- If the projectile is in the top left position
if(t.x < 105 and t.y < _H - 165)then
myLineBack = display.newLine(t.x - 30, t.y, 455, _H - 125);
myLine = display.newLine(t.x - 30, t.y, 375, _H - 125);
-- If the projectile is in the top right position
elseif(t.x > 105 and t.y < _H - 125)then
myLineBack = display.newLine(t.x + 10, t.y - 25, 455, _H - 125);
myLine = display.newLine(t.x + 10, t.y - 25, 375, _H - 125);
-- If the projectile is in the bottom left position
elseif(t.x < 105 and t.y > _H - 125)then
myLineBack = display.newLine(t.x - 25, t.y + 20, 455, _H - 125);
myLine = display.newLine(t.x - 25, t.y + 20, 375, _H - 125);
-- If the projectile is in the bottom right position
elseif(t.x > 105 and t.y > _H - 125)then
myLineBack = display.newLine(t.x - 15, t.y + 30, 455, _H - 125);
myLine = display.newLine(t.x - 15, t.y + 30, 375, _H - 125);
else
-- Default position (just in case).
myLineBack = display.newLine(t.x - 25, t.y, 420, _H - 125);
myLine = display.newLine(t.x - 25, t.y, 375, _H - 125);
end
-- Set the elastic band's visual attributes
myLineBack:setColor(20,51,51);
myLineBack.width = 12;
myLine:setColor(20,51,51);
myLine.width = 12;
-- Insert the components of the catapult into a group.
slingshot_container:insert(sling);
slingshot_container:insert(myLineBack);
slingshot_container:insert(t);
slingshot_container:insert(myLine);
slingshot_container:insert(sling);
-- Boundary for the projectile when grabbed
local bounds = e.target.stageBounds;
bounds.xMax = 600;
bounds.xMin = 300;
bounds.yMax = _H - 250;
bounds.yMax = 250;
if(e.y > bounds.yMax) then
t.y = e.y;
else
end
if(e.x < bounds.xMax) then
t.x = e.x;
else
-- Do nothing
end
-- If the projectile touch event ends (player lets go)...
elseif(e.phase == "ended" or e.phase == "cancelled") then
-- Open bunny eyes
-- Remove projectile touch so player can't grab it back and re-use after firing.
projectiles_container:removeEventListener("touch", projectileTouchListener);
-- Reset the stage focus
display.getCurrentStage():setFocus(nil);
t.isFocus = false;
-- Play the release sound
audio.play(shot);
-- Remove the elastic band
if(myLine) then
myLine.parent:remove(myLine); -- erase previous line
myLineBack.parent:remove(myLineBack); -- erase previous line
myLine = nil;
myLineBack = nil;
end
-- Launch projectile
t.bodyType = "dynamic";
t:applyForce((160 - e.x)*force_multiplier, (_H - 160 - e.y)*force_multiplier, t.x, t.y);
t:applyTorque( 100 )
t.isFixedRotation = false;
-- Wait a second before the catapult is reloaded (Avoids conflicts).
t.timer = timer.performWithDelay(1000, function(e)
state:dispatchEvent({name="change", state="fire"});
if(e.count == 1) then
timer.cancel(t.timer);
t.timer = nil;
end
end, 1)
end
end
end
end
--[[
SPAWN projectile FUNCTION
]]--
local function spawnProjectile()
-- If there is a projectile available then...
if(projectile.ready)then
projectiles_container = projectile.newProjectile();
-- Flag projectiles for removal
projectiles_container.ready = true;
projectiles_container.remove = true;
-- Reset the indexing for the visual attributes of the catapult.
slingshot_container:insert(projectiles_container);
-- Reset bunny eyes animation
-- Add an event listener to the projectile.
projectiles_container:addEventListener("touch", projectileTouchListener);
end
end
--[[
GAME STATE CHANGE FUNCTION
]]--
function state:change(e)
if(e.state == "fire") then
-- You fired...
-- new projectile please
spawnProjectile();
end
end
-- Tell the projectile it's good to go!
projectile.ready = true;
-- Spawn the first projectile.
spawnProjectile();
-- Create listnener for state changes in the game
state:addEventListener("change", state); |