How to make a multi-colored ring shape?!

@starcrunch 

Great job again! the inside edges are now static and everything is working amazingly! 

My final question is:  

in the code you posted earlier;

[lua]–keep track of positions of color quadrents

local angle = math.atan2(pos.y, pos.x) --pos = collision point

local degrees = math.deg(angle)

degrees = (degrees - wheel.rotation) % 360 – The wheel may have rotated ahead, so what are we really

                                           – hitting? Normalize the result to the (0, 360) range.

if degrees < 90 then

  – purple

  print(“purple”)

elseif degrees < 180 then

 – green

 print(“green”)

elseif degress < 270 then

 – red

 print(“red”)

else

 – yellow

 print(“yellow”)

end[/lua]

What value do I insert into the “pos.x” and “pos.y”?

How do I find the collision point to put there?

The only thing that prints to the console is “purple”! 

Thanks in advance you’ve hepled a ton!

-Max

When you get your collision event, it should have x and y values during the “began” phase. Your wheel will be found under  target or other ; it sounds like you’ve got that one, if you were able to get the rotation. The “pos” is the position on the wheel relative to its center, so something like:

if event.phase == "began" then local wheel = event.target -- or event.other, if the listener is on the bouncing object local posx, posy = event.x - wheel.x, event.y - wheel.y local angle = math.atan2(posy, posx) -- And so on...

Looks like I had a typo (“degress”) in the red case, too.

@starcrunch

That also worked! My project is nearly complete! However I have ran into yet another problem that I need help with!

Right now, I have the spinning wheel with the bouncing object inside it.  The ball bounces and lets say it hits the purple quadrant, it will change color and the process will repeat.

How can I make it so a false collision(i.e. a red ball hits a purple quadrant) ends the game?

I have done this before in other games, but for some reason I can’t figure out how to go about doing this in this style/kind of game :frowning:

Thanks!

-Max

Heh, I wish my own projects went so smoothly.  :slight_smile:

You may be getting hung up thinking about things too visually (“how do I know it was red?”) but all you really need to do is make sure the underlying state matches. You already found a string (“red”, “green”, …) for your quadrant, above. All you would really need to do is assign one of those same strings to some unused key in your bouncing object, whenever it updates. For example:

local Colors = { "purple", "green", "red", "yellow" } function SetColor (object) -- Update our own private object color local current = object.m\_color repeat object.m\_color = Colors[math.random(4)] until object.m\_color ~= current -- just to ensure variety, but optional end -- other code... function StartGame () -- Various fancy stuff SetColor(bouncing\_object) -- set initial color -- More fancy stuff end -- other code... function CollisionHandler (event) if event.phase == "began" then -- stuff... if event.other.m\_color ~= quadrant\_color then -- This is the color you found earlier GameOver() end else SetColor(event.other) -- pick new color end -- more stuff... end

@starcrunch

The code you gave me above runs fine but the ball doesn’t have a color! It’s just white always! any help?

Ah, well, as I said, this wasn’t actually the color itself, just what color the ball understands itself to have. :) You would probably use setFillColor on your ball, assigning numerical RGB values.

All is not lost, however! A second lookup table could be paired with Colors , and then the above becomes:

local Colors = { "purple", "green", "red", "yellow" } local ColorValues = { -- same RGB values as in the shader; adjust as you see fit red = { 1, 0, 0 }, yellow = { 1, 1, 0 }, purple = { .5, 0, .5 }, green = { 0, 1, 0 } } function SetColor (object) -- Update our own private object color local current = object.m\_color repeat object.m\_color = Colors[math.random(4)] until object.m\_color ~= current -- just to ensure variety, but optional object:setFillColor(ColorValues[object.m\_color]) end&nbsp;

@starcrunch

I did the exact code you posted and now the ball is black!  I keep trying everything and I can’t seem to figure out why!

HELP MEEE!

Oh, whoops. :slight_smile:

(Don’t be afraid to second-guess my code. These posts are all rather off the cuff, apart from a quick hop to the docs sometimes.)

