JavaScript:一个数组中的子弹和敌人(拼接,重新索引)
JavaScript: Bullets and enemy in one array (splice, re-indexed)
我在制作简单的射击游戏时遇到了问题(有时):
GIF Game problem
3 颗子弹被移除(但只有一颗子弹相撞)。子弹和敌人(蓝色方块)在一个数组中(var objects = [])。有时它只摧毁(拼接)子弹而不是敌人。
当我执行 .splice() 时,正在重新索引数组,我知道我可以使用:
- 拆分对象(敌人和子弹的两个数组)
- 或使用"delete"
但我想使用 splice() 并且我希望所有对象(子弹、敌人)都在一个数组中,这可能吗?有任何想法吗?我不需要代码(但如果有人有时间请更新我的 jsfiddle ...)。我尝试在 .splice() 之后递减 (i--) 变量 "i"(在循环中)——但这并没有解决问题。
示例:https://jsfiddle.net/uy9okuzv/1/(space == 射击,按键 == 控制)
html
<canvas id="game" width="500" height="400" style="border: 1px red solid;">
javascript
var ctx = document.getElementById("game").getContext('2d');
var objects = [];
var keys = [];
var shotTime = 30;
var ship = {
x: 20,
y: 200,
w: 50,
h: 50,
}
setInterval(function(){
// controls
if(keys[37]){
ship.x-=4;
}
if(keys[38]){
ship.y-=4;
}
if(keys[39]){
ship.x+=4;
}
if(keys[40]){
ship.y+=4;
}
if(keys[32] && shotTime<=0){
push(ship.x+ship.w, ship.y, "bullet", "red", "left");
shotTime = 30;
}else{
shotTime--;
}
// update
for(var e=0; e<objects.length; e++){
var obj = objects[e];
if(obj.type=="bullet"){
for (var i = 0; i<objects.length; i++) {
var enemy = objects[i];
if(enemy.type=="enemy"){
if(collisionObj(obj, enemy)){
objects.splice(e,1);
objects.splice(i,1);
}
}
}
}
if(obj.dir=="left"){
obj.x+=5;
}
if(obj.dir=="right"){
obj.x--;
}
}
// render
ctx.clearRect(0,0,game.width, game.height);
for(var e=0; e<objects.length; e++){
var obj = objects[e];
ctx.fillStyle=obj.color;
ctx.fillRect(obj.x, obj.y, obj.w, obj.h);
}
ctx.fillStyle="green";
ctx.fillRect(ship.x, ship.y, ship.w, ship.h);
},1000/60);
// add enemy
setInterval(function(){
push(game.width, mt_rand(10,game.height-50), "enemy", "blue", "right");
},1000);
// functions
function collisionObj(obj1, obj2, marginX, marginY){
if(marginX==null){
marginX = 0;
}
if(marginY==null){
marginY = 0;
}
if(obj1.x < obj2.x + obj2.w-marginX
&& obj1.x + obj1.w-marginX > obj2.x &&
obj1.y < obj2.y + obj2.h-marginY &&
obj1.h-marginY + obj1.y > obj2.y){
return true;
}
return false;
}
function mt_rand(minimum, maximum) {
minimum = parseInt(minimum, 10);
maximum = parseInt(maximum, 10);
return Math.floor(Math.random() * (maximum - minimum + 1)) + minimum;
}
function push(x,y, what,color, dir){
objects.push({
x: x,
y: y,
h: 50,
w: 50,
type: what,
color: color,
dir: dir,
});
}
// listeners
window.addEventListener('keydown', function(e){
keys[e.keyCode] = true;
}, false);
window.addEventListener('keyup', function(e){
delete keys[e.keyCode];
}, false);
我认为问题是这样的:
if(collisionObj(obj, enemy)){
objects.splice(e,1);
objects.splice(i,1);
}
发生碰撞时,您会移除子弹(索引 e
)和敌人(索引 i
)。每当敌人指数大于子弹时,移除子弹后,敌人指数将不再正确。
您必须先删除最后一个:
if(collisionObj(obj, enemy)){
if( e > i ){
objects.splice(e,1);
objects.splice(i,1);
}
else{
objects.splice(i,1);
objects.splice(e,1);
}
}
我在制作简单的射击游戏时遇到了问题(有时):
GIF Game problem
3 颗子弹被移除(但只有一颗子弹相撞)。子弹和敌人(蓝色方块)在一个数组中(var objects = [])。有时它只摧毁(拼接)子弹而不是敌人。
当我执行 .splice() 时,正在重新索引数组,我知道我可以使用:
- 拆分对象(敌人和子弹的两个数组)
- 或使用"delete"
但我想使用 splice() 并且我希望所有对象(子弹、敌人)都在一个数组中,这可能吗?有任何想法吗?我不需要代码(但如果有人有时间请更新我的 jsfiddle ...)。我尝试在 .splice() 之后递减 (i--) 变量 "i"(在循环中)——但这并没有解决问题。
示例:https://jsfiddle.net/uy9okuzv/1/(space == 射击,按键 == 控制)
html
<canvas id="game" width="500" height="400" style="border: 1px red solid;">
javascript
var ctx = document.getElementById("game").getContext('2d');
var objects = [];
var keys = [];
var shotTime = 30;
var ship = {
x: 20,
y: 200,
w: 50,
h: 50,
}
setInterval(function(){
// controls
if(keys[37]){
ship.x-=4;
}
if(keys[38]){
ship.y-=4;
}
if(keys[39]){
ship.x+=4;
}
if(keys[40]){
ship.y+=4;
}
if(keys[32] && shotTime<=0){
push(ship.x+ship.w, ship.y, "bullet", "red", "left");
shotTime = 30;
}else{
shotTime--;
}
// update
for(var e=0; e<objects.length; e++){
var obj = objects[e];
if(obj.type=="bullet"){
for (var i = 0; i<objects.length; i++) {
var enemy = objects[i];
if(enemy.type=="enemy"){
if(collisionObj(obj, enemy)){
objects.splice(e,1);
objects.splice(i,1);
}
}
}
}
if(obj.dir=="left"){
obj.x+=5;
}
if(obj.dir=="right"){
obj.x--;
}
}
// render
ctx.clearRect(0,0,game.width, game.height);
for(var e=0; e<objects.length; e++){
var obj = objects[e];
ctx.fillStyle=obj.color;
ctx.fillRect(obj.x, obj.y, obj.w, obj.h);
}
ctx.fillStyle="green";
ctx.fillRect(ship.x, ship.y, ship.w, ship.h);
},1000/60);
// add enemy
setInterval(function(){
push(game.width, mt_rand(10,game.height-50), "enemy", "blue", "right");
},1000);
// functions
function collisionObj(obj1, obj2, marginX, marginY){
if(marginX==null){
marginX = 0;
}
if(marginY==null){
marginY = 0;
}
if(obj1.x < obj2.x + obj2.w-marginX
&& obj1.x + obj1.w-marginX > obj2.x &&
obj1.y < obj2.y + obj2.h-marginY &&
obj1.h-marginY + obj1.y > obj2.y){
return true;
}
return false;
}
function mt_rand(minimum, maximum) {
minimum = parseInt(minimum, 10);
maximum = parseInt(maximum, 10);
return Math.floor(Math.random() * (maximum - minimum + 1)) + minimum;
}
function push(x,y, what,color, dir){
objects.push({
x: x,
y: y,
h: 50,
w: 50,
type: what,
color: color,
dir: dir,
});
}
// listeners
window.addEventListener('keydown', function(e){
keys[e.keyCode] = true;
}, false);
window.addEventListener('keyup', function(e){
delete keys[e.keyCode];
}, false);
我认为问题是这样的:
if(collisionObj(obj, enemy)){
objects.splice(e,1);
objects.splice(i,1);
}
发生碰撞时,您会移除子弹(索引 e
)和敌人(索引 i
)。每当敌人指数大于子弹时,移除子弹后,敌人指数将不再正确。
您必须先删除最后一个:
if(collisionObj(obj, enemy)){
if( e > i ){
objects.splice(e,1);
objects.splice(i,1);
}
else{
objects.splice(i,1);
objects.splice(e,1);
}
}