Would this be possible?

Monkey Archive Forums/Monkey Discussion/Would this be possible?

wmaass(Posted 2012) [#1]
Terrible thread title I know but:

I'm getting back to my top view golf game and I want to add terrain elevation and friction for ground collisions. I'm thinking I could have a color image that represents the course nice and pretty, a grayscale image for terrain height and another image that represents the different surfaces. Then I would get the color of the pixel under the ball for the terrain and friction when the ball hits the ground. Something like SetImage() and then GetColor(). Is this feasible?


therevills(Posted 2012) [#2]
The GetColor() command only gets the current colour set by SetColor().

You would need something like GetPixel(), which isnt included with Monkey/Mojo... I have added it to Diddy, but I wouldnt use it in a game as it seems pretty slow.


invaderJim(Posted 2012) [#3]
So I set out to come up with a really fast way to do this with Diddy's GetPixel function, but it doesn't seem to be fully implemented, and what you really need is a way to get pixels of images instead of the entire screen, so I made a little getimagepixel module!

I've got it working with all targets except iOS. iOS is going to be tricky...

Performance seems fairly decent on my machine. HTML5 is definitely the slowest, but that can be remedied by breaking the image up into smaller ones and then getting their pixels using a grid system.

Also, if you want to build for GLFW, you have to hack graphics.monkey by changing "Extern Private" to "Extern" before "Class Surface=..." and then adding the following to the Public section of the Image class:

	Method GetSurface:Surface()
		Return surface
	End


Here is an example of the HTML5 version in action:

http://www.invaderjim.com/games/GetPixelTest/MonkeyGame.html

My fabulous golf course image is somewhat big (640 x 960), so the "GetImagePixel Time" might not be ideal, but, as a I said, smaller images go much, much faster.

Enough babble.

Here's the download: http://www.invaderjim.com/games/GetPixelTest/GetPixelTest.zip

This is my example with the getimagepixel module included. Let me know if this helps you out any.

-Jim


MikeHart(Posted 2012) [#4]
How about predetermine the colors of an image and store it inside a 2D array. Then instead reading the color from the image, you read it from the array which should be blazing fast.


Paul - Taiphoz(Posted 2012) [#5]
If you are going to dump the level data into an array, then you could do that before hand and save the level hight friction data out to a textfile , then all your doing is loading that data into the array for each level.

I would also only read the height data from every third or fourth pixel, there really is not need to read every single pixel and your ball will probably sit over a number of pixels anyway.

Cutting down the number of pixels you read into your array will speed things up and make your arrays smaller and easier to manage.


wmaass(Posted 2012) [#6]
Thanks guys, this helps a great deal.


wmaass(Posted 2012) [#7]
invaderJim do you think iOS will be doable for your getimagepixel module? I am liking how it works for the targets it supports so far. Reading the data in to an array is still an option but I am finding that a nested loop is really slow. For example:


For y = 0 To 150
     For x = 0 To 100
	Print "Hi"
     Next
Next



...takes forever or never appears to run at all in an HTML5 test. I can do this ahead of time with a B3D or other app and create a text file to read from but for an image with the dimensions given in the nested loop above the filesize is 256k - not enormous but not tidy either.


muddy_shoes(Posted 2012) [#8]
Is what you posted what you actually mean? There's no reason why that would "never appear to run at all" on HTML5 unless there's something about the rest of your code that means it never gets called.

It will be slow because you're printing thousands of lines into the console and that's slow. Simply doing a loop isn't.


therevills(Posted 2012) [#9]
To time it:

Local start:Int = Millisecs()
Local counter:Int = 0
For y = 0 To 150
     For x = 0 To 100
	counter+=1
     Next
Next
Print "Time taken ="+(Millisecs() - start)+"ms"



wmaass(Posted 2012) [#10]
You are right muddy_shoes, it does run - just takes a long time when printing to the console. My test wasn't very good as therevills demonstrated.


wmaass(Posted 2012) [#11]
Well I have something working, thanks all for the tips, now I can get on with the rest of the development. You can check it out below.

While invaderJim's solution is very fast and would work well for me, I decided to go the route of predetermining the colors with a custom utility, storing them in a text file and then reading them into an array when the game loads. This appears to be the best way to maintain cross platform compatibility. The image used to define the surfaces (green, sand etc) is actually 1/4 of the size of the course image to keep the array as small as possible. The demo does not yet do bounce and roll but it will tell you what surface the ball is on based on the above (have not defined terrain height yet). I defined the green, sand and fairway area for this par 3.

To play:

1. Change your club to a 5 or 6 iron.
2. Click on the center of the green.
2. Hold the left mouse button and swipe upwards from the bottom of the screen, release mouse button. Deviating from center imparts side spin.

http://www.maasscreativelabs.com/gtest/