Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift Pong(No SpriteKit): How to calculate ball angles to move ball

Tags:

swift

pong

I'm trying to make the game Pong using Swift, but without using SpriteKit. So far, I have been able to successfully draw a rectangle on my view, and I am able to drag this around the screen. This is my current code:

import UIKit

class PongView: UIView {
    lazy var paddle: CGRect = {
        return CGRect(x: 200,
                             y: 200,
                             width: self.frame.width / 6,
                             height: self.frame.height / 60)
    }()
    var movePaddle = false

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        let gesture = UIPanGestureRecognizer(target: self, action: #selector(dragPaddle(recognizer:)))
        addGestureRecognizer(gesture)
    }

    override func draw(_ rect: CGRect) {
        drawPaddle(rect)
    }

    func drawPaddle(_ rect: CGRect) {
        let path = UIBezierPath(rect: paddle)
        UIColor.black.set()
        path.fill()
    }

    func paddleInBounds() -> Bool {
        //padding vars are calculated in another file
        return (paddle.minX >= frame.minX + leftPadding) &&
               (paddle.maxX <= frame.maxX - rightPadding) &&
               (paddle.minY >= frame.minY + topPadding) &&
               (paddle.maxY <= frame.maxY - bottomPadding)
    }

    func setPaddleInBounds() {
        if (paddle.minX < frame.minX + leftPadding) {
            paddle.origin.x = frame.minX + leftPadding
        }
        if (paddle.maxX > frame.maxX - rightPadding) {
            paddle.origin.x = frame.maxX - rightPadding - paddle.width
        }
        if (paddle.minY < frame.minY + topPadding) {
            paddle.origin.y = frame.minY + topPadding
        }
        if (paddle.maxY > frame.maxY - bottomPadding) {
            paddle.origin.y = frame.maxY - bottomPadding - paddle.height
        }
    }

    @objc func dragPaddle(recognizer: UIPanGestureRecognizer) {
        print(paddle.origin)
        print(paddle.minX)
        print(paddle.minY)
        if paddleInBounds() {
            let translation = recognizer.translation(in: self)
            paddle.origin = CGPoint(x: paddle.minX + translation.x, y: paddle.minY + translation.y)
            recognizer.setTranslation(CGPoint.zero, in: self)
            setNeedsDisplay()
        } else {
            setPaddleInBounds()
        }
    }
}

Now I would like to create the ball. I'm not sure how to begin, though. Collisions should be easy:

if (ball coordinates are within boundaries) || 
   (ball coordinates touch paddle coordinates) {
    //collision detected
}

But without SpriteKit, I'm not sure how to calculate ball bouncing angles and move the ball accordingly, which are the main parts of the game. Any suggestions?

like image 546
Xcoder Avatar asked Jun 28 '19 22:06

Xcoder


1 Answers

Simply put, you need to reverse the ball velocity 'x' if reached x-boundary and 'y' if reached y-boundary.

Considering no friction or acceleration any and no other factors to effect the velocity. Lets say the ball is traveling 60 degrees towards bottom right and hits right boundary. It needs to travel below on same 'y' velocity while returning towards left with same 'x' velocity. And as it hits bottom boundary, it will still move towards left, while returning towards top with same 'y' velocity.

var posX = 0
var posY = 0
var velX = 5
var velY = 8

func moveBall(){
    posX += velX
    posY += velY
    if collideOnXBoundary {
        velX = -velX
    }
    if collideOnYBoundary {
        velY = -velY
    }
}

You can create a whole physics for ball using this velocity. Change its value to speed up, use friction to slow it down as it moves, use acceleration, torque etc to create different mechanisms.

like image 167
Alok Subedi Avatar answered Nov 15 '22 07:11

Alok Subedi