Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat | DONATE
How to achieve this effect? — Gideros Forum

How to achieve this effect?

rrraptorrrraptor Member
edited March 2020 in General questions
I need to achieve a wrap effect on a line like this:


It kinda works, BUT only if there is 4 columns and tile size is 64. For other values it brakes :(

local W = 4 -- amount of columns
local TILE = 64 -- tile size
stage:setX(TILE)
 
local layer = Sprite.new()
stage:addChild(layer)
math.randomseed(0)
 
for i = 1, W do 
	local px = Pixel.new(math.random(0xffffff), 1, TILE, TILE)
	px:setX((i - 1) * TILE)
	layer:addChild(px)
end
 
local oldX = 0
local rt = RenderTarget.new(W * TILE, TILE, true, true)
local btm = Pixel.new(rt, W * TILE, TILE)
btm:setY(TILE * 2.5)
layer:addChild(btm)
 
stage:addEventListener("mouseDown", function(e)
	oldX = e.x
 
	rt:draw(layer)
end)
 
stage:addEventListener("mouseMove", function(e)
	local dx = e.x - oldX
 
	local x = btm:getTexturePosition()
	btm:setTexturePosition(x + dx, 0)
 
	oldX = e.x
end)


I guess it breaks because of RenderTarget's size (which is power of 2 number).

Comments

  • I can't test your code right now, but may I suggest something?
    From hgy29 space shooter tutorial on the wiki: https://wiki.giderosmobile.com/index.php/2D_Space_Shooter_Part_2:_Background
    he uses a texture with wrap:
    local far=Texture.new("gfx/star_far.jpg",true, { wrap=TextureBase.REPEAT })
    then in the game loop:
    self:setTexturePosition(0,self.position/3)

    You can try to save your generated pixels to a texture then use it like hgy29 did. This will work for any size :)
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
  • rrraptorrrraptor Member
    edited March 2020
    @MoKaLux that is exactly what I did with RenderTarget. 4th argument is repeat flag.
    I kinda find the solution, but it requires to set width of RT to power of 2 number and then calculate proper tile size.
    So that works:
    local W = 9 -- amount of columns
    local TILE = 512/W -- tile size
    ...
    local rt = RenderTarget.new(512, TILE, true, true)
    But I dont like that width must be 512 px...
  • MoKaLuxMoKaLux Member
    edited March 2020
    MoKaLux said:

    You can try to save your generated pixels to a texture then use it like hgy29 did. This will work for any size :)

    I mean save the rt to a file in |D| or |T| and then use it as a texture.
    RenderTarget:save(filename,x,y,width,height)
    my growING GIDEROS github repositories: https://github.com/mokalux?tab=repositories
  • hgy29hgy29 Maintainer
    With textures you are indeed limited to POT textures when repeating. Another technique is to use a viewport to your first sprite and place it next to the original sprite. Then slide the parent sprite modulo the size if the original sprite. You’ll have to clip the parent sprite to the size of your view too.
  • rrraptorrrraptor Member
    edited March 2020
    hgy29 said:

    With textures you are indeed limited to POT textures when repeating. Another technique is to use a viewport to your first sprite and place it next to the original sprite. Then slide the parent sprite modulo the size if the original sprite. You’ll have to clip the parent sprite to the size of your view too.

    Well, I dont need to wrap the order. It must be always 1.. N.
    Anyways, I have managed to do this thing :) I added 2 extra tiles on each side.
    But I have strange problem xD Colors are different.


    local W = 4 -- amount of columns
    local TILE = 128 -- tile size
    stage:addChild(Pixel.new(0,0.1,W * TILE, 2 * TILE))
    stage:setClip(0,0,W * TILE,TILE)
     
    math.randomseed(123)
     
    local t = {}
    local Lextra = Pixel.new(0,1,TILE,TILE)
    local Rextra = Pixel.new(0,1,TILE,TILE)
    stage:setX(TILE)
     
    for i = 1, W do 
    	local px = Pixel.new(math.random(WHITE), 1, TILE, TILE)
    	px:setX((i - 1) * TILE)
    	t[i] = px
    	stage:addChild(px)
    end
     
    stage:addEventListener("mouseDown", function(e)
    	oldX = e.x
    	stage:addChildAt(Lextra,1)
    	stage:addChildAt(Rextra,1)
    end)
     
    stage:addEventListener("mouseMove", function(e)
    	local dx = e.x - oldX
     
    	-- move all pieces
    	for i,v in ipairs(t) do 
    		v:setX(v:getX() + dx)		
    	end
     
    	local first = t[1]
    	local last  = t[W]
    	local offsetLeft = first:getX() + TILE
    	local offsetRight = (W * TILE) - last:getX()
    	if offsetLeft <= 0 then 
    		-- move first element to the end of the array
    		table.insert(t, W, table.remove(t, 1)) 
    		-- update position
    		first:setX((W-1) * TILE + offsetLeft)
    		last = first
    	end
    	if offsetRight <= 0 then 
    		-- move last element to the begining of the array
    		table.insert(t, 1, table.remove(t, W)) 
    		-- update position
    		last:setX(-offsetRight)
    		first = last
    	end
    	Rextra:setColor(first:getColor())
    	Rextra:setX((W-1) * TILE + offsetLeft)
    	Lextra:setColor(last:getColor())
    	Lextra:setX(-offsetRight)
     
    	oldX = e.x
    end)

    wtf.jpg
    396 x 101 - 17K
    wtf.jpg 16.8K
  • Made much more simpler version with viewport :)
    local VisibleW = 5 -- in tiles
    local VisibleH = 1
    local COLUMNS = 5
    local TILE = 32
     
    -- WRAP effect setup
    local content = Sprite.new()
    stage:addChild(content)
     
    local mirror = Viewport.new()
    mirror:setClip(0,0,VisibleW * TILE,VisibleH * TILE)
    mirror:setTransform(Matrix.new(1,0,0,1,-VisibleW * TILE,0))
    mirror:setContent(content)
    stage:addChild(mirror)
    stage:setClip(0,0,VisibleW * TILE,VisibleH * TILE)
     
    -- add content!
    local cont = Sprite.new()
    content:addChild(cont)
    for i = 1, COLUMNS do 
    	local px = Pixel.new(math.random(0xffffff), 1, TILE, TILE)
    	px:setX((i-1) * TILE)
    	cont:addChild(px)
    end
     
    local oldx = 0
    stage:addEventListener("mouseDown", function(e)
    	oldx = e.x
    end)
    stage:addEventListener("mouseMove", function(e)
    	local dx = e.x - oldx
    	cont:setX((cont:getX() + dx) % (VisibleW * TILE))
    	oldx = e.x
    end)

    Likes: hgy29, MoKaLux

    +1 -1 (+2 / -0 )Share on Facebook
Sign In or Register to comment.