I'm trying to scroll side a background in corona sdk (infinity background)
I used two images repeated (854x176).
I tried this function:
function mov(self, event)
if self.x < -854 then
self.x = 854
else
self.x = self.x - self.speed
end
end
it's working just fine but the problem that a small white space occurred between repetitions.
Is there a better way to do this?
One way of doing this would be to take advantage of Graphics 2.0 Engine's feature called repeating fills.
Here are the steps:
Set the default texture wrapping mode for x (you could do the same for y too):
display.setDefault("textureWrapX", "mirroredRepeat")
The modes for wrapping are:
"clampToEdge" - (default) clamped fill won't repeat
"repeat" - fill is repeated as if same tiles were placed side by side
"mirroredRepeat" - fill is repeated in a mirrored pattern, each tile being a mirror image of the one next to it
Create a rectangle the size of the background you want to have, eg. full screen
local background = display.newRect(display.contentCenterX, display.contentCenterY, 320, 480)
Fill your display object with your background image
background.fill = {type = "image", filename = "background.jpg"}
Animate it using whatever method fits your app. Below's just one way:
local function animateBackground()
transition.to(background.fill, {time=5000, x=1, delta=true, onComplete=animateBackground})
end
animateBackground()
Here you simply run transition on x property of background.fill object, delta=true indicating that we're rather using changes in x value, not final ending values (see here).
Play with the values for time, x, set delta to false, play with wrapping modes, just to see what effect it has on animation. You might even accidentally discover some cool effect which you might want to use later...
Check this excellent tutorial by Brent Sorrentino, who goes through more details on fills. Additionally, see sample code in CoronaSDK under Graphics-Premium/PatternFill.
Full code:
display.setDefault("textureWrapX", "mirroredRepeat")
local background = display.newRect(display.contentCenterX, display.contentCenterY, 320, 480)
background.fill = {type = "image", filename = "background.jpg" }
local function animateBackground()
transition.to( background.fill, { time=5000, x=1, delta=true, onComplete=animateBackground } )
end
animateBackground()
Related
Hey so I am looking for something similar to in tennis when players challenge a point and the video shows whether the ball was in or out by zooming in really really close to the moment when the ball lands to see whether a fraction was on the line.
I have experimented with using transitions with xScale and yScale but the results I get is strange, almost as if the objects have moved during zooming in. If there was a way to lock in position and then zoom, that would work. The second method I tried is putting the graphics into a display group and then scaling the group. This also results in weird behaviour where the whole group begins moving diagonally across the screen.
Please help as this is confusing me
cheers.
Objects which will scale:
cloud = display.newImageRect("cloud.png", 419,273)
cloud.anchorY = 0
cloud.anchorX = 0.5
cloud.alpha = 1
cloud.x = display.contentCenterX
cloud.y = display.contentCenterY + 250
physics.addBody(cloud, {isSensor=true})
star = display.newImageRect("Star.png", 78,72)
star.anchorY = 0
star.anchorX = 0.5
star.alpha = 1
star.name = "Star"
physics.addBody(star, {isSensor=true})
star.x = display.contentCenterX
star.y = display.actualContentHeight - display.actualContentHeight - 100
Scale Function
function scale( event )
transition.to(star, {time=2000, xScale=1.5, yScale = 1.5})
transition.to(cloud, {time=2000, xScale=1.5, yScale=1.5})
end
When you scale an object, it may "move" due to its anchor position, which is the position of the object that is used to position it and also works as its 'anchor' during rotation or scale.
So, you have 2 options:
1) Set the anchor position (obj.anchorX = value , obj.anchorY = value ) to the one that will make your object stays in the position that you want;
2) During the transition, also change its x and y to compensate the moving.
Im fighting here with the so called ghost collisions on a simple tile based map with a circle as player character.
When applying an impulse to the circle it first starts bouncing correctly, then sooner or later it bounces wrong (wrong angle).
Looking up on the internet i read about an issue in Box2D (i use iOS Swift with Box2d port for Swift).
Using b2ChainShape does not help, but it looks i misunderstood it. I also need to use the "prevVertex" and "nextVertex" properties to set up the ghost vertices.
But im confused. I have a simple map made up of boxes (simple square), all placed next to each other forming a closed room. Inside of it my circle i apply an impulse seeing the issue.
Now WHERE to place those ghost vertices for each square/box i placed on the view in order to solve this issue? Do i need to place ANY vertex close to the last and first vertice of chainShape or does it need to be one of the vertices of the next box to the current one? I dont understand. Box2D's manual does not explain where these ghost vertices coordinates are coming from.
Below you can see an image describing the problem.
Some code showing the physics parts for the walls and the circle:
First the wall part:
let bodyDef = b2BodyDef()
bodyDef.position = self.ptm_vec(node.position+self.offset)
let w = self.ptm(Constants.Config.wallsize)
let square = b2ChainShape()
var chains = [b2Vec2]()
chains.append(b2Vec2(-w/2,-w/2))
chains.append(b2Vec2(-w/2,w/2))
chains.append(b2Vec2(w/2,w/2))
chains.append(b2Vec2(w/2,-w/2))
square.createLoop(vertices: chains)
let fixtureDef = b2FixtureDef()
fixtureDef.shape = square
fixtureDef.filter.categoryBits = Constants.Config.PhysicsCategory.Wall
fixtureDef.filter.maskBits = Constants.Config.PhysicsCategory.Player
let wallBody = self.world.createBody(bodyDef)
wallBody.createFixture(fixtureDef)
The circle part:
let bodyDef = b2BodyDef()
bodyDef.type = b2BodyType.dynamicBody
bodyDef.position = self.ptm_vec(node.position+self.offset)
let circle = b2CircleShape()
circle.radius = self.ptm(Constants.Config.playersize)
let fixtureDef = b2FixtureDef()
fixtureDef.shape = circle
fixtureDef.density = 0.3
fixtureDef.friction = 0
fixtureDef.restitution = 1.0
fixtureDef.filter.categoryBits = Constants.Config.PhysicsCategory.Player
fixtureDef.filter.maskBits = Constants.Config.PhysicsCategory.Wall
let ballBody = self.world.createBody(bodyDef)
ballBody.linearDamping = 0
ballBody.angularDamping = 0
ballBody.createFixture(fixtureDef)
Not sure that I know of a simple solution in the case that each tile can potentially have different physics.
If your walls are all horizontal and/or vertical, you could write a class to take a row of boxes, create a single edge or rectangle body, and then on collision calculate which box (a simple a < x < b test) should interact with the colliding object, and apply the physics appropriately, manually calling the OnCollision method that you would otherwise specify as the callback for each individual box.
Alternatively, to avoid the trouble of manually testing intersection with different boxes, you could still merge all common straight edge boxes into one edge body for accurate reflections. However, you would still retain the bodies for the individual boxes. Extend the boxes so that they overlap the edge.
Now here's the trick: all box collision handlers return false, but they toggle flags on the colliding object (turning flags on OnCollision, and off OnSeparation). The OnCollision method for the edge body then processes the collision based on which flags are set.
Just make sure that the colliding body always passes through a box before it can touch an edge. That should be straightforward.
What I want is that the images fall from the top side of the screen and start falling down accelerating, they would only be falling straight down, alternating positions around the width of the screen, meaning one on the right, then another one in the middle, and then another one on the left side and so on in the different positions, until they disappear at the bottom of the screen.
I tried this
function moveMeteors()
for i = 1, math.random(1, 2) do
meteors = display.newImage("meteor.png")
screenGroup:insert(meteors)
meteors.x = (math.random(display.contentWidth))
meteors.y = centerY - 340
transition.to(meteors, {time = math.random(3500 - speedMeteor, 4500 - speedMeteor),
y = 1000 + speedMeteor, onComplete = clear })
speedMeteor = speedMeteor + 10
end
end
But, sometimes the images appear one over the other and I do not want that, I mean, each image appear and go from the top to the bottom of the screen in his own line. I hope that I've explained this well.
You should look into utilizing the built in physics of Coronasdk. CoronaDocs:Physics.
As an example this code should easily simulate the effect you a trying to get, you will have to add functions to take care of removing objects as they leave the screen etc.
local physics = require("physics")
physics.start()
function SpawnMeteor()
local meteor = display.newImage( "meteor.png", math.random(display.contentWidth), centerY - 340)
physics.addBody( meteor)
end
timer.performWithDelay( 2000, SpawnMeteor)
I'm getting a (a nil value) error when i try to do this :
player = display.newSprite( imageSheet, "sequenceDataPlayer"..math.random(1, 7) )
Looking at a test print :
print ("sequenceDataPlayer"..math.random(1, 7) )
It prints the data oky 'sequenceDataPlayer1'
What Im i doing wrong here ?
Your print statement is just printing the string "sequenceDataPlayer" concatenated with a random number between 1 and 7.
It took me a little while to figure out how to use sprites in Corona, but here's how I do it. I'll use Player for the variables since that's what you're using.
First I create an options variable to get the frames from my Player.lua file:
optionsPlayer =
{
frames = require("player").frames,
}
Then I create a variable for the image sheet:
playerSheet = graphics.newImageSheet( "player.png", optionsPlayer )
After that, I create a variable to set up the name, the sequence of frames, the time it takes to play, and set how many times it will loop:
spriteOptionsPlayer = { name="Player", start=1, count=10, time=500, loopCount = 1}
Finally, I create the new sprite:
spriteInstancePlayer = display.newSprite( playerSheet, spriteOptionsPlayer )
Once I've done all this, I usually set up the x and y positions, xScale and yScale, and other properties along with adding it to a display group.
Last of all, then I play the sprite somewhere:
spriteInstancePlayer:play()
From what it looks like, you want to have 7 different sprites to choose from. Personally, I would just create seven different sprites using all of the steps above and then put them in a table.
sprites = { spriteInstancePlayer, spriteInstancePlayer2, spriteInstancePlayer3, etc.. }
Then when I wanted to play them, I would set the position and visibility and just do:
r = math,random(1, 7)
sprites[r].x = x position
sprites[r].y = y position
sprites[r].isVisible = true
sprites[r]:play()
Of course, then I would want to set listeners to either completely remove the sprite or set the visibility to false when it's done playing, there's a collision(you'd have to add a physics body and set that all up), or whatever else might happen...
There are probably simpler ways to do it, but that's what I do.
Hope this helps.
I didn't understand some object position concepts in Corona SDK
I have created sprite sheet:
local spriteSheet = sprite.newSpriteSheet("button.png", 138, 64);
local spriteSet = sprite.newSpriteSet(spriteSheet, 1, 2);
local sp = sprite.newSprite( spriteSet );
and it's positions are strange and sprite is out of screen bounds even I set x and y positions to zero
config.lua is:
application =
{
content =
{
width = 320,
height = 480,
scale = "letterbox"
},
}
I think that problem in "referencePoint"
just say me how to change setReferencePoint of default screen (not image or group ...), just default screen...
Technically you can use a different coordinate system for all your graphics by creating a display group and attach everything to that group, but really it seems like you're asking the wrong question. Rather than trying to change the reference point of the screen, you should be wondering why your sprites aren't positioned correctly.
Please create a new question that focuses on that problem and explains it further, because all you say here is that the positions are "strange". What's that mean?
You can modify your code like below and just check it,it will work:
local spriteSheet = sprite.newSpriteSheetFromData( "button.png",require("button").getSpriteSheetData())
local spriteSet = sprite.newSpriteSet(spriteSheet,1,9);
sprite.add(spriteset,"button",1,9,1000,0);
//button is lua file use button.lua
local sp = sprite.newSprite( spriteSet );
sp:prepare("button");
sp.x = display.screenOriginX+138;
sp.y = display.screenOriginY+64;