Skip to content

Commit 4ca9c8b

Browse files
author
Alex Swan
committed
More examples
1 parent 238d5a7 commit 4ca9c8b

File tree

14 files changed

+3118
-2216
lines changed

14 files changed

+3118
-2216
lines changed

boggle.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@
88
<canvas id='canvas' width=480 height=600></canvas>
99
<script src="kontra.js"></script>
1010
<script src="boggle.js"></script>
11+
<div>Drag to connect adjacent letters. Find words.</div>
1112
</body>
1213
</html>

boggle.js

Lines changed: 1 addition & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

critter.html

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<html>
2+
<head>
3+
<title>One Button Race</title>
4+
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
5+
<link rel="stylesheet" type="text/css" href="main.css">
6+
</head>
7+
<body>
8+
<canvas id='canvas' width=480 height=600></canvas>
9+
<div>Feed the center "critter" by dragging "food" of the same color to it. Incorrect colors make it sick.</div>
10+
<script src="kontra.js"></script>
11+
<script src="critter.js"></script>
12+
</body>
13+
</html>

critter.js

Lines changed: 319 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,319 @@
1+
2+
const SCREENSHOT_UPDATE_DELAY = 60; // send a screenshot every 60 frames
3+
const COLOR_AMBER = '#FFBF00'
4+
const COLOR_GREEN = '#33ff33'
5+
const COLOR_DURATION = 150
6+
var Foods = [
7+
{x:0.25, y: 0.25, color: '#3c6e6f'},
8+
{x:0.5, y: 0.25, color: '#007727'},
9+
{x:0.75, y: 0.25, color: '#b8aa01'},
10+
11+
{x:0.25, y: 0.5, color: '#0350a0'},
12+
{x:0.75, y: 0.5, color: '#966401'},
13+
14+
{x:0.25, y: 0.75, color: '#48019d'},
15+
{x:0.5, y: 0.75, color: '#730075'},
16+
{x:0.75, y: 0.75, color: '#9c0e3e'}
17+
]
18+
kontra.init();
19+
20+
var sprites = []
21+
22+
var degreesToRadians = function (deg) {
23+
return deg * Math.PI / 180;
24+
}
25+
26+
function lerp (min, max, t) {
27+
return min * (1-t) + max * t
28+
}
29+
30+
function damp (a, b, lambda, dt) {
31+
return lerp(a, b, 1 - Math.exp(-lambda * dt))
32+
}
33+
34+
function shuffle(array) {
35+
var m = array.length, t, i;
36+
37+
// While there remain elements to shuffle…
38+
while (m) {
39+
40+
// Pick a remaining element…
41+
i = Math.floor(Math.random() * m--);
42+
43+
// And swap it with the current element.
44+
t = array[m];
45+
array[m] = array[i];
46+
array[i] = t;
47+
}
48+
49+
return array;
50+
}
51+
52+
var score = kontra.sprite({
53+
x:0,
54+
y:480,
55+
hunger:0,
56+
color: COLOR_AMBER,
57+
render: function () {
58+
// Make a progress bar
59+
this.context.fillStyle = '#333';
60+
this.context.fillRect(this.x, this.y, kontra.canvas.width, kontra.canvas.height - this.y)
61+
this.context.fillStyle = '#666';
62+
let percent = this.hunger / 40.0;
63+
let percentWidth = percent * kontra.canvas.width
64+
this.context.fillRect(this.x, this.y, percentWidth, kontra.canvas.height - this.y)
65+
66+
// Write the hunger
67+
this.context.fillStyle = this.color;
68+
this.context.font = "48px Courier New"
69+
this.context.textBaseline = 'top'
70+
this.context.fillText(this.hunger + '/40', this.x, this.y)
71+
}
72+
})
73+
sprites.unshift(score)
74+
75+
var critter = {
76+
anchor: {
77+
x: 0.5,
78+
y: 0.5
79+
},
80+
x: kontra.canvas.width * 0.5, // remove - 48 when anchor works with pointers
81+
y: kontra.canvas.width * 0.5, // Width bc we don't want to count the bar at the bottom
82+
width:96,
83+
height:96,
84+
color: COLOR_GREEN,
85+
selected: false,
86+
colorFrames: 0,
87+
sick: false,
88+
desiredRotation: 0,
89+
collidesWith(object) {
90+
// We're ok with the collision being a rough estimate, ignore rotation
91+
// if (this.rotation || object.rotation) return null;
92+
93+
// take into account sprite anchors
94+
let x = this.x - this.width * this.anchor.x;
95+
let y = this.y - this.height * this.anchor.y;
96+
97+
let objX = object.x;
98+
let objY = object.y;
99+
if (object.anchor) {
100+
objX -= object.width * object.anchor.x;
101+
objY -= object.height * object.anchor.y;
102+
}
103+
104+
return x < objX + object.width &&
105+
x + this.width > objX &&
106+
y < objY + object.height &&
107+
y + this.height > objY;
108+
},
109+
update: function (dt) {
110+
if (!this.colorFrames || this.colorFrames<=0){
111+
this.newColor()
112+
this.sick = false
113+
}
114+
this.colorFrames--
115+
if (this.colorFrames < 15) {
116+
this.desiredRotation = degreesToRadians(-45)
117+
}
118+
this.advance()
119+
this.rotation = damp(this.rotation, this.desiredRotation, 8, dt)
120+
121+
if (this.sick && this.colorFrames > 25) {
122+
if (Math.floor(Math.random()*4) == 0) { // One in 4 chance
123+
let b = kontra.sprite({
124+
x:this.x,
125+
y:this.y + this.height*0.25,
126+
color: '#ffffff',
127+
dx: Math.random()*9-2,
128+
dy:1,
129+
ddy: 1.0,
130+
width:12,
131+
height:12,
132+
ttl: 4 * 60,
133+
update: function(dt){ // override to get desired behavior
134+
this.advance()
135+
}
136+
})
137+
sprites.push(b)
138+
// b.x = this.x
139+
// b.y = this.y
140+
// b.radius = b.width = 8
141+
// b.dx = {'up':0, 'down':0, 'left':5, 'right':-5}[this.direction]
142+
// b.dy = {'up':5, 'down':-5, 'left':0, 'right':0}[this.direction]
143+
// sprites.push(b)
144+
}
145+
}
146+
},
147+
feed: function (color) {
148+
if (this.sickFrames>0) return
149+
if (this.color !== color) { // Fail
150+
this.sick = true
151+
this.color = "#ff00ff"
152+
this.colorFrames = 4 * 60
153+
154+
} else { // Success
155+
score.hunger++
156+
this.colorFrames = 0
157+
158+
// Throw some particles
159+
for (let i = 0; i < 18; i++) {
160+
let particle = kontra.sprite({
161+
type:'particle',
162+
x: this.x,
163+
y: this.y,
164+
dx: 24 * Math.cos(degreesToRadians(i*20)),
165+
dy: 24 * Math.sin(degreesToRadians(i*20)),
166+
ttl: 20,
167+
width:16,
168+
height:16,
169+
color:'#fff',
170+
update: function (dt) {
171+
// this.color = '#' + (this.ttl*15).toString(16) + (this.ttl*15).toString(16) + '00'
172+
this.advance()
173+
},
174+
render: function () {
175+
kontra.context.save()
176+
kontra.context.fillStyle = this.color
177+
kontra.context.beginPath()
178+
kontra.context.arc(this.x, this.y, 16, 0, 2*Math.PI)
179+
kontra.context.fill()
180+
kontra.context.restore()
181+
}
182+
})
183+
sprites.push(particle)
184+
}
185+
// Shuffle the foods
186+
shuffle(Foods)
187+
let foodIndex = 0;
188+
sprites.forEach(sprite => {
189+
if (sprite.type == 'food') {
190+
sprite.desiredX = Foods[foodIndex].x * kontra.canvas.width
191+
sprite.desiredY = Foods[foodIndex].y * kontra.canvas.width
192+
sprite.dx = Math.floor(Math.random() * 2) == 0 ? -1 : 1
193+
sprite.dy = Math.floor(Math.random() * 2) == 0 ? -1 : 1
194+
foodIndex++
195+
}
196+
})
197+
}
198+
},
199+
newColor: function (dt) {
200+
this.color = Foods[Math.floor(Math.random()*Foods.length)].color
201+
this.colorFrames = COLOR_DURATION
202+
this.rotation -= degreesToRadians(180)
203+
this.desiredRotation = 0
204+
}
205+
}
206+
207+
let food = {
208+
type: 'food',
209+
anchor: {
210+
x: 0.5,
211+
y: 0.5
212+
},
213+
x: kontra.canvas.width/2, // remove - 48 when anchor works with pointers
214+
y: kontra.canvas.width/2, // Width bc we don't want to count the bar at the bottom
215+
desiredX: 240,
216+
desiredY: 480,
217+
width:48,
218+
height:48,
219+
color: COLOR_GREEN,
220+
selected: false,
221+
onDown: function() {
222+
this.selected = true;
223+
this.lastPosition = {
224+
x: kontra.pointer.x,
225+
y: kontra.pointer.y
226+
}
227+
},
228+
onUp: function() {
229+
this.selected = false;
230+
if (this.critter) {
231+
if (this.critter.collidesWith(this)) {
232+
this.critter.feed(this.color)
233+
}
234+
}
235+
},
236+
update: function(dt) {
237+
if (!kontra.pointer.pressed('left')) this.selected = false
238+
if (!this.selected) {
239+
// damp it back to desiredX
240+
this.desiredX += this.dx
241+
this.desiredY += this.dy
242+
if (this.desiredX < 0) this.dx = Math.abs(this.dx)
243+
if (this.desiredX > kontra.canvas.width) this.dx = -1 * Math.abs(this.dx)
244+
if (this.desiredY < 0) this.dy = Math.abs(this.dx)
245+
if (this.desiredY > kontra.canvas.width) this.dy = -1 * Math.abs(this.dy)
246+
247+
this.x = damp(this.x, this.desiredX, 8, dt)
248+
this.y = damp(this.y, this.desiredY, 8, dt)
249+
this.advance()
250+
} else {
251+
let dx = kontra.pointer.x - this.lastPosition.x
252+
let dy = kontra.pointer.y - this.lastPosition.y
253+
254+
this.x += dx
255+
this.y += dy
256+
257+
// // Flinging
258+
// this.dx = dx
259+
// this.dy = dy
260+
261+
this.lastPosition = {
262+
x: kontra.pointer.x,
263+
y: kontra.pointer.y
264+
}
265+
266+
// Collision
267+
268+
}
269+
},
270+
}
271+
272+
var debugSprite = kontra.sprite({
273+
render: function() {
274+
kontra.context.save()
275+
this.context.fillStyle = "#ff00ff";
276+
this.context.font = "24px Courier New"
277+
this.context.textBaseline = 'top'
278+
// this.context.fillText("pointer: " + kontra.pointer.pressed('left'), 0, 0)
279+
280+
kontra.context.restore()
281+
}
282+
})
283+
sprites.push(debugSprite)
284+
285+
let reset = function() {
286+
// Place the critter in the middle
287+
let critterSprite = kontra.sprite(critter)
288+
sprites.push(critterSprite)
289+
kontra.pointer.track(critterSprite)
290+
// Position foods
291+
for (let i = 0; i < Foods.length; i++) {
292+
let s = kontra.sprite(food)
293+
s.critter = critterSprite
294+
s.color = Foods[i].color
295+
s.x = s.desiredX = Foods[i].x * kontra.canvas.width // remove - 24 when anchor works
296+
s.y = s.desiredY = Foods[i].y * kontra.canvas.width // Squared screen
297+
kontra.pointer.track(s)
298+
sprites.push(s)
299+
}
300+
}
301+
302+
var loop = kontra.gameLoop({ // create the main game loop
303+
fps: 60,
304+
update(dt) { // update the game state
305+
sprites.forEach(sprite => {
306+
sprite.update(dt)
307+
})
308+
sprites = sprites.filter(sprite => sprite.isAlive());
309+
},
310+
render() { // render the game state
311+
sprites.forEach(sprite => {
312+
sprite.render();
313+
})
314+
}
315+
});
316+
317+
reset()
318+
loop.start();
319+
this.loop = loop

hundreds.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
</head>
77
<body>
88
<canvas width=480 height=600></canvas>
9+
<div>Touch a circle to grow it. You lose if another circle touches it while you're touching. Get a sum of 100 to advance.</div>
910
<script src="kontra.js"></script>
1011
<script src="hundreds.js"></script>
1112
</body>

hundreds.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,5 +277,4 @@ var loop = kontra.gameLoop({
277277
this.loop = loop
278278

279279
reset()
280-
loop.start();
281-
document.getElementById('canvas').addEventListener('touchmove', function(e){e.preventDefault();})
280+
loop.start();

index.html

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ <h1>Sample Games:</h1>
1212
<li>
1313
<a href='boggle.html'>Boggle Puzzle</a>
1414
</li>
15-
<li>
16-
<a href='hundreds.html'>Hundreds Game</a>
17-
</li>
15+
<li><a href='hundreds.html'>Hundreds Game</a></li>
16+
<li><a href='race.html'>One Button Race</a></li>
17+
<li><a href='tanks.html'>Tanks</a></li>
18+
<li><a href='critter.html'>Critter</a></li>
1819
</ul>
1920
</body>
20-
</html>
21+
</html>

0 commit comments

Comments
 (0)