Skip to content

Instantly share code, notes, and snippets.

@coolbutuseless
Forked from Enchufa2/pong.R
Created July 24, 2022 00:57
Show Gist options
  • Save coolbutuseless/09bdd702a3dfa36c14ea9f099d634ceb to your computer and use it in GitHub Desktop.
Save coolbutuseless/09bdd702a3dfa36c14ea9f099d634ceb to your computer and use it in GitHub Desktop.
Pong in R
# remotes::install_github("coolbutuseless/eventloop")
Pong <- R6::R6Class(
"pong",
public = list(
initialize = function(width=10, height=7, speed=0.02) {
require(grid)
private$width <- width
private$height <- height
private$speed <- speed
private$respawn()
},
play = function() {
eventloop::run_loop(private$loop, NULL, private$width, private$height)
}
),
private = list(
width = NULL,
height = NULL,
speed = NULL,
pos = NULL,
angle = NULL,
ball.r = 0.03,
pad.r = 0.1,
p.points = c(0, 0),
p.y = c(0.5, 0.5),
loop = function(event, ...) {
private$move_ball()
private$move_pads(event)
grid.rect(gp=gpar(fill="black"))
grid.lines(c(0.5, 0.5), c(0, 1), gp=gpar(col="white", lty="dashed"))
grid.circle(private$pos[1], private$pos[2], private$ball.r, gp=gpar(fill="white"))
grid.rect(0, private$p.y[1], 0.02, 2*private$pad.r, gp=gpar(fill="white"))
grid.rect(1, private$p.y[2], 0.02, 2*private$pad.r, gp=gpar(fill="white"))
grid.text(private$p.points[1], 0.45, 0.95, gp=gpar(col="white", fontsize=30))
grid.text(private$p.points[2], 0.55, 0.95, gp=gpar(col="white", fontsize=30))
},
respawn = function(scored) {
if (!missing(scored))
private$p.points[scored] <- private$p.points[scored] + 1
private$pos <- c(0.5, runif(1))
private$angle <- runif(1, -pi/4, pi/4) + sample(c(0, pi), 1)
},
move_ball = function() {
private$pos <- private$pos + c(cos(private$angle), sin(private$angle)) * private$speed
# x bounce or score
if (private$pos[1] <= private$ball.r) {
if (private$pos[2] <= private$p.y[1] + private$pad.r &&
private$pos[2] >= private$p.y[1] - private$pad.r) {
private$pos[1] <- private$ball.r
private$angle <- pi - private$angle
} else private$respawn(2)
} else if (private$pos[1] >= 1 - private$ball.r) {
if (private$pos[2] <= private$p.y[2] + private$pad.r &&
private$pos[2] >= private$p.y[2] - private$pad.r) {
private$pos[1] <- 1 - private$ball.r
private$angle <- pi - private$angle
} else private$respawn(1)
}
# y bounce
if (private$pos[2] <= private$ball.r) {
private$pos[2] <- private$ball.r
private$angle <- 2*pi - private$angle
} else if (private$pos[2] >= 1 - private$ball.r) {
private$pos[2] <- 1 - private$ball.r
private$angle <- 2*pi - private$angle
}
# normalize angle
private$angle <- private$angle - private$angle %/% (2*pi) * 2*pi
},
move_pads = function(event) {
if (!is.null(event) && event$type == "key_press") {
# player 2
if (event$str == "Up" && private$p.y[2] < 1 - private$pad.r) {
private$p.y[2] <- private$p.y[2] + 2 * private$speed
} else if (event$str == "Down" && private$p.y[2] > private$pad.r) {
private$p.y[2] <- private$p.y[2] - 2 * private$speed
}
# player 1
if (event$str == "w" && private$p.y[1] < 1 - private$pad.r) {
private$p.y[1] <- private$p.y[1] + 2 * private$speed
} else if (event$str == "s" && private$p.y[1] > private$pad.r) {
private$p.y[1] <- private$p.y[1] - 2 * private$speed
}
}
}
)
)
Pong$new()$play()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment