Using friction with tile maps in phaser - javascript

I have been making a simple platformer using phaser 3. The level is designed with a tile map from an array and the only sprite is the player itself. When the player presses the right arrow key the x velocity of the player increases. What I would like to do is have friction between the ground and the player so that our player stops once they let go of the key. I know that you can do this with other sprites but can you do it with tilemaps?

With arcade physics it is abit difficult to do this (or more or less impossible). I personally would fake the friction by setting a callback with the method map.setTileLocationCallback, this callback sets the drag of the player (or if you have multiple layers, you could even define a layer for this case).
With matter physics engine it should be possible, checkout this demo and/or the documentation.
Here is a short Demo for arcade physics:
In this small demo, the player is moved with the cursor-keys.
(the player should slide less on the left side = more friction)
document.body.style = 'margin:0;';
let player;
let cursors;
let playerStateText;
let config = {
type: Phaser.AUTO,
width: 12 * 16,
height: 6 * 16,
zoom: 2,
physics: {
default: 'arcade',
arcade: {
gravity: { y: 100 },
debug: true
}
},
scene: { create, preload, update },
banner: false
};
function preload () {
this.load.image('mario-tiles', 'https://labs.phaser.io/assets/tilemaps/tiles/super-mario.png');
}
function create () {
playerStateText = this.add.text(10, 10, 'Playerstate: ???', {color: '#ffffff', fontSize: 10})
.setDepth(10);
// Load a map from a 2D array of tile indices
let level = [
[ 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 35, 36, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
[ 39, 39, 39, 39, 39, 39, 14, 14, 14, 14, 14, 14 ]
];
// When loading from an array, make sure to specify the tileWidth and tileHeight
let map = this.make.tilemap({ data: level, tileWidth: 16, tileHeight: 16 });
let tiles = map.addTilesetImage('mario-tiles');
let layer = map.createLayer(0, tiles, 0, 0);
map.setCollision([ 39, 14], true, true, layer);
player = this.add.rectangle(10, 10, 8, 8, 0xffffff);
this.physics.add.existing(player);
player.body.setCollideWorldBounds(true);
// Just to be sure that the player doesn't get too fast
player.body.setMaxSpeed(160);
// Tweak this value to define how far/long the player should slide
player.body.setDrag(120, 0);
this.physics.add.collider(player, layer);
map.setTileLocationCallback(0, 4, 6, 1, _ => player.body.setDrag(1000, 0) )
map.setTileLocationCallback(6, 4, 6, 1, _ => player.body.setDrag(100, 0) )
cursors = this.input.keyboard.createCursorKeys();
}
function update(){
let currentState = 'Playerstate: running';
if (cursors.left.isDown){
player.body.setAccelerationX(-160);
} else if (cursors.right.isDown) {
player.body.setAccelerationX(160);
}
else {
player.body.setAccelerationX(0);
if(Math.abs(player.body.velocity.x) > 3) {
currentState = 'Playerstate: sliding';
} else if(Math.abs(player.body.velocity.y) > 3) {
currentState = 'Playerstate: falling';
} else {
currentState = 'Playerstate: stopped';
}
}
if(player.x > 400){
player.x = -20;
}
if(player.x < -20){
player.x = 400;
}
playerStateText.setText(currentState);
}
new Phaser.Game(config);
<script src="//cdn.jsdelivr.net/npm/phaser#3.55.2/dist/phaser.js"></script>

Related

Typescript Sudoku problem outputting incomplete boards

I've managed to convert a js sudoku generator into a ts generator for some practice and the only problem I'm having is getting it to output only complete boards. Right now, it's outputting boards regardless if they're complete and I have to refresh until one board is correct.
I'm not sure how to write the following function so that it only outputs full boards:
function fillBoard(puzzleArray: number[][]): number[][] {
if (nextEmptyCell(puzzleArray).colIndex === -1) return puzzleArray;
let emptyCell = nextEmptyCell(puzzleArray);
for (var num in shuffle(numArray)) {
if (safeToPlace(puzzleArray, emptyCell, numArray[num])) {
puzzleArray[emptyCell.rowIndex][emptyCell.colIndex] = numArray[num];
fillBoard(puzzleArray);
}
}
return puzzleArray;
}
Here is all my code:
import { Box } from "./Box";
export function Board() {
let BLANK_BOARD = [
[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, 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, 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, 0, 0, 0],
];
let NEW_BOARD = [
[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, 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, 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, 0, 0, 0],
];
let counter: number = 0;
let check: number[];
const numArray: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9];
function rowSafe(
puzzleArray: number[][],
emptyCell: { rowIndex: number; colIndex: number },
num: number
): boolean {
return puzzleArray[emptyCell.rowIndex].indexOf(num) == -1;
}
function colSafe(
puzzleArray: number[][],
emptyCell: { rowIndex: number; colIndex: number },
num: number
): boolean {
let test = puzzleArray.flat();
for (let i = emptyCell.colIndex; i < test.length; i += 9) {
if (test[i] === num) {
return false;
}
}
return true;
}
function regionSafe(
puzzleArray: number[][],
emptyCell: { rowIndex: number; colIndex: number },
num: number
): boolean {
const rowStart: number = emptyCell.rowIndex - (emptyCell.rowIndex % 3);
const colStart: number = emptyCell.colIndex - (emptyCell.colIndex % 3);
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
if (puzzleArray[rowStart + i][colStart + j] === num) {
return false;
}
}
}
return true;
}
console.log(rowSafe(BLANK_BOARD, { rowIndex: 4, colIndex: 6 }, 5));
console.log(colSafe(BLANK_BOARD, { rowIndex: 2, colIndex: 3 }, 4));
console.log(regionSafe(BLANK_BOARD, { rowIndex: 5, colIndex: 6 }, 5));
function safeToPlace(
puzzleArray: number[][],
emptyCell: { rowIndex: number; colIndex: number },
num: number
): boolean {
return (
regionSafe(puzzleArray, emptyCell, num) &&
rowSafe(puzzleArray, emptyCell, num) &&
colSafe(puzzleArray, emptyCell, num)
);
}
console.log(safeToPlace(BLANK_BOARD, { rowIndex: 5, colIndex: 6 }, 5));
function nextEmptyCell(puzzleArray: number[][]): {
colIndex: number;
rowIndex: number;
} {
let emptyCell = { rowIndex: -1, colIndex: -1 };
for (let i = 0; i < 9; i++) {
for (let j = 0; j < 9; j++) {
if (puzzleArray[i][j] === 0) {
return { rowIndex: i, colIndex: j };
}
}
}
return emptyCell;
}
function shuffle(array: number[]): number[] {
// using Array sort and Math.random
let shuffledArr = array.sort(() => 0.5 - Math.random());
return shuffledArr;
}
function fillBoard(puzzleArray: number[][]): number[][] {
if (nextEmptyCell(puzzleArray).colIndex === -1) return puzzleArray;
let emptyCell = nextEmptyCell(puzzleArray);
for (var num in shuffle(numArray)) {
if (safeToPlace(puzzleArray, emptyCell, numArray[num])) {
puzzleArray[emptyCell.rowIndex][emptyCell.colIndex] = numArray[num];
fillBoard(puzzleArray);
} else {
puzzleArray[emptyCell.rowIndex][emptyCell.colIndex] = 0;
}
}
return puzzleArray;
}
console.log(nextEmptyCell(BLANK_BOARD));
NEW_BOARD = fillBoard(BLANK_BOARD);
function fullBoard(puzzleArray: number[][]): boolean {
return puzzleArray.every((row) => row.every((col) => col !== 0));
}
return (
<div
style={{
height: "450px",
width: "450px",
display: "inline-grid",
gap: "10px",
gridTemplateColumns: "repeat(9,50px)",
gridTemplateRows: "repeat(9,50px)",
position: "absolute",
top: "30px",
left: "0px",
right: "0px",
marginLeft: "auto",
marginRight: "auto",
}}
>
{NEW_BOARD.flat().map((item) => (
<Box i={item} />
))}
</div>
);
}
The function will return an incomplete board when it turns out there is no way to add a digit in a free cell that will be valid.
To solve that, your function should:
implement proper backtracking, i.e. taking back a move that didn't work out
Have the function return a boolean (for success/failure) -- there is no need for it to return puzzleArray, since that array is mutated inplace, so the caller has access to the changes.
This also means that NEW_BOARD = fillBoard(BLANK_BOARD); is having as side effect that NEW_BOARD and BLANK_BOARD reference the same board, and it is not blank any more (so the name is misleading).
break/return out of the loop when there is success.
Here is the adapted implementation:
function fillBoard(puzzleArray: number[][]): boolean {
if (nextEmptyCell(puzzleArray).colIndex === -1) return true; // boolean
let emptyCell = nextEmptyCell(puzzleArray);
for (var num in shuffle(numArray)) {
if (safeToPlace(puzzleArray, emptyCell, numArray[num])) {
puzzleArray[emptyCell.rowIndex][emptyCell.colIndex] = numArray[num];
if fillBoard(puzzleArray) return true; // exit upon success
}
}
puzzleArray[emptyCell.rowIndex][emptyCell.colIndex] = 0; // undo
return false; // boolean - no success
}
The caller should check the return value, but if you start with a blank board, it is guaranteed to get true as return value. So you could do:
const puzzleArray = BLANK_BOARD.map(row => [...row]); // deep copy
const success = fillBoard(puzzleArray); // returns a boolean
// ... do something with puzzleArray ...

