animate rect color change - lua

Hey guys just wondering how I can make a smooth transition of a rects change in colour? So for example I have a basic grey rect background which I turn red, the problem is that the change in colour is instant. How can i do it so its a gradual change over seconds?
Here is my quick example. Cheers
local myRectangle = display.newRect(0, 0, 480, 320)
myRectangle.strokeWidth = 3
myRectangle:setFillColor(140, 140, 140)
local function changeColor()
myRectangle:setFillColor(240, 140, 140)
end
timer.performWithDelay(2500, changeColor)

If you need transition, basically, you really can't do this with transition.to . You can do it with the help of an enterFrame listener and increment values for your R, G and B on each call.
Otherwise there is a sample code/library posted by atoko in corona forum. I haven't tried that personally, but you can check it here: http://developer.coronalabs.com/code/color-transition-wrapper
Keep Coding............ :)

Related

SKSpriteNode not responding to set color & blendModeFactor (SpriteKit & Swift)

I know there are several other posts about this, but my case is kinda specific, i haven't seen this one yet.
I have in my game a ball-shaped sprite, that whenever I tap on it, I would like to add a colorised version of the very same sprite but with an effect of fadeIn and fadeOut.
Going to give you an example code:
self.ball = SKSpriteNode(imageNamed: "ball")
self.ball.position = CGPoint(x: midX, y: midY)
self.ball.zPosition = 1
self.ball.size = CGSize(width: 100, height: 100)
self.touchEffect = SKSpriteNode(imageNamed: "ball")
self.touchEffect.position = CGPoint(x: 0, y: 0)
self.touchEffect.zPosition = 2
self.touchEffect.size = CGSize(width: 100, height: 100)
self.touchEffect.color = UIColor.whiteColor()
self.touchEffect.blendColorFactor = 1
self.touchEffect.alpha = 0
self.ball.addChild(self.touchEffect)
self.addChild(self.ball)
Now, up to this point... I can't even see the touchEffect sprite colorised (if I put alpha to 1), but the same color of the original sprite. Why is this?
At the touchesBegan I do something like this:
func showTapEffect() {
let fadeIn = SKAction.fadeInWithDuration(0.3)
let fadeOut = SKAction.fadeOutWithDuration(0.3)
let sequence = SKAction.sequence([fadeIn,fadeOut])
self.touchEffect.runAction(sequence)
}
I also used it in different scenarios within my very same game, and it worked. Don't know why this unique case doesn't. Any hint? If you need more example code, let me know, is not a copy paste of my current code tho, I just typed it from my memory so you might see a typo error in there. But the code is very alike.
(And my sprite isn't dark or black)
Thanks in advance.
I am posting this an an answer because it is too large for comments, and I can post code in here if need be.
I just reread your thing like 3 times over, You are blending with White, what color are you expecting to get? if you blend Blue and White, you get Blue, if you blend Purple and Blue, You would get Blue. If you blend Blue and Gray, you get a darker Blue. It is all percentage multiplication. I do not believe you get a blend mode to pick from with colors. How it works is it takes the color of each pixel, and on the pixel, breaks it up into R,G,B, then it takes your color, and breaks that up into R G B (lets call it CR CG CB). The math becomes (R * CR,G * CG,B * CB) on a per pixel level.
You are doing (R * 1,G * 1,B * 1) which is (R,G,B)
If you want to colorize your sprite, then you need your sprite to be a gray scale image, and use colors only when you want them to stay that color (To a degree, because blending will still apply to them, you need to figure out the math on how you want it to blend)

SpriteKit - Basic Positioning of a label in a background

Very new to Sprite Kit and i'm doing some reading now, but wanted to ask about something that I haven't found the best answer to yet.
I'm doing a tutorial with some code that creates a background, and then adds a label to show a score. I started changing the label code to position it on the top-left corner of the screen.
Here is the code (with my edits to the label, gameLabel):
let screenSize = UIScreen.mainScreen().bounds
let screenWidth = screenSize.width
let screenHeight = screenSize.height
let background = SKSpriteNode(imageNamed: "background")
background.position = CGPoint(x: screenWidth / 10, y: (screenHeight / 15) - 100)
background.blendMode = .Replace
background.zPosition = -1
addChild(background)
gameScore = SKLabelNode(fontNamed: "Chalkduster")
gameScore.text = "Score: 0"
gameScore.position = CGPoint(x: screenWidth / 10, y: (screenHeight / 15) - 100)
gameScore.horizontalAlignmentMode = .Left
gameScore.verticalAlignmentMode = .Top
gameScore.fontSize = 48
addChild(gameScore)
So the label is not displaying in any case, and my assumption is this:
Because i'm adding the background first, the label is getting added within the confines of the background, therefore it needs to be positioned differently, perhaps using the label size instead of the screen size?
My questions:
How can I get the label to always appear in the top left?
The author chose a hard-coded CGPoint for this background image and then said it has to be on an iPad, but i'd like to do it for iPhone 6/plus in landscape as well as iPad. Is there a way I can just make it work on both devices without having to specify a CGPoint like that? Can't it just scale and work regardless?
Thanks and apologies if these are basic questions - i'm going to do my best to continue reading on the subject..
Your question has a simple answer to it. You have forgotten and missed out somethings in your code, and I can show you these things.
In your code you set the background ZPosition to -1, the smallest number will always appear at the back. So if you set the SKLabelNode to a bigger zPosition it will always appear at the front, as maybe there may be a problem with rendering, as I have also experience like these, I fix it this way:
Before you add the LabelNode set it's property to this:
gamescore.zPosition = 0
0, In this case could just be anything bigger than the backgrounds(or the node that you want to appear at the back). So this just tells the compiler that you want the LabelNode to appear at the front, or in front of the Background.
If you want to make a universal app or game, with SpriteKit you will need to add some extra code to your game or app. Since I think that it is better to give you a good tutorial to show you instead of showing you some basics, I will give you a good link on how to do this:
SpriteKit: how to make a universal app
I hope this helps, and don't worry this took me some time to figure out my self.

SpriteKit fast fullscreen vignette / lighting with alpha blending

I am making a platforming game with SpriteKit. I want to achieve the effect that only the area around the player is lit and everything else fades into darkness. Imagine something like a fake light source or a strong vignette. For testing purpose I created the following code:
let effect = SKEffectNode()
effect.zPosition = 100
effect.position = CGPoint(x: 0, y: 0)
effect.shouldRasterize = false
effect.blendMode = SKBlendMode.Multiply
let gray = SKSpriteNode()
gray.color = SKColor.grayColor()
gray.size = self.frame.size
gray.blendMode = SKBlendMode.Multiply
gray.position = CGPoint(x: 0, y: 0)
let shine = SKSpriteNode(imageNamed: "Shine")
shine.position = CGPoint(x: 0, y: 0)
shine.blendMode = SKBlendMode.Screen
shine.setScale(3.0)
effect.addChild(gray)
effect.addChild(shine)
self.world.addChild(effect)
This works as desired but has a somewhat significant impact on the frame rate. Considering that there might be additional effects like these from e. g. torches or other light sources on the map, I expect the frame rate to drop even more.
Next, I wanted to make the light flicker, so I assigned a random alpha value to the shine sprite in the update function. This really killed the frame rate, letting it drop instantly to about 4 frames.
I have read about SKEffectNodes and their heavy impact on the frame rate. Is there any other way to achieve this sort of fullscreen alpha blending, that is reasonably fast, even with multiple "lights"?
Any advice is truly appreciated.
Could this be solved with a SKLightNode perhaps?
https://developer.apple.com/library/prerelease/ios/documentation/SpriteKit/Reference/SKLightNode_Ref/index.html
Here's an article about how to use the SKLightNode:
http://www.ymc.ch/en/playing-with-ios-8-sprite-kit-and-sklightnode
Hope that's of any usage to you

Swift SpriteKit Health Bar

I want to add a Health Bar (a progressing Bar) in my Scene.
It's a rectangle bar filled with a color, on the upper left in the Scene, and every second the bar decreases (the filled color). After 2 Objects (SKSpriteNode's) hit each other, it gives you + 5 seconds time.
Thanks to LearnCocos2D and CloakedEddy, I know that I can make the Bar by using simply SKSpriteNode with Color or SKCropNode instead of SKShapeNode.
How should I implement it now at best to decrease itself every second smoothly?
My Code:
....
var progressValue = 200
....
HealthBar = SKSpriteNode(color:SKColor .yellowColor(), size: CGSize(width: progressValue, height: 30))
HealthBar.position = CGPointMake(self.frame.size.width / 3, self.frame.size.height / 1.05)
HealthBar.anchorPoint = CGPointMake(0.0, 0.5)
HealthBar.zPosition = 4
self.addChild(HealthBar)
What you could do is have a SKSpriteNode be the health bar. Then you have a SKSpriteNode as a frame over the first node. You have an action SKAction.repeatForever(SKAction.sequence([SKAction.moveByX(moveAmount, y: 0, duration: 0.5), SKAction.waitForDuration(0.5)])) and make the health bar (not the frame) run that action. What that will do is move the health bar off the screen, making it look like its going down.
About the collision problem, look at this tutorial. If that doesn't help, maybe you could find others. I want to help with this one, but collision detection is fairly in-depth even with SpriteKit. I hope this helped. Good Luck!

