gpt4 book ai didi

javascript - 我如何使用键盘输入更改 Sprite 我正在使用 vanilla JS

转载 作者:行者123 更新时间:2023-12-04 08:56:24 28 4
gpt4 key购买 nike

所以我一直在测试 HTML Canvas 。我试图让 Sprite 改变键盘输入。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<canvas id='Game' width='200' height='200' style='border: 2px solid #000000;'></canvas>
<script>
window.onload = function(){
var Game = document.getElementById('Game');
var context = Game.getContext('2d')
var room = new Image();
var lx = 0;
var ly = 0;
var li = 0;
var lo = 0;
var lwidth = 100;
var lheight = 100;
room.onload = function(){
context.drawImage(room,lx,ly,lwidth,lheight,li,lo,200,200);
}
room.src = 'https://i.ibb.co/D7fL7yN/Room.png';
var sprite = new Image();
var cx = 0;
var cy = 125;
var sy = 0;
var sx = 0;
var swidth = 35;
var sheight = 34;
sprite.onload = function(){
context.drawImage(sprite,sx,sy,swidth,sheight,cx,cy,50,50);
}
sprite.src = 'https://i.ibb.co/7VhjqPr/John-Sheet.png';
}

</script>
</body>
</html>

我一直在寻找如何使用键盘输入更改 SX,以便我的 Angular 色更改 Sprite 。你能帮助我吗?最好有一个代码示例!

最佳答案

跟踪键盘状态。
您可以创建一个保存键盘状态的对象,特别是您有兴趣响应的键。使用 "keydown" "keyup" KeyboardEvent在事件触发时更新键盘状态。使用 KeyboardEvent 属性 code锻炼哪个键正在改变。不要使用 keyCode因为它已经贬值并且是非标准的
您还希望防止键的默认行为。例如,防止箭头键滚动页面。这是通过调用 event 来完成的。 preventDefault功能

const keys = {
ArrowRight: false,
ArrowLeft: false,
ArrowUp: false,
ArrowDown: false,
}
addEventListener("keydown", keyEvent);
addEventListener("keyup", keyEvent);
function keyEvent(event) {
if (keys[event.code] !== undefined) {
keys[event.code] = event.type === "keydown";
event.preventDefault();
}
}
然后在游戏中你只需要检查键盘状态
if (keys.ArrowRight) { moveRight() }
if (keys.ArrowLeft) { moveLeft() }
// and so on
在下面的演示中,键绑定(bind)到游戏 Action ,这意味着使用什么键以及使用多少键与 Action 无关。也是通过配置设置的,因此可以在不更改游戏代码的情况下更改键绑定(bind)。您还可以绑定(bind)其他输入,如示例
动画片
要制作动画,您应该使用计时器功能 requestAnimationFrame因为它是专门为提供最佳动画效果而设计的。它将调用您的渲染函数,您可以将渲染函数视为循环,即每次在动画时间前进时调用。
把它放在一起
下面的演示使用上述(修改后的)方法来获取键盘输入并通过动画帧请求渲染场景。
它还使用一些技术(简单版本)来帮助您的游戏成为更好的产品。
  • 封装player作为对象
  • 通过在 currentRenderState 中保存当前渲染函数来保持游戏状态
  • 有配置config所以所有重要的值都在一个地方,并且可以(从 JSON 文件)加载,以便在不更改代码的情况下轻松更改游戏。
  • 具有可配置的键盘绑定(bind),注意多个键可以绑定(bind)到一个游戏 Action 。例如,移动是通过 WASD 或箭头键。
  • 所有文本都是可配置的(使其与语言无关)
  • 将 2D 上下文传递给所有渲染代码。
  • 将游戏与渲染分开。这使得将游戏移植到低端或高端设备更容易,甚至可以将其移动到 ctx 替换为 coms 并且可以广播游戏的服务器。游戏不仅仅改变它的渲染方式

  • var currentRenderState = getFocus; // current game state
    const config = {
    player: {
    start: {x: 100, y:100},
    speed: 2,
    imageURL: "/image/C7qq2.png?s=64&g=1",
    },
    keys: { // link key code to game action
    up: ["ArrowUp", "KeyW"],
    down: ["ArrowDown", "KeyS"],
    left: ["ArrowLeft", "KeyA"],
    right: ["ArrowRight", "KeyD"],
    },
    touchableTime: 140, // in ms. Set to 0 or remove to deactivate
    text: {
    focus: "Click canvas to get focus",
    loading: "Just a moment still loading media!",
    instruct: "Use arrow keys or WASD to move",
    }
    };

    requestAnimationFrame(mainLoop); // request first frame
    const ctx = gameCanvas.getContext("2d");
    const w = gameCanvas.width, h = gameCanvas.height;



    const player = {
    image: (()=> {
    const img = new Image;
    img.src = config.player.imageURL;
    img.addEventListener("load", () => player.size = img.width, {once: true});
    return img;
    })(),
    x: config.player.start.x,
    y: config.player.start.y,
    size: 0,
    speed: config.player.speed,
    direction: 0,
    update() {
    var oldX = this.x, oldY = this.y;
    if (actions.left) { this.x -= this.speed }
    if (actions.right) { this.x += this.speed }
    if (actions.up) { this.y -= this.speed }
    if (actions.down) { this.y += this.speed }

    if (this.x < 0) { this.x = 0 }
    else if (this.x > w - this.size) { this.x = w - this.size }
    if (this.y < 0) { this.y = 0 }
    else if (this.y > h - this.size) { this.y = h - this.size }

    const mx = this.x - oldX, my = this.y - oldY;
    if (mx !== 0 || my !== 0) { this.direction = Math.atan2(my, mx) }
    },
    draw(ctx) {
    if (ctx) {
    ctx.setTransform(1, 0, 0, 1, this.x + this.size / 2, this.y + this.size / 2);
    ctx.rotate(this.direction + Math.PI / 2); // rotate 90 deg as image points up
    ctx.drawImage(this.image,-this.size / 2, -this.size / 2, this.size, this.size);
    }
    }
    }
    function drawText(ctx, text, size, color) {
    if (ctx) {
    ctx.fillStyle = color;
    ctx.font = size + "px Arial";
    ctx.textAlign = "center";
    ctx.fillText(text, w / 2, h * (1/4));
    }
    }
    function getFocus(ctx) {
    drawText(ctx, config.text.focus, 24, "black");
    }
    function drawScene(ctx) {
    if (!player.size === 0) {
    drawText(ctx, config.text.loading, 16, "blue")
    actions.hasInput = false; // ensure instruction are up when ready
    } else {
    if (!actions.hasInput) { drawText(ctx, config.text.instruct, 16, "blue") }
    player.update();
    player.draw(ctx);
    }
    }
    function mainLoop() {
    ctx.setTransform(1, 0, 0, 1, 0, 0);
    ctx.clearRect(0, 0, w, h);
    currentRenderState(ctx);
    requestAnimationFrame(mainLoop); // request next frame
    }
    // keys holds action name for each named key. eg for up action ArrowUp: "up", KeyW: "up",
    const keys = Object.entries(config.keys)
    .reduce((keys, [action,codes]) =>
    codes.reduce((keys, code) => (keys[code] = action, keys), keys), {});
    // actions are set true when key down. NOTE first up key for action cancels action
    const actions = Object.keys(config.keys)
    .reduce((actions,action) => (actions[action] = false, actions),{});
    addEventListener("keydown", keyEvent);
    addEventListener("keyup", keyEvent);
    function keyEvent(event) {
    if (keys[event.code] !== undefined) {
    actions[keys[event.code]] = event.type === "keydown";
    event.preventDefault();
    actions.hasInput = true;
    }
    }
    if (config.touchableTime) {
    const actionTimers = {};
    touchable.addEventListener("click", (e) => {
    if (e.target.dataset.action) {
    actions[e.target.dataset.action] = true;
    clearTimeout(actionTimers[e.target.dataset.action]);
    actionTimers[e.target.dataset.action] = setTimeout(() => actions[e.target.dataset.action] = false, config.touchableTime);
    actions.hasInput=true;
    if (currentRenderState !== drawScene) {
    window.focus();
    currentRenderState = drawScene;
    }
    }
    });
    } else {
    touchable.classList.add("hide");
    }

    gameCanvas.addEventListener("click", () => currentRenderState = drawScene, {once: true});
    canvas {border: 1px solid black}
    #game {
    width:402px;
    height:182px;
    font-size: 24px;
    user-select: none;
    }
    .left {
    position: absolute;
    top: 160px;
    left: 10px;
    cursor: pointer;
    }
    .right {
    position: absolute;
    top: 160px;
    left: 355px;
    cursor: pointer;
    }
    #touchable span:hover {color: red}
    .hide { display: none }
    <div id="game">
    <canvas id="gameCanvas" width="400" height="180"></canvas>
    <div id="touchable">
    <div class="left">
    <span data-action="up">&#x25B2;</span>
    <span data-action="down">&#x25BC;</span>
    </div>
    <div class="right">
    <span data-action="left">&#x25C4;</span>
    <span data-action="right">&#x25BA;</span>
    </div>
    </div>
    </div>

    关于javascript - 我如何使用键盘输入更改 Sprite 我正在使用 vanilla JS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63807941/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com