Spritekit Swift particle SKEmitterNode add remove - xcode

so this is nice for create a particle, but whats the right way to remove it , after the duration, sparkEmmiter.particleLifetime do not remove it automatically
let sparkEmmiter = SKEmitterNode(fileNamed: "MyParticle.sks")
sparkEmmiter.position = CGPointMake(self.frame.size.width/2, self.frame.size.height/2 - 200)
sparkEmmiter.name = "sparkEmmitter"
sparkEmmiter.zPosition = 1
sparkEmmiter.targetNode = self
sparkEmmiter.particleLifetime = 1
self.addChild(sparkEmmiter)
this solutions produce simulator crash
var re = SKAction.waitForDuration(1)
var remove = SKAction.removeFromParent()
var seq = SKAction.sequence([re , remove])
sparkEmmiter.runAction(seq)

Related

Script to Align Text layer to center of another reference layer

The contents to the text layer are added from csv import. Some are short length and some are long, contain 2 words and take up 2 lines in the layer. What I need is after the content is added, the layer should be horizontally and vertically aligned to another layer. I want to do this alignment using a script.
var doc = app.activeDocument;
var grps = doc.layerSets;
var pnamegrp = grps.getByName('Group 1');
var childlyr = pnamegrp.layers.getByName('child');
childlyr.textItem.contents = pname; //come from a csv file
var parentlyr= pnamegrp.layers.getByName('ReferenceRectangle');
Align_HorizCenter_VerticalCenter_withreference( childlyr , parent);
function Align_HorizCenter_VerticalCenter_withreference( child, parent){
//need help to write this
}
I am using Photoshop cc 2015 and JavaScript jsx file scripting.
Just incase somebody is looking for a solution. Translate is the method to move layer. The number of pixels to be moved can be determined by the difference in the width between the target and reference layer.
var startRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.INCHES;
var doc = app.activeDocument;
var grps = doc.layerSets;
var pnamegrp = grps.getByName('Group 1');
var pnamelyr= pnamegrp.layers.getByName('pname'); //target
var pnameREF = pnamegrp.layers.getByName('Rectangle 1'); //reference var LB = pnameREF.bounds;
var RWidth = (LB[2].value) - (LB[0].value);
var RHeight = (LB[3].value) - (LB[1].value);
pnamelyr.textItem.contents = pnamearr[i];
LB = pnamelyr.bounds;
TWidth = (LB[2].value) - (LB[0].value);
THeight = (LB[3].value) - (LB[1].value);
var OffsetX = (RWidth - TWidth)/2;
var OffsetY = (RHeight - THeight)/2;
pnameTGT.translate(OffsetX,OffsetY); //move layer by offset pixels from the current position

How would I get my background image to repeat forever in Swift?

I have these two images that are the same image and I want them to repeat so it looks like the background is moving. I have this code but only one of the background images goes through then it goes back to the grey screen. The other background image doesn't follow the first one. How do I fix that? Thanks! (This is in swift xcode)
func spawnBackground() {
let cloud = SKSpriteNode(imageNamed: "CloudBg")
let cloud2 = SKSpriteNode(imageNamed: "CloudBg2")
cloud.position = CGPointMake(frame.size.width + cloud.frame.size.width / 2,cloud.frame.height / 2)
cloud.setScale(1.35)
cloud.zPosition = -15
cloud2.position = CGPointMake(self.size.width/2, self.size.height/2)
cloud2.setScale(1.35)
cloud.zPosition = -15
let moveTop = SKAction.moveByX(0, y: cloud.size.height, duration: NSTimeInterval(CGFloat(gameSpeed) * cloud.size.height))
cloud.runAction(SKAction.repeatActionForever(moveTop))
cloud2.runAction(SKAction.repeatActionForever(moveTop))
addChild(cloud)
addChild(cloud2)
}
I think you are looking for an action sequence like this:
let cloud = SKSpriteNode(imageNamed: "CloudBg")
let cloud2 = SKSpriteNode(imageNamed: "CloudBg2")
cloud.position = CGPointMake(frame.size.width + cloud.frame.size.width / 2,cloud.frame.height / 2)
cloud.setScale(1.35)
cloud.zPosition = -15
cloud2.position = CGPointMake(self.size.width/2, self.size.height/2)
cloud2.setScale(1.35)
cloud.zPosition = -15
var actionone = SKAction.moveToX(0, y: cloud.size.height, duration: NSTimeInterval(CGFloat(gameSpeed) * cloud.size.height))
var actiontwo = SKAction.runBlock({
cloud.position = CGPointMake(frame.size.width + cloud.frame.size.width / 2,cloud.frame.height / 2)
})
cloud.runAction(SKAction.repeatForever(SKAction.sequence([actionone,actiontwo])))
Of course you will have to edit this code to work where when one cloud reaches a certain point the other one begins, but that is the general idea.

Creating UI element won't let change position

I tried this:
#IBAction func test(sender : AnyObject){
let height:CGFloat = 44
var tableFrame:CGRect = tableView.frame;
var fieldFrame = CGRect()
fieldFrame.origin = tableFrame.origin
fieldFrame.size.height = height
fieldFrame.size.width = tableFrame.size.width
var textField = UITextField(frame: fieldFrame)
textField.backgroundColor = UIColor(white: 0, alpha: 1)
view.addSubview(textField)
tableFrame.size.height = tableFrame.size.height - height
tableFrame.origin.y = tableFrame.origin.y + height
tableView.frame = tableFrame
}
When running, black field appears, but table won't move nor change size. Removing line
view.addSubview(textField)
allows table to change size and move, but, obviously, no field appears. What is the problem?
your textfield is actually on top of tableview. Your touch actions are probably going to the text fieldview and not to the tableview

AS3 SharedObject - Background images fails to load correctly. Set of images stored inside MC fails to load correct image from save

having issues with making a set of background images save and load correctly. Please note, that this has worked correctly in the past with "1 - 2" images in the caseSwapper.
Structure :
On my stage I have set of draggable objects that you can save and load as you please. (these work)
The background, which is movieClip called "caseSwapper" contains a set of frames with different images inside each frame. E.G frame one is called (labelled) "frameone" - contains a pretty picture. Frame 2 is labelled "Frametwo" which contains an alternative image etc etc
A load and save button on the stage allows you to store the data to sharedObject "mySO"
Issues and Behaviour
On the face of it, the save appears to be working. The trace statement is declaring that the current frame is being stored to mySO... although I'm not entirely convinced it is. Basically, when the player has a certain background selected and they click 'save' I need the current image to be saved/written to the sharedObject.
Notes : Frame 1 appears to work when I click 'load' from the stage. When I 'launch' the application (not load) even after saving frame 123 or 4 only frame 4 launches/dis[lays. I then have to click load to retrieve my sharedObject... which only shows the first frame... Any pointers. Script to edit is at the bottom. Please Note, that I'm designer first and foremost!
save_btn.addEventListener (MouseEvent.CLICK, clickersave);
function clickersave (e:MouseEvent):void {
saved.play();
mySO.data.myblcskull_mc_x = blcskull_mc.x;
mySO.data.myblcskull_mc_y = blcskull_mc.y;
mySO.data.myblackhandbag_mc_y = blackhandbag_mc.y;
mySO.data.myblackhandbag_mc_x = blackhandbag_mc.x;
mySO.data.myhotlips_mc_x = hotlips_mc.x;
mySO.data.myhotlips_mc_y = hotlips_mc.y;
mySO.data.my_x = bones_mc.x;
mySO.data.my_y = bones_mc.y;
mySO.data.mybut_x = btrfly_mc.x;
mySO.data.mybut_y = btrfly_mc.y;
mySO.data.mytig_x = tiger_mc.x;
mySO.data.mytig_y = tiger_mc.y;
mySO.data.myskullface_mc_y = skullface_mc.y;
mySO.data.myskullface_mc_x = skullface_mc.x;
mySO.data.myblack_tile_mc_zero_y = black_tile_mc_zero.y;
mySO.data.myblack_tile_mc_zero_x = black_tile_mc_zero.x;
mySO.data.myblack_tile_mc_one_x = black_tile_mc_one.x;
mySO.data.myblack_tile_mc_one_y = black_tile_mc_one.y;
mySO.data.mycrown_mc_y = crown_mc.y;
mySO.data.mycrown_mc_x = crown_mc.x;
mySO.data.myperfume_mc_y = perfume_mc.y;
mySO.data.myperfume_mc_x = perfume_mc.x;
mySO.data.myheart_mc_x = heart_mc.x;
mySO.data.myheart_mc_y = heart_mc.y;
mySO.data.myrose_mc_y = rose_mc.y;
mySO.data.myrose_mc_x = rose_mc.x;
// tears saved - - - - - - -
mySO.data.mytear_drop_mc_one_x = tear_drop_mc_one.x;
mySO.data.mytear_drop_mc_one_y = tear_drop_mc_one.y;
mySO.data.mytearup_drop_mc_three_x = tearup_drop_mc_three.x;
mySO.data.mytearup_drop_mc_three_y = tearup_drop_mc_three.y;
mySO.data.mytearup_drop_mc_four_x = tearup_drop_mc_four.x;
mySO.data.mytearup_drop_mc_four_y = tearup_drop_mc_four.y;
mySO.data.mytear_drop_mc_two_x = tear_drop_mc.x;
mySO.data.mytear_drop_mc_two_y = tear_drop_mc.y;
mySO.data.mytear_side_mc_one_x = tear_side_mc_one.x;
mySO.data.mytear_side_mc_one_y = tear_side_mc_one.y;
mySO.data.mytear_side_mc_two_x = tear_side_mc_two.x;
mySO.data.mytear_side_mc_two_y = tear_side_mc_two.y;
mySO.data.mytear_op_mc_one_y = tear_op_mc_one.y;
mySO.data.mytear_op_mc_one_x = tear_op_mc_one.x;
mySO.data.mytear_op_mc_two_y = tear_op_mc_two.y;
mySO.data.mytear_op_mc_two_x = tear_op_mc_two.x;
//tear_op_mc_one
// pink gems
mySO.data.mypink_jewel_mc_one_x = pink_jewel_mc_one.x;
mySO.data.mypink_jewel_mc_one_y = pink_jewel_mc_one.y;
mySO.data.mypink_jewel_mc_two_x = pink_jewel_mc_two.x;
mySO.data.mypink_jewel_mc_two_y = pink_jewel_mc_two.y;
mySO.data.mypink_jewel_mc_three_x = pink_jewel_mc_three.x;
mySO.data.mypink_jewel_mc_three_y = pink_jewel_mc_three.y;
mySO.data.mypink_jewel_mc_four_x = pink_jewel_mc_four.x;
mySO.data.mypink_jewel_mc_four_y = pink_jewel_mc_four.y;
mySO.data.mypink_jewel_mc_five_x = pink_jewel_mc_five.x;
mySO.data.mypink_jewel_mc_five_y = pink_jewel_mc_five.y;
mySO.data.mypink_jewel_mc_six_x = pink_jewel_mc_six.x;
mySO.data.mypink_jewel_mc_six_y = pink_jewel_mc_six.y;
mySO.data.mypink_jewel_mc_seven_x = pink_jewel_mc_seven.x;
mySO.data.mypink_jewel_mc_seven_y = pink_jewel_mc_seven.y;
mySO.data.mypink_jewel_mc_eight_x = pink_jewel_mc_eight.x;
mySO.data.mypink_jewel_mc_eight_y = pink_jewel_mc_eight.y;
mySO.data.mypink_jewel_mc_nine_x = pink_jewel_mc_nine.x;
mySO.data.mypink_jewel_mc_nine_y = pink_jewel_mc_nine.y;
// bg saves
mySO.data.myBgFrame = 1;
mySO.data.myBgFrameone = 2;
mySO.data.myBgFrametwo = 3;
mySO.data.myBgFramethree = 4;
trace("bgbackgrounds");
// silver gems - - - - - - - - -
mySO.data.mycircle_gem_mc_x = circle_gem_mc.x;
mySO.data.mycircle_gem_mc_y = circle_gem_mc.y;
mySO.data.mycircle_gem_mc_two_x = circle_gem_mc_two.x;
mySO.data.mycircle_gem_mc_two_y = circle_gem_mc_two.y;
mySO.data.mycircle_gem_mc_thirteen_x = circle_gem_mc_thirteen.x;
mySO.data.mycircle_gem_mc_thirteen_y = circle_gem_mc_thirteen.y;
//circle_gem_mc_six
mySO.flush ();
}
if (mySO.data.myBgFrame){
caseSwapper.gotoAndStop(mySO.data.myBgFrame);
}
if (mySO.data.myBgFrameone){
caseSwapper.gotoAndStop(mySO.data.myBgFrameone);
}
if (mySO.data.myBgFrametwo){
caseSwapper.gotoAndStop(mySO.data.myBgFrametwo);
}
if (mySO.data.myBgFramethree){
caseSwapper.gotoAndStop(mySO.data.myBgFramethree);
}
//caseSwapper.currentFrame = mySO.data.myBgFrame;
/////// ---------------------- loader
// ---------------------- LOADER -------------------------
//--------------------------------------------------------
//--------------------------------------------------------
// when load button is clicked it loads the x and y position of dragged objects pulled from the
//sharedOject, it remembers the last var!
load_btn.addEventListener (MouseEvent.CLICK, loadlast);
function loadlast (e:MouseEvent):void {
//saved.play();
caseSwapper.gotoAndStop(mySO.data.myBgFrame);
//caseSwapper.currentFrame = mySO.data.myBgFrame;
//caseSwapper.gotoAndStop(mySO.data.myBgFrameone);
//caseSwapper.gotoAndStop(mySO.data.myBgFrametwo);
//caseSwapper.gotoAndStop(mySO.data.myBgFramethree);
//caseSwapper.gotoAndStop(mySO.data.myBgFramefour);
blcskull_mc.x = mySO.data.myblcskull_mc_x;
blcskull_mc.y = mySO.data.myblcskull_mc_y;
blackhandbag_mc.y = mySO.data.myblackhandbag_mc_y;
blackhandbag_mc.x = mySO.data.myblackhandbag_mc_x;
bones_mc.x = mySO.data.my_x;
bones_mc.y = mySO.data.my_y;
tiger_mc.x = mySO.data.mytig_x;
tiger_mc.y = mySO.data.mytig_y;
btrfly_mc.x = mySO.data.mybut_x;
btrfly_mc.y = mySO.data.mybut_y;
crown_mc.x = mySO.data.mycrown_mc_x;
crown_mc.y = mySO.data.mycrown_mc_y;
perfume_mc.x = mySO.data.myperfume_mc_x;
perfume_mc.y = mySO.data.myperfume_mc_y;
heart_mc.x = mySO.data.myheart_mc_x;
heart_mc.y = mySO.data.myheart_mc_y;
rose_mc.y = mySO.data.myrose_mc_y;
rose_mc.x = mySO.data.myrose_mc_x;
pink_jewel_mc_one.x = mySO.data.mypink_jewel_mc_one_x;
pink_jewel_mc_one.y = mySO.data.mypink_jewel_mc_one_y;
pink_jewel_mc_two.x = mySO.data.mypink_jewel_mc_two_x;
pink_jewel_mc_two.y = mySO.data.mypink_jewel_mc_two_y;
pink_jewel_mc_three.x = mySO.data.mypink_jewel_mc_three_x;
pink_jewel_mc_three.y = mySO.data.mypink_jewel_mc_three_y;
pink_jewel_mc_four.x = mySO.data.mypink_jewel_mc_four_x;
pink_jewel_mc_four.y = mySO.data.mypink_jewel_mc_four_y;
pink_jewel_mc_five.x = mySO.data.mypink_jewel_mc_five_x;
pink_jewel_mc_five.y = mySO.data.mypink_jewel_mc_five_y;
pink_jewel_mc_six.x = mySO.data.mypink_jewel_mc_six_x;
pink_jewel_mc_six.y = mySO.data.mypink_jewel_mc_six_y;
pink_jewel_mc_seven.x = mySO.data.mypink_jewel_mc_seven_x;
pink_jewel_mc_seven.y = mySO.data.mypink_jewel_mc_seven_y;
pink_jewel_mc_eight.x = mySO.data.mypink_jewel_mc_eight_x;
pink_jewel_mc_eight.y = mySO.data.mypink_jewel_mc_eight_y;
pink_jewel_mc_nine.x = mySO.data.mypink_jewel_mc_nine_x;
pink_jewel_mc_nine.y = mySO.data.mypink_jewel_mc_nine_y;
hotlips_mc.x = mySO.data.myhotlips_mc_x;
hotlips_mc.y = mySO.data.myhotlips_mc_y;
tearup_drop_mc_three.y = mySO.data.mytearup_drop_mc_three_y;
tearup_drop_mc_three.x = mySO.data.mytearup_drop_mc_three_x;
tearup_drop_mc_four.x = mySO.data.mytearup_drop_mc_four_x;
tearup_drop_mc_four.y = mySO.data.mytearup_drop_mc_four_y;
tear_side_mc_one.x = mySO.data.mytear_side_mc_one_x;
tear_side_mc_one.y = mySO.data.mytear_side_mc_one_y;
//tear_side_mc_two.x = mySO.data.mytear_side_mc_two_x;
//tear_side_mc_two.y = mySO.data.mytear_side_mc_two_y;
tear_op_mc_one.y = mySO.data.mytear_op_mc_one_y;
tear_op_mc_one.x = mySO.data.mytear_op_mc_one_x;
tear_op_mc_two.y = mySO.data.mytear_op_mc_two_y;
tear_op_mc_two.x = mySO.data.mytear_op_mc_two_x;
//--- silver little gems -----------------
circle_gem_mc_thirteen.x = mySO.data.mycircle_gem_mc_thirteen_x;
circle_gem_mc_thirteen.y = mySO.data.mycircle_gem_mc_thirteen_y;
circle_gem_mc_two.x = mySO.data.mycircle_circle_gem_mc_two_x;
circle_gem_mc_two.y = mySO.data.mycircle_circle_gem_mc_two_y;
mySO.flush ();
}
You're not actually storing the current frame anywhere — this section just saves the same numbers every time:
mySO.data.myBgFrame = 1;
mySO.data.myBgFrameone = 2;
mySO.data.myBgFrametwo = 3;
mySO.data.myBgFramethree = 4;
This is also why you're only seeing frame four when you launch, because all of your if statements see a positive number (and anything other than zero or NaN counts as true), so they all get executed one after the other.
Instead of the above, all you need is this in your save function:
mySO.data.myBgFrame = caseSwapper.currentFrame;
Then if you want to jump to that frame on launch, you only need your first if statement:
if (mySO.data.myBgFrame){
caseSwapper.gotoAndStop(mySO.data.myBgFrame);
}

Windows Forms chart with two aligned/overlapping areas don't use the entire control

A chart on a form I created has two overlapping areas. The overlapping part works just fine. The problem is that visible graph only takes up half the height of the chart control:
The bottom half of the control is left empty (presumably because that's where the second area would have gone were the two areas not aligned?). I can't figure out how to get the chart to use the entire control. The code is below:
chart1.Dock = DockStyle.Fill;
chart1.Legends.Add(new Legend { Name = "Legend1" });
chart1.Location = new Point(435, 3);
chart1.Name = "chart1";
chart1.Size = new Size(426, 287);
chart1.TabIndex = 2;
chart1.Text = "chart1";
var firstArea = chart1.ChartAreas.Add("First Area");
var seriesFirst = chart1.Series.Add("First Series");
seriesFirst.ChartType = SeriesChartType.Line;
seriesFirst.Points.Add(new DataPoint(10, 55));
seriesFirst.Points.Add(new DataPoint(11, 56));
seriesFirst.Points.Add(new DataPoint(12, 59));
var secondArea = chart1.ChartAreas.Add("Second Area");
secondArea.BackColor = Color.Transparent;
secondArea.AlignmentOrientation = AreaAlignmentOrientations.All;
secondArea.AlignmentStyle = AreaAlignmentStyles.All;
secondArea.AlignWithChartArea = firstArea.Name;
secondArea.AxisY.LabelStyle.Enabled = false;
secondArea.AxisX.LabelStyle.Enabled = false;
var seriesSecond = chart1.Series.Add("Second Series");
seriesSecond.ChartType = SeriesChartType.Line;
seriesSecond.ChartArea = secondArea.Name;
seriesSecond.Points.Add(new DataPoint(10, 1001));
seriesSecond.Points.Add(new DataPoint(11, 1015));
seriesSecond.Points.Add(new DataPoint(12, 1016));
This is some old code I've dug out and modified to suit your example. The problem is the InnerPlotPosition.Auto and Position.Auto status of the ChartAreas, thats why after you add the second chart the first charts auto position jumps up and then the second chart aligns with the new InnerPlotPosition.Auto values.
You can try turning this off but I think its easier to just position the first chart manually and then allow the second to align with the new manual position. It produces the below image (minus your legend you can work the values needed yourself)
Bit of pain in the ass solution but hopefully it helps
Dim chart1 As New Chart
Me.Controls.Add(chart1)
chart1.Location = New Point(435, 3)
chart1.Name = "chart1"
chart1.Size = New Size(426, 287)
chart1.TabIndex = 2
chart1.Text = "chart1"
Dim firstArea As ChartArea = chart1.ChartAreas.Add("First Area")
Dim seriesFirst = chart1.Series.Add("First Series")
seriesFirst.ChartType = SeriesChartType.Line
seriesFirst.Points.Add(New DataPoint(10, 55))
seriesFirst.Points.Add(New DataPoint(11, 56))
seriesFirst.Points.Add(New DataPoint(12, 59))
Dim secondArea As ChartArea = chart1.ChartAreas.Add("Second Area")
secondArea.BackColor = Color.Transparent
secondArea.AlignmentOrientation = AreaAlignmentOrientations.All
secondArea.AlignmentStyle = AreaAlignmentStyles.All
secondArea.AlignWithChartArea = firstArea.Name
secondArea.AxisY.LabelStyle.Enabled = False
secondArea.AxisX.LabelStyle.Enabled = False
Dim seriesSecond = chart1.Series.Add("Second Series")
seriesSecond.ChartType = SeriesChartType.Line
seriesSecond.ChartArea = secondArea.Name
seriesSecond.Points.Add(New DataPoint(10, 1001))
seriesSecond.Points.Add(New DataPoint(11, 1015))
seriesSecond.Points.Add(New DataPoint(12, 1016))
' *** Set locational values here for your first chart***
Dim heightAboveChartArea As Integer = 20
Dim heightBelowChartArea As Integer = 20
Dim axisLabelHeight As Integer = 40
Dim widthLeftOfChartArea As Integer = 20
Dim widthRightOfChartArea As Integer = 20
Dim heightPerBar As Integer = 20
Dim numberOfPoints As Integer = chart1.Series(0).Points.Count
' *** The following code should not normally be modified ***
chart1.Height = heightAboveChartArea + heightBelowChartArea + axisLabelHeight + (numberOfPoints * heightPerBar)
chart1.ChartAreas(0).Position.X = widthLeftOfChartArea / chart1.Width * 100
chart1.ChartAreas(0).Position.Width = 100 - (widthRightOfChartArea / chart1.Width * 100) - chart1.ChartAreas(0).Position.X
chart1.ChartAreas(0).Position.Y = (heightAboveChartArea / chart1.Height * 100)
chart1.ChartAreas(0).Position.Height = 100 - (heightBelowChartArea / chart1.Height * 100) - chart1.ChartAreas(0).Position.Y
I thought about monkeying with the position, but I'd have to take into account borders and the legend and other chart components and assumed I'd never get it as good as the auto-positioning provided by the chart - and it would drive me nuts. However, the suggestion by TylerDurden led me to the idea of simply delaying the addition of the second series/area until after the chart had rendered at least once and had calculated the position. This turned out to be non-trivial, since for most of the chart's initialization the X, Y, Height and Width are still zero. The best way I found was to add the second series in the Form's Shown event:
private void OnShown(object sender, EventArgs eventArgs)
{
Application.DoEvents();
var f = chart1.ChartAreas[0].Position.ToRectangleF();
chart1.ChartAreas[0].Position.Auto = false;
chart1.ChartAreas[0].Position.X = f.X;
chart1.ChartAreas[0].Position.Y = f.Y;
chart1.ChartAreas[0].Position.Height = f.Height;
chart1.ChartAreas[0].Position.Width = f.Width;
// add second area/series here
The call to Application.DoEvents() is required to force the chart to render and calculate the Position. Since Position is a percentage, both chart areas will always occupy the full height and width of the parent Chart.

Resources