-
-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
89 changed files
with
3,784 additions
and
947 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
_Message | ||
════════════════════════════════════════════════════════════════════════ | ||
let onDone | ||
|
||
const fadeInFrames = 42 | ||
const holdFrames = 110 | ||
const fadeOutFrames = 42 | ||
|
||
enter(callback) | ||
──────────────────────────────────────────────────────────────────────── | ||
onDone = callback | ||
|
||
|
||
frame | ||
──────────────────────────────────────────────────────────────────────── | ||
setBackground(#0) | ||
|
||
let α = modeFrames | ||
let done = false | ||
|
||
if modeFrames < fadeInFrames: | ||
α = (modeFrames + 1) / fadeInFrames | ||
else if modeFrames < fadeInFrames + holdFrames: | ||
α = 1 | ||
else if modeFrames < fadeInFrames + holdFrames + fadeOutFrames: | ||
α = 1 - (modeFrames + 1 - fadeInFrames - holdFrames) / fadeOutFrames | ||
else: | ||
done = true | ||
|
||
drawSprite({sprite: pauseMessageSprite, pos: ½ screenSize, opacity: α}) | ||
|
||
if done or anyButtonPress(): | ||
onDone() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,220 @@ | ||
_Play | ||
════════════════════════════════════════════════════════════════════════ | ||
|
||
const gameArray = [{ | ||
title: "Quadpaddle", | ||
developer: "CasualEffects", | ||
url: "quad://games/quadpaddle", | ||
description: "Blast bricks as a team from all four sides, grabbing powerups and racking up points.", | ||
version: 0.5, | ||
cooperative: true, | ||
competitive: false, | ||
minPlayers: 1, | ||
maxPlayers: 4, | ||
achievements: false, | ||
builtin: true, | ||
highscores: false, | ||
label: qplabel[0][0], | ||
preview: qppreview | ||
}, | ||
|
||
{ | ||
title: "Serpitron", | ||
developer: "CasualEffects", | ||
url: "quad://games/serpitron", | ||
description: "Grow your serpent without crashing into obstacles or yourself. With rats, shotguns, blizzards, cities, & pyramids.", | ||
version: 0.5, | ||
cooperative: false, | ||
competitive: true, | ||
minPlayers: 1, | ||
maxPlayers: 4, | ||
achievements: false, | ||
builtin: true, | ||
highscores: false, | ||
label: splabel[0][0], | ||
preview: sppreview | ||
}, | ||
|
||
{ | ||
title: "Ice Time", | ||
developer: "CasualEffects", | ||
url: "quad://games/icetime", | ||
description: "2 vs. 2 ice hockey with teams, player stats., faceoffs, passing…and a Zamboni.", | ||
version: 0.5, | ||
cooperative: true, | ||
competitive: true, | ||
minPlayers: 1, | ||
maxPlayers: 4, | ||
achievements: false, | ||
highscores: false, | ||
builtin: true, | ||
label: itlabel[0][0], | ||
preview: itpreview | ||
}, | ||
|
||
{ | ||
title: "SpeedStreet", | ||
developer: "CasualEffects", | ||
url: "quad://games/speedstreet", | ||
|
||
version: 0.5, | ||
description: "How fast can you go? Tear through the road course pulling tricks off jumps and fighting to be the leader of the pack.", | ||
minPlayers: 1, | ||
maxPlayers: 4, | ||
cooperative: false, | ||
competitive: true, | ||
achievements: false, | ||
highscores: false, | ||
builtin: true, | ||
label: sslabel[0][0], | ||
preview: sspreview | ||
} | ||
] | ||
|
||
const backgroundColor = #135 | ||
const promptColor = #4DF | ||
const promptFont = mediumFont | ||
const shadowColor = #0006 | ||
const selectedColor = #f | ||
const unselectedColor = #9 | ||
|
||
// Pixel scrolling | ||
let gameShift = 0 | ||
let gameIndex = 0 | ||
|
||
let modeFrameShift = 0 | ||
|
||
def drawIcon(icon, pos): | ||
assert(icon != nil) | ||
drawSprite({sprite: icon, pos: pos + xy(3 + icon.size.x / 2, 3 - icon.size.y / 2)}) | ||
return xy(icon.size.x + 2, icon.size.y + 2) | ||
|
||
|
||
frame | ||
──────────────────────────────────────────────────────────────────────── | ||
|
||
const introFrames = 20 | ||
if gameFrames < introFrames: | ||
// Fade and slide in | ||
const α = 1 - min(1, (gameFrames + 1) / (introFrames + 1)) | ||
setPostEffects({background:#0, | ||
pos: xy(α * screenSize.x, 0), | ||
color: rgba(0, 0, 0, α)}) | ||
else if gameFrames == introFrames: | ||
resetPostEffects() | ||
|
||
setBackground(backgroundColor) | ||
|
||
drawCornerRect(xy(0,0), xy(90, 15), #2) | ||
drawCornerRect(xy(155,0), xy(230, 15), #2) | ||
drawText({font: mediumFont, text:joy.prompt["⍇"], pos: xy(70,12), color: promptColor, shadow: shadowColor}) | ||
drawText({font: mediumFont, text:"LIBRARY", pos: xy(99,12), color: selectedColor, shadow: shadowColor}) | ||
drawText({font: mediumFont, text:"DISCOVER", pos: xy(180,12), color: unselectedColor, shadow: shadowColor}) | ||
drawText({font: mediumFont, text:"URL", pos: xy(260,12), color: unselectedColor, shadow: shadowColor}) | ||
drawText({font: mediumFont, text:joy.prompt["⍈"], pos: xy(300,12), color: promptColor, shadow: shadowColor}) | ||
|
||
drawLine(xy(0, 16), xy(90, 16), #f) | ||
drawLine(xy(90, 16), xy(90, 1), #f) | ||
drawLine(xy(91, 0), xy(154, 0), #f) | ||
drawLine(xy(155, 1), xy(155, 16), #f) | ||
drawLine(xy(155, 16), xy(384, 16), #f) | ||
|
||
drawText({font: mediumFont, text:joy.prompt["⍐"], pos: xy(1, 28), color: promptColor, shadow: shadowColor}) | ||
drawText({font: mediumFont, text:joy.prompt["⍗"], pos: xy(1, 220), color: promptColor, shadow: shadowColor}) | ||
|
||
const boxVerticalSpacing = 75 | ||
|
||
setClip(xy(12, 20), xy(64, 201)) | ||
for gameIndex - 2 <= g <= gameIndex + 2: | ||
const game = arrayValue(gameArray, g, "loop") | ||
const pos = xy(44, boxVerticalSpacing * g + 64/2 + 19 - gameShift - (gameIndex - 1) * boxVerticalSpacing) | ||
drawSprite({sprite: game.label, pos: pos}) | ||
drawLine(pos + xy(1-64/2, 64/2), pos + xy(64/2-2, 64/2), shadowColor) | ||
resetClip() | ||
|
||
// Highlight selected game | ||
drawCornerRect(xy(11, 93), xy(66, 66), nil, #f) | ||
drawCornerRect(xy(10, 92), xy(68, 68), nil, #d) | ||
|
||
local: | ||
const game = gameArray[gameIndex] | ||
const t = floor((modeFrames - modeFrameShift) / 3) mod 60 | ||
const x = 99 | ||
const pos = xy(x + 384/4, 224/4 + 66) | ||
drawSprite({sprite: game.preview[t mod 6][floor(t / 6)], pos: pos}) | ||
drawLine(pos + xy(1-384/4, 224/4), pos + xy(384/4-2, 224/4), shadowColor) | ||
drawLine(pos + xy(2-384/4, 224/4 + 1), pos + xy(384/4-3, 224/4 + 1), shadowColor / 2) | ||
drawText({font:largeFont, text:game.title, pos:xy(x, 40), color:selectedColor, shadow:shadowColor, xAlign:"left"}) | ||
drawText({font:mediumFont, text:"by " + game.developer, pos:xy(x, 56), color:selectedColor, shadow:shadowColor, xAlign:"left"}) | ||
drawText({font:smallFont, text:game.url, pos:xy(x, 220), color:unselectedColor, xAlign:"left"}) | ||
drawText({font:smallFont, text:game.description, pos:xy(x, 193), color:selectedColor, xAlign:"left", wrapWidth: 280}) | ||
|
||
const sideX = 295 | ||
const wordX = sideX + 27 | ||
drawText({font:promptFont, text:joy.prompt["ⓠ"] + " PLAY", pos:xy(sideX + 7, 74), color:promptColor, shadow:shadowColor, xAlign:"left"}) | ||
if not game.builtin: drawText({font:promptFont, text:joy.prompt["ⓓ"] + " FORGET", pos:xy(sideX + 7, 88), color:promptColor, shadow:shadowColor, xAlign:"left"}) | ||
|
||
// Icons | ||
let y = 112 | ||
if game.maxPlayers == 0 or game.minPlayers == 0 and game.maxPlayers == nil: | ||
drawText({font:mediumFont, text:"Animation", pos:xy(wordX, y), color:selectedColor, xAlign:"left"}).y | ||
drawIcon(icons.players[0], xy(sideX, y)).y | ||
y += 15 | ||
else if game.minPlayers != nil and game.maxPlayers != nil: | ||
let lo = clamp(min(game.minPlayers, game.maxPlayers), 1, 5) | ||
let hi = clamp(max(game.minPlayers, game.maxPlayers), 1, 5) | ||
if lo != hi: | ||
drawIcon(icons.players[lo], xy(sideX, y)) | ||
drawLine(xy(sideX + 21, y - 4), xy(sideX + 28, y - 4), selectedColor) | ||
drawIcon(icons.players[hi], xy(sideX + 29, y)).y | ||
else: | ||
drawIcon(icons.players[lo], xy(sideX, y)) | ||
drawText({font:mediumFont, text:"" + lo + "-Player", pos:xy(wordX, y), color:selectedColor, xAlign:"left"}) | ||
y += 15 | ||
else if game.minPlayers != nil or game.maxPlayers != nil: | ||
// Only one specified | ||
let lo = if game.minPlayers != nil then game.minPlayers else game.maxPlayers | ||
drawIcon(icons.players[clamp(lo, 1, 5)], xy(sideX, y)) | ||
drawText({font:mediumFont, text:"" + lo + "-Player", pos:xy(wordX, y), color:selectedColor, xAlign:"left"}) | ||
y += 15 | ||
|
||
if game.cooperative: | ||
drawIcon(icons.cooperative, xy(sideX, y)).y | ||
y += drawText({font:mediumFont, text:"Cooperate", pos:xy(wordX, y), color:selectedColor, xAlign:"left"}).y | ||
|
||
if game.competitive: | ||
drawIcon(icons.competitive, xy(sideX, y)).y | ||
y += drawText({font:mediumFont, text:"Compete", pos:xy(wordX, y), color:selectedColor, xAlign:"left"}).y | ||
|
||
if game.achievements: | ||
drawIcon(icons.achievements, xy(sideX, y)).y | ||
y += drawText({font:mediumFont, text:"Achieve", pos:xy(wordX, y), color:selectedColor, xAlign:"left"}).y | ||
|
||
if game.highscores: | ||
drawIcon(icons.highscores, xy(sideX, y)).y | ||
y += drawText({font:mediumFont, text:"Score", pos:xy(wordX, y), color:selectedColor, xAlign:"left"}).y | ||
|
||
if joy.aa or joy.qq: | ||
def callback(): | ||
launchGame(gameArray[gameIndex].url) | ||
setMode(_SlideOut, callback) because "Player selected game" | ||
|
||
// Animate scrolling | ||
if joy.yy: | ||
const Δy = 3 joy.yy | ||
playAudioClip(boop, false, 300%) | ||
def shift(): gameShift += Δy | ||
addFrameHook(shift, nil, boxVerticalSpacing / 3) | ||
|
||
// Change games | ||
if gameShift >= boxVerticalSpacing: | ||
gameShift -= boxVerticalSpacing | ||
modeFrameShift = modeFrames - 1 | ||
++gameIndex | ||
else if gameShift <= -boxVerticalSpacing: | ||
gameShift += boxVerticalSpacing | ||
--gameIndex | ||
modeFrameShift = modeFrames - 1 | ||
|
||
gameIndex = loop(gameIndex, gameArray.length) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
_SlideOut | ||
════════════════════════════════════════════════════════════════════════ | ||
|
||
let onDone | ||
|
||
enter(callback) | ||
──────────────────────────────────────────────────────────────────────── | ||
onDone = callback | ||
|
||
|
||
frame | ||
──────────────────────────────────────────────────────────────────────── | ||
|
||
const introFrames = 20 | ||
if modeFrames < introFrames: | ||
// Fade and slide in | ||
const α = clamp((modeFrames + 1) / (introFrames + 1), 0, 1) | ||
drawPreviousMode() | ||
setPostEffects({background:#0, | ||
pos: xy(α * screenSize.x, 0), | ||
color: rgba(0, 0, 0, α²)}) | ||
else: | ||
// Animation complete | ||
resetPostEffects() | ||
setMode(_Message, onDone) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.