Graphical object builder

Hi,

I realise this has probably been done in many ways by many people, but I thought I should share for those who haven’t done this yet…

I’ve built a little program which (preferably using the iPad simulator) can be used to load an image, add it to a display group, draw a physics collision object on top of the image and drop it onto a platform.

Its best to use the mouse in the simulator, but it would run fine, if imprecise, on the device, and should run on all devices and the centre of the world is calculated, not fixed.

The source is below and only needs a couple of images from the Chains sample code, but if you want to download it and run it straight off, here’s a direct link to the whole thing:

https://files.me.com/horacebury/rdfxzh

Hope this is useful, I know it will be for me…

Matt.

local physics = require(“physics”)
physics.start()
local physicsState = true

– not used, but simply prints all values in a table
function PrintAll( event )
for i,v in pairs(event) do
print( tostring(i) … ’ ’ … tostring(v))
end
end

– this image is found in the Chains sample code, among others
local imgpath = “grille_bkg.png”
local centre = { x = display.contentWidth / 2, y = display.contentHeight / 2 }
local points = {}

– cog is just a name for the display group, its not important (thought I was going to draw a cog, at the start)
local cog = display.newGroup()
– loads the image, places it in the centre of the display group and the display group in the centre of the world (selfish)
local img = display.newImage( cog, imgpath )
img.x = 0
img.y = 0
cog.x = display.contentWidth / 2
cog.y = display.contentHeight / 2

– draws a dot, but be careful because the x’s and y’s must be relative to the display group’s centre, not world centre
function Dot(x,y,r,g,b,s)
local circle = display.newCircle( cog, x, y, 1 )
circle:setStrokeColor( r,g,b )
circle.strokeWidth = s
end

– the initial, world centre and position the display group is placed at (for easier drawing around centre of phyiscal object)
Dot( 0,0, 255,255,255, 1 )

– draws a line, but be careful because the x’s and y’s must be relative to the display group’s centre, not world centre
function Line(ax,ay,bx,by,r,g,b,s)
local line = display.newLine( cog, ax,ay , bx,by )
line:setColor( r,g,b )
line.width = s
end

– deals with adding points to the points table
function OnTap(event)
print('x: ‘…event.x…’ y: '…event.y )
if (event.y > display.contentHeight - 100) then
– draw the final line to complete the outline
Line(
points[1], points[2],
points[#points-1], points[#points-0],
0,255,0, 5
)
– create the physical object
DoBuildPhysical()
– save the points data to a re-usable file
Save()
else
– add a point as consecutive values in the array
– just try to make sure your final object has points encircling the centre point, otherwise the physics goes weird
points[#points+1] = event.x - centre.x
points[#points+1] = event.y - centre.y
– if there are not enough points to draw a line, draw the first point as a dot
if (#points < 4) then
Dot( event.x-centre.x,event.y-centre.y, 0,255,0, 1 )
else
– there are enough points to start drawing the outline, so draw it
Line(
points[#points-3], points[#points-2],
points[#points-1], points[#points-0],
0,255,0, 5
)
end
end
end

– saves the centre values then the points values in a file. prints the path name in the console, too.
function Save()
– get path to data file
local path = system.pathForFile( “data.txt”, system.DocumentsDirectory )
print('path: '…path)

– open file for writing, overwrites previous file of same name
local file = io.open( path, “w” )

– save name of image used
file:write( imgpath, “\n” )

– save point
file:write( centre.x, “\n”, centre.y, “\n” )

– save individual points (x,y stored at consecutive indices)
for i=1, #points do
file:write(points[i], “\n”)
end

– close data file
io.close( file )
end

– builds the physics object using the points provided
function DoBuildPhysical()
physics.addBody( cog, { friction=0.5, bounce=0.5, density=3, shape=points } )
cog.x = centre.x
cog.y = centre.y
end

– just puts some ground for the eventual object to land on (aren’t I nice?)
– this image can be found, also, in the Chains sample code, among others
for i=0, 3 do
local g1 = display.newImage( “beam_long.png” )
g1.x = i*300
g1.y = display.contentHeight - 100
physics.addBody( g1, “static”, { friction=1, bounce=0.1, density=3 } )
end

– just attaches the listener for tap events - it is better to places points on screen using the simulator
– because the mouse is more precise, but it’s fun to build objects using your finger too
Runtime:addEventListener( “tap”, OnTap )
[import]uid: 8271 topic_id: 3326 reply_id: 303326[/import]

Thanks for providing this for the people. Next time wrap your code around these statements:

< LUA>
< /LUA>

Just like it is listed below. [import]uid: 5712 topic_id: 3326 reply_id: 9945[/import]

Ah, yes, sorry; I was looking for that element the other day and must have missed it… [import]uid: 8271 topic_id: 3326 reply_id: 9953[/import]

Btw, just to point out that the add points to the physical collision object created, tap/click around the white centre dot in a clockwise direction, as per Ansca’s instructions:

http://developer.anscamobile.com/content/game-edition-physics-bodies#Polygon_bodies

Once you’ve placed your last point, which is NOT at the same location as the first point, tap BELOW the platform images at the bottom. The program will then complete the outline of the collision shape with one last line and add it as a collision shape to the dynamic physics object.

I’ve had some unusual results, but I personally haven’t seen anything that seems to indicate the limit of 8 points is really important. Having said that, this is a very simple program, of course.

Matt. [import]uid: 8271 topic_id: 3326 reply_id: 9956[/import]