| 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 |