- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
当我在 Canvas 上移动 player.hero 的图像时,我想要一个变量来保存英雄当前的 x 和 y 位置。所以我可以让僵尸图像向英雄的当前位置移动。谢谢,如果到目前为止我的代码很糟糕,请提出修改建议,谢谢。
(function() {
var canvas, context, width, height, speed = 8;
var interval_id;
var zombies = [];
var bullets = [];
var moveLeft = false;
var moveRight = false;
var moveUp = false;
var moveDown = false;
var player = {
x : 0,
y : 0,
width : 35,
height : 60,
hero : new Image(),
};
for (var i = 0; i < 10; i += 1){
var zombie = {
x : 10,
y : 10,
undead : new Image(),
targetToGox : 0,
targetToGoy : 0,
};
zombies.push(zombie);
}
var mouse = {
x : 0,
y : 0,
}
document.addEventListener('DOMContentLoaded', init, false);
function init() {
canvas = document.querySelector('canvas');
context = canvas.getContext('2d');
width = canvas.width;
height = canvas.height;
player.x = width / 2 - 18;
player.y = height / 2 - 30;
player.hero.src = 'hero.png';
zombie.undead.src = 'zombie.png';
//context.drawImage(player.hero, player.x, player.y);
window.addEventListener("keydown", activate,false);
window.addEventListener("keyup",deactivate,false);
//window.addEventListener("mouseover", drawImagePointingAt, false);
interval_player = window.setInterval(drawPlayer, 33);
}
function drawPlayer() {
context.clearRect(0 ,0 ,width, height);
context.drawImage(player.hero,player.x, player.y);
//******** need zombie to go to position of player.hero******///
context.drawImage(zombie.undead (somthing for x and y coordinats of player.hero);
// stops player moveing beyond the bounds of the canvas
if (player.x + player.width >= width) {
moveRight = false
}
if (player.y + player.height >= height) {
moveDown = false
}
if (player.x <= 0) {
moveLeft = false
}
if (player.y <= 0) {
moveUp = false
}
if (moveRight) {
player.x += speed;
}
if (moveUp) {
player.y -= speed;
}
if (moveDown) {
player.y += speed;
}
if (moveLeft){
player.x -= speed;
}
function activate(event) {
var keyCode = event.keyCode;
if (keyCode === 87){
moveUp = true;
}
else if (keyCode === 68){
moveRight = true;
}
else if (keyCode === 83){
moveDown = true;
}
else if (keyCode === 65){
moveLeft = true;
}
}
function deactivate(event) {
var keyCode = event.keyCode;
if (keyCode === 87){
moveUp = false;}
else if (keyCode === 68){
moveRight = false;}
else if (keyCode === 83){
moveDown = false;}
else if (keyCode === 65){
moveLeft = false;}
}
function getRandomNumber(min, max) {
return Math.round(Math.random() * (max - min)) + min;
}
function stop() {
clearInterval(interval_player);
}
})();
最佳答案
这是一个相当长的文字墙,讲述了为什么我认为重构代码而不是 “...获取我在屏幕上移动的图像的 X 和 Y 坐标”。
这篇文章的结尾包含一个脚本,它试图展示您可以如何去做。
您询问了代码的质量。对于新程序员来说,您的代码并不很糟糕,但是随着您的代码库变大,您陷入一些经典陷阱将会很痛苦。
这方面的一个例子可能是为您的玩家在按键后应该移动的每个可能方向保留变量(在单独的函数中操作和使用)。这样做的问题是,当您决定更改此系统的任何 方面时,它就会崩溃。
相反,考虑让一个对象代表玩家,它包含它自己的内部逻辑,通过改变它自己的坐标来“移动”。
我怎么强调这个想法都不为过——优秀的黑客总是给自己一个工作的空间。你不应该(例如)让Player
直接操纵游戏绘图例程。这是一个如此普遍的概念,以至于在软件工程中实际上有一些词来描述这种组织原则的不同方面(像“Encapsulation”或“Loose coupling”或“Law of Demeter”这样的词)。这很重要。
这引出了另一点:全局变量。
这是一个更难的问题,因为所有程序员如果对它过于挑剔(特别是如果他们从事的是低级工作),最终都会变成伪君子。尽管如此,最好还是合并您拥有 的任何全局变量,并可能创建函数作为它们与“外部世界”的接口(interface)。
在您的游戏中,这意味着像 moveLeft
一样移动到一个“游戏循环”中,该循环只检查所有“对象”坐标,清除屏幕并适本地绘制这些对象。
这里的另一个重要想法是“重复”功能应该共享一个方法。在您的情况下,这将导致 Player
和 Zombie
成为某个更抽象的类别的实例,我将其命名为 GameObject
。这允许您为 GameObject
编写一次所有主要功能,并在 Player
和 Zombie
中“继承”它们的功能(有许多 other , perhaps even better , 无需原型(prototype)或继承即可实现的方法)
考虑到所有这一切,我试着花 20 分钟来制作一些东西,希望它能给你一些东西来工作。如果这与您的目的完全无关,至少您可以在自己的腰包下进行另一轮可能毫无意义的互联网自负。
我的代码的“继承”是以一种非常简单的 Javascript 风格完成的,尽管事实上有不少于 12 种“新的和改进的”方法来在 JS 代码之间共享实现细节,每一种都有很大的不同他们对原型(prototype)或面向对象编程原则的坚持程度。
我不希望涵盖 Stamps、jSL,甚至 Javascript 现在臭名昭著的 new 'class' keyword ,所以我建议您阅读这些内容,也许自己将它们用于有利可图的用途,但现在我坚持使用基础知识。
const ZOMBIE_COUNT = 10
function GameState() {
this.player = null;
this.enemies = []
}
var Game = new GameState() // our global game state
// An abstract 'game object' or character
function GameObject({x, y, image}) {
this.x = x
this.y = y
this.image = image
}
GameObject.prototype.draw = function() {
Game.ctx.fillStyle = this.color
Game.ctx.fillRect(this.x, this.y, 10, 10)
}
GameObject.prototype.moveLeft = function(n) { if(this.x > 0) this.x -= n }
GameObject.prototype.moveRight = function(n) { if(this.x < Game.width) this.x += n }
GameObject.prototype.moveDown = function(n) { if(this.y < Game.height) this.y += n}
GameObject.prototype.moveUp = function(n) { if(this.y > 0) this.y -= n }
function Player({x, y, width}) {
GameObject.call(this, {x, y}) // setup x, y & image
this.color = 'red'
}
Player.prototype = Object.create(GameObject.prototype, {})
function Zombie({x, y, target}) {
GameObject.call(this, {x, y}) // setup x, y & image
this.target = target // target contains the player
this.color = 'blue'
}
Zombie.prototype = Object.create(GameObject.prototype, {})
Zombie.prototype.moveToPlayer = function() {
let {x, y} = Game.player
// very basic 'movement' logic
if (this.x < x) {
this.moveRight(1/4)
} else if (this.x > x) {
this.moveLeft(1/4)
}
if (this.y > y) {
this.moveUp(1/4)
} else if (this.y < y) {
this.moveDown(1/4)
}
}
function init() {
var canvas = document.getElementById('canvas')
if (canvas.getContext) {
var ctx = canvas.getContext('2d')
} else {
console.log("No canvas")
return -1
}
let {width, height} = canvas
// Setup our game object
Game.width = width
Game.height = height
Game.ctx = ctx
// Create our player in the middle
Game.player = new Player({x: width / 2, y: height / 2})
// Create our enemies
for(let i = 0; i < ZOMBIE_COUNT; i++) {
Game.enemies.push(new Zombie({x: Math.random() * width | 0, // truncate our value
y: Math.random() * height | 0}))
}
game_loop()
}
function game_loop() {
window.requestAnimationFrame(game_loop)
Game.ctx.fillStyle = 'white'
Game.ctx.fillRect(0, 0, Game.width, Game.height);
Game.player.draw()
Game.enemies.map(enemy => {
enemy.moveToPlayer()
enemy.draw()
})
}
function process_key(ev) {
let speed = 3
let key = ev.keyCode
if (key === 68)
Game.player.moveRight(speed)
if (key === 87)
Game.player.moveUp(speed)
if (key === 65)
Game.player.moveLeft(speed)
if (key === 83)
Game.player.moveDown(speed)
}
window.addEventListener('keydown', process_key, false);
init()
canvas { border: 3px solid #333; }
<canvas id="canvas" width="400" height="400"></canvas>
关于javascript - 如何获取在 Canvas 上移动的图像的 X 和 Y 坐标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42739926/
我刚刚编写了这些代码,但输出不同。第二个代码的输出符合我的预期,但第一个代码的输出不正确。但为什么呢? def fib(n): x = 0 y = 1 print x
#include #include #define CUBE(y)y*(y*y) main() { int j; j = CUBE(-2+4);
这个问题在这里已经有了答案: Multiple assignment and evaluation order in Python (11 个答案) 关闭 1 年前。 我看到下面的代码,但不知道它做
我正在阅读 book , 并讲了 typeclass Eq 的定义 有两个功能== , /=在等式中,它们被实现为: x == y = not (x /= y) x /= y = not (
我最近参加了一个代码力量竞赛。在比赛的编辑部分,我看到了按位运算符之间的一种美妙关系,即 x + y = x & y + x |是的我还不知道证据。我拿了几个数字来看看这个等式是否正确。我很高兴知道这
我使用 CGRectMake(x,x,x,x) 在我的 View 中放置了一个按钮,当然 x 是位置和大小。当我使用 -(BOOL)shouldAutoRotate... 旋转 View 时,我想将按
this.x = (Math.random()*canvasWidth); this.y = (Math.random()*canvasHeight); (1) this.shift = {x: th
我想将此代码运行为“if 'Britain' or 'UK' in string do stuff, but don't do stuff if "Ex UK" 在字符串中": #Case insen
早上好,我是新来的,我带来了一个小问题。我无法针对以下问题开发有效的算法:我需要找到三个正数 x、y 和 z 的组合,以便 x + y、x - y、y + z、y - z、x + z 和 x - z
我现在正在使用 C++ 编写方案的解释器。我有一个关于定义和 lambda 的问题。 (define (add x y) (+ x y)) 扩展为 (define add (lambda (x y)
我正在尝试使用一台主机通过 FTP 将内容上传到另一台主机。 “我不会打开到 172.xxx.xxx.xxx(仅到 54.xxx.xxx.xxx)的连接”甚至不相关,因为我没有连接到那个主持人。这是托
在 Python 中,使用 [] 解包函数调用有什么区别? , 与 ()还是一无所有? def f(): return 0, 1 a, b = f() # 1 [a, b] = f() # 2
给定方程 z = z(x,y) 2 个表面 I和 II : z_I(x, y) = a0 + a1*y + a2*x + a3*y**2 + a4*x**2 + a5*x*y z_II(x, y)
几年前我有这个面试问题,但我还没有找到答案。 x 和 y 应该是什么才能形成无限循环? while (x = y && x != y) { } 我们尝试了 Nan,infinity+/-,null f
我正在尝试使用 Camel FTP Producer 将文件发送到第三方 ftp 服务器(似乎由 Amazon 托管),但遇到了一个问题,写入文件失败,并显示:文件操作失败...主机尝试数据连接 x.
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 8 年前。 Improve t
我正在使用 torch.tensor.repeat() x = torch.tensor([[1, 2, 3], [4, 5, 6]]) period = x.size(1) repeats = [1
#include int main() { int x = 9; int y = 2; int z = x - (x / y) * y; printf("%d", z
我很难理解先有定义然后有两个异或表达式的含义。这个定义的作用是什么? 我尝试发送 x=8, y=7,结果是 x=15 和 y=8为什么会这样? 这是程序: #define FUNC(a,b) a^=b
我正在尝试使用 SIMD 优化此功能,但我不知道从哪里开始。 long sum(int x,int y) { return x*x*x+y*y*y; } 反汇编函数如下所示: 4007a0
我是一名优秀的程序员,十分优秀!