How to anchor object inside a rectangle in corona sdk? - lua

I am trying to add a little rectangle inside of a big rectangle as seen in the images below but nothing seems to be working. I want to use anchors but I do not know how to proceed. I am trying to put the little rectangle in the top right corner of the bigger rectangle.Any advice would be extremely helpful!
local bigRectangle = display.newRect(200,200,320,400)
bigRectangle:setFillColor(0,0,1)
bigRectangle.x = _X
bigRectangle.y = _Y
local smallRectangle = display.newRect(200,200,20,20)
bigRectangle:setFillColor(255/255,255/255,0/255)
what I am trying to accomplish:

It can be accomplish in many ways. The simplest way is to change anchor point to (1, 0). It requires that both objects have the same x and y coords:
local bigRectangle = display.newRect( 200, 200, 320, 400 )
bigRectangle.anchorX, bigRectangle.anchorY = 1, 0
bigRectangle:setFillColor( 0, 0, 1 )
local smallRectangle = display.newRect( 200, 200, 20, 20 )
smallRectangle.anchorX, smallRectangle.anchorY = 1, 0
smallRectangle:setFillColor( 255 / 255, 255 / 255, 0 / 255 )
More universal method use bounds property of display objects:
local bigRectangle = display.newRect( 200, 200, 320, 400 )
bigRectangle:setFillColor( 0, 0, 1 )
bigRectangle.x = _X
bigRectangle.y = _Y
local smallRectangle = display.newRect( 200, 200, 20, 20 )
smallRectangle:setFillColor( 255 / 255, 255 / 255, 0 / 255 )
local bounds = bigRectangle.contentBounds
smallRectangle.x = bounds.xMax - smallRectangle.width * smallRectangle.anchorX
smallRectangle.y = bounds.yMin + smallRectangle.height * smallRectangle.anchorY

Related

How can I use turtle graphics in maxscript to align the bent boxes

struct Turtle (
position_ = [0, 0, 0],
heading_= [0, 1, 0],
rotationQuat_ = quat 0 0 0 1,
amount = 200,
turnAngle = 45,
fn forward = (
c = box pos: position_ wirecolor: red width: 40 length: amount height: 2 lengthSegs: 10
rotate c rotationQuat_
position_ = position_ + amount * heading_
),
fn left = (
q = quat -turnAngle [0, 0, 1]
rotationQuat_ = q * rotationQuat_
invq = inverse q
heading_ = heading_ * invq
c = box pos: position_ wirecolor: red width: 40 length: amount height: 2 lengthSegs: 10
addmodifier c (bend())
c.bend.bendAngle = 45
c.bend.bendAxis = 1
rotate c rotationQuat_
position_ = position_ + amount * heading_
),
fn right = (
q = quat turnAngle [0, 0, 1]
rotationQuat_ = q * rotationQuat_
invq = inverse q
heading_ = heading_ * invq
c = box pos: position_ wirecolor: red width: 40 length: amount height: 2 lengthSegs: 10
addmodifier c (bend())
c.bend.bendangle = -45
c.bend.bendAxis = 1
rotate c rotationQuat_
position_ = position_ + amount * heading_
)
)
fn main = (
delete objects
t = Turtle()
t.left()
t.left()
t.left()
t.left()
t.left()
t.left()
t.left()
t.right()
t.forward()
t.forward()
t.right()
)
main()
I'm trying to create a path using turtle graphics but because the boxes don't line up properly once you bend it I can't get them align. I managed to get it temporarily working by changing the pivot point on each shape but it was hard coded so that only worked in certain scenarios. How can I get each of the boxes to align?
I'd make use of the fact that pivot of a box is at zero in local Z, and switch the orientation of both the box and the bend gizmo so that it bends around its base and not around the center. Since you're bending the box, you also cannot simply move by the box lenght but you have to calculate an offset along the bent arc instead. All in all, this is how I'd do that:
struct Turtle
(
private transform = arbAxis y_axis,
public stepLength = 200,
public turnAngle = 45,
private fn updateTransform angle distance =
if angle == 0 then transform *= transMatrix (transform.row3 * distance)
else transform = rotateYMatrix angle * transMatrix (distance / degToRad angle * [1 - cos angle, 0, sin angle]) * transform,
private fn stride distance bendAngle =
(
local stripe = Box width:40 length:2 height:stepLength widthSegs:1 lengthSegs:1 heightSegs:10 transform:transform wirecolor:red
if bendAngle != 0 do addModifier stripe (Bend bendAxis:2 bendAngle:bendAngle)
updateTransform bendAngle distance
),
public fn forward = stride stepLength 0,
public fn left = stride stepLength turnAngle,
public fn right = stride stepLength -turnAngle
)

