Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

image generalization
Started by zettelrhean Oct 18 2018 08:57 AM

26 replies to this topic
lua corona
[TOPIC CONTROLS]
Page 1 of 2 1 2
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

zettelrhean

[GLOBAL: userInfoPane.html]
zettelrhean
  • Observer

  • 25 posts
  • Corona SDK

is there any way that i can have multiple images under one name so when i do interactions between objects i can just have it do stuff with a general thing like a player with obstacles, i have multiple obstacle images and i dont want to code each ones interactions with the player, is there a way i can generalize multiple images into one name like obstacle?



[TOPIC: post.html]
#2

nick_sherman

[GLOBAL: userInfoPane.html]
nick_sherman
  • Corona Geek

  • 1,610 posts
  • Corona SDK

Yep, you just give them all a common .id field or whatever you want to call it when the objects are spawned. Then in your collision listeners etc. you run different code depending on the .id field i.e enemy, powerup, obstacle.

[TOPIC: post.html]
#3

zettelrhean

[GLOBAL: userInfoPane.html]
zettelrhean
  • Observer

  • 25 posts
  • Corona SDK

ok how do i do that?



[TOPIC: post.html]
#4

nick_sherman

[GLOBAL: userInfoPane.html]
nick_sherman
  • Corona Geek

  • 1,610 posts
  • Corona SDK

Display objects are just sophisticated lua tables, therefore you can add custom keys to the object like you would any other lua table.

 

 
local image1 = display.newRect(0,0, 100, 100)
image.id = "obstacle"
image.name = "Rock"
image.hitPoints = 10000
 
local image2 = display.newRect(200, 200, 50, 50)
image2.id = "enemy"
image2.name = "Tony the Alien"
image2.hitPoints = 50
 
local image3 = display.newRect(300, 300, 200, 10)
image3.id = "enemy"
image3.name = "Dave the Snake"
image3.hitPoints = 10
 
 



[TOPIC: post.html]
#5

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Contributor

  • 293 posts
  • Corona SDK

Sure, I'd expect Rock to be tough, but not 200 times tougher than Tony the Alien in terms of hp. That's a great example, but I think your math is wrong here, unless that Rock happens to also be called Dwayne.


  • nick_sherman likes this

[TOPIC: post.html]
#6

nick_sherman

[GLOBAL: userInfoPane.html]
nick_sherman
  • Corona Geek

  • 1,610 posts
  • Corona SDK

It's all relative. Tony and Dave have absolutely no stomach for a fight.


  • XeduR @Spyric likes this

[TOPIC: post.html]
#7

SGS

[GLOBAL: userInfoPane.html]
SGS
  • Corona Geek

  • 1,878 posts
  • Corona SDK

Dave prefers origami.... sometimes a bit of cross-stitch



[TOPIC: post.html]
#8

zettelrhean

[GLOBAL: userInfoPane.html]
zettelrhean
  • Observer

  • 25 posts
  • Corona SDK

doing that creates an error for me



[TOPIC: post.html]
#9

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Contributor

  • 293 posts
  • Corona SDK

You are seeing an error because nick has a few typos in his sample code. On line 2, he creates "image1", but then he refers to just "image" on rows 3, 4 and 5.

If you run it locally, you'll receive an error message. My error message is "main.lua:2: attempt to index global 'image' (a nil value)" and simply means that on row 2, there is no "local image", i.e. it has a nil value. You need to learn some basic debugging instead of just copying the code. :P



[TOPIC: post.html]
#10

zettelrhean

[GLOBAL: userInfoPane.html]
zettelrhean
  • Observer

  • 25 posts
  • Corona SDK

i didnt copy his code, i put what i saw into mine, i dont typically use local since im told they arent necessary for what im doing



[TOPIC: post.html]
#11

zettelrhean

[GLOBAL: userInfoPane.html]
zettelrhean
  • Observer

  • 25 posts
  • Corona SDK

fixed it



[TOPIC: post.html]
#12

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Contributor

  • 293 posts
  • Corona SDK

doing that creates an error for me

 

 Well, you may not have copied all of his code, but you copied enough to reproduce nick's error. :P

Also, while using locals is not absolutely necessary, I would highly recommend on using them as locals are less risky than globals and they hog far less resources. Or in other words, globals are more prone to bugs, data leaks and will potentially make your game lag more than using locals.

