UIButton simultaneous clicks action depending count - uibutton

If user clicks 1 and less than 5 times click/press then OneTimeClickAction func should called,
If User simultaneously or consecutively 5 times and less than 10 times click/press then FiveTimeClickAction func should get called
and If User simultaneously or consecutively more than 10 times click/press then tenTimeClickAction func should get called.
{
guard let tempDate = self.lastTappedAt else { return }
let elapsed = Date().timeIntervalSince(tempDate)
let duration = Int(elapsed)
print(duration)
if duration < 2 {
tapCount = tapCount + 1
// return
} else {
tapCount = 0
}
self.lastTappedAt = Date()
if tapCount > 9 {
let dispatchTime = DispatchTime.now() + 3.0
DispatchQueue.main.asyncAfter(deadline: dispatchTime) {
self.didTappedTenTimes(.happy)
}
return
}
if ((tapCount < 6) && (duration > 2)) {
let dispatchTime = DispatchTime.now() + 3.0
DispatchQueue.main.asyncAfter(deadline: dispatchTime) {
self.didTappedFiveTimes(.react)
}
return
}
if tapCount == 0{
let dispatchTime = DispatchTime.now() + 3.0
DispatchQueue.main.asyncAfter(deadline: dispatchTime) {
self.didTapped(.wink)
}
}
}
please feel free to let me know more about the same in depth and suggest me to deal this in better way.
Thanks

OK, I understand you don't want to track actual time when button is pressed, but only count taps in some reasonable time, assuming multiple taps one after another belonging to same action (wink, happy, react).
var tapCount = 0
var lastTappedAt: Date = Date()
func scheduleCheckResult() {
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {
let timePassedSinceLastTap = Int(Date().timeIntervalSince(self.lastTappedAt))
print("last tap was \(timePassedSinceLastTap) ago")
// Wait a bit more for resolving final reaction. Adjust if you want quicker/slower taps (more than 1s for slower, less for quiceker)
guard timePassedSinceLastTap > 1 else {
return self.scheduleCheckResult()
}
print("FINISHED WITH: \(self.tapCount)")
// Verify result
switch self.tapCount {
case let n where n >= 10:
print("Super duper happy")
case let n where n >= 5:
print("Very happy")
default:
print("Medium happy")
}
// Reset state
self.tapCount = 0
}
}
#IBAction func didTap() {
if tapCount == 0 {
scheduleCheckResult()
}
lastTappedAt = Date()
tapCount += 1
}

Related

Tile based movement on Actionscript 2.0 (adobe flash cs6)

So I have got this problem where I do not know how to possible code tile based movement in 4 directions (NSWE) for action script 2.0.
I have this code but it is dynamic movement, which makes the char move in all 8 directions (NW,NE,SW,SE N,S,W,E). The goal is to limit the movements to tile based and in only 4 directions (NSEW)
onClipEvent(enterFrame)
{
speed=5;
if(Key.isDown(Key.RIGHT))
{
this.gotoAndStop(4);
this._x+=speed;
}
if(Key.isDown(Key.LEFT))
{
this.gotoAndStop(3);
this._x-=speed;
}
if(Key.isDown(Key.UP))
{
this.gotoAndStop(1);
this._y-=speed;
}
if(Key.isDown(Key.DOWN))
{
this.gotoAndStop(2);
this._y+=speed;
}
}
The most simple and straightforward way is to move that thing along X-axis OR along Y-axis, only one at a time, not both.
onClipEvent(enterFrame)
{
speed = 5;
dx = 0;
dy = 0;
// Figure out the complete picture of keyboard input.
if (Key.isDown(Key.RIGHT))
{
dx += speed;
}
if (Key.isDown(Key.LEFT))
{
dx -= speed;
}
if (Key.isDown(Key.UP))
{
dy -= speed;
}
if (Key.isDown(Key.DOWN))
{
dy += speed;
}
if (dx != 0)
{
// Move along X-axis if LEFT or RIGHT pressed.
// Ignore if it is none or both of them.
this._x += dx;
if (dx > 0)
{
this.gotoAndStop(4);
}
else
{
this.gotoAndStop(3);
}
}
else if (dy != 0)
{
// Ignore if X-axis motion is already applied.
// Move along Y-axis if UP or DOWN pressed.
// Ignore if it is none or both of them.
this._y += dy;
if (dy > 0)
{
this.gotoAndStop(2);
}
else
{
this.gotoAndStop(1);
}
}
}

Calculating size of Google Firestore documents

