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