Making a chessboard with two queens on it [duplicate]

This question already has answers here:
Unexpected value change in 2D array in JavaScript
(1 answer)
How can I create a two dimensional array in JavaScript?
(56 answers)
Closed 3 years ago.
Im looking to make an 8 x 8 chessboard in my terminal. I've made the proper 8 x 8 grid but can't add the two queens now as 1's
I keep trying as you can see in the code arrayz[0][1] = 1. I'm wondering if the problem is with my looping or there's an easy way to insert two ones into the problem.
const generateBoard= function(){
let arrayz = []
let set= []
let newArray = []
for (i = 0; i < 8; i++){
newArray.push(0)
}
for (y = 0; y < 8; y++){
//newArray[0][1] = 1
arrayz.push(newArray)
arrayz[0][1] = 1 //my failed code that im trying to use to input a single one
}
return arrayz
}
console.log(generateBoard(whiteQueen, blackQueen))
[ [ 0, 1, 0, 0, 0, 0, 0, 0 ],
[ 0, 1, 0, 0, 0, 0, 0, 0 ],
[ 0, 1, 0, 0, 0, 0, 0, 0 ],
[ 0, 1, 0, 0, 0, 0, 0, 0 ],
[ 0, 1, 0, 0, 0, 0, 0, 0 ],
[ 0, 1, 0, 0, 0, 0, 0, 0 ],
[ 0, 1, 0, 0, 0, 0, 0, 0 ],
[ 0, 1, 0, 0, 0, 0, 0, 0 ] ] //what i keep getting
[ [ 0, 1, 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, 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, 0, 0 ],
[ 0, , 0, 0, 0, 0, 0, 1 ] ]//what i want
This code creates only one board row array, newArray, rather than the desired 8. All 8 entries in the array arrayz are just references to newArray. Modifying any one of them will modify all 8, which is obviously not the intent.
In fact, printing the output here on Stack Overflow shows:
[
[
/**id:2**/
0,
1,
0,
0,
0,
0,
0,
0
],
/**ref:2**/,
/**ref:2**/,
/**ref:2**/,
/**ref:2**/,
/**ref:2**/,
/**ref:2**/,
/**ref:2**/
]
Which labels each reference array as a pointer to the first element which has the id 2. Here's the runnable example:
const generateBoard= function(){
let arrayz = []
let set= []
let newArray = []
for (i = 0; i < 8; i++){
newArray.push(0)
}
for (y = 0; y < 8; y++){
//newArray[0][1] = 1
arrayz.push(newArray)
arrayz[0][1] = 1 //my failed code that im trying to use to input a single one
}
return arrayz
}
console.log(generateBoard())
The reference problem can be addressed in a variety of ways. For example, changing
arrayz.push(newArray)
to
arrayz.push(newArray.slice());
makes a true copy of newArray using Array#slice, eliminating the unwanted aliasing.
Another way to make a 2d grid of zeroes is using the Array constructor, Array#fill and Array#map:
const board = Array(8).fill().map(() => Array(8).fill(0));
board[0][1] = 1;
console.log(board);