You can read up on https://docs.coronalabs.com/tutorial/basics/globals/index.html.

 



[TOPIC: post.html]
#13

zettelrhean

[GLOBAL: userInfoPane.html]
zettelrhean
  • Observer

  • 25 posts
  • Corona SDK

ok so i have the whole id thing down but now that i think about it how will i call to it without just having to type the name anyways? i want to be able to just check if it falls under "obstacle" and thats when stuff happens

ob1 = display.newImage("TLCorner.png")
			ob1.xScale = 0.45
			ob1.yScale = 0.45
			ob1.x = 201
			ob1.y = 112
			ob1.id = obstacle
		ob2 = display.newImage("TMidCent.png")
			ob2.xScale = 0.45
			ob2.yScale = 0.45
			ob2.x = 240
			ob2.y = 112
			ob2.id = obstacle
		ob3 = display.newImage("TRCorner.png")
			ob3.xScale = 0.45
			ob3.yScale = 0.45
			ob3.x = 278
			ob3.y = 112
			ob3.id = obstacle
		ob4 = display.newImage("StubLeft.png")
			ob4.xScale = 0.45
			ob4.yScale = 0.50
			ob4.x = 160
			ob4.y = 158
			ob4.id = obstacle
		ob5 = display.newImage("mid.png")
			ob5.xScale = 0.45
			ob5.yScale = 0.55
			ob5.x = 201
			ob5.y = 157
			ob5.id = obstacle
		ob6 = display.newImage("mid.png")
			ob6.xScale = 0.45
			ob6.yScale = 0.55
			ob6.x = 240
			ob6.y = 157
			ob6.id = obstacle
		ob7 = display.newImage("mid.png")
			ob7.xScale = 0.45
			ob7.yScale = 0.55
			ob7.x = H
			ob7.y = 157
			ob7.id = obstacle


[TOPIC: post.html]
#14

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Contributor

  • 293 posts
  • Corona SDK

There are numerous ways for doing that, so it depends on what exact use you need.

For instance, are they physics objects and you want to check their id for collision purposes? Then check https://docs.coronalabs.com/guide/physics/collisionDetection/index.html#local-collision-handling.

Or, if you want to know what the object's id is when it is touched by the player, then check out https://docs.coronalabs.com/api/event/touch/index.html.

 

Or, if we are talking about that grid movement, you might want to check the nearby tiles ids to see if they are obstacles or not. In this case, a simple if else statement would check something like "if tile[xy].id == "obstacles" then" and so on.

 



[TOPIC: post.html]
#15

davebollinger

[GLOBAL: userInfoPane.html]
davebollinger
  • Corona Geek

  • 1,236 posts
  • Enterprise

during player's collision event, check against the other object's id field, fe:

if (event.other.id == "enemy") then
  print("player collided with an enemy")
  doEnemyCollisionStuff()
elseif (event.other.id == "obstacle") then
  print("player collided with an obstacle")
  doObstacleCollisionStuff()
else
  print("player collided with something that I forgot to assign an id to, oops!  what should i do???")
  doNothingProbably()
end


[TOPIC: post.html]
#16

zettelrhean

[GLOBAL: userInfoPane.html]
zettelrhean
  • Observer

  • 25 posts
  • Corona SDK

ok so thats one problem solved but i really want it so that say mid.png and stubleft.png are still seperate images but i dont need to type the image name, just have those specific images labeled as "obstacle" sure i could have it be that the image name is just obstacle but then that limits me on the amount of variation for the obstacles, i want multiple images but all of them to be referred to as "obstacle"



[TOPIC: post.html]
#17

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,286 posts
  • Corona SDK

Wow, that is some super redundant code. Why not take this...
 

ok so i have the whole id thing down but now that i think about it how will i call to it without just having to type the name anyways? i want to be able to just check if it falls under "obstacle" and thats when stuff happens