The setFillColor method can take a table, but in the case you want will take the numbers.Try this instead (to extract them in order from the table) and see if you get a better result:

 object:setFillColor(unpack(ColorValues[object.m\_color]))

@starcrunch 

Again you have helped me! I appreciate it so much!

I have one last question for you!

In the segment of code you provided before:

if (event.other.m_color ~= quadrantColor) then – This is the color you found earlier

The “event.other.m_color” returns nil.  Im assuming this is because I am defining “event.other.m_color” in another function.

How can I make that either not be nil or exchange that for another variable?

There is no “getFillColor” feature that I am aware of… So how can I make it equal the color of the current ball so I can compare it to the quadrantColor?

Thanks so much for all of your help through this process as I’m new to corona sdk and lua programming!

swear  this is my last question :wink:

-Max

Looking at it again (and assuming the ball is the one with the event listener), those should probably be event.target , not event.other (which would be your wheel).

There are ways to query the color: through a paint’s fill or display.colorSample, off the top of my head. But they’re overkil, herel. (They would make sense, say, if the color was changing continuously, possibly via user input. I would recommend waiting until you’re more comfortable with everything before tackling something like that. You’d have to compare multiple components and account for floating point imprecision, at the very least.)

No worries on the questions. They’ve helped to break up some mind-numbing copy-editing work. That said, I’ll be traveling tomorrow, so somebody else can have a turn.  :stuck_out_tongue:

@starcrunch

I have read your reply above and I don’t think you fully understood my question.

I need to know how to compare the color of the ball and the color of the quadrant when a collision occurs.

You have so far provided me a basic back-bone of the code I need to accomplish this task, however, I need to know exactly what to write in order to make this work.  

I have the following code so far: 

[lua] --collision of ball and wheel

local function onCollision(event)

if (event.phase == “began”) then

  local ball = event.target – or event.other, if the listener is on the bouncing object

  local posx, posy = event.x - wheel.x, event.y - wheel.y

–keep track of positions of color quadrents

local angle = math.atan2(posy, posx) --pos = collision point

local degrees = math.deg(angle)

degrees = (degrees - wheel.rotation) % 360 – The wheel may have rotated ahead, so what are we really

                                           – hitting? Normalize the result to the (0, 360) range.

if (degrees < 90 ) then

  – purple

  quadrantColor = “purple”

  physics.setGravity( 0, -3)

 

  elseif (degrees < 180) then

 – green

 quadrantColor = “green”

 physics.setGravity( 0, -3)

elseif (degrees < 270) then

 – red

 quadrantColor = “red”

 physics.setGravity( 0, -3)

else

 – yellow

 quadrantColor = “yellow”

  physics.setGravity( 0, -3)

end

 if (event.target.m_color ~= quadrantColor) then – This is the color you found earlier

      display.newText(“GAME OVER!”, 165, 160, “Arial”, 40)

    end

  else

    SetColor(ball) – pick new color

  end 

end

Runtime:addEventListener( “collision”, onCollision )[/lua]

Ah, I figured you were doing “local” collision, whereas yours is “global” (since you added your listener to Runtime ).

See here for the differences: collision

Is it possible to add the event listener to the ball, instead? (And remove it between rounds, or whatever.)

Otherwise… I’m not actually sure if there’s any policy regarding which object winds up in object1 versus object2 , so you’d have to sort those out. I guess if you’ve followed my approach so far, you can choose the one that has  m_color :

local ball, wheel if event.object1.m\_color then ball, wheel = event.object1, event.object2 else ball, wheel = event.object2, event.object1 end

This assumes the initial color was assigned, of course.

(Then lower down you’ll want to use ball , instead of event.target , when you do the color comparison.)

Otherwise, your code above is basically how I would have approached it.

@starcrunch

I have now added all necessary functions to my game thanks to you!

However, when I run my app now all is well EXCEPT for one thing!

Sometimes, the ball collides with the right color quadrant and it proceeds to go to the “gameOver” scene as if it wasn’t the right color collision!  This is obviously a  major issue and flaw that needs to be fixed!

If you wouldn’t mind helping me figure this one out that would be great!  I am posting code below, but if you need to see more code to figure it out just ask me! Thanks in advance I know you will help me fix it!

