Chromium Code Reviews| 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 |