Every example is a whole program. Paste it into a new codetoy, press ▶ Play and start changing numbers.
#Follow the cursor
A circle that chases the mouse smoothly and logs clicks.
import { fill, rect, circle } from "codetoy/canvas"
import * as screen from "codetoy/screen"
import * as input from "codetoy/input"
import { deltaTime } from "codetoy/time"
let x: f64 = 0
let y: f64 = 0
export function update(): void {
const k = 1.0 - Math.exp(-8.0 * deltaTime())
x += (input.mouseX() - x) * k
y += (input.mouseY() - y) * k
fill(20, 20, 30)
rect(0, 0, screen.width(), screen.height())
fill(0, 150, 255)
circle(x, y, 30)
}
export function onMouseDown(button: i32): void {
console.log("Clicked at " + input.mouseX().toString() + ", " + input.mouseY().toString())
}double x = 0, y = 0;
Screen.OnUpdate(() => {
double k = 1.0 - Math.Exp(-8.0 * Screen.DeltaTime);
x += (Input.MouseX - x) * k;
y += (Input.MouseY - y) * k;
Canvas.Fill(20, 20, 30);
Canvas.Rect(0, 0, Screen.Width, Screen.Height);
Canvas.Fill(0, 150, 255);
Canvas.Circle(x, y, 30);
});
Input.OnMouseDown((int button) => {
Console.Log($"Clicked at {Input.MouseX}, {Input.MouseY}");
});import math
from codetoy.canvas import fill, rect, circle
from codetoy.screen import width, height
from codetoy.time import deltaTime
from codetoy._input import mouseX, mouseY
x, y = 0.0, 0.0
def update():
global x, y
k = 1.0 - math.exp(-8.0 * deltaTime())
x += (mouseX() - x) * k
y += (mouseY() - y) * k
fill(20, 20, 30)
rect(0, 0, width(), height())
fill(0, 150, 255)
circle(x, y, 30)
def mouseDown(button):
print(f"Clicked at {mouseX():.0f}, {mouseY():.0f}")#Responsive grid
A grid that always fills the screen, whatever its size.
import { fill, rect, noStroke } from "codetoy/canvas"
import * as screen from "codetoy/screen"
const cols = 6
const rows = 4
export function update(): void {
noStroke()
fill(30, 30, 30)
rect(0, 0, screen.width(), screen.height())
const cw = screen.width() / (cols as f64)
const ch = screen.height() / (rows as f64)
for (let row = 0; row < rows; row++) {
for (let col = 0; col < cols; col++) {
fill(80 + col * 30, 90 + row * 35, 210)
rect(col * cw + 4, row * ch + 4, cw - 8, ch - 8, 8)
}
}
}int cols = 6, rows = 4;
Screen.OnUpdate(() => {
Canvas.NoStroke();
Canvas.Fill(30, 30, 30);
Canvas.Rect(0, 0, Screen.Width, Screen.Height);
double cw = Screen.Width / cols;
double ch = Screen.Height / rows;
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
Canvas.Fill(80 + col * 30, 90 + row * 35, 210);
Canvas.Rect(col * cw + 4, row * ch + 4, cw - 8, ch - 8, 8);
}
}
});from codetoy.canvas import fill, rect, noStroke
from codetoy.screen import width, height
cols, rows = 6, 4
def update():
noStroke()
fill(30, 30, 30)
rect(0, 0, width(), height())
cw = width() / cols
ch = height() / rows
for row in range(rows):
for col in range(cols):
fill(80 + col * 30, 90 + row * 35, 210)
rect(col * cw + 4, row * ch + 4, cw - 8, ch - 8, 8)#Click to spawn
Every click adds a dot with a random size and color. The dots live in a list, since there are no game objects.
import { fill, rect, circle, noStroke } from "codetoy/canvas"
import * as screen from "codetoy/screen"
import * as input from "codetoy/input"
class Dot {
constructor(public x: f64, public y: f64, public r: f64, public hue: f64) {}
}
const dots = new Array<Dot>()
export function onMouseDown(button: i32): void {
dots.push(new Dot(input.mouseX(), input.mouseY(), 6 + Math.random() * 18, Math.random() * 360))
}
export function update(): void {
noStroke()
fill(15, 15, 25)
rect(0, 0, screen.width(), screen.height())
for (let i = 0; i < dots.length; i++) {
const d = dots[i]
fill(128 + Math.cos(d.hue) * 127, 128 + Math.sin(d.hue) * 127, 200)
circle(d.x, d.y, d.r)
}
}var dots = new List<(double X, double Y, double R, int Red, int Green)>();
var rng = new Random();
Input.OnMouseDown((int button) => {
dots.Add((Input.MouseX, Input.MouseY, 6 + rng.NextDouble() * 18, rng.Next(80, 256), rng.Next(80, 256)));
});
Screen.OnUpdate(() => {
Canvas.NoStroke();
Canvas.Fill(15, 15, 25);
Canvas.Rect(0, 0, Screen.Width, Screen.Height);
foreach (var d in dots) {
Canvas.Fill(d.Red, d.Green, 220);
Canvas.Circle(d.X, d.Y, d.R);
}
});import random
from codetoy.canvas import fill, rect, circle, noStroke
from codetoy.screen import width, height
from codetoy._input import mouseX, mouseY
dots = []
def mouseDown(button):
color = (random.randint(80, 255), random.randint(80, 255), 220)
dots.append((mouseX(), mouseY(), random.uniform(6, 24), color))
def update():
noStroke()
fill(15, 15, 25)
rect(0, 0, width(), height())
for x, y, r, (red, green, blue) in dots:
fill(red, green, blue)
circle(x, y, r)#Sine wave
A path that follows a moving sine wave across the screen.
import { fill, rect, stroke, lineWidth, beginPath, moveTo, lineTo, strokePath } from "codetoy/canvas"
import * as screen from "codetoy/screen"
import { elapsedTime } from "codetoy/time"
export function update(): void {
const t = elapsedTime()
fill(15, 15, 30)
rect(0, 0, screen.width(), screen.height())
stroke(100, 200, 255)
lineWidth(3)
beginPath()
for (let x: f64 = 0; x <= screen.width(); x += 4) {
const y = screen.centerY() + Math.sin(x * 0.02 + t * 3) * 80
if (x == 0) moveTo(x, y)
else lineTo(x, y)
}
strokePath()
}double t = 0;
Screen.OnUpdate(() => {
t += Screen.DeltaTime;
Canvas.Fill(15, 15, 30);
Canvas.Rect(0, 0, Screen.Width, Screen.Height);
Canvas.Stroke(100, 200, 255);
Canvas.LineWidth(3);
Canvas.BeginPath();
for (double x = 0; x <= Screen.Width; x += 4) {
double y = Screen.CenterY + Math.Sin(x * 0.02 + t * 3) * 80;
if (x == 0) Canvas.MoveTo(x, y);
else Canvas.LineTo(x, y);
}
Canvas.StrokePath();
});import math
from codetoy.canvas import fill, rect, stroke, lineWidth, beginPath, moveTo, lineTo, strokePath
from codetoy.screen import width, height, centerY
from codetoy.time import elapsedTime
def update():
t = elapsedTime()
fill(15, 15, 30)
rect(0, 0, width(), height())
stroke(100, 200, 255)
lineWidth(3)
beginPath()
for i in range(0, int(width()) + 1, 4):
y = centerY() + math.sin(i * 0.02 + t * 3) * 80
if i == 0:
moveTo(i, y)
else:
lineTo(i, y)
strokePath()#Orbits
Transforms and push()Canvas.Push()push()/pop()Canvas.Pop()pop(): a moon orbits a planet that orbits a sun.
import { fill, rect, circle, noStroke, push, pop, translate, rotate } from "codetoy/canvas"
import * as screen from "codetoy/screen"
import { elapsedTime } from "codetoy/time"
export function update(): void {
const t = elapsedTime()
noStroke()
fill(10, 10, 20)
rect(0, 0, screen.width(), screen.height())
push()
translate(screen.centerX(), screen.centerY())
fill(255, 200, 60)
circle(0, 0, 40) // sun
rotate(t * 0.8)
translate(150, 0)
fill(80, 160, 255)
circle(0, 0, 18) // planet
rotate(t * 3)
translate(36, 0)
fill(220, 220, 230)
circle(0, 0, 6) // moon
pop()
}double t = 0;
Screen.OnUpdate(() => {
t += Screen.DeltaTime;
Canvas.NoStroke();
Canvas.Fill(10, 10, 20);
Canvas.Rect(0, 0, Screen.Width, Screen.Height);
Canvas.Push();
Canvas.Translate(Screen.CenterX, Screen.CenterY);
Canvas.Fill(255, 200, 60);
Canvas.Circle(0, 0, 40); // sun
Canvas.Rotate(t * 0.8);
Canvas.Translate(150, 0);
Canvas.Fill(80, 160, 255);
Canvas.Circle(0, 0, 18); // planet
Canvas.Rotate(t * 3);
Canvas.Translate(36, 0);
Canvas.Fill(220, 220, 230);
Canvas.Circle(0, 0, 6); // moon
Canvas.Pop();
});from codetoy.canvas import fill, rect, circle, noStroke, push, pop, translate, rotate
from codetoy.screen import width, height, centerX, centerY
from codetoy.time import elapsedTime
def update():
t = elapsedTime()
noStroke()
fill(10, 10, 20)
rect(0, 0, width(), height())
push()
translate(centerX(), centerY())
fill(255, 200, 60)
circle(0, 0, 40) # sun
rotate(t * 0.8)
translate(150, 0)
fill(80, 160, 255)
circle(0, 0, 18) # planet
rotate(t * 3)
translate(36, 0)
fill(220, 220, 230)
circle(0, 0, 6) # moon
pop()#Multi-touch paint
Each finger paints in its own color, and old strokes slowly fade. Try it on a phone or tablet.
import { fill, rect, circle, noStroke } from "codetoy/canvas"
import * as screen from "codetoy/screen"
import * as input from "codetoy/input"
const ids = new Array<i32>()
export function onTouchStart(id: i32, x: f64, y: f64): void { ids.push(id) }
export function onTouchEnd(id: i32): void {
const i = ids.indexOf(id)
if (i >= 0) ids.splice(i, 1)
}
export function update(): void {
noStroke()
fill(20, 20, 30, 0.08) // translucent background leaves trails
rect(0, 0, screen.width(), screen.height())
for (let i = 0; i < ids.length; i++) {
const id = ids[i]
fill(120 + (id * 70) % 135, 255 - (id * 50) % 155, 200)
circle(input.touchX(id), input.touchY(id), 24)
}
}var colors = new Dictionary<int, (int R, int G)>();
var rng = new Random();
Input.OnTouchStart((int id, double x, double y) => colors[id] = (rng.Next(100, 256), rng.Next(100, 256)));
Input.OnTouchEnd((int id) => colors.Remove(id));
Screen.OnUpdate(() => {
Canvas.NoStroke();
Canvas.Fill(20, 20, 30, 0.08); // translucent background leaves trails
Canvas.Rect(0, 0, Screen.Width, Screen.Height);
foreach (var (id, c) in colors) {
if (!Input.IsTouchDown(id)) continue;
Canvas.Fill(c.R, c.G, 220);
Canvas.Circle(Input.TouchX(id), Input.TouchY(id), 24);
}
});import random
from codetoy.canvas import fill, rect, circle, noStroke
from codetoy.screen import width, height
from codetoy._input import isTouchDown, touchX, touchY
touches = {} # id -> color
def touchStart(id, x, y):
touches[id] = (random.randint(100, 255), random.randint(100, 255), 220)
def touchEnd(id):
touches.pop(id, None)
def update():
noStroke()
fill(20, 20, 30, 0.08) # translucent background leaves trails
rect(0, 0, width(), height())
for id, (r, g, b) in list(touches.items()):
if isTouchDown(id):
fill(r, g, b)
circle(touchX(id), touchY(id), 24)#Catch the stars
A complete mini-game: move the paddle with the arrow keys (or A/D), catch falling stars and don't miss three.
import { fill, rect, circle, text, font, measureText, noStroke } from "codetoy/canvas"
import * as screen from "codetoy/screen"
import * as input from "codetoy/input"
import { deltaTime } from "codetoy/time"
let paddleX: f64 = 200
let starX: f64 = 100
let starY: f64 = -20
let starSpeed: f64 = 180
let score = 0
let lives = 3
function dropStar(): void {
starX = 20 + Math.random() * (screen.width() - 40)
starY = -20
}
export function onKeyDown(key: string): void {
if (lives == 0 && key == " ") { score = 0; lives = 3; starSpeed = 180; dropStar() }
}
export function update(): void {
const dt = deltaTime()
const w = screen.width(), h = screen.height()
if (lives > 0) {
if (input.isKeyDown("ArrowLeft") || input.isKeyDown("a")) paddleX -= 420 * dt
if (input.isKeyDown("ArrowRight") || input.isKeyDown("d")) paddleX += 420 * dt
paddleX = Math.max(50, Math.min(w - 50, paddleX))
starY += starSpeed * dt
if (starY > h - 40 && starY < h - 20 && Math.abs(starX - paddleX) < 60) {
score++
starSpeed += 15
dropStar()
} else if (starY > h + 20) {
lives--
dropStar()
}
}
noStroke()
fill(15, 18, 35)
rect(0, 0, w, h)
fill(255, 220, 80)
circle(starX, starY, 12)
fill(120, 200, 255)
rect(paddleX - 50, h - 30, 100, 14, 7)
fill(255, 255, 255)
font("Arial", 18, "bold")
text("Score " + score.toString() + " Lives " + lives.toString(), 12, 12)
if (lives == 0) {
font("Arial", 28, "bold")
const msg = "Game over! Press Space"
text(msg, w / 2 - measureText(msg) / 2, h / 2 - 14)
}
}double paddleX = 200, starX = 100, starY = -20, starSpeed = 180;
int score = 0, lives = 3;
var rng = new Random();
void DropStar() {
starX = 20 + rng.NextDouble() * (Screen.Width - 40);
starY = -20;
}
Input.OnKeyDown((string key) => {
if (lives == 0 && key == " ") { score = 0; lives = 3; starSpeed = 180; DropStar(); }
});
Screen.OnUpdate(() => {
double dt = Screen.DeltaTime, w = Screen.Width, h = Screen.Height;
if (lives > 0) {
if (Input.IsKeyDown("ArrowLeft") || Input.IsKeyDown("a")) paddleX -= 420 * dt;
if (Input.IsKeyDown("ArrowRight") || Input.IsKeyDown("d")) paddleX += 420 * dt;
paddleX = Math.Clamp(paddleX, 50, w - 50);
starY += starSpeed * dt;
if (starY > h - 40 && starY < h - 20 && Math.Abs(starX - paddleX) < 60) {
score++;
starSpeed += 15;
DropStar();
} else if (starY > h + 20) {
lives--;
DropStar();
}
}
Canvas.NoStroke();
Canvas.Fill(15, 18, 35);
Canvas.Rect(0, 0, w, h);
Canvas.Fill(255, 220, 80);
Canvas.Circle(starX, starY, 12);
Canvas.Fill(120, 200, 255);
Canvas.Rect(paddleX - 50, h - 30, 100, 14, 7);
Canvas.Fill(255, 255, 255);
Canvas.Font("Arial", 18, "bold");
Canvas.Text($"Score {score} Lives {lives}", 12, 12);
if (lives == 0) {
Canvas.Font("Arial", 28, "bold");
string msg = "Game over! Press Space";
Canvas.Text(msg, w / 2 - Canvas.MeasureText(msg) / 2, h / 2 - 14);
}
});import random
from codetoy.canvas import fill, rect, circle, text, font, measureText, noStroke
from codetoy.screen import width, height
from codetoy.time import deltaTime
from codetoy._input import isKeyDown
paddle_x, star_x, star_y, star_speed = 200.0, 100.0, -20.0, 180.0
score, lives = 0, 3
def drop_star():
global star_x, star_y
star_x = random.uniform(20, width() - 20)
star_y = -20
def keyDown(key):
global score, lives, star_speed
if lives == 0 and key == " ":
score, lives, star_speed = 0, 3, 180
drop_star()
def update():
global paddle_x, star_y, star_speed, score, lives
dt, w, h = deltaTime(), width(), height()
if lives > 0:
if isKeyDown("ArrowLeft") or isKeyDown("a"): paddle_x -= 420 * dt
if isKeyDown("ArrowRight") or isKeyDown("d"): paddle_x += 420 * dt
paddle_x = max(50, min(w - 50, paddle_x))
star_y += star_speed * dt
if h - 40 < star_y < h - 20 and abs(star_x - paddle_x) < 60:
score += 1
star_speed += 15
drop_star()
elif star_y > h + 20:
lives -= 1
drop_star()
noStroke()
fill(15, 18, 35)
rect(0, 0, w, h)
fill(255, 220, 80)
circle(star_x, star_y, 12)
fill(120, 200, 255)
rect(paddle_x - 50, h - 30, 100, 14, 7)
fill(255, 255, 255)
font("Arial", 18, "bold")
text(f"Score {score} Lives {lives}", 12, 12)
if lives == 0:
font("Arial", 28, "bold")
msg = "Game over! Press Space"
text(msg, w / 2 - measureText(msg) / 2, h / 2 - 14)Make it a Discord game
The AssemblyScript version of Catch the stars is ready to publish. Capture a build and follow the Discord Activities guide to play it with friends.