Firestore docs give details of how to manually calculate the stored size of a document, but there does not seem to be a function provided for this on any of document reference, snapshot, or metadata.
Before I attempt to use my own calculation, does anyone know of an official or unofficial function for this?
Here is my (completely untested) first cut for such a function from my interpretation of the docs at https://firebase.google.com/docs/firestore/storage-size
function calcFirestoreDocSize(collectionName, docId, docObject) {
let docNameSize = encodedLength(collectionName) + 1 + 16
let docIdType = typeof(docId)
if(docIdType === 'string') {
docNameSize += encodedLength(docId) + 1
} else {
docNameSize += 8
}
let docSize = docNameSize + calcObjSize(docObject)
return docSize
}
function encodedLength(str) {
var len = str.length;
for (let i = str.length - 1; i >= 0; i--) {
var code = str.charCodeAt(i);
if (code > 0x7f && code <= 0x7ff) {
len++;
} else if (code > 0x7ff && code <= 0xffff) {
len += 2;
} if (code >= 0xDC00 && code <= 0xDFFF) {
i--;
}
}
return len;
}
function calcObjSize(obj) {
let key;
let size = 0;
let type = typeof obj;
if(!obj) {
return 1
} else if(type === 'number') {
return 8
} else if(type === 'string') {
return encodedLength(obj) + 1
} else if(type === 'boolean') {
return 1
} else if (obj instanceof Date) {
return 8
} else if(obj instanceof Array) {
for(let i = 0; i < obj.length; i++) {
size += calcObjSize(obj[i])
}
return size
} else if(type === 'object') {
for(key of Object.keys(obj)) {
size += encodedLength(key) + 1
size += calcObjSize(obj[key])
}
return size += 32
}
}
In Android, if you want to check the size of a document against the maximum of 1 MiB (1,048,576 bytes), there is a library that can help you with that:
https://github.com/alexmamo/FirestoreDocument-Android/tree/master/firestore-document
In this way, you'll be able to always stay below the limit. The algorithm behind this library is the one that is explained in the official documentation regarding the Storage Size.

The processing speed between swift and objective-c in Metal