ob1 = display.newImage("TLCorner.png")
			ob1.xScale = 0.45
			ob1.yScale = 0.45
			ob1.x = 201
			ob1.y = 112
			ob1.id = obstacle
		ob2 = display.newImage("TMidCent.png")
			ob2.xScale = 0.45
			ob2.yScale = 0.45
			ob2.x = 240
			ob2.y = 112
			ob2.id = obstacle
		ob3 = display.newImage("TRCorner.png")
			ob3.xScale = 0.45
			ob3.yScale = 0.45
			ob3.x = 278
			ob3.y = 112
			ob3.id = obstacle
		ob4 = display.newImage("StubLeft.png")
			ob4.xScale = 0.45
			ob4.yScale = 0.50
			ob4.x = 160
			ob4.y = 158
			ob4.id = obstacle
		ob5 = display.newImage("mid.png")
			ob5.xScale = 0.45
			ob5.yScale = 0.55
			ob5.x = 201
			ob5.y = 157
			ob5.id = obstacle
		ob6 = display.newImage("mid.png")
			ob6.xScale = 0.45
			ob6.yScale = 0.55
			ob6.x = 240
			ob6.y = 157
			ob6.id = obstacle
		ob7 = display.newImage("mid.png")
			ob7.xScale = 0.45
			ob7.yScale = 0.55
			ob7.x = H
			ob7.y = 157
			ob7.id = obstacle

 
and do this instead...
local function newObstacle( img, x, y, params )
   group = group or display.currentStage
   params = params or {}

   local obj = display.newImage( params.parent or display.currentStage, img, x, y )
   obj.xScale = params.xScale or 0.45
   obj.yScale = params.yScale or 0.45
   obj.id = params.id or "obstacle"

   return obj
end

-- then later...

ob1 = newObstacle( "TLCorner.png", 201, 112  )
ob2 = newObstacle( "TMidCent.png", 240, 112  )
ob3 = newObstacle( "TRCorner.png", 278, 112  )
ob4 = newObstacle( "StubLeft.png", 160, 158, { yScale = 0.5 }  )
ob5 = newObstacle( "mid.png", 201, 157, { yScale = 0.55 }  )
ob6 = newObstacle( "mid.png", 240, 157, { yScale = 0.55 }  )
ob7 = newObstacle( "mid.png", H, 157, { yScale = 0.55 }  )


Then, consider that if you wanted them all to have the same collision listener code you could do this:


local collision( self, event )
  -- code for your listener here
  return false
end

local function newObstacle( img, x, y, params )
   group = group or display.currentStage
   params = params or {}

   local obj = display.newImage( params.parent or display.currentStage, img, x, y )
   obj.xScale = params.xScale or 0.45
   obj.yScale = params.yScale or 0.45
   obj.id = params.id or "obstacle"

   obj.collision = collision
   obj:addEventListener("collision")

   return obj
end

-- then later...

ob1 = newObstacle( "TLCorner.png", 201, 112  )
ob2 = newObstacle( "TMidCent.png", 240, 112  )
ob3 = newObstacle( "TRCorner.png", 278, 112  )
ob4 = newObstacle( "StubLeft.png", 160, 158, { yScale = 0.5 }  )
ob5 = newObstacle( "mid.png", 201, 157, { yScale = 0.55 }  )
ob6 = newObstacle( "mid.png", 240, 157, { yScale = 0.55 }  )
ob7 = newObstacle( "mid.png", H, 157, { yScale = 0.55 }  )



[TOPIC: post.html]
#18

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,286 posts
  • Corona SDK

@zetterlhean,

 

You might find this code interesting in terms of how to make generation and collision code compact:

 

https://forums.coronalabs.com/topic/74120-mechanics-in-250-or-less-with-corona-doodle-jump/

 

Pay particular attention to player.collision() ... and createGameObject()



[TOPIC: post.html]
#19

zettelrhean

[GLOBAL: userInfoPane.html]
zettelrhean
  • Observer

  • 25 posts
  • Corona SDK

that isnt what i need, i dont care how redundant my code is, im doing what i know and i need the solution for what im asking for not having my code picked apart by people far more skilled than me and using techniques i have no clue how they work, id really appreciate if i can just get what im looking for and not everything else, i just want to put multiple images under ONE name and then i can work on it from there with what i know.

 

i dont know how to do stages, i dont think that i need local since everything is in one lua file, i dont understand "params" you guys are all taking this way too fast, i cant learn by reading documentations and stuff, i learn by doing, if i get given an example that needs ME to fill in parts and not have someone else do it and show it to me then i can figure it out, watching someone do something does nothing for me, i need to do it myself and im not saying that to help me you need to create a whole coding course for me i just need help with the problem at hand

 

