Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Help rendering a realistic road

edited February 2012 Posts: 2,820

Hello fellow coders,
As I mentioned before, I'm coding frogger and want a nice road. I want it to not be repudiative, so I don't want to tile an image, which i've done and looks alright, but not high enough for my standards. Right now, this is my code. On estimation, it would take 5.25 hours to render on my iPad 2.

``````Road = class()

self.lanes = 10
self.lly = 0
--self.pavement = pavement()
self.pavementdots = makeArray(WIDTH)
for x = 1, WIDTH do
for y = 1, HEIGHT/7*5 do
self.pavementdots[x][y] = math.random(125)
end
end
self.pavement = image(WIDTH,HEIGHT/7*5)
for x = 1, WIDTH do
for y = 1, HEIGHT/7*5 do
clearOutput()
print(x.."\n"..y)
print(WIDTH.."\n".. HEIGHT)
self.pavement:set(x,y,self.pavementdots[x][y],
self.pavementdots[x][y],
self.pavementdots[x][y],255)
end
end
end

--draw the pavement
sprite(pavement,0,HEIGHT - HEIGHT/7*6)

--draw the lines
strokeWidth(8)
for j = 1,(self.lanes-1) do
self.lly = (HEIGHT - HEIGHT/7*6)+((HEIGHT/7*5)/(self.lanes))*j
for i = 0, WIDTH/50 do
sline = i * 50
line(sline, self.lly,sline+25,self.lly)
end
end
end

end
``````

I've tried different methods, but I can't get it fast. I'm wondering if meshing it is the solution... Although it's kind of hard for me to understand meshes... Can someone please help?
Thanks!

Tagged:

• Posts: 2,820

Can someone please create a good mesh tutorial please?

• Posts: 622

Possible solution

Start with a small image and random it normally

Copy it

Rotate it 90 degrees

Randomly randomize only a small percent of it

Repeat

Possibly combine all the images onto one image when done (and draw the lines over it)

• Posts: 622

also the noise example only takes ~30 seconds to render when tileSize = 1 on an IPad1

you have to exit codea to stop it (sort of hard to time pressing exit between the long draws)

• edited February 2012 Posts: 622

Sorry for the triple post ...

Instant

``````function setup()
pr = image(WIDTH,1)
for x = 1, WIDTH do
dot = math.random(125)
pr:set(x,1,dot,dot,dot,255)
end
ps = {}
for y = 1, HEIGHT do
ps[y] = math.random(WIDTH)
end
end

function draw()
for y = 1, HEIGHT do
sprite(pr,(WIDTH/2)-ps[y],y)
sprite(pr,WIDTH+(WIDTH/2)-ps[y],y)
end
end
``````
• Posts: 2,820

Oh... Thanks. I forgot about noise.

• Posts: 2,820

I'll try that put when I get a chance.

• Posts: 143

Maybe the array creation is the problem. You create a huge array of random numbers, then use those numbers to set pixels in the image, and then never use the array again. Why not just set the pixel components to random numbers and not use an array at all?

• edited February 2012 Posts: 622

thx @nat, I was wondering why mine was so much faster. I thought it was just the reuse of a 1 pixel tall image, randomly stacked on itself, but, the direct random may have been a big boost as well.

• Posts: 2,820

Generating noise is working very well :-) Thanks guys!

• Posts: 159

@Zoyt I just put this together, not sure if it's any use? You can specify a road's x, y, width, height, 'scale factor' (basically the size of the pixels that make up the road's texture), and an optional number of lanes.

``````--# Main

function setup()
road1 = Road(WIDTH/2, 200, WIDTH, 250, 1, 5)
road2 = Road(WIDTH/2, 450, WIDTH, 100, 2)
road3 = Road(WIDTH/2, 600, WIDTH, 100, 4)
end

function draw()
background(56, 201, 15, 255)
end

RoadLineHeight = 2    -- base height of road markings
RoadLineWidth = 40    -- width of each road marking
RoadLineGap = 40      -- gap between each road marking

self.x = x
self.y = y
self.s = scaleFactor    -- default of 2 - change to alter 'blockiness'
if (not self.s) then self.s = 2 end
self.lanes = lanes
if (not self.lanes) then self.lanes = 2 end

self.img = image(w, h)    -- our road image!
self:render()
end

sprite(self.img, self.x, self.y)
end

-- for each block in the road
for xx = 1, self.img.width, self.s do
for yy = 1, self.img.height, self.s do
-- pick a random grey
local grey = math.random(30)
-- fill in a scaleFactor x scaleFactor block of pixels
for xoffset = 0, self.s-1 do
for yoffset = 0, self.s-1 do
self.img:set(xx+xoffset, yy+yoffset, grey, grey, grey, 255)
end
end
end
end

-- finally, draw on the markings
setContext(self.img)
pushStyle()

stroke(255, 241, 0, 255)
noSmooth()
if self.lanes > 1 then
local gap = self.img.height / self.lanes
for i = 0, self.lanes-1 do
local lineStart = RoadLineGap
while (lineStart < self.img.width) do
line(lineStart, gap * i, lineStart+RoadLineWidth, gap * i)
lineStart = lineStart + RoadLineWidth + RoadLineGap
end
end
end

popStyle()
setContext()
end
``````
• Posts: 2,820

Wow. Thanks @frosty. I'll try it out. As you may be able to tell, I'm picky w my graphics

• Posts: 622

We should make this into a side contest, which method is fastest. Mine is a bit of a cheat since it's not a parameterized class, so, it would be hard to tell.

• Posts: 2,820

Haha. I think I'll try it and tell you guys.

• Posts: 159

Mine takes a little bit of time to create the road in the first place, but it's then rendered to a single image so drawing it is as fast as drawing any other sprite.

Here's a quick image:

• Posts: 2,820

Most beautiful - @frosty :-) Much better looking than my meathod with darkening noise. Speed?... I'll see. An frosty, what ups are you using?

• Posts: 2,820

Haha. Can't wait to release this M rated version of Frogger :-)

• Posts: 159

@Zoyt ups?

• Posts: 2,820