I have written a demo base on apple official document in swift. And I found the usage of CPU is lower in Objective-c than in swift.
Does it mean Objective-c is much effective than swift while handling metal app?
I'm confused because many people says that swift is faster than Objective-c in general. Or it is just an exception?
The demo involved pointer management. I know it is trouble handle pointer with swift. Maybe it is the reason why the app is cost much resource in swift? I am still finding.
The demo below is a triple buffer model which renders hundreds of small quads, updates their positions at the start of each frame and writes them into a vertex buffer. And uses semaphores to wait for full frame completions in case the CPU is running too far ahead of the GPU.
This is the part of code from apple official document
- (void)updateState
{
AAPLVertex *currentSpriteVertices = _vertexBuffers[_currentBuffer].contents;
NSUInteger currentVertex = _totalSpriteVertexCount-1;
NSUInteger spriteIdx = (_rowsOfSprites * _spritesPerRow)-1;
for(NSInteger row = _rowsOfSprites - 1; row >= 0; row--)
{
float startY = _sprites[spriteIdx].position.y;
for(NSInteger spriteInRow = _spritesPerRow-1; spriteInRow >= 0; spriteInRow--)
{
vector_float2 updatedPosition = _sprites[spriteIdx].position;
if(spriteInRow == 0)
{
updatedPosition.y = startY;
}
else
{
updatedPosition.y = _sprites[spriteIdx-1].position.y;
}
_sprites[spriteIdx].position = updatedPosition;
for(NSInteger vertexOfSprite = AAPLSprite.vertexCount-1; vertexOfSprite >= 0 ; vertexOfSprite--)
{
currentSpriteVertices[currentVertex].position = AAPLSprite.vertices[vertexOfSprite].position + _sprites[spriteIdx].position;
currentSpriteVertices[currentVertex].color = _sprites[spriteIdx].color;
currentVertex--;
}
spriteIdx--;
}
}
}
- (void)drawInMTKView:(nonnull MTKView *)view
{
dispatch_semaphore_wait(_inFlightSemaphore, DISPATCH_TIME_FOREVER);
_currentBuffer = (_currentBuffer + 1) % MaxBuffersInFlight;
[self updateState];
id<MTLCommandBuffer> commandBuffer = [_commandQueue commandBuffer];
commandBuffer.label = #"MyCommand";
__block dispatch_semaphore_t block_sema = _inFlightSemaphore;
[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> buffer)
{
dispatch_semaphore_signal(block_sema);
}];
MTLRenderPassDescriptor *renderPassDescriptor = view.currentRenderPassDescriptor;
if(renderPassDescriptor != nil)
{
id<MTLRenderCommandEncoder> renderEncoder =
[commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor];
renderEncoder.label = #"MyRenderEncoder";
[renderEncoder setCullMode:MTLCullModeBack];
[renderEncoder setRenderPipelineState:_pipelineState];
[renderEncoder setVertexBuffer:_vertexBuffers[_currentBuffer]
offset:0
atIndex:AAPLVertexInputIndexVertices];
[renderEncoder setVertexBytes:&_viewportSize
length:sizeof(_viewportSize)
atIndex:AAPLVertexInputIndexViewportSize];
[renderEncoder drawPrimitives:MTLPrimitiveTypeTriangle
vertexStart:0
vertexCount:_totalSpriteVertexCount];
[renderEncoder endEncoding];
[commandBuffer presentDrawable:view.currentDrawable];
}
[commandBuffer commit];
}
and this is in swift
func updateSprite() {
let currentSpriteVertices = vertexBuffer[currentBuffer].contents().bindMemory(to: DFVertex.self, capacity: totalSpriteVertexCount * MemoryLayout<DFVertex>.size)
var currentVertex = totalSpriteVertexCount - 1
var spriteIdx = (rowsOfSprites * spritePerRow) - 1
for _ in stride(from: rowsOfSprites - 1, through: 0, by: -1) {
let startY = sprites[spriteIdx].position.y
for spriteInRow in stride(from: spritePerRow - 1, through: 0, by: -1) {
var updatePosition = sprites[spriteIdx].position
if spriteInRow == 0 {
updatePosition.y = startY
} else {
updatePosition.y = sprites[spriteIdx - 1].position.y
}
sprites[spriteIdx].position = updatePosition
for vertexOfSprite in stride(from: DFSprite.vertexCount - 1, through: 0, by: -1) {
currentSpriteVertices[currentVertex].position = DFSprite.vertices[vertexOfSprite].position + sprites[spriteIdx].position
currentSpriteVertices[currentVertex].color = sprites[spriteIdx].color
currentVertex -= 1
}
spriteIdx -= 1
}
}
}
func draw(in view: MTKView) {
inFlightSemaphore.wait()
currentBuffer = (currentBuffer + 1) % maxBufferInFlight
updateSprite()
let commandBuffer = commandQueue.makeCommandBuffer()
if commandBuffer == nil {
print("create command buffer failed.")
}
commandBuffer!.label = "command buffer"
commandBuffer!.addCompletedHandler { (buffer) in
self.inFlightSemaphore.signal()
}
if let renderPassDescriptor = view.currentRenderPassDescriptor,
let renderEncoder = commandBuffer!.makeRenderCommandEncoder(descriptor: renderPassDescriptor) {
renderEncoder.setCullMode(.back)
renderEncoder.setRenderPipelineState(pipelineState!)
renderEncoder.setVertexBuffer(vertexBuffer[currentBuffer],
offset: 0,
index: DFVertexInputIndex.vertex.rawValue)
renderEncoder.setVertexBytes(&viewportSize,
length: MemoryLayout.size(ofValue: viewportSize),
index: DFVertexInputIndex.viewportSize.rawValue)
renderEncoder.drawPrimitives(type: .triangle,
vertexStart: 0,
vertexCount: totalSpriteVertexCount)
renderEncoder.endEncoding()
commandBuffer!.present(view.currentDrawable!)
}
commandBuffer!.commit()
}
the result is that the app written in objective-c cost about 40% cpu usage while about 100% in swift. I thought swift would be faster.

Player should win when all objects are collected

I have a simple game where the player needs to collect 4 game objects within 30 sec. Now I already created the timer, so I need to let the game know that if all game objects are collected under the time limit the player wins.
This is my code so far:
using UnityEngine;
using System.Collections;
public class GameState : MonoBehaviour
{
public static int count = 0;
public float seconds = 30;
public float minutes = 0;
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update ()
{
if (seconds <= 0)
{
seconds = 30;
if (minutes >= 1)
{
minutes -- ;
}
else
{
minutes = 0;
seconds = 0;
GameObject.Find("TimerText").guiText.text = minutes.ToString("f0") + ":0" + seconds.ToString("f0");
}
}
else
{
seconds -= Time.deltaTime;
}
if (Mathf.Round(seconds) <=9)
{
GameObject.Find("TimerText").guiText.text = minutes.ToString("f0") + ":0" + seconds.ToString("f0");
}
else
{
GameObject.Find("TimerText").guiText.text = minutes.ToString("f0") + ":" + seconds.ToString("f0");
}
if(count >= 1)
{
print("You Won!");
}
}
void OnTriggerEnter(Collider collide)
{
if (collide.transform.tag == "Cube")
{
count = count + 1;
Destroy (collide.gameObject);
}
}
}
Note: cube is one of the game object that needs to be picked up.
you could interrupt the game or show a victory menu or something when you have all the cubes collected
void Update ()
{
bool cubescollected = false;
if(cubescollected == 4)
{
ShowVictoryOrSomething();
cubescollected = true
}
if(cubescollected == true)
return;
... your timer code
}
good luck and happy coding

Error #2006: The supplied index is out of bounds