How do I change the color of the smoke in smoke.js?

Ok, so I'm using the script from this CodePen:
var smokemachine = function(context, color) {
color = color || [245, 46.8, 48.2]
var polyfillAnimFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
var lastframe;
var currentparticles = []
var pendingparticles = []
var buffer = document.createElement('canvas'),
bctx = buffer.getContext('2d')
buffer.width = 20
buffer.height = 20
var opacities = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 5, 7, 4, 4, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 17, 27, 41, 52, 56, 34, 23, 15, 11, 4, 9, 5, 1, 0, 0, 0, 0, 0, 0, 1, 45, 63, 57, 45, 78, 66, 52, 41, 34, 37, 23, 20, 0, 1, 0, 0, 0, 0, 1, 43, 62, 66, 64, 67, 115, 112, 114, 56, 58, 47, 33, 18, 12, 10, 0, 0, 0, 0, 39, 50, 63, 76, 87, 107, 105, 112, 128, 104, 69, 64, 29, 18, 21, 15, 0, 0, 0, 7, 42, 52, 85, 91, 103, 126, 153, 128, 124, 82, 57, 52, 52, 24, 1, 0, 0, 0, 2, 17, 41, 67, 84, 100, 122, 136, 159, 127, 78, 69, 60, 50, 47, 25, 7, 1, 0, 0, 0, 34, 33, 66, 82, 113, 138, 149, 168, 175, 82, 142, 133, 70, 62, 41, 25, 6, 0, 0, 0, 18, 39, 55, 113, 111, 137, 141, 139, 141, 128, 102, 130, 90, 96, 65, 37, 0, 0, 0, 2, 15, 27, 71, 104, 129, 129, 158, 140, 154, 146, 150, 131, 92, 100, 67, 26, 3, 0, 0, 0, 0, 46, 73, 104, 124, 145, 135, 122, 107, 120, 122, 101, 98, 96, 35, 38, 7, 2, 0, 0, 0, 50, 58, 91, 124, 127, 139, 118, 121, 177, 156, 88, 90, 88, 28, 43, 3, 0, 0, 0, 0, 30, 62, 68, 91, 83, 117, 89, 139, 139, 99, 105, 77, 32, 1, 1, 0, 0, 0, 0, 0, 16, 21, 8, 45, 101, 125, 118, 87, 110, 86, 64, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 28, 79, 79, 117, 122, 88, 84, 54, 46, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 6, 55, 61, 68, 71, 30, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 23, 25, 20, 12, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 12, 9, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0]
var data = bctx.createImageData(20, 20)
var d = data.data
for (var i = 0; i < d.length; i += 4) {
d[i] = color[0]
d[i + 1] = color[1]
d[i + 2] = color[2]
d[i + 3] = opacities[i / 4]
}
bctx.putImageData(data, 0, 0)
var imagewidth = 20 * 5
var imageheight = 20 * 5
function particle(x, y, l) {
this.x = x
this.y = y
this.age = 0
this.vx = (Math.random() * 8 - 4) / 100
this.startvy = -(Math.random() * 30 + 10) / 100
this.vy = this.startvy
this.scale = Math.random() * .5
this.lifetime = Math.random() * l + l / 2
this.finalscale = 5 + this.scale + Math.random()
this.update = function(deltatime) {
this.x += this.vx * deltatime
this.y += this.vy * deltatime
var frac = Math.pow((this.age) / this.lifetime, .5)
this.vy = (1 - frac) * this.startvy
this.age += deltatime
this.scale = frac * this.finalscale
}
this.draw = function() {
context.globalAlpha = (1 - Math.abs(1 - 2 * (this.age) / this.lifetime)) / 8
var off = this.scale * imagewidth / 2
var xmin = this.x - off
var xmax = xmin + this.scale * imageheight
var ymin = this.y - off
var ymax = ymin + this.scale * imageheight
context.drawImage(buffer, xmin, ymin, xmax - xmin, ymax - ymin)
}
}
function addparticles(x, y, n, lifetime) {
lifetime = lifetime || 4000
n = n || 10
if (n < 1) return Math.random() <= n && pendingparticles.push(new particle(x, y, lifetime));
for (var i = 0; i < n; i++) {
pendingparticles.push(new particle(x, y, lifetime))
};
}
function updateanddrawparticles(deltatime) {
context.clearRect(0, 0, canvas.width, canvas.height);
deltatime = deltatime || 16
var newparticles = []
currentparticles = currentparticles.concat(pendingparticles)
pendingparticles = []
currentparticles.forEach(function(p) {
p.update(deltatime)
if (p.age < p.lifetime) {
p.draw()
newparticles.push(p)
}
})
currentparticles = newparticles
}
function frame(time) {
if (running) {
var deltat = time - lastframe
lastframe = time;
updateanddrawparticles(deltat)
polyfillAnimFrame(frame)
}
}
var running = false
function start() {
running = true
polyfillAnimFrame(function(time) {
lastframe = time
polyfillAnimFrame(frame)
})
}
function stop() {
running = false
}
return {
start: start,
stop: stop,
step: updateanddrawparticles,
addsmoke: addparticles
}
}
var canvas = document.getElementById('canvas')
var ctx = canvas.getContext('2d')
canvas.width = innerWidth
canvas.height = innerHeight
var party = smokemachine(ctx, [254, 16.8, 18.2])
party.start() // start animating
onmousemove = function(e) {
var x = e.clientX
var y = e.clientY
var n = .5
var t = Math.floor(Math.random() * 200) + 3800
party.addsmoke(x, y, n, t)
}
setInterval(function() {
party.addsmoke(innerWidth / 2, innerHeight, 1)
}, 100)
html,
body {
position: absolute;
margin: 0;
width: 100%;
}
#hi {
position: absolute;
top: 40%;
width: 100%;
text-align: center;
}
#hi a {
color: #fff;
font-size: 80px;
text-decoration: none;
font-family: Lobster;
}
<body cz-shortcut-listen="true">
<a href="https://github.com/bijection/smoke.js">
<img style="width: 150px; position: absolute; top: 0; right: 0; border: 0;" src="./github.png" alt="Spoon me on GitHub">
</a>
<canvas id="canvas" width="1777" height="898"></canvas>
<div id="hi">
<a href="https://github.com/bijection/smoke.js">
smoke.js
</a>
</div>
</body>
In the script box you see how it shows a RGB value for color, I figured changing that would do it but it doesn't, and I've looked through everything I can that might possibly change the color and just can't seem to find it, can anyone help me out?
I'm trying to make it a normal grayish looking smoke.
The second thing I need to know how to do is move it from the center, again tried all the things I can think of. I currently have two floating DIVs one at each bottom corner, I put the canvas in my left floating div, and it still forces it to the middle, even when the div worked in the corner before I added the canvas div inside my floating div.
the floating DIV code I'm using is:
<!-- Smoke Left -->
<div id="floatLogo">
<canvas id="canvas" width="1777" height="898"></canvas>
<div id="hi"></div>
</div>
withe the css of:
#floatLogo {
width:auto;
height:auto;
padding:5px 2px;
text-align:center;
position: fixed;
bottom: 0;
left: 0;
}
The DIV floated perfect to the left before I added the canvas into it, and now its being forced to the center
this will do it, replace MYCOLORCODEHERE with the color you desire;
var ctx = canvas.getContext('2d')
var party = smokemachine(ctx,MYCOLORCODEHERE)
party.addsmoke(500,500)
party.start()
From the docs:
smokemachine(context, [r,g,b])
Returns a smoke machine that makes smoke.
context — the context of the canvas we wanna draw smoke on [r,g,b] —
(optional) the color we want the smoke to be var party =
smokemachine(context, [1,5,253])
Here: https://github.com/bijection/smoke.js
This line:
color = color || [24, 46.8, 48.2];
var polyfillAnimFrame ...
you can try color in the right side to any color you want, for example:
color = [255, 0, 255]
var polyfillAnimFrame ...
will turn the color to pink