How does the buffer from the ws2812b module work?

This is an example taken from the ws2812 documentation:
ws2812.init()
local i, buffer = 0, ws2812.newBuffer(300, 4); buffer:fill(0, 0, 0, 0); tmr.create():alarm(50, 1, function()
i = i + 1
buffer:fade(2)
buffer:set(i % buffer:size() + 1, 0, 0, 0, 255)
ws2812.write(buffer)
end)
First of all I tried to translate this into something more readable and since I use RGB and not RGBW LEDs, I also removed the W component:
local numberOfLeds = 300
local bytesPerLed = 3 -- (R, G and B)
ws2812.init()
local i
local buffer = 0
ws2812.newBuffer(numberOfLeds, bytesPerLed)
buffer:fill(255, 255, 255)
tmr.create():alarm(50, 1, function() -- repeat every 50 milliseconds
i = i + 1
buffer:fade(2)
buffer:set(i % buffer:size() + 1, 255, 255, 255)
ws2812.write(buffer)
end)
It doesn't really make any sense to me, though. Why does buffer have a fill method? I mean didn't we set it to simply be 0? buffer = 0
Am I translating this incorrectly?
The original code said local i, buffer = 0, ws2812.newBuffer(...); ...
The original code is equivalent to
local i = 0
local buffer = ws2812.newBuffer(300, 4); buffer:fill(0, 0, 0, 0); tmr.create():alarm(50, 1, function()
In general,
local x,y,z = a,b,c
is equivalent to
local x = a
local y = b
local z = c
See the manual.

Randomly putting a circle in a box

I am making a game and I am trying to randomly put a circle in a rectangle. But, it seems that the circle sometimes appear outside of the rectangle. What would I have to do so the circle ALWAYS appears somewhere in the rectangle?
this is my code:
rectangle:
--bottom
local floor = display.newRect(0, display.contentCenterY/.665, display.contentWidth*2, 10)
physics.addBody(floor, "static", {density = 1, friction = 1, bounce = 0})
--top
local floor = display.newRect(0, display.contentCenterY/2, display.contentWidth*2, 10)
physics.addBody(floor, "static", {density = 1, friction = 1, bounce = 0})
--right
local floor = display.newRect(display.contentCenterX*2, display.contentCenterY/1, 10, display.contentHeight/2)
physics.addBody(floor, "static", {density = 1, friction = 1, bounce = 0})
--left
local floor = display.newRect(0, display.contentCenterY/1, 10, display.contentHeight/2)
physics.addBody(floor, "static", {density = 1, friction = 1, bounce = 0})
circle:
--Small sprites--
local randomX = math.random(1,display.contentCenterX*2)
local randomY = math.random(1, display.contentCenterY*2)
local smallSprite = display.newCircle(randomX, randomY, display.contentWidth/100)
smallSprite:setFillColor(1, 1, .3, 1) --This will set the fill color to transparent
smallSprite.strokeWidth = 7 --This is the width of the outline of the circle
smallSprite:setStrokeColor(.1,1,1) --This is the color of the outline
smallSprite = display.newGroup(smallSprite)
That is easy, you know where the sides of rectangle are (call them rigth, left, top and bottom) and the radius of circle, so: randomX will be between left+radius and right-radius, and randomY will be between top+radius and bottom-radius
-- remember to add/substract the width of the walls
local left = 0 + 10
local right = display.contentCenterX * 2 - 10
--Small sprites--
local randomX = math.random(left+radius,right-radius)
local randomY = math.random(top+radius, bottom-radius)
You can generate a random number between any 2 numbers of your choice.
Remember also you can use display.contentHeight and display.contentWidth
As a tip, you can add at the beginning of your file a section with variables like:
-- Variables
local w = display.contentWidth
local h = display.contentHeight
local centerX = display.contentCenterX
local centerY = display.contentCenterY
So you can use only centerX instead of display.contentCenterX

I drawed a player into my love2d but it only fills out 1/4?

This is my charecter in love2d while jumping.
It looks fine but..
when I get on the ground it looks like this.
I figured out that it may have some thing to do with the img, that it doesn't fill out the entire square.
So it is simply is out of the collision square.
Thats the square it should have been in, but since im quite new to programing I cant figure out how to do it.
I have been searching for a solution but cant find one ATM.
This is my
love.load
function love.load()
love.graphics.setBackgroundColor( 204, 255, 204 )
crazy = love.graphics.newImage("player.png")
pwidth = crazy.getWidth
pheight = crazy.getHeight
AdvTiledLoader.path = "maps/"
map = AdvTiledLoader.load("map.tmx")
map:setDrawRange(0, 0, map.width * map.tileWidth, map.height * map.tileHeight)
camera:setBounds(0, 0, map.width * map.tileWidth - love.graphics.getWidth(), map.height * map.tileHeight - love.graphics.getHeight() )
world = {
gravity = 1536,
ground = 512,
}
player = {
x = 256,
y = 256,
x_vel = 0,
y_vel = 0,
jump_vel = -1024,
speed = 512,
flySpeed = 700,
state = "",
h = 32,
w = 32,
standing = false,
}
function player:jump()
if self.standing then
self.y_vel = self.jump_vel
self.standing = false
end
end
function player:right()
self.x_vel = self.speed
end
function player:left()
self.x_vel = -1 * (self.speed)
end
function player:stop()
self.x_vel = 0
end
function player:collide(event)
if event == "floor" then
self.y_vel = 0
self.standing = true
end
if event == "cieling" then
self.y_vel = 0
end
end
And my love.draw
function love.draw()
camera:set()
love.graphics.draw(crazy, player.x , player.y)
love.graphics.setColor( 255, 255, 255 )
map:draw()
camera:unset()
end
If you need to see my collision or anything else just ask and I will paste it below :)
I really apriciate your help thanks!
What is most likely happening is that the you have the x,y co-ordinate as the centre of the sprite. So it's stopping when the map meets the centre.
As you're drawing the sprite before the map, you only see the bit not covered by the map.
An easy way of proving this is to draw the sprite after the map and you should see the whole sprite over the map.
There would be a couple of ways to resolve this. Either leave the collisions where they are and draw the sprite with ox=-width/2,oy=-height/2.
Alternatively have the collision at the at the bottom of the sprite by adding width/2 and height/2 to the collision point.
If this doesn't help then we'll probably need the collision logic.
First of all, I assume you want pwidth/pheight to be numbers, not the get functions.
pwidth = crazy.getWidth()
pheight = crazy.getHeight()
The image is drawn from it's topleft corner, but I'm guessing that your collision logic has the hitbox centered on the player's position.
You can either compensate by changing the coordinate of the draw function, or pass in an origin offset to the image. The advantage of specifying the origin offset is that you can then rotate and scale relative to that origin.
love.graphics.draw(crazy, player.x - pwidth/2 , player.y - pheight/2)
or
rotation, scalex, scaley = 0, 1, 1
love.graphics.draw(crazy, player.x, player.y, rotation, scalex, scaley, pwidth/2, pheight/2)

