質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

783閲覧

javascriptバイク走行で一定時間過ぎるとcanvasの左上に行ってしまう。原因不明です。

Y.Arai

総合スコア42

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2022/02/11 00:03

下記のscriptでバイク走行をする画面を作成しましたが、一定時間過ぎると下記のように画面の左上に
行ってしまいます。原因がわかる方ご教授ください。

html

1<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Document</title> 8</head> 9<body> 10 <script src="app.js"></script> 11</body> 12</html>

app.js

javascript

1let c = document.createElement("canvas"); 2let ctx = c.getContext("2d"); 3 4c.width = 1000; 5c.height = 400; 6 7document.body.appendChild(c); 8 9let perm = []; 10 11while (perm.length < 255) { 12 while (perm.includes(val = Math.floor(Math.random() * 255))); 13 perm.push(val); 14} 15 16let lerp = (a, b, t) => a + (b - a) * (1 - Math.cos(t * Math.PI)) / 2; 17 18let noise = x => { 19 x = x * 0.01 % 255; 20 return lerp(perm[Math.floor(x)], perm[Math.ceil(x)], x - Math.floor(x)); 21} 22 23let player = new function () { 24 this.x = c.width / 2; 25 this.y = 0; 26 this.ySpeed = 0; 27 this.rot = 0; 28 29 this.img = new Image(); 30 this.img.src = 'moto.png'; 31 32 this.draw = function () { 33 let p1 = c.height - noise(t + this.x) * 0.25; 34 35 36 if (p1 - 30 > this.y) { 37 this.ySpeed += 0.1; 38 } else { 39 this.ySpeed -= this.y - (p1 - 30); 40 this.y = p1 - 30; 41 } 42 this.y += this.ySpeed; 43 44 ctx.save(); 45 ctx.translate(this.x, this.y) 46 ctx.drawImage(this.img, 0, 0, 30, 30); 47 48 ctx.restore(); 49 50 } 51} 52 53let t = 0; 54function loop() { 55 56 t += 7; 57 ctx.fillStyle = "pink"; 58 ctx.fillRect(0, 0, c.width, c.height); 59 60 ctx.fillStyle = "black"; 61 62 ctx.beginPath(); 63 ctx.moveTo(0, c.height); 64 65 for (let i = 0; i < c.width; i++) { 66 ctx.lineTo(i, c.height - noise(t + i) * 0.25); 67 } 68 69 ctx.lineTo(c.width, c.height); 70 71 ctx.fill(); 72 73 player.draw(); 74 75 requestAnimationFrame(loop); 76} 77loop();

走行画面
イメージ説明

左上に行ってしまう画面イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KoichiSugiyama

2022/02/11 00:56

想定した処理で、バイクがどう走行するのが正常であるかも記載してもらった方がアドバイスが集まりやすいと思います。
Y.Arai

2022/02/11 09:41

失礼しました。 黒い描画の表面を走っていますが、登りでジャンプし戻ってきます。 下の黒い部分が右から左に動いています。 よろしくお願いします。
guest

回答1

0

ベストアンサー

掲題のコードだと、noiseの中で、引数xの値によってperm[Math.ceil(x)] がpermの要素数を超えたアクセスとなる場合があります。
このとき、perm[Math.ceil(x)] は undefinedとなり、noiseはNaNを返します。

js

1while (perm.length < 255) { 2 while (perm.includes(val = Math.floor(Math.random() * 255))); 3 perm.push(val); 4}
let noise = x => { x = x * 0.01 % 255; return lerp(perm[Math.floor(x)], perm[Math.ceil(x)], x - Math.floor(x)); }

noiseがNaNのとき、this.yがNaNとなるため
ctx.translate(this.x, this.y)
で左上に固定されて描画されます。


あと直接の原因ではありませんが、tが加算され続けるのも直した方がよいと思います。


バイクが消えるのを直すならば下記のようになるでしょうか。

let noise = x => { x = x * 0.01 % perm.length; const start = Math.floor(x); const end = start == perm.length-1 ? 0 : start + 1; return lerp(perm[start], perm[end], x - start); }

投稿2022/02/11 01:34

編集2022/02/11 12:15
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Y.Arai

2022/02/11 11:48

ありがとうございました。 tが10000を超えたら0にリセットするif分を加えて対応できました。
退会済みユーザー

退会済みユーザー

2022/02/11 12:13

回答に書いたように、tが加算され続けることは、バイクが消えることの直接の原因ではないため、それは本質的な対応ではなく、間接的な対応に過ぎません。 tが10000を超えてリセットされたときに地面がガクッと切り替わるように見えるのを許容するならばそれでもよいかもしれませんね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問