How can I load these images

Though I have been able to create and use animations for small demos in the past using the CreateJS library, i'm currently stumped in trying to understand why Nothing is displaying to the canvas even though I have verified that my animation tiles are all being added. I'm going senile from stepping through the debugger and seeing everything work properly, but getting a completely blank page on reloads.
Any ideas are much appreciated!
var stage, loader;
function tick() {
stage.update();
}
function generateMap(rekeyed_array, spriteSheet, row_length, col_length, tilesize) {
for (var x = 0; x < col_length; x++) {
for (var y = 0; y < row_length; y++) {
// z is a onedimentional value mapped from x and y iterators
spriteInstance = new createjs.Sprite(spriteSheet, rekeyed_array[z]);
var z = x * row_length + y;
spriteInstance.x = tilesize * x;
spriteInstance.y = tilesize * y;
spriteInstance.gotoAndPlay(rekeyed_array[z]);
spriteInstance = spriteInstance.clone();
stage.addChild(spriteInstance);
}
}
console.groupEnd();
stage.update();
}
//Replace Tiled's map data numbers with the actual Game Object's Names
function rekeyTiledMapData(spritemappings, array_to_reindex, rows, cols) {
var reindexedArray = new Array();
for (var y = 0; y < cols; y++) {
for (var x = 0; x < rows; x++) {
// z is a onedimentional value mapped from x and y iterators
var z = y * rows + x;
var currentItem = array_to_reindex[z];
if (typeof spritemappings[currentItem] === "string") {
reindexedArray.push(spritemappings[currentItem]);
} else {
reindexedArray.push(currentItem);
}
}
}
return reindexedArray;
}
function getSpriteData(loadedimg) {
var data = {
framerate: 60,
images: [loadedimg],
frames: [
/*middlearth*/
[592, 654, 70, 70, 0, 0, 0],
/*water*/
[562, 434, 70, 70, 0, 0, 0],
/*doormid*/
[146, 290, 70, 70, 0, 0, 0],
/*doortop*/
[218, 290, 70, 70, 0, 0, 0],
/*grass*/
[736, 362, 70, 70, 0, 0, 0]
],
animations: {
"sand": {
frames: 0,
next: "sand",
speed: 1
},
"water": {
frames: 1,
next: "water",
speed: 1
},
"doormid": [2, 2, "doormid", 1],
"doortop": [3, 3, "doortop", 1],
"grass": [4, 4, "grass", 1],
}
};
return data;
}
var mapdata = [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, 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, 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, 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, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 7, 7, 7, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5];
var spritemappings = {
'0': "water",
'8': "water",
'7': "water",
'5': "sand",
'6': "grass",
'10': "doortop",
'11': "doormid"
};
function loadLevel(event) {
var tileimage = loader.getResult("tiles");
levelanimations = rekeyTiledMapData(spritemappings, mapdata, 16, 10);
var spritesheet = new createjs.SpriteSheet(getSpriteData(tileimage));
generateMap(levelanimations, spritesheet, 16, 10, 70);
}
function init() {
stage = new createjs.Stage("gameCanvas");
createjs.Ticker.on("tick", tick);
createjs.Ticker.setFPS(60);
loader = new createjs.LoadQueue(false);
loader.addEventListener("complete", loadLevel)
loader.loadManifest({
id: "tiles",
src: "assets/images/level_tiles.png"
});
}
init();
</script>
</head>
<body>
<canvas id="gameCanvas" width="1600" height="900"></canvas>
</body>
If that script is a copy and paste, the script in the head is executed before the body is being created. Thats why you are seeing that it is executing correctly, but nothing is actually happening.
I would copy and paste the script tag in the header down below the canvas element.