Corona SDK custom physics bodies

i have some trouble with the custom shapes in corona.
Here is my code and what it does is that i'm adding some spheres to the scene so that they fall inside a basket, this basket is the custom shape object that i defined in the newBasket() function, the problem is that the basket does collide with the ground object but it doesn't collide with the spheres and i don't know why, please someone help me here, i can't find a solution elsewhere, thanks in advance.
_W = display.contentWidth
_H = display.contentHeight
--Physics
local physics = require("physics")
physics.start()
physics.setDrawMode("debug")
-- iOS
display.setStatusBar(display.HiddenStatusBar)
-- screen boundaries
local ground = display.newRect(0, _H, _W, 5)
local leftWall = display.newRect(0,0,1,_H)
local rightWall = display.newRect(_W,0,1,_H)
physics.addBody(ground, "static", {friction = .2, bounce = .1})
physics.addBody(leftWall, "static", {friction = .2, bounce = .1})
physics.addBody(rightWall, "static", {friction = .2, bounce = .1})
local function newBasket()
local body = display.newImage("assets/basket.png")
body.x = 0 body.y = 0
local physics_body = {}
physics_body["basket"] = {
{
--LeftArm
density = 10, friction = 10, bounce = 0.15,
shape = {-126, 40, -110, 40, -140, -64, -156, -64}
},
{
--Bottom
density = 10, friction = 1, bounce = 0,
shape = {-121, 60, 125, 60, 128, 40, -126, 40}
},
{
--RightArm
density = 10, friction = 10, bounce = 0.15,
shape = {113, 40, 129, 40, 158, -64, 143, -64}
}
}
physics.addBody(body, unpack(physics_body["basket"]) )
return body
end
local basket = newBasket()
basket.x = _W * .5 basket.y = _H - 100
local function newPlanet()
local planets = {
{img = "bigBall.png", radius = 45},
{img = "mediumBall.png", radius = 30},
{img = "smallBall.png", radius = 20}
}
local n = math.random(1,3)
local img = "assets/" .. planets[n].img
local ball = display.newImage(img)
ball.x = math.random((_W * 0.5) -100, (_W * 0.5) + 100) ball.y = 0
physics.addBody(ball, {bounce = 0.3, radius = planets[n].radius})
end
local function spawnPlanets(number)
local function spawn(e)
newPlanet()
if(e.count == number) then
timer.cancel(tmr)
tmr = nil
end
end
tmr = timer.performWithDelay(500, spawn, number)
end
spawnPlanets(20)
According to the manual:
If a shape is specified, then the body boundaries will follow the polygon provided by the shape. Note that the maximum number of sides per shape is eight, and all angles must be convex. [...] The shape coordinates must be defined in clockwise order, and the resulting shape must be convex-only.
So you have two issues working against you. First the shapes must be defined in clockwise order, as I've done in the below example. Secondly, all shapes must be convex (even complex body shapes) so you can't do anything that turns in on itself like a crescent moon or basket.
Unfortunantly, this means you have to make your basket as 3 separate shapes. Also, since they are now separate shapes, they won't stay stuck together when they fall (unless you use joints). I've just made the basket 3 static bodies and put it in the right place to start with:
local function newBasket()
local physics_body = {}
physics_body["basket"] = {
{
--LeftArm
density = 10, friction = 10, bounce = 0.15,
shape = {-126, 40, -156, -64, -140, -64, -110, 40 }
},
{
--Bottom
density = 10, friction = 1, bounce = 0,
shape = {-121, 60,-126, 40, 128, 40, 125, 60 }
},
{
--RightArm
density = 10, friction = 10, bounce = 0.15,
shape = {113, 40, 143, -64, 158, -64, 129, 40 }
}
}
for k,shape in pairs(physics_body["basket"]) do
local body = display.newRect(0, 0, 200, 100)
body.x = display.contentCenterX
body.y = display.contentHeight - 60
physics.addBody(body, 'static', shape )
end
end
newBasket()

Resources