Hi I am new to coding and I am using Lua and solar2d, trying to transition object1 via another object2's co-ordinates and for object1 to continue along the same path with the same velocity if it doesn't hit object2.
I can easily transition to the obeject but I don't know how to then go beyond that.
transition.to( object1, { x=object2.x, y=object2.y, time=3000, })
I feel I will have to add an oncomplete but not sure what.
any help would be greatly appreciated.
You have to calculate the equation of the line (y = m * x + b) that you are traveling.
Formulas:
m = (y2 - y1) / (x2 - x1)
b = y1 - m * x1
So in your case:
m = (object2.y - object1.y) / (object2.x - object1.x)
b = object1.y - m * object1.x
Now you have the equation of the path (line) to keep if object1 doesn't hit object2.
When the transition ends, you want to check if the object2 is still there (object1 hit it) or not (object1 keeps moving), so you need to include an onComplete listener to check for that.
As for the speed, you have to decide if you want a constant speed and then you have to calculate the time for each transition or if you are using always 3 seconds no matter if the object2 is close or far away from the object1. I guess you probably want the first option, so it doesn't go pretty slow if objects are close and too fast if the object are far away. In that case you have to set a constant speed s, that you want.
Formulas:
Speed = Distance / Time
Time = Distance / Speed
Distance between 2 points:
d = squareRoot( (x2 - x1)^2 + (y2 - y1)^2 )
In summary, it would be something like that:
s = 10 --Constant speed
m = (object2.y - object1.y) / (object2.x - object1.x)
b = object1.y - m * object1.x
direction = 1 --assume it's traveling to the right
if(object2.x < object1.x)then
direction = -1 --it's traveling to the left
end
local function checkCollision( obj )
if(obj.x == object2.x and obj.y == object2.y)then
-- Object1 hit Object2
else
-- Object2 is not here anymore, continue until it goes offscreen
-- following the line equation
x3 = -10 -- if it's traveling to the left
if(direction == 1)then
--it's traveling to the right
x3 = display.contentWidth + 10
end
y3 = m * x3 + b
d2 = math.sqrt( (x3 - obj.x)^2 + (y3 - obj.y)^2 )
t2 = d2 / s
transition.to( obj, {x=x3, y=y3, time=t2} )
end
end
d1 = math.sqrt( (object2.x - object1.x)^2 + (object2.y - object1.y)^2 )
t1 = d1 / s
transition.to( object1, { x=object2.x, y=object2.y, time=t1, onComplete=checkCollision} )
You should try different values for the speed s until you get the desired movement.
New to Lua/Game dev in general here. I'm trying to write a code to draw the background of my game. I have four different spritesheets for things related to setting:
Background - which contains the drawn "background image" of the game
Platforms - which contain the platform sprites of the game
objectsBig - which contain the relatively bigger drawn objects in the background (example rocks, seaweed, etc)
objectsSmall - which contain the relatively smaller drawn objects (smaller rocks, plants, etc)
I made a function, called generateQuads() which is in my Util.lua file, which, given a spritesheet, splices it up into the different sprites in the spritesheet and returns those sprites. It is as follows:
-- Function to generate quads/cut the spritesheet
function generateQuads(atlas, tileWidth, tileHeight)
local sheetWidth = atlas:getWidth() / tileWidth
local sheetHeight = atlas:getHeight() / tileHeight
local sheetCounter = 1
local quads = {}
-- for every line of the sprite sheet
for y = 0, sheetHeight - 1 do
-- for every piece in the width
for x = 0, sheetWidth - 1 do
-- quads generated will be the ones specified by tileWidth and tileHeight
quads[sheetCounter] = love.graphics.newQuad(x * tileWidth, y * tileHeight, tileWidth,
tileHeight, atlas:getDimensions())
sheetCounter = sheetCounter + 1
end
end
return quads
end
I also have a class called Map, which is meant to contain information for the Map. The following are the functions in it:
FUNCTION TO SET UP THE CLASS
function Map:init()
-- Load the background sprite into variable
-- Each is 500x500, total is 1500x500
self.background = love.graphics.newImage('Graphics/platform/background/full.png')
-- Load all the ground platforms into variable
-- Each is 60x30, total is 240x30
self.platforms = love.graphics.newImage('Graphics/platform/ground/all.png')
-- Load all the bigger misc objects into variable
-- Each is 15x20, total is 15x120
self.objectsBig = love.graphics.newImage('Graphics/platform/objects/15x20/all.png')
-- Load all the smaller misc objects into variable
-- Each is 15x15, total is 60x15
self.objectsSmall = love.graphics.newImage('Graphics/platform/objects/15x15/all.png')
-- Setting the size for each of the variables IN PIXELS
self.backgroundWidth = 500
self.backgroundHeight = 1500
self.platformWidth = 60
self.platformHeight = 30
self.objectsBigWidth = 15
self.objectsBigHeight = 20
self.objectsSmallWidth = 15
self.objectsSmallHeight = 15
-- Setting the map size IN TILES
-- EXPERIMENTAL, CHECK AGAIN
self.mapWidth = 432
self.mapHeight = 243
-- Setting the width of the map IN PIXELS (in relation to platforms)
self.mapWidthPixels = self.backgroundWidth
self.mapHeightPixels = self.backgroundHeight
-- Storing our map features
self.tiles = {}
-- Storing the camera points, starting from the bottom
-- The 243 is the VIRTUAL_HEIGHT, which we needed to subtract to account for the
-- offset of the screen
self.camX = 0
self.camY = self.backgroundHeight - 243
-- Cutting each of the spritesheets
self.backgroundSprite = generateQuads(self.background, self.backgroundWidth, self.backgroundHeight)
self.platformSprite = generateQuads(self.platforms, self.platformWidth, self.platformHeight)
self.objectsBigSprite = generateQuads(self.objectsBig, self.objectsBigWidth, self.objectsBigHeight)
self.objectsSmallSprite = generateQuads(self.objectsSmall, self.objectsSmallWidth, self.objectsSmallHeight)
-- 'Setting' the tiles for the map to be background
for y = 1, self.mapHeight do
for x = 1, self.mapWidth do
self:setTile(x, y, BACKGROUND)
end
end
-- 'Setting' the platform tiles for where we start
for x = 1, self.mapWidth do
self:setTile(x, self.mapHeight - 303, GROUND_MIDDLE)
end
end
FUNCTION TO 'SET' WHERE IN THE X, Y COORDINATE THE TILES SHOULD BE
function Map:setTile(x, y, tile)
-- The table 'tiles' is going to store what tile should be in what x and y position
-- subtracting y by 1 so that it's 0 indexed, not 1 indexed
self.tiles[(y - 1) * self.mapWidth + x] = tile
end
FUNCTION TO RETURN WHAT TILE IS IN THE X, Y COORDINATE
function Map:getTile(x, y, tile)
-- This function is going to tell us what tile is set at this x and y position
return self.tiles[(y - 1) * self.mapWidth + x]
end
FUNCTION TO UPDATE
function Map:update(dt)
-- Moving the camera depending on the key being pressed
if love.keyboard.isDown('w') then
-- up movement, clamped between 0 and the other
self.camY = math.max(0, math.floor(self.camY - SCROLL_SPEED * dt))
elseif love.keyboard.isDown('a') then
-- left movement
self.camX = math.max(0, math.floor(self.camX - SCROLL_SPEED * dt))
elseif love.keyboard.isDown('s') then
-- down movement, subtracting VIRTUAL_HEIGHT to account for the screen offset
self.camY = math.min(self.backgroundHeight - VIRTUAL_HEIGHT, math.floor(self.camY + SCROLL_SPEED * dt))
elseif love.keyboard.isDown('d') then
-- right movement
self.camX = math.min(self.backgroundWidth - VIRTUAL_WIDTH, math.floor(self.camX + SCROLL_SPEED * dt))
end
end
FUNCTION TO RENDER
function Map:render()
for y = 1, self.mapHeight do
for x = 1, self.mapWidth do
-- Drawing the background first
love.graphics.draw(self.background, self.backgroundSprite[self:getTile(x, y)],
(x - 1) * self.backgroundWidth, (y - 1) * self.backgroundHeight)
love.graphics.draw(self.platform, self.platformSprite[self:getTile(x, y)],
(x - 1) * self.platformWidth, (y - 1) * self.platformHeight)
end
end
end
What I'm trying to do is splice up each spritesheet, and for set the background and bottom tiles so that I can see a bottom floor. I'm trying to do this through giving numbers to the components in my spritesheet, so that, for example, in a 1500x500 spritesheet for the background, the entire thing is considered 'one' sprite, and treated as such. Its number, 1, is given in a variable. Another example is a 240x30 platform spritesheet, where each 60x30 is considered 'one' sprite, and given a corresponding number, like so:
-- Know where the platforms are in the spritesheet
GROUND_LEFT = 1
GROUND_RIGHT = 2
GROUND_SMALL = 3
GROUND_MIDDLE = 4
-- Know where the backgrounds are in the spritesheet
BACKGROUND = 1
[...]
I want to then store each in the self.tiles list, so that I can access them at any time from the table (Do note that most of this is taken from the CS50 implementation of mario, and so I understand if I've gotten any concepts wrong). When I run this code, though, I get the following error:
Error
Error
Map.lua:135: bad argument #1 to 'draw' (Texture expected, got nil)
Traceback
[C]: in function 'draw'
Map.lua:135: in function 'render'
main.lua:48: in function 'draw'
[C]: in function 'xpcall'
Essentially, I just want to know a way in which I can set the bottom platform tiles, and then be able to iterate over the map and 'set' where the other object sprites should be. The background alone works fine, but once I added the:
-- 'Setting' the platform tiles for where we start
for x = 1, self.mapWidth do
self:setTile(x, self.mapHeight - 303, GROUND_MIDDLE)
end
and
love.graphics.draw(self.platform, self.platformSprite[self:getTile(x, y)],
(x - 1) * self.platformWidth, (y - 1) * self.platformHeight)
lines, the program wouldn't run.
Any help is appreciated!
EDIT: The line I'm getting an error on is the self.platform one.
i had the same problem before, and it turned out to be a typo when typing the variable. looking at your code, i saw that there was no self.platform, instead, there was self.platforms.
try:
love.graphics.draw(self.platforms, self.platformSprite[self:getTile(x, y)],
(x - 1) * self.platformWidth, (y - 1) * self.platformHeight)
I am creating a rails application which is like a game. So it has points and levels. For example: to become level one the user has to get atleast 100 points and again for level two the user has to reach level 2 the user has to collect 200 points. The level difference changes after every 10 levels i.e., The difference between each level changes after 10 levels always. By that I mean the difference in points between level one and two is 100 and the difference in points in level 11 and 12 is 150 and so on. There is no upper bound for levels.
Now my question is let's say a user's total points is 3150 and just got updated to 3155. What's the optimal solution to find the current level and update it if needed?
I can get a solution using while loops and again looping inside it which will give a result in O(n^2). I need something better.
I think this code works but I'm not sure if this is the best way to go about it
def get_level(points)
diff = 100
sum = 0
level = -1
current_level = 0
while level.negative?
10.times do |i|
current_level += 1
sum += diff
if points > sum
next
elsif points <= sum
level = current_level
break
end
end
diff += 50
end
puts level
end
I wrote a get_points function (it should not be difficult). Then based on it get_level function in which it was necessary to solve the quadratic equation to find high value, and then calc low.
If you have any questions, let me know.
Check output here.
#!/usr/bin/env python3
import math
def get_points(level):
high = (level + 1) // 10
low = (level + 1) % 10
high_point = 250 * high * high + 750 * high # (3 + high) * high // 2 * 500
low_point = (100 + 50 * high) * low
return low_point + high_point
def get_level(points):
# quadratic equation
a = 250
b = 750
c = -points
d = b * b - 4 * a * c
x = (-b + math.sqrt(d)) / (2 * a)
high = int(x)
remainder = points - (250 * high * high + 750 * high)
low = remainder // (100 + 50 * high)
level = high * 10 + low
return level
def main():
for l in range(0, 40):
print(f'{l:3d} {get_points(l - 1):5d}..{get_points(l) - 1}')
for level, (l, r) in (
(1, (100, 199)),
(2, (200, 299)),
(9, (900, 999)),
(10, (1000, 1149)),
(11, (1150, 1299)),
(19, (2350, 2499)),
(20, (2500, 2699)),
):
for p in range(l, r + 1): # for in [l, r]
assert get_level(p) == level, f'{p} {l}'
if __name__ == '__main__':
main()
Why did you set the value of a=250 and b = 750? Can you explain that to me please?
Let's write out every 10 level and the difference between points:
lvl - pnt (+delta)
10 - 1000 (+1000 = +100 * 10)
20 - 2500 (+1500 = +150 * 10)
30 - 4500 (+2000 = +200 * 10)
40 - 7000 (+2500 = +250 * 10)
Divide by 500 (10 levels * 50 difference changes) and received an arithmetic progression starting at 2:
10 - 2 (+2)
20 - 5 (+3)
30 - 9 (+4)
40 - 14 (+5)
Use arithmetic progression get points formula for level = k * 10 equal to:
sum(x for x in 2..k+1) * 500 =
(2 + k + 1) * k / 2 * 500 =
(3 + k) * k * 250 =
250 * k * k + 750 * k
Now we have points and want to find the maximum high such that point >= 250 * high^2 + 750 * high, i. e. 250 * high^2 + 750 * high - points <= 0. Value a = 250 is positive and branches of the parabola are directed up. Now we find the solution of quadratic equation 250 * high^2 + 750 * high - points = 0 and discard the real part (is high = int(x) in python script).
In Neural networks, we regularly use the equation:
w1*x1 + w2*x2 + w3*x3 ...
We can interpret this as equation of a line with each x as a dimension. To make things more clearer, lets take an example of a simple perceptron network.
Imagine a single layer perceptron with 2 ip's/features (x1 & x2) and one output (y). (Sorry stackoverflow didn't allow me to post an additional image)
Let
R = w1*x1 + w2 * x2
y = 0 if R >= threshold
y = 1 if R < threshold
Scenario 1:
Threshold = 0
w1 = 2, w2 = -1
The line separating class 0 and 1 has the equation 2*x1 - x2 = 0
Suppose we get a test sample
P = (1,1)
R = 2*1 - 1 = 1 > 0
Sample P belongs to class 1
My questions is what is this R?
From the figure, its horizontal distance from the line.
Scenario 2:
Threshold = 0
w1 = 2, w2 = 1
The line separating class 0 and 1 has the equation 2*x1 + x2 = 0
P = (1,1)
R = 2*1 + 1 = 3 > 0
Sample P belongs to class 1
From the figure, its vertical distance from the line.
R is supposed to mean some form of distance from the classifying line. More the distance, more farther away from the line and we are more confident about the classification.
Just want to know what kind of distance from the line is R?
I am current determined to complete a problem in Lua and have no idea where to begin. I was thinking about beginning with a modulus operator. I am searching for advice from experienced Lua programmers on how to program this and mainly how I can calculate the theoretically mathematical side of the problem.
Source of the question... (http://www.eecs.qmul.ac.uk/~pbo/ACM/archive/00209.html)
Gratitude will be shown to anyone who answers correctly.
Thank-you.
function get_left(max)
i = 0
j = 1
ls = {}
repeat
i = i + 1
j = j + i - 1
ls[i] = j
print (ls[i], " ls")
until j >= max
return ls
end
a = get_left(27)
(need to format that as code -.-)
if the point1 is between a[i] and a[i+1]
if then point2 is still between a[i] and a[i+1] it is on the same line
else if point2 is between a[i + n] and a[i + n + 1]
then if point2 is at a[i + n] + (a[i] - point1) + n + 1 its in a strait line right above it
else if point2 is at a[i + n] + (a[i] - point1) + n - 1 its in a strait line left above it
if for all points n or n*(-1) is equal the distance between the points is equal.
That is if I didn't make any logical errors and you probably have to check more for it to work properly.
This is more a mathematical question than lua I recommend adding a math tag to it.