webkitAudioContext Playback of base64 WAV

I have a wav file which with: ffmpeg -i my.wav
Gives the output:
output: Duration: 00:00:12.63, bitrate: 352 kb/s
Stream #0.0: Audio: pcm_s16le, 22050 Hz, 1 channels, s16, 352 kb/s
This is stored as a base64 string in JavaScript loaded in memory as base64 variable listed below.
Here is the code:
byte_str = Base64.decode(base64)
buffer = new ArrayBuffer(byte_str.length*2)
buffer_view = new Uint16Array(buffer)
/* this is coffeescript */
for i in [0..byte_str.length]
buffer_view[i] = byte_str.charCodeAt(i)
console.log(byte_str.length)
console.log(buffer_view)
console.log(buffer_view.buffer)
context = new webkitAudioContext()
context.decodeAudioData(buffer,function (buffer) {
/* never gets hit */
source = #context.createBufferSource()
source.buffer = buffer
source.connect(#context.destination)
source.noteOn(0)
});
Output:
108185
[82, 73, 70, 70, 36, 128, 87, 65, 86, 69, 102, 109, 116, 32, 16, 0, 0, 0, 1, 0, 1, 0, 34, 86, 0, 0, 68, 49152, 2, 0, 16, 0, 100, 97, 116, 97, 0, 128, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,....]
ArrayBuffer {byteLength: 216370}
If you look in this presentation it has a WAV header:
http://html5-demos.appspot.com/static/html5-whats-new/template/index.html#29
var header = new Uint8Array([
0x52,0x49,0x46,0x46, // "RIFF"
0, 0, 0, 0, // put total size here
0x57,0x41,0x56,0x45,
...
]);
Which is identical to mine if you convert the first values to hex, yet on mine the callback never fires for decodeAudioData. Any ideas?
It turns out it was an encoding issue using this library: http://www.webtoolkit.info/javascript-base64.html I removed the _utf8_decode step and it worked great!

Categories

Resources