OLD | NEW |
1 -- Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 -- Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 -- Use of this source code is governed by a BSD-style license that can be | 2 -- Use of this source code is governed by a BSD-style license that can be |
3 -- found in the LICENSE file. | 3 -- found in the LICENSE file. |
4 | 4 |
5 -- Functions for drawing new sprites using a brush. | 5 -- Functions for drawing new sprites using a brush. |
6 -- This module defines a single 'drawing' global containing the following | 6 -- This module defines a single 'drawing' global containing the following |
7 -- functions: | 7 -- functions: |
8 -- - SetBrush | 8 -- - SetBrush |
9 -- - CreateShape | 9 -- - CreateShape |
10 -- - CreateSprite | 10 -- - CreateSprite |
(...skipping 10 matching lines...) Expand all Loading... |
21 MODE_SELECT = 1, | 21 MODE_SELECT = 1, |
22 MODE_FREEHAND = 2, | 22 MODE_FREEHAND = 2, |
23 MODE_LINE = 3, | 23 MODE_LINE = 3, |
24 MODE_RECT = 4, | 24 MODE_RECT = 4, |
25 MODE_CIRCLE = 5, | 25 MODE_CIRCLE = 5, |
26 } | 26 } |
27 | 27 |
28 drawing.mode = drawing.MODE_FREEHAND | 28 drawing.mode = drawing.MODE_FREEHAND |
29 | 29 |
30 -- Brush information (set by SetBrush) | 30 -- Brush information (set by SetBrush) |
31 local brush_node | 31 local brush_tex |
32 local brush_thickness | 32 local brush_thickness |
33 | 33 |
34 -- Constant for grouping physics bodies | 34 -- Constant for grouping physics bodies |
35 local MAIN_CATEGORY = 0x1 | 35 local MAIN_CATEGORY = 0x1 |
36 local DRAWING_CATEGORY = 0x2 | 36 local DRAWING_CATEGORY = 0x2 |
37 | 37 |
| 38 -- Constants for tagging cocos nodes |
| 39 local TAG_BATCH_NODE = 0x1 |
| 40 |
| 41 -- Starting batch size for CCSpriteBatchNode. We override |
| 42 -- the default since we often have many sprites in each |
| 43 -- node (each drawn element is it own batch node). |
| 44 local DEFAULT_BATCH_COUNT = 100 |
| 45 |
38 -- Local state for default touch handlers | 46 -- Local state for default touch handlers |
39 local current_shape = nil | 47 local current_shape = nil |
40 local current_tag = 99 -- util.tags.TAG_DYNAMIC_START | 48 local current_tag = 99 -- util.tags.TAG_DYNAMIC_START |
41 local start_pos = nil | 49 local start_pos = nil |
42 local last_pos = nil | 50 local last_pos = nil |
43 local brush_color = ccc3(255, 100, 100) | 51 local brush_color = ccc3(255, 100, 100) |
44 | 52 |
45 -- Callbacks that are registered for drawn objects. The game | 53 -- Callbacks that are registered for drawn objects. The game |
46 -- can register its own callbacks here to add behavior for | 54 -- can register its own callbacks here to add behavior for |
47 -- drawn objects. | 55 -- drawn objects. |
48 drawing.handlers = {} | 56 drawing.handlers = {} |
49 | 57 |
50 --- Create a b2Vec from a lua list containing 2 elements. | 58 --- Create a b2Vec from a lua list containing 2 elements. |
51 -- This is used to convert point data from .def files directly | 59 -- This is used to convert point data from .def files directly |
52 -- to the box2dx coordinate system | 60 -- to the box2dx coordinate system |
53 local function b2VecFromLua(point) | 61 local function b2VecFromLua(point) |
54 return util.b2VecFromCocos(util.PointFromLua(point)) | 62 return util.b2VecFromCocos(util.PointFromLua(point)) |
55 end | 63 end |
56 | 64 |
| 65 local function CreateBrushBatch(parent) |
| 66 local node = CCSpriteBatchNode:createWithTexture(brush_tex, DEFAULT_BATCH_CO
UNT) |
| 67 assert(node) |
| 68 parent:addChild(node, 1, TAG_BATCH_NODE) |
| 69 return node |
| 70 end |
| 71 |
57 --- Create a fixed pivot point between the world and the given body. | 72 --- Create a fixed pivot point between the world and the given body. |
58 local function CreatePivot(anchor, body) | 73 local function CreatePivot(anchor, body) |
59 local anchor_point = util.b2VecFromCocos(anchor) | 74 local anchor_point = util.b2VecFromCocos(anchor) |
60 | 75 |
61 -- create a new fixed body to pivot against | 76 -- create a new fixed body to pivot against |
62 local ground_def = b2BodyDef:new_local() | 77 local ground_def = b2BodyDef:new_local() |
63 ground_def.position = anchor_point | 78 ground_def.position = anchor_point |
64 local ground_body = level_obj.world:CreateBody(ground_def); | 79 local ground_body = level_obj.world:CreateBody(ground_def); |
65 | 80 |
66 -- create the pivot joint | 81 -- create the pivot joint |
67 local joint_def = b2RevoluteJointDef:new_local() | 82 local joint_def = b2RevoluteJointDef:new_local() |
68 joint_def:Initialize(ground_body, body, anchor_point) | 83 joint_def:Initialize(ground_body, body, anchor_point) |
69 local joint = level_obj.world:CreateJoint(joint_def) | 84 local joint = level_obj.world:CreateJoint(joint_def) |
70 end | 85 end |
71 | 86 |
72 local function AddShapeToBody(body, shape, sensor) | 87 local function AddShapeToBody(body, shape, sensor) |
73 local fixture_def = b2FixtureDef:new_local() | 88 local fixture_def = b2FixtureDef:new_local() |
74 fixture_def.shape = shape | 89 fixture_def.shape = shape |
75 fixture_def.density = 1.0 | 90 fixture_def.density = 1.0 |
76 fixture_def.friction = 0.5 | 91 fixture_def.friction = 0.5 |
77 fixture_def.restitution = 0.3 | 92 fixture_def.restitution = 0.3 |
78 fixture_def.isSensor = sensor | 93 fixture_def.isSensor = sensor |
79 return body:CreateFixture(fixture_def) | 94 return body:CreateFixture(fixture_def) |
80 end | 95 end |
81 | 96 |
82 local function InitPhysicsSprite(sprite, location, dynamic) | 97 local function InitPhysicsNode(node, location, dynamic, tag) |
83 local body_def = b2BodyDef:new_local() | 98 local body_def = b2BodyDef:new_local() |
84 if dynamic == true then | 99 if dynamic == true then |
85 body_def.type = b2_dynamicBody | 100 body_def.type = b2_dynamicBody |
86 end | 101 end |
87 local body = level_obj.world:CreateBody(body_def) | 102 local body = level_obj.world:CreateBody(body_def) |
88 sprite:setB2Body(body) | 103 node:setB2Body(body) |
89 sprite:setPTMRatio(util.PTM_RATIO) | 104 node:setPTMRatio(util.PTM_RATIO) |
90 sprite:setPosition(location) | 105 node:setPosition(location) |
| 106 node:setTag(tag) |
| 107 body:SetUserData(tag) |
| 108 level_obj.layer:addChild(node, 1, tag) |
91 return body | 109 return body |
92 end | 110 end |
93 | 111 |
| 112 -- Create and initialise a new invisible physics node. |
| 113 local function CreatePhysicsNode(location, dynamic, tag) |
| 114 local node = CCPhysicsNode:create() |
| 115 InitPhysicsNode(node, location, dynamic, tag) |
| 116 return node |
| 117 end |
| 118 |
94 local function DrawBrush(parent, location, color) | 119 local function DrawBrush(parent, location, color) |
95 local child_sprite = CCSprite:createWithTexture(brush_tex) | 120 local child_sprite = CCSprite:createWithTexture(brush_tex) |
96 child_sprite:setPosition(location) | 121 child_sprite:setPosition(location) |
97 child_sprite:setColor(color) | 122 child_sprite:setColor(color) |
98 parent:addChild(child_sprite) | 123 parent:addChild(child_sprite) |
99 end | 124 end |
100 | 125 |
101 function DrawPhysicsBrush(location, color, tag, dynamic) | |
102 local sprite = CCPhysicsSprite:createWithTexture(brush_tex) | |
103 local body = InitPhysicsSprite(sprite, location, dynamic) | |
104 sprite:setColor(color) | |
105 sprite:setTag(tag) | |
106 body:SetUserData(tag) | |
107 brush_node:addChild(sprite) | |
108 return sprite | |
109 end | |
110 | |
111 -- Add a new circle/sphere fixture to a body and return the new fixture | 126 -- Add a new circle/sphere fixture to a body and return the new fixture |
112 local function AddSphereToBody(body, location, radius, sensor) | 127 local function AddSphereToBody(body, location, radius, sensor) |
113 local sphere = b2CircleShape:new_local() | 128 local sphere = b2CircleShape:new_local() |
114 sphere.m_radius = util.ScreenToWorld(radius) | 129 sphere.m_radius = util.ScreenToWorld(radius) |
115 sphere.m_p.x = util.ScreenToWorld(location.x) - body:GetPosition().x | 130 sphere.m_p.x = util.ScreenToWorld(location.x) - body:GetPosition().x |
116 sphere.m_p.y = util.ScreenToWorld(location.y) - body:GetPosition().y | 131 sphere.m_p.y = util.ScreenToWorld(location.y) - body:GetPosition().y |
117 return AddShapeToBody(body, sphere, sensor) | 132 return AddShapeToBody(body, sphere, sensor) |
118 end | 133 end |
119 | 134 |
120 -- Add a new line/box fixture to a body and return the new fixture | 135 -- Add a new line/box fixture to a body and return the new fixture |
121 local function AddLineToShape(sprite, from, to, color) | 136 local function AddLineToShape(node, from, to, color, absolute) |
122 -- calculate length and angle of line based on start and end points | 137 -- calculate length and angle of line based on start and end points |
123 local body = sprite:getB2Body() | 138 local body = node:getB2Body() |
124 local length = ccpDistance(from, to); | 139 local length = ccpDistance(from, to); |
125 local dist_x = to.x - from.x | 140 local dist_x = to.x - from.x |
126 local dist_y = to.y - from.y | 141 local dist_y = to.y - from.y |
127 | 142 |
128 -- create fixture | 143 -- create fixture |
129 local relative_start_x = from.x - sprite:getPositionX() | 144 local rel_start = from |
130 local relative_start_y = from.y - sprite:getPositionY() | 145 if absolute then |
131 local center = b2Vec2:new_local(util.ScreenToWorld(relative_start_x + dist_x
/2), | 146 rel_start = node:convertToNodeSpace(from) |
132 util.ScreenToWorld(relative_start_y + dist_y
/2)) | 147 end |
| 148 local center = b2Vec2:new_local(util.ScreenToWorld(rel_start.x + dist_x/2), |
| 149 util.ScreenToWorld(rel_start.y + dist_y/2)) |
133 local shape = b2PolygonShape:new_local() | 150 local shape = b2PolygonShape:new_local() |
134 local angle = math.atan2(dist_y, dist_x) | 151 local angle = math.atan2(dist_y, dist_x) |
135 shape:SetAsBox(util.ScreenToWorld(length/2), util.ScreenToWorld(brush_thickn
ess), | 152 shape:SetAsBox(util.ScreenToWorld(length/2), util.ScreenToWorld(brush_thickn
ess), |
136 center, angle) | 153 center, angle) |
137 local fixture = AddShapeToBody(body, shape, false) | 154 local fixture = AddShapeToBody(body, shape, false) |
138 | 155 |
139 -- Now create the visible CCPhysicsSprite that the body is attached to | 156 -- Create sequence of sprite nodes as children |
140 sprite:setColor(color) | |
141 sprite:setPTMRatio(util.PTM_RATIO) | |
142 | |
143 -- And add a sequence of non-physics sprites as children of the first | |
144 local dist = CCPointMake(dist_x, dist_y) | 157 local dist = CCPointMake(dist_x, dist_y) |
145 local num_children = math.ceil(length / brush_step) | 158 local num_children = math.ceil(length / brush_step) |
146 local inc_x = dist_x / num_children | 159 local inc_x = dist_x / num_children |
147 local inc_y = dist_y / num_children | 160 local inc_y = dist_y / num_children |
148 local child_location = ccp(relative_start_x + brush_thickness, relative_star
t_y + brush_thickness) | 161 local child_location = rel_start |
149 | 162 |
150 util.Log('Create line at: ' .. util.PointToString(from) .. ' len=' .. length
.. ' num=' .. num_children) | 163 util.Log('Create line at: rel=' .. util.PointToString(rel_start) .. ' len='
.. length .. ' num=' .. num_children) |
| 164 |
| 165 local batch_node = node:getChildByTag(TAG_BATCH_NODE) |
| 166 assert(batch_node) |
151 for i = 1,num_children do | 167 for i = 1,num_children do |
152 child_location.x = child_location.x + inc_x | 168 child_location.x = child_location.x + inc_x |
153 child_location.y = child_location.y + inc_y | 169 child_location.y = child_location.y + inc_y |
154 DrawBrush(sprite, child_location, color) | 170 DrawBrush(batch_node, child_location, color) |
155 end | 171 end |
156 | 172 |
157 return fixture | 173 return fixture |
158 end | 174 end |
159 | 175 |
160 --- Create a line between two points. | |
161 -- Uses a sequence of brush sprites an a single box2d rect. | |
162 local function CreateLine(from, to, objdef) | |
163 -- create body | |
164 util.Log("Creating line with tag " .. objdef.tag) | |
165 | |
166 if objdef.color then | |
167 color = ccc3(objdef.color[1], objdef.color[2], objdef.color[3]) | |
168 else | |
169 color = ccc3(255, 255, 255) | |
170 end | |
171 | |
172 local sprite = drawing.DrawStartPoint(from, color, objdef.tag, objdef.dynami
c) | |
173 if objdef.anchor then | |
174 CreatePivot(objdef.anchor, sprite:getB2Body()) | |
175 end | |
176 AddLineToShape(sprite, from, to, color) | |
177 return sprite | |
178 end | |
179 | |
180 -- Set the collision group for a fixture | 176 -- Set the collision group for a fixture |
181 local function SetCategory(fixture, category) | 177 local function SetCategory(fixture, category) |
182 local filter = fixture:GetFilterData() | 178 local filter = fixture:GetFilterData() |
183 filter.categoryBits = category | 179 filter.categoryBits = category |
184 filter.maskBits = category | 180 filter.maskBits = category |
185 fixture:SetFilterData(filter) | 181 fixture:SetFilterData(filter) |
186 end | 182 end |
187 | 183 |
188 --- Make the a body dynamic and put it in the default collision group | 184 --- Make the a body dynamic and put it in the default collision group |
189 local function MakeBodyDynamic(body) | 185 local function MakeBodyDynamic(body) |
190 body:SetType(b2_dynamicBody) | 186 body:SetType(b2_dynamicBody) |
191 local fixture = body:GetFixtureList() | 187 local fixture = body:GetFixtureList() |
192 while fixture do | 188 while fixture do |
193 SetCategory(fixture, MAIN_CATEGORY) | 189 SetCategory(fixture, MAIN_CATEGORY) |
194 fixture = fixture:GetNext() | 190 fixture = fixture:GetNext() |
195 end | 191 end |
196 end | 192 end |
197 | 193 |
198 --- Set brush texture for subsequent draw operations | 194 --- Set brush texture for subsequent draw operations |
199 function drawing.SetBrush(brush) | 195 function drawing.SetBrush(brush) |
200 -- calculate thickness based on brush sprite size | 196 -- calculate thickness based on brush sprite size |
201 brush_node = brush | |
202 brush_tex = brush:getTexture() | 197 brush_tex = brush:getTexture() |
203 local brush_size = brush_tex:getContentSizeInPixels() | 198 local brush_size = brush_tex:getContentSizeInPixels() |
204 brush_thickness = math.max(brush_size.height/2, brush_size.width/2) | 199 brush_thickness = math.max(brush_size.height/2, brush_size.width/2) |
205 brush_step = brush_thickness * 1.5 | 200 brush_step = brush_thickness * 1.5 |
206 end | 201 end |
207 | 202 |
| 203 --- Create a physics sprite at a given location with a given image |
| 204 local function AddSpriteToShape(node, sprite_def, absolute) |
| 205 local pos = util.PointFromLua(sprite_def.pos, absolute) |
| 206 util.Log('Create sprite [tag=' .. sprite_def.tag .. ' image=' .. sprite_def.
image .. ' absolute=' .. tostring(absolute) .. ']: ' .. |
| 207 util.PointToString(pos)) |
| 208 local image = game_obj.assets[sprite_def.image] |
| 209 local sprite = CCSprite:create(image) |
| 210 local rel_pos |
| 211 local world_pos |
| 212 if absolute then |
| 213 rel_pos = node:convertToNodeSpace(pos) |
| 214 world_pos = pos |
| 215 else |
| 216 rel_pos = pos |
| 217 world_pos = node:convertToWorldSpace(pos) |
| 218 end |
| 219 sprite:setPosition(rel_pos) |
| 220 node:addChild(sprite) |
| 221 AddSphereToBody(node:getB2Body(), world_pos, sprite:boundingBox().size.heigh
t/2, sprite_def.sensor) |
| 222 return sprite |
| 223 end |
| 224 |
| 225 local function AddChildShape(shape, child_def, absolute) |
| 226 if child_def.color then |
| 227 color = ccc3(child_def.color[1], child_def.color[2], child_def.color[3]) |
| 228 else |
| 229 color = ccc3(255, 255, 255) |
| 230 end |
| 231 |
| 232 if child_def.type == 'line' then |
| 233 local start = util.PointFromLua(child_def.start, absolute) |
| 234 local finish = util.PointFromLua(child_def.finish, absolute) |
| 235 AddLineToShape(shape, start, finish, color, absolute) |
| 236 elseif child_def.type == 'image' then |
| 237 AddSpriteToShape(shape, child_def, absolute) |
| 238 else |
| 239 assert(false, 'invalid shape type: ' .. shape_def.type) |
| 240 end |
| 241 end |
| 242 |
208 --- Draw a shape described by a given shape def. | 243 --- Draw a shape described by a given shape def. |
209 -- This creates physics sprites and accosiated box2d bodies for | 244 -- This creates physics sprites and accosiated box2d bodies for |
210 -- the shape. | 245 -- the shape. |
211 function drawing.CreateShape(shape_def) | 246 function drawing.CreateShape(shape_def) |
212 if shape_def.type == 'line' then | 247 local shape = nil |
213 local start = util.PointFromLua(shape_def.start) | 248 |
214 local finish = util.PointFromLua(shape_def.finish) | 249 if shape_def.type == 'compound' then |
215 if shape_def.anchor then | 250 local pos = util.PointFromLua(shape_def.pos) |
216 shape_def.anchor = util.PointFromLua(shape_def.anchor) | 251 shape = CreatePhysicsNode(pos, shape_def.dynamic, shape_def.tag) |
| 252 CreateBrushBatch(shape) |
| 253 if shape_def.children then |
| 254 for _, child_def in ipairs(shape_def.children) do |
| 255 child_def.tag = shape_def.tag |
| 256 child = AddChildShape(shape, child_def, false) |
| 257 end |
217 end | 258 end |
218 return CreateLine(start, finish, shape_def) | 259 elseif shape_def.type == 'line' then |
| 260 local pos = util.PointFromLua(shape_def.start) |
| 261 shape = CreatePhysicsNode(pos, shape_def.dynamic, shape_def.tag) |
| 262 CreateBrushBatch(shape) |
| 263 AddChildShape(shape, shape_def, true) |
219 elseif shape_def.type == 'edge' then | 264 elseif shape_def.type == 'edge' then |
220 local body_def = b2BodyDef:new_local() | 265 local body_def = b2BodyDef:new_local() |
221 local body = level_obj.world:CreateBody(body_def) | 266 local body = level_obj.world:CreateBody(body_def) |
222 local b2shape = b2EdgeShape:new_local() | 267 local b2shape = b2EdgeShape:new_local() |
223 b2shape:Set(b2VecFromLua(shape_def.start), b2VecFromLua(shape_def.finish
)) | 268 b2shape:Set(b2VecFromLua(shape_def.start), b2VecFromLua(shape_def.finish
)) |
224 body:CreateFixture(b2shape, 0) | 269 body:CreateFixture(b2shape, 0) |
| 270 return |
| 271 elseif shape_def.type == 'image' then |
| 272 local pos = util.PointFromLua(shape_def.pos) |
| 273 shape = CreatePhysicsNode(pos, shape_def.dynamic, shape_def.tag) |
| 274 AddChildShape(shape, shape_def, true) |
225 else | 275 else |
226 assert(false) | 276 assert(false, 'invalid shape type: ' .. shape_def.type) |
227 end | 277 end |
228 end | |
229 | 278 |
230 --- Create a physics sprite at a fiven location with a given image | 279 if shape_def.anchor then |
231 function drawing.CreateSprite(sprite_def) | 280 local body = shape:getB2Body() |
232 local pos = util.PointFromLua(sprite_def.pos) | 281 local anchor = util.PointFromLua(shape_def.anchor) |
233 -- util.Log('Create sprite [tag=' .. sprite_def.tag .. ' image=' .. sprite_d
ef.image .. ']: ' .. | 282 CreatePivot(anchor, body) |
234 -- util.PointToString(pos)) | 283 end |
235 local image = game_obj.assets[sprite_def.image] | |
236 local sprite = CCPhysicsSprite:create(image) | |
237 local dynamic = not sprite_def.sensor | |
238 local body = InitPhysicsSprite(sprite, pos, dynamic) | |
239 body:SetUserData(sprite_def.tag) | |
240 | 284 |
241 AddSphereToBody(body, pos, sprite:boundingBox().size.height/2, sprite_def.se
nsor) | 285 return shape |
242 return sprite | |
243 end | 286 end |
244 | 287 |
245 --- Create a single circlular point with the brush. | 288 --- Create a single circlular point with the brush. |
246 -- This is used to start shapes that the use draws. The starting | 289 -- This is used to start shapes that the user draws. The returned |
247 -- point contains the box2d body for the shape. | 290 -- node is the an invisible node that acts as the physics objects. |
| 291 -- Sprite nodes are then attached to this as the user draws. |
248 function drawing.DrawStartPoint(location, color, tag, dynamic) | 292 function drawing.DrawStartPoint(location, color, tag, dynamic) |
| 293 -- Add invisibe physics node |
| 294 local node = CreatePhysicsNode(location, dynamic, tag) |
| 295 CreateBrushBatch(node) |
| 296 |
249 -- Add visible sprite | 297 -- Add visible sprite |
250 local sprite = DrawPhysicsBrush(location, color, tag, dynamic) | 298 local sprite = CCSprite:createWithTexture(brush_tex) |
| 299 sprite:setColor(color) |
| 300 node:addChild(sprite) |
251 | 301 |
252 -- Add collision info | 302 -- Add collision info |
253 local fixture = AddSphereToBody(sprite:getB2Body(), location, brush_thicknes
s, false) | 303 local fixture = AddSphereToBody(node:getB2Body(), location, brush_thickness,
false) |
254 SetCategory(fixture, DRAWING_CATEGORY) | 304 SetCategory(fixture, DRAWING_CATEGORY) |
255 | 305 |
256 return sprite | 306 return node |
257 end | 307 end |
258 | 308 |
259 --- Create a circle composed of brush sprites backed by a single box2d | 309 --- Create a circle composed of brush sprites backed by a single box2d |
260 -- circle fixture. | 310 -- circle fixture. |
261 function drawing.DrawCircle(center, radius, color, tag) | 311 function drawing.DrawCircle(center, radius, color, tag) |
262 -- Create an initial, invisble sprite at the center, to which we | 312 -- Create the initial (invisible) node at the center |
263 -- attach a sequence of visible child sprites | 313 -- and then attach a sequence of visible child sprites |
| 314 local node = CreatePhysicsNode(center, true, tag) |
| 315 local batch_node = CreateBrushBatch(node) |
264 | 316 |
265 local inner_radius = math.max(radius - brush_thickness, 1) | 317 local inner_radius = math.max(radius - brush_thickness, 1) |
266 local circumference = 2 * math.pi * inner_radius | 318 local circumference = 2 * math.pi * inner_radius |
267 local num_sprites = math.max(circumference / brush_step, 1) | 319 local num_sprites = math.max(circumference / brush_step, 1) |
268 local angle_delta = 2 * math.pi / num_sprites | 320 local angle_delta = 2 * math.pi / num_sprites |
269 | 321 |
270 -- The firsh brush draw is the origin of the physics object. | 322 util.Log('drawing circle: radius=' .. math.floor(radius) .. ' sprites=' .. m
ath.floor(num_sprites)) |
271 local start_point = ccp(center.x + inner_radius, center.y) | 323 for angle = 0, 2 * math.pi, angle_delta do |
272 local sprite = DrawPhysicsBrush(start_point, color, tag) | |
273 | |
274 local start_offset = ccp(start_point.x - center.x, start_point.y - center.y) | |
275 | |
276 local anchor = sprite:getAnchorPointInPoints() | |
277 util.Log('drawing circle: radius=' .. math.floor(radius) .. ' sprites=' .. n
um_sprites) | |
278 util.Log('drawing circle: anchor=' .. util.PointToString(anchor)) | |
279 for angle = angle_delta, 2 * math.pi, angle_delta do | |
280 x = inner_radius * math.cos(angle) | 324 x = inner_radius * math.cos(angle) |
281 y = inner_radius * math.sin(angle) | 325 y = inner_radius * math.sin(angle) |
282 local pos = ccp(x - start_offset.x + anchor.x, y - start_offset.y + anch
or.y) | 326 DrawBrush(batch_node, ccp(x, y), color) |
283 DrawBrush(sprite, pos, color) | |
284 end | 327 end |
285 | 328 |
286 -- Create the box2d physics body to match the sphere. | 329 -- Create the box2d physics body to match the sphere. |
287 local fixture = AddSphereToBody(sprite:getB2Body(), center, radius, false) | 330 local fixture = AddSphereToBody(node:getB2Body(), center, radius, false) |
288 SetCategory(fixture, DRAWING_CATEGORY) | 331 SetCategory(fixture, DRAWING_CATEGORY) |
289 | 332 return node |
290 return sprite | |
291 end | 333 end |
292 | 334 |
293 function drawing.DrawEndPoint(sprite, location, color) | 335 function drawing.DrawEndPoint(node, location, color) |
294 -- Add visible sprite | 336 -- Add visible sprite |
295 local child_sprite = CCSprite:createWithTexture(brush_tex) | 337 local child_sprite = CCSprite:createWithTexture(brush_tex) |
296 local relative_x = location.x - sprite:getPositionX() | 338 local relative_x = location.x - node:getPositionX() |
297 local relative_y = location.y - sprite:getPositionY() | 339 local relative_y = location.y - node:getPositionY() |
298 local brush_size = brush_tex:getContentSizeInPixels() | 340 child_sprite:setPosition(ccp(relative_x, relative_y)) |
299 child_sprite:setPosition(ccp(relative_x + brush_size.width/2, relative_y + b
rush_size.height/2)) | |
300 child_sprite:setColor(color) | 341 child_sprite:setColor(color) |
301 sprite:addChild(child_sprite) | 342 node:addChild(child_sprite) |
302 | 343 |
303 -- Add collision info | 344 -- Add collision info |
304 local body = sprite:getB2Body() | 345 local body = node:getB2Body() |
305 local fixture = AddSphereToBody(body, location, sprite:boundingBox().size.he
ight/2, false) | 346 local fixture = AddSphereToBody(body, location, brush_thickness, false) |
306 SetCategory(fixture, DRAWING_CATEGORY) | 347 SetCategory(fixture, DRAWING_CATEGORY) |
307 end | 348 end |
308 | 349 |
309 function drawing.AddLineToShape(sprite, from, to, color) | 350 function drawing.AddLineToShape(sprite, from, to, color) |
310 fixture = AddLineToShape(sprite, from, to, color) | 351 fixture = AddLineToShape(sprite, from, to, color, true) |
311 SetCategory(fixture, DRAWING_CATEGORY) | 352 SetCategory(fixture, DRAWING_CATEGORY) |
312 end | 353 end |
313 | 354 |
314 function drawing.IsDrawing() | 355 function drawing.IsDrawing() |
315 return current_shape ~= nil | 356 return current_shape ~= nil |
316 end | 357 end |
317 | 358 |
318 --- Sample OnTouchBegan for drawing-based games. For bespoke drawing behaviour | 359 --- Sample OnTouchBegan for drawing-based games. For bespoke drawing behaviour |
319 -- clone and modify this code. | 360 -- clone and modify this code. |
320 function drawing.OnTouchBegan(x, y) | 361 function drawing.OnTouchBegan(x, y) |
321 --- ignore touches if we are already drawing something | 362 --- ignore touches if we are already drawing something |
322 if drawing.IsDrawing() then | 363 if drawing.IsDrawing() then |
323 return false | 364 return false |
324 end | 365 end |
325 | 366 |
| 367 if drawing.mode == drawing.MODE_SELECT then |
| 368 return false |
| 369 end |
| 370 |
326 start_pos = ccp(x, y) | 371 start_pos = ccp(x, y) |
327 last_pos = start_pos | 372 last_pos = start_pos |
328 | 373 |
329 -- New shape def | 374 -- New shape def |
330 local shape = { | 375 local shape = { |
331 tag = current_tag, | 376 tag = current_tag, |
332 tag_str = 'drawn_shape_' .. current_tag, | 377 tag_str = 'drawn_shape_' .. current_tag, |
333 script = drawing.handlers, | 378 script = drawing.handlers, |
334 } | 379 } |
335 | 380 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 if length > brush_thickness * 2 then | 413 if length > brush_thickness * 2 then |
369 drawing.AddLineToShape(current_shape.node, last_pos, new_pos, brush_
color) | 414 drawing.AddLineToShape(current_shape.node, last_pos, new_pos, brush_
color) |
370 last_pos = new_pos | 415 last_pos = new_pos |
371 end | 416 end |
372 elseif drawing.mode == drawing.MODE_LINE then | 417 elseif drawing.mode == drawing.MODE_LINE then |
373 local tag = current_shape.node:getTag() | 418 local tag = current_shape.node:getTag() |
374 drawing.DestroySprite(current_shape.node) | 419 drawing.DestroySprite(current_shape.node) |
375 | 420 |
376 current_shape.node = drawing.DrawStartPoint(start_pos, brush_color, tag) | 421 current_shape.node = drawing.DrawStartPoint(start_pos, brush_color, tag) |
377 drawing.AddLineToShape(current_shape.node, start_pos, new_pos, brush_col
or) | 422 drawing.AddLineToShape(current_shape.node, start_pos, new_pos, brush_col
or) |
378 | |
379 elseif drawing.mode == drawing.MODE_CIRCLE then | 423 elseif drawing.mode == drawing.MODE_CIRCLE then |
380 local tag = current_shape.node:getTag() | 424 local tag = current_shape.node:getTag() |
381 drawing.DestroySprite(current_shape.node) | 425 drawing.DestroySprite(current_shape.node) |
382 radius = ccpDistance(start_pos, new_pos) | 426 radius = ccpDistance(start_pos, new_pos) |
383 current_shape.node = drawing.DrawCircle(start_pos, radius, brush_color,
tag) | 427 current_shape.node = drawing.DrawCircle(start_pos, radius, brush_color,
tag) |
384 else | 428 else |
385 error('invalid drawing mode: ' .. tostring(drawing.mode)) | 429 error('invalid drawing mode: ' .. tostring(drawing.mode)) |
386 end | 430 end |
387 end | 431 end |
388 | 432 |
(...skipping 18 matching lines...) Expand all Loading... |
407 MakeBodyDynamic(current_shape.node:getB2Body()) | 451 MakeBodyDynamic(current_shape.node:getB2Body()) |
408 | 452 |
409 local rtn = current_shape | 453 local rtn = current_shape |
410 last_pos = nil | 454 last_pos = nil |
411 start_pos = nil | 455 start_pos = nil |
412 current_shape = nil | 456 current_shape = nil |
413 return rtn | 457 return rtn |
414 end | 458 end |
415 | 459 |
416 return drawing | 460 return drawing |
OLD | NEW |