game help with object and image change on click.

Hi

I’m very new to Lua and Corona (about 1 week old)

I’m trying to make a simple game that starts by displaying one screen wide image with a a square shape object hidden in the image. if the player clicks (or taps) the object the original image is replaced with a second one and the object is also replaced with a second square object hidden in the second image.

The players gets points if they click/tap the object and lose points if they click on the image. 

In some levels i’d like to add a second negative image (one that takes away a larger amount of points if clicked).

My problem is that once the object is clicked and the new image and square object load the first square object is still active under the new image. as the game progresses there are far too many squares still active under the newer image. That and I have now way to set up the scores. (I’d like the final score to be displayed only at the end of the game.

here is an example of the code: (I have 12 images in total so this repeats over and over)

function createPlayScreen()

local image = display.newImageRect(“Slide001.png”, display.contentWidth, display.contentHeight) 

image.anchorX = 0

image.anchorY = 0

local rectangleA = display.newRect( 110, 290, 100, 100 )

rectangleA.alpha = 1

rectangleA:addEventListener ( “tap”, slide1, score + 1, shipSmash,  {onComplete = removeRect }, onTouch, rectangleA:toBack( ),{removeObjectOntouch} ) --rectangle:removeSelf();

–rectangle = nil 

end

function slide1()

local image1 = display.newImageRect(“Slide002.png”, display.contentWidth, display.contentHeight) 

image1.anchorX = 0

image1.anchorY = 0

image1.alpha = 1

local rectangle1 = display.newRect( 720, 312, 100, 110 )

rectangle1.alpha = .1

rectangle1:toFront( )

rectangle1:addEventListener ( “tap”, slide3, onTouch,rectangle1:toBack( ), {removeObjectOntouch} )

end

function slide2()

local image2 = display.newImageRect(“Slide003.png”, display.contentWidth, display.contentHeight) 

image2.anchorX = 0

image2.anchorY = 0

image2.alpha = 1

local rectangle2 = display.newRect( 720, 312, 100, 110 )

rectangle2.alpha = 1

rectangle2:toFront( )

rectangle2:addEventListener ( “tap”, slide3, onTouch, rectangle2:toBack( ), {removeObjectOntouch} )

end

As you can see I’m trying to have the original objects be removed or go to the back and add a score, but no luck. 

Thanks in advance.

Hi @richtornado,

Welcome to Corona! The first comment I have is that your “:addEventListener()” calls are not correct. If you look at the documentation…

https://docs.coronalabs.com/api/type/EventDispatcher/addEventListener.html

… you’ll see that it only accepts two arguments, not a long list as you have done. You have the first argument correct (i.e. “tap”) but the second argument needs to be either a reference to a properly-scoped function, or an inline “anonymous” function. So, it might look something like this, using an anonymous function (I’m making some assumptions since I don’t know all of the code you’ve written):

[lua]

rectangleA:addEventListener ( “tap”,

    function()

        slide1();

        score = score + 1;

        shipSmash();

        – more?

    end;

)

[/lua]

Hope this points you in the right direction,

Brent

Thank you for the fast reply.

I did try the core you provided but it gives me errors, not sure why?

I’m still not sure how to remove the object once it’s clicked?

I’ve tried other types of commands but nothing works.

Hi @richtornado,

The correct commands to remove an object are either “display.remove( object )” or “object:removeSelf()”, either of which could be called from the function which listens for a tap on the object.

I’m curious, have you seen or followed through our Getting Started guide and game project?

https://docs.coronalabs.com/guide/programming/01/index.html

If not, I highly recommend that you do, because it covers a large amount of core aspects of Corona. I know it’s probably more fun to just dive in and start working on your game idea, but the guide is also pretty fun because you get to create a working “Asteroids” game while learning many valuable things about Corona… and doing so will make your own game development much easier and enjoyable. :slight_smile:

Brent

I have been doing a bit of both actually.

I did try the “object:removeSelf()” line a few different times in a few different places and it just takes the square away before it can even be tapped.

I have been reading the guides, I’m now just trying to see if I can put to my own use and understanding. Looks like I have a ways to go as I’m still not grasping some concepts.

If you do something like

obj:addEventListener("tap", obj:removeSelf())

then the object will be removed instantly and not on the tap event.  This may not makes sense to you know but take it as fact. What you want is this

obj:addEventListener("tap", function()   if obj then obj:removeSelf();   obj = nil end end)

Note: In that example I’ve added a check that the obj exists BEFORE  trying to remove it as a double tap would crash your game

I’ve tried all of the above examples into my code.

No matter how I insert it I keep getting errors.

Not sure how to remove modify with my existing text, but as soon as I change on line of my existing code I get run errors.

do I need to keep my original addEvent line because I’ve been cutting it out and replacing it with the suggestions above only to get errors.

I gave you example code it is NOT a straight replacement,  It is to show you HOW to code things.  

Paste this into a blank main.lua, run it and try and learn from how it is made

local rect1, rect2 = nil, nil local function drawRect2()   transition.to(rect1, {time=1000, alpha=0, onComplete=function()      rect1:removeSelf()     rect1 = nil   end})   rect2 = display.newRect(200, 200, 50, 50)   rect2.alpha = 0   transition.to(rect2, {time=1000, alpha=1}) end rect1 = display.newRect(100, 100, 50, 50) rect1:addEventListener("tap", drawRect2)

I know it was example code. I copied and added my own modifications (probably where I’m getting the errors).

It seems the events I’m creating are not working correctly.

The example you just provided worked great in a new file, it’s when I try to adapt it to my project I get errors (I have changed obj names) and if I try to add going to the next slide seems to make it worse.

If you use the code I wrote for you above, you will see it draws a white box and when you tap on that box it fades into another box and removes the first box.  This is how you should be coding.  You can replace the boxes with your images easily.

As Brent already pointed out, your code for adding events is completely wrong and will not work.

I understand that my code is not working correctly, thats why I’m asking for help (and I do appreciate the help, thank you).

When I try to replace the scares with my images (and keeping my images centered, and adding the squares, and keeping the squares centered I get errors. I’m also trying to add scores and I know I can’t do all of that in one line. the more lines or events I add the more errors.

So far I am able to display my first image, have one square appear, have it clicked, it fades, new square appears. 

I’m still not able to have it go to the next slide/image or keep scores.

Post your variation of my code (boxes swapped for images only.  Ignore scores and everything else for now). You gotta get the basics nailed first.

local rectangleA, rect2 = nil, nil

local function drawRect2()

  transition.to(rectangleA, {time=1000, alpha=0, onComplete=function() 

    rectangleA:removeSelf()

    rectangleA = nil

  end})

  

  

  rect2 = display.newRect(200, 200, 50, 50)

  rect2.alpha = 0

  transition.to(rect2, {time=1000, alpha=1})

end

image = display.newImageRect(“Slide001.png”, display.contentWidth, display.contentHeight) 

image.anchorX = 0

image.anchorY = 0

rectangleA = display.newRect( 110, 290, 100, 100 )

rectangleA.alpha = 1

rectangleA:addEventListener(“tap”, drawRect2)

This works. i just need it to also switch slides (the whole game will have about 12 slides and squares).

(Sorry I don’t know how to post it and have the colours and all)

So you want to have 12 different background images and 12 really faint touch points?  A tap on the touch point moves to the next slide and awards some score but a tap not on the touch points decrements the score?  I also assume you want to move the touch point per slide - otherwise it will be a bit easy?

Yes that is correct.

This will do what you want as long as you set the arrays up correctly.  Scoring is built in and you can extend ot to have 100 slides if you want.

Take some time to understand HOW and WHY it works…

local images = {"1.png", "2.png", "3.png"} -- add as many here as you want local rects = {{100,100,50,50},{200,200,50,50},{300,300,50,50}} &nbsp;-- make sure you define the rects here MUST match above local myBackground, myRect = nil, nil local myScore, currentSlide = 0, 0 local myScoreDisplay = display.newText({text = "0", x = display.contentWidth/2,y = 50, width = 200, font = native.systemFont, fontSize = 24}) local function setSlide() &nbsp; --remove old slide &nbsp; if myBackground then &nbsp; &nbsp; myBackground:removeSelf() &nbsp; &nbsp; myBackground = nil &nbsp; end &nbsp; if myRect then &nbsp; &nbsp; myRect:removeSelf() &nbsp; &nbsp; myRect = nil &nbsp; end &nbsp; &nbsp; --create new slide &nbsp; MyBackground = display.newImage(images[currentSlide], display.contentWidth, display.contentHeight)&nbsp; &nbsp; myRect = display.newRect(rects[currentSlide][1], rects[currentSlide][2], rects[currentSlide][3], rects[currentSlide][4]) &nbsp; myRect.alpha = 0.1 &nbsp; --put score back on top &nbsp; myScoreDisplay:toFront() end local function myTap(event) &nbsp; --is tap on rect? &nbsp; local bounds = myRect.contentBounds&nbsp; &nbsp; if event.x \> bounds.xMin and event.x \< bounds.xMax and event.y \> bounds.yMin and event.y \< bounds.yMax then &nbsp; &nbsp; --hit &nbsp; &nbsp; myScore = myScore + 10 &nbsp; &nbsp; currentSlide = currentSlide + 1 &nbsp; &nbsp; if currentSlide \<= #images then &nbsp; &nbsp; &nbsp; --render next slide &nbsp; &nbsp; &nbsp; myScoreDisplay.text = myScore &nbsp; &nbsp; &nbsp; setSlide() &nbsp; &nbsp; else &nbsp; &nbsp; &nbsp; --run out of slides so game is over &nbsp; &nbsp; &nbsp; Runtime:removeEventListener( "tap", myTap ) &nbsp; &nbsp; &nbsp; myScoreDisplay.text = "You won" &nbsp; &nbsp; end &nbsp; else &nbsp; &nbsp; --miss &nbsp; &nbsp; myScore = myScore -1 &nbsp; &nbsp; if myScore \< 0 then&nbsp; &nbsp; &nbsp; &nbsp; --end game now? &nbsp; &nbsp; &nbsp; Runtime:removeEventListener( "tap", myTap ) &nbsp; &nbsp; &nbsp; myScoreDisplay.text = "You lost" &nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; myScoreDisplay.text = myScore &nbsp; &nbsp; end &nbsp; end end --start game running Runtime:addEventListener( "tap", myTap ) currentSlide = 1 setSlide()

Thank you so much!! his looks awesome and I can actually understand most of it from what I’ve previously read.

is there a way to place the squares in specific spots with the specific slides/images? (I’m using transparent squares to have the player click on objects in the photos/mages). I’m pretty sure you did that in the second line. 

This looks much easier, sorry I was used to working with longer scripts.

And again. Thank you so much.  :slight_smile:

Yes you define the rects in the second line.  I used a runtime tap handler and then worked out if the tap “hit” the current rect or not and adjusted accordingly.  I’ve left enough comments so it should make sense.

For 30 mins of my time that will be $100 :wink:

Keep in mind that when you use an anonymous function with addEventListener(), you get a memory address returned and both the event type and the address have to match if you ever want to call removeEventListener(). Since you have no access to address of the anonymous function, you can’t remove it.

Now for touch and tap handlers on display objects, you will likely remove the object and never need to remove the touch/tap handler, so you can get away with an anonymous function, but if you want to set up other types of event listeners that you want to remove, you have to use a non-anonymous function so you can pass the same memory address to removeEventListener() that you did to addEventListener()

Rob

Wow thanks again.
I assume it would also be possible to add a second object (say “rect2” or some other shape) to some slides (or on every slide but hide them off screen–I’ve been redoing the Astroid game).
I’m wondering if some slides can make use a second object so that the game can have a “choose your own adventure” style text gameplay.
Click on the proper square and go to the next slide, click on the second square and have a detour to a different slide or text. And back again to the original slide.
I’ll keep typing with what you gave me
Thanks again