sorry if i seem aggressive, im not in the greatest mood at the time of writing this but hopefully this clears things up for you guys



[TOPIC: post.html]
#20

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,286 posts
  • Corona SDK

Sure, no prob.  I do want to say, that taking a little time refactoring will help.

 

By examining your code for the redundant parts and removing them you will improve your understanding and I think the important bits will start to be more apparent.   

 

As well, having less code to review and pore over when debugging and trying to make things work will help reduce stress.

 

As for the rest, I am having trouble understanding the problem you are outlining.  I will go back and re-read to see if it becomes more clear.



[TOPIC: post.html]
#21

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,286 posts
  • Corona SDK

Your Original Question
 


is there any way that i can have multiple images under one name ...

 
Answer: If I take your question at face value, then "No."  That is not a thing.   All image files need have unique names on the 'disk'.
  
Longer Answer: 
Of course I don't think that is what you meant.  What I think you want is to be able to create game objects using any image you want, but to have all of those objects be considered 'obstacles', 'pickups', or some other category of things.
 
In other words, I think you want to employ logic in your game that treats objects by their category, and your question is, "How do I group objects by category?"
 
Use Arbitrary Fields (like id)
This has been pointed out to you and I think you mostly get it.
 
@nick_sherman ponited out that you can add an arbitrary field to any display object and later check for it.
 
Ex:

local obj = display.newImage( ... )

obj.id = "obstacle"

 
In my second-to-last post I quoted your post of this code:

ob1 = display.newImage("TLCorner.png")
			ob1.xScale = 0.45
			ob1.yScale = 0.45
			ob1.x = 201
			ob1.y = 112
			ob1.id = obstacle 

 
I wanted to show that you could simplify it and wanted to show you how the concept could be applied using a builder. 
 
What I didn't mention was, "Your code is wrong."  Specifically this line:

			ob1.id = obstacle

That line, all similar lines  should have quotes around the word obstacle.

			ob1.id = "obstacle"

 
Syntax Errors?
Later in the thread, you posted:
 

doing that creates an error for me


Contextually, I don't know what you mean, but I'm guessing you typed in some code and got errors.  We can't do much to help you with that if we don't see the code.  Still, all you need to solve syntax errors is provided right in the console.  Just go to the line specified, or the few lines before that and you should see the source of your syntax error.
 
 
Back To The Original Question 

... i have multiple obstacle images and i dont want to code each ones interactions with the player, is there a way i can generalize multiple images into one name like obstacle?

 

Answer: I think what you want here is a collision listener for the player object that knows how to deal with different categories of collided objects.

 

You would do that like this:

function player.collision( self, event )
   local phase = event.phase
   local other = event.other -- thing player collided with

   if( phase == "began" ) then

      if( other.id == "obstacle" ) then
         -- do whatever you are supposed to with obstacles here

      elseif( other.id == "pickup" ) then
         -- do whatever you are supposed to with pickups here

      elseif( other.id == "danger" ) then
         -- do whatever you are supposed to with dangers here
      end
    
   end

   return false
end

player:addEventListener( "collision" )

That is about all I can get out of all the posts I've seen in this thread.  I hope this is what you're looking for.



[TOPIC: post.html]
#22

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Contributor

  • 293 posts
  • Corona SDK

I'm in the same boat as Ed in that I don't seem to fully understand what it is that you are asking.

I'm just taking a blind guess here at what I think you might be asking.

 

If you create display objects called ob1, ob2, etc. then the only way that you can refer back to them specifically is by referring to the actual object, e.g. the only way to get the x coordinate or id of ob1 is to use ob1.x or ob1.id, etc.

Commonly, when you are creating a large amount of similar objects, such as tiles, then you create a table. For example, when using your code as you presented it:

local ob = {}

ob[1] = display.newImage("TLCorner.png")
ob[1].xScale = 0.45
ob[1].yScale = 0.45
ob[1].x = 201
ob[1].y = 112
ob[1].id = "obstacle"

ob[2] = display.newImage("TMidCent.png")
ob[2].xScale = 0.45
ob[2].yScale = 0.45
ob[2].x = 240
ob[2].y = 112
ob[2].id = "obstacle"

-- etc.

With tables, you can refer to objects, like tiles, much easier. As you could check the x coordinate or id of any element in the ob table by using ob[n].x or ob[n].id, where n is a number you want.

 