I keep getting
Error #2006: The supplied index is out of bounds.
at flash.display::DisplayObjectContainer/getChildAt()
at Main/onFrame()
This is mostly referring to this part of my code
else if (comp) //if completion is true
{
var animation = char.getChildAt(2); //
if (animation.currentFrame == animation.totalFrames)
{
animation.stop();
addChild(end);
My animation that I am pulling at the second frame also isn't running at all, though I have checked the symbol and the frames within it, and it should work fine. I'm pretty new to code and this is what I have been taught so far.
This is the rest of my code here.
We are supposed to make a basic game where our character walks to a power up and does a power up animation, followed by an end game title.
package
{
import flash.display.MovieClip;
import fl.motion.easing.Back;
import flash.sampler.Sample;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
public class Main extends MovieClip
{
var bg:Background;
var b:Bubbles;
var b2:Bubbles;
var s:Seaweed;
var pressingRight:Boolean = false;
var pressingLeft:Boolean = false;
var comp:Boolean = false;
var speed:int = 10;
var char:Character;
var pu:PowerUp;
var hit:hit1
var end:EndGame;
public function Main()
{
bg = new Background;
addChild(bg);
char = new Character();
addChild(char);
char.x = stage.stageWidth/2;
char.y = 488;
b = new Bubbles();
addChild(b);
b2 = new Bubbles();
addChild(b2);
b2.y = +b2.height;
s = new Seaweed();
addChild(s);
pu = new PowerUp();
addChild(pu);
pu.x = 200;
pu.y = 450;
pu.height = 50;
pu.scaleX = pu.scaleY;
pu.gotoAndStop("SPIN");
hit = new hit1;
addChild(hit);
hit.x = char.x
hit.y = char.y - 50
end = new EndGame();
end.x = stage.stageWidth/2;
end.y = stage.stageHeight/2;
stage.addEventListener(Event.ENTER_FRAME, onFrame);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
stage.addEventListener(KeyboardEvent.KEY_UP, keyReleased);
}//main()
public function onFrame(e:Event)
{
if (!comp)
//Bubble Movement
b.y -= 1;
b2.y -= 1;
if (b.y >= stage.stageHeight)
{
b.y = b2.y + bg.height;
}
else if (b2.y >= stage.stageHeight)
{
b2.y = b.y + b2.height;
}
//Background & Character Movement
if (pressingRight && char.x < stage.stageWidth/2)
{
char.x += speed * 0.4
}
else if (pressingRight == true && (bg.width + bg.x) > stage.stageWidth)
{
bg.x -= speed * 0.4;
s.x -= speed * 0.6;
pu.x -= speed * 0.4;
}
else if (pressingRight == true)
{
char.x += speed * 0.4;
}
if (pressingLeft == true && char.x > stage.stageWidth/2)
{
char.x -= speed * 0.4;
}
else if (pressingLeft == true && bg.x <0)
{
bg.x += speed * 0.4;
s.x += speed * 0.6;
pu.x += speed * 0.4;
}
else if (pressingLeft)
{
char.x -= speed * 0.4;
}
//Boundaries
if (char.x > stage.stageWidth)
{
char.x = stage.stageWidth;
}
else if (char.x < 0)
{
char.x = 0;
}
//Character Looking Directions
if (pressingLeft == true)
{
char.scaleX = -1;
hit.x = char.x
}
if (pressingRight == true)
{
char.scaleX = 1;
hit.x = char.x
}
//Character Movements
if (pressingRight || pressingLeft)
{
char.gotoAndStop("WALK");
}
else if (!pressingRight || !pressingLeft)
{
char.gotoAndStop("IDLE");
}
//Getting the Power up
if (pu.hitTestObject(hit))
{
char.gotoAndStop("POWER");
comp = true;
pu.gotoAndStop("GONE");
}
// !end
else if (comp) //if completion is true
{
var animation = char.getChildAt(2); //
if (animation.currentFrame == animation.totalFrames)
{
animation.stop();
addChild(end);
}
}//Comp
}//onFrame
public function keyPressed(k:KeyboardEvent)
{
if (k.keyCode == Keyboard.RIGHT)
{
pressingRight = true;
}
else if (k.keyCode == Keyboard.LEFT)
{
pressingLeft = true;
}
} // keyPressed()
public function keyReleased(k:KeyboardEvent)
{
if (k.keyCode == Keyboard.RIGHT)
{
pressingRight = false;
}
else if (k.keyCode == Keyboard.LEFT)
{
pressingLeft = false;
}
} // keyReleased()
}//public class()
}//package()
If you're using a language with zero-based indexing (where array indexes start at 0, not 1) Then this could be the problem.
Frame 1 would be at index [0] and frame 2 would be at index [1].
If you have 2 frames for example and try to access the frame at index[2] you are stepping beyond the bounds of your array and this is probably why you are getting that error message.