[lua]local colors = { “red”, “green”, “purple”, “yellow” }

–colors in game

local colorValues = {

red = {1, 0, 0},

yellow = {1, 1, 0},

purple = {.5, 0, .5},

green = {0, 1, 0}

}

–change balls color function

local function SetColor(object) – Update our own private object color

local current = object.m_color

repeat

    object.m_color = colors[math.random(4)]

    print(object.m_color)

  until object.m_color ~= current – just to ensure variety, but optional

object:setFillColor(unpack(colorValues[object.m_color]))

print(unpack(colorValues[object.m_color]))

end

–collision of ball and wheel

local function onCollision(event)

if (event.phase == “began”) then

  local ball = event.target – or event.other, if the listener is on the bouncing object

  local posx, posy = event.x - wheel.x, event.y - wheel.y

–keep track of positions of color quadrents

local angle = math.atan2(posy, posx) --pos = collision point

local degrees = math.deg(angle)

degrees = (degrees - wheel.rotation) % 360 – The wheel may have rotated ahead, so what are we really

                                           – hitting? Normalize the result to the (0, 360) range.

if (degrees < 90 ) then

  – purple

  quadrantColor = “purple”

  physics.setGravity( 0, -3)

 

  elseif (degrees < 180) then

 – green

 quadrantColor = “green”

 physics.setGravity( 0, -3)

elseif (degrees < 270) then

 – red

 quadrantColor = “red”

 physics.setGravity( 0, -3)

else

 – yellow

 quadrantColor = “yellow”

  physics.setGravity( 0, -3)

end

 if (event.target.m_color ~= quadrantColor) then – This is the color you found earlier

      storyboard.gotoScene( “gameover” )

  wheel:removeEventListener(‘touch’, rotateWheel)

ball:removeEventListener( “collision”, onCollision )

audio.stop()

    end

  elseif (event.target.m_color == quadrantColor) then

    SetColor(ball) – pick new color

    audio.play(collisionSound)

    updateScore()

    currentScore = 0

    local currentScoreFilename = “currentScore.text”

saveValue( currentScoreFilename, tostring(currentScore))

    currentScore = score

    local currentScoreFilename = “currentScore.text”

saveValue( currentScoreFilename, tostring(currentScore))

    

    if (score > highScore) then

  highScore = score

local highScoreFilename = “highScore.text”

saveValue( highScoreFilename, tostring(highScore))

end

  end 

  

  if (score > 10) then

print(“making gravity stronger”)

physics.setGravity( 0, 5)

end  

end

ball:addEventListener( “collision”, onCollision )

SetColor(ball)

end[/lua]

If it’s only sometimes wrong (is it always okay if the wheel hasn’t spun?), then my best guess is to add wheel.rotation, not subtract it. (That, or negate posy.) It might be the case that clockwise and counterclockwise angles are getting mixed.

@starcrunch 

that did not seem to do anything except make it worse.

With either of things you told me to do, on any collision it goes to game over instantly!  Any other advice?

-Max

Well, now you’re going to have to do some debugging.

If it’s sort of fast-paced, you might first want to slow down the speed of the ball and / or wheel a bit.

In the “began” phase of your collision handler, dump a bunch of print statements, at least stuff like this, but anything else you might find helpful:

print("QUADRANT COLOR", quadrantColor) print("BALL COLOR", event.target.m\_color) print("ANGLES", angle, wheel.rotation) print("") -- dummy line, just to add a space in the console (if able to test multiple collisions)

Then, try it in a bunch of wheel orientations: a small rotation, then greater and greater ones, both for correct and incorrect collisions. Look at the printouts. With any luck, something will stand out. “The colors from the opposite side are being detected”, for example, or “The angles are always 90 degrees off”.

Are you writing your code in any specific editor / IDE? (Asked in case it has debugger support.)

@starcrunch

I figured out what’s causing the problem!  

When the issue occurs, the console prints out that the ball color is a different color than it appears on screen!

This means that for some reason the ball is displaying a different color for us to see than actually in the code.