In your specific use, if I still remember it correctly, if you have... let's say X number of rows and Y number of columns, then you could create the tiles in the following loop.
 

 

local tile = {}
local rowCount = 8
local columnCount = 12

for i = 1, rowCount do
	tile[i] = {}

	for j = 1, columnCount do
		tile[i][j] = display.newRect( x, y, width, height )
	end
end

This would create a table for each row and fill that table with as many tiles as there are columns. This style also allows you to control the size and coordinates of all the tiles from one location. But, with this method, you could refer to any specific tile by using tile[row][column] code, e.g. if you want to refer to tile on row 2, column 3, you'd write tile[2][3].

I hope this answer was at least close to what you were asking :P

 


  • roaminggamer likes this

[TOPIC: post.html]
#23

zettelrhean

[GLOBAL: userInfoPane.html]
zettelrhean
  • Observer

  • 25 posts
  • Corona SDK

my teacher said something about having them in a table and then just checking if that name is in the table, how would i do that?



[TOPIC: post.html]
#24

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,286 posts
  • Corona SDK

Your teacher?  Why isn't your teacher helping with this?  

 

I'm sorry if you're not getting sufficient help from your teacher, that bites.

 

... to the question 

 

 

The use of the term 'name' doesn't make any sense in this context.  Anything you use as an index in a table must be unique or you are referencing the same position in the table.

 

So, if you did this:

local objs = {}

objs["obstacle"] = display.new...()

objs["obstacle"] = display.new...()

You will have created two objects, but only one (the last one created) will be referenced in the table.

 

 

 

Perhaps, your teacher meant or said, 'reference objects by their ID'.

local objs = {}

local tmp = display.new...()
objs[tmp] = tmp

local tmp = display.new...()
objs[tmp] = tmp


The table above has two unique entries, each referencing one of the two created objects.

 

However, because you used non-numeric indices, you have to iterate over the table like this:

for k,v in pairs( objs ) do
   ... do some work on the objects here
   v is the object
   k is the index
end

For a concrete example, lets change the color of all objects in the table to red:

for k,v in pairs( objs ) do
   v:setFillColor(1,0,0)
end

Now, lets apply the ID concept.  Let's add a few objects and set pickups to yellow and obstacles to red:

local objs = {}

-- make two pickup objects 
local tmp = display.new...()
tmp.id = "pickup"
objs[tmp] = tmp

local tmp = display.new...()
tmp.id = "pickup"
objs[tmp] = tmp



-- make two obstacle objects 
local tmp = display.new...()
tmp.id = "obstacle"
objs[tmp] = tmp

local tmp = display.new...()
tmp.id = "obstacle"
objs[tmp] = tmp

later...

for k,v in pairs( objs ) do

   if( v.id == "pickup" ) then
      v:setFillColor(1,1,0)   

   elseif( v.id == "obstacle" ) then  
      v:setFillColor(1,0,0)
   end
end

What about removing objects from the table?

I'm going to use the collision code I provided in a prior post and assume that all objects are in the table objs and that objs is visible in the collision listener.

 

If all that is true, I can do this:

-- somewhere above the listener
local score = 0
local objs = {}


function player.collision( self, event )
   local phase = event.phase
   local other = event.other -- thing player collided with

   if( phase == "began" ) then

      if( other.id == "obstacle" ) then
         -- do whatever you are supposed to with obstacles here

      elseif( other.id == "pickup" ) then
         -- lets increment the score, delete the pickup object, and remove it from the tracking
         -- table
         score = score + 1
         display.remove(other)
         objs[other] = nil

      elseif( other.id == "danger" ) then
         -- do whatever you are supposed to with dangers here
      end
    
   end

   return false
end

player:addEventListener( "collision" )

Edited by roaminggamer, 23 October 2018 - 12:57 PM.


[TOPIC: post.html]
#25

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,286 posts
  • Corona SDK

If this is still not what you want, I suggest we back up a bit.

 

Tell us clearly and concisely what your game is and the mechanics in the game.  Please try to use clear sentences, distinct paragraphs,  and bullet lists if you can.

 

Knowing more about your project may help us to help you.




[topic_controls]
Page 1 of 2 1 2
 
[/topic_controls]

Also tagged with one or more of these keywords: lua, corona