Change icon color by means of awesome wm

In awesome wm 3.5 you can create custom widgets using cairo to draw its visual. I want a widget which displays monochrome PNG icon (like wibox.widget.imagebox do it) and allows quickly change its color. I tried modify several lines in draw function of wibox.widget.imagebox
local cairo = require("lgi").cairo
--- Draw an imagebox with the given cairo context in the given geometry.
function imagebox:draw(wibox, cr, width, height)
if not self._image then return end
if width == 0 or height == 0 then return end
cr:save()
if not self.resize_forbidden then
-- Let's scale the image so that it fits into (width, height)
local w = self._image:get_width()
local h = self._image:get_height()
local aspect = width / w
local aspect_h = height / h
if aspect > aspect_h then aspect = aspect_h end
cr:scale(aspect, aspect)
end
-- Here is my modifications
cr:set_source_surface(self._image, 0, 0)
cr:paint()
cr:set_operator(cairo.Operator.IN)
cr:set_source_rgba(0, 0, 1, 0.5)
cr:paint()
-- End of my my modifications
-- This is original draw code how it was
--cr:set_source_surface(self._image, 0, 0)
--cr:paint()
cr:restore()
end
But it doesn't work. I tried set several other cairo's compositing operators and most of them works not as expected. Wrong overlapping areas and black regions instead of wibox background color. SOURCE and OVER are only works right. Where did I make mistake?
The mistake is your understanding of cairo's drawing methods. Black/transparent is just what IN leaves behind in the places that it did not touch. In other words, you are first drawing something else over the background and thus the background is lost.
Try this instead:
local pat = require("lgi").cairo.Pattern
cr:set_source_rgba(0, 0, 1, 0.5)
cr:mask(pat.create_for_surface(self._image), 0, 0)

Resources