Now the question is, ​why is this occurring? And, how can I fix it?

Here is the majority of the code in the game that would be causing the problem:

[lua]local colors = { “red”, “green”, “purple”, “yellow” }

–colors in game

local colorValues = {

red = {1, 0, 0},

yellow = {1, 1, 0},

purple = {.5, 0, .5},

green = {0, 1, 0}

}

–change balls color function

local function SetColor(object) – Update our own private object color

local current = object.m_color

repeat

    object.m_color = colors[math.random(4)]

    print(object.m_color)

  until object.m_color ~= current – just to ensure variety, but optional

object:setFillColor(unpack(colorValues[object.m_color]))

print(unpack(colorValues[object.m_color]))

end

–collision of ball and wheel

local function onCollision(event)

if (event.phase == “began”) then

  local ball = event.target

  local posx, posy = event.x - wheel.x, event.y - wheel.y

–keep track of positions of color quadrents

local angle = math.atan2(posy, posx) --pos = collision point

local degrees = math.deg(angle)

degrees = (degrees - wheel.rotation) % 360 – The wheel may have rotated ahead, so what are we really

                                           – hitting? Normalize the result to the (0, 360) range.

if (degrees < 90 ) then

  – purple

  quadrantColor = “purple”

  physics.setGravity( 0, -3)

 

  elseif (degrees < 180) then

 – green

 quadrantColor = “green”

 physics.setGravity( 0, -3)

elseif (degrees < 270) then

 – red

 quadrantColor = “red”

 physics.setGravity( 0, -3)

else

 – yellow

 quadrantColor = “yellow”

  physics.setGravity( 0, -3)

end

 if (event.target.m_color ~= quadrantColor) then – This is the color you found earlier

      storyboard.gotoScene( “gameover” )

  wheel:removeEventListener(‘touch’, rotateWheel)

ball:removeEventListener( “collision”, onCollision )

audio.stop()

    end

  elseif (event.target.m_color == quadrantColor) then

    SetColor(ball) – pick new color

    audio.play(collisionSound)

    updateScore()

    currentScore = 0

    local currentScoreFilename = “currentScore.text”

saveValue( currentScoreFilename, tostring(currentScore))

    currentScore = score

    local currentScoreFilename = “currentScore.text”

saveValue( currentScoreFilename, tostring(currentScore))

print(“QUADRANT COLOR”, quadrantColor)

print(“BALL COLOR”, event.target.m_color)

print(“ANGLES”, angle, wheel.rotation)

print("") – dummy line, just to add a space in the console (if able to test multiple collisions)

    

    if (score > highScore) then

  highScore = score

local highScoreFilename = “highScore.text”

saveValue( highScoreFilename, tostring(highScore))

end

  end 

  

  if (score > 10) then

print(“making gravity stronger”)

physics.setGravity( 0, 5)

end  

end

ball:addEventListener( “collision”, onCollision )

SetColor(ball)

end[/lua]

-Max

Ah, then I suspect it’s this line:

elseif (event.target.m\_color == quadrantColor) then

The formatting is a bit messy, but I think that can just be “else” (it’s just the phase == “ended” case). It’s not the appropriate test, so the color is getting out of sync.

Incidentally, you should prefer locals where possible, as here with quadrantColor , so you don’t get values lingering around.

@starcrunch

Sadly, what you said above did not solve the problem… it still occurs.

Also, on top of the ball color being displayed wrong opposed to in the code like I said in my previous reply,

The print codes you gave me before to track things in my console reads that the angle is nil.

May 22 21:07:46.193: QUADRANT COLOR yellow

May 22 21:07:46.193: BALL COLOR purple

May 22 21:07:46.194: ANGLES nil -35.461097717285

 

maybe that could be the problem? Very confused on why I have this error :frowning:

 

Thanks.

 

-Max

Remove the “end” in the line before it, too… that will pair it with the quadrantColor check (as opposed to the phase began one). And as I said, you just want an “else”.

Anyhow, by that point, angle was out of scope. If you aren’t doing so already, you should read up on some Lua details, like locals and their scope.