Skip to content

Instantly share code, notes, and snippets.

@PifyZ
Last active May 1, 2016 20:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PifyZ/dfbf9e6231adb22dacb7a1dcd50d363a to your computer and use it in GitHub Desktop.
Save PifyZ/dfbf9e6231adb22dacb7a1dcd50d363a to your computer and use it in GitHub Desktop.
shopt -s globstar
skewc src/**/*.sk --output-file=app.js --target=js --message-limit=0
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, user-scalable=no"
/>
<link rel="stylesheet" type="text/css" href="./web/css/style.css" />
<title>Physics engine</title>
</head>
<body>
<canvas class="layer" id="app"></canvas>
<script src="./app.js"></script>
</body>
</html>
const map = [
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ],
[ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ],
[ 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ],
[ 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ],
[ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ],
[ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ],
[ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ],
[ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ],
[ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ],
[ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ],
[ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ],
[ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ],
[ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ],
[ 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ],
[ 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ],
[ 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ],
[ 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ],
[ 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ],
[ 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ],
[ 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ],
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ]
]
class Point {
var x double
var y double
}
namespace Game {
const GRID = 20
var hero Entity
}
namespace Entity {
var ALL = List<Entity>.new
}
class AABB {
var x double
var y double
var width double
var height double
def overlaps(r AABB) bool {
return x < r.x + r.width && x + width > r.x &&
y < r.y + r.height && y + height > r.y
}
}
class Entity {
var repels bool
var radius double
var weight double
var dx double
var dy double
var killed bool
var cx double
var xr double
var cy double
var yr double
var xx int
var yy int
var frict double
def new(radius double) {
self.radius = radius
repels = true
cx = 5
cy = 5
xr = 0.5
yr = 0.5
xx = 0
yy = 0
weight = 1
killed = false
frict = 0.98
}
def aabb AABB {
return AABB.new(xx - radius, yy - radius, radius * 2, radius * 2)
}
def update {
if repels {
for e in ALL {
if e != self && !e.killed && e.repels && isClose(e) {
var pt = getPoint
var ept = e.getPoint
var d = distance(pt.x, pt.y, ept.x, ept.y)
var min = radius + e.radius
if d < min {
var angle = Math.atan2(e.yy - yy, e.xx - xx) / Math.PI
var conflict = min - d
var w = weight / (weight + e.weight)
var ew = e.weight / (weight + e.weight)
if angle >= 0.25 && angle < 0.75 {
dy -= (conflict / Game.GRID) * ew
e.dy += (conflict / Game.GRID) * w
} else if angle >= -0.75 && angle < -0.25 {
dy += (conflict / Game.GRID) * ew
e.dy -= (conflict / Game.GRID) * w
} else if angle >= -0.25 && angle < 0.25 {
dx -= (conflict / Game.GRID) * ew
e.dx += (conflict / Game.GRID) * w
} else if (angle >= -1 && angle < -0.75) || (angle > 0.75 && angle < 1) {
dx += (conflict / Game.GRID) * ew
e.dx -= (conflict / Game.GRID) * w
}
###
dx -= Math.cos(a) * (conflict / Game.GRID) * ew
dy -= Math.sin(a) * (conflict / Game.GRID) * ew
e.dx += Math.cos(a) * (conflict / Game.GRID) * w
e.dy += Math.sin(a) * (conflict / Game.GRID) * w
if e == Game.hero {
onHeroContact
}
###
}
}
}
}
xr += dx
dx *= frict
while xr < 0 {
cx--
xr++
}
while xr > 1 {
cx++
xr--
}
yr += dy
dy *= frict
while yr < 0 {
cy--
yr++
}
while yr > 1 {
cy++
yr--
}
xx = (cx * Game.GRID + xr * Game.GRID) as int
yy = (cy * Game.GRID + yr * Game.GRID) as int
}
def isClose(e Entity) bool {
return Math.abs(cx - e.cx) <= 2 && Math.abs(cy - e.cy) <= 2
}
def getPoint Point {
return Point.new((cx + xr) * Game.GRID, (cy + yr) * Game.GRID)
}
def distance(x1 double, y1 double, x2 double, y2 double) double {
return Math.sqrt((x1 - x2) ** 2 + ((y1 - y2) ** 2))
}
def onHeroContact {
}
def draw(ctx CanvasRenderingContext2D) {
ctx.drawImage(Img.get("crate"), xx - radius, yy - radius)
# ctx.fillRect(aabb.x, aabb.y, aabb.width, aabb.height)
###
ctx.fillStyle = "rgb(0, 255, 0)"
ctx.beginPath
ctx.arc(xx, yy, radius, 0, Math.PI * 2)
ctx.fill
###
}
}
class Player : Entity {
over draw(ctx CanvasRenderingContext2D) {
ctx.drawImage(Img.get("player"), 0, 0, 14, 15, xx - radius, yy - radius, 14, 15)
# ctx.fillRect(aabb.x, aabb.y, aabb.width, aabb.height)
###
ctx.fillStyle = "rgb(0, 255, 0)"
ctx.beginPath
ctx.arc(xx, yy, radius, 0, Math.PI * 2)
ctx.fill
###
}
}
# APPLICATION
# -----------
var ctx CanvasRenderingContext2D
var kb = input.Keyboard.new
def tick {
Entity.ALL[2].dx = 0
Entity.ALL[2].dy = 0
if kb.down(Key.Left) {
Entity.ALL[2].dx -= 0.2
}
if kb.down(Key.Right) {
Entity.ALL[2].dx += 0.2
}
if kb.down(Key.Up) {
Entity.ALL[2].dy -= 0.2
}
if kb.down(Key.Down) {
Entity.ALL[2].dy += 0.2
}
ctx.clearRect(0, 0, 640, 480)
for y in 0 .. map.count - 1 {
for x in 0 .. map[y].count - 1 {
if map[y][x] == 1 {
ctx.fillRect(x * Game.GRID, y * Game.GRID, Game.GRID, Game.GRID)
}
}
}
for entity in Entity.ALL {
entity.update
}
for entity in Entity.ALL {
entity.draw(ctx)
}
requestAnimationFrame(=> tick)
}
@entry
def main {
var images = {
"player": "player.png",
"wall": "wall.png",
"ground": "ground.png",
"font": "font.png",
"font2": "font2.png",
"barrel": "block-barrel.png",
"mine": "block-mine.png",
"dynamite": "block-dynamite.png",
"crate": "block-crate.png",
"bullet": "bullet-normal.png",
"rocketLauncherBullet": "bullet-rocket-launcher.png",
"grenade": "bullet-grenade.png",
"miniatures": "miniatures-weapons.png",
"bonusIncreaseHealth": "bonus-increase-health.png"
}
Img.setPath("assets/img")
Img.setCallback(=> run)
Img.load(images)
}
def run {
var canvas = document.getElementById("app") as HTMLCanvasElement
canvas.width = 640
canvas.height = 480
ctx = canvas.getContext2D
Entity.ALL.append(Entity.new(12))
Entity.ALL.append(Entity.new(12))
Entity.ALL.append(Player.new(7))
Game.hero = Entity.ALL[2]
Entity.ALL[0].cx = 25
Entity.ALL[0].cy = 16
Entity.ALL[0].weight = 20
Entity.ALL[0].frict = 0
Entity.ALL[1].cx = 18
Entity.ALL[1].cy = 11
Entity.ALL[1].weight = 20
Entity.ALL[1].frict = 0
Entity.ALL[2].weight = 10
tick
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment