Skip to content

Instantly share code, notes, and snippets.

@trevphil
Created July 14, 2019 19:16
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save trevphil/58d3cbbfdefc2ec71e986b28aaf29f32 to your computer and use it in GitHub Desktop.
Save trevphil/58d3cbbfdefc2ec71e986b28aaf29f32 to your computer and use it in GitHub Desktop.
Pong Screensaver Full Code
import ScreenSaver
class PongView: ScreenSaverView {
private var ballPosition: CGPoint = .zero
private var ballVelocity: CGVector = .zero
private var paddlePosition: CGFloat = 0
private let ballRadius: CGFloat = 15
private let paddleBottomOffset: CGFloat = 100
private let paddleSize = NSSize(width: 60, height: 20)
// MARK: - Initialization
override init?(frame: NSRect, isPreview: Bool) {
super.init(frame: frame, isPreview: isPreview)
ballPosition = CGPoint(x: frame.width / 2, y: frame.height / 2)
ballVelocity = initialVelocity()
}
@available(*, unavailable)
required init?(coder decoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: - Lifecycle
override func draw(_ rect: NSRect) {
drawBackground(.white)
drawBall()
drawPaddle()
}
override func animateOneFrame() {
super.animateOneFrame()
let oobAxes = ballIsOOB()
if oobAxes.xAxis {
ballVelocity.dx *= -1
}
if oobAxes.yAxis {
ballVelocity.dy *= -1
}
let paddleContact = ballHitPaddle()
if paddleContact {
ballVelocity.dy *= -1
}
ballPosition.x += ballVelocity.dx
ballPosition.y += ballVelocity.dy
paddlePosition = ballPosition.x
setNeedsDisplay(bounds)
}
// MARK: - Helper Functions
private func drawBackground(_ color: NSColor) {
let background = NSBezierPath(rect: bounds)
color.setFill()
background.fill()
}
private func drawBall() {
let ballRect = NSRect(x: ballPosition.x - ballRadius,
y: ballPosition.y - ballRadius,
width: ballRadius * 2,
height: ballRadius * 2)
let ball = NSBezierPath(roundedRect: ballRect,
xRadius: ballRadius,
yRadius: ballRadius)
NSColor.black.setFill()
ball.fill()
}
private func drawPaddle() {
let paddleRect = NSRect(x: paddlePosition - paddleSize.width / 2,
y: paddleBottomOffset - paddleSize.height / 2,
width: paddleSize.width,
height: paddleSize.height)
let paddle = NSBezierPath(rect: paddleRect)
NSColor.black.setFill()
paddle.fill()
}
private func initialVelocity() -> CGVector {
let desiredVelocityMagnitude: CGFloat = 10
let xVelocity = CGFloat.random(in: 2.5...7.5)
let xSign: CGFloat = Bool.random() ? 1 : -1
let yVelocity = sqrt(pow(desiredVelocityMagnitude, 2) - pow(xVelocity, 2))
let ySign: CGFloat = Bool.random() ? 1 : -1
return CGVector(dx: xVelocity * xSign, dy: yVelocity * ySign)
}
private func ballIsOOB() -> (xAxis: Bool, yAxis: Bool) {
let xAxisOOB = ballPosition.x - ballRadius <= 0 ||
ballPosition.x + ballRadius >= bounds.width
let yAxisOOB = ballPosition.y - ballRadius <= 0 ||
ballPosition.y + ballRadius >= bounds.height
return (xAxisOOB, yAxisOOB)
}
private func ballHitPaddle() -> Bool {
let xBounds = (lower: paddlePosition - paddleSize.width / 2,
upper: paddlePosition + paddleSize.width / 2)
let yBounds = (lower: paddleBottomOffset - paddleSize.height / 2,
upper: paddleBottomOffset + paddleSize.height / 2)
return ballPosition.x >= xBounds.lower &&
ballPosition.x <= xBounds.upper &&
ballPosition.y - ballRadius >= yBounds.lower &&
ballPosition.y - ballRadius <= yBounds.upper
}
}
@kevando
Copy link

kevando commented Jun 12, 2023

I follow your instructions on your medium post, but when i click build/run it says its Build Succeeded, but I dont see this Pong.Saver file. Any idea what I'm doing wrong?

@AjayChandran11
Copy link

@kevando Did you find the reason? I am also facing the same.

@skwidz
Copy link

skwidz commented Jul 12, 2023

@kevando @AjayChandran11 Found the solution for this from chriswaco on reddit

Apple changed the way to find build products.

If you want the debug version, select "Show Build Folder in Finder" from the "Product" menu.

If you want a release version, select "Archive" from the "Product" menu and when done select "Organizer" from the "Window" menu and choose "Export".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment