Skip to content

Instantly share code, notes, and snippets.

@hboon
Forked from amirrajan/iap.rb
Created February 5, 2018 15:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hboon/616e1210671c039a7dd7673ab5c74d26 to your computer and use it in GitHub Desktop.
Save hboon/616e1210671c039a7dd7673ab5c74d26 to your computer and use it in GitHub Desktop.
# coding: utf-8
class IAPScene < SKScene
include ScreenSizes
attr_accessor :root
def button_size
device_screen_width.fdiv(buttons_per_row + 2)
end
def buttons_per_row
return 6 if iPad?
3
end
def padding
10
end
def add_button x, y, text
b = Button.new(IdGenerator.burn, 1.5)
b.init_sprite_with_text x,
y,
button_size,
text,
'button.png',
0.5, 0.5
@buttons << b
@camera.addChild b.sprite
b
end
def show_modal formatted_price, description
init_modal unless @modal
return if @modal_shown
@formatted_price = formatted_price
@description = description
@modal.xScale = 1
@modal.yScale = 1
@modal.alpha = 0
@modal.zPosition = 500
@modal_controls.zPosition = 501
@modal_controls.xScale = 1
@modal_controls.yScale = 1
@modal_controls.alpha = 0
@modal_shown = true
end
def collapse node
node.xScale = 0
node.yScale = 0
end
def init_modal
@modal_controls = SKNode.new
@modal = SKSpriteNode.spriteNodeWithColor UIColor.whiteColor, size: CGSizeMake(device_screen_width, device_screen_height)
@modal.anchorPoint = CGPointMake(0, 0)
collapse @modal
collapse @modal_controls
@purchase_description_label = SKLabelNode.labelNodeWithText ''
@purchase_description_label.fontName = 'Courier'
@purchase_description_label.fontColor = UIColor.blackColor
@purchase_description_label.fontSize = button_size.fdiv(4.5)
@purchase_description_label.position = CGPointMake(device_screen_width.fdiv(2), device_screen_height.fdiv(2) + button_size + button_size)
@modal_controls.addChild @purchase_description_label
@purchase_iap_button = Button.new(IdGenerator.burn, 1.5)
@purchase_iap_button.init_sprite_with_text(
device_screen_width.fdiv(2) - button_size.fdiv(2) - 5,
@purchase_description_label.position.y - button_size,
button_size,
'Done',
'button.png',
0.5,
0.5
)
@modal_controls.addChild @purchase_iap_button.sprite
@close_modal_button = Button.new(IdGenerator.burn, 1.5)
@close_modal_button.init_sprite_with_text(
device_screen_width.fdiv(2) + button_size.fdiv(2) + 5,
@purchase_description_label.position.y - button_size,
button_size,
'Close',
'button.png',
0.5,
0.5
)
@modal_controls.addChild @close_modal_button.sprite
@extra_info_label = SKLabelNode.labelNodeWithText "(content will be restored for free if already purchased)"
@extra_info_label.fontName = 'Courier'
@extra_info_label.fontColor = UIColor.blackColor
@extra_info_label.fontSize = button_size.fdiv(7)
@extra_info_label.position = CGPointMake(device_screen_width.fdiv(2), @close_modal_button.sprite.position.y - button_size)
@modal_controls.addChild @extra_info_label
addChild @modal
addChild @modal_controls
end
def didMoveToView _
self.scaleMode = SKSceneScaleModeAspectFit
self.backgroundColor = UIColor.whiteColor
@buttons = []
@camera = SKNode.new
addChild @camera
SKPaymentQueue.defaultQueue.addTransactionObserver(self)
@previous_message = nil
@next_message = 0
@title = SKLabelNode.labelNodeWithText 'Mildly Interesting RTS'
@title.fontName = 'Courier'
@title.fontColor = UIColor.blackColor
@title.fontSize = button_size.fdiv(3)
if iPhoneX?
@title.position = CGPointMake(device_screen_width.fdiv(2), device_screen_height - button_size.fdiv(2) - padding - padding - padding.fdiv(2))
else
@title.position = CGPointMake(device_screen_width.fdiv(2), device_screen_height - button_size.fdiv(2) - padding)
end
addChild @title
@message = SKLabelNode.labelNodeWithText ''
@message.fontName = 'Courier'
@message.fontColor = UIColor.blackColor
@message.fontSize = button_size.fdiv(5.5)
@message.position = CGPointMake(
device_screen_width.fdiv(2),
device_screen_height -
button_size.fdiv(2) -
padding -
button_size
)
@message.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeCenter
@message.alpha = 0
@camera.addChild @message
@message_two = SKLabelNode.labelNodeWithText ''
@message_two.fontName = 'Courier'
@message_two.fontColor = UIColor.blackColor
@message_two.fontSize = button_size.fdiv(5.5)
@message_two.position = CGPointMake(
device_screen_width.fdiv(2),
device_screen_height -
button_size.fdiv(3) -
padding -
button_size -
@message_two.fontSize -
@message_two.fontSize
)
@message_two.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeCenter
@message_two.alpha = 0
@camera.addChild @message_two
@message_three = SKLabelNode.labelNodeWithText ''
@message_three.fontName = 'Courier'
@message_three.fontColor = UIColor.blackColor
@message_three.fontSize = button_size.fdiv(5.5)
@message_three.position = CGPointMake(
device_screen_width.fdiv(2),
device_screen_height -
button_size.fdiv(3) -
padding -
button_size -
@message_three.fontSize -
@message_three.fontSize -
@message_three.fontSize
)
@message_three.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeCenter
@message_three.alpha = 0
@camera.addChild @message_three
@next_message_button = add_button(
device_screen_width.fdiv(2),
device_screen_height - button_size.fdiv(2) -
padding - button_size -
padding - button_size -
padding - button_size,
'...'
)
@next_message_button.hide
@buy_button = add_button(
device_screen_width.fdiv(2),
device_screen_height - button_size.fdiv(2) -
padding - button_size -
padding - button_size -
padding - button_size -
padding - button_size,
'Buy'
)
@buy_button.hide
@back_button = add_button(
device_screen_width.fdiv(2),
@next_message_button.sprite.position.y - padding - button_size - padding - button_size,
'Back'
)
@back_button.hide
end
def fade_out_messages
@message.alpha = 0
@message_two.alpha = 0
end
def touchesBegan touches, withEvent: _
node = nodeAtPoint(touches.allObjects.first.locationInNode(self))
if node.meta[:class] == @next_message_button
fade_out_messages
@next_message_button.pulse
@next_message += 1 if @messages[@next_message + 1]
save_cta_seen if @next_message > cta_index
elsif node.meta[:class] == @buy_button
run_after(0.15) do
display_purchase_request
end
elsif node.meta[:class] == @back_button
run_after(0.15) do
@root.present_stage_select_scene
end
elsif node.meta[:class] == @close_modal_button
run_after(0.15) do
@modal_shown = false
end
elsif node.meta[:class] == @purchase_iap_button
payment = SKPayment.paymentWithProductIdentifier(product_id)
SKPaymentQueue.defaultQueue.addPayment(payment)
end
node.meta[:class].pulse if node.meta[:class].is_a? Button
end
def product_id
'veteran_content'
end
def time_played
number = (GameState.number_of_games_played * 6).fdiv(60).round # about 5 minutes per game
if number == 1
return 'an hour'
else
return "#{number} hours"
end
end
def messages
@messages ||= {
0 => ['Do you trust me as a game developer?'],
1 => ['Do you trust me to stay true', 'to what makes a good RTS?'],
2 => ["Given that you've played #{GameState.number_of_games_played} games of MIRTS,",
"I'd say that answer is yes."],
3 => ["That's over #{time_played} of gaming btw."],
4 => ['Not a single moment of that time',
'was spent watching a stupid ad.'],
5 => ['(and then failing to dismiss them by',
'tapping a tiny, stupid-ass close button)'],
6 => ['Not a single moment of play time',
'spent waiting for an energy bar to fill up.'],
7 => ['Not a single moment of play time',
'spent grinding through crippled gameplay.'],
8 => ['I can continue to provide you an AD FREE,',
'MICRO TRANSACTION FREE game...'],
9 => ['for CHANGE you can find in your COUCH...'],
10 => ['for LESS THAN a MOVIE TICKET...'],
11 => ['for LESS THAN a PUMPKIN SPICE LATTE...'],
12 => ["#{Emoji.gasp(2)} I PRESENT TO YOU VETERAN CONTENT! #{Emoji.gasp(2)}"],
13 => ["Here's what you'll get:", '(pretend Billy Mays RIP is talking to you)'],
14 => ['VETERAN MAP PACK - Ten MORE competitive', ' maps. Plus an ENDLESS amount of', 'random map generation.'],
15 => ['SUPPLY - Supply limit cutomizations. (play', 'from small skirmishes to grandious battles)'],
16 => ['HASTE - A brand new ability. (this', ' increases movement speed through nodes)'],
17 => ['MOBS - Neutral units. (they guard unoccupied', 'nodes, and get bigger as the', 'match continues)'],
18 => ['You will get all this with a SINGLE purchase.'],
19 => ['I will NEVER nickel and dime you.'],
20 => ['I will NEVER do "mountain of gems", "bags of',
'coins", or other bullshit in-app currencies.'],
21 => ['I will NEVER show you an AD. I will NEVER', 'CRIPPLE gameplay to force you to spend.'],
22 => ['I would rather give up building games', 'altogether, than betray a fellow gamer', 'with DISGUSTING monetization strategies.'],
23 => ['Unlock this awesome stuff and see', 'how deep the strategy of MIRTS goes.'],
24 => ['Get the VETERAN CONTENT via the "Buy" button.', "You won't be disappointed. Promise..."],
25 => ['Please, TRUST me (a fellow RTS player).', "Turn your hours played into many, many more."],
26 => ['DO IT.'],
27 => ['WHY ARE YOU STILL TAPPING AND NOT BUYING', 'THE VETERAN CONTENT?!'],
28 => ["I'M WARNING YOU."],
29 => ["I'M SERIOUS DAMMIT. STOP IT. OPEN", 'YOUR WALLET AND BUY THE VETERAN CONTENT!'],
30 => ['STOP POKING MEEEE!'],
31 => ["LAST WARNING. DON'T TAP AGAIN."],
32 => ['Never gonna give you up.', 'Never gonna let you down.', 'Never gonna run around, and desert you.'],
33 => [Emoji.heart]
}
end
def cta_index
11
end
def save_cta_seen
GameState.mark_iap_request_seen
end
def goto_url url
UIApplication.sharedApplication.openURL NSURL.URLWithString(url)
end
def update _
@buttons.each(&:update)
@message.alpha += 0.1
@message.alpha = 1 if @message.alpha > 1
@message_two.alpha += 0.1
@message_two.alpha = 1 if @message_two.alpha > 1
@message_three.alpha += 0.1
@message_three.alpha = 1 if @message_three.alpha > 1
@next_message_button.fade_in
if @previous_message != @next_message
@message.text = messages[@next_message][0]
@message_two.text = messages[@next_message][1]
@message_three.text = messages[@next_message][2]
end
if GameState.iap_request_seen? || (@next_message > cta_index)
@buy_button.fade_in
@back_button.fade_in
end
update_modal
@previous_message = @next_message
end
def modal_shown?
@modal_shown
end
def run_after(delay, &block)
NSTimer.scheduledTimerWithTimeInterval(
delay,
target: block,
selector: 'call:',
userInfo: nil,
repeats: false
)
end
def display_purchase_request
productsRequest = SKProductsRequest.alloc.initWithProductIdentifiers(NSSet.setWithArray([product_id]))
productsRequest.delegate = self
productsRequest.start
end
def productsRequest(request, didReceiveResponse: response)
if(response.products.count > 0)
@veteran_content = response.products[0]
end
buy_options
end
def alertView(alertView, clickedButtonAtIndex: indexPath)
if(indexPath == 1)
payment = SKPayment.paymentWithProductIdentifier(product_id)
SKPaymentQueue.defaultQueue.addPayment(payment)
end
end
def buy_options
return unless @veteran_content
number = NSNumberFormatter.alloc.init
number.setFormatterBehavior(NSNumberFormatterBehavior10_4)
number.setNumberStyle(NSNumberFormatterCurrencyStyle)
number.setLocale(@veteran_content.priceLocale)
formatted_price = number.stringFromNumber(@veteran_content.price)
show_modal "#{formatted_price}", 'Buy the VETERAN CONTENT. DO IT.'
end
def update_modal
return unless @modal
return unless @modal_controls
if modal_shown?
@purchase_iap_button.text = @formatted_price if @formatted_price
@purchase_description_label.text = @description if @description
@modal.alpha += 0.05
@modal_controls.alpha += 0.05
@modal.alpha = 1 if @modal.alpha > 1
@modal_controls.alpha = 1 if @modal_controls.alpha > 1
elsif
@modal.alpha -= 0.1
@modal_controls.alpha -= 0.1
@modal.alpha = 0 if @modal.alpha < 0
@modal_controls.alpha = 0 if @modal_controls.alpha < 0
collapse @modal if @modal.alpha == 0
collapse @modal_controls if @modal_controls.alpha == 0
end
@purchase_iap_button.update if @purchase_iap_button
@close_modal_button.update if @close_modal_button
end
def unlock_content
GameState.unlock_veteran_content
end
def content_unlocked?
GameState.veteran_content_unlocked?
end
def paymentQueue(queue, updatedTransactions: transactions)
message = ''
transactions.each do |t|
if(t.transactionState == SKPaymentTransactionStateFailed)
message << "Purchase Failed: #{t.error.localizedDescription}"
SKPaymentQueue.defaultQueue.finishTransaction t
elsif(t.transactionState == SKPaymentTransactionStatePurchased || t.transactionState == SKPaymentTransactionStateRestored)
message << 'Veteran Content unlocked. Thank you for the support. It means a lot. Enjoy.'
unlock_content
SKPaymentQueue.defaultQueue.finishTransaction t
end
end
if(message.length != 0)
UIAlertView.alloc.initWithTitle(
"",
message: message,
delegate: nil,
cancelButtonTitle: 'close',
otherButtonTitles: nil
).show
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment