├── img
├── background.png
└── warrior
│ ├── Attack1.png
│ ├── Attack2.png
│ ├── Attack3.png
│ ├── Death.png
│ ├── Fall.png
│ ├── FallLeft.png
│ ├── Idle.png
│ ├── IdleLeft.png
│ ├── Jump.png
│ ├── JumpLeft.png
│ ├── Run.png
│ ├── RunLeft.png
│ ├── Take Hit - white silhouette.png
│ └── Take Hit.png
├── index.html
├── index.js
└── js
├── classes
├── CollisionBlock.js
├── Player.js
└── Sprite.js
├── data
└── collisions.js
└── utils.js
/img/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chriscourses/vertical-platformer/fa3d460de134ae395eab4b2c5100fdb4a96a5bca/img/background.png
--------------------------------------------------------------------------------
/img/warrior/Attack1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chriscourses/vertical-platformer/fa3d460de134ae395eab4b2c5100fdb4a96a5bca/img/warrior/Attack1.png
--------------------------------------------------------------------------------
/img/warrior/Attack2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chriscourses/vertical-platformer/fa3d460de134ae395eab4b2c5100fdb4a96a5bca/img/warrior/Attack2.png
--------------------------------------------------------------------------------
/img/warrior/Attack3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chriscourses/vertical-platformer/fa3d460de134ae395eab4b2c5100fdb4a96a5bca/img/warrior/Attack3.png
--------------------------------------------------------------------------------
/img/warrior/Death.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chriscourses/vertical-platformer/fa3d460de134ae395eab4b2c5100fdb4a96a5bca/img/warrior/Death.png
--------------------------------------------------------------------------------
/img/warrior/Fall.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chriscourses/vertical-platformer/fa3d460de134ae395eab4b2c5100fdb4a96a5bca/img/warrior/Fall.png
--------------------------------------------------------------------------------
/img/warrior/FallLeft.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chriscourses/vertical-platformer/fa3d460de134ae395eab4b2c5100fdb4a96a5bca/img/warrior/FallLeft.png
--------------------------------------------------------------------------------
/img/warrior/Idle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chriscourses/vertical-platformer/fa3d460de134ae395eab4b2c5100fdb4a96a5bca/img/warrior/Idle.png
--------------------------------------------------------------------------------
/img/warrior/IdleLeft.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chriscourses/vertical-platformer/fa3d460de134ae395eab4b2c5100fdb4a96a5bca/img/warrior/IdleLeft.png
--------------------------------------------------------------------------------
/img/warrior/Jump.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chriscourses/vertical-platformer/fa3d460de134ae395eab4b2c5100fdb4a96a5bca/img/warrior/Jump.png
--------------------------------------------------------------------------------
/img/warrior/JumpLeft.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chriscourses/vertical-platformer/fa3d460de134ae395eab4b2c5100fdb4a96a5bca/img/warrior/JumpLeft.png
--------------------------------------------------------------------------------
/img/warrior/Run.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chriscourses/vertical-platformer/fa3d460de134ae395eab4b2c5100fdb4a96a5bca/img/warrior/Run.png
--------------------------------------------------------------------------------
/img/warrior/RunLeft.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chriscourses/vertical-platformer/fa3d460de134ae395eab4b2c5100fdb4a96a5bca/img/warrior/RunLeft.png
--------------------------------------------------------------------------------
/img/warrior/Take Hit - white silhouette.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chriscourses/vertical-platformer/fa3d460de134ae395eab4b2c5100fdb4a96a5bca/img/warrior/Take Hit - white silhouette.png
--------------------------------------------------------------------------------
/img/warrior/Take Hit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chriscourses/vertical-platformer/fa3d460de134ae395eab4b2c5100fdb4a96a5bca/img/warrior/Take Hit.png
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | const canvas = document.querySelector('canvas')
2 | const c = canvas.getContext('2d')
3 |
4 | canvas.width = 1024
5 | canvas.height = 576
6 |
7 | const scaledCanvas = {
8 | width: canvas.width / 4,
9 | height: canvas.height / 4,
10 | }
11 |
12 | const floorCollisions2D = []
13 | for (let i = 0; i < floorCollisions.length; i += 36) {
14 | floorCollisions2D.push(floorCollisions.slice(i, i + 36))
15 | }
16 |
17 | const collisionBlocks = []
18 | floorCollisions2D.forEach((row, y) => {
19 | row.forEach((symbol, x) => {
20 | if (symbol === 202) {
21 | collisionBlocks.push(
22 | new CollisionBlock({
23 | position: {
24 | x: x * 16,
25 | y: y * 16,
26 | },
27 | })
28 | )
29 | }
30 | })
31 | })
32 |
33 | const platformCollisions2D = []
34 | for (let i = 0; i < platformCollisions.length; i += 36) {
35 | platformCollisions2D.push(platformCollisions.slice(i, i + 36))
36 | }
37 |
38 | const platformCollisionBlocks = []
39 | platformCollisions2D.forEach((row, y) => {
40 | row.forEach((symbol, x) => {
41 | if (symbol === 202) {
42 | platformCollisionBlocks.push(
43 | new CollisionBlock({
44 | position: {
45 | x: x * 16,
46 | y: y * 16,
47 | },
48 | height: 4,
49 | })
50 | )
51 | }
52 | })
53 | })
54 |
55 | const gravity = 0.1
56 |
57 | const player = new Player({
58 | position: {
59 | x: 100,
60 | y: 300,
61 | },
62 | collisionBlocks,
63 | platformCollisionBlocks,
64 | imageSrc: './img/warrior/Idle.png',
65 | frameRate: 8,
66 | animations: {
67 | Idle: {
68 | imageSrc: './img/warrior/Idle.png',
69 | frameRate: 8,
70 | frameBuffer: 3,
71 | },
72 | Run: {
73 | imageSrc: './img/warrior/Run.png',
74 | frameRate: 8,
75 | frameBuffer: 5,
76 | },
77 | Jump: {
78 | imageSrc: './img/warrior/Jump.png',
79 | frameRate: 2,
80 | frameBuffer: 3,
81 | },
82 | Fall: {
83 | imageSrc: './img/warrior/Fall.png',
84 | frameRate: 2,
85 | frameBuffer: 3,
86 | },
87 | FallLeft: {
88 | imageSrc: './img/warrior/FallLeft.png',
89 | frameRate: 2,
90 | frameBuffer: 3,
91 | },
92 | RunLeft: {
93 | imageSrc: './img/warrior/RunLeft.png',
94 | frameRate: 8,
95 | frameBuffer: 5,
96 | },
97 | IdleLeft: {
98 | imageSrc: './img/warrior/IdleLeft.png',
99 | frameRate: 8,
100 | frameBuffer: 3,
101 | },
102 | JumpLeft: {
103 | imageSrc: './img/warrior/JumpLeft.png',
104 | frameRate: 2,
105 | frameBuffer: 3,
106 | },
107 | },
108 | })
109 |
110 | const keys = {
111 | d: {
112 | pressed: false,
113 | },
114 | a: {
115 | pressed: false,
116 | },
117 | }
118 |
119 | const background = new Sprite({
120 | position: {
121 | x: 0,
122 | y: 0,
123 | },
124 | imageSrc: './img/background.png',
125 | })
126 |
127 | const backgroundImageHeight = 432
128 |
129 | const camera = {
130 | position: {
131 | x: 0,
132 | y: -backgroundImageHeight + scaledCanvas.height,
133 | },
134 | }
135 |
136 | function animate() {
137 | window.requestAnimationFrame(animate)
138 | c.fillStyle = 'white'
139 | c.fillRect(0, 0, canvas.width, canvas.height)
140 |
141 | c.save()
142 | c.scale(4, 4)
143 | c.translate(camera.position.x, camera.position.y)
144 | background.update()
145 | // collisionBlocks.forEach((collisionBlock) => {
146 | // collisionBlock.update()
147 | // })
148 |
149 | // platformCollisionBlocks.forEach((block) => {
150 | // block.update()
151 | // })
152 |
153 | player.checkForHorizontalCanvasCollision()
154 | player.update()
155 |
156 | player.velocity.x = 0
157 | if (keys.d.pressed) {
158 | player.switchSprite('Run')
159 | player.velocity.x = 2
160 | player.lastDirection = 'right'
161 | player.shouldPanCameraToTheLeft({ canvas, camera })
162 | } else if (keys.a.pressed) {
163 | player.switchSprite('RunLeft')
164 | player.velocity.x = -2
165 | player.lastDirection = 'left'
166 | player.shouldPanCameraToTheRight({ canvas, camera })
167 | } else if (player.velocity.y === 0) {
168 | if (player.lastDirection === 'right') player.switchSprite('Idle')
169 | else player.switchSprite('IdleLeft')
170 | }
171 |
172 | if (player.velocity.y < 0) {
173 | player.shouldPanCameraDown({ camera, canvas })
174 | if (player.lastDirection === 'right') player.switchSprite('Jump')
175 | else player.switchSprite('JumpLeft')
176 | } else if (player.velocity.y > 0) {
177 | player.shouldPanCameraUp({ camera, canvas })
178 | if (player.lastDirection === 'right') player.switchSprite('Fall')
179 | else player.switchSprite('FallLeft')
180 | }
181 |
182 | c.restore()
183 | }
184 |
185 | animate()
186 |
187 | window.addEventListener('keydown', (event) => {
188 | switch (event.key) {
189 | case 'd':
190 | keys.d.pressed = true
191 | break
192 | case 'a':
193 | keys.a.pressed = true
194 | break
195 | case 'w':
196 | player.velocity.y = -4
197 | break
198 | }
199 | })
200 |
201 | window.addEventListener('keyup', (event) => {
202 | switch (event.key) {
203 | case 'd':
204 | keys.d.pressed = false
205 | break
206 | case 'a':
207 | keys.a.pressed = false
208 | break
209 | }
210 | })
211 |
--------------------------------------------------------------------------------
/js/classes/CollisionBlock.js:
--------------------------------------------------------------------------------
1 | class CollisionBlock {
2 | constructor({ position, height = 16 }) {
3 | this.position = position
4 | this.width = 16
5 | this.height = height
6 | }
7 |
8 | draw() {
9 | c.fillStyle = 'rgba(255, 0, 0, 0.5)'
10 | c.fillRect(this.position.x, this.position.y, this.width, this.height)
11 | }
12 |
13 | update() {
14 | this.draw()
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/js/classes/Player.js:
--------------------------------------------------------------------------------
1 | class Player extends Sprite {
2 | constructor({
3 | position,
4 | collisionBlocks,
5 | platformCollisionBlocks,
6 | imageSrc,
7 | frameRate,
8 | scale = 0.5,
9 | animations,
10 | }) {
11 | super({ imageSrc, frameRate, scale })
12 | this.position = position
13 | this.velocity = {
14 | x: 0,
15 | y: 1,
16 | }
17 |
18 | this.collisionBlocks = collisionBlocks
19 | this.platformCollisionBlocks = platformCollisionBlocks
20 | this.hitbox = {
21 | position: {
22 | x: this.position.x,
23 | y: this.position.y,
24 | },
25 | width: 10,
26 | height: 10,
27 | }
28 |
29 | this.animations = animations
30 | this.lastDirection = 'right'
31 |
32 | for (let key in this.animations) {
33 | const image = new Image()
34 | image.src = this.animations[key].imageSrc
35 |
36 | this.animations[key].image = image
37 | }
38 |
39 | this.camerabox = {
40 | position: {
41 | x: this.position.x,
42 | y: this.position.y,
43 | },
44 | width: 200,
45 | height: 80,
46 | }
47 | }
48 |
49 | switchSprite(key) {
50 | if (this.image === this.animations[key].image || !this.loaded) return
51 |
52 | this.currentFrame = 0
53 | this.image = this.animations[key].image
54 | this.frameBuffer = this.animations[key].frameBuffer
55 | this.frameRate = this.animations[key].frameRate
56 | }
57 |
58 | updateCamerabox() {
59 | this.camerabox = {
60 | position: {
61 | x: this.position.x - 50,
62 | y: this.position.y,
63 | },
64 | width: 200,
65 | height: 80,
66 | }
67 | }
68 |
69 | checkForHorizontalCanvasCollision() {
70 | if (
71 | this.hitbox.position.x + this.hitbox.width + this.velocity.x >= 576 ||
72 | this.hitbox.position.x + this.velocity.x <= 0
73 | ) {
74 | this.velocity.x = 0
75 | }
76 | }
77 |
78 | shouldPanCameraToTheLeft({ canvas, camera }) {
79 | const cameraboxRightSide = this.camerabox.position.x + this.camerabox.width
80 | const scaledDownCanvasWidth = canvas.width / 4
81 |
82 | if (cameraboxRightSide >= 576) return
83 |
84 | if (
85 | cameraboxRightSide >=
86 | scaledDownCanvasWidth + Math.abs(camera.position.x)
87 | ) {
88 | camera.position.x -= this.velocity.x
89 | }
90 | }
91 |
92 | shouldPanCameraToTheRight({ canvas, camera }) {
93 | if (this.camerabox.position.x <= 0) return
94 |
95 | if (this.camerabox.position.x <= Math.abs(camera.position.x)) {
96 | camera.position.x -= this.velocity.x
97 | }
98 | }
99 |
100 | shouldPanCameraDown({ canvas, camera }) {
101 | if (this.camerabox.position.y + this.velocity.y <= 0) return
102 |
103 | if (this.camerabox.position.y <= Math.abs(camera.position.y)) {
104 | camera.position.y -= this.velocity.y
105 | }
106 | }
107 |
108 | shouldPanCameraUp({ canvas, camera }) {
109 | if (
110 | this.camerabox.position.y + this.camerabox.height + this.velocity.y >=
111 | 432
112 | )
113 | return
114 |
115 | const scaledCanvasHeight = canvas.height / 4
116 |
117 | if (
118 | this.camerabox.position.y + this.camerabox.height >=
119 | Math.abs(camera.position.y) + scaledCanvasHeight
120 | ) {
121 | camera.position.y -= this.velocity.y
122 | }
123 | }
124 |
125 | update() {
126 | this.updateFrames()
127 | this.updateHitbox()
128 |
129 | this.updateCamerabox()
130 | // c.fillStyle = 'rgba(0, 0, 255, 0.2)'
131 | // c.fillRect(
132 | // this.camerabox.position.x,
133 | // this.camerabox.position.y,
134 | // this.camerabox.width,
135 | // this.camerabox.height
136 | // )
137 |
138 | // draws out the image
139 | // c.fillStyle = 'rgba(0, 255, 0, 0.2)'
140 | // c.fillRect(this.position.x, this.position.y, this.width, this.height)
141 |
142 | // c.fillStyle = 'rgba(255, 0, 0, 0.2)'
143 | // c.fillRect(
144 | // this.hitbox.position.x,
145 | // this.hitbox.position.y,
146 | // this.hitbox.width,
147 | // this.hitbox.height
148 | // )
149 |
150 | this.draw()
151 |
152 | this.position.x += this.velocity.x
153 | this.updateHitbox()
154 | this.checkForHorizontalCollisions()
155 | this.applyGravity()
156 | this.updateHitbox()
157 | this.checkForVerticalCollisions()
158 | }
159 |
160 | updateHitbox() {
161 | this.hitbox = {
162 | position: {
163 | x: this.position.x + 35,
164 | y: this.position.y + 26,
165 | },
166 | width: 14,
167 | height: 27,
168 | }
169 | }
170 |
171 | checkForHorizontalCollisions() {
172 | for (let i = 0; i < this.collisionBlocks.length; i++) {
173 | const collisionBlock = this.collisionBlocks[i]
174 |
175 | if (
176 | collision({
177 | object1: this.hitbox,
178 | object2: collisionBlock,
179 | })
180 | ) {
181 | if (this.velocity.x > 0) {
182 | this.velocity.x = 0
183 |
184 | const offset =
185 | this.hitbox.position.x - this.position.x + this.hitbox.width
186 |
187 | this.position.x = collisionBlock.position.x - offset - 0.01
188 | break
189 | }
190 |
191 | if (this.velocity.x < 0) {
192 | this.velocity.x = 0
193 |
194 | const offset = this.hitbox.position.x - this.position.x
195 |
196 | this.position.x =
197 | collisionBlock.position.x + collisionBlock.width - offset + 0.01
198 | break
199 | }
200 | }
201 | }
202 | }
203 |
204 | applyGravity() {
205 | this.velocity.y += gravity
206 | this.position.y += this.velocity.y
207 | }
208 |
209 | checkForVerticalCollisions() {
210 | for (let i = 0; i < this.collisionBlocks.length; i++) {
211 | const collisionBlock = this.collisionBlocks[i]
212 |
213 | if (
214 | collision({
215 | object1: this.hitbox,
216 | object2: collisionBlock,
217 | })
218 | ) {
219 | if (this.velocity.y > 0) {
220 | this.velocity.y = 0
221 |
222 | const offset =
223 | this.hitbox.position.y - this.position.y + this.hitbox.height
224 |
225 | this.position.y = collisionBlock.position.y - offset - 0.01
226 | break
227 | }
228 |
229 | if (this.velocity.y < 0) {
230 | this.velocity.y = 0
231 |
232 | const offset = this.hitbox.position.y - this.position.y
233 |
234 | this.position.y =
235 | collisionBlock.position.y + collisionBlock.height - offset + 0.01
236 | break
237 | }
238 | }
239 | }
240 |
241 | // platform collision blocks
242 | for (let i = 0; i < this.platformCollisionBlocks.length; i++) {
243 | const platformCollisionBlock = this.platformCollisionBlocks[i]
244 |
245 | if (
246 | platformCollision({
247 | object1: this.hitbox,
248 | object2: platformCollisionBlock,
249 | })
250 | ) {
251 | if (this.velocity.y > 0) {
252 | this.velocity.y = 0
253 |
254 | const offset =
255 | this.hitbox.position.y - this.position.y + this.hitbox.height
256 |
257 | this.position.y = platformCollisionBlock.position.y - offset - 0.01
258 | break
259 | }
260 | }
261 | }
262 | }
263 | }
264 |
--------------------------------------------------------------------------------
/js/classes/Sprite.js:
--------------------------------------------------------------------------------
1 | class Sprite {
2 | constructor({
3 | position,
4 | imageSrc,
5 | frameRate = 1,
6 | frameBuffer = 3,
7 | scale = 1,
8 | }) {
9 | this.position = position
10 | this.scale = scale
11 | this.loaded = false
12 | this.image = new Image()
13 | this.image.onload = () => {
14 | this.width = (this.image.width / this.frameRate) * this.scale
15 | this.height = this.image.height * this.scale
16 | this.loaded = true
17 | }
18 | this.image.src = imageSrc
19 | this.frameRate = frameRate
20 | this.currentFrame = 0
21 | this.frameBuffer = frameBuffer
22 | this.elapsedFrames = 0
23 | }
24 |
25 | draw() {
26 | if (!this.image) return
27 |
28 | const cropbox = {
29 | position: {
30 | x: this.currentFrame * (this.image.width / this.frameRate),
31 | y: 0,
32 | },
33 | width: this.image.width / this.frameRate,
34 | height: this.image.height,
35 | }
36 |
37 | c.drawImage(
38 | this.image,
39 | cropbox.position.x,
40 | cropbox.position.y,
41 | cropbox.width,
42 | cropbox.height,
43 | this.position.x,
44 | this.position.y,
45 | this.width,
46 | this.height
47 | )
48 | }
49 |
50 | update() {
51 | this.draw()
52 | this.updateFrames()
53 | }
54 |
55 | updateFrames() {
56 | this.elapsedFrames++
57 |
58 | if (this.elapsedFrames % this.frameBuffer === 0) {
59 | if (this.currentFrame < this.frameRate - 1) this.currentFrame++
60 | else this.currentFrame = 0
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/js/data/collisions.js:
--------------------------------------------------------------------------------
1 | const floorCollisions = [
2 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
9 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
10 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
11 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
12 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
13 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
14 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
16 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
17 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
18 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
19 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
20 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
21 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
22 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
23 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
24 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
25 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
26 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
27 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
28 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
29 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
30 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
31 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
32 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 202, 202, 202, 0, 0, 0, 0, 0, 0, 0, 0, 0,
33 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
34 | 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
35 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
36 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 202, 202,
37 | 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202,
38 | 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202,
39 | 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
40 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
41 | ]
42 |
43 | const platformCollisions = [
44 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
45 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
46 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
47 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
48 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
49 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 202, 202, 202, 0, 0, 0, 0, 0, 0, 0,
50 | 0, 0, 202, 202, 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 202, 202, 202, 0, 0, 0, 202,
51 | 202, 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
52 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 202, 202,
53 | 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 202, 202, 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
54 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
55 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
56 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
57 | 202, 202, 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 202, 202, 202, 0, 0, 0, 0, 0, 0, 0,
58 | 0, 0, 0, 0, 0, 202, 202, 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
59 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
60 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
61 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 202, 202, 202, 0, 0, 0, 0, 0,
62 | 0, 0, 0, 0, 202, 202, 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
63 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
64 | 202, 202, 202, 0, 0, 0, 0, 0, 0, 0, 202, 202, 202, 0, 0, 0, 0, 0, 0, 0, 0,
65 | 202, 202, 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
66 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
67 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 202, 202, 202, 0, 0, 0, 0, 0,
68 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
69 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 202, 202,
70 | 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
71 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 202,
72 | 202, 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
73 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
74 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
75 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 202, 202, 202, 0, 0, 0, 0, 0, 0,
76 | 0, 0, 0, 202, 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
77 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
78 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
79 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
80 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
81 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
82 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
83 | ]
84 |
--------------------------------------------------------------------------------
/js/utils.js:
--------------------------------------------------------------------------------
1 | function collision({ object1, object2 }) {
2 | return (
3 | object1.position.y + object1.height >= object2.position.y &&
4 | object1.position.y <= object2.position.y + object2.height &&
5 | object1.position.x <= object2.position.x + object2.width &&
6 | object1.position.x + object1.width >= object2.position.x
7 | )
8 | }
9 |
10 | function platformCollision({ object1, object2 }) {
11 | return (
12 | object1.position.y + object1.height >= object2.position.y &&
13 | object1.position.y + object1.height <=
14 | object2.position.y + object2.height &&
15 | object1.position.x <= object2.position.x + object2.width &&
16 | object1.position.x + object1.width >= object2.position.x
17 | )
18 | }
19 |
--------------------------